Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Performance concerns of using static variables inside display function in OpenGL?

I’m learning OpenGL 4 and am reading an ebook Computer Graphics Programming in OpenGL with C++ Second Edition. They explain that it is very important in our display function, where drawing operations are handled, that we avoid instantiating objects or declaring variables to maximize performance and minimize overhead. Which is why up until that point they’d been globally declaring variables used in the display function as a means to avoid any memory allocation locally.

I’ve been instead opting to use static variables in the display function like so:

void display(GLFWwindow* window, double currentTime) {

    static float cameraX = 0.0f, cameraY = 0.0f, cameraZ = 20.0f; // <-- statically assigned 

    glm::mat4 mMat, vMat, pMat, mvMat;

    int width, height;

    std::stack<glm::mat4> mvStack;

    glfwGetFramebufferSize(window, &width, &height);

    float aspect = static_cast<float>(width) / static_cast<float>(height);

    glClear(GL_DEPTH_BUFFER_BIT);

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(renderingProgram);

    GLuint mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");
    GLuint pLoc = glGetUniformLocation(renderingProgram, "p_matrix");

    pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);

    vMat = glm::translate( glm::mat4(1.0f), glm::vec3(-cameraX, -cameraY, -cameraZ) );
    mvStack.push(vMat);

    glUniformMatrix4fv(pLoc, 1, GL_FALSE, glm::value_ptr(pMat));

    mvStack.push(mvStack.top());
    mvStack.top() *= glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));

    mvStack.push(mvStack.top());
    mvStack.top() *= glm::rotate(glm::mat4(1.0f), static_cast<float>(currentTime), glm::vec3(1.0f, 0.0f, 0.0f));

    glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvStack.top()));

    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glDrawArrays(GL_TRIANGLES, 0, 18);

    mvStack.pop();

    mvStack.push(mvStack.top());
    mvStack.top() *= glm::translate(glm::mat4(1.0f),
        glm::vec3(
            sin(static_cast<float>(currentTime)) * 4.0f,
            0.0f,
            cos(static_cast<float>(currentTime)) * 4.0f
        ));

    mvStack.push(mvStack.top());
    mvStack.top() *= glm::rotate(glm::mat4(1.0f), static_cast<float>(currentTime), glm::vec3(0.0f, 1.0f, 0.0f));

    glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvStack.top()));
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    glDrawArrays(GL_TRIANGLES, 0, 36);
    mvStack.pop();

    mvStack.push(mvStack.top());
    mvStack.top() *= glm::translate(glm::mat4(1.0f),
        glm::vec3(
            0.0f,
            sin(static_cast<float>(currentTime) * 0.5) * 2.0f,
            cos(static_cast<float>(currentTime) * 0.5) * 2.0f
        ));

    mvStack.push(mvStack.top());
    mvStack.top() *= glm::rotate(glm::mat4(1.0f), static_cast<float>(currentTime), glm::vec3(-1.0f, 0.0f, 0.0f));

    mvStack.push(mvStack.top());
    mvStack.top() *= glm::scale(glm::mat4(1.0f), glm::vec3(0.25f));

    glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvStack.top()));
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    glDrawArrays(GL_TRIANGLES, 0, 36);

    mvStack.pop(); mvStack.pop(); mvStack.pop(); mvStack.pop();
}

static variables are initialized once in a function and maintain their original value throughout the scope of that function and go out of scope with that function. In my mind since it’s only allocated once, assigned to once and maintains the same value and address in memory then there shouldn’t be much of a performance concern except during the very first call of the function when the variable is actually instantiated.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Any performance concerns to keep in mind? Would global variables be a better alternative in terms of performance?

>Solution :

I believe your question can be simplied down to this one Is there a penalty for using static variables in C++11, and it seems that the answer is "yes, but mildly"

The second answer posits an explanation to this:

Yes, there will be a cost to check whether the object has been
initialised. This would typically test an atomic Boolean variable,
rather than lock a mutex. @Mike Seymour

I believe it is better to examine the linked question and the top answer, they are golden

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading