shader work

This commit is contained in:
austin 2025-05-15 09:46:53 -04:00
parent f1d75a08a3
commit 3962b7e5c6
5 changed files with 80 additions and 69 deletions

View File

@ -1790,6 +1790,11 @@ Remove warnings for fast loading
Work on debugging framebuffers Work on debugging framebuffers
Work to unify opengl error reporting Work to unify opengl error reporting
(05/15/2025)
Explicitly scream if trying to bind a shader that is invalid
Support for freeing shaders
Utilities to free all of a type of resource

View File

@ -57,6 +57,7 @@ public class AssetManager {
List<String> audioInQueue = new LinkedList<String>(); List<String> audioInQueue = new LinkedList<String>();
Map<String,VisualShader> shadersLoadedIntoMemory = new HashMap<String,VisualShader>(); Map<String,VisualShader> shadersLoadedIntoMemory = new HashMap<String,VisualShader>();
List<String> shadersInDeleteQueue = new LinkedList<String>();
List<ActorShaderMask> shadersInQueue = new LinkedList<ActorShaderMask>(); List<ActorShaderMask> shadersInQueue = new LinkedList<ActorShaderMask>();
// //
@ -270,6 +271,7 @@ public class AssetManager {
this.deleteModelsInDeleteQueue(); this.deleteModelsInDeleteQueue();
this.deletePoseModelsInDeleteQueue(); this.deletePoseModelsInDeleteQueue();
this.deleteTexturesInDeleteQueue(); this.deleteTexturesInDeleteQueue();
this.deleteShadersInDeleteQueue();
lock.unlock(); lock.unlock();
} }
@ -400,6 +402,17 @@ public class AssetManager {
lock.unlock(); lock.unlock();
} }
/**
* Queues all models for deletion
*/
public void queueAllModelsForDeletion(){
lock.lock();
for(String modelPath : this.modelsLoadedIntoMemory.keySet()){
this.queueModelForDeletion(modelPath);
}
lock.unlock();
}
@ -581,6 +594,17 @@ public class AssetManager {
lock.unlock(); lock.unlock();
} }
/**
* Queues all textures for deletion
*/
public void queueAllTexturesForDeletion(){
lock.lock();
for(String texturePath : this.texturesLoadedIntoMemory.keySet()){
this.queueTextureForDeletion(texturePath);
}
lock.unlock();
}
@ -670,6 +694,40 @@ public class AssetManager {
lock.unlock(); lock.unlock();
} }
/**
* Queues a shader for deletion
* @param shaderPath The path to the shader
*/
public void queueShaderForDeletion(String shaderPath){
lock.lock();
shadersInDeleteQueue.add(shaderPath);
lock.unlock();
}
/**
* Queues all shaders for deletion
*/
public void queueAllShadersForDeletion(){
lock.lock();
for(String shaderKey : this.shadersLoadedIntoMemory.keySet()){
this.queueShaderForDeletion(shaderKey);
}
lock.unlock();
}
/**
* Deletes all shaders in the delete queue
*/
public void deleteShadersInDeleteQueue(){
lock.lock();
for(String shaderKey : this.shadersInDeleteQueue){
VisualShader shader = this.shadersLoadedIntoMemory.remove(shaderKey);
shader.free();
}
this.shadersInDeleteQueue.clear();
lock.unlock();
}
// //
//SHADERS //SHADERS
// //

View File

@ -234,6 +234,9 @@ 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; activeShader = program;
if(!GL40.glIsProgram(activeShader.getId()) && activeShader.getId() != Shader.UNBIND_SHADER_ID){
throw new Error("Tried to bind shader that is not an active program! " + activeShader.getId());
}
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

