We are pleased to announce the upcoming shader builder, to easily create custom shaders in AGE. This is part of our ongoing campaign to shield you from actual GL details, and writing shaders certainly qualifies!
You can already provide custom shaders to AGE, but are responsible for the actual GLSL code and its correct syntax, etc. The new ShaderBuilder class takes away a great deal of that pain, and also handles much of the "bookkeeping" aspects of creating shaders, like making sure varying shows up in both vertex and fragment shaders, and inserting GLSL for standard uniforms and attributes in a simple way.
An example is in order! The next sections show using the builder to create some of the pre-built AGE shaders.
Uniform color ("basic" AGE shader):
builder .mvpMatrix() .position() .fragmentUniform(GL_Vec4, UniformColor) .stdVertexPosition() .fragmentColor(UniformColor)
Per-vertex color ("cpv" AGE shader):
builder .mvpMatrix() .position() .color() .varying(GL_Vec4, "DestinationColor") .inVertex(assignment("DestinationColor", AttributeColor)) .stdVertexPosition() .fragmentColor("DestinationColor")
Texture mapping ("tex" AGE shader):
builder .mvpMatrix() .position() .texture() .textureUnit(UniformTexture1) .varying(GL_Vec2, "TextureCoord") .stdVertexPosition() .inVertex(assignment("TextureCoord", AttributeTexture)) .fragmentColor(texture2D(UniformTexture1, "TextureCoord"))
Mix 2 textures ("textex" AGE shader):
builder .mvpMatrix() .position() .texture() .textureUnit(UniformTexture1) .textureUnit(UniformTexture2) .fragmentUniform(GL_Float, UniformRatio) .varying(GL_Vec2, "TextureCoord") .stdVertexPosition() .inVertex(assignment("TextureCoord", AttributeTexture)) .fragmentColor(mix(texture2D(UniformTexture1, "TextureCoord"), texture2D(UniformTexture2, "TextureCoord"), UniformRatio))
The most-common things are expressible directly with the builder.
You are free to use as much "fluency" as desired; at some point it is less typing to supply an expression directly, e.g. "abc * def" as opposed to .multiply("abc","def") in builder syntax.
Once shader logic is complicated enough, you must submit complete GLSL code fragments to the builder to include in shader source output.
The final step is actually obtaining the GLSL source code for your brand new shader!
String vertexSource = builder.buildVertexShader(); String fragmentSource = builder.buildFragmentShader();
Are we just switching over to this internally? Probably not for the current set of shaders. The pre-built shaders are static strings, and that is just faster to access.