Search code examples
c++openglglutopengl-compat

Drawing 3d and 2d in the same window not working correctly openGl


I am trying to draw some 3d ( a sun) and 2d (ground, cloud, ...) shapes in the same window, it actually worked! But the problem is when I when I run the program, it does not show smooth screen, it shows one shape then the other (while the first disappears), then the next shape and so on... here is the code, than you.

#include<windows.h>
#include<stdio.h>
#include<GL/glut.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#define CIRCLE_RADIUS  0.15f
# define PI 3.14159265358979323846
int eggs_caught = 0, missed_eggs = 0, level_count = 1, points = 0;


int egg_xc, egg_yc;
// for coordinates of egg
int basket_x, basket_y;
// for coordinates of basket
int a = 600, b = 650; // for default size of the screen
int s = 0;
// for menu option
int dropped_eggs = 0;
int speed_1 = 1, speed_2 = 1.5, speed_3 = 2, speed_4 = 2.5;
int w = 48, h = 48, t = 10, e = 9, g = 12;
void myinit();
void start_screen(int, int);
void cloud1();
void egg();
void basket(int, int);
void duck(int, int);
void print_score();
void egg_start();
void color();
void score();
void display(void);
void basket_set(int, int);
void myReshape(int, int);
void keys(unsigned char, int, int);
void menu(int);
void myinit()
{

}


void sun()
{
    GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
    GLfloat direction[] = { 1.0, 1.0, 1.0, 0.0 };

    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, yellow);
    glMaterialfv(GL_FRONT, GL_SPECULAR, yellow);
    glMaterialf(GL_FRONT, GL_SHININESS, 30);

    glLightfv(GL_LIGHT0, GL_AMBIENT, black);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, yellow);
    glLightfv(GL_LIGHT0, GL_SPECULAR, yellow);

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();

    glPushMatrix();
    glTranslatef(0, 0.0, 0);
    glutSolidSphere(0.5, 30, 30);
    glPopMatrix();

    glPopMatrix();
    glFlush();

    glDisable(GL_LIGHTING);
    glDisable(GL_LIGHT0);
    glDisable(GL_DEPTH_TEST);

}
void cloud1()
{

    float theta;
    GLfloat angle;
    glLineWidth(1.5);
    glColor3f(1, 1, 1);
    glBegin(GL_POLYGON);
    for (int i = 0; i < 360; i++)
    {
        theta = i * PI * i / 180;
        glVertex2f(100 + 50 * cos(theta) / 2, 590 + 50 * sin(theta) / 2);
    }

    glEnd();
    glLineWidth(1.5);
    glColor3f(1, 1, 1);
    glBegin(GL_POLYGON);
    for (int i = 0; i < 360; i++)
    {
        theta = i * PI * i / 180;
        glVertex2f(130 + 50 * cos(theta) / 2, 580 + 50 * sin(theta) / 2);
    }
    glEnd();

    glLineWidth(1.5);
    glColor3f(1, 1, 1);
    glBegin(GL_POLYGON);
    for (int i = 0; i < 360; i++)
    {
        theta = i * PI * i / 180;
        glVertex2f(140 + 50 * cos(theta) / 2, 600 + 50 * sin(theta) / 2);
    }
    glEnd();

    glLineWidth(1.5);
    glColor3f(1, 1, 1);
    glBegin(GL_POLYGON);
    for (int i = 0; i < 360; i++)
    {
        theta = i * PI * i / 180;
        glVertex2f(170 + 50 * cos(theta) / 2, 590 + 50 * sin(theta) / 2);
    }

    glEnd();
    glFlush();
}

void backk(int i, int j)
{


    glColor3f(0, .5, 1);
    glBegin(GL_QUADS);
    glVertex2f(0.0 + i, 0.0 + j);
    glVertex2f(600.0 + i, 0.0 + j);
    glVertex2f(600.0 + i, -500 + j);
    glVertex2f(0.0 + i, -500 + j);
    glEnd();
    glFlush();


}
void ground(int i, int j)
{

    glBegin(GL_QUADS);
    glColor3f(0, 1.0, 0);
    glVertex2f(0.0 + i, 0.0 + j);
    glVertex2f(600.0 + i, 0.0 + j);
    glVertex2f(600.0 + i, -j);
    glVertex2f(0.0 + i, -j);
    glEnd();
}


