Modern OpenGL: VBO, GLM and Matrix Stacks

After searching and reading about Modern OpenGL to update an existing project, I got a little confused since my three-dimensional structure is based on OpenGL 2.1.

so as far as I know ...

  • We need to generate our vertex buffer objects from vertices, indexes, normals, colors, uvs, etc.

  • then we can use GLM for matrix transformation, and we only use VBO to create or manipulate grids, and finally we pass everything to the shaders of the GLSL vertices, like this ...

    glm::mat4 MVP = projection * view * model; glUniformMatrix4fv(glGetUniformLocation(shaderProgramID, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); //or &MVP[0][0] // uniform mat4 MVP; // in vec3 Vertex; // void main(void) // { // gl_Position = MVP * vec4(Vertex, 1.0); //instead of ftransform(); // } 

QUESTION: How do we perform hierarchical transformations without pushMatrix / popMatrix? (or maybe we are doing a hierarchical transformation using our VBOs, is this possible?)

If this is not possible, then how to achieve the same result as pushMatrix / popMatrix using the GLM and C ++ <stack> library?

Let's say I need something like this:

 > Set identity > Translate to X, Y, Z > Draw Mesh 1 > Rotate 0.5 by X axis > Draw Mesh 2 > Scale down to 0.1 > Draw Mesh 3 
+7
source share
4 answers
  • We need to generate our vertex buffer objects from vertices, indexes, normals, colors, uvs, etc.

In fact, you do not need to use VBO, on the client side Vertex Arrays also work. However, it is highly recommended that you use VBO because it makes life easier for the driver and ultimately also yours as the one who needs to manipulate the data. The code overhead is not taken into account (this is about the same as generating and loading texture data), and performance will only increase.

  • then we can use GLM to transform the matrix, and we only use VBO to create or manipulate the grids, and finally we pass everything to the shaders of the GLSL vertices, like this ...

You are not limited to GLM. Any matrix math library will do. If you are looking for something you can use on C99, look at my (yet incomplete) linmath.h https://github.com/datenwolf/linmath.h , which is just a header with static inline . I have not tested yet whether duplication of code affects performance (the size of the code creates pressure in the L1 cache).

QUESTION: How do we do hierarchical transformations without pushMatrix / popMatrix? (or maybe we are doing a hierarchical transformation using our VBOs, is this possible?)

VBOs have nothing to do with this. What most users of the old-fashioned OpenGL problem give is those matrix stack functions that make OpenGL a bit like a scene graph. But this is not so.

If you forget about the matrix stack of the old OpenGL, it becomes obvious how to perform hierarchical transformations: on each hierarchy branch, create a copy of the transformation matrix and operate on it. You get a hierarchical tree of transformations, on each node the corresponding matrix is ​​stored. Then you pass these matrices as uniforms to the vertex shader; or just one matrix if you are drawing a rigid object that has only one transformation. A few matrices that you usually need only for deformable objects, such as skeletal animation of such a character

 worldtransform -> pelvis -> left upper leg -> left lower leg -> left foot right upper leg -> right lower leg -> right foot torso -> neck -> head -> left eye right eye facial deformation // this is a whole chapter of it own left upper arm -> left lower arm -> left hand right upper arm -> right lower arm -> right hand 

Each time you call -> in such a hierarchy, you make a copy of the matrix and continue to work on it. When you return to a higher level of the tree, you again begin to work with this matrix.

+5
source

Yes, if you need hierarchical transformations, then you need to do it yourself. However, this is pretty trivial if you only need a stack. Just grab the last entry on the stack and multiply it by the next matrix you want to apply and push the result onto the stack.

[To your edited question]: for this you do not need a stack, and there is no hierarchical transformation. Just use a single matrix and apply your translation, draw, multiply it by your rotation matrix, draw, multiply scale, draw.

+4
source

If your rendering is already performed hierarchically, for example, recursing a function, then you already have a matrix stack!

 void renderMesh(Matrix transform, Mesh mesh) { // here call glDrawElements/glDrawArrays and send transform matrix to MVP uniform mesh->draw(transform); // now render all the sub-meshes, then will be transformed relative to current mesh for (int i=0; i<mesh->subMeshCount(); i++) { Matrix subMeshTransform = mesh->getSubMeshTransform(i); Mesh subMesh = mesh->getSubMesh(); renderMesh(subMeshTransform * transform, subMesh); } } // somwhere in main function ... Matrix projection = Matrix::perspective(...); Matrix view = camera->getViewMatrix(); Matrix transform = view * projectIon; renderMesh(transform, rootMesh); 
+4
source

Regarding the performance of VAO and VBO, I do not agree that VBO is faster, I suggest looking at this link

http://www.openglsuperbible.com/2013/12/09/vertex-array-performance/

From the above results, you can see that, at least for our small set of samples, VAO is faster in all implementations. Of course, there are several options to check when calling glBindVertexArray than glBindBuffer or glVertexAttribPointer. Even if there is only one vertex attribute, in OpenGL there are only half the calls with the VAO switch than with the explicit update of the global VAO. In addition, with the obvious relation “fewer API calls mean faster execution,” VAO is the place where the OpenGL driver can hide the information needed to program the underlying GPU. The total number of state changes sent to the GPU is the same anyway.

0
source

All Articles