Developing Algorithms
The renderer is designed to facilitate the development of new algorithms. All that is necessary to this end is implementing two callbacks.PreProcess is used in conjunction with multipass algorithms to render to a texture which may then be used in postProcess. PostProcess in contrary is used to render directly to the screen. For algorithms that don't need multiple passes, it is sufficient to implement only postProcess.
Each algorithm has a render() method which may be used multiple times to render the scene.
If you plan to use OpenGL, don't forget to put
at the beginning of each method.
Developing Shading and Shadow Algorithms
For developing new shading or shadow algorithms, two other callbacks are of interest.This approach requires editing the main shader main-shader.vert and main-shader.frag, as shading and shadows are dependent on each other. For example, you don't want shading where an object is in shadow. It is recommended to first develop a prototype using a separate shader and the usual preProcess and postProcess mechanism, however.
Prepare takes care of setting shader uniform variables and binding textures. CleanUp is used to unbind textures. Furthermore, a boolean uniform variable in the main shader should indicate whether the respective algorithm is active. It is important to reset this variable to false in cleanUp. Otherwise, the algorithm would stay active even after it was disabled.
To set uniform variables, first request the main shader from the renderer using
Since now multiple algorithms may want to bind textures independent from each other, the renderer itself keeps track of the current texture unit. To get the next available texture unit, use
Assuming unit is the value returned from getNextTextureUnit(), you can now activate a texture unit using
Rendering to Textures
For rendering to textures, a RenderToTexture class is available. It encapsulates framebuffer objects, but provides an automatic fallback to copying from the regular read buffer to a texture.
creates a RenderToTexture object. If framebuffer objects are supported, the texture size will be a power of 2 size fitting or larger than the screen. Otherwise, the size is set to the next smaller power of two to the screen size.
Creates a RenderToTexture object of specified width and height. Width and height should be power of 2 for performance reasons. If framebuffer objects are not supported, the size is set to the next smaller power of two to the screen size.
Begins rendering to the texture. If framebuffer objects are supported, all rendering operations are now bound to the framebuffer.
Ends rendering to the texture. All rendering operations are now returned to the previous buffer (probably GL_BACK).
Binds the color texture.
Binds the depth texture.
Disables the texture.
GLSL
Another class that is useful for developing algorithms is the GLSL class. The example below shows how to use it.void setup(){
// ... normal setup stuff ...
glsl=new GLSL();
glsl.loadVertexShader("myShader.vert");
glsl.loadFragmentShader("myShader.frag");
glsl.useShaders();
}
void draw(){
glsl.startShader();
//draw stuff
glsl.endShader();
}
In addition, the GLSL class offers various methods for setting uniform variables in a shader. Before, the uniform location has to be fetched using getUniformLocation. To set uniform variables, startShader() has to be called first.