Best place to store model matrix in OpenGL?

Schnigges

I'm currently refactoring my OpenGL program (used to be one single enormous file) to use C++ classes. The basic framework looks like this:

I have an interface Drawable with the function virtual void Render(GLenum type) const = 0; and a bunch of classes implementing this interface (Sphere, Cube, Grid, Plane, PLYMesh and OBJMesh).

In my main.cpp I'm setting up a scene containing multiple of these objects, each with its own shader program. After setting uniform buffer objects and each program's individual uniforms, I'm calling glutMainLoop().

In my Display function called each frame, the first thing I'm doing is setting up all the transformation matrices and finally call the above mentioned Render function for every object in the scene:

void Display()
{
    // Clear framebuffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


    modelViewMatrix  = glm::mat4(1.0);
    projectionMatrix = glm::mat4(1.0);
    normalMatrix     = glm::mat4(1.0);

    modelViewMatrix = glm::lookAt(glm::vec3(0.0, 0.0, mouse_translate_z), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));
    modelViewMatrix = glm::rotate(modelViewMatrix, -mouse_rotate_x, glm::vec3(1.0f, 0.0f, 0.0f));
    modelViewMatrix = glm::rotate(modelViewMatrix, -mouse_rotate_y, glm::vec3(0.0f, 1.0f, 0.0f));

    projectionMatrix = glm::perspective(45.0f, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 1.0f, 10000.f);

    // No non-uniform scaling (only use mat3(normalMatrix in shader))
    normalMatrix = modelViewMatrix;

    glBindBuffer(GL_UNIFORM_BUFFER, ubo_global_matrices);
        glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(modelViewMatrix));
        glBufferSubData(GL_UNIFORM_BUFFER, 1 * sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(projectionMatrix));
        glBufferSubData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(normalMatrix));
    glBindBuffer(GL_UNIFORM_BUFFER, 0);

    // ************************************************** //
    // **************** DRAWING COMMANDS **************** //
    // ************************************************** //

    // Grid
    if (grid->GetIsRendered())
    {
        program_GRID_NxN->Use();
            grid->Render(GL_LINES);
        program_GRID_NxN->UnUse();
    }

    // Plane
    ...

    // Sphere
    ...

    // Swap front and back buffer and redraw scene
    glutSwapBuffers();
    glutPostRedisplay();
}

My question now is the following: With the current code, I'm using the same ModelView matrix for every object. What if I wanna translate only the sphere, or rotate only the plane without changing the vertex positions? Where is the best place to store the model matrix in a large OpenGL program? What about putting a protected member variable glam::mat4 modelMatrix into the Drawable interface? Also, should the model and the view matrix be split (for example using a Camera class containing the view matrix only)?

Iggy

My answer is mainly based off Tom Dalling's excellent tutorial, but with some minor changes.

Firstly all your view and projection matrix operations should go in the Camera class. Camera will provide a convenient way of getting the view and projection matrix by calling the matrix() method.

glm::mat4 Camera::matrix() const {
    return projection() * view();
}

Camera.cpp

Then for this example you'd have an Model Asset, which contains everything you need to render the geometry. This asset should be unique and stored in a ResourceManager or something similar.

struct ModelAsset {
    Shader*  shader;
    Texture* texture;
    GLuint   vbo;
    GLuint   vao;
    GLenum   drawType;
    GLint    drawStart;
    GLint    drawCount;
};

Then you have an Model Instance, which has a pointer to the assest plus a unique transform matrix. This way you can create as many instances of a particular asset each one with its own unique transformation.

struct ModelInstance {
    ModelAsset* asset;
    glm::mat4 transform;
};

ModelInstance cube;
cube.asset = &asset; // An asset that you created somewhere else (e.g. ResourceManager)
cube.transform = glm::mat4(); // Your unique transformation for this instance

To render an instance you pass the view and model matrix as uniforms to the shader, and shader does the rest of the work.

shaders->setUniform("camera", camera.matrix());
shaders->setUniform("model", cube.transform);

