0
votes

I'm trying to manipulate some code to draw a circle instead of the triangle that is already being printed by the tutorial. I'm not super familiar with C++ or OpenGL, which is why I'm just trying it out.

Any suggestions or corrections to my code would be greatly appreciated. I keep getting a breakpoint error in XCODE on this line:

glDrawArrays(GL_TRIANGLE_FAN, 0, numPoints); // draw the points and fill it in

and it says:

Thread 1: EXC_BAD_ACCESS(code=1, address=0x0)

Here is the original vector buffer for the triangle in the tutorial I'm following:

static const GLfloat g_vertex_buffer_data[] = { 
     -1.0f,  -1.0f, 0.0f,
     1.0f,  -1.0f, 0.0f,
     0.0f,  1.0f, 0.0f,
};

I'm pretty sure that my calculations are correct, but I don't know why it' not drawing a circle. Here is my manipulation:

// Make a circle
GLfloat x;
GLfloat y;
GLfloat z = 0.0f;
int theta = 0;
float radius = 50.0f;
int currentSize = 0;
int numPoints = 30;
GLfloat g_vertex_buffer_data[numPoints*3];

while (theta <= 360) {

    x = (GLfloat) radius * cosf(theta);
    y = (GLfloat) radius * sinf(theta);

    g_vertex_buffer_data[currentSize++] = x;
    g_vertex_buffer_data[currentSize++] = y;
    g_vertex_buffer_data[currentSize++] = z;

   /*
    cout << "Theta: " << theta << endl;

    for (int i = 0; i < currentSize; i++) {

        cout << "g_vertex_buffer_data[" << g_vertex_buffer_data[i] << "]" << endl;
    }
    */

    theta = theta + (360/numPoints);
}

Here is the rest of the code in the .cpp file:

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data),g_vertex_buffer_data, GL_STATIC_DRAW);

do{

    // Clear the screen
    glClear( GL_COLOR_BUFFER_BIT );

    // Use our shader
    glUseProgram(programID);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(vertexPosition_modelspaceID);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
        vertexPosition_modelspaceID, // The attribute we want to configure
        numPoints,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );

    // Draw the circle!
    glDrawArrays(GL_TRIANGLE_FAN, 0, numPoints); // draw the points and fill it in

    glDisableVertexAttribArray(vertexPosition_modelspaceID);

    // Swap buffers
    glfwSwapBuffers(window);
    glfwPollEvents();

} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
       glfwWindowShouldClose(window) == 0 );


// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
1
Try putting calls to glGetError in between to see if any of your previous gl calls failed opengl.org/sdk/docs/man/docbook4/xhtml/glGetError.xml - timdykes
The second parameter of glVertexAttribPointer has to be the number of floats each vertex has, not the number of vertices. - BDL
OK that makes a little bit of sense for glVertexAttribPointer because it had 3 in that spot before, but I just assumed it meant the number of vertices. - Maggie S.
This kind of helped just changing the glVertexAttribPointer but now the whole window is red (the color I'm expecting the circle to be) no matter how big or small I make the circle radius. - Maggie S.

1 Answers

2
votes

There are a few problems in this code. The most severe one that probably causes the crash is here:

glVertexAttribPointer(
    vertexPosition_modelspaceID, // The attribute we want to configure
    numPoints,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    0,                  // stride
    (void*)0            // array buffer offset
);

The second argument to glVertexAttribPointer() is the number of components per vertex. Since you have 3 floats (x, y and z) per vertex, the correct value is 3. So the call should be:

glVertexAttribPointer(
    vertexPosition_modelspaceID, // The attribute we want to configure
    3,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    0,                  // stride
    (void*)0            // array buffer offset
);

There is also a 1-off error where the points are created:

while (theta <= 360) {

If you include 360 in the range, you will effectively repeat the first vertex, and write one more vertex than the allocated space. This should be:

while (theta < 360) {

Also, the arguments to cosf() and sinf() are in radians. So you will have to convert the angles from degrees to radians for these functions:

x = (GLfloat) radius * cosf(theta * M_PI / 180.0f);
y = (GLfloat) radius * sinf(theta * M_PI / 180.0f);