Make vertex builder be able to switch geometry type on the fly
This commit is contained in:
parent
96cc44c592
commit
386d71b92f
@ -103,8 +103,6 @@ class ClientWorld(
|
|||||||
for ((baked, builder, zLevel) in meshes.meshes()) {
|
for ((baked, builder, zLevel) in meshes.meshes()) {
|
||||||
bakedMeshes.add(ConfiguredMesh(baked, Mesh(state, builder)) to zLevel)
|
bakedMeshes.add(ConfiguredMesh(baked, Mesh(state, builder)) to zLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
meshes.clear()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package ru.dbotthepony.kstarbound.client.gl.vertex
|
package ru.dbotthepony.kstarbound.client.gl.vertex
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntList
|
||||||
|
|
||||||
enum class GeometryType(
|
enum class GeometryType(
|
||||||
/**
|
/**
|
||||||
* Число вершин у одного элемента
|
* Число вершин у одного элемента
|
||||||
@ -9,22 +11,22 @@ enum class GeometryType(
|
|||||||
/**
|
/**
|
||||||
* Индекс вершин одного элемента
|
* Индекс вершин одного элемента
|
||||||
*/
|
*/
|
||||||
val indices: IntArray
|
val indices: IntList
|
||||||
) {
|
) {
|
||||||
AS_IS(1, intArrayOf(0)),
|
AS_IS(1, IntList.of(0)),
|
||||||
LINES(2, intArrayOf(0, 1)),
|
LINES(2, IntList.of(0, 1)),
|
||||||
TRIANGLES(3, intArrayOf(0, 1, 2)),
|
TRIANGLES(3, IntList.of(0, 1, 2)),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A B C B C D
|
* A B C B C D
|
||||||
*/
|
*/
|
||||||
QUADS(4, intArrayOf(0, 1, 2, 1, 2, 3)),
|
QUADS(4, IntList.of(0, 1, 2, 1, 2, 3)),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A B C C D A
|
* A B C C D A
|
||||||
*/
|
*/
|
||||||
QUADS_ALTERNATIVE(4, intArrayOf(0, 1, 2, 2, 3, 0)),
|
QUADS_ALTERNATIVE(4, IntList.of(0, 1, 2, 2, 3, 0)),
|
||||||
|
|
||||||
QUADS_AS_LINES(4, intArrayOf(0, 1, 0, 2, 1, 3, 2, 3)),
|
QUADS_AS_LINES(4, IntList.of(0, 1, 0, 2, 1, 3, 2, 3)),
|
||||||
QUADS_AS_LINES_WIREFRAME(4, intArrayOf(0, 1, 0, 2, 1, 3, 2, 3, 0, 3, 1, 2)),
|
QUADS_AS_LINES_WIREFRAME(4, IntList.of(0, 1, 0, 2, 1, 3, 2, 3, 0, 3, 1, 2)),
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ private fun indexSize(type: Int): Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Создаёт буферы вне кучи для загрузки геометрии в них, с набором аттрибутов [attributes], типом [type] и указанным начальным размером.
|
* Создаёт буферы вне кучи для загрузки геометрии в них, с набором аттрибутов [attributes], типом [mode] и указанным начальным размером.
|
||||||
*
|
*
|
||||||
* По мере необходимости, буферы могут быть увеличены в размерах.
|
* По мере необходимости, буферы могут быть увеличены в размерах.
|
||||||
*
|
*
|
||||||
@ -51,23 +51,28 @@ private fun indexSize(type: Int): Int {
|
|||||||
*/
|
*/
|
||||||
class VertexBuilder(
|
class VertexBuilder(
|
||||||
val attributes: GLAttributeList,
|
val attributes: GLAttributeList,
|
||||||
val type: GeometryType,
|
val defaultMode: GeometryType? = null,
|
||||||
initialCapacity: Int = 64
|
initialCapacity: Int = 64
|
||||||
) {
|
) {
|
||||||
|
init {
|
||||||
|
require(initialCapacity > 0) { "Invalid capacity: $initialCapacity" }
|
||||||
|
}
|
||||||
|
|
||||||
|
private var mode: GeometryType? = defaultMode
|
||||||
|
|
||||||
|
private var vertexCapacity = if (defaultMode == null) initialCapacity else defaultMode.elements * initialCapacity
|
||||||
|
private var indexCapacity = if (defaultMode == null) initialCapacity else defaultMode.indices.size * initialCapacity
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [GL_UNSIGNED_BYTE], [GL_UNSIGNED_SHORT] или [GL_UNSIGNED_INT]
|
* [GL_UNSIGNED_BYTE], [GL_UNSIGNED_SHORT] или [GL_UNSIGNED_INT]
|
||||||
*/
|
*/
|
||||||
var indexType: Int = chooseIndexType(initialCapacity)
|
var indexType: Int = chooseIndexType(indexCapacity)
|
||||||
private set
|
private set
|
||||||
var indexSize: Int = indexSize(indexType)
|
var indexSize: Int = indexSize(indexType)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
/**
|
private var vertexMemory = ByteBuffer.allocateDirect(vertexCapacity * attributes.stride).also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
||||||
* В элементах, не вершинах
|
private var indexMemory = ByteBuffer.allocateDirect(indexCapacity * indexSize).also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
||||||
*/
|
|
||||||
private var capacity = initialCapacity
|
|
||||||
private var vertexMemory = ByteBuffer.allocateDirect(capacity * attributes.stride * type.elements).also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
|
||||||
private var indexMemory = ByteBuffer.allocateDirect(capacity * indexSize * type.indices.size).also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
|
||||||
private var indexWriter = writer(indexType)
|
private var indexWriter = writer(indexType)
|
||||||
|
|
||||||
private var inVertex = false
|
private var inVertex = false
|
||||||
@ -76,16 +81,105 @@ class VertexBuilder(
|
|||||||
|
|
||||||
private var elementVertices = 0
|
private var elementVertices = 0
|
||||||
|
|
||||||
var vertexCount = 0
|
var vertexCount = 0 // distinct vertices
|
||||||
|
private set
|
||||||
|
var indexCount = 0 // distinct indices
|
||||||
|
private set
|
||||||
|
var elementCount = 0 // GeometryType specific (quads, triangles, lines), less than or equal (points) to vertexCount
|
||||||
private set
|
private set
|
||||||
|
|
||||||
var indexCount = 0
|
private fun ensureCapacity() {
|
||||||
private set
|
val mode = mode ?: return
|
||||||
|
|
||||||
var elementCount = 0
|
if (indexCapacity < indexCount + mode.indices.size) {
|
||||||
private set
|
indexCapacity = (indexCapacity * 2).coerceAtLeast(indexCount + mode.indices.size)
|
||||||
|
|
||||||
fun begin() {
|
// probable double recreation if we also resize vertex array AND it ends up
|
||||||
|
val indexPos = indexMemory.position()
|
||||||
|
val indexMemory = ByteBuffer.allocateDirect(indexCapacity * indexSize).also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
||||||
|
this.indexMemory.position(0)
|
||||||
|
indexMemory.put(this.indexMemory)
|
||||||
|
indexMemory.position(indexPos)
|
||||||
|
|
||||||
|
this.indexMemory = indexMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertexCapacity < vertexCount + mode.elements) {
|
||||||
|
vertexCapacity = (vertexCapacity * 2).coerceAtLeast(vertexCount + mode.elements)
|
||||||
|
|
||||||
|
val indexType = chooseIndexType(vertexCapacity)
|
||||||
|
val indexSize = indexSize(indexType)
|
||||||
|
|
||||||
|
val vertexPos = vertexMemory.position()
|
||||||
|
val vertexMemory = ByteBuffer.allocateDirect(vertexCapacity * attributes.stride).also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
||||||
|
|
||||||
|
this.vertexMemory.position(0)
|
||||||
|
vertexMemory.put(this.vertexMemory)
|
||||||
|
vertexMemory.position(vertexPos)
|
||||||
|
|
||||||
|
if (indexType != this.indexType) {
|
||||||
|
val indexMemory = ByteBuffer.allocateDirect(vertexCapacity * indexSize).also { it.order(ByteOrder.LITTLE_ENDIAN) }
|
||||||
|
|
||||||
|
when (this.indexType) {
|
||||||
|
GL_UNSIGNED_BYTE -> {
|
||||||
|
when (indexType) {
|
||||||
|
GL_UNSIGNED_BYTE -> throw IllegalArgumentException()
|
||||||
|
GL_UNSIGNED_SHORT -> {
|
||||||
|
this.indexMemory.position(0)
|
||||||
|
|
||||||
|
for (i in 0 until indexCount) {
|
||||||
|
indexMemory.putShort(this.indexMemory.get().toShort())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GL_UNSIGNED_INT -> {
|
||||||
|
this.indexMemory.position(0)
|
||||||
|
|
||||||
|
for (i in 0 until indexCount) {
|
||||||
|
indexMemory.putInt(this.indexMemory.get().toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GL_UNSIGNED_SHORT -> {
|
||||||
|
when (indexType) {
|
||||||
|
GL_UNSIGNED_BYTE -> throw IllegalArgumentException()
|
||||||
|
GL_UNSIGNED_SHORT -> throw IllegalArgumentException()
|
||||||
|
GL_UNSIGNED_INT -> {
|
||||||
|
this.indexMemory.position(0)
|
||||||
|
|
||||||
|
for (i in 0 until indexCount) {
|
||||||
|
indexMemory.putInt(this.indexMemory.getShort().toInt())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> throw IllegalArgumentException()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.indexMemory = indexMemory
|
||||||
|
this.indexType = indexType
|
||||||
|
this.indexSize = indexSize
|
||||||
|
}
|
||||||
|
|
||||||
|
this.vertexMemory = vertexMemory
|
||||||
|
this.indexWriter = writer(indexType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mode(mode: GeometryType): VertexBuilder {
|
||||||
|
check(!inVertex) { "Can't change buffer geometry type during vertex construction" }
|
||||||
|
check(elementVertices == 0) { "Can't change buffer geometry type while not having fully built current element" }
|
||||||
|
this.mode = mode
|
||||||
|
ensureCapacity()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mode() = mode
|
||||||
|
|
||||||
|
fun begin(mode: GeometryType? = defaultMode): VertexBuilder {
|
||||||
|
this.mode = mode
|
||||||
inVertex = false
|
inVertex = false
|
||||||
attributeIndex = 0
|
attributeIndex = 0
|
||||||
elementIndexOffset = 0
|
elementIndexOffset = 0
|
||||||
@ -94,6 +188,8 @@ class VertexBuilder(
|
|||||||
elementCount = 0
|
elementCount = 0
|
||||||
vertexMemory.position(0)
|
vertexMemory.position(0)
|
||||||
indexMemory.position(0)
|
indexMemory.position(0)
|
||||||
|
ensureCapacity()
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkBounds() {
|
private fun checkBounds() {
|
||||||
@ -102,20 +198,24 @@ class VertexBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun expect(type: GLType) {
|
fun expect(type: GLType): VertexBuilder {
|
||||||
checkBounds()
|
checkBounds()
|
||||||
|
|
||||||
if (attributes[attributeIndex].glType != type) {
|
if (attributes[attributeIndex].glType != type) {
|
||||||
throw IllegalStateException("Expected attribute type $type, got ${attributes[attributeIndex].name}[${attributes[attributeIndex].glType}] (at position $attributeIndex)")
|
throw IllegalStateException("Expected attribute type $type, got ${attributes[attributeIndex].name}[${attributes[attributeIndex].glType}] (at position $attributeIndex)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun expect(name: String) {
|
fun expect(name: String): VertexBuilder {
|
||||||
checkBounds()
|
checkBounds()
|
||||||
|
|
||||||
if (attributes[attributeIndex].name != name) {
|
if (attributes[attributeIndex].name != name) {
|
||||||
throw IllegalStateException("Expected attribute name $name, got ${attributes[attributeIndex].name}[${attributes[attributeIndex].glType}] (at position $attributeIndex)")
|
throw IllegalStateException("Expected attribute name $name, got ${attributes[attributeIndex].name}[${attributes[attributeIndex].glType}] (at position $attributeIndex)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun upload(vbo: VertexBufferObject, ebo: VertexBufferObject, drawType: Int = GL46.GL_DYNAMIC_DRAW) {
|
fun upload(vbo: VertexBufferObject, ebo: VertexBufferObject, drawType: Int = GL46.GL_DYNAMIC_DRAW) {
|
||||||
@ -124,7 +224,7 @@ class VertexBuilder(
|
|||||||
|
|
||||||
end()
|
end()
|
||||||
|
|
||||||
check(elementVertices == 0) { "Not fully built vertex element ($type requires ${type.elements} vertex points to be present, yet last strip has only $elementVertices elements)" }
|
check(elementVertices == 0) { "Not fully built vertex element ($mode requires ${mode?.elements} vertex points to be present, yet last strip has only $elementVertices elements)" }
|
||||||
|
|
||||||
val vertexPos = vertexMemory.position()
|
val vertexPos = vertexMemory.position()
|
||||||
val elementPos = indexMemory.position()
|
val elementPos = indexMemory.position()
|
||||||
@ -140,100 +240,36 @@ class VertexBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun end() {
|
fun end() {
|
||||||
if (inVertex) {
|
if (!inVertex) return
|
||||||
inVertex = false
|
|
||||||
|
|
||||||
if (attributeIndex != attributes.size) {
|
val mode = mode!!
|
||||||
throw IllegalStateException("Unfinished vertex, we are at $attributeIndex, while we have ${attributes.size} attributes")
|
inVertex = false
|
||||||
|
|
||||||
|
if (attributeIndex != attributes.size) {
|
||||||
|
throw IllegalStateException("Unfinished vertex, we are at $attributeIndex, while we have ${attributes.size} attributes")
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexCount++
|
||||||
|
elementVertices++
|
||||||
|
|
||||||
|
if (elementVertices == mode.elements) {
|
||||||
|
elementCount++
|
||||||
|
elementVertices = 0
|
||||||
|
|
||||||
|
for (index in mode.indices.indices) {
|
||||||
|
indexWriter.write(indexMemory, mode.indices.getInt(index) + elementIndexOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexCount++
|
elementIndexOffset += mode.elements
|
||||||
elementVertices++
|
indexCount += mode.indices.size
|
||||||
|
|
||||||
if (elementVertices == type.elements) {
|
ensureCapacity()
|
||||||
elementCount++
|
|
||||||
elementVertices = 0
|
|
||||||
|
|
||||||
for (index in type.indices) {
|
|
||||||
indexWriter.write(indexMemory, index + elementIndexOffset)
|
|
||||||
}
|
|
||||||
|
|
||||||
elementIndexOffset += type.elements
|
|
||||||
indexCount += type.indices.size
|
|
||||||
|
|
||||||
if (capacity <= elementCount) {
|
|
||||||
check(this.vertexMemory.position() == this.vertexMemory.capacity()) { "${this.vertexMemory.position()} != ${this.vertexMemory.capacity()}" }
|
|
||||||
check(this.indexMemory.position() == this.indexMemory.capacity()) { "${this.indexMemory.position()} != ${this.indexMemory.capacity()}" }
|
|
||||||
|
|
||||||
val capacity = capacity * 2
|
|
||||||
val indexType = chooseIndexType(capacity)
|
|
||||||
val indexSize = indexSize(indexType)
|
|
||||||
|
|
||||||
val vertexMemory = ByteBuffer.allocateDirect(capacity * attributes.stride * type.elements)
|
|
||||||
vertexMemory.order(ByteOrder.LITTLE_ENDIAN)
|
|
||||||
|
|
||||||
this.vertexMemory.position(0)
|
|
||||||
vertexMemory.put(this.vertexMemory)
|
|
||||||
|
|
||||||
val indexMemory = ByteBuffer.allocateDirect(capacity * indexSize * type.indices.size)
|
|
||||||
indexMemory.order(ByteOrder.LITTLE_ENDIAN)
|
|
||||||
|
|
||||||
if (indexType != this.indexType) {
|
|
||||||
when (this.indexType) {
|
|
||||||
GL_UNSIGNED_BYTE -> {
|
|
||||||
when (indexType) {
|
|
||||||
GL_UNSIGNED_BYTE -> throw IllegalArgumentException()
|
|
||||||
GL_UNSIGNED_SHORT -> {
|
|
||||||
this.indexMemory.position(0)
|
|
||||||
|
|
||||||
for (i in 0 until this.capacity) {
|
|
||||||
indexMemory.putShort(this.indexMemory.get().toShort())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GL_UNSIGNED_INT -> {
|
|
||||||
this.indexMemory.position(0)
|
|
||||||
|
|
||||||
for (i in 0 until this.capacity) {
|
|
||||||
indexMemory.putInt(this.indexMemory.get().toInt())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GL_UNSIGNED_SHORT -> {
|
|
||||||
when (indexType) {
|
|
||||||
GL_UNSIGNED_BYTE -> throw IllegalArgumentException()
|
|
||||||
GL_UNSIGNED_SHORT -> throw IllegalArgumentException()
|
|
||||||
GL_UNSIGNED_INT -> {
|
|
||||||
this.indexMemory.position(0)
|
|
||||||
|
|
||||||
for (i in 0 until this.capacity) {
|
|
||||||
indexMemory.putInt(this.indexMemory.getShort().toInt())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> throw IllegalArgumentException()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.indexMemory.position(0)
|
|
||||||
indexMemory.put(this.indexMemory)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.capacity = capacity
|
|
||||||
this.vertexMemory = vertexMemory
|
|
||||||
this.indexMemory = indexMemory
|
|
||||||
this.indexType = indexType
|
|
||||||
this.indexSize = indexSize
|
|
||||||
this.indexWriter = writer(indexType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun vertex(): VertexBuilder {
|
fun vertex(): VertexBuilder {
|
||||||
end()
|
end()
|
||||||
|
checkNotNull(mode) { "No builder mode is set" }
|
||||||
|
|
||||||
inVertex = true
|
inVertex = true
|
||||||
attributeIndex = 0
|
attributeIndex = 0
|
||||||
@ -319,7 +355,7 @@ class VertexBuilder(
|
|||||||
y1: Float,
|
y1: Float,
|
||||||
lambda: QuadVertexTransformer = EMPTY_VERTEX_TRANSFORM
|
lambda: QuadVertexTransformer = EMPTY_VERTEX_TRANSFORM
|
||||||
): VertexBuilder {
|
): VertexBuilder {
|
||||||
check(type.elements == 4) { "Currently building $type" }
|
check(mode?.elements == 4) { "Currently building $mode" }
|
||||||
|
|
||||||
lambda(vertex().pushVec2f(x0, y0), 0).end()
|
lambda(vertex().pushVec2f(x0, y0), 0).end()
|
||||||
lambda(vertex().pushVec2f(x1, y0), 1).end()
|
lambda(vertex().pushVec2f(x1, y0), 1).end()
|
||||||
@ -339,7 +375,7 @@ class VertexBuilder(
|
|||||||
angle: Double,
|
angle: Double,
|
||||||
lambda: QuadVertexTransformer = EMPTY_VERTEX_TRANSFORM
|
lambda: QuadVertexTransformer = EMPTY_VERTEX_TRANSFORM
|
||||||
): VertexBuilder {
|
): VertexBuilder {
|
||||||
check(type.elements == 4) { "Currently building $type" }
|
check(mode?.elements == 4) { "Currently building $mode" }
|
||||||
|
|
||||||
val s = sin(angle).toFloat()
|
val s = sin(angle).toFloat()
|
||||||
val c = cos(angle).toFloat()
|
val c = cos(angle).toFloat()
|
||||||
@ -370,7 +406,7 @@ class VertexBuilder(
|
|||||||
z: Float,
|
z: Float,
|
||||||
lambda: QuadVertexTransformer = EMPTY_VERTEX_TRANSFORM
|
lambda: QuadVertexTransformer = EMPTY_VERTEX_TRANSFORM
|
||||||
): VertexBuilder {
|
): VertexBuilder {
|
||||||
check(type.elements == 4) { "Currently building $type" }
|
check(mode?.elements == 4) { "Currently building $mode" }
|
||||||
|
|
||||||
lambda(vertex().pushVec3f(x0, y0, z), 0).end()
|
lambda(vertex().pushVec3f(x0, y0, z), 0).end()
|
||||||
lambda(vertex().pushVec3f(x1, y0, z), 1).end()
|
lambda(vertex().pushVec3f(x1, y0, z), 1).end()
|
||||||
@ -391,7 +427,7 @@ class VertexBuilder(
|
|||||||
angle: Double,
|
angle: Double,
|
||||||
lambda: QuadVertexTransformer = EMPTY_VERTEX_TRANSFORM
|
lambda: QuadVertexTransformer = EMPTY_VERTEX_TRANSFORM
|
||||||
): VertexBuilder {
|
): VertexBuilder {
|
||||||
check(type.elements == 4) { "Currently building $type" }
|
check(mode?.elements == 4) { "Currently building $mode" }
|
||||||
|
|
||||||
val s = sin(angle).toFloat()
|
val s = sin(angle).toFloat()
|
||||||
val c = cos(angle).toFloat()
|
val c = cos(angle).toFloat()
|
||||||
|
@ -16,7 +16,7 @@ class MultiMeshBuilder {
|
|||||||
fun get(config: RenderConfig<*>, layer: Int): VertexBuilder {
|
fun get(config: RenderConfig<*>, layer: Int): VertexBuilder {
|
||||||
return meshes.computeIfAbsent(config, Reference2ObjectFunction {
|
return meshes.computeIfAbsent(config, Reference2ObjectFunction {
|
||||||
Int2ObjectOpenHashMap()
|
Int2ObjectOpenHashMap()
|
||||||
}).computeIfAbsent(layer, Int2ObjectFunction { Entry(config, VertexBuilder(config.program.attributes, GeometryType.QUADS), layer) }).builder
|
}).computeIfAbsent(layer, Int2ObjectFunction { Entry(config, VertexBuilder(config.program.attributes), layer) }).builder
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clear() = meshes.clear()
|
fun clear() = meshes.clear()
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package ru.dbotthepony.kstarbound.client.render
|
package ru.dbotthepony.kstarbound.client.render
|
||||||
|
|
||||||
import ru.dbotthepony.kstarbound.client.gl.GLStateTracker
|
|
||||||
import ru.dbotthepony.kstarbound.client.gl.shader.GLShaderProgram
|
import ru.dbotthepony.kstarbound.client.gl.shader.GLShaderProgram
|
||||||
import ru.dbotthepony.kvector.arrays.Matrix4f
|
import ru.dbotthepony.kvector.arrays.Matrix4f
|
||||||
|
|
||||||
abstract class RenderConfig<out T : GLShaderProgram>(val state: GLStateTracker, val program: T) {
|
abstract class RenderConfig<out T : GLShaderProgram>(val program: T) {
|
||||||
|
val state get() = program.state
|
||||||
|
|
||||||
open fun setup(transform: Matrix4f = state.matrixStack.last()) {
|
open fun setup(transform: Matrix4f = state.matrixStack.last()) {
|
||||||
program.use()
|
program.use()
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ class TileRenderers(val client: StarboundClient) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class Config(private val texture: GLTexture2D, private val color: RGBAColor) : RenderConfig<GLTileProgram>(state, state.programs.tile) {
|
private inner class Config(private val texture: GLTexture2D, private val color: RGBAColor) : RenderConfig<GLTileProgram>(state.programs.tile) {
|
||||||
override fun setup(transform: Matrix4f) {
|
override fun setup(transform: Matrix4f) {
|
||||||
super.setup(transform)
|
super.setup(transform)
|
||||||
state.activeTexture = 0
|
state.activeTexture = 0
|
||||||
@ -168,7 +168,7 @@ class TileRenderer(val renderers: TileRenderers, val def: IRenderableTile) {
|
|||||||
renderers.foreground(state.loadTexture(renderPiece.piece.texture!!))
|
renderers.foreground(state.loadTexture(renderPiece.piece.texture!!))
|
||||||
}
|
}
|
||||||
|
|
||||||
tesselateAt(self, renderPiece.piece, getter, meshBuilder.get(program, def.renderParameters.zLevel), pos, renderPiece.offset, isModifier)
|
tesselateAt(self, renderPiece.piece, getter, meshBuilder.get(program, def.renderParameters.zLevel).mode(GeometryType.QUADS), pos, renderPiece.offset, isModifier)
|
||||||
} else {
|
} else {
|
||||||
tesselateAt(self, renderPiece.piece, getter, thisBuilder, pos, renderPiece.offset, isModifier)
|
tesselateAt(self, renderPiece.piece, getter, thisBuilder, pos, renderPiece.offset, isModifier)
|
||||||
}
|
}
|
||||||
@ -206,7 +206,7 @@ class TileRenderer(val renderers: TileRenderers, val def: IRenderableTile) {
|
|||||||
// то мы просто не можем его отрисовать
|
// то мы просто не можем его отрисовать
|
||||||
val template = def.renderTemplate.value ?: return
|
val template = def.renderTemplate.value ?: return
|
||||||
|
|
||||||
val vertexBuilder = meshBuilder.get(if (background) bakedBackgroundProgramState else bakedProgramState, def.renderParameters.zLevel)
|
val vertexBuilder = meshBuilder.get(if (background) bakedBackgroundProgramState else bakedProgramState, def.renderParameters.zLevel).mode(GeometryType.QUADS)
|
||||||
|
|
||||||
for ((_, matcher) in template.matches) {
|
for ((_, matcher) in template.matches) {
|
||||||
for (matchPiece in matcher) {
|
for (matchPiece in matcher) {
|
||||||
|
Loading…
Reference in New Issue
Block a user