Рисование круга с помощью OpenGL

Я пытаюсь манипулировать некоторым кодом, чтобы нарисовать круг вместо треугольника, который уже печатается в учебнике. Я не очень знаком с C++ или 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;

1 ответ

Решение

В этом коде есть несколько проблем. Самый серьезный, который, вероятно, вызывает сбой, находится здесь:

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 числа с плавающей точкой (x, y и z) на вершину, правильное значение равно 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);
Другие вопросы по тегам