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 oglplus
namespace.
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 oglplus::Example
.
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::VertexShader
and oglplus::FragmentShader
, 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 version
directive.
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 vertColor
.
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 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::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.
The 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.
Now the 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 Reshape
and Render
when appropriate. To see how this can be incorporated into a complete application see the standalone examples and the related tutorials.