@ -7,6 +7,11 @@ import electrosphere.renderer.OpenGLState;
*/ */
public interface Shader { public interface Shader {
/**
* ID to unbind a shader
*/
public static final int UNBIND_SHADER_ID = 0;
/** /**
* Returned if the uniform isn't found * Returned if the uniform isn't found
*/ */

View File

@ -15,7 +15,6 @@ import javax.management.RuntimeErrorException;
import org.lwjgl.opengl.GL40; import org.lwjgl.opengl.GL40;
import electrosphere.engine.Globals; import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.logger.LoggerInterface; import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.OpenGLState; import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.RenderingEngine;
@ -262,74 +261,6 @@ public class VisualShader implements Shader {
return rVal; return rVal;
} }
/**
* Loads the default shader program
* @return The default shader
*/
public static VisualShader loadDefaultShaderProgram(){
//
//Create ShaderProgram object
//
VisualShader rVal = new VisualShader();
//
//Read in shader programs
//
String vertexShaderSource = VisualShader.recursivelyPreprocessFile(AssetDataStrings.SHADER_DEFAULT_VERT);
String fragmentShaderSource = VisualShader.recursivelyPreprocessFile(AssetDataStrings.SHADER_DEFAULT_FRAG);
//Creates a new shader object and assigns its 'pointer' to the integer "vertexShader"
rVal.vertexShader = GL40.glCreateShader(GL40.GL_VERTEX_SHADER);
//This alerts openGL to the presence of a vertex shader and points the shader at its source
GL40.glShaderSource(rVal.vertexShader, vertexShaderSource);
//Compiles the source for the vertex shader object
GL40.glCompileShader(rVal.vertexShader);
//The following tests if the vertex shader compiles successfully
int success;
success = GL40.glGetShaderi(rVal.vertexShader, GL40.GL_COMPILE_STATUS);
if (success != GL40.GL_TRUE) {
LoggerInterface.loggerRenderer.WARNING("Vertex Shader failed to compile!");
LoggerInterface.loggerRenderer.WARNING("Source is: ");
LoggerInterface.loggerRenderer.WARNING(GL40.glGetShaderSource(rVal.vertexShader));
LoggerInterface.loggerRenderer.ERROR("Runtime Exception", new RuntimeException(GL40.glGetShaderInfoLog(rVal.vertexShader)));
}
//Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader
rVal.fragmentShader = GL40.glCreateShader(GL40.GL_FRAGMENT_SHADER);
//This points the opengl shadder object to its proper source
GL40.glShaderSource(rVal.fragmentShader, fragmentShaderSource);
//This compiles the shader object
GL40.glCompileShader(rVal.fragmentShader);
//This tests for the success of the compile attempt
success = GL40.glGetShaderi(rVal.fragmentShader, GL40.GL_COMPILE_STATUS);
if (success != GL40.GL_TRUE) {
LoggerInterface.loggerRenderer.WARNING("Fragment Shader failed to compile!");
LoggerInterface.loggerRenderer.WARNING("Source is: ");
LoggerInterface.loggerRenderer.WARNING(GL40.glGetShaderSource(rVal.fragmentShader));
LoggerInterface.loggerRenderer.ERROR("Runtime Exception", new RuntimeException(GL40.glGetShaderInfoLog(rVal.fragmentShader)));
}
//This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram
rVal.shaderId = GL40.glCreateProgram();
//This attaches the vertex and fragment shaders to the program
GL40.glAttachShader(rVal.shaderId, rVal.vertexShader);
GL40.glAttachShader(rVal.shaderId, rVal.fragmentShader);
//This links the program to the GPU (I think its to the GPU anyway)
GL40.glLinkProgram(rVal.shaderId);
//Tests for the success of the shader program creation
success = GL40.glGetProgrami(rVal.shaderId, GL40.GL_LINK_STATUS);
if (success != GL40.GL_TRUE) {
throw new RuntimeException(GL40.glGetProgramInfoLog(rVal.shaderId));
}
//Deletes the individual shader objects to free up memory
GL40.glDeleteShader(rVal.vertexShader);
GL40.glDeleteShader(rVal.fragmentShader);
return rVal;
}
/** /**
* Loads a specific shader * Loads a specific shader
* @param vertexPath The vertex shader's path * @param vertexPath The vertex shader's path
@ -544,4 +475,13 @@ public class VisualShader implements Shader {
return this.shaderId; return this.shaderId;
} }
/**
* Frees the shader
*/
public void free(){
GL40.glDeleteShader(this.getId());
this.shaderId = VisualShader.INVALID_UNIFORM_NAME;
}
} }