A simple to use, general purpose, 3D media framework using OpenGL, OpenAL and OpenDE

Development

I’ve added the Red Book Cubemap example to the OpenGL 4 Tutorial Code page.
Red Book Chapter 6, OpenGL 4.3 Cube Map Example

I had to use a different 3d object because the object loader used by the Red Book segfaults (on my system) with the object originally used in this example.
Instead of trying to bugfix and change the loader code I just used another object (still from the redbook files).

I’ve added the shadowmap example to the OpenGL 4 Tutorial Code (Red Book) page.

I had to change

    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depth_texture, 0);

to

    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_texture, 0);

otherwise I get GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT from

 
glCheckFramebufferStatus(GL_FRAMEBUFFER);

Not sure why this happens. (Driver is NVIDIA 340.24 on Ubuntu 14.04)

I’ve made a page (OpenGL 4 Tutorial Code (Red Book)) with the Red Book examples I’ve ported so far.

This include a simple example showing of the different drawing commands and one showing how to instance vertex buffer objects.

Currently there’s only simple build scripts for Linux but they should compile on any system with SDL2 glew(1.10) and glm(0.9.5.1)

I’ve ported one of the Red Book OpenGL 4.3 code examples (ch03_drawcommands) to SDL2 using glew and glm

The main source file is below and the complete source (including shaders) is here: redbook_chapter_03_drawcommands_SDL2_GLM.zip
It contains a simple build script for Linux. You only need to install SDL2, glew and glm using your favourite package manager.

I’m not going to explain the code beyond the comments. If you’re serious about OpenGL 4.x+ you should buy the Red Book (8th edition)

Update:
I’ve made a page with some other Red Book OpenGL 4 examples that I’ve ported. Currently there are 3d object instancing, shadowmapping and cubemapping.
They can be found here: OpenGL 4 Example Code

#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> 
#include <SDL2/SDL.h>

#include "LoadShaders.h"
extern GLuint LoadShaders(ShaderInfo *shaderinfo);

#define PROGRAM_NAME "Red Book - Chapter 3 - Draw Commands"
 
void Initialize();
void Display();
void Finalize(void);
void Reshape(int width, int height);

float aspect;
GLuint render_prog;
GLuint vao;
GLuint vbo;
GLuint ebo;

GLint render_model_matrix_loc;
GLint render_projection_matrix_loc;

void Initialize() {

    ShaderInfo shader_info[] = {
      { GL_VERTEX_SHADER, "primitive_restart.vs.glsl" },
      { GL_FRAGMENT_SHADER, "primitive_restart.fs.glsl" },
      { GL_NONE, NULL }
    };

  render_prog = LoadShaders(shader_info);
  glUseProgram(render_prog);

  render_model_matrix_loc = glGetUniformLocation(render_prog, "model_matrix");
  render_projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix");

  // A single triangle
  static const GLfloat vertex_positions[] = {
      -1.0f, -1.0f,  0.0f, 1.0f,
      1.0f, -1.0f,  0.0f, 1.0f,
      -1.0f,  1.0f,  0.0f, 1.0f,
      -1.0f, -1.0f,  0.0f, 1.0f,
  };

  // Color for each vertex
  static const GLfloat vertex_colors[] = {
      1.0f, 1.0f, 1.0f, 1.0f,
      1.0f, 1.0f, 0.0f, 1.0f,
      1.0f, 0.0f, 1.0f, 1.0f,
      0.0f, 1.0f, 1.0f, 1.0f
  };

  // Indices for the triangle strips
  static const GLushort vertex_indices[] = {
      0, 1, 2
  };

  // Set up the element array buffer
  glGenBuffers(1, &ebo);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW);

  // Set up the vertex attributes
  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);

  glGenBuffers(1, &vbo);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions) + sizeof(vertex_colors), NULL, GL_STATIC_DRAW);
  glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_positions), vertex_positions);
  glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_positions), sizeof(vertex_colors), vertex_colors);

  glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
  glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)sizeof(vertex_positions));
  glEnableVertexAttribArray(0);
  glEnableVertexAttribArray(1);

  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

