Updated render classes structure to be less alien
This commit is contained in:
parent
370c93226b
commit
ef838d52c2
@ -1,21 +1,10 @@
|
||||
package ru.dbotthepony.kstarbound.client
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
||||
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
||||
import ru.dbotthepony.kstarbound.client.render.ConfiguredStaticMesh
|
||||
import ru.dbotthepony.kstarbound.client.render.entity.EntityRenderer
|
||||
import ru.dbotthepony.kstarbound.client.render.LayeredRenderer
|
||||
import ru.dbotthepony.kstarbound.client.render.TileLayerList
|
||||
import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition
|
||||
import ru.dbotthepony.kstarbound.world.*
|
||||
import ru.dbotthepony.kstarbound.world.CHUNK_SIZEd
|
||||
import ru.dbotthepony.kstarbound.world.api.ITileAccess
|
||||
import ru.dbotthepony.kstarbound.world.Chunk
|
||||
import ru.dbotthepony.kstarbound.world.ChunkPos
|
||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||
import ru.dbotthepony.kvector.vector.Vector2d
|
||||
import ru.dbotthepony.kvector.vector.Vector2f
|
||||
import ru.dbotthepony.kvector.vector.Vector2i
|
||||
import java.io.Closeable
|
||||
import java.util.LinkedList
|
||||
|
||||
/**
|
||||
* Псевдо zPos у фоновых тайлов
|
||||
@ -70,6 +59,6 @@ class ClientChunk(world: ClientWorld, pos: ChunkPos) : Chunk<ClientWorld, Client
|
||||
}
|
||||
|
||||
override fun onEntityRemoved(entity: Entity) {
|
||||
entityRenderers.remove(entity)!!.close()
|
||||
entityRenderers.remove(entity)
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
|
||||
import it.unimi.dsi.fastutil.longs.LongArraySet
|
||||
import it.unimi.dsi.fastutil.objects.ReferenceArraySet
|
||||
import ru.dbotthepony.kstarbound.client.render.ConfiguredStaticMesh
|
||||
import ru.dbotthepony.kstarbound.client.render.ConfiguredMesh
|
||||
import ru.dbotthepony.kstarbound.client.render.LayeredRenderer
|
||||
import ru.dbotthepony.kstarbound.client.render.Mesh
|
||||
import ru.dbotthepony.kstarbound.client.render.TileLayerList
|
||||
import ru.dbotthepony.kstarbound.client.render.MultiMeshBuilder
|
||||
import ru.dbotthepony.kstarbound.defs.tile.LiquidDefinition
|
||||
import ru.dbotthepony.kstarbound.math.roundTowardsNegativeInfinity
|
||||
import ru.dbotthepony.kstarbound.math.roundTowardsPositiveInfinity
|
||||
@ -51,23 +51,16 @@ class ClientWorld(
|
||||
inner class RenderRegion(val x: Int, val y: Int) {
|
||||
inner class Layer(private val view: ITileAccess, private val isBackground: Boolean) {
|
||||
private val state get() = client.gl
|
||||
private val layers = TileLayerList()
|
||||
val bakedMeshes = ArrayList<Pair<ConfiguredStaticMesh, Int>>()
|
||||
val bakedMeshes = ArrayList<Pair<ConfiguredMesh<*>, Int>>()
|
||||
var isDirty = true
|
||||
|
||||
fun bake() {
|
||||
if (!isDirty) return
|
||||
isDirty = false
|
||||
|
||||
if (state.isSameThread()) {
|
||||
for (mesh in bakedMeshes) {
|
||||
mesh.first.close()
|
||||
}
|
||||
}
|
||||
|
||||
bakedMeshes.clear()
|
||||
|
||||
layers.clear()
|
||||
val meshes = MultiMeshBuilder()
|
||||
|
||||
for (x in 0 until renderRegionWidth) {
|
||||
for (y in 0 until renderRegionHeight) {
|
||||
@ -77,30 +70,22 @@ class ClientWorld(
|
||||
val material = tile.material
|
||||
|
||||
if (material != null) {
|
||||
client.tileRenderers.getTileRenderer(material.materialName).tesselate(tile, view, layers, Vector2i(x, y), background = isBackground)
|
||||
client.tileRenderers.getMaterialRenderer(material.materialName).tesselate(tile, view, meshes, Vector2i(x, y), background = isBackground)
|
||||
}
|
||||
|
||||
val modifier = tile.modifier
|
||||
|
||||
if (modifier != null) {
|
||||
client.tileRenderers.getModifierRenderer(modifier.modName).tesselate(tile, view, layers, Vector2i(x, y), background = isBackground, isModifier = true)
|
||||
client.tileRenderers.getModifierRenderer(modifier.modName).tesselate(tile, view, meshes, Vector2i(x, y), background = isBackground, isModifier = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (layers.isNotEmpty) {
|
||||
for (mesh in bakedMeshes) {
|
||||
mesh.first.close()
|
||||
}
|
||||
|
||||
bakedMeshes.clear()
|
||||
|
||||
for ((baked, builder, zLevel) in layers.layers()) {
|
||||
bakedMeshes.add(ConfiguredStaticMesh(baked, builder) to zLevel)
|
||||
}
|
||||
|
||||
layers.clear()
|
||||
for ((baked, builder, zLevel) in meshes.meshes()) {
|
||||
bakedMeshes.add(ConfiguredMesh(baked, Mesh(state, builder)) to zLevel)
|
||||
}
|
||||
|
||||
meshes.clear()
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +135,7 @@ class ClientWorld(
|
||||
for ((baked, zLevel) in background.bakedMeshes) {
|
||||
layers.add(zLevel + Z_LEVEL_BACKGROUND) {
|
||||
it.push().last().translateWithMultiplication(renderOrigin.x, renderOrigin.y)
|
||||
baked.renderStacked(it)
|
||||
baked.render(it.last())
|
||||
it.pop()
|
||||
}
|
||||
}
|
||||
@ -158,7 +143,7 @@ class ClientWorld(
|
||||
for ((baked, zLevel) in foreground.bakedMeshes) {
|
||||
layers.add(zLevel) {
|
||||
it.push().last().translateWithMultiplication(renderOrigin.x, renderOrigin.y)
|
||||
baked.renderStacked(it)
|
||||
baked.render(it.last())
|
||||
it.pop()
|
||||
}
|
||||
}
|
||||
|
@ -16,9 +16,7 @@ data class BlendFunc(
|
||||
Func.ZERO
|
||||
)
|
||||
|
||||
constructor(
|
||||
source: Func, destination: Func
|
||||
) : this(
|
||||
constructor(source: Func, destination: Func) : this(
|
||||
source,
|
||||
destination,
|
||||
source,
|
||||
|
@ -13,7 +13,7 @@ import org.lwjgl.opengl.GL45.glCheckNamedFramebufferStatus
|
||||
import org.lwjgl.opengl.GL45.glNamedFramebufferTexture
|
||||
import org.lwjgl.opengl.GL46
|
||||
|
||||
class GLFrameBuffer(val state: GLStateTracker) : AutoCloseable {
|
||||
class GLFrameBuffer(val state: GLStateTracker) {
|
||||
init {
|
||||
state.ensureSameThread()
|
||||
}
|
||||
@ -22,6 +22,7 @@ class GLFrameBuffer(val state: GLStateTracker) : AutoCloseable {
|
||||
|
||||
init {
|
||||
checkForGLError("Creating framebuffer")
|
||||
state.registerCleanable(this, GL46::glDeleteFramebuffers, pointer)
|
||||
}
|
||||
|
||||
val isComplete: Boolean get() {
|
||||
@ -50,7 +51,6 @@ class GLFrameBuffer(val state: GLStateTracker) : AutoCloseable {
|
||||
}
|
||||
|
||||
fun reattachTexture(width: Int, height: Int, format: Int = GL_RGB) {
|
||||
texture?.close()
|
||||
texture = null
|
||||
attachTexture(width, height, format)
|
||||
}
|
||||
@ -76,17 +76,4 @@ class GLFrameBuffer(val state: GLStateTracker) : AutoCloseable {
|
||||
state.readFramebuffer = null
|
||||
}
|
||||
}
|
||||
|
||||
private val cleanable = state.registerCleanable(this, GL46::glDeleteFramebuffers, pointer)
|
||||
var isValid = true
|
||||
private set
|
||||
|
||||
override fun close() {
|
||||
if (!isValid)
|
||||
return
|
||||
|
||||
cleanable.clean()
|
||||
texture?.close()
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ private class GLTexturePropertyTracker(private val flag: Int, private var value:
|
||||
}
|
||||
|
||||
@Suppress("SameParameterValue")
|
||||
class GLTexture2D(val state: GLStateTracker, val name: String = "<unknown>") : AutoCloseable {
|
||||
class GLTexture2D(val state: GLStateTracker, val name: String = "<unknown>") {
|
||||
init {
|
||||
state.ensureSameThread()
|
||||
}
|
||||
@ -38,10 +38,9 @@ class GLTexture2D(val state: GLStateTracker, val name: String = "<unknown>") : A
|
||||
|
||||
init {
|
||||
checkForGLError()
|
||||
state.registerCleanable(this, ::glDeleteTextures, pointer)
|
||||
}
|
||||
|
||||
private val cleanable = state.registerCleanable(this, ::glDeleteTextures, pointer)
|
||||
|
||||
var width = 0
|
||||
private set
|
||||
|
||||
@ -269,23 +268,6 @@ class GLTexture2D(val state: GLStateTracker, val name: String = "<unknown>") : A
|
||||
return this
|
||||
}
|
||||
|
||||
var isValid = true
|
||||
private set
|
||||
|
||||
override fun close() {
|
||||
state.ensureSameThread()
|
||||
|
||||
if (!isValid)
|
||||
return
|
||||
|
||||
if (state.texture2D == this) {
|
||||
state.texture2D = null
|
||||
}
|
||||
|
||||
cleanable.clean()
|
||||
isValid = false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
}
|
||||
|
@ -1,29 +1,24 @@
|
||||
package ru.dbotthepony.kstarbound.client.gl
|
||||
|
||||
import org.lwjgl.opengl.GL46.*
|
||||
import java.io.Closeable
|
||||
|
||||
class VertexArrayObject(val state: GLStateTracker) : Closeable {
|
||||
class VertexArrayObject(val state: GLStateTracker) {
|
||||
val pointer = glGenVertexArrays()
|
||||
|
||||
init {
|
||||
checkForGLError()
|
||||
state.registerCleanable(this, ::glDeleteVertexArrays, pointer)
|
||||
}
|
||||
|
||||
private val cleanable = state.registerCleanable(this, ::glDeleteVertexArrays, pointer)
|
||||
|
||||
fun bind(): VertexArrayObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexArrayObject" }
|
||||
return state.bind(this)
|
||||
}
|
||||
|
||||
fun unbind(): VertexArrayObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexArrayObject" }
|
||||
return state.unbind(this)
|
||||
}
|
||||
|
||||
fun attribute(position: Int, size: Int, type: Int, normalize: Boolean, stride: Int, offset: Long = 0L): VertexArrayObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexArrayObject" }
|
||||
state.ensureSameThread()
|
||||
glVertexAttribPointer(position, size, type, normalize, stride, offset)
|
||||
checkForGLError()
|
||||
@ -31,27 +26,10 @@ class VertexArrayObject(val state: GLStateTracker) : Closeable {
|
||||
}
|
||||
|
||||
fun enableAttribute(position: Int): VertexArrayObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexArrayObject" }
|
||||
state.ensureSameThread()
|
||||
glEnableVertexArrayAttrib(pointer, position)
|
||||
//glEnableVertexAttribArray(position)
|
||||
checkForGLError()
|
||||
return this
|
||||
}
|
||||
|
||||
var isValid = true
|
||||
private set
|
||||
|
||||
override fun close() {
|
||||
state.ensureSameThread()
|
||||
|
||||
if (!isValid) return
|
||||
|
||||
if (state.VAO == this) {
|
||||
state.VAO = null
|
||||
}
|
||||
|
||||
cleanable.clean()
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package ru.dbotthepony.kstarbound.client.gl
|
||||
|
||||
import org.lwjgl.opengl.GL46.*
|
||||
import org.lwjgl.system.MemoryUtil
|
||||
import java.io.Closeable
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
enum class VBOType(val glType: Int) {
|
||||
@ -10,32 +9,28 @@ enum class VBOType(val glType: Int) {
|
||||
ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER),
|
||||
}
|
||||
|
||||
class VertexBufferObject(val state: GLStateTracker, val type: VBOType = VBOType.ARRAY) : Closeable {
|
||||
class VertexBufferObject(val state: GLStateTracker, val type: VBOType = VBOType.ARRAY) {
|
||||
val pointer = glGenBuffers()
|
||||
|
||||
init {
|
||||
checkForGLError("Creating Vertex Buffer Object")
|
||||
state.registerCleanable(this, ::glDeleteBuffers, pointer)
|
||||
}
|
||||
|
||||
private val cleanable = state.registerCleanable(this, ::glDeleteBuffers, pointer)
|
||||
|
||||
val isArray get() = type == VBOType.ARRAY
|
||||
val isElementArray get() = type == VBOType.ELEMENT_ARRAY
|
||||
|
||||
fun bind(): VertexBufferObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexBufferObject" }
|
||||
state.bind(this)
|
||||
return this
|
||||
}
|
||||
|
||||
fun unbind(): VertexBufferObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexBufferObject" }
|
||||
state.unbind(this)
|
||||
return this
|
||||
}
|
||||
|
||||
fun bufferData(data: ByteBuffer, usage: Int): VertexBufferObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexBufferObject" }
|
||||
state.ensureSameThread()
|
||||
glNamedBufferData(pointer, data, usage)
|
||||
checkForGLError()
|
||||
@ -43,7 +38,6 @@ class VertexBufferObject(val state: GLStateTracker, val type: VBOType = VBOType.
|
||||
}
|
||||
|
||||
fun bufferData(data: ByteBuffer, usage: Int, length: Long): VertexBufferObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexBufferObject" }
|
||||
state.ensureSameThread()
|
||||
|
||||
if (length > data.remaining().toLong()) {
|
||||
@ -57,7 +51,6 @@ class VertexBufferObject(val state: GLStateTracker, val type: VBOType = VBOType.
|
||||
}
|
||||
|
||||
fun bufferData(data: IntArray, usage: Int): VertexBufferObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexBufferObject" }
|
||||
state.ensureSameThread()
|
||||
glNamedBufferData(pointer, data, usage)
|
||||
checkForGLError()
|
||||
@ -65,7 +58,6 @@ class VertexBufferObject(val state: GLStateTracker, val type: VBOType = VBOType.
|
||||
}
|
||||
|
||||
fun bufferData(data: FloatArray, usage: Int): VertexBufferObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexBufferObject" }
|
||||
state.ensureSameThread()
|
||||
glNamedBufferData(pointer, data, usage)
|
||||
checkForGLError()
|
||||
@ -73,7 +65,6 @@ class VertexBufferObject(val state: GLStateTracker, val type: VBOType = VBOType.
|
||||
}
|
||||
|
||||
fun bufferData(data: DoubleArray, usage: Int): VertexBufferObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexBufferObject" }
|
||||
state.ensureSameThread()
|
||||
glNamedBufferData(pointer, data, usage)
|
||||
checkForGLError()
|
||||
@ -81,27 +72,9 @@ class VertexBufferObject(val state: GLStateTracker, val type: VBOType = VBOType.
|
||||
}
|
||||
|
||||
fun bufferData(data: LongArray, usage: Int): VertexBufferObject {
|
||||
check(isValid) { "Tried to use NULL GLVertexBufferObject" }
|
||||
state.ensureSameThread()
|
||||
glNamedBufferData(pointer, data, usage)
|
||||
checkForGLError()
|
||||
return this
|
||||
}
|
||||
|
||||
var isValid = true
|
||||
private set
|
||||
|
||||
override fun close() {
|
||||
state.ensureSameThread()
|
||||
|
||||
if (!isValid) return
|
||||
|
||||
if (state.VBO == this) {
|
||||
state.VBO = null
|
||||
}
|
||||
|
||||
cleanable.clean()
|
||||
|
||||
isValid = false
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
||||
import org.lwjgl.opengl.GL46.*
|
||||
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
||||
import ru.dbotthepony.kstarbound.client.gl.checkForGLError
|
||||
import ru.dbotthepony.kstarbound.client.gl.vertex.GLAttributeList
|
||||
import ru.dbotthepony.kvector.api.IStruct2f
|
||||
import ru.dbotthepony.kvector.api.IStruct3f
|
||||
import ru.dbotthepony.kvector.api.IStruct4f
|
||||
@ -22,7 +23,11 @@ import kotlin.NoSuchElementException
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
open class GLShaderProgram(val state: GLStateTracker, shaders: Iterable<GLStateTracker.Shader>) {
|
||||
open class GLShaderProgram(
|
||||
val state: GLStateTracker,
|
||||
shaders: Iterable<GLStateTracker.Shader>,
|
||||
val attributes: GLAttributeList
|
||||
) {
|
||||
init {
|
||||
state.ensureSameThread()
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ private fun GLStateTracker.gshaders(name: String): List<GLStateTracker.Shader> {
|
||||
)
|
||||
}
|
||||
|
||||
class GLLiquidProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("liquid")) {
|
||||
class GLLiquidProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("liquid"), FORMAT) {
|
||||
var baselineColor by F4Uniform("baselineColor")
|
||||
var transform by F4x4Uniform("transform")
|
||||
|
||||
@ -35,7 +35,7 @@ class GLLiquidProgram(state: GLStateTracker) : GLShaderProgram(state, state.shad
|
||||
}
|
||||
}
|
||||
|
||||
class GLLightProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("light")) {
|
||||
class GLLightProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("light"), FORMAT) {
|
||||
var baselineColor by F4Uniform("baselineColor")
|
||||
var transform by F4x4Uniform("transform")
|
||||
|
||||
@ -48,7 +48,7 @@ class GLLightProgram(state: GLStateTracker) : GLShaderProgram(state, state.shade
|
||||
}
|
||||
}
|
||||
|
||||
class GLColorQuadProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("screen_quad")) {
|
||||
class GLColorQuadProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("screen_quad"), FORMAT) {
|
||||
var color by F4Uniform("color")
|
||||
|
||||
private val builder by lazy {
|
||||
@ -94,7 +94,7 @@ class GLColorQuadProgram(state: GLStateTracker) : GLShaderProgram(state, state.s
|
||||
}
|
||||
}
|
||||
|
||||
class GLTextureQuadProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("screen_quad_tex")) {
|
||||
class GLTextureQuadProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("screen_quad_tex"), FORMAT) {
|
||||
var texture by IUniform("texture0")
|
||||
|
||||
private val builder by lazy {
|
||||
@ -118,7 +118,7 @@ class GLTextureQuadProgram(state: GLStateTracker) : GLShaderProgram(state, state
|
||||
}
|
||||
}
|
||||
|
||||
class GLTextureBlurredQuadProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("screen_quad_tex_blur")) {
|
||||
class GLTextureBlurredQuadProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("screen_quad_tex_blur"), FORMAT) {
|
||||
var texture by IUniform("texture0")
|
||||
|
||||
private val builder by lazy {
|
||||
@ -142,7 +142,7 @@ class GLTextureBlurredQuadProgram(state: GLStateTracker) : GLShaderProgram(state
|
||||
}
|
||||
}
|
||||
|
||||
class GLFlatColorProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("flat_color")) {
|
||||
class GLFlatColorProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("flat_color"), FORMAT) {
|
||||
var transform by F4x4Uniform("transform")
|
||||
|
||||
val builder by lazy {
|
||||
@ -154,7 +154,22 @@ class GLFlatColorProgram(state: GLStateTracker) : GLShaderProgram(state, state.s
|
||||
}
|
||||
}
|
||||
|
||||
class GLTileProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("tile")) {
|
||||
class GLTileProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("tile"), FORMAT) {
|
||||
var transform by F4x4Uniform("transform")
|
||||
var color by F4Uniform("color")
|
||||
var texture by IUniform("texture0")
|
||||
|
||||
init {
|
||||
transform = Matrix4f.identity()
|
||||
color = RGBAColor.WHITE
|
||||
}
|
||||
|
||||
companion object {
|
||||
val FORMAT = GLAttributeList.Builder().push(GLType.VEC3F, GLType.VEC2F, GLType.FLOAT).build()
|
||||
}
|
||||
}
|
||||
|
||||
class GLFontProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("font"), GLAttributeList.VERTEX_2D_TEXTURE) {
|
||||
var transform by F4x4Uniform("transform")
|
||||
var color by F4Uniform("color")
|
||||
var texture by IUniform("texture0")
|
||||
@ -165,18 +180,7 @@ class GLTileProgram(state: GLStateTracker) : GLShaderProgram(state, state.shader
|
||||
}
|
||||
}
|
||||
|
||||
class GLFontProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("font")) {
|
||||
var transform by F4x4Uniform("transform")
|
||||
var color by F4Uniform("color")
|
||||
var texture by IUniform("texture0")
|
||||
|
||||
init {
|
||||
transform = Matrix4f.identity()
|
||||
color = RGBAColor.WHITE
|
||||
}
|
||||
}
|
||||
|
||||
class GLFlatProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("flat")) {
|
||||
class GLFlatProgram(state: GLStateTracker) : GLShaderProgram(state, state.shaders("flat"), GLAttributeList.VEC2F) {
|
||||
var transform by F4x4Uniform("transform")
|
||||
var color by F4Uniform("color")
|
||||
|
||||
@ -185,7 +189,7 @@ class GLFlatProgram(state: GLStateTracker) : GLShaderProgram(state, state.shader
|
||||
}
|
||||
}
|
||||
|
||||
class GLTexturedProgram(state: GLStateTracker) : GLShaderProgram(state, listOf(state.internalVertex("shaders/vertex/texture.glsl"), state.internalFragment("shaders/fragment/texture.glsl"))) {
|
||||
class GLTexturedProgram(state: GLStateTracker) : GLShaderProgram(state, listOf(state.internalVertex("shaders/vertex/texture.glsl"), state.internalFragment("shaders/fragment/texture.glsl")), GLAttributeList.VERTEX_TEXTURE) {
|
||||
var transform by F4x4Uniform("transform")
|
||||
var texture by IUniform("texture0")
|
||||
|
||||
@ -194,7 +198,7 @@ class GLTexturedProgram(state: GLStateTracker) : GLShaderProgram(state, listOf(s
|
||||
}
|
||||
}
|
||||
|
||||
class GLTexturedColoredProgram(state: GLStateTracker) : GLShaderProgram(state, listOf(state.internalVertex("shaders/vertex/texture.glsl"), state.internalFragment("shaders/fragment/texture_color.glsl"))) {
|
||||
class GLTexturedColoredProgram(state: GLStateTracker) : GLShaderProgram(state, listOf(state.internalVertex("shaders/vertex/texture.glsl"), state.internalFragment("shaders/fragment/texture_color.glsl")), GLAttributeList.VERTEX_TEXTURE) {
|
||||
var transform by F4x4Uniform("transform")
|
||||
var texture by IUniform("texture0")
|
||||
var color by F4Uniform("color")
|
||||
|
@ -83,12 +83,7 @@ class GLAttributeList(builder: Builder) {
|
||||
|
||||
companion object {
|
||||
val VEC2F = Builder().push(GLType.VEC2F).build()
|
||||
val VEC3F = Builder().push(GLType.VEC3F).build()
|
||||
|
||||
val VERTEX_TEXTURE = Builder().push(GLType.VEC3F).push(GLType.VEC2F).build()
|
||||
|
||||
val VERTEX_2D_TEXTURE = Builder().push(GLType.VEC2F).push(GLType.VEC2F).build()
|
||||
|
||||
val TILE = Builder().push(GLType.VEC3F, GLType.VEC2F, GLType.FLOAT).build()
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package ru.dbotthepony.kstarbound.client.gl.vertex
|
||||
import org.lwjgl.opengl.GL46
|
||||
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
||||
import ru.dbotthepony.kstarbound.client.gl.checkForGLError
|
||||
import java.io.Closeable
|
||||
|
||||
/**
|
||||
* Быстрое наполнение буфера вершинами, загрузка в память видеокарты, и отрисовка
|
||||
@ -13,7 +12,7 @@ class StreamVertexBuilder(
|
||||
attributes: GLAttributeList,
|
||||
type: GeometryType,
|
||||
initialCapacity: Int = 64,
|
||||
) : Closeable {
|
||||
) {
|
||||
val builder = VertexBuilder(attributes, type, initialCapacity)
|
||||
private val vao = state.newVAO()
|
||||
private val vbo = state.newVBO()
|
||||
@ -44,12 +43,6 @@ class StreamVertexBuilder(
|
||||
checkForGLError()
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
vao.close()
|
||||
vbo.close()
|
||||
ebo.close()
|
||||
}
|
||||
|
||||
fun singleSprite(x: Float, y: Float, width: Float, height: Float, z: Float = 5f, angle: Double = 0.0, transformer: QuadVertexTransformer) {
|
||||
builder.begin()
|
||||
|
||||
|
@ -1,99 +0,0 @@
|
||||
package ru.dbotthepony.kstarbound.client.render
|
||||
|
||||
import org.lwjgl.opengl.GL46.*
|
||||
import ru.dbotthepony.kstarbound.client.gl.shader.GLShaderProgram
|
||||
import ru.dbotthepony.kstarbound.client.gl.VertexArrayObject
|
||||
import ru.dbotthepony.kstarbound.client.gl.checkForGLError
|
||||
import ru.dbotthepony.kstarbound.client.gl.vertex.VertexBuilder
|
||||
import ru.dbotthepony.kvector.arrays.Matrix4f
|
||||
import ru.dbotthepony.kvector.arrays.Matrix4fStack
|
||||
|
||||
/**
|
||||
* Служит для быстрой настройки состояния для будущей отрисовки
|
||||
*
|
||||
* Установка текстурных блоков, программы, самих текстур и загрузка юниформ должна осуществляться тут
|
||||
*
|
||||
* Класс обязан быть наследован для осмысленных результатов
|
||||
*
|
||||
* Ожидается, что состояние будет выставлено ПОЛНОСТЬЮ, т.е. НИКАКОЙ предыдущий код НЕ МОЖЕТ повлиять на результат выполнения
|
||||
* шейдерной программы, которая связанна с этим объектом (за исключением не вызова [setTransform] внешним кодом)
|
||||
*/
|
||||
open class ConfiguredShaderProgram<T : GLShaderProgram>(
|
||||
val program: T,
|
||||
) {
|
||||
private val transformLocation = program.getUniform("transform") as? GLShaderProgram.F4x4Uniform
|
||||
|
||||
open fun setTransform(value: Matrix4f) {
|
||||
transformLocation?.value = value
|
||||
}
|
||||
|
||||
/**
|
||||
* Вызывается перед началом отрисовки
|
||||
*/
|
||||
open fun setup() {
|
||||
program.use()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Запечённый статичный меш, позволяет быстро отрисовать меш со всеми параметрами
|
||||
* с заданной матрицей трансформации
|
||||
*/
|
||||
class ConfiguredStaticMesh(
|
||||
val programState: ConfiguredShaderProgram<*>,
|
||||
val indexCount: Int,
|
||||
val vao: VertexArrayObject,
|
||||
val elementIndexType: Int,
|
||||
) : AutoCloseable {
|
||||
private var onClose = {}
|
||||
|
||||
constructor(programState: ConfiguredShaderProgram<*>, builder: VertexBuilder) : this(
|
||||
programState,
|
||||
builder.indexCount,
|
||||
programState.program.state.newVAO(),
|
||||
builder.indexType,
|
||||
) {
|
||||
val vbo = programState.program.state.newVBO()
|
||||
val ebo = programState.program.state.newEBO()
|
||||
|
||||
onClose = {
|
||||
vbo.close()
|
||||
ebo.close()
|
||||
}
|
||||
|
||||
vao.bind()
|
||||
vbo.bind()
|
||||
ebo.bind()
|
||||
|
||||
builder.upload(vbo, ebo, GL_STATIC_DRAW)
|
||||
builder.attributes.apply(vao, true)
|
||||
|
||||
vao.unbind()
|
||||
vbo.unbind()
|
||||
ebo.unbind()
|
||||
}
|
||||
|
||||
fun render(transform: Matrix4f? = null) {
|
||||
check(isValid) { "$this is no longer valid" }
|
||||
programState.setup()
|
||||
|
||||
if (transform != null) {
|
||||
programState.setTransform(transform)
|
||||
}
|
||||
|
||||
vao.bind()
|
||||
glDrawElements(GL_TRIANGLES, indexCount, elementIndexType, 0L)
|
||||
checkForGLError()
|
||||
}
|
||||
|
||||
fun renderStacked(transform: Matrix4fStack) = render(transform.last())
|
||||
|
||||
var isValid = true
|
||||
private set
|
||||
|
||||
override fun close() {
|
||||
vao.close()
|
||||
onClose.invoke()
|
||||
isValid = false
|
||||
}
|
||||
}
|
@ -244,7 +244,7 @@ class Font(
|
||||
return size(breakLines(text))
|
||||
}
|
||||
|
||||
private inner class Glyph(val char: Char) : AutoCloseable {
|
||||
private inner class Glyph(val char: Char) {
|
||||
private val texture: GLTexture2D?
|
||||
|
||||
val isEmpty: Boolean
|
||||
@ -349,13 +349,5 @@ class Font(
|
||||
|
||||
stack.last().translateWithMultiplication(advanceX - bearingX, bearingY)
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
vao?.close()
|
||||
ebo?.close()
|
||||
vbo?.close()
|
||||
|
||||
texture?.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package ru.dbotthepony.kstarbound.client.render
|
||||
import org.lwjgl.opengl.GL46
|
||||
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
||||
import ru.dbotthepony.kstarbound.client.gl.checkForGLError
|
||||
import ru.dbotthepony.kstarbound.client.gl.shader.GLShaderProgram
|
||||
import ru.dbotthepony.kstarbound.client.gl.vertex.VertexBuilder
|
||||
import ru.dbotthepony.kvector.arrays.Matrix4f
|
||||
|
||||
class Mesh(state: GLStateTracker) {
|
||||
constructor(state: GLStateTracker, builder: VertexBuilder) : this(state) {
|
||||
@ -39,5 +41,14 @@ class Mesh(state: GLStateTracker) {
|
||||
vao.bind()
|
||||
GL46.glDrawElements(GL46.GL_TRIANGLES, indexCount, indexType, 0L)
|
||||
checkForGLError()
|
||||
vao.unbind()
|
||||
}
|
||||
}
|
||||
|
||||
data class ConfiguredMesh<T : GLShaderProgram>(val config: RenderConfig<T>, val mesh: Mesh = Mesh(config.state)) {
|
||||
fun render(transform: Matrix4f = config.state.matrixStack.last()) {
|
||||
config.setup(transform)
|
||||
mesh.render()
|
||||
config.uninstall()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package ru.dbotthepony.kstarbound.client.render
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
|
||||
import ru.dbotthepony.kstarbound.client.gl.vertex.GeometryType
|
||||
import ru.dbotthepony.kstarbound.client.gl.vertex.VertexBuilder
|
||||
import java.util.stream.Stream
|
||||
|
||||
class MultiMeshBuilder {
|
||||
data class Entry(val config: RenderConfig<*>, val builder: VertexBuilder, val layer: Int)
|
||||
|
||||
private val meshes = Reference2ObjectOpenHashMap<RenderConfig<*>, Int2ObjectOpenHashMap<Entry>>()
|
||||
|
||||
fun get(config: RenderConfig<*>, layer: Int): VertexBuilder {
|
||||
return meshes.computeIfAbsent(config, Reference2ObjectFunction {
|
||||
Int2ObjectOpenHashMap()
|
||||
}).computeIfAbsent(layer, Int2ObjectFunction { Entry(config, VertexBuilder(config.program.attributes, GeometryType.QUADS), layer) }).builder
|
||||
}
|
||||
|
||||
fun clear() = meshes.clear()
|
||||
fun isEmpty() = meshes.isEmpty()
|
||||
fun isNotEmpty() = meshes.isNotEmpty()
|
||||
|
||||
fun meshes(): Stream<Entry> {
|
||||
return meshes.values.stream().flatMap { it.values.stream() }
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package ru.dbotthepony.kstarbound.client.render
|
||||
|
||||
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
||||
import ru.dbotthepony.kstarbound.client.gl.shader.GLShaderProgram
|
||||
import ru.dbotthepony.kvector.arrays.Matrix4f
|
||||
|
||||
abstract class RenderConfig<out T : GLShaderProgram>(val state: GLStateTracker, val program: T) {
|
||||
open fun setup(transform: Matrix4f = state.matrixStack.last()) {
|
||||
program.use()
|
||||
}
|
||||
|
||||
open fun uninstall() {}
|
||||
}
|
@ -1,54 +1,21 @@
|
||||
package ru.dbotthepony.kstarbound.client.render
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.lwjgl.opengl.GL46.*
|
||||
import ru.dbotthepony.kstarbound.PIXELS_IN_STARBOUND_UNITf
|
||||
import ru.dbotthepony.kstarbound.client.StarboundClient
|
||||
import ru.dbotthepony.kstarbound.client.gl.*
|
||||
import ru.dbotthepony.kstarbound.client.gl.shader.GLTileProgram
|
||||
import ru.dbotthepony.kstarbound.client.gl.vertex.GLAttributeList
|
||||
import ru.dbotthepony.kstarbound.client.gl.vertex.*
|
||||
import ru.dbotthepony.kstarbound.defs.tile.*
|
||||
import ru.dbotthepony.kstarbound.world.api.ITileAccess
|
||||
import ru.dbotthepony.kstarbound.world.api.ITileState
|
||||
import ru.dbotthepony.kstarbound.world.api.TileColor
|
||||
import ru.dbotthepony.kvector.arrays.Matrix4f
|
||||
import ru.dbotthepony.kvector.vector.RGBAColor
|
||||
import ru.dbotthepony.kvector.vector.Vector2i
|
||||
import java.util.stream.Stream
|
||||
import kotlin.collections.HashMap
|
||||
|
||||
data class TileLayer(
|
||||
val program: ConfiguredShaderProgram<GLTileProgram>,
|
||||
val vertices: VertexBuilder,
|
||||
val zPos: Int
|
||||
)
|
||||
|
||||
class TileLayerList {
|
||||
private val layers = HashMap<ConfiguredShaderProgram<GLTileProgram>, Int2ObjectOpenHashMap<TileLayer>>()
|
||||
|
||||
/**
|
||||
* Получает геометрию слоя ([DynamicVertexBuilder]), который имеет программу для отрисовки [program] и располагается на [zLevel].
|
||||
*
|
||||
* Если такого слоя нет, вызывается [compute] и создаётся новый [TileLayer], затем возвращается результат [compute].
|
||||
*/
|
||||
fun computeIfAbsent(program: ConfiguredShaderProgram<GLTileProgram>, zLevel: Int, compute: () -> VertexBuilder): VertexBuilder {
|
||||
return layers.computeIfAbsent(program) { Int2ObjectOpenHashMap() }.computeIfAbsent(zLevel, Int2ObjectFunction {
|
||||
return@Int2ObjectFunction TileLayer(program, compute.invoke(), zLevel)
|
||||
}).vertices
|
||||
}
|
||||
|
||||
fun layers(): Stream<TileLayer> {
|
||||
return layers.values.stream().flatMap { it.values.stream() }
|
||||
}
|
||||
|
||||
fun clear() = layers.clear()
|
||||
|
||||
val isEmpty get() = layers.isEmpty()
|
||||
val isNotEmpty get() = layers.isNotEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* Хранит в себе программы для отрисовки определённых [TileDefinition]
|
||||
*
|
||||
@ -56,28 +23,29 @@ class TileLayerList {
|
||||
*/
|
||||
class TileRenderers(val client: StarboundClient) {
|
||||
val state get() = client.gl
|
||||
private val foregroundTilePrograms = HashMap<GLTexture2D, ForegroundTileProgram>()
|
||||
private val backgroundTilePrograms = HashMap<GLTexture2D, BackgroundTileProgram>()
|
||||
private val tileRenderersCache = HashMap<String, TileRenderer>()
|
||||
private val modifierRenderersCache = HashMap<String, TileRenderer>()
|
||||
|
||||
fun getTileRenderer(defName: String): TileRenderer {
|
||||
return tileRenderersCache.computeIfAbsent(defName) {
|
||||
private val foreground = HashMap<GLTexture2D, Config>()
|
||||
private val background = HashMap<GLTexture2D, Config>()
|
||||
private val matCache = HashMap<String, TileRenderer>()
|
||||
private val modCache = HashMap<String, TileRenderer>()
|
||||
|
||||
fun getMaterialRenderer(defName: String): TileRenderer {
|
||||
return matCache.computeIfAbsent(defName) {
|
||||
val def = client.starbound.tiles[defName] // TODO: Пустой рендерер
|
||||
return@computeIfAbsent TileRenderer(this, def!!.value)
|
||||
}
|
||||
}
|
||||
|
||||
fun getModifierRenderer(defName: String): TileRenderer {
|
||||
return modifierRenderersCache.computeIfAbsent(defName) {
|
||||
return modCache.computeIfAbsent(defName) {
|
||||
val def = client.starbound.tileModifiers[defName] // TODO: Пустой рендерер
|
||||
return@computeIfAbsent TileRenderer(this, def!!.value)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class ForegroundTileProgram(private val texture: GLTexture2D) : ConfiguredShaderProgram<GLTileProgram>(state.programs.tile) {
|
||||
override fun setup() {
|
||||
super.setup()
|
||||
private inner class Config(private val texture: GLTexture2D, private val color: RGBAColor) : RenderConfig<GLTileProgram>(state, state.programs.tile) {
|
||||
override fun setup(transform: Matrix4f) {
|
||||
super.setup(transform)
|
||||
state.activeTexture = 0
|
||||
state.depthTest = false
|
||||
program.texture = 0
|
||||
@ -85,68 +53,19 @@ class TileRenderers(val client: StarboundClient) {
|
||||
texture.textureMagFilter = GL_NEAREST
|
||||
texture.textureMinFilter = GL_NEAREST
|
||||
|
||||
program.color = FOREGROUND_COLOR
|
||||
program.transform = transform
|
||||
program.color = color
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (other is ForegroundTileProgram) {
|
||||
return texture == other.texture
|
||||
}
|
||||
|
||||
return super.equals(other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return texture.hashCode()
|
||||
}
|
||||
override fun uninstall() {}
|
||||
}
|
||||
|
||||
private inner class BackgroundTileProgram(private val texture: GLTexture2D) : ConfiguredShaderProgram<GLTileProgram>(state.programs.tile) {
|
||||
override fun setup() {
|
||||
super.setup()
|
||||
state.activeTexture = 0
|
||||
state.depthTest = false
|
||||
program.texture = 0
|
||||
texture.bind()
|
||||
texture.textureMagFilter = GL_NEAREST
|
||||
texture.textureMinFilter = GL_NEAREST
|
||||
|
||||
program.color = BACKGROUND_COLOR
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (other is BackgroundTileProgram) {
|
||||
return texture == other.texture
|
||||
}
|
||||
|
||||
return super.equals(other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return texture.hashCode()
|
||||
}
|
||||
fun foreground(texture: GLTexture2D): RenderConfig<GLTileProgram> {
|
||||
return foreground.computeIfAbsent(texture) { Config(it, FOREGROUND_COLOR) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает запечённое состояние шейдера shaderVertexTexture с данной текстурой
|
||||
*/
|
||||
fun foreground(texture: GLTexture2D): ConfiguredShaderProgram<GLTileProgram> {
|
||||
return foregroundTilePrograms.computeIfAbsent(texture, ::ForegroundTileProgram)
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает запечённое состояние шейдера shaderVertexTextureRGBAColor с данной текстурой
|
||||
*/
|
||||
fun background(texture: GLTexture2D): ConfiguredShaderProgram<GLTileProgram> {
|
||||
return backgroundTilePrograms.computeIfAbsent(texture, ::BackgroundTileProgram)
|
||||
fun background(texture: GLTexture2D): RenderConfig<GLTileProgram> {
|
||||
return background.computeIfAbsent(texture) { Config(it, BACKGROUND_COLOR) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -155,8 +74,6 @@ class TileRenderers(val client: StarboundClient) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun vertexTextureBuilder() = VertexBuilder(GLAttributeList.TILE, GeometryType.QUADS)
|
||||
|
||||
private class TileEqualityTester(val definition: TileDefinition) : EqualityRuleTester {
|
||||
override fun test(thisTile: ITileState?, otherTile: ITileState?): Boolean {
|
||||
return otherTile?.material == definition && thisTile?.hueShift == otherTile.hueShift
|
||||
@ -236,7 +153,7 @@ class TileRenderer(val renderers: TileRenderers, val def: IRenderableTile) {
|
||||
self: ITileState,
|
||||
matchPiece: RenderMatch,
|
||||
getter: ITileAccess,
|
||||
layers: TileLayerList,
|
||||
meshBuilder: MultiMeshBuilder,
|
||||
pos: Vector2i,
|
||||
thisBuilder: VertexBuilder,
|
||||
background: Boolean,
|
||||
@ -251,14 +168,14 @@ class TileRenderer(val renderers: TileRenderers, val def: IRenderableTile) {
|
||||
renderers.foreground(state.loadTexture(renderPiece.piece.texture!!))
|
||||
}
|
||||
|
||||
tesselateAt(self, renderPiece.piece, getter, layers.computeIfAbsent(program, def.renderParameters.zLevel, ::vertexTextureBuilder), pos, renderPiece.offset, isModifier)
|
||||
tesselateAt(self, renderPiece.piece, getter, meshBuilder.get(program, def.renderParameters.zLevel), pos, renderPiece.offset, isModifier)
|
||||
} else {
|
||||
tesselateAt(self, renderPiece.piece, getter, thisBuilder, pos, renderPiece.offset, isModifier)
|
||||
}
|
||||
}
|
||||
|
||||
for (subPiece in matchPiece.subMatches) {
|
||||
val matched = tesselatePiece(self, subPiece, getter, layers, pos, thisBuilder, background, isModifier)
|
||||
val matched = tesselatePiece(self, subPiece, getter, meshBuilder, pos, thisBuilder, background, isModifier)
|
||||
|
||||
if (matched == TestResult.HALT || matched == TestResult.CONTINUE && matchPiece.haltOnSubMatch) {
|
||||
return TestResult.HALT
|
||||
@ -280,20 +197,20 @@ class TileRenderer(val renderers: TileRenderers, val def: IRenderableTile) {
|
||||
*
|
||||
* [getter] Нужен для получения информации о ближайших блоках
|
||||
*
|
||||
* [layers] содержит текущие программы и их билдеры и их zPos
|
||||
* [meshBuilder] содержит текущие программы и их билдеры и их zPos
|
||||
*
|
||||
* Тесселирует тайлы в нужный VertexBuilder с масштабом согласно константе [PIXELS_IN_STARBOUND_UNITf]
|
||||
*/
|
||||
fun tesselate(self: ITileState, getter: ITileAccess, layers: TileLayerList, pos: Vector2i, background: Boolean = false, isModifier: Boolean = false) {
|
||||
fun tesselate(self: ITileState, getter: ITileAccess, meshBuilder: MultiMeshBuilder, pos: Vector2i, background: Boolean = false, isModifier: Boolean = false) {
|
||||
// если у нас нет renderTemplate
|
||||
// то мы просто не можем его отрисовать
|
||||
val template = def.renderTemplate.value ?: return
|
||||
|
||||
val vertexBuilder = layers.computeIfAbsent(if (background) bakedBackgroundProgramState else bakedProgramState, def.renderParameters.zLevel, ::vertexTextureBuilder)
|
||||
val vertexBuilder = meshBuilder.get(if (background) bakedBackgroundProgramState else bakedProgramState, def.renderParameters.zLevel)
|
||||
|
||||
for ((_, matcher) in template.matches) {
|
||||
for (matchPiece in matcher) {
|
||||
val matched = tesselatePiece(self, matchPiece, getter, layers, pos, vertexBuilder, background, isModifier)
|
||||
val matched = tesselatePiece(self, matchPiece, getter, meshBuilder, pos, vertexBuilder, background, isModifier)
|
||||
|
||||
if (matched == TestResult.HALT) {
|
||||
break
|
||||
|
@ -7,14 +7,13 @@ import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
||||
import ru.dbotthepony.kstarbound.world.entities.Entity
|
||||
import ru.dbotthepony.kvector.arrays.Matrix4fStack
|
||||
import ru.dbotthepony.kvector.vector.Vector2d
|
||||
import java.io.Closeable
|
||||
|
||||
/**
|
||||
* Базовый класс, отвечающий за отрисовку определённого ентити в мире
|
||||
*
|
||||
* Считается, что процесс отрисовки ограничен лишь одним слоем (т.е. отрисовка происходит в один проход)
|
||||
*/
|
||||
open class EntityRenderer(val client: StarboundClient, val entity: Entity, open var chunk: ClientChunk?) : Closeable {
|
||||
open class EntityRenderer(val client: StarboundClient, val entity: Entity, open var chunk: ClientChunk?) {
|
||||
inline val state: GLStateTracker get() = client.gl
|
||||
open val renderPos: Vector2d get() = entity.position
|
||||
|
||||
@ -30,10 +29,6 @@ open class EntityRenderer(val client: StarboundClient, val entity: Entity, open
|
||||
|
||||
open val layer: Int get() = Z_LEVEL_ENTITIES
|
||||
|
||||
override fun close() {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Pseudo Z position for entities, for them to appear behind tile geometry,
|
||||
|
@ -2,7 +2,6 @@ package ru.dbotthepony.kstarbound.io
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
||||
import ru.dbotthepony.kstarbound.api.IStarboundFile
|
||||
import ru.dbotthepony.kstarbound.io.json.BinaryJsonReader
|
||||
import java.io.BufferedInputStream
|
||||
|
Loading…
Reference in New Issue
Block a user