如何在Modern OpenGL中绘制圆形?现有代码运行异常求助
Modern OpenGL 绘制圆形问题修复
核心错误点
- 角度转弧度函数
degToRad返回值类型声明为int,所有浮点运算结果被强制截断为整数,导致顶点坐标计算完全失效 - 绘制时使用
GL_LINES图元类型,该类型会将顶点两两分组绘制独立线段,无法形成闭合的圆形轮廓 - (非致命问题)桌面端OpenGL核心模式无需声明
precision mediump float,该语法为OpenGL ES专用,保留不影响运行但无实际作用
修复后的完整代码
#include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream> #include <cmath> #include <vector> GLfloat pi() { return atan(1) * 4; } // 修正1:返回值改为GLfloat保留浮点精度 GLfloat degToRad(float degree) { return (pi() / 180) * degree; } int main() { if (!glfwInit()) { return -1; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); GLFWwindow *window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL); if (!window) { glfwTerminate(); return -1; } glfwMakeContextCurrent(window); gladLoadGL(); std::vector<GLfloat> vertices = { }; // 如果需要绘制填充圆形,先添加圆心坐标 // vertices.push_back(0.0f); // vertices.push_back(0.0f); // vertices.push_back(0.0f); GLfloat radius = 0.5; for(int i = 0; i < 360; i++) { GLfloat x = radius * cos(degToRad(i)); GLfloat y = radius * sin(degToRad(i)); vertices.push_back(x); vertices.push_back(y); vertices.push_back(0.0f); } unsigned int VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW); const char *vertexShaderSource = "#version 410 core\n" "layout (location = 0) in vec3 position;\n" "void main() {\n" " gl_Position = vec4(position, 1.0);\n" "}"; const char *fragmentShaderSource = "#version 410 core\n" "out vec4 color;\n" "void main() {\n" " color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n" "}"; unsigned int vertexShader; vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); int success; char infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } unsigned int fragmentShader; fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } unsigned int vertexArray; glGenVertexArrays(1, &vertexArray); glBindVertexArray(vertexArray); unsigned int shaderProgram; shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); while (!glfwWindowShouldClose(window)) { glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); // 修正2:改为GL_LINE_LOOP绘制闭合轮廓,填充则改为GL_TRIANGLE_FAN glDrawArrays(GL_LINE_LOOP, 0, vertices.size() / 3); glfwSwapBuffers(window); glfwPollEvents(); } glfwTerminate(); return 0; }
内容的提问来源于stack exchange,提问作者Axel
相关产品推荐
相关产品推荐

