0

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;
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Maggie S.
  • 1,076
  • 4
  • 20
  • 30
  • Try putting calls to glGetError in between to see if any of your previous gl calls failed https://www.opengl.org/sdk/docs/man/docbook4/xhtml/glGetError.xml – timdykes Sep 07 '15 at 18:12
  • 1
    The second parameter of `glVertexAttribPointer` has to be the number of floats each vertex has, not the number of vertices. – BDL Sep 07 '15 at 18:13
  • 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. Sep 07 '15 at 18:14
  • 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. Sep 07 '15 at 18:16

1 Answers1

2

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);
Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • This took care of my error (thank you!), but now my whole window is colored red instead of just showing a red circle, no matter how big or small I define the radius. – Maggie S. Sep 07 '15 at 18:22
  • Would I not need to convert to radians if I just used `cos()` and `sin()`? I just grabbed those from a separate tutorial code as well. – Maggie S. Sep 07 '15 at 18:22
  • @MaggieB. All those standard library functions take angles in radians. The only difference is that `cos()` is for double, and `cosf()` for float. You don't show your transformations, but the circle is much larger than the triangle you had before. Have you tried using something like 0.5 for the radius? – Reto Koradi Sep 07 '15 at 18:25
  • That worked making the radius smaller! Before your suggestion the smallest I had tried was `3.0f` but `0.5f` fit into my window. In fact it's more like an oval. I should check my calculations to make a circle? – Maggie S. Sep 07 '15 at 18:29