void duck(int i, int j)
{
    int h;
    glColor3f(1.0, 1.0, 0.0);
    glBegin(GL_POLYGON);
    glVertex2f(45 + i, 45 + j);
    glVertex2f(70 + i, 20 + j);
    glVertex2f(95 + i, 20 + j);
    glVertex2f(120 + i, 45 + j);
    glVertex2f(95 + i, 70 + j);
    glVertex2f(70 + i, 70 + j);
    glVertex2f(95 + i, 95 + j);
    glVertex2f(82.5 + i, 107.5 + j);
    glVertex2f(32.5 + i, 57.5 + j);
    glEnd();
    glFlush();
    for (h = 0; h < 13; h += 4)
    {
        glBegin(GL_LINES);
        glColor3f(0.7, 0.4, 0);
        glVertex2f(57.5 + h + i, 52.5 + h + j);
        glVertex2f(100 + h + i, 30 + h + j);
        glEnd();
        glFlush();
    }
    glColor3f(0.0, 1.0, 0.0);
    glBegin(GL_POLYGON);
    glVertex2f(82.5 + i, 107.5 + j);
    glVertex2f(65 + i, 107.5 + j);
    glVertex2f(50 + i, 95 + j);
    glVertex2f(70 + i, 95 + j);
    glEnd();
    glFlush();
    glColor3f(0.0, 0.0, 0.0);
    glPointSize(5);
    glBegin(GL_POINTS);
    glVertex2f(76 + i, 101 + j);
    glEnd();
    glColor3f(0.0, 1.0, 0.0);
    glBegin(GL_LINE_LOOP);
    glVertex2f(72.5 + i, 107.5 + j);
    glVertex2f(67.5 + i, 112.5 + j);
    glVertex2f(72.5 + i, 110 + j);
    glVertex2f(77.5 + i, 112.5 + j);
    glEnd();
    glFlush();
}


void display(void)
{
    GLfloat aspect = GLfloat(a) / GLfloat(b);
    glOrtho(-2.5 * aspect, 2.5 * aspect, -2.5, 2.5, -10.0, 10.0);
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-2.5 * aspect, 2.5 * aspect, -2.5, 2.5, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    sun();

    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, (GLdouble)a, 0.0, (GLdouble)b, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    cloud1();
    ground(0, 650);
    backk(0, 650);
    duck(40, 375);
    duck(180, 375);
    duck(320, 375);
}

void myReshape(int w, int h)
{
}
void keys(unsigned char key, int x, int y)
{
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);

    glutInitWindowSize(a, b);
    glutCreateWindow("EGG GAME");
    myinit();
    glutInitWindowPosition(100, 100);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    glutDisplayFunc(display);
    glutKeyboardFunc(keys);
    glutIdleFunc(display);
    glutReshapeFunc(myReshape);
    glutMainLoop();
}

Solution

  • not using GLUT but this is What I see at first look.

    1. glClear(GL_DEPTH_BUFFER_BIT);

      why not clear also color? try glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    2. no glutSwapBuffers();

      without this call at the end of display function your render is not updated when it needs to.

    3. no glFlush/glFinish before swapping buffers

      its safe to have them at the end. I see you got them in some of the rendering calls not all though.

    4. using int operands for glVertex2f

      Why not use glVertex2i instead when all of your coordinates are integers anyway. The int to float conversions slowing things down ...

    Take a look at some simple GLUT example I just found:

    In there the Display look like this:

    void display(void)
      {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      drawBox(); // here yoru rendering stuff instead
      glFlush(); // I usually add this before swapping buffers
      glutSwapBuffers();
      }
    

    so change your code accordingly...

    On top of all this I would maybe try to use Blending for the clouds ...