diff --git a/src/main/kotlin/solve/rendering/canvas/OpenGLCanvas.kt b/src/main/kotlin/solve/rendering/canvas/OpenGLCanvas.kt index 4cb4ad07..917a4380 100644 --- a/src/main/kotlin/solve/rendering/canvas/OpenGLCanvas.kt +++ b/src/main/kotlin/solve/rendering/canvas/OpenGLCanvas.kt @@ -8,12 +8,16 @@ import com.huskerdev.openglfx.events.GLReshapeEvent import com.huskerdev.openglfx.lwjgl.LWJGLExecutor import org.joml.Vector2i import org.lwjgl.opengl.GL.createCapabilities +import org.lwjgl.opengl.GL11.GL_ALPHA_TEST import org.lwjgl.opengl.GL11.GL_BLEND import org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT import org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT import org.lwjgl.opengl.GL11.GL_DEPTH_TEST import org.lwjgl.opengl.GL11.GL_LEQUAL +import org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA import org.lwjgl.opengl.GL11.GL_PROJECTION +import org.lwjgl.opengl.GL11.GL_SRC_ALPHA +import org.lwjgl.opengl.GL11.glBlendFunc import org.lwjgl.opengl.GL11.glClear import org.lwjgl.opengl.GL11.glDepthFunc import org.lwjgl.opengl.GL11.glEnable @@ -38,6 +42,8 @@ abstract class OpenGLCanvas { open fun onDraw(deltaTime: Float) { } open fun onInit() { + glEnable(GL_ALPHA_TEST) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(GL_BLEND) glEnable(GL_DEPTH_TEST) glEnable(GL_MULTISAMPLE) diff --git a/src/main/kotlin/solve/rendering/engine/core/batch/RenderBatch.kt b/src/main/kotlin/solve/rendering/engine/core/batch/RenderBatch.kt index 422b0ad3..129f6423 100644 --- a/src/main/kotlin/solve/rendering/engine/core/batch/RenderBatch.kt +++ b/src/main/kotlin/solve/rendering/engine/core/batch/RenderBatch.kt @@ -14,10 +14,10 @@ import org.lwjgl.opengl.GL15.glDeleteBuffers import org.lwjgl.opengl.GL15.glGenBuffers import org.lwjgl.opengl.GL20.glDisableVertexAttribArray import org.lwjgl.opengl.GL20.glEnableVertexAttribArray -import org.lwjgl.opengl.GL20.glVertexAttribPointer import org.lwjgl.opengl.GL30.glBindVertexArray import org.lwjgl.opengl.GL30.glDeleteVertexArrays import org.lwjgl.opengl.GL30.glGenVertexArrays +import org.lwjgl.opengl.GL30.glVertexAttribPointer import solve.rendering.engine.core.texture.Texture import solve.rendering.engine.shader.ShaderAttributeType import solve.rendering.engine.utils.toList diff --git a/src/main/kotlin/solve/rendering/engine/core/renderers/LinesLayerRenderer.kt b/src/main/kotlin/solve/rendering/engine/core/renderers/LinesLayerRenderer.kt index 2244f1ba..1f3f06cc 100644 --- a/src/main/kotlin/solve/rendering/engine/core/renderers/LinesLayerRenderer.kt +++ b/src/main/kotlin/solve/rendering/engine/core/renderers/LinesLayerRenderer.kt @@ -1,7 +1,7 @@ package solve.rendering.engine.core.renderers import org.joml.Vector2f -import org.joml.Vector3f +import org.joml.Vector4f import solve.constants.ShadersLineLandmarkFragmentPath import solve.constants.ShadersLineLandmarkVertexPath import solve.rendering.engine.Window @@ -16,6 +16,7 @@ import solve.rendering.engine.utils.times import solve.scene.model.Landmark import solve.scene.model.Layer.LineLayer import solve.scene.model.Scene +import kotlin.math.min class LinesLayerRenderer( window: Window, @@ -38,7 +39,7 @@ class LinesLayerRenderer( override fun createNewBatch(zIndex: Int): RenderBatch { val shaderAttributesTypes = listOf( ShaderAttributeType.FLOAT2, - ShaderAttributeType.FLOAT3 + ShaderAttributeType.FLOAT4 ) return RenderBatch( @@ -73,7 +74,6 @@ class LinesLayerRenderer( visibleLineLayersLandmarks.forEachIndexed { visibleLayerIndex, linesLayerLandmarks -> linesLayerLandmarks.forEach { lineLandmark -> val selectionLayerIndex = visibleLayersSelectionIndices[visibleLayerIndex] - val batch = getAvailableBatch(null, 0) val lineStartPosition = Vector2f( lineLandmark.startCoordinate.x.toFloat(), @@ -87,7 +87,6 @@ class LinesLayerRenderer( val lineFinishShaderPosition = getFramePixelShaderPosition(selectionLayerIndex, lineFinishPosition) val lineVector = lineFinishShaderPosition - lineStartShaderPosition val normalVector = Vector2f(-lineVector.y, lineVector.x).normalize() - val linePoints = listOf(lineStartShaderPosition, lineFinishShaderPosition) val highlightingProgress = lineLandmark.layerState.getLandmarkHighlightingProgress(lineLandmark.uid) var widthMultiplier = 1f @@ -103,29 +102,77 @@ class LinesLayerRenderer( ) } - val lineColorVector = Vector3f( + val lineColorVector = Vector4f( lineColor.red.toFloat(), lineColor.green.toFloat(), - lineColor.blue.toFloat() + lineColor.blue.toFloat(), + 1f + ) + val zeroAlphaLineColorVector = Vector4f(lineColorVector).also { it.w = 0f } + + val opaqueLineRectWidth = linesWidth * widthMultiplier + drawLineRectVertices( + lineStartShaderPosition, + lineFinishShaderPosition, + opaqueLineRectWidth, + lineColorVector, + lineColorVector, + normalVector + ) + val nonOpaqueLineRectWidth = min( + opaqueLineRectWidth * NonOpaqueLineWidthFactor, + NonOpaqueMaxLineWidth + ) + val nonOpaqueRectNormalOffset = Vector2f(normalVector) * + (opaqueLineRectWidth + nonOpaqueLineRectWidth) / 2f / window.camera.zoom / + DefaultLocalVerticesPositionsDivider + drawLineRectVertices( + lineStartShaderPosition + nonOpaqueRectNormalOffset, + lineFinishShaderPosition + nonOpaqueRectNormalOffset, + nonOpaqueLineRectWidth, + lineColorVector, + zeroAlphaLineColorVector, + normalVector + ) + drawLineRectVertices( + lineStartShaderPosition - nonOpaqueRectNormalOffset, + lineFinishShaderPosition - nonOpaqueRectNormalOffset, + nonOpaqueLineRectWidth, + zeroAlphaLineColorVector, + lineColorVector, + normalVector ) - - linePoints.forEachIndexed { sideIndex, linePoint -> - val pointToVertexVector = Vector2f(normalVector) * linesWidth * widthMultiplier / - window.camera.zoom / DefaultLocalVerticesPositionsDivider - - val upperVertexPosition = linePoint + pointToVertexVector - val bottomVertexPosition = linePoint - pointToVertexVector - val firstVertexPosition = if (sideIndex == 0) upperVertexPosition else bottomVertexPosition - val secondVertexPosition = if (sideIndex == 0) bottomVertexPosition else upperVertexPosition - batch.pushVector2f(firstVertexPosition) - batch.pushVector3f(lineColorVector) - batch.pushVector2f(secondVertexPosition) - batch.pushVector3f(lineColorVector) - } } } } + private fun drawLineRectVertices( + rectCenterStartPoint: Vector2f, + rectCenterFinishPoint: Vector2f, + rectWidth: Float, + bottomVerticesColor: Vector4f, + upperVerticesColor: Vector4f, + normalVector: Vector2f + ) { + val batch = getAvailableBatch(null, 0) + val centerLinePoints = listOf(rectCenterStartPoint, rectCenterFinishPoint) + centerLinePoints.forEachIndexed { sideIndex, linePoint -> + val pointToVertexVector = Vector2f(normalVector) * (rectWidth / 2f) / window.camera.zoom / + DefaultLocalVerticesPositionsDivider + + val upperVertexPosition = linePoint + pointToVertexVector + val bottomVertexPosition = linePoint - pointToVertexVector + val firstVertexPosition = if (sideIndex == 0) upperVertexPosition else bottomVertexPosition + val secondVertexPosition = if (sideIndex == 0) bottomVertexPosition else upperVertexPosition + val firstVertexColor = if (sideIndex == 0) upperVerticesColor else bottomVerticesColor + val secondVertexColor = if (sideIndex == 0) bottomVerticesColor else upperVerticesColor + batch.pushVector2f(firstVertexPosition) + batch.pushVector4f(firstVertexColor) + batch.pushVector2f(secondVertexPosition) + batch.pushVector4f(secondVertexColor) + } + } + private fun getLinesWidth(): Float { return visibleLineLayers.firstOrNull()?.settings?.selectedWidth?.toFloat() ?: return 1f } @@ -141,7 +188,15 @@ class LinesLayerRenderer( companion object { private const val UseCommonColorUniformName = "uUseCommonColor" - private const val DefaultLocalVerticesPositionsDivider = 800f + private val boundsVerticesLocalPositions = listOf( + Vector2f(1f, 1f), + Vector2f(1f, -1f), + Vector2f(-1f, -1f), + Vector2f(-1f, 1f) + ) + private const val DefaultLocalVerticesPositionsDivider = 600f private const val HighlightingWidthMultiplier = 2.5f + private const val NonOpaqueLineWidthFactor = 1f + private const val NonOpaqueMaxLineWidth = 4f } } diff --git a/src/main/resources/engine/shaders/landmark/line/line.frag b/src/main/resources/engine/shaders/landmark/line/line.frag index 8e32b6e8..f0a7a4de 100644 --- a/src/main/resources/engine/shaders/landmark/line/line.frag +++ b/src/main/resources/engine/shaders/landmark/line/line.frag @@ -1,6 +1,6 @@ #version 330 core -in vec3 fColor; +in vec4 fColor; uniform int uUseCommonColor; @@ -8,5 +8,10 @@ out vec4 color; void main() { - color = vec4(fColor, 1.0); -} \ No newline at end of file + vec4 premulitpliedColor = fColor; + float alpha = fColor.w; + premulitpliedColor.x *= alpha; + premulitpliedColor.y *= alpha; + premulitpliedColor.z *= alpha; + color = premulitpliedColor; +} diff --git a/src/main/resources/engine/shaders/landmark/line/line.vert b/src/main/resources/engine/shaders/landmark/line/line.vert index f3046ec4..682bfda5 100644 --- a/src/main/resources/engine/shaders/landmark/line/line.vert +++ b/src/main/resources/engine/shaders/landmark/line/line.vert @@ -1,11 +1,11 @@ #version 330 core layout (location=0) in vec2 aPos; -layout (location=1) in vec3 aColor; +layout (location=1) in vec4 aColor; uniform mat4 uProjection; -out vec3 fColor; +out vec4 fColor; void main() { diff --git a/src/main/resources/engine/shaders/landmark/point/point.frag b/src/main/resources/engine/shaders/landmark/point/point.frag index 6df2f82b..747f5e9e 100644 --- a/src/main/resources/engine/shaders/landmark/point/point.frag +++ b/src/main/resources/engine/shaders/landmark/point/point.frag @@ -10,9 +10,12 @@ out vec4 color; void main() { float localRadius = dot(fLocalPos, fLocalPos); - if (length(localRadius) > 1) { + if (localRadius > 1) { discard; } - color = vec4(fColor, 1.0); + if (localRadius < 0.6) + color = vec4(fColor, 1); + else + color = vec4(fColor, (1 - localRadius) * (1 - localRadius)); }