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 occasional updates? Please sign up for my free newsletter.

Copyright Bartlomiej Filipek, 2016, 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.