Use a GLSL Shader
Source file: GLShadingLangExample01
JavaDoc: GlslProgram
JavaDoc: GlslPolygonShader
This tutorial includes three different examples. The first two illustrate using the GlslPolygonShader
class; the third illustrates how to use the standard DefaultPolygonShader
class.
Example 1
The shading process in jReality is designed to accommodate customized shaders. For example, the JOGL backend supports polygon shaders written in the OpenGL Shading Language (or GLSL for short). The following example shows how to attach a GLSL shader to a jReality scene graph. It uses a publicly available GLSL brick shader which is also distributed with the jReality package.
When other backends rendering a scene graph where a GLSL shader appears, they use the default polygon shader.
... public class GLShadingLangExample01 { public static void main(String[] args) { SceneGraphComponent world = SceneGraphUtility.createFullSceneGraphComponent("world"); Appearance ap = world.getAppearance(); DefaultGeometryShader dgs = (DefaultGeometryShader) ShaderUtility.createDefaultGeometryShader(ap, true); dgs.setShowLines(false); dgs.setShowPoints(false); dgs.createPolygonShader("glsl"); GlslProgram brickProg = null; world.setGeometry(SphereUtility.tessellatedIcosahedronSphere(3, true)); try { brickProg = new GlslProgram(ap, "polygonShader", Input.getInput("de/jreality/jogl/shader/resources/brick.vert"), Input.getInput("de/jreality/jogl/shader/resources/brick.frag") ); } catch (IOException e) { e.printStackTrace(); } double[] brickSize = {.2, .25}; double[] brickPct = {.5, .75}; double[] mortarPct = new double[2]; double[] lightPosition = {-2,0,4}; mortarPct[0] = 1.0 - brickPct[0]; mortarPct[1] = 1.0 - brickPct[1]; brickProg.setUniform("SpecularContribution", .5); brickProg.setUniform("DiffuseContribution", 1.0); brickProg.setUniform("BrickColor", new double[]{.2,0f,.8}); brickProg.setUniform("MortarColor", new double[] {.8,1f,.2}); brickProg.setUniform("BrickSize", brickSize); brickProg.setUniform("BrickPct", brickPct); brickProg.setUniform("MortarPct", mortarPct); brickProg.setUniform("LightPosition", lightPosition); JRViewer.display(world); } }
Example 2
Source file: GLShadingLangExample02
This is another example showing how to create several different instances of the same GLSL brick shader.
The result should look like this:
Example 3
Source file: GLShadingLangExample03
In this example, you see how to activate GLSL shaders while using the DefaultPolygonShader
. Additionally, you'll see how to access textures in your GLSL shader, which you loaded into jReality.
To use GLSL shaders with a DefaultPolygonShader
, you need to do two things:
- Create an instance of
GlslProgram
exactly as above, and - Rather than creating an instance of
GlslPolygonShader
as above, create a default polygon shader and set the appearance attribute"useGLSL"
to true in the associated appearance.
dgs.createPolygonShader("default"); .... // dgs.createPolygonShader("glsl"); ap.setAttribute("useGLSL", true);
In this example, the GLSL shader used here is only the fragment shader (meaning the standard OpenGL vertex shader will be used). Of course, you can also provide a vertex shader of your own as in the examples above. The fragment shader "sampler.frag"
just looks up a color in a texture sampler and uses it as the fragment color.
Note that when using the default polygon shader, the geometry will be rendered using the older OpenGL style calls (including display lists if requested) rather than using vertex arrays.
The code also demonstrates how to pass a 2D texture sampler to the GLSL shader. Take a closer look at the code:
ImageData id = stf.getImageData(); Texture2D tex = TextureUtility.createTexture(ap, POLYGON_SHADER, 0, id); tex.setTextureMatrix(MatrixBuilder.euclidean().scale(5).getMatrix()); try { brickProg = new GlslProgram(ap, "polygonShader", null, Input.getInput("de/jreality/jogl/shader/resources/sampler.frag") ); } catch (IOException e) { e.printStackTrace(); } brickProg.setUniform("sampler", 0);
You create a texture just as you would normally. The argument 0
identifies the texture unit to be used with this texture. You can also omit this argument; the default value is 0. This texture is then processed by the DefaultPolygonShader and loaded into the OpenGL state. So the setUniform
method assigns same value 0
to the sampler
uniform variable.
We load a second texture into the second texture unit using this code
ImageData id = stf.getImageData(); Texture2D gradTexture = TextureUtility.createTexture(ap, POLYGON_SHADER, 1, id); ... brickProg.setUniform("sampler", 1);
Currently
Note: The same idea should work with the GlslPolygonShader
but doesn't currently work. (March 16, 2009).
|