Drawing Circle with OpenGL

2020-03-01 05:27发布

I'm trying to draw simple circle with C++/OpenGl

my code is:

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

}

I'm beginner with OpenGL and now i'm starting to learn, Can someone please explain me why i don't get the circle (i only see the black box), Thanks!

标签: c++ opengl
6条回答
你好瞎i
2楼-- · 2020-03-01 05:31

Here is a code to draw a fill elipse, you can use the same method but replacing de xcenter and y center with radius

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

}

查看更多
【Aperson】
3楼-- · 2020-03-01 05:33

There is another way to draw a circle - draw it in fragment shader. Create a quad:

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,
};

Bind VBO:

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

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

Vertex shader

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

Fragment shader

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

Don't forget to enable alpha blending:

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

UPDATE: Read more

查看更多
Rolldiameter
4楼-- · 2020-03-01 05:33

We will find the value of X and Y from this image. We know, sinθ=vertical/hypotenuse and cosθ=base/hypotenuse from the image we can say base=X and Y=vertical. Now we can write X=hypotenuse*cosθ and Y=hypotenuse*sinθ. We will find the value of X and Y from this image. We know, sinθ=vertical/hypotenuse and cosθ=base/hypotenuse from the image we can say X=base and Y=vertical. Now we can write X=hypotenuse * cosθ and Y=hypotenuse * sinθ.

Now look at this code

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楼-- · 2020-03-01 05:34
#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();
}

This is what I did. I hope this helps. Two types of circle are here. Filled and unfilled.

查看更多
祖国的老花朵
6楼-- · 2020-03-01 05:36

It looks like immediately after you draw the circle, you go into the main glut loop, where you've set the Draw() function to draw every time through the loop. So it's probably drawing the circle, then erasing it immediately and drawing the square. You should probably either make DrawCircle() your glutDisplayFunc(), or call DrawCircle() from Draw().

查看更多
迷人小祖宗
7楼-- · 2020-03-01 05:51

I have done it using the following code,

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();
查看更多
登录 后发表回答