用OpenGL绘制圆

Drawing a Circle with OpenGL

本文关键字:绘制 OpenGL      更新时间:2023-10-16

我试图操纵一些代码来绘制一个圆圈,而不是已经由教程打印的三角形。我对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;

这段代码中存在一些问题。可能导致崩溃的最严重的一个在这里:

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-off错误:

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