You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 23:45:03