03 December 2012

OpenGL startup V3.0


Over the years I've created several frameworks for OpenGL Applications. Although some of them were only a private libraries I've managed to write some code that was actually used by some other people as well. In my previous posts (startup_1startup_2startup_3) I described the "first" version of the framework for my workshops. This framework evolved and now I can say that it is in the "third" version.
This post is a description of this new framework.

Design goals

  • Be as simple as possible. This means no complex class hierarchies. No complex design patterns. 
  • Small amount of additional code - the whole pack should be quite small. Students should be able to grab a whole solution (without downloading tens of MB) and quickly compile this.
  • Modern OpenGL. My previous frameworks was a mix of OpenGL 2.0 and 3.0... now I wanted to have only 3.+ solution. Unfortunately this involves some third party math library, additional code for shader loading, etc, etc.
  • Easy to read and understand.

Components

  • C++
  • freeGLUT
  • GLM
  • SOIL
  • antTweakBar
  • glLoadGen
  • custom code: shader loading, shader object wrapper, logger, utils
  • VisualStudio 2008, 2010, 2012 - code is based on freeGLUT thus it should be not so hard to compile it under Linux/Mac
Example file structure

Physical Structure

  • app.cpp - source file with custom code for the app (name can be different, like w04_stripes.cpp in the picture on the right)
  • main.h/main.cpp - main code for the framework - GLUT init, OpenGL 3.* functions loading, basic GLUT event handling, timer, antTweakBar init & event handling (mouse only).
  • addons folder - folder with all the additional libraries - headers and libs - GLM, freeGlut, SOIL library, OpenGL Loader
  • commonCode - Shaders, utils and additionally Framebuffer wrappers and Geometry utils
  • data and shaders folders

Code structure

main()
1. init_glut
2. set glut callbacks
3. init GL (load extensions, print some basic info)
4. init antTweakBar
5. call initApp() - calls custom function defined in app.cpp file
6. call glutMainLoop()
7. call cleanUp() - cunstom function defined in app.cpp file
8. cleanup additional libs like antTweakBar
GLUT callbacks:
callbacks are used to process basic events (like for antTweakBar) and they call custom code defined in app.cpp file.
// window:
void mainChangeSize(int w, int h);

// mouse:
void mainProcessMouse(int button, int state, int x, int y);
void mainProcessMouseMotion(int x, int y);
void mainProcessMousePassiveMotion(int x, int y);

mainIdle
updates the timer, calculates fps, calls updateScene and renderScene custom functions
    
{
    double deltaTime;
    utils::updateTimer(&deltaTime, &Globals::sAppTime);
 
    utils::calculateFps(&Globals::sFps);

    updateScene(deltaTime);

    renderScene();

    TwDraw();
    glutSwapBuffers();
}
Custom code
This is defined in app.cpp file, contains code specific for the particular application.
// init textures, camera, shaders, etc, etc
bool initApp()

void cleanUp();

// window:
void changeSize(int w, int h);

// keyboard:
void processNormalKeys(unsigned char key, int x, int y);
void pressSpecialKey(int key, int x, int y);
void releaseSpecialKey(int key, int x, int y);

// mouse:
void processMouse(int button, int state, int x, int y);
void processMouseMotion(int x, int y);
void processMousePassiveMotion(int x, int y);

// update & rendering (called from mainIdle())
void updateScene(double deltaTime);
void renderScene();

Example Code

// shader loading
ShaderProgram gStripesProgram; // declared as global (not nice!)
shaderUtils::loadAndBuildShaderPairFromFile(&gStripesProgram, 
                                            "shaders/stripes.vs", 
                                            "shaders/stripes.fs");

// transformations & camera (declared as globals)
glm::vec3 gCamPos;
glm::mat4 gModelViewMatrix;
glm::mat4 gProjectionMatrix;

// in renderScene:
gModelViewMatrix = glm::lookAt(gCamPos, glm::vec3(0.0f, 0.0f, gCamPos[2]-2), 
                               glm::vec3(0.0f, 1.0f, 0.0f));

// shader setup:
gStripesProgram.use();
    
gStripesProgram.uniform1f("animParam", gAnimParam);
gStripesProgram.uniform1i("texture0", 0);
gStripesProgram.uniformMatrix4f("projectionMatrix", 
                                glm::value_ptr(gProjectionMatrix));
gStripesProgram.uniformMatrix4f("modelviewMatrix",  
                                glm::value_ptr(gModelViewMatrix));

// Tweak:
TwAddVarRW(Globals::sMainTweakBar, "camera Z", TW_TYPE_FLOAT, 
           &gCamPos[2], "min=0.0 max=12.0 step=0.1");

Screens




Problems

  • Use of globals - I do not like usage of global variables, but it is very convenient when creating simple examples for classes.
  • C style for most of the framework. C style is quite clean, but maybe C++ (with some classes) would not be so scarry.

Future improvements

  • new framework for WebGL? Most of my classes are in C++, but in a future version I could use some other language. Maybe WebGL (thus JavaScript) would be also nice.

Links

Interested in new blog posts and bonus content? Sign up for my newsletter.

© 2017, Bartlomiej Filipek, Blogger platform
Any opinions expressed herein are in no way representative of those of my employers.
This site contains ads or referral links, which provide me with a commission. Thank you for your understanding.