Тесселятор тайлов теперь знает про haltOnMatch
This commit is contained in:
parent
f0af2d5a8e
commit
4bd1cae5e1
@ -162,6 +162,14 @@ private fun loop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
for (x in 0 .. 24) {
|
||||||
|
for (y in 0 .. 24) {
|
||||||
|
chunk[x, y] = Starbound.getTileDefinition("sewerpipe")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
val chunkRenderer = ChunkRenderer(state, chunk)
|
val chunkRenderer = ChunkRenderer(state, chunk)
|
||||||
chunkRenderer.tesselateStatic()
|
chunkRenderer.tesselateStatic()
|
||||||
chunkRenderer.uploadStatic()
|
chunkRenderer.uploadStatic()
|
||||||
|
@ -188,8 +188,8 @@ sealed class RenderRule(params: Map<String, Any>) {
|
|||||||
"EqualsSelf" -> RenderRuleEqualsSelf(params)
|
"EqualsSelf" -> RenderRuleEqualsSelf(params)
|
||||||
"Shadows" -> RenderRuleShadows(params)
|
"Shadows" -> RenderRuleShadows(params)
|
||||||
|
|
||||||
// неизвестно что оно делает
|
// неизвестно что оно делает, но вероятнее всего, есть ли там что либо в принципе
|
||||||
"Connects" -> AlwaysFailingRenderRule(params)
|
"Connects" -> RenderRuleConnects(params)
|
||||||
|
|
||||||
else -> throw IllegalArgumentException("Unknown render rule '$name'")
|
else -> throw IllegalArgumentException("Unknown render rule '$name'")
|
||||||
}
|
}
|
||||||
@ -236,6 +236,15 @@ class RenderRuleShadows(params: Map<String, Any>) : RenderRule(params) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RenderRuleConnects(params: Map<String, Any>) : RenderRule(params) {
|
||||||
|
override fun test(getter: IChunk, thisRef: TileDefinition, thisPos: Vector2i, offsetPos: Vector2i): Boolean {
|
||||||
|
if (inverse)
|
||||||
|
return getter[thisPos + offsetPos] == null
|
||||||
|
|
||||||
|
return getter[thisPos + offsetPos] != null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class AlwaysPassingRenderRule(params: Map<String, Any>) : RenderRule(params) {
|
class AlwaysPassingRenderRule(params: Map<String, Any>) : RenderRule(params) {
|
||||||
override fun test(getter: IChunk, thisRef: TileDefinition, thisPos: Vector2i, offsetPos: Vector2i): Boolean {
|
override fun test(getter: IChunk, thisRef: TileDefinition, thisPos: Vector2i, offsetPos: Vector2i): Boolean {
|
||||||
return inverse
|
return inverse
|
||||||
@ -345,10 +354,19 @@ data class TileRenderMatchPositioned(
|
|||||||
data class TileRenderMatchPiece(
|
data class TileRenderMatchPiece(
|
||||||
val pieces: List<TileRenderMatchedPiece>,
|
val pieces: List<TileRenderMatchedPiece>,
|
||||||
val matchAllPoints: List<TileRenderMatchPositioned>,
|
val matchAllPoints: List<TileRenderMatchPositioned>,
|
||||||
val subMatches: List<TileRenderMatchPiece>
|
val matchAnyPoints: List<TileRenderMatchPositioned>,
|
||||||
|
val subMatches: List<TileRenderMatchPiece>,
|
||||||
|
val haltOnSubMatch: Boolean,
|
||||||
|
val haltOnMatch: Boolean
|
||||||
) {
|
) {
|
||||||
|
init {
|
||||||
|
if (matchAnyPoints.isNotEmpty() || matchAllPoints.isNotEmpty()) {
|
||||||
|
require(matchAnyPoints.isEmpty() || matchAllPoints.isEmpty()) { "Both matchAllPoints and matchAnyPoints are present, this is not valid." }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Возвращает, сработали ли ВСЕ [matchAllPoints]
|
* Возвращает, сработали ли ВСЕ [matchAllPoints] или ЛЮБОЙ ИЗ [matchAnyPoints]
|
||||||
*
|
*
|
||||||
* Если хотя бы один из них вернул false, весь тест возвращает false
|
* Если хотя бы один из них вернул false, весь тест возвращает false
|
||||||
*
|
*
|
||||||
@ -361,7 +379,17 @@ data class TileRenderMatchPiece(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
if (matchAnyPoints.isEmpty()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for (matcher in matchAnyPoints) {
|
||||||
|
if (matcher.test(getter, thisRef, thisPos)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -386,6 +414,16 @@ data class TileRenderMatchPiece(
|
|||||||
return@let ImmutableList.copyOf(list)
|
return@let ImmutableList.copyOf(list)
|
||||||
} ?: listOf()
|
} ?: listOf()
|
||||||
|
|
||||||
|
val matchAnyPoints = input["matchAnyPoints"]?.asJsonArray?.let {
|
||||||
|
val list = ArrayList<TileRenderMatchPositioned>()
|
||||||
|
|
||||||
|
for (thisPiece in it) {
|
||||||
|
list.add(TileRenderMatchPositioned.fromJson(thisPiece.asJsonArray, rulePieces))
|
||||||
|
}
|
||||||
|
|
||||||
|
return@let ImmutableList.copyOf(list)
|
||||||
|
} ?: listOf()
|
||||||
|
|
||||||
val subMatches = input["subMatches"]?.asJsonArray?.let {
|
val subMatches = input["subMatches"]?.asJsonArray?.let {
|
||||||
val list = ArrayList<TileRenderMatchPiece>()
|
val list = ArrayList<TileRenderMatchPiece>()
|
||||||
|
|
||||||
@ -396,7 +434,18 @@ data class TileRenderMatchPiece(
|
|||||||
return@let ImmutableList.copyOf(list)
|
return@let ImmutableList.copyOf(list)
|
||||||
} ?: listOf()
|
} ?: listOf()
|
||||||
|
|
||||||
return TileRenderMatchPiece(pieces, matchAllPoints, subMatches)
|
val haltOnSubMatch = input["haltOnSubMatch"]?.asBoolean ?: false
|
||||||
|
val haltOnMatch = input["haltOnMatch"]?.asBoolean ?: false
|
||||||
|
|
||||||
|
return TileRenderMatchPiece(
|
||||||
|
pieces = pieces,
|
||||||
|
matchAllPoints = matchAllPoints,
|
||||||
|
matchAnyPoints = matchAnyPoints,
|
||||||
|
subMatches = subMatches,
|
||||||
|
|
||||||
|
haltOnSubMatch = haltOnSubMatch,
|
||||||
|
haltOnMatch = haltOnMatch,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,8 +459,12 @@ data class TileRenderMatch(
|
|||||||
val name = input[0].asString
|
val name = input[0].asString
|
||||||
val pieces = ArrayList<TileRenderMatchPiece>()
|
val pieces = ArrayList<TileRenderMatchPiece>()
|
||||||
|
|
||||||
for (elem in input[1].asJsonArray) {
|
try {
|
||||||
pieces.add(TileRenderMatchPiece.fromJson(elem.asJsonObject, tilePieces, rulePieces))
|
for (elem in input[1].asJsonArray) {
|
||||||
|
pieces.add(TileRenderMatchPiece.fromJson(elem.asJsonObject, tilePieces, rulePieces))
|
||||||
|
}
|
||||||
|
} catch(err: Throwable) {
|
||||||
|
throw IllegalArgumentException("Failed to deserialize render match rule $name", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return TileRenderMatch(name, ImmutableList.copyOf(pieces))
|
return TileRenderMatch(name, ImmutableList.copyOf(pieces))
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.kstarbound.render
|
package ru.dbotthepony.kstarbound.render
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
import org.lwjgl.glfw.GLFW.glfwGetTime
|
import org.lwjgl.glfw.GLFW.glfwGetTime
|
||||||
import org.lwjgl.opengl.GL46.*
|
import org.lwjgl.opengl.GL46.*
|
||||||
import ru.dbotthepony.kstarbound.Starbound
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
@ -12,7 +13,10 @@ import ru.dbotthepony.kstarbound.math.Vector2i
|
|||||||
import ru.dbotthepony.kstarbound.world.IChunk
|
import ru.dbotthepony.kstarbound.world.IChunk
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
data class TileLayer(val bakedProgramState: BakedProgramState, val vertexBuilder: VertexBuilder, val zPos: Int)
|
data class TileLayer(
|
||||||
|
val bakedProgramState: BakedProgramState,
|
||||||
|
val vertexBuilder: VertexBuilder,
|
||||||
|
val zPos: Int)
|
||||||
|
|
||||||
class TileLayerList {
|
class TileLayerList {
|
||||||
private val layers = HashMap<BakedProgramState, ArrayList<TileLayer>>()
|
private val layers = HashMap<BakedProgramState, ArrayList<TileLayer>>()
|
||||||
@ -63,6 +67,7 @@ class TileRenderers(val state: GLStateTracker) {
|
|||||||
override fun setup() {
|
override fun setup() {
|
||||||
super.setup()
|
super.setup()
|
||||||
state.activeTexture = 0
|
state.activeTexture = 0
|
||||||
|
// state.depthTest = true
|
||||||
program["_texture"] = 0
|
program["_texture"] = 0
|
||||||
texture.bind()
|
texture.bind()
|
||||||
texture.textureMagFilter = GL_NEAREST
|
texture.textureMagFilter = GL_NEAREST
|
||||||
@ -94,12 +99,19 @@ class TileRenderers(val state: GLStateTracker) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum class TileRenderTesselateResult {
|
||||||
|
NO_MATCH,
|
||||||
|
CONTINUE,
|
||||||
|
HALT
|
||||||
|
}
|
||||||
|
|
||||||
class TileRenderer(val state: GLStateTracker, val tile: TileDefinition) {
|
class TileRenderer(val state: GLStateTracker, val tile: TileDefinition) {
|
||||||
val texture = state.loadNamedTexture(tile.render.texture).also {
|
val texture = state.loadNamedTexture(tile.render.texture).also {
|
||||||
it.textureMagFilter = GL_NEAREST
|
it.textureMagFilter = GL_NEAREST
|
||||||
}
|
}
|
||||||
|
|
||||||
val bakedProgramState = state.tileRenderers.simpleProgram(texture)
|
val bakedProgramState = state.tileRenderers.simpleProgram(texture)
|
||||||
|
// private var notifiedDepth = false
|
||||||
|
|
||||||
private fun tesselateAt(piece: TileRenderPiece, getter: IChunk, builder: VertexBuilder, pos: Vector2i, offset: Vector2i = Vector2i.ZERO) {
|
private fun tesselateAt(piece: TileRenderPiece, getter: IChunk, builder: VertexBuilder, pos: Vector2i, offset: Vector2i = Vector2i.ZERO) {
|
||||||
val fx = pos.x.toFloat()
|
val fx = pos.x.toFloat()
|
||||||
@ -121,10 +133,18 @@ class TileRenderer(val state: GLStateTracker, val tile: TileDefinition) {
|
|||||||
d += offset.y / BASELINE_TEXTURE_SIZE
|
d += offset.y / BASELINE_TEXTURE_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!notifiedDepth && tile.render.zLevel >= 5900) {
|
||||||
|
LOGGER.warn("Tile {} has out of bounds zLevel of {}", tile.materialName, tile.render.zLevel)
|
||||||
|
notifiedDepth = true
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (tile.render.variants == 0 || piece.texture != null || piece.variantStride == null) {
|
if (tile.render.variants == 0 || piece.texture != null || piece.variantStride == null) {
|
||||||
val (u0, v0) = texture.pixelToUV(piece.texturePosition)
|
val (u0, v0) = texture.pixelToUV(piece.texturePosition)
|
||||||
val (u1, v1) = texture.pixelToUV(piece.texturePosition + piece.textureSize)
|
val (u1, v1) = texture.pixelToUV(piece.texturePosition + piece.textureSize)
|
||||||
|
|
||||||
|
//builder.quadZ(a, b, c, d, tile.render.zLevel.toFloat() + 200f, VertexTransformers.uv(u0, v1, u1, v0))
|
||||||
builder.quadZ(a, b, c, d, Z_LEVEL, VertexTransformers.uv(u0, v1, u1, v0))
|
builder.quadZ(a, b, c, d, Z_LEVEL, VertexTransformers.uv(u0, v1, u1, v0))
|
||||||
} else {
|
} else {
|
||||||
val variant = (getter.randomDoubleFor(pos) * tile.render.variants).toInt()
|
val variant = (getter.randomDoubleFor(pos) * tile.render.variants).toInt()
|
||||||
@ -132,15 +152,16 @@ class TileRenderer(val state: GLStateTracker, val tile: TileDefinition) {
|
|||||||
val (u0, v0) = texture.pixelToUV(piece.texturePosition + piece.variantStride * variant)
|
val (u0, v0) = texture.pixelToUV(piece.texturePosition + piece.variantStride * variant)
|
||||||
val (u1, v1) = texture.pixelToUV(piece.texturePosition + piece.textureSize + piece.variantStride * variant)
|
val (u1, v1) = texture.pixelToUV(piece.texturePosition + piece.textureSize + piece.variantStride * variant)
|
||||||
|
|
||||||
|
//builder.quadZ(a, b, c, d, tile.render.zLevel.toFloat() + 200f, VertexTransformers.uv(u0, v1, u1, v0))
|
||||||
builder.quadZ(a, b, c, d, Z_LEVEL, VertexTransformers.uv(u0, v1, u1, v0))
|
builder.quadZ(a, b, c, d, Z_LEVEL, VertexTransformers.uv(u0, v1, u1, v0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tesselatePiece(matchPiece: TileRenderMatchPiece, getter: IChunk, layers: TileLayerList, pos: Vector2i, thisBuilder: VertexBuilder) {
|
private fun tesselatePiece(matchPiece: TileRenderMatchPiece, getter: IChunk, layers: TileLayerList, pos: Vector2i, thisBuilder: VertexBuilder): TileRenderTesselateResult {
|
||||||
if (matchPiece.test(getter, tile, pos)) {
|
if (matchPiece.test(getter, tile, pos)) {
|
||||||
for (renderPiece in matchPiece.pieces) {
|
for (renderPiece in matchPiece.pieces) {
|
||||||
if (renderPiece.piece.texture != null) {
|
if (renderPiece.piece.texture != null) {
|
||||||
tesselateAt(renderPiece.piece, getter, layers.getLayer(state.tileRenderers.simpleProgram(state.loadNamedTexture(renderPiece.piece.texture)), tile.render.zLevel - 1) {
|
tesselateAt(renderPiece.piece, getter, layers.getLayer(state.tileRenderers.simpleProgram(state.loadNamedTexture(renderPiece.piece.texture)), tile.render.zLevel) {
|
||||||
return@getLayer VertexBuilder(GLFlatAttributeList.VERTEX_TEXTURE, VertexType.QUADS)
|
return@getLayer VertexBuilder(GLFlatAttributeList.VERTEX_TEXTURE, VertexType.QUADS)
|
||||||
}, pos, renderPiece.offset)
|
}, pos, renderPiece.offset)
|
||||||
} else {
|
} else {
|
||||||
@ -149,9 +170,21 @@ class TileRenderer(val state: GLStateTracker, val tile: TileDefinition) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (subPiece in matchPiece.subMatches) {
|
for (subPiece in matchPiece.subMatches) {
|
||||||
tesselatePiece(subPiece, getter, layers, pos, thisBuilder)
|
val matched = tesselatePiece(subPiece, getter, layers, pos, thisBuilder)
|
||||||
|
|
||||||
|
if (matched == TileRenderTesselateResult.HALT || matched == TileRenderTesselateResult.CONTINUE && matchPiece.haltOnSubMatch) {
|
||||||
|
return TileRenderTesselateResult.HALT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (matchPiece.haltOnMatch) {
|
||||||
|
return TileRenderTesselateResult.HALT
|
||||||
|
}
|
||||||
|
|
||||||
|
return TileRenderTesselateResult.CONTINUE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TileRenderTesselateResult.NO_MATCH
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,7 +207,11 @@ class TileRenderer(val state: GLStateTracker, val tile: TileDefinition) {
|
|||||||
|
|
||||||
for ((_, matcher) in tile.render.renderTemplate.matches) {
|
for ((_, matcher) in tile.render.renderTemplate.matches) {
|
||||||
for (matchPiece in matcher.pieces) {
|
for (matchPiece in matcher.pieces) {
|
||||||
tesselatePiece(matchPiece, getter, layers, pos, builder)
|
val matched = tesselatePiece(matchPiece, getter, layers, pos, builder)
|
||||||
|
|
||||||
|
if (matched == TileRenderTesselateResult.HALT) {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,5 +312,6 @@ class TileRenderer(val state: GLStateTracker, val tile: TileDefinition) {
|
|||||||
companion object {
|
companion object {
|
||||||
const val BASELINE_TEXTURE_SIZE = 8f
|
const val BASELINE_TEXTURE_SIZE = 8f
|
||||||
const val Z_LEVEL = 1f
|
const val Z_LEVEL = 1f
|
||||||
|
private val LOGGER = LogManager.getLogger()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,10 @@ in vec2 _uv_out;
|
|||||||
out vec4 _color_out;
|
out vec4 _color_out;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
_color_out = texture(_texture, _uv_out);
|
vec4 texel = texture(_texture, _uv_out);
|
||||||
//_color_out = vec4(1.0, 1.0, 1.0, 1.0);
|
|
||||||
|
//if (texel.a < 0.5)
|
||||||
|
// discard;
|
||||||
|
|
||||||
|
_color_out = texel;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user