This tutorial shows the usage of lazily-initialized uniforms. Unlike regular Uniforms which require the program, which they reference to be compiled and linked before the
Uniform is constructed, lazy uniforms only require that the Program instance exists - it does not have to be built yet. LazyUniforms postpone the initialization until the value of the uniform is set or some other operation is executed.
If you are not familiar with the basics of OGLplus, it is recommended that you read the RGB triangle first for a more detailed introduction. You can also see the Basic usage with GLUT and GLEW for a complete standalone example including the code responsible for window initialization, OpenGL initialization and event handling.
The new things that this tutorial covers are:
For a full working code see the
oglplus/004_rect.cpp file in the example directory.
Like in the previous tutorials we first include the header that makes sure that the OpenGL symbols are defined and the one that includes everything from OGLplus,
and also the header declaring the base class for OGLplus examples.
Just like the other examples that come with the library this one is also implemented inside of the
As before, the example code is encapsulated in the
RectangleExample class which is derived from
Most of the member variables are the same as in the previous tutorials. There is an instance of the
oglplus::Context class wrapping the current context functions:
The following line is a little different from the previous tutorials. We could have used
oglplus::VertexShader and a
oglplus::FragmentShader types, but sometimes it is necessary to decide what kind of shader we want at run-time (based for example on some input data). This tutorial is not one of those time, but we take this opportunity to show the usage of untyped shaders:
Now we declare three oglplus::LazyUniform variables which set the values of the
GreenCenter uniform variables in the fragment shader below. The uniforms in the shader have the
vec2 type - hence the
Vec2f template parameter for
The public interface again consists of a constructor and a couple of member functions.
The constructor constructs the vertex and fragment shaders, using the oglplus::ShaderType:
The following line is technically not necessary, but it is here to remind us that the program must be constructed before we try to initialize the uniforms:
Now we can initialize the uniforms, the constructor takes a reference to a Program and the identifier of the variable that we wish to reference by the
Now we can set the source of the vertex shader. There is one new thing here - we are wrapping the source string in the
StrLit class to tell the shader that it is initialized from a literal (which allows OGLplus and the compiler to do some optimizations):
The vertex shader is complete and can be compiled.
The fragment shader is similar to the one from the previous tutorials. It has one input variable - the vertex coordinate that will be used in the newton fractal computations.
Also note the three uniform variables, that specify the centers of the red, green and blue 'lights' on the surface of the rendered rectangle:
As before, the output of the shader is a vec4 representing the color of the fragment.
Then we calculate the distances of the fragment from the centers of the three 'lights' stored in the uniforms, store them in a vector and then use the values to colorize the fragment.
We can now compile the fragment shader source code, attach both shaders to the shading program and try to link and use it.
Now we can start to specify the data for the individual vertex attributes of the rectangle we're going to render. The first step as before is to bind the vertex array object managing the vertex data.
Again, since this is a simple example the coordinates are hardcoded.
We bind the VBO for vertex positions to the
The data are uploaded from client's memory to the server's memory by using the
Data static function.
Then we use a oglplus::VertexAttribArray object referencing the
Position input variable in the
prog program, to tell OpenGL about the structure of the data in the currently bound VBO and to enable this vertex attribute.
Now we can specify the values of the uniform variables. Note that because we used lazily-initialized uniforms, the uniform variables in the compiled program are referenced only now. We use the
Set function with two parameters since the underlying uniform type is
The rest of the tutorial is basically the same as before. We finish the constructor and we implement the
Render member functions and the
makeExample function for creating an instance of the