rendering: improve outline

This commit is contained in:
Lukas 2021-05-16 17:28:38 +02:00
parent f62fc6a11e
commit e8fcf67610
3 changed files with 43 additions and 13 deletions

View File

@ -23,10 +23,14 @@ import de.bixilon.minosoft.gui.rendering.RenderWindow
import de.bixilon.minosoft.gui.rendering.Renderer import de.bixilon.minosoft.gui.rendering.Renderer
import de.bixilon.minosoft.gui.rendering.RendererBuilder import de.bixilon.minosoft.gui.rendering.RendererBuilder
import de.bixilon.minosoft.gui.rendering.chunk.VoxelShape import de.bixilon.minosoft.gui.rendering.chunk.VoxelShape
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.ElementRenderer
import de.bixilon.minosoft.gui.rendering.shader.Shader import de.bixilon.minosoft.gui.rendering.shader.Shader
import de.bixilon.minosoft.gui.rendering.util.VecUtil
import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset import de.bixilon.minosoft.gui.rendering.util.VecUtil.getWorldOffset
import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.network.connection.PlayConnection
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.BitByte.isBit
import de.bixilon.minosoft.util.MMath.positiveNegative
import glm_.vec3.Vec3 import glm_.vec3.Vec3
import glm_.vec3.Vec3i import glm_.vec3.Vec3i
import org.lwjgl.opengl.GL11.* import org.lwjgl.opengl.GL11.*
@ -52,15 +56,31 @@ class BlockOutlineRenderer(
} }
private fun drawLine(start: Vec3, end: Vec3, mesh: BlockOutlineMesh) { private fun drawLine(start: Vec3, end: Vec3, mesh: BlockOutlineMesh) {
// ToDo: Maybe use a cuboid, also we need to rotate `rotatedLineWidth` val direction = (end-start).normalize()
val rotatedLineWidth = Vec3(HALF_LINE_WIDTH, HALF_LINE_WIDTH, HALF_LINE_WIDTH) val normal1 = Vec3(direction.z, direction.z, direction.x-direction.y)
mesh.addVertex(Vec3(start.x, start.y, start.z) - rotatedLineWidth) if (normal1 == VecUtil.EMPTY_VEC3) {
mesh.addVertex(Vec3(start.x, start.y, start.z) + rotatedLineWidth) normal1.x = normal1.z
mesh.addVertex(Vec3(end.x, end.y, end.z) - rotatedLineWidth) normal1.z = direction.z
}
normal1.normalizeAssign()
val normal2 = (direction cross normal1).normalize()
for (i in 0..4) {
drawLineQuad(mesh, start, end, direction, normal1, normal2, i.isBit(0), i.isBit(1))
}
}
mesh.addVertex(Vec3(end.x, end.y, end.z) - rotatedLineWidth) private fun drawLineQuad(mesh: BlockOutlineMesh, start: Vec3, end: Vec3, direction: Vec3, normal1: Vec3, normal2: Vec3, invertNormal1: Boolean, invertNormal2: Boolean) {
mesh.addVertex(Vec3(start.x, start.y, start.z) + rotatedLineWidth) val normal1Multiplier = invertNormal1.positiveNegative
mesh.addVertex(Vec3(end.x, end.y, end.z) + rotatedLineWidth) val normal2Multiplier = invertNormal2.positiveNegative
val positions = listOf(
start + normal2 * normal2Multiplier * HALF_LINE_WIDTH - direction * HALF_LINE_WIDTH,
start + normal1 * normal1Multiplier * HALF_LINE_WIDTH - direction * HALF_LINE_WIDTH,
end + normal1 * normal1Multiplier * HALF_LINE_WIDTH + direction * HALF_LINE_WIDTH,
end + normal2 * normal2Multiplier * HALF_LINE_WIDTH + direction * HALF_LINE_WIDTH,
)
for ((_, positionIndex) in ElementRenderer.DRAW_ODER) {
mesh.addVertex(positions[positionIndex])
}
} }
private fun drawVoxelShape(shape: VoxelShape, blockPosition: Vec3, mesh: BlockOutlineMesh, margin: Float = 0.0f) { private fun drawVoxelShape(shape: VoxelShape, blockPosition: Vec3, mesh: BlockOutlineMesh, margin: Float = 0.0f) {
@ -167,7 +187,7 @@ class BlockOutlineRenderer(
companion object : RendererBuilder<BlockOutlineRenderer> { companion object : RendererBuilder<BlockOutlineRenderer> {
override val RESOURCE_LOCATION = ResourceLocation("minosoft:block_outline") override val RESOURCE_LOCATION = ResourceLocation("minosoft:block_outline")
private const val LINE_WIDTH = 1.0f / 64.0f private const val LINE_WIDTH = 1.0f / 128.0f
private const val HALF_LINE_WIDTH = LINE_WIDTH / 2.0f private const val HALF_LINE_WIDTH = LINE_WIDTH / 2.0f
override fun build(connection: PlayConnection, renderWindow: RenderWindow): BlockOutlineRenderer { override fun build(connection: PlayConnection, renderWindow: RenderWindow): BlockOutlineRenderer {

View File

@ -73,17 +73,20 @@ class ElementRenderer(
val lightLevel = context.lightAccessor.getLightLevel(context.blockPosition + face.cullFace?.let { directionMapping[it] }) // ToDo: rotate cullface val lightLevel = context.lightAccessor.getLightLevel(context.blockPosition + face.cullFace?.let { directionMapping[it] }) // ToDo: rotate cullface
val drawPositions = arrayOf(transformedPositions[positionTemplate[0]], transformedPositions[positionTemplate[1]], transformedPositions[positionTemplate[2]], transformedPositions[positionTemplate[3]]) val drawPositions = mutableListOf<Vec3>()
for (position in positionTemplate) {
drawPositions += transformedPositions[position]
}
val mesh = getMesh(context.meshCollection, texture.transparency) val mesh = getMesh(context.meshCollection, texture.transparency)
val texturePositions = face.getTexturePositionArray(realDirection) val texturePositions = face.getTexturePositionArray(realDirection)
for (vertex in DRAW_ODER) { for ((drawPositionIndex, texturePositionIndex) in DRAW_ODER) {
val input = drawPositions[vertex.first] val input = drawPositions[drawPositionIndex]
val output = context.blockPosition plus context.offset + input + DRAW_OFFSET val output = context.blockPosition plus context.offset + input + DRAW_OFFSET
mesh.addVertex( mesh.addVertex(
position = output, position = output,
textureCoordinates = texturePositions[vertex.second]!!, textureCoordinates = texturePositions[texturePositionIndex]!!,
texture = texture, texture = texture,
tintColor = if (face.tint) { tintColor = if (face.tint) {
tintColor tintColor

View File

@ -100,4 +100,11 @@ object MMath {
val Float.floor: Float get() = glm.floor(this) val Float.floor: Float get() = glm.floor(this)
val Float.fractionalPart: Float get() = this - floor val Float.fractionalPart: Float get() = this - floor
val Boolean.positiveNegative: Int get() =
if (this) {
1
} else {
-1
}
} }