Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying OpenGL Development Cookbook
  • Table Of Contents Toc
  • Feedback & Rating feedback
OpenGL Development Cookbook

OpenGL Development Cookbook

By : Movania
4.1 (10)
close
close
OpenGL Development Cookbook

OpenGL Development Cookbook

4.1 (10)
By: Movania

Overview of this book

OpenGL is the leading cross-language, multi-platform API used by masses of modern games and applications in a vast array of different sectors. Developing graphics with OpenGL lets you harness the increasing power of GPUs and really take your visuals to the next level. OpenGL Development Cookbook is your guide to graphical programming techniques to implement 3D mesh formats and skeletal animation to learn and understand OpenGL. OpenGL Development Cookbook introduces you to the modern OpenGL. Beginning with vertex-based deformations, common mesh formats, and skeletal animation with GPU skinning, and going on to demonstrate different shader stages in the graphics pipeline. OpenGL Development Cookbook focuses on providing you with practical examples on complex topics, such as variance shadow mapping, GPU-based paths, and ray tracing. By the end you will be familiar with the latest advanced GPU-based volume rendering techniques.
Table of Contents (10 chapters)
close
close
9
Index

Dynamically subdividing a plane using the geometry shader with instanced rendering

In order to avoid pushing the same data multiple times, we can exploit the instanced rendering functions. We will now see how we can omit the multiple glDrawElements calls in the previous recipe with a single glDrawElementsInstanced call.

Getting ready

Before doing this, we assume that the reader knows how to use the geometry shader in the OpenGL 3.3 core profile. The code for this recipe is in the Chapter1\SubdivisionGeometryShader_Instanced directory.

How to do it…

Converting the previous recipe to use instanced rendering requires the following steps:

  1. Change the vertex shader to handle the instance modeling matrix and output world space positions (shaders/shader.vert).
    #version 330 core
    layout(location=0) in vec3 vVertex;  
    uniform mat4 M[4];
    void main()
    {
      gl_Position =  M[gl_InstanceID]*vec4(vVertex, 1);
    }
  2. Change the geometry shader to replace the MVP matrix with the PV matrix (shaders/shader.geom).
    #version 330 core
    layout (triangles) in;
    layout (triangle_strip, max_vertices=256) out;
    uniform int sub_divisions;
    uniform mat4 PV;
    
    void main()
    {
      vec4 v0 = gl_in[0].gl_Position;
      vec4 v1 = gl_in[1].gl_Position;
      vec4 v2 = gl_in[2].gl_Position;
      float dx = abs(v0.x-v2.x)/sub_divisions;
      float dz = abs(v0.z-v1.z)/sub_divisions;
      float x=v0.x;
      float z=v0.z;
      for(int j=0;j<sub_divisions*sub_divisions;j++) {
        gl_Position =  PV * vec4(x,0,z,1);        EmitVertex();
        gl_Position =  PV * vec4(x,0,z+dz,1);     EmitVertex();
        gl_Position =  PV * vec4(x+dx,0,z,1);     EmitVertex();
        gl_Position =  PV * vec4(x+dx,0,z+dz,1);  EmitVertex();
        EndPrimitive();
        x+=dx;
        if((j+1) %sub_divisions == 0) {
          x=v0.x;
          z+=dz;
        }
      }
    }
  3. Initialize the per-instance model matrices (M).
    void OnInit() {
      //set the instance modeling matrix
      M[0] = glm::translate(glm::mat4(1), glm::vec3(-5,0,-5));
      M[1] = glm::translate(M[0], glm::vec3(10,0,0));
      M[2] = glm::translate(M[1], glm::vec3(0,0,10));
      M[3] = glm::translate(M[2], glm::vec3(-10,0,0));
      ..
      shader.Use();
        shader.AddAttribute("vVertex");
        shader.AddUniform("PV");
         shader.AddUniform("M");
         shader.AddUniform("sub_divisions");
         glUniform1i(shader("sub_divisions"), sub_divisions);
         glUniformMatrix4fv(shader("M"), 4, GL_FALSE, glm::value_ptr(M[0])); 
      shader.UnUse();
  4. Render instances using the glDrawElementInstanced call.
    void OnRender() {
      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
      glm::mat4 T =glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, dist));
      glm::mat4 Rx=glm::rotate(T,rX,glm::vec3(1.0f, 0.0f, 0.0f));
      glm::mat4 V =glm::rotate(Rx,rY,glm::vec3(0.0f, 1.0f,0.0f));
      glm::mat4 PV = P*V;
      
      shader.Use();
        glUniformMatrix4fv(shader("PV"),1,GL_FALSE,glm::value_ptr(PV));
        glUniform1i(shader("sub_divisions"), sub_divisions);
        glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0, 4);
      shader.UnUse();
      glutSwapBuffers();
    }

How it works…

First, we need to store the model matrix for each instance separately. Since we have four instances, we store a uniform array of four elements (M[4]). Second, we multiply the per-vertex position (vVertex) with the model matrix for the current instance (M[gl_InstanceID]).

Tip

Note that the gl_InstanceID built-in attribute will be filled with the index of each instance automatically at the time of the glDrawElementsInstanced call. Also note that this built-in attribute is only accessible in the vertex shader.

The MVP matrix is omitted from the geometry shader since now the input vertex positions are in world space. So we only need to multiply them with the combined view projection (PV) matrix. On the application side, the MV matrix is removed. Instead, we store the model matrix array for all four instances (glm::mat4 M[4]). The values of these matrices are initialized in the OnInit() function as follows:

M[0] = glm::translate(glm::mat4(1), glm::vec3(-5,0,-5));
M[1] = glm::translate(M[0], glm::vec3(10,0,0));
M[2] = glm::translate(M[1], glm::vec3(0,0,10));
M[3] = glm::translate(M[2], glm::vec3(-10,0,0));

The rendering function, OnRender(), creates the combined view projection matrix (PV) and then calls glDrawElementsInsntanced. The first four parameters are similar to the glDrawElements function. The final parameter is the total number of instances desired. Instanced rendering is an efficient mechanism for rendering identical geometry whereby the GL_ARRAY_BUFFER and GL_ELEMENT_ARRAY_BUFFER bindings are shared between instances allowing the GPU to do efficient resource access and sharing.

void OnRender() {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  glm::mat4 T = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f, 0.0f, dist));
  glm::mat4 Rx = glm::rotate(T,  rX, glm::vec3(1.0f, 0.0f, 0.0f));
  glm::mat4 V = glm::rotate(Rx, rY, glm::vec3(0.0f, 1.0f, 0.0f));
  glm::mat4 PV = P*V;
  shader.Use();
    glUniformMatrix4fv(shader("PV"),1,GL_FALSE,glm::value_ptr(PV));
    glUniform1i(shader("sub_divisions"), sub_divisions);
    glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,0, 4);
  shader.UnUse();
  glutSwapBuffers();
}

There is always a limit on the maximum number of matrices one can output from the vertex shader and this has some performance implications as well. Some performance improvements can be obtained by replacing the matrix storage with translation and scaling vectors, and an orientation quaternion which can then be converted on the fly into a matrix in the shader.

See also

The official OpenGL wiki can be found at http://www.opengl.org/wiki/Built-in_Variable_%28GLSL%29.

An instance rendering tutorial from OGLDev can be found at http://ogldev.atspace.co.uk/www/tutorial33/tutorial33.html.

Visually different images
CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
OpenGL Development Cookbook
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon