Search code examples
c++openglglut

OpenGL with GLUT - black screen


I want to receive a small animation for four triangles. I wrote a several versions of the code, but none of these versions works. In result I have a blank black screen. My code:

#define GLUT_DISABLE_ATEXIT_HACK
#define TIMERSECS 20

#include <windows.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/GL.H>
#include <stdlib.h>

float arc = 0.0f;

void draw_traingle(float x0, float y0, float x1, float y1, float x2, float y2) {
    glColor4f(0.0f, 0.0f, 1.0f, 1.0f); //Blue
    glVertex2f(x0, y0);
    glVertex2f(x1, y1);
    glVertex2f(x2, y2);
}

void draw(void) {
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT);
    glRotatef(arc, 1.0f,0.0f,0.0f);

    glBegin(GL_POLYGON);

    float center_x = 300.0f;
    float center_y = 300.0f;

    float up_x = center_x;
    float up_y = 250.0f;

    float down_x = center_x;
    float down_y = 350.0f;

    float right_x = 350.0f;
    float right_y = center_y;

    float left_x = 250.0f;
    float left_y = center_y;
    glPushMatrix();
    draw_traingle(up_x, up_y, right_x, right_y, center_x, center_y);
    draw_traingle(right_x, right_y, down_x, down_y, center_x, center_y);
    draw_traingle(down_x, down_y, left_x, left_y, center_x, center_y);
    draw_traingle(left_x, left_y, up_x, up_y, center_x, center_y);
    glPopMatrix();
    glEnd();
    glFlush();
    glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
    switch (key) {
    case 27:
        exit(0);
    }
}
void init(void) {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glViewport(0, 0, 600, 600);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity(); //=1
    gluOrtho2D(0.0, 600.0, 0.0, 600.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity(); //=1
}
void update(int value) {
    arc += 2.0f;
    if (arc > 360.f) {
        arc -= 360;
    }
    glutPostRedisplay();
    glutTimerFunc(TIMERSECS, update, 0);
}
int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //single buffer and RGBA
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Window");
    init();
    glutDisplayFunc(draw);
    glutTimerFunc(TIMERSECS, update, 0);
    glutKeyboardFunc(handleKeypress);
    glutMainLoop();
    return 0;
}

I want to create an animation where my rectange builded from traingles will rotate for 2 degrees per some small time. I want to rotate it like clock works. i know that the problem is not in time (not to small) but in glRotatef - I don't know what parameters it should takes to give me a proper effect.

Thanks in advance! :)


Solution

  • #include <GL/glut.h>
    #include <GL/gl.h>
    #include <stdlib.h>
    //#define TIMERSECS 200 prefer not to use preprocessor macros
    //instead you can use:
    static const int TIMERSECS = 200;
    
    float arc = 0.0f;
    
    void draw_traingle(float x0, float y0, float x1, float y1, float x2,     float y2) {
        glBegin(GL_POLYGON);
        glColor4f(0.0f, 0.0f, 1.0f, 1.0f); //Blue
        glVertex2f(x0, y0);
        glVertex2f(x1, y1);
        glVertex2f(x2, y2);
        glEnd();
    }
    
    void draw(void) {
        glClear(GL_COLOR_BUFFER_BIT);
        glTranslatef(300, 300, 0);
        glRotatef(arc, 0.0f,0.0f,1.0f);
        glTranslatef(-300, -300, 0);
    
        float center_x = 300.0f;
        float center_y = 300.0f;
    
        float up_x = center_x;
        float up_y = 250.0f;
    
        float down_x = center_x;
        float down_y = 350.0f;
    
        float right_x = 350.0f;
        float right_y = center_y;
    
        float left_x = 250.0f;
        float left_y = center_y;
        draw_traingle(up_x, up_y, right_x, right_y, center_x,     center_y);
        draw_traingle(right_x, right_y, down_x, down_y, center_x, center_y);
        draw_traingle(down_x, down_y, left_x, left_y, center_x, center_y);
        draw_traingle(left_x, left_y, up_x, up_y, center_x, center_y);
    
        glutSwapBuffers();
    }
    
    void handleKeypress(unsigned char key, int x, int y) {
        switch (key) {
        case 27:
                exit(0);
        }
    }
    
    void init() {
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glViewport(0, 0, 600, 600);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity(); //=1
        gluOrtho2D(0.0, 600.0, 0.0, 600.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity(); //=1
    }
    void update(int value) {
        arc += 2.0f;
        if (arc > 360.f) {
                arc -= 360;
        }
        glutPostRedisplay();
        glutTimerFunc(200, update, 1);
    }
    int main(int argc, char** argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE  | GLUT_RGBA); //single buffer and RGBA
        glutInitWindowSize(600, 600);
        glutCreateWindow("Window");
        init();
        glutDisplayFunc(draw);
        glutTimerFunc(TIMERSECS, update, 1);
        glutKeyboardFunc(handleKeypress);
        glutMainLoop();
        return 0;
    }
    

    Rotation is always relative to the coordinate system you are using. Transforimations are always applied in the reverse order. When we use rotatef function to rotate an object it's always relative to the center of the coordinate system. So first we need to translate it to to the center which is done by translatef(-300,-300,0). Now the object is on the center. Then we use rotatef to rotate the object to x,y or z axis. Then we translate the object again to the position that was before the transformation. Finally we write the functions in reverse order. You are good to go :)