OGLplus (0.52.0) a C++ wrapper for OpenGL

RGB color mixing (lazy uniforms)

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:

  • Lazy uniform variables
  • Untyped shaders

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,

#include <oglplus/gl.hpp>
#include <oglplus/all.hpp>

and also the header declaring the base class for OGLplus examples.

#include "example.hpp"

Just like the other examples that come with the library this one is also implemented inside of the oglplus namespace.

namespace oglplus {
Real-life applications should instead do something like:

using namespace oglplus;

As before, the example code is encapsulated in the RectangleExample class which is derived from oglplus::Example.

class RectangleExample : public Example

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:

Context gl;

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:

Shader vs, fs;

next there is a oglplus::Program a oglplus::VertexArray object managing the vertex data for the rendered rectangle stored in oglplus::Buffer.

// Program
Program prog;
// A vertex array object for the rendered rectangle
VertexArray rectangle;
// VBO for the rectangle's vertices
Buffer verts;

Now we declare three oglplus::LazyUniform variables which set the values of the RedCenter, BlueCender and GreenCenter uniform variables in the fragment shader below. The uniforms in the shader have the vec2 type - hence the Vec2f template parameter for LazyUniform.

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 LazyUniform:

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 ARRAY_BUFFER target.

The data are uploaded from client's memory to the server's memory by using the Buffer 's 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 Vec2f.

The rest of the tutorial is basically the same as before. We finish the constructor and we implement the Reshape and Render member functions and the makeExample function for creating an instance of the RectangleExample class.

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).