Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Dynamic Allocation and OpenGL

  1. #1
    Newbie Newbie
    Join Date
    Jul 2018
    Posts
    2

    Question Dynamic Allocation and OpenGL

    Hi. I've been trying to draw a series of triangles to the screen. I generate buffers, bind them correctly, and buffer the arrays of floats using glBufferData. If I use arrays of data created with stack memory, it works fine. The problem occurs when I create dynamically allocated arrays from the heap and pass them to OpenGL. I wrote a test function that emulates exactly what I'm trying to do elsewhere which highlights the problem.

    Here's the code that works fine:

    Code cpp:
    void testFunction() {
     
        GLuint vertexBufferId, indexBufferId;
        int triangleCount = 3;
     
        float newPositions[] = {
        -0.5f, 0.5f, -0.5f,
        -0.5f, -0.5f, -0.5f,
        0.5f, 0.5f, -0.5f,
        0.5f, -0.5f, -0.5f,
        -0.5f, 0.5f, 0.5f
        };
     
        GLushort vertexIndices[] = {
        0, 1, 2,
        2, 1, 3,
        0, 1, 4
        };
     
        glGenBuffers(1, &vertexBufferId);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
        glBufferData(GL_ARRAY_BUFFER, sizeof(newPositions), newPositions, GL_STATIC_DRAW);
     
     
        glGenBuffers(1, &indexBufferId);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertexIndices), vertexIndices, GL_STATIC_DRAW);
     
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
     
        glDrawElements(GL_TRIANGLES, triangleCount * 3, GL_UNSIGNED_SHORT, 0);
    }

    When I change the data to use dynamically allocated memory, I get a black screen instead of the triangles which were drawn before.

    Code cpp:
    void testFunction() {
        GLuint vertexBufferId, indexBufferId, colourBufferId;
        int triangleCount = 3;
     
        float* newPositions = new float[15]{
            -0.5f, 0.5f, -0.5f,
            -0.5f, -0.5f, -0.5f,
            0.5f, 0.5f, -0.5f,
            0.5f, -0.5f, -0.5f,
            -0.5f, 0.5f, 0.5f
        };
     
        GLushort* vertexIndices = new GLushort[9] {
            0, 1, 2,
            2, 1, 3,
            0, 1, 4
        };
     
        glGenBuffers(1, &vertexBufferId);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
        glBufferData(GL_ARRAY_BUFFER, sizeof(newPositions), newPositions, GL_STATIC_DRAW);
     
        glGenBuffers(1, &indexBufferId);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertexIndices), vertexIndices, GL_STATIC_DRAW);
     
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
     
        glDrawElements(GL_TRIANGLES, triangleCount * 3, GL_UNSIGNED_SHORT, 0);
     
        delete[] vertexIndices;
        delete[] newPositions;
    }

    I'm still quite new to OpenGL, so if I need to approach it differently with heap memory then please let me know. Thanks for your help.
    Last edited by Dark Photon; 07-12-2018 at 04:43 PM.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,962
    Quote Originally Posted by pentagast View Post
    When I change the data to use dynamically allocated memory, I get a black screen instead of the triangles which were drawn before.
    Code :
    	float* newPositions = new float[15]{
    	...
    	glBufferData(GL_ARRAY_BUFFER, sizeof(newPositions), newPositions, GL_STATIC_DRAW);
    I'm still quite new to OpenGL, so if I need to approach it differently with heap memory then please let me know. Thanks for your help.
    It seems that you're also still quite new to C++. This isn't an OpenGL problem per se. The issue is that in the second case sizeof(newPositions) is equivalent to sizeof(float*); in the first case it was equivalent to sizeof(float[15]).

    C++ doesn't provide a mechanism to obtain the size of a dynamically-allocated array. The implementation may not even store this; if it rounds the allocation up to a larger size, there's no reason for it to record the requested size. So you have to keep track of the size yourself. One way to do that is to use std::vector instead.

  3. #3
    Newbie Newbie
    Join Date
    Jul 2018
    Posts
    2
    I completely missed that and assumed a problem with OpenGL. Thanks for the help.

  4. #4
    Intern Contributor
    Join Date
    Oct 2014
    Posts
    71
    Additionally it might be beneficial if you try to avoid using raw new calls for dynamic allocation in general and use the standard template library instead. The new operator is the source for a lot of mistakes that can be completely avoided by using the STL.

    To do so, replace your c style static array (vertexIndices[] = ...) with a std::array and your dynamically allocated array with a std::vector. Because the STL containers are designed to have mostly equal interfaces your OpenGL call would be the same for both container types. It should look like this:

    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*myContainer.size(), myContainer.data(), GL_STATIC_DRAW);
    You also get additional functionality that is often needed with arrays.

    Greetings

    EDIT: Make sure that you compile with c++ 11 support. Use -std=c++11 for clang and gcc. Not sure about msvc, but google will tell you.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •