blShapeAPI — A simple c++ shape API to construct and render static and live shapes in opengl

This entry is part 1 of 6 in the series blShapeAPI -- BarbatoLabs Shape API

Introduction

When first playing with opengl, everyone starts off with what is known as “direct-mode”, using the infamous glBegin() and glEnd() functions. They are very easy to use and produce much more readable code, at least to the beginners’ eyes. To draw a rectangle in direct mode, one would do the following:

glBegin(GL_QUADS);
    glVertex3f(0.0f,0.0f,0.0f);
    glVertex3f(1.0f,0.0f,0.0f);
    glVertex3f(1.0f,1.0f,0.0f);
    glVertex3f(0.0f,1.0f,0.0f);
glEnd();

The above code is very easy to understand, and if we wanted to we could apply a texture coordinate and/or normal coordinate before each vertex and so on. The main problem with the direct-mode approach is that it’s very slow. Even when using display lists, the code is very slow, as the processor has to sequentially go line through line.

GPUs are parallel machines by design, and they can batch process a lot of data in parallel. If we were to provide vertex data all at once, they could dump all that data in parallel directly to the screen. As it turns out, opengl provides such a mechanism through the use of vertex arrays, and provides an compiled data equivalent through the use of Vertex Buffer Objects (VBOs).

In this article, I present blShapeAPI, (BarbatoLabs Shape API), a simple c++ library that I have developed and evolved over the years to construct and render static or live shapes in opengl using vertex arrays and/or VBOs.

API Structure

The blShapeAPI structure is defined as follows:

Dependencies

Overall of course, this library depends on the opengl library. But it also needs the glext.h file and the blCheckForOPENGLExtensions.hpp file which I have packaged into the GLext.zip (1877) file.

  1. blShape dependencies
    1. ublas::matrix — Matrix class from the boost c++ libraries.
      1. Used to hold the vertex data, the normals, the texture coordinates and the vertex colors
    2. std::vector
      1. Used for the index array
    3. blColor4 — From the blImageAPI library
      1. Used to represent vertex colors
    4. blVector3d — From the blMathAPI library
      1. Used to represent the individual vertex coordinates
  2. blShapeVBO dependencies
    1. blShape — Parent class
    2. glGenBuffersARB
      1. Used to generate the VBOs
    3. glBindBufferARB
      1. Used to bind to the current VBO
    4. glDeleteBuffersARB
      1. Used to delete VBOs
    5. glIsBufferARB
      1. Used to check if a VBO is valid
  3. blShapeDraw dependencies
    1. blShapeVBO — Parent class
    2. GrabVBOfunctions
      1. Used to check if VBOs are available
    3. glEnableClientState
      1. Used to enable the vertex arrays
    4. GL_VERTEX_ARRAY — The vertex array state
    5. GL_NORMAL_ARRAY — The normals array state
    6. GL_TEXTURE_COORD_ARRAY — The texture coordinates array state
    7. GL_COLOR_ARRAY — The colors array state
    8. glVertexPointer
      1. Used to assign the vertex array
    9. glNormalPointer
      1. Used to assign the normals array
    10. glTexCoordPointer
      1. Used to assign the texture coordinates array
    11. glColorPointer
      1. Used to assign the colors array
    12. glGetFloatv
      1. Used to get the current model view matrix before translating, rotating and scaling so that it can be restored after we’re done drawing
    13. glLoadMatrixf
      1. Used to store the model view matrix after we’re done drawing

The code

My code uses inline documentation and follows a clean structure, (at least to me).

The blShapeAPI is made of several classes as shown above, and they’ve been placed inside the namespace blShapeAPI, which resides in the file blShapeAPI.hpp

Note: This file will change as I add more classes to it, but the latest version will be found in the downloads section at the bottom of this post

blShapeAPI.hpp (Click to see code…)

The blShape class is defined in the file blShape.hpp as follows:

blShape.hpp (Click to see code…)

The blShapeVBO class is defined in the file blShapeVBO.hpp file as follows:

blShapeVBO.hpp (Click to see code…)

And finally the blShapeDraw class is defined in the file blShapeDraw.hpp as follows:

blShapeDraw.hpp (Click to see code…)

Note: All shapes will be derived from these three classes and will be defined within the blShapeAPI namespace. The updated file is in the download section of this post.

Usage

As I build shapes, I will show you how to use them in a program. This article is just about the core shape API.

Downloads

I have put all the files into a zip file which can be downloaded here. All you have to do is extract it somewhere, let’s say in a directory called blShapeAPI, and then include the blShapeAPI.hpp file as follows:

#include "blShapeAPI/blShapeAPI.hpp"
using namespace blShapeAPI;

Note: The blShapeAPI depends on the blMathAPI and thus you’ll need both APIs:
blMathAPI.zip Ver 02/22/2011 2:50am (1724) blShapeAPI.zip Ver 11/27/2010 11:40PM (1206)

Updates

I forgot to mention that you’ll also need the glext.h file for opengl extensions with a special function to search for extensions which I placed in this file: GLext.zip (1877)

11/21/2010 — I updated the GenerateVertices function, so that when you generate a height map, you can control the maximum map height.

11/27/2010 — I added classes to construct super quadric shapes and dynamic super quadric height maps

About Vincenzo Barbato

Known to his friends as Enzo, he's an outside-the-box engineer/researcher whose interests and expertise span many fields, including controls systems, multi-physics simulations, mechatronics, oil technologies, data analysis and machine vision just to name a few.

Refusing to grow up, he's on a continuous journey to develop simple and creative solutions that have the power of disrupting industries by optimizing systems and processes.

Married to a beautiful wife, with two beautiful daughters and two identical twin boys, his home is a never ending chaotic fountain of inspiration.

His outlook on life:

"Never blindly accept what you're told, listen, but then question, with curiosity, creativity and collaboration we can change the world"

About Enzo

Known to his friends as Enzo, he's an outside-the-box engineer/researcher whose interests and expertise span many fields, including controls systems, multi-physics simulations, mechatronics, oil technologies, data analysis and machine vision just to name a few. Refusing to grow up, he's on a continuous journey to develop simple and creative solutions that have the power of disrupting industries by optimizing systems and processes. Married to a beautiful wife, with two beautiful daughters and two identical twin boys, his home is a never ending chaotic fountain of inspiration. His outlook on life: "Never blindly accept what you're told, listen, but then question, with curiosity, creativity and collaboration we can change the world"

Leave a Reply

Your email address will not be published. Required fields are marked *