Finally it's best when all your instances are grouped nicely in some resizable container.

std::vector<ModelInstance> instances;
instances.push_back(cube);
instances.push_back(sphere);
instances.push_back(pyramid);

for (ModelInstance i : instances) {
    i.transform = glm::rotate(i.transform, getTime(), glm::vec3(0.0f, 1.0f, 0.0f));
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Rotate matrix in place

From Dev

What is the best place to store user configurations settings

From Dev

The best way to discretise a 3D model into a matrix

From Dev

What is the standard place to keep the Model Matrix?

From Dev

Android - where it is the best place to store a list of images locally?

From Dev

Best place to store resolve methods in angularJs

From Dev

Best place to store DB parameters in IBM Integration Bus

From Dev

Where is the best place to store supporting JSON on dynamic AJAX load?

From Dev

What is the best place to store ng-templates in Angular/Django SPA

From Dev

In place update columns of a matrix

From Dev

Matrix assignment in place?

From Dev

Invert a matrix in place with NumPy

From Dev

Opengl Translation on Model Matrix malforms result

From Dev

In place update columns of a matrix

From Dev

In OpenGL, ModelView Matrix is ModelxView or View x Model?

From Dev

Where is the best place to store layout logic in Rails?

From Dev

The best way to discretise a 3D model into a matrix

From Dev

Best place to store saved messages

From Dev

Opengl Model Matrix doesnt rotate around the origin after one rotation

From Dev

Best place to store custom functions?

From Dev

Opengl ES 2.0: Model Matrix vs Per Vertex Calculation

From Dev

Best place to store google maps data

From Dev

What is the best place to store ng-templates in Angular/Django SPA

From Dev

Best place to store an array in Laravel

From Dev

What is the best place to store configuration files in a war file so that they can be imported easily using Spring

From Dev

OpenGL why send only one model matrix if two models in scene?

From Dev

The best place to store custom interfaces in ZF2

From Dev

Where is the best place to store an RTCPeerConnection object in a React/Redux app?

From Dev

Model Matrix trasformations OpenGL ES 2.0

Related Related

  1. 1

    Rotate matrix in place

  2. 2

    What is the best place to store user configurations settings

  3. 3

    The best way to discretise a 3D model into a matrix

  4. 4

    What is the standard place to keep the Model Matrix?

  5. 5

    Android - where it is the best place to store a list of images locally?

  6. 6

    Best place to store resolve methods in angularJs

  7. 7

    Best place to store DB parameters in IBM Integration Bus

  8. 8

    Where is the best place to store supporting JSON on dynamic AJAX load?

  9. 9

    What is the best place to store ng-templates in Angular/Django SPA

  10. 10

    In place update columns of a matrix

  11. 11

    Matrix assignment in place?

  12. 12

    Invert a matrix in place with NumPy

  13. 13

    Opengl Translation on Model Matrix malforms result

  14. 14

    In place update columns of a matrix

  15. 15

    In OpenGL, ModelView Matrix is ModelxView or View x Model?

  16. 16

    Where is the best place to store layout logic in Rails?

  17. 17

    The best way to discretise a 3D model into a matrix

  18. 18

    Best place to store saved messages

  19. 19

    Opengl Model Matrix doesnt rotate around the origin after one rotation

  20. 20

    Best place to store custom functions?

  21. 21

    Opengl ES 2.0: Model Matrix vs Per Vertex Calculation

  22. 22

    Best place to store google maps data

  23. 23

    What is the best place to store ng-templates in Angular/Django SPA

  24. 24

    Best place to store an array in Laravel

  25. 25

    What is the best place to store configuration files in a war file so that they can be imported easily using Spring

  26. 26

    OpenGL why send only one model matrix if two models in scene?

  27. 27

    The best place to store custom interfaces in ZF2

  28. 28

    Where is the best place to store an RTCPeerConnection object in a React/Redux app?

  29. 29

    Model Matrix trasformations OpenGL ES 2.0

HotTag

Archive