From 2f3a25dfb3a68f28508eb62be1e8798b18d22283 Mon Sep 17 00:00:00 2001 From: IntegratedQuantum <43880493+IntegratedQuantum@users.noreply.github.com> Date: Mon, 12 May 2025 17:47:14 +0200 Subject: [PATCH] Draw a thicker selection box (#1435) * Draw a thicker bounding box * Draw an actual 3d model for the selection box. This is done using a line model with a cubiod offset model. --- .../cubyz/shaders/block_selection_vertex.vert | 73 ++++++++++++++++++- src/renderer.zig | 61 ++-------------- 2 files changed, 78 insertions(+), 56 deletions(-) diff --git a/assets/cubyz/shaders/block_selection_vertex.vert b/assets/cubyz/shaders/block_selection_vertex.vert index d3f1e3cc..a37e5194 100644 --- a/assets/cubyz/shaders/block_selection_vertex.vert +++ b/assets/cubyz/shaders/block_selection_vertex.vert @@ -1,7 +1,5 @@ #version 460 -layout(location = 0) in vec3 position; - layout(location = 0) out vec3 mvVertexPos; layout(location = 0) uniform mat4 projectionMatrix; @@ -9,9 +7,78 @@ layout(location = 1) uniform mat4 viewMatrix; layout(location = 2) uniform vec3 modelPosition; layout(location = 3) uniform vec3 lowerBounds; layout(location = 4) uniform vec3 upperBounds; +layout(location = 5) uniform float lineSize; + +vec3 offsetVertices[] = vec3[] ( + vec3(-1, -1, -1), + vec3(-1, -1, 1), + vec3(-1, 1, -1), + vec3(-1, 1, 1), + vec3(1, -1, -1), + vec3(1, -1, 1), + vec3(1, 1, -1), + vec3(1, 1, 1), + + vec3(-1, -1, -1), + vec3(-1, -1, 1), + vec3(1, -1, -1), + vec3(1, -1, 1), + vec3(-1, 1, -1), + vec3(-1, 1, 1), + vec3(1, 1, -1), + vec3(1, 1, 1), + + vec3(-1, -1, -1), + vec3(-1, 1, -1), + vec3(1, -1, -1), + vec3(1, 1, -1), + vec3(-1, -1, 1), + vec3(-1, 1, 1), + vec3(1, -1, 1), + vec3(1, 1, 1) +); + +vec3 lineVertices[] = vec3[] ( + vec3(0, 0, 0), + vec3(0, 0, 1), + vec3(0, 1, 0), + vec3(0, 1, 1), + vec3(1, 0, 0), + vec3(1, 0, 1), + vec3(1, 1, 0), + vec3(1, 1, 1), + + vec3(0, 0, 0), + vec3(0, 1, 0), + vec3(0, 0, 1), + vec3(0, 1, 1), + vec3(1, 0, 0), + vec3(1, 1, 0), + vec3(1, 0, 1), + vec3(1, 1, 1), + + vec3(0, 0, 0), + vec3(1, 0, 0), + vec3(0, 0, 1), + vec3(1, 0, 1), + vec3(0, 1, 0), + vec3(1, 1, 0), + vec3(0, 1, 1), + vec3(1, 1, 1) +); void main() { - vec4 mvPos = viewMatrix*vec4(lowerBounds + position*(upperBounds - lowerBounds) + modelPosition, 1); + int vertexIndex = gl_VertexID%24; + int lineIndex = gl_VertexID/24; + vec3 lineStart = lineVertices[lineIndex*2]; + vec3 lineEnd = lineVertices[lineIndex*2 + 1]; + vec3 lineCenter = (lineStart + lineEnd)/2*(upperBounds - lowerBounds); + + vec3 offsetVector = vec3(lineSize); + offsetVector += vec3(notEqual(lineStart, lineEnd))*(upperBounds.x - lowerBounds.x)/2; + + vec3 vertexPos = lineCenter + offsetVertices[vertexIndex]*offsetVector; + vec4 mvPos = viewMatrix*vec4(lowerBounds + vertexPos + modelPosition, 1); gl_Position = projectionMatrix*mvPos; mvVertexPos = mvPos.xyz; } diff --git a/src/renderer.zig b/src/renderer.zig index 33aac8f3..8f3bac59 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -221,7 +221,6 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo gpu_performance_measuring.startQuery(.chunk_rendering_preparation); const direction = crosshairDirection(game.camera.viewMatrix, lastFov, lastWidth, lastHeight); MeshSelection.select(playerPos, direction, game.Player.inventory.getItem(game.Player.selectedSlot)); - MeshSelection.render(game.projectionMatrix, game.camera.viewMatrix, playerPos); chunk_meshing.beginRender(); @@ -241,6 +240,8 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo itemdrop.ItemDropRenderer.renderItemDrops(game.projectionMatrix, ambientLight, playerPos); gpu_performance_measuring.stopQuery(); + MeshSelection.render(game.projectionMatrix, game.camera.viewMatrix, playerPos); + // Render transparent chunk meshes: worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE5); @@ -845,69 +846,23 @@ pub const MeshSelection = struct { // MARK: MeshSelection modelPosition: c_int, lowerBounds: c_int, upperBounds: c_int, + lineSize: c_int, } = undefined; - var cubeVAO: c_uint = undefined; - var cubeVBO: c_uint = undefined; - var cubeIBO: c_uint = undefined; - pub fn init() void { pipeline = graphics.Pipeline.init( "assets/cubyz/shaders/block_selection_vertex.vert", "assets/cubyz/shaders/block_selection_fragment.frag", "", &uniforms, - .{.depthBias = .{ - .slopeFactor = -2, - .clamp = 0, - .constantFactor = 0, - }}, + .{.cullMode = .none}, .{.depthTest = true, .depthWrite = true}, - .{.attachments = &.{.noBlending}}, + .{.attachments = &.{.alphaBlending}}, ); - - const rawData = [_]f32{ - 0, 0, 0, - 0, 0, 1, - 0, 1, 0, - 0, 1, 1, - 1, 0, 0, - 1, 0, 1, - 1, 1, 0, - 1, 1, 1, - }; - const indices = [_]u8{ - 0, 1, - 0, 2, - 0, 4, - 1, 3, - 1, 5, - 2, 3, - 2, 6, - 3, 7, - 4, 5, - 4, 6, - 5, 7, - 6, 7, - }; - - c.glGenVertexArrays(1, &cubeVAO); - c.glBindVertexArray(cubeVAO); - c.glGenBuffers(1, &cubeVBO); - c.glBindBuffer(c.GL_ARRAY_BUFFER, cubeVBO); - c.glBufferData(c.GL_ARRAY_BUFFER, rawData.len*@sizeOf(f32), &rawData, c.GL_STATIC_DRAW); - c.glVertexAttribPointer(0, 3, c.GL_FLOAT, c.GL_FALSE, 3*@sizeOf(f32), null); - c.glEnableVertexAttribArray(0); - c.glGenBuffers(1, &cubeIBO); - c.glBindBuffer(c.GL_ELEMENT_ARRAY_BUFFER, cubeIBO); - c.glBufferData(c.GL_ELEMENT_ARRAY_BUFFER, indices.len*@sizeOf(u8), &indices, c.GL_STATIC_DRAW); } pub fn deinit() void { pipeline.deinit(); - c.glDeleteBuffers(1, &cubeIBO); - c.glDeleteBuffers(1, &cubeVBO); - c.glDeleteVertexArrays(1, &cubeVAO); } var posBeforeBlock: Vec3i = undefined; @@ -1162,10 +1117,10 @@ pub const MeshSelection = struct { // MARK: MeshSelection ); c.glUniform3f(uniforms.lowerBounds, min[0], min[1], min[2]); c.glUniform3f(uniforms.upperBounds, max[0], max[1], max[2]); + c.glUniform1f(uniforms.lineSize, 1.0/128.0); - c.glBindVertexArray(cubeVAO); - // TODO: Draw thicker lines so they are more visible. Maybe a simple shader + cube mesh is enough. - c.glDrawElements(c.GL_LINES, 12*2, c.GL_UNSIGNED_BYTE, null); + c.glBindVertexArray(main.renderer.chunk_meshing.vao); + c.glDrawElements(c.GL_TRIANGLES, 24*24, c.GL_UNSIGNED_INT, null); } pub fn render(projectionMatrix: Mat4f, viewMatrix: Mat4f, playerPos: Vec3d) void {