From 7f8b5579c514e86b5a88a2a614ed1f93005a8b35 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 30 Jun 2024 09:25:12 -0500 Subject: [PATCH] Add generic rendering profilers and move some vertex attribs to uniforms --- .../renderer/GenericObjectRenderer.java | 148 ++++++++++++------ .../core/render/renderer/LodRenderer.java | 2 +- .../shaders/genericObject/instanced/vert.vert | 28 +++- 3 files changed, 127 insertions(+), 51 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericObjectRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericObjectRenderer.java index c89d385d8..a0036e6c9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericObjectRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/GenericObjectRenderer.java @@ -37,6 +37,7 @@ import com.seibel.distanthorizons.core.render.glObject.shader.ShaderProgram; import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.AbstractVertexAttribute; import com.seibel.distanthorizons.core.render.glObject.vertexAttribute.VertexPointer; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.distanthorizons.coreapi.util.math.Mat4f; import com.seibel.distanthorizons.coreapi.util.math.Vec3d; import com.seibel.distanthorizons.coreapi.util.math.Vec3f; @@ -88,14 +89,17 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // instance data - private int instanceTransformVBO; + private int instanceTranslateVBO; + private int instanceScaleVBO; private int instanceColorVBO; // shader uniforms private int directShaderTransformUniformLocation; private int directShaderColorUniformLocation; - private int instancedShaderOriginOffsetUniformLocation; + private int instancedShaderOffsetUniformLocation; + private int instancedShaderCameraPosUniformLocation; + private int instancedShaderProjectionModelViewMatrixUniformLocation; // TODO may need to be double buffered to prevent rendering lag @@ -179,7 +183,9 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister this.directShaderTransformUniformLocation = this.shader.tryGetUniformLocation("uTransform"); this.directShaderColorUniformLocation = this.shader.tryGetUniformLocation("uColor"); - this.instancedShaderOriginOffsetUniformLocation = this.shader.tryGetUniformLocation("uOriginOffset"); + this.instancedShaderOffsetUniformLocation = this.shader.tryGetUniformLocation("uOffset"); + this.instancedShaderCameraPosUniformLocation = this.shader.tryGetUniformLocation("uCameraPos"); + this.instancedShaderProjectionModelViewMatrixUniformLocation = this.shader.tryGetUniformLocation("uProjectionMvm"); this.createBuffers(); @@ -234,6 +240,36 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister }); DhApi.Delayed.renderRegister.add(relativePosCubeGroup); + + + + // massive relative cube group + ArrayList massRelCubeList = new ArrayList<>(); + for (int x = 0; x < 40*2; x+=2) + { + for (int z = 0; z < 40*2; z+=2) + { + massRelCubeList.add(new DhApiRenderableBox( + new Vec3f(0f-x, 0f, 0f-z), new Vec3f(1f-x, 1f, 1f-z), + new Color(Color.RED.getRed(), Color.RED.getGreen(), Color.RED.getBlue()))); + } + } + IDhApiRenderableBoxGroup massRelativePosCubeGroup = DhApi.Delayed.renderRegister.createRelativePositionedGroup( + -25f, 140f, 0f, + massRelCubeList); + massRelativePosCubeGroup.setPreRenderFunc((event) -> + { + float y = massRelativePosCubeGroup.getOriginBlockY(); + y += event.partialTicks / 4; + if (y > 150f) + { + y = 140f; + } + massRelativePosCubeGroup.setOriginBlockPos(massRelativePosCubeGroup.getOriginBlockX(), y, massRelativePosCubeGroup.getOriginBlockZ()); + }); + DhApi.Delayed.renderRegister.add(massRelativePosCubeGroup); + + } private void createBuffers() { @@ -258,7 +294,8 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // instance buffers - this.instanceTransformVBO = GL32.glGenBuffers(); + this.instanceTranslateVBO = GL32.glGenBuffers(); + this.instanceScaleVBO = GL32.glGenBuffers(); this.instanceColorVBO = GL32.glGenBuffers(); } @@ -273,7 +310,7 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister { ArrayList list = new ArrayList<>(); list.add(box); - return new DhApiRenderableBoxGroup(0, 0, 0, list, false); + return this.createAbsolutePositionedGroup(list); } @Override @@ -347,9 +384,10 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // rendering // //===========// - public void render(DhApiRenderParam renderEventParam) + public void render(DhApiRenderParam renderEventParam, IProfilerWrapper profiler) { // render setup // + profiler.push("setup"); GLState glState = new GLState(); this.init(); @@ -367,8 +405,8 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister this.solidIndexBuffer.bind(); - Mat4f transformMatrix = new Mat4f(renderEventParam.dhProjectionMatrix); - transformMatrix.multiply(renderEventParam.dhModelViewMatrix); + Mat4f projectionMvmMatrix = new Mat4f(renderEventParam.dhProjectionMatrix); + projectionMvmMatrix.multiply(renderEventParam.dhModelViewMatrix); Vec3d camPosDouble = MC_RENDER.getCameraExactPosition(); Vec3f camPos = new Vec3f((float) camPosDouble.x, (float) camPosDouble.y, (float) camPosDouble.z); @@ -377,26 +415,38 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // rendering // + LongSet keys = boxGroupById.keySet(); for (long key : keys) { + profiler.popPush("render prep"); + DhApiRenderableBoxGroup boxGroup = boxGroupById.get(key); + boxGroup.preRender(renderEventParam); + if (this.useInstancedRendering) { - this.renderBoxGroupInstanced(boxGroup, renderEventParam, transformMatrix, camPos); + updateCubeGroupInstanceBuffers(boxGroup, camPos, projectionMvmMatrix); + + profiler.popPush("rendering"); + this.renderBoxGroupInstanced(boxGroup, camPos, projectionMvmMatrix); } else { - this.renderBoxGroupDirect(boxGroup, renderEventParam, transformMatrix, camPos); + profiler.popPush("rendering"); + this.renderBoxGroupDirect(boxGroup, projectionMvmMatrix, camPos); } } // clean up // + profiler.popPush("cleanup"); this.shader.unbind(); glState.restore(); + + profiler.pop(); } @@ -405,15 +455,26 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // instanced rendering // //=====================// - private void renderBoxGroupInstanced(DhApiRenderableBoxGroup cubeGroup, - DhApiRenderParam renderEventParam, Mat4f transformMatrix, Vec3f camPos) + private void renderBoxGroupInstanced(DhApiRenderableBoxGroup cubeGroup, Vec3f camPos, Mat4f projectionMvmMatrix) { // update instance data // - cubeGroup.preRender(renderEventParam); - int boxCount = updateCubeGroupInstanceBuffers(cubeGroup, camPos, transformMatrix); // Update instance data + this.shader.setUniform(this.instancedShaderOffsetUniformLocation, + new Vec3f( + cubeGroup.originBlockX, + cubeGroup.originBlockY, + cubeGroup.originBlockZ + )); - this.shader.setUniform(this.instancedShaderOriginOffsetUniformLocation, new Vec3f(cubeGroup.originBlockX, cubeGroup.originBlockY, cubeGroup.originBlockZ)); + this.shader.setUniform(this.instancedShaderCameraPosUniformLocation, + new Vec3f( + camPos.x, + camPos.y, + camPos.z + )); + + this.shader.setUniform(this.instancedShaderProjectionModelViewMatrixUniformLocation, + projectionMvmMatrix); @@ -425,23 +486,19 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister GL32.glVertexAttribPointer(1, 4, GL32.GL_FLOAT, false, 4 * Float.BYTES, 0); vertexAttribDivisor(1, 1); - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceTransformVBO); + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceTranslateVBO); GL32.glEnableVertexAttribArray(2); vertexAttribDivisor(2, 1); - GL32.glVertexAttribPointer(2, 4, GL32.GL_FLOAT, false, 16 * Float.BYTES, 0); + GL32.glVertexAttribPointer(2, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0); + + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceScaleVBO); GL32.glEnableVertexAttribArray(3); vertexAttribDivisor(3, 1); - GL32.glVertexAttribPointer(3, 4, GL32.GL_FLOAT, false, 16 * Float.BYTES, 16); - GL32.glEnableVertexAttribArray(4); - vertexAttribDivisor(4, 1); - GL32.glVertexAttribPointer(4, 4, GL32.GL_FLOAT, false, 16 * Float.BYTES, 32); - GL32.glEnableVertexAttribArray(5); - vertexAttribDivisor(5, 1); - GL32.glVertexAttribPointer(5, 4, GL32.GL_FLOAT, false, 16 * Float.BYTES, 48); + GL32.glVertexAttribPointer(3, 3, GL32.GL_FLOAT, false, 3 * Float.BYTES, 0); // Draw instanced - GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, SOLID_BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, boxCount); + GL32.glDrawElementsInstanced(GL32.GL_TRIANGLES, SOLID_BOX_INDICES.length, GL32.GL_UNSIGNED_INT, 0, cubeGroup.size()); // Clean up @@ -471,37 +528,38 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister } } - private int updateCubeGroupInstanceBuffers(DhApiRenderableBoxGroup cubeGroup, Vec3f camPos, Mat4f transformationMatrix) + private void updateCubeGroupInstanceBuffers(DhApiRenderableBoxGroup cubeGroup, Vec3f camPos, Mat4f projectionMvmMatrix) { int boxCount = cubeGroup.size(); // Prepare transformation matrices - float[] transformationData = new float[boxCount * 16]; + float[] translateData = new float[boxCount * 3]; + float[] scaleData = new float[boxCount * 3]; for (int i = 0; i < cubeGroup.size(); i++) { DhApiRenderableBox cube = cubeGroup.get(i); - Mat4f boxTransform = Mat4f.createTranslateMatrix( - cube.minPos.x - camPos.x, - cube.minPos.y - camPos.y, - cube.minPos.z - camPos.z); - boxTransform.multiply(Mat4f.createScaleMatrix( + System.arraycopy(new float[] + { + cube.minPos.x, + cube.minPos.y, + cube.minPos.z + }, 0, translateData, i * 3, 3); + + System.arraycopy(new float[] + { cube.maxPos.x - cube.minPos.x, cube.maxPos.y - cube.minPos.y, - cube.maxPos.z - cube.minPos.z)); - Mat4f transformMatrix = transformationMatrix.copy(); - transformMatrix.multiply(boxTransform); - - // due to how the matrix is being read in by GL, we need to transpose it - // (This is probably a bug due to how James set up the vertex array attributes) - transformMatrix.transpose(); - System.arraycopy(transformMatrix.getValuesAsArray(), 0, transformationData, i * 16, 16); + cube.maxPos.z - cube.minPos.z + }, 0, scaleData, i * 3, 3); } // Upload transformation matrices - GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceTransformVBO); - GL32.glBufferData(GL32.GL_ARRAY_BUFFER, transformationData, GL32.GL_DYNAMIC_DRAW); + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceTranslateVBO); + GL32.glBufferData(GL32.GL_ARRAY_BUFFER, translateData, GL32.GL_DYNAMIC_DRAW); + GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceScaleVBO); + GL32.glBufferData(GL32.GL_ARRAY_BUFFER, scaleData, GL32.GL_DYNAMIC_DRAW); @@ -521,8 +579,6 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // Upload colors GL32.glBindBuffer(GL32.GL_ARRAY_BUFFER, this.instanceColorVBO); GL32.glBufferData(GL32.GL_ARRAY_BUFFER, colors, GL32.GL_DYNAMIC_DRAW); - - return boxCount; } @@ -531,10 +587,8 @@ public class GenericObjectRenderer implements IDhApiCustomRenderRegister // direct rendering // //==================// - private void renderBoxGroupDirect(DhApiRenderableBoxGroup cubeGroup, - DhApiRenderParam renderEventParam, Mat4f transformMatrix, Vec3f camPos) + private void renderBoxGroupDirect(DhApiRenderableBoxGroup cubeGroup, Mat4f transformMatrix, Vec3f camPos) { - cubeGroup.preRender(renderEventParam); for (DhApiRenderableBox box : cubeGroup.cubeList) { renderBox(cubeGroup, box, transformMatrix, camPos); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java index 8e6c3f148..6a89ef21f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/renderer/LodRenderer.java @@ -422,7 +422,7 @@ public class LodRenderer } profiler.popPush("Custom Objects"); - GenericObjectRenderer.INSTANCE.render(renderEventParam); + GenericObjectRenderer.INSTANCE.render(renderEventParam, profiler); profiler.popPush("LOD cleanup"); diff --git a/core/src/main/resources/shaders/genericObject/instanced/vert.vert b/core/src/main/resources/shaders/genericObject/instanced/vert.vert index 33491329e..0849e9f7c 100644 --- a/core/src/main/resources/shaders/genericObject/instanced/vert.vert +++ b/core/src/main/resources/shaders/genericObject/instanced/vert.vert @@ -1,9 +1,12 @@ #version 330 core layout (location = 1) in vec4 aColor; -layout (location = 2) in mat4 aTransform; +layout (location = 2) in vec3 aTranslate; +layout (location = 3) in vec3 aScale; -uniform vec3 uOriginOffset; +uniform vec3 uOffset; +uniform vec3 uCameraPos; +uniform mat4 uProjectionMvm; in vec3 vPosition; @@ -11,6 +14,25 @@ out vec4 fColor; void main() { - gl_Position = aTransform * vec4(vPosition + uOriginOffset, 1.0); + // aTranslate - moves the vertex to the boxGroup's relative position + // uOffset - moves the vertex to the boxGroup's position + // uCameraPos - moves the vertex into camera space + float transX = aTranslate.x + uOffset.x - uCameraPos.x; + float transY = aTranslate.y + uOffset.y - uCameraPos.y; + float transZ = aTranslate.z + uOffset.z - uCameraPos.z; + + float scaleX = aScale.x; + float scaleY = aScale.y; + float scaleZ = aScale.z; + + // combination translation and scaling matrix + mat4 transform = mat4( + scaleX, 0.0, 0.0, 0.0, + 0.0, scaleY, 0.0, 0.0, + 0.0, 0.0, scaleZ, 0.0, + transX, transY, transZ, 1.0 + ); + + gl_Position = uProjectionMvm * transform * vec4(vPosition, 1.0); fColor = aColor; } \ No newline at end of file