This will basically allow clients to add custom shader programs to the Renderer and associate the shaders with different models/tasks.
High Level
We need basically an enum to identify the shader type (regular shader for renderables, shader for skybox, shader for picking, shader for post-processing, etc)
The client should be able to do 2 things
Define a shader program and attach it to a task (e.g. skybox) in the renderer.
Define a shader program and attach it to a model. Each model should be able to safely share references to shader programs (which will be the case 99% of the time).
Low Level
This is the tricky part. Basically each ShaderProgram class should know what uniforms and what attributes the shaders themselves have defined. The client will supply this definition.
Ex) If the shader is intended for models with position and colours defined as attributes, the ShaderProgram class should have the name and types for the attributes found in the shader code provided. If the uniform variables are the model, view, and projection matrices, the ShaderProgram class needs to identify that.
The harder part is basically integrating the shader code with the abstractions provided (such as Light, Fog, etc). I think the best way of doing that is providing a standardized interface for the ShaderProgram class that states what functionality the shader. Suppose the ShaderProgram class has an interface:
boolean hasDiffuseLight();
boolean hasFog();
Then every derived ShaderProgram would override hasDiffuseLight and hasFog and return true if that shader provides that support. I think it would be best (for now) to standardize the types for each component (i.e. light always comes as vec3). This way each abstraction basically handles the data processing and the passing the data to the shader, but the shaders can be customized by the user.
This will basically allow clients to add custom shader programs to the Renderer and associate the shaders with different models/tasks.
High Level
Low Level
Ex) If the shader is intended for models with position and colours defined as attributes, the ShaderProgram class should have the name and types for the attributes found in the shader code provided. If the uniform variables are the model, view, and projection matrices, the ShaderProgram class needs to identify that.
The harder part is basically integrating the shader code with the abstractions provided (such as Light, Fog, etc). I think the best way of doing that is providing a standardized interface for the ShaderProgram class that states what functionality the shader. Suppose the ShaderProgram class has an interface:
boolean hasDiffuseLight(); boolean hasFog();
Then every derived ShaderProgram would override hasDiffuseLight and hasFog and return true if that shader provides that support. I think it would be best (for now) to standardize the types for each component (i.e. light always comes as vec3). This way each abstraction basically handles the data processing and the passing the data to the shader, but the shaders can be customized by the user.