Archive for July, 2014

OpenGL 4 Tutorial Code Update

I’ve added a few more Red Book (8th edition) examples including fur shading and tessellation.
All these examples use OpenGL 4.3, SDL2, glm and glew (except tessellation which uses freeglut)

OpenGL 4.3 draw commands using SDL2 glew and glm
OpenGL 4.3 object instancing (Red Book Chapter 3)
OpenGL 4.3 Shadow mapping (Red Book Chapter 4)
OpenGL 4.3 Cube mapping (Red Book Chapter 6)
OpenGL 4.3 Light Models (Red Book Chapter 8)
OpenGL 4.3 Fur shading using geometry shader (RedBook Chapter 10)
Tessellated Teapot (Red Book Chapter 9)
Order Independent Transparency (Red Book Chapter 11)

OpenGL Super Bible (OpenGL 4.3 Core) Example Code

The OpenGL SuperBible (6th edition) seems to have much better example code, for OpenGL 4.3, than the Red Book (8th edition).

You can download the source from git here: https://github.com/openglsuperbible/sb6code
(In Linux, just type git clone https://github.com/openglsuperbible/sb6code)
and download the media files here: http://openglsuperbible.com/files/sb6media_2013_11_10.zip

Currently there is a bug in the CmakeLists.txt that prevents linking on Linux systmes, in line 13 you need to change “elif (UNIX)” to “elseif (UNIX)” and you should be fine.

The SuperBible example code is based on glfw and in Linux you also need to install GLX and GL headers and libs.

OpenGL 4 CubeMap example (Red Book Chapter 6)

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).

OpenGL 4.3 Shadowmap (Red Book chapter 4)

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)

More OpenGL 4.x Red Book examples

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)

OpenGL 4.3/4.4 example using SDL2 and GLM

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;
}

Return top

Site News

If your brave enough you can download and install the entire code (alpha release). hg clone http://juvul.com:8000/OME OME Feedback can be sendt to info@juvul.com