26
votes

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!

7

7 Answers

18
votes

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

13
votes
#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
votes

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

3
votes

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();
}
2
votes

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();
}
2
votes
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();
0
votes

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