0

I want to use some convenience methods to generate vertex and colour arrays for use in objects. From what i've seen on generating arrays, this is an example of what I currently use:

GLfloat * CDMeshVertexesCreateRectangle(CGFloat height, CGFloat width) {

// Requires the rendering method GL_TRIANGLE_FAN
GLfloat *squareVertexes = (GLfloat *) malloc(8 * sizeof(GLfloat));
squareVertexes[0] = -(width / 2);
squareVertexes[1] = -(height / 2);
squareVertexes[2] = -(width / 2);
squareVertexes[3] = (height / 2);
squareVertexes[4] = (width / 2);
squareVertexes[5] = (height / 2);
squareVertexes[6] = (width / 2);
squareVertexes[7] = -(height / 2);

return squareVertexes;

}

But when i use it on something such as this:

GLuint memoryPointer = 0;
    GLuint colourMemoryPointer = 0;

    GLfloat *vertexes = CDMeshVertexesCreateRectangle(200, 200);
    GLfloat *colors = CDMeshColorsCreateGrey(1.0, 4);

    // Allocate the buffer
    glGenBuffers(1, &memoryPointer);
    // Bind the buffer object (tell OpenGL what to use)
    glBindBuffer(GL_ARRAY_BUFFER, memoryPointer);

    // Allocate space for the VBO
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);


    // Allocate the buffer
    glGenBuffers(1, &colourMemoryPointer);
    // Bind the buffer object (tell OpenGL what to use)
    glBindBuffer(GL_ARRAY_BUFFER, colourMemoryPointer);

    // Allocate space for the VBO
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);

    glEnableClientState(GL_VERTEX_ARRAY); // Activate vertex coordinates array
    glEnableClientState(GL_COLOR_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, memoryPointer);
    glVertexPointer(2, GL_FLOAT, 0, 0);   

    glBindBuffer(GL_ARRAY_BUFFER, colourMemoryPointer);
    glColorPointer(4, GL_FLOAT, 0, 0);

    //render
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY); // Deactivate vertex coordinates array
    glDisableClientState(GL_COLOR_ARRAY);

    free(vertexes);
    free(colors);

The rendering doesn't hold up, and random problems occur during rendering such as flickering, color distortion and more. When using the same code for initialisation and rendering when using a normally defined array (removing the generated vertexes and its related code), no problems occur.

GLfloat Square[8] = {
-100, -100,
-100, 100,
100, 100,
100, -100
};

Does anyone know where i'm going wrong?

1
  • 1
    sizeof(vertexes) returns the size of the pointer (most likely 4), not the size of the array. You need to keep track of the size separately. Not sure if this is the cause of your problems though. Commented Jul 14, 2011 at 16:05

1 Answer 1

4

You have two problems in your code. First this pattern:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), vertexes, GL_STATIC_DRAW);

sizeof(vertexes) evaluates to the size of the pointer variable, not the size of the buffer. C/C++ newbie mistake, we all did it. You need to keep track of the size yourself. So do it like this:

int allocate_a_buffer(CGFloat height, CGFloat width, GLfloat **buffer, size_t *buffer_size) 
{
// Requires the rendering method GL_TRIANGLE_FAN
    return  ( *buffer = (GLfloat *) malloc( *buffer_size = ( <xxx> * sizeof(GLfloat)) ) ) != 0;
}

and

GLfloat *vertices;
size_t vertices_size;

if( !allocate_a_buffer(..., &vertices, &vertices_size) ) {
    error();
    return;
}
glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices, GL_STATIC_DRAW);

If you're using C++ just use a std::vector passed by reference:

void initialize_buffer(..., std::vector<GLfloat> &buffer)
{
    buffer.resize(...);
    for(int n = ...; ...; ...) {
         buffer[n] = ...;
    }
}

and

std::vector<GLfloat> vertices;
initialize_buffer(..., vertices);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);

much less fuzz.


The other problem is, that this code seems to be called by the drawing function. The whole point of buffer objects is, that you initialize them only one time and then only bind and draw from them in the display routine. So glDrawArrays belongs into another function than the rest of this code, namely the display routine, while the rest belongs into the data loading and scene data management code.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot for your answer, everything worked apart from where you were trying to assign a value to vertex_size, which worked when I added a pointer. Also, the OpenGL code is there as a demonstration, i only bind and draw the vertex buffers in the display routine.
@Croc: I think you mean dereferenciation. Yes that was missing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.