blShapeQuadric — Construct and render static or dynamic Quadrics shapes in opengl

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

Introduction

As part of the blShapeAPI series, in this article I present blShapeQuadric, a class which will serve as the basic framework with which to build Quadric shapes.

Quadric shapes are simple shapes that have a virtually unlimited number of applications. Not only are they used in all the modern 3d graphics packages, but they can also be used to convey information in very powerful ways.

Here’s a simple example that I built using the blShapeQuadric class together with the blImageAPI to get a webcam feed.

Here you can see my hand being dynamically drawn on top of a quadric built using blShapeQuadric. We can easily use it for generating dynamic terrains, building all types of different shapes. Each vertex can have its own height, normal, texture coordinate and color.

Dependencies

blShape is derived from blShapeDraw

  1. blVector3d — From the blMathAPI library

The code

My code uses inline documentation and follows a clean structure, (at least to me). The blShapeQuadric class is saved in a file called blShapeQuadric.hpp as follows:

blShapeQuadric.hpp (Click to see code…)

Usage

To show the potential of blShapeQuadric, the following snippet shows how to create a height map, grab a video feed from a webcam, and use the grabbed frames to assign the height of the map’s vertices. It assigns the value of the frames pixels as the height of the vertices:

Note: The following snippet grabs the webcam feed naively, in later posts I will show you how to grab the video in parallel to the rendering thread.

<br />
int main(int argc, char *argv[])<br />
{<br />
    // Create an OpenGL window<br />
    // using the sfml library<br />
    sf::WindowSettings Settings;<br />
    Settings.DepthBits         = 24;<br />
    Settings.StencilBits       = 8;<br />
    Settings.AntialiasingLevel = 2;</p>
<p>    sf::Window App(sf::VideoMode(500,500,32),<br />
                   "SFML OpenGL",<br />
                   sf::Style::Close,<br />
                   Settings);</p>
<p>    glClearDepth(1.f);<br />
    glClearColor(0.f, 0.f, 0.f, 0.f);</p>
<p>    // Enable Z-buffer read and write<br />
    glEnable(GL_DEPTH_TEST);<br />
    glDepthMask(GL_TRUE);<br />
    glEnable(GL_TEXTURE_2D);</p>
<p>    // Setup a perspective projection<br />
    glMatrixMode(GL_PROJECTION);<br />
    glLoadIdentity();<br />
    gluPerspective(90.f, 1.f, 1.f, 1000.f);</p>
<p>    // Connect to the webcam<br />
    blCaptureDevice Webcam;<br />
    Webcam.ConnectToWebcam(0);</p>
<p>    // The webcam frame grayscale<br />
    blImage<float> Frame;</p>
<p>    // Create a texture<br />
    blTexture MyTexture;</p>
<p>    // Create a quadric surface<br />
    // and use triangles drawing mode<br />
    blShapeQuadric<float> MyQuad(20,20);<br />
    MyQuad.SetDrawingMode(GL_LINES);<br />
    MyQuad.GenerateVertices();<br />
    MyQuad.GenerateNormals();<br />
    MyQuad.GenerateTextureCoords();<br />
    //MyQuad.GenerateVBOs(true);</p>
<p>    // Grab a new frame from the webcam<br />
    Webcam.QueryFrame(Frame);</p>
<p>    // Load the grabbed frame into our texture<br />
    MyTexture.LoadImageToTexture(Frame,true,false);</p>
<p>    // Generate the vertices using<br />
    // the frame as our height map<br />
    MyQuad.GenerateVertices(Frame.GetImageDataCast(),Frame.size1(),Frame.size2(),0,1,true);</p>
<p>    // Generate the normals and texture coords<br />
    MyQuad.GenerateNormals();<br />
    MyQuad.GenerateTextureCoords();</p>
<p>    // Create a boolean to exit<br />
    // when the user decides to do so<br />
    bool Running = true;</p>
<p>    while (Running)<br />
    {<br />
        sf::Event MyEvent;<br />
        while(App.GetEvent(MyEvent))<br />
        {<br />
            if(MyEvent.Type == sf::Event::Closed)<br />
                Running = false;<br />
        }</p>
<p>        // Let's make sure our app is the<br />
        // active opengl rendering context<br />
        App.SetActive();</p>
<p>        // Let's do some clearing<br />
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
        glDisable(GL_CULL_FACE);</p>
<p>        // Let's do some moving around<br />
        glMatrixMode(GL_MODELVIEW);<br />
        glLoadIdentity();<br />
        glTranslatef(0.0f, 0.0f, -2.0f);<br />
        glColor4f(1,1,1,1);</p>
<p>        // Grab a new frame from the webcam<br />
        Webcam.QueryFrame(Frame);</p>
<p>        // Load the grabbed frame into our texture<br />
        MyTexture.LoadImageToTexture(Frame,true,false);</p>
<p>        // Generate the vertices using<br />
        // the frame as our height map<br />
        MyQuad.GenerateVertices(Frame.GetImageDataCast(),Frame.size1(),Frame.size2(),0,1,true);</p>
<p>        // Draw the quadric<br />
        MyQuad.Draw(true,true,false);</p>
<p>        // Let's move around a bit<br />
        glTranslatef(1,0.5,0);<br />
        glRotatef(-30,1,1,0);</p>
<p>        // Let's apply a yellow tint to it<br />
        glColor4f(1,1,0,1);</p>
<p>        // Let's draw the quadric again<br />
        MyQuad.Draw(true,true,true);</p>
<p>        // Display the opengl stuff<br />
        App.Display();<br />
    }<br />
}<br />

The resulting output is the following window:

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:

<br />
#include "blShapeAPI/blShapeAPI.hpp"<br />
using namespace blShapeAPI;<br />

Note: The blShapeAPI depends on the blMathAPI and thus you’ll need both APIs:

blMathAPI.zip Ver 02/22/2011 2:50am (1748) blShapeAPI.zip Ver 11/27/2010 11:40PM (1229)

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 (1904)

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

11/24/2010 — Changed the texture coordinate generation for the GL_QUADS case.  Now it generates the coordinates correctly.

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"

2 Comments

  1. Pingback: blShapePartialDisk — Construct and render static or dynamic partial disk shapes in opengl | BarbatoLabs

  2. Pingback: blShapeSuperEllipsoid — Construct and render super ellipsoid shapes and height maps in opengl | BarbatoLabs

Leave a Reply

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