【问题标题】:Drawing Circle with OpenGL用OpenGL画圆
【发布时间】:2014-03-16 23:19:14
【问题描述】:

我正在尝试用 C++/OpenGl 绘制简单的圆圈

我的代码是:

#include <GL/glut.h>
#include <math.h>

void Draw() {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);

    glBegin(GL_QUADS);
      glColor3f (0.0, 0.0, 0.0);

      glVertex3f (0.1, 0.1, 0.0);
      glVertex3f (0.9, 0.1, 0.0);
      glVertex3f (0.9, 0.9, 0.0);
      glVertex3f (0.1, 0.9, 0.0);

    glEnd();

    glFlush();
}

void DrawCircle(float cx, float cy, float r, int num_segments)
{
    glBegin(GL_LINE_LOOP);
    for(int ii = 0; ii < num_segments; ii++)
    {
        float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);//get the current angle

        float x = r * cosf(theta);//calculate the x component
        float y = r * sinf(theta);//calculate the y component

        glVertex2f(x + cx, y + cy);//output vertex

    }
    glEnd();
}


void Initialize() {
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}

int main(int iArgc, char** cppArgv) {
    glutInit(&iArgc, cppArgv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(950, 500);
    glutInitWindowPosition(200, 200);
    glutCreateWindow("Universum");
    Initialize();
    glutDisplayFunc(Draw);
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 1.0, 1.0);
    DrawCircle(0.5, 0.5, 0.2, 5);

    glutMainLoop();
    return 0;

}

我是 OpenGL 的初学者,现在我开始学习, 有人可以解释一下为什么我没有得到圆圈(我只看到黑框), 谢谢!

