fix static state bug
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2025-05-15 10:18:21 -04:00
parent 881ff98308
commit c6948b89ce
5 changed files with 92 additions and 22 deletions

View File

@ -1795,6 +1795,7 @@ Explicitly scream if trying to bind a shader that is invalid
Support for freeing shaders Support for freeing shaders
Utilities to free all of a type of resource Utilities to free all of a type of resource
Slowdown entity tests to prevent VSCode from exploding when running tests Slowdown entity tests to prevent VSCode from exploding when running tests
Fix static state caching between tests in visual shader construction

View File

@ -21,41 +21,70 @@ import electrosphere.renderer.shader.VisualShader;
*/ */
public class OpenGLState { public class OpenGLState {
//tracks whether caching should be used or not (to deduplicate opengl calls) /**
* tracks whether caching should be used or not (to deduplicate opengl calls)
*/
public static final boolean DISABLE_CACHING = false; public static final boolean DISABLE_CACHING = false;
//the max texture allowed by the current environment /**
* the max texture allowed by the current environment
*/
int MAX_TEXTURE_WIDTH; int MAX_TEXTURE_WIDTH;
//the current viewport dimensions /**
* the current viewport dimensions
*/
private Vector2i viewport; private Vector2i viewport;
//whether depth test is enabled or not /**
* whether depth test is enabled or not
*/
boolean depthTest; boolean depthTest;
//the current depth function /**
* the current depth function
*/
int depthFunction; int depthFunction;
//whether to blend or nit /**
* whether to blend or not
*/
boolean blendTest; boolean blendTest;
//the current blend func /**
//map is (texture unit) -> [sfactor,dfactor] * the current blend func
* map is (texture unit) -> [sfactor,dfactor]
*/
Map<Integer,int[]> blendFuncMap; Map<Integer,int[]> blendFuncMap;
//the key that contains the value of glBlendFunc (which would affect all buffers)
/**
* the key that contains the value of glBlendFunc (which would affect all buffers)
*/
static final int ALL_BUFFERS_KEY = -1; static final int ALL_BUFFERS_KEY = -1;
//the currently active texture /**
* the currently active texture
*/
int activeTexture; int activeTexture;
//the currently bound framebuffer /**
* Currently bound framebuffer type
*/
int framebufferType; int framebufferType;
/**
* Pointer for currently bound framebuffer
*/
int framebufferPointer; int framebufferPointer;
//active shader /**
* active shader
*/
Shader activeShader; Shader activeShader;
//map of texture units and their corresponding texture pointers /**
* map of texture units and their corresponding texture pointers
*/
Map<Integer,Integer> unitToPointerMap; Map<Integer,Integer> unitToPointerMap;
/** /**
@ -82,6 +111,7 @@ public class OpenGLState {
framebufferPointer = 0; framebufferPointer = 0;
GL45.glBindFramebuffer(this.framebufferType, this.framebufferPointer); GL45.glBindFramebuffer(this.framebufferType, this.framebufferPointer);
activeShader = null; activeShader = null;
GL45.glUseProgram(Shader.UNBIND_SHADER_ID);
this.unitToPointerMap = new HashMap<Integer,Integer>(); this.unitToPointerMap = new HashMap<Integer,Integer>();
this.indexBlockMap = new HashMap<Integer,UniformBlockBinding>(); this.indexBlockMap = new HashMap<Integer,UniformBlockBinding>();
this.storeCurrentEnvironmentContraints(); this.storeCurrentEnvironmentContraints();
@ -233,10 +263,13 @@ public class OpenGLState {
*/ */
public void setActiveShader(RenderPipelineState renderPipelineState, Shader program){ public void setActiveShader(RenderPipelineState renderPipelineState, Shader program){
if(DISABLE_CACHING || program != activeShader){ if(DISABLE_CACHING || program != activeShader){
activeShader = program; //error check
if(!GL40.glIsProgram(activeShader.getId()) && activeShader.getId() != Shader.UNBIND_SHADER_ID){ if(program.getId() != Shader.UNBIND_SHADER_ID && !GL40.glIsProgram(program.getId())){
throw new Error("Tried to bind shader that is not an active program! " + activeShader.getId()); throw new Error("Tried to bind shader that is not an active program! " + program.getId());
} }
//actually bind
activeShader = program;
GL40.glUseProgram(activeShader.getId()); GL40.glUseProgram(activeShader.getId());
int glErrorCode = Globals.renderingEngine.getError(); int glErrorCode = Globals.renderingEngine.getError();
if(glErrorCode != 0){ if(glErrorCode != 0){

View File

@ -208,8 +208,8 @@ public class RenderUtils {
VisualShader shader = VisualShader.smartAssembleOITProgram(false, true);
particleMesh.setShader(VisualShader.smartAssembleOITProgram(false, true)); particleMesh.setShader(shader);

View File

@ -849,6 +849,15 @@ public class RenderingEngine {
volumeDepthFrontfaceTexture = null; volumeDepthFrontfaceTexture = null;
normalsOutlineTexture = null; normalsOutlineTexture = null;
//reset shader loading
VisualShader.clearAlreadyCompiledMap();
//destroy loaded resources
Globals.assetManager.queueAllModelsForDeletion();
Globals.assetManager.queueAllTexturesForDeletion();
Globals.assetManager.queueAllShadersForDeletion();
Globals.assetManager.handleDeleteQueue();
//end glfw //end glfw
GLFW.glfwDestroyWindow(Globals.window); GLFW.glfwDestroyWindow(Globals.window);
GLFW.glfwTerminate(); GLFW.glfwTerminate();

View File

@ -13,6 +13,7 @@ import java.util.regex.Pattern;
import javax.management.RuntimeErrorException; import javax.management.RuntimeErrorException;
import org.lwjgl.opengl.GL40; import org.lwjgl.opengl.GL40;
import org.lwjgl.opengl.GL45;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
@ -173,6 +174,11 @@ public class VisualShader implements Shader {
alreadyCompiledMap.put(shaderKey,rVal); alreadyCompiledMap.put(shaderKey,rVal);
//check program status
if(!GL45.glIsProgram(rVal.shaderId)){
throw new Error("Failed to build program!");
}
return rVal; return rVal;
} }
@ -213,7 +219,7 @@ public class VisualShader implements Shader {
//This alerts openGL to the presence of a vertex shader and points the shader at its source //This alerts openGL to the presence of a vertex shader and points the shader at its source
GL40.glShaderSource(rVal.vertexShader, vertexShaderSource); GL40.glShaderSource(rVal.vertexShader, vertexShaderSource);
//Compiles the source for the vertex shader object //Compiles the source for the vertex shader object
GL40. glCompileShader(rVal.vertexShader); GL40.glCompileShader(rVal.vertexShader);
//The following tests if the vertex shader compiles successfully //The following tests if the vertex shader compiles successfully
int success; int success;
success = GL40.glGetShaderi(rVal.vertexShader, GL40.GL_COMPILE_STATUS); success = GL40.glGetShaderi(rVal.vertexShader, GL40.GL_COMPILE_STATUS);
@ -246,8 +252,8 @@ public class VisualShader implements Shader {
GL40. glLinkProgram(rVal.shaderId); GL40. glLinkProgram(rVal.shaderId);
//Tests for the success of the shader program creation //Tests for the success of the shader program creation
success = GL40.glGetProgrami(rVal.shaderId, GL40.GL_LINK_STATUS); success = GL40.glGetProgrami(rVal.shaderId, GL40.GL_LINK_STATUS);
if (success != GL40.GL_TRUE) { if(success != GL40.GL_TRUE){
throw new RuntimeException(GL40.glGetProgramInfoLog(rVal.shaderId)); throw new Error(GL40.glGetProgramInfoLog(rVal.shaderId));
} }
//Deletes the individual shader objects to free up memory //Deletes the individual shader objects to free up memory
@ -258,6 +264,9 @@ public class VisualShader implements Shader {
alreadyCompiledMap.put(shaderKey,rVal); alreadyCompiledMap.put(shaderKey,rVal);
//check program status
rVal.validate();
return rVal; return rVal;
} }
@ -417,7 +426,10 @@ public class VisualShader implements Shader {
GL40.glDeleteShader(rVal.fragmentShader); GL40.glDeleteShader(rVal.fragmentShader);
Globals.renderingEngine.checkError(); Globals.renderingEngine.checkError();
//check program status
if(!GL45.glIsProgram(rVal.shaderId)){
throw new Error("Failed to build program!");
}
return rVal; return rVal;
} }
@ -475,6 +487,14 @@ public class VisualShader implements Shader {
return this.shaderId; return this.shaderId;
} }
/**
* Validates the shader
*/
public void validate(){
if(!GL40.glIsProgram(this.getId())){
throw new Error("Shader is not a program!");
}
}
/** /**
* Frees the shader * Frees the shader
@ -484,4 +504,11 @@ public class VisualShader implements Shader {
this.shaderId = VisualShader.INVALID_UNIFORM_NAME; this.shaderId = VisualShader.INVALID_UNIFORM_NAME;
} }
/**
* Clears the map of already-compiled shaders
*/
public static void clearAlreadyCompiledMap(){
VisualShader.alreadyCompiledMap.clear();
}
} }