2015-09-07 3 views
0

Я пытаюсь манипулировать некоторым кодом, чтобы нарисовать круг вместо треугольника, который уже печатается в учебнике. Я не очень хорошо знаком с C++ или OpenGL, поэтому я просто пытаюсь это сделать.Рисование круга с OpenGL

Любые предложения или исправления в отношении моего кода будут очень признательны. я получаю точки останова ошибки в Xcode на этой линии:

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

, и он говорит:

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

Вот исходный вектор буфер для треугольника в учебнике я следующее:

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, 
}; 

Я уверен, что мои расчеты правильные, но я не знаю, почему он не рисует круг. Вот моя манипуляция:

// 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); 
} 

Вот остальная часть кода в файле .cpp:

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; 
+0

Попробуйте положить вызовы glGetError между ними, чтобы увидеть, если любой из ваших предыдущих Gl вызовов не удалось https://www.opengl.org/sdk /docs/man/docbook4/xhtml/glGetError.xml – timdykes

+0

Второй параметр 'glVertexAttribPointer' должен быть числом поплавков каждой вершины, а не числом вершин. – BDL

+0

ОК, что немного имеет смысл для 'glVertexAttribPointer', потому что раньше у него было' 3', но я просто предположил, что это означает количество вершин. –

ответ

2

Есть несколько проблем, в этом коде. Наиболее тяжелая один, что, вероятно, приводит к аварии здесь:

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

второй аргумент glVertexAttribPointer() это число компонентов в вершине. Поскольку у вас есть 3 поплавки (х, у, г) на вершине, правильное значение 3. Таким образом, вызов должен быть:

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

Существует также 1-офф ошибка, при которой создаются точки:

while (theta <= 360) { 

Если вы включили 360 в диапазон, вы эффективно повторите первую вершину и напишите еще одну вершину, чем выделенное пространство. Это должно быть:

while (theta < 360) { 

Кроме того, аргументы cosf() и sinf() в радианах. Таким образом, вы должны преобразовать углы из градусов в радианы для этих функций:

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

Это позаботилось о моей ошибке (спасибо!), Но теперь все мое окно окрашено в красный цвет вместо того, чтобы просто показывать красный круг, независимо от того, насколько большой или малый я определяю радиус. –

+0

Мне не нужно было бы конвертировать в радианы, если бы я просто использовал 'cos()' и 'sin()'? Я просто схватил их из отдельного учебного кода. –

+0

@MaggieB. Все эти стандартные библиотечные функции имеют углы в радианах. Единственное отличие состоит в том, что 'cos()' для double и 'cosf()' для float.Вы не показываете свои преобразования, но круг намного больше, чем у вас ранее. Вы пытались использовать что-то вроде 0,5 радиуса? –