rendering optimization and error checking
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-22 19:25:56 -04:00
parent cb3ccbef0b
commit 560d306445
8 changed files with 53 additions and 16 deletions

View File

@ -1939,6 +1939,8 @@ Floating point starting to play nice with engine
Fix geom-body collision sending wrong vector to body
Per-mesh draw calls in batched static draw calls
Main content pipeline tracking
Error checking on mesh rendering (making sure not trying to draw 0-element meshes)
Fix generating rendering geometry for blocks/terrain with 0 elements

View File

@ -343,6 +343,9 @@ public class ClientTerrainManager {
* @return The model path that is promised to eventually reflect the terrain model when it makes it to gpu
*/
public static String queueTerrainGridGeneration(TerrainChunkData data, VoxelTextureAtlas atlas, DrawCell notifyTarget, Entity toDelete){
if(data.getFaceElements().length < 1){
throw new Error("Invalid data!");
}
String promisedHash = "";
UUID newUUID = UUID.randomUUID();
promisedHash = newUUID.toString();

View File

@ -72,7 +72,7 @@ public class BlockChunkEntity {
BlockMeshData data;
try {
data = BlockMeshgen.rasterize(chunkData, true, solidsMap);
if(Globals.clientState.clientScene.containsEntity(solidsEnt)){
if(Globals.clientState.clientScene.containsEntity(solidsEnt) && data.getFaceElements().length > 0){
String modelPath = Globals.assetManager.queuedAsset(new QueuedModel(() -> {
return BlockMeshgen.generateBlockModel(data);
}));
@ -123,7 +123,7 @@ public class BlockChunkEntity {
BlockMeshData data;
try {
data = BlockMeshgen.rasterize(chunkData, false, solidsMap);
if(Globals.clientState.clientScene.containsEntity(transparentEnt)){
if(Globals.clientState.clientScene.containsEntity(transparentEnt) && data.getFaceElements().length > 0){
String modelPath = Globals.assetManager.queuedAsset(new QueuedModel(() -> {
return BlockMeshgen.generateBlockModel(data);
}));

View File

@ -70,7 +70,7 @@ public class TerrainChunk {
try {
data = TransvoxelModelGeneration.generateTerrainChunkData(chunkData);
data.constructBuffers();
if(Globals.clientState.clientScene.containsEntity(rVal)){
if(Globals.clientState.clientScene.containsEntity(rVal) && data.getFaceElements().length > 0){
String modelPath = ClientTerrainManager.queueTerrainGridGeneration(data, atlas, notifyTarget, toDelete);
EntityCreationUtils.makeEntityDrawablePreexistingModel(rVal, modelPath);
if(levelOfDetail == BlockChunkData.LOD_FULL_RES && data.getFaceElements().length > 0){

View File

@ -564,6 +564,9 @@ public class BlockMeshgen {
// Buffer data to GPU
//
int elementCount = meshData.faceElements.length;
if(elementCount < 1){
throw new Error("Invalid mesh data!");
}
try {
//actually buffer vertices
if(vertexArrayBufferData.position() > 0){

View File

@ -795,6 +795,9 @@ public class TerrainChunkModelGeneration {
// Buffer data to GPU
//
int elementCount = data.getFaceElements().length;
if(elementCount < 1){
throw new Error("Invalid mesh data!");
}
try {
//actually buffer vertices

View File

@ -2206,6 +2206,9 @@ public class TransvoxelModelGeneration {
// Buffer data to GPU
//
int elementCount = data.getFaceElements().length;
if(elementCount < 1){
throw new Error("Invalid mesh data!");
}
try {
//actually buffer vertices

View File

@ -223,6 +223,9 @@ public class Mesh {
* @param elementCount The number of faces
*/
public void bufferFaces(IntBuffer faces, int elementCount){
if(elementCount < 1){
throw new Error("Sending mesh with 0 faces!");
}
if(!EngineState.EngineFlags.HEADLESS){
elementArrayBuffer = GL45.glGenBuffers();
GL45.glBindBuffer(GL45.GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
@ -573,26 +576,46 @@ public class Mesh {
if(renderPipelineState.getInstanced()){
if(this.elementCount > 0 ){
GL45.glDrawElementsInstanced(GL45.GL_TRIANGLES, this.elementCount, GL45.GL_UNSIGNED_INT, 0, renderPipelineState.getInstanceCount());
Globals.renderingEngine.checkError();
if(renderPipelineState.getInstanceCount() < 1){
throw new Error("Failed to render instanced mesh with invalid instance count! " + this.getDebugData());
}
GL45.glDrawElementsInstanced(GL45.GL_TRIANGLES, this.elementCount, GL45.GL_UNSIGNED_INT, 0, renderPipelineState.getInstanceCount());
Globals.renderingEngine.checkError();
} else if(this.useElementArray){
if(this.elementCount < 1){
throw new Error("Failed to render mesh with invalid element count! " + this.getDebugData());
}
GL45.glDrawElements(GL45.GL_TRIANGLES, this.elementCount, GL45.GL_UNSIGNED_INT, 0);
Globals.renderingEngine.checkError();
} else {
if(this.useElementArray){
if(this.elementCount > 0){
GL45.glDrawElements(GL45.GL_TRIANGLES, this.elementCount, GL45.GL_UNSIGNED_INT, 0);
Globals.renderingEngine.checkError();
}
} else {
if(this.elementCount > 0){
GL45.glDrawArrays(GL45.GL_TRIANGLES, 0, this.elementCount);
Globals.renderingEngine.checkError();
}
if(this.elementCount < 1){
throw new Error("Failed to render mesh with invalid element count! " + this.getDebugData());
}
GL45.glDrawArrays(GL45.GL_TRIANGLES, 0, this.elementCount);
Globals.renderingEngine.checkError();
}
Globals.profiler.endCpuSample();
}
/**
* Gets debug data for the mesh
* @return The debug data in a string
*/
private String getDebugData(){
String rVal = "\n" +
"Mesh name: " + this.meshName + "\n" +
"Vertex buffer: " + this.vertexBuffer + "\n" +
"Normal buffer: " + this.normalBuffer + "\n" +
"Texture buffer: " + this.textureCoordBuffer + "\n" +
"Bone Index buffer: " + this.boneIndexBuffer + "\n" +
"Bone Weight buffer: " + this.boneWeightBuffer + "\n" +
"Element buffer: " + this.elementArrayBuffer + "\n" +
"Element count: " + this.elementCount + "\n" +
"Use element array: " + this.useElementArray + "\n" +
"";
return rVal;
}
/**
* Updates the bounding sphere of the mesh
* @param x