Developing Algorithms

The renderer is designed to facilitate the development of new algorithms. All that is necessary to this end is implementing two callbacks.
public void preProcess()
public void postProcess()

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.

public void render()

If you plan to use OpenGL, don't forget to put

renderer= (NPR)parent.g; gl= renderer.gl;

at the beginning of each method.

Developing Shading and Shadow Algorithms

For developing new shading or shadow algorithms, two other callbacks are of interest.
public void prepare()
public void cleanUp()

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

public GLSL getMainShader()

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

public int getNextTextureUnit()

Assuming unit is the value returned from getNextTextureUnit(), you can now activate a texture unit using

gl.glActiveTexture(renderer.textureUnits[GL.GL_TEXTURE0 + unit]);

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.

RenderToTexture()

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.

public RenderToTexture(int width, int height)

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.

public void begin()

Begins rendering to the texture. If framebuffer objects are supported, all rendering operations are now bound to the framebuffer.

public void end()

Ends rendering to the texture. All rendering operations are now returned to the previous buffer (probably GL_BACK).

public void bindColorTexture()

Binds the color texture.

public void bindDepthTexture()

Binds the depth texture.

public void unbind()

Disables the texture.

GLSL

Another class that is useful for developing algorithms is the GLSL class. The example below shows how to use it.
GLSL glsl;

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.

public int getUniformLocation(String name)
public void setTextureUnit(int location, int unit)
public void setBoolean(int location, boolean value)
public void setInteger(int location, int value)
public void setFloat(int location, float value)
public void setIntegerVec2(int location, int x, int y)
public void setFloatVec2(int location, float x, float y)
public void setIntegerVec3(int location, int x, int y, int z)
public void setFloatVec3(int location, float x, float y, float z)
public void setIntegerVec4(int location, int x, int y, int z, int w)
public void setFloatVec4(int location, float x, float y, float z, float w)
public void setMatrix3x3(int location, float[] data)
public void setMatrix4x4(int location, float[] data)