Previous: Quick tour of the demo.
Setting up the Shaders
This is followed by the shader setup, which uses GLScene helpers too, f.i. the fragment shader is created and compiled with
fragmentShader := TGLFragmentShader.Create(rc); if not fragmentShader.Compile(#" precision mediump float; varying vec4 vColor; void main(void) { gl_FragColor = vColor; }") then raise Exception.Create(fragmentShader.InfoLog);
The vertex shader is created & compiled similarly, then both are linked into a shader program:
shaderProgram := TGLShaderProgram.Create(rc); if not shaderProgram.Link(vertexShader, fragmentShader) then raise Exception.Create(shaderProgram.InfoLog);
Note that the shader program automatically builds a cache of uniforms and locations, and you can also use the AttribInfo[] and UniformInfo[] properties to enumerate attributes and uniforms.
Finally the Render loop is where you can see the vector & matrix helpers at work.
Since OpenGL ES 2.0 doesn’t include matrix stacks, you have to do them on your side, but this is easily achieved with a dynamic array’s Push() & Pop() pseudo-methods.
const cSpeed = 24*3600; var projMat, mvMat : Matrix4; mvStack : array of Matrix4; begin gl.ViewportSet(0, 0, canvas.Handle.width, canvas.Handle.height); gl.clear(gl.COLOR_BUFFER_BIT); shaderProgram.Use; projMat := Matrix4.CreatePerspective(45, canvas.width/canvas.height, 0.1, 100); mvMat := Matrix4.Identity; shaderProgram.SetUniform('uPMatrix', projMat); gl.enableVertexAttribArray(vertexPosAttrib); mvMat := mvMat.Translate([-1.5, 0, -7]); mvStack.Push(mvMat); mvMat := mvMat.RotateY(Frac(Now)*cSpeed); shaderProgram.SetUniform('uMVMatrix', mvMat); triangleBuffer.VertexAttribPointer(vertexPosAttrib, 3, false, 0, 0); gl.drawArrays(gl.TRIANGLES, 0, 3); mvMat := mvStack.Pop; mvMat := mvMat.Translate([3.0, 0, 0]).RotateX(Frac(Now)*cSpeed); shaderProgram.SetUniform('uMVMatrix', mvMat); squareBuffer.VertexAttribPointer(vertexPosAttrib, 3, false, 0, 0); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
The last bit I didn’t mention is the requestAnimationFrame shim, which is used to keep things rotating/animating, and which should at some point become part of the VJL or RTL.
So that’s about it for the walk-through!