This tutorial is an extension of the Basic usage with GLUT and GLEW tutorial, but it does not go through the code responsible for window initialization, OpenGL initialization and event handling.
For a full working code see the
oglplus/002_triangle.cpp file in the example directory.
First we include a locale helper header that in turn includes
GL3/gl3.h , GLEW or makes sure that the OpenGL symbols are defined. It is however not required for your applications to do it this way and if you wish you can use other means of defining the necessary OpenGL 3 functions, constants, etc.
Include everything from OGLplus, except the image loaders and generators and geometric shape data generators.
The header declaring the base class for OGLplus examples.
Since this is an example that comes with the library it is implemented inside of the
Doing this on the global scope may cause name clashes with other libraries especially in larger applications, so it may be a better idea to use fully qualified names or apply the
using directive only in local scopes.
As before, the rendering code is encapsulated in the
TriangleExample class which is derived from
Most of the member variables are the same as in the previous tutorial. There is an instance of the
oglplus::Context class wrapping the current context functions, a
oglplus::Program which define the custom functionality of the rendering pipeline and a
oglplus::VertexArray object managing the vertex data for the rendered triangle.
The first difference between this and the previous tutorial is that there are two
oglplus::Buffer objects, one for the vertex positions and the second for vertex colors.
The public interface consists of a constructor and a couple of member functions.
The constructor takes no arguments and again sets the vertex shader source:
As before we specify the version of GLSL we wish to use with the
Declare the input variables of the vertex shader;
Position for vertex positions and
Color for vertex colors.
This time there is also an explicitly declared output variable called
The main function again passes the value of the
Position input variable to the next stages of the rendering pipeline via the implicitly declared
gl_Position output variable:
We also pass the color value to the fragment shader, converting the RGB value into RGBA, with the alpha component set to 1.0.
That's it for the vertex shader and now it can be compiled:
The fragment shader is similar to the one from the previous tutorial:
This time there is a input variable
vertColor, matching the output variable from vertex shader in both name and type. The value of this variable will be smoothly interpolated across the surface of the rendered triangle.
The only thing the shader does is that is assigns the
vertColor value to the
fragColor output variable:
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 triangle we're going to render. The first step as before is to bind the vertex array object managing the vertex data.
Since this is a simple example the vertex positions 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::VertexArrayAttrib 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 repeat the steps above, for the second vertex attribute, specifying the colors of the individual vertices:
That's it for the vertex data specification. As the last step of initialization we specify the clear value for the color buffer and disable the depth test.
Reshape function gets called when the window is created and everytime the window's size changes. Here we tell the GL that the rendering viewport has changed.
This function redraws our scene and is basically the same as in the previous tutorial; we clear the color buffer and we tell the GL to draw triangle from the vertex data stored in the buffer objects tied to the currently bound VAO, which is still
triangle, because we didn't bind any other VAO since initialization. More precisely we draw the triangle composed from 3 vertices starting at index 0 in the buffers.
TriangleExample class is complete:
The last thing in this example's source is the
makeExample function. This function is called by shared internal piece of code (that comes with the examples) which does the initialization and event processing common to all the examples.
makeExample creates an instance of our
TriangleExample class. The common code then calls the event handler functions like
Render when appropriate. To see how this can be incorporated into a complete application see the standalone examples and the related tutorials.