【问题讨论】:

    标签: c++ opengl


    【解决方案1】:

    看起来在你画完圆圈之后,你立即进入了主 glut 循环,在那里你设置了 Draw() 函数在每次通过循环时进行绘制。所以它可能是画圆,然后立即擦除它并画正方形。您可能应该将DrawCircle() 设为您的glutDisplayFunc(),或者从Draw() 调用DrawCircle()

    【讨论】:

    • 泰!从 Draw() 调用 DrawCircle() - 它奏效了!顺便说一句,有没有办法让圆圈充满颜色?
    • 要获得一个实心圆,您可以将 GL_LINE_LOOP 更改为 GL_TRIANGLE_FAN。
    • 如上所述,使用GL_TRIANGLE_FAN,但请注意,您需要将第一个点放在圆的中心。
    • @user1118321:实际上不需要中心的顶点,因为形状是凸的。
    【解决方案2】:
    #include <Windows.h>
    #include <GL/glu.h>
    #include <GL/glut.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #define window_width  1080  
    #define window_height 720 
    void drawFilledSun(){
        //static float angle;
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        glTranslatef(0, 0, -10);
        int i, x, y;
        double radius = 0.30;
        //glColor3ub(253, 184, 19);     
        glColor3ub(255, 0, 0);
        double twicePi = 2.0 * 3.142;
        x = 0, y = 0;
        glBegin(GL_TRIANGLE_FAN); //BEGIN CIRCLE
        glVertex2f(x, y); // center of circle
        for (i = 0; i <= 20; i++)   {
            glVertex2f (
                (x + (radius * cos(i * twicePi / 20))), (y + (radius * sin(i * twicePi / 20)))
                );
        }
        glEnd(); //END
    }
    void DrawCircle(float cx, float cy, float r, int num_segments) {
        glBegin(GL_LINE_LOOP);
        for (int ii = 0; ii < num_segments; ii++)   {
            float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);//get the current angle 
            float x = r * cosf(theta);//calculate the x component 
            float y = r * sinf(theta);//calculate the y component 
            glVertex2f(x + cx, y + cy);//output vertex 
        }
        glEnd();
    }
    void main_loop_function() {
        int c;
        drawFilledSun();
        DrawCircle(0, 0, 0.7, 100);
        glutSwapBuffers();
        c = getchar();
    }
    void GL_Setup(int width, int height) {
        glViewport(0, 0, width, height);
        glMatrixMode(GL_PROJECTION);
        glEnable(GL_DEPTH_TEST);
        gluPerspective(45, (float)width / height, .1, 100);
        glMatrixMode(GL_MODELVIEW);
    }
    int main(int argc, char** argv) {
        glutInit(&argc, argv);
        glutInitWindowSize(window_width, window_height);
        glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
        glutCreateWindow("GLUT Example!!!");
        glutIdleFunc(main_loop_function);
        GL_Setup(window_width, window_height);
        glutMainLoop();
    }
    

    这就是我所做的。我希望这有帮助。这里有两种类型的圆圈。已填充和未填充。

    【讨论】:

      【解决方案3】:

      还有另一种绘制圆的方法 - 在片段着色器中绘制它。 创建一个四边形:

      float right = 0.5;
      float bottom = -0.5;
      float left = -0.5;
      float top = 0.5;
      float quad[20] = {
          //x, y, z, lx, ly
          right, bottom, 0, 1.0, -1.0,
          right, top, 0, 1.0, 1.0,
          left, top, 0, -1.0, 1.0,
          left, bottom, 0, -1.0, -1.0,
      };
      

      绑定VBO:

      unsigned int glBuffer;
      glGenBuffers(1, &glBuffer);
      glBindBuffer(GL_ARRAY_BUFFER, glBuffer);
      glBufferData(GL_ARRAY_BUFFER, sizeof(float)*20, quad, GL_STATIC_DRAW);
      

      然后画图:

      #define BUFFER_OFFSET(i) ((char *)NULL + (i))
      glEnableVertexAttribArray(ATTRIB_VERTEX);
      glEnableVertexAttribArray(ATTRIB_VALUE);
      glVertexAttribPointer(ATTRIB_VERTEX , 3, GL_FLOAT, GL_FALSE, 20, 0);
      glVertexAttribPointer(ATTRIB_VALUE , 2, GL_FLOAT, GL_FALSE, 20, BUFFER_OFFSET(12));
      glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
      

      顶点着色器

      attribute vec2 value;
      uniform mat4 viewMatrix;
      uniform mat4 projectionMatrix;
      varying vec2 val;
      void main() {
          val = value;
          gl_Position = projectionMatrix*viewMatrix*vertex;
      }
      

      片段着色器

      varying vec2 val;
      void main() {
          float R = 1.0;
          float R2 = 0.5;
          float dist = sqrt(dot(val,val));
          if (dist >= R || dist <= R2) {
              discard;
          }
          float sm = smoothstep(R,R-0.01,dist);
          float sm2 = smoothstep(R2,R2+0.01,dist);
          float alpha = sm*sm2;
          gl_FragColor = vec4(0.0, 0.0, 1.0, alpha);
      }
      

      不要忘记启用 alpha 混合:

      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
      

      更新:Read more

      【讨论】:

        【解决方案4】:

        我们将从这张图片中找到 X 和 Y 的值。我们知道,sinθ=vertical/hypotenuse 和 cosθ=base/hypotenuse 从图像中我们可以说 X=base 和 Y=vertical。现在我们可以写成 X=hypotenuse * cosθ 和 Y=hypotenuse * sinθ。

        现在看看这段代码

        void display(){
        float x,y;
        glColor3f(1, 1, 0);
        for(double i =0; i <= 360;){
            glBegin(GL_TRIANGLES);
            x=5*cos(i);
            y=5*sin(i);
            glVertex2d(x, y);
            i=i+.5;
            x=5*cos(i);
            y=5*sin(i);
            glVertex2d(x, y);
            glVertex2d(0, 0);
            glEnd();
            i=i+.5;
        }
        glEnd();
        
        glutSwapBuffers();
        }
        

        【讨论】:

          【解决方案5】:
          glBegin(GL_POLYGON);                        // Middle circle
          double radius = 0.2;
          double ori_x = 0.0;                         // the origin or center of circle
          double ori_y = 0.0;
          for (int i = 0; i <= 300; i++) {
              double angle = 2 * PI * i / 300;
              double x = cos(angle) * radius;
              double y = sin(angle) * radius;
              glVertex2d(ori_x + x, ori_y + y);
          }
          glEnd();
          

          【讨论】:

          • //我用下面的代码做了这个,//但是确保你已经导入了需要的库
          • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
          【解决方案6】:

          这是一个绘制填充椭圆的代码,您可以使用相同的方法,但将 de xcenter 和 y center 替换为半径

          void drawFilledelipse(GLfloat x, GLfloat y, GLfloat xcenter,GLfloat ycenter) {
              int i;
              int triangleAmount = 20; //# of triangles used to draw circle
          
              //GLfloat radius = 0.8f; //radius
              GLfloat twicePi = 2.0f * PI;
          
              glBegin(GL_TRIANGLE_FAN);
              glVertex2f(x, y); // center of circle
              for (i = 0; i <= triangleAmount; i++) {
                  glVertex2f(
                      x + ((xcenter+1)* cos(i * twicePi / triangleAmount)),
                      y + ((ycenter-1)* sin(i * twicePi / triangleAmount))
                  );
              }
              glEnd();
          }
          

          【讨论】:

            【解决方案7】:

            我已经使用以下代码完成了,

            glBegin(GL.GL_LINE_LOOP);
                 for(int i =0; i <= 300; i++){
                     double angle = 2 * Math.PI * i / 300;
                     double x = Math.cos(angle);
                     double y = Math.sin(angle);
                     gl.glVertex2d(x,y);
                 }
            glEnd();
            

            【讨论】:

              【解决方案8】:
              glBegin(GL_POLYGON);
              double x = 2;
              double y = 2;
              for (int i = 0; i <= 360; i++) {
                  glVertex2d(x * sin(i), y * cos(i));
              }
              glEnd();
              

              【讨论】:

              • 这个答案与这里的其他答案没有什么不同。我正在投票关闭它。
              猜你喜欢
              • 2014-10-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-01-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多