void Display() {
  glm::mat4 model_matrix;

  // Setup
  glEnable(GL_CULL_FACE);
  glDisable(GL_DEPTH_TEST);

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  // Activate simple shading program
  glUseProgram(render_prog);

  // Set up the model and projection matrix
  glm::mat4 projection_matrix(glm::frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 500.0f));
  glUniformMatrix4fv(render_projection_matrix_loc, 1, GL_FALSE, glm::value_ptr(projection_matrix));

  // Set up for a glDrawElements call
  glBindVertexArray(vao);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

  // Draw Arrays...
  model_matrix = glm::translate(glm::mat4(1.0f),glm::vec3(-3.0f, 0.0f, -5.0f));
  glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, glm::value_ptr(model_matrix));
  glDrawArrays(GL_TRIANGLES, 0, 3);

  // DrawElements
  model_matrix = glm::translate(glm::mat4(1.0f),glm::vec3(-1.0f, 0.0f, -5.0f));
  glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, glm::value_ptr(model_matrix));
  glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL);

  // DrawElementsBaseVertex
  model_matrix = glm::translate(glm::mat4(1.0f),glm::vec3(1.0f, 0.0f, -5.0f));
  glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, glm::value_ptr(model_matrix));
  glDrawElementsBaseVertex(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, NULL, 1);

  // DrawArraysInstanced
  model_matrix = glm::translate(glm::mat4(1.0f),glm::vec3(3.0f, 0.0f, -5.0f));
  glUniformMatrix4fv(render_model_matrix_loc, 1, GL_FALSE, glm::value_ptr(model_matrix));
  glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1);
}

void Finalize(void) {
  glUseProgram(0);
  glDeleteProgram(render_prog);
  glDeleteVertexArrays(1, &vao);
  glDeleteBuffers(1, &vbo);
}

void Reshape(int width, int height) {
  glViewport(0, 0 , width, height);
  aspect = float(height) / float(width);
}
 
int main(int argc, char *argv[]){
 
  SDL_Window *mainwindow; /* Our window handle */
  SDL_GLContext maincontext; /* Our opengl context handle */

  if (SDL_Init(SDL_INIT_VIDEO) < 0) { /* Initialize SDL's Video subsystem */
    std::cout << "Unable to initialize SDL"; 
    return 1;
  }

  /* Request opengl 4.4 context. */
  SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4);
 
  /* Turn on double buffering with a 24bit Z buffer.
   * You may need to change this to 16 or 32 for your system */
  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 
  /* Create our window centered at 512x512 resolution */
  mainwindow = SDL_CreateWindow(PROGRAM_NAME, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
				512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
  if (!mainwindow){ /* Die if creation failed */
     std::cout << "SDL Error: " << SDL_GetError() << std::endl;
     SDL_Quit();
     return 1;
  } 

  /* Create our opengl context and attach it to our window */
  maincontext = SDL_GL_CreateContext(mainwindow);
 
  GLenum rev;
  glewExperimental = GL_TRUE; 
  rev = glewInit();

  if (GLEW_OK != rev){
      std::cout << "Error: " << glewGetErrorString(rev) << std::endl;
      exit(1);
  } else {
      std::cout << "GLEW Init: Success!" << std::endl;
  }

  /* This makes our buffer swap syncronized with the monitor's vertical refresh */
  
SDL_GL_SetSwapInterval(1);
  
  bool quit=false;

  Initialize();
  Reshape(512,512);

  SDL_Event event;

  while(!quit){

    Display();
    SDL_GL_SwapWindow(mainwindow);

    while( SDL_PollEvent( &event ) ){
	if( event.type == SDL_QUIT ){
            quit = true;
	  }
      }
  } 

  Finalize();

  /* Delete our opengl context, destroy our window, and shutdown SDL */
  SDL_GL_DeleteContext(maincontext);
  SDL_DestroyWindow(mainwindow);
  SDL_Quit();
 
  return 0;
}

OME has just been blessed with a cleaned up C API exposing all member functions of the central meContext class. Using this API I’m also almost done writing support for embedded Lua scripting.

To check out the API browse this file:
OME C API

Feel the source Luke!

If your brave enough you can download and compinstall the entire code in its alpha state.
Currently only Linux compiles (easily anyway)

(my system which is fairly tested is Ubuntu 10.10)

In a shell type:
hg clone http://juvul.com:8000/OME OME
cd OME
sh autogen && configure && make && sudo make install

and the run MIDIumEdit
or
omeplayer

supported data formats are:
COMMON INTERCHANGE FORMATS
Collada ( .dae )
3ds Max 3DS ( .3ds )
3ds Max ASE ( .ase )
Wavefront Object ( .obj )
Stanford Polygon Library ( .ply )
* AutoCAD DXF ( .dxf )
LightWave ( .lwo )
Modo ( .lxo )
Stereolithography ( .stl )
AC3D ( .ac )
Milkshape 3D ( .ms3d )
* TrueSpace ( .cob,.scn )

GAME FILE FORMATS
* Valve Model ( .smd,.vta )
Quake I ( .mdl )
Quake II ( .md2 )
Quake III ( .md3 )
* Return to Castle Wolfenstein ( .mdc )
Doom 3 ( .md5* )