Search code examples
copenglglutbresenhamopengl-compat

opengl not showing output from renderFunction


I was implementing this dda algorithm using opengl. However, for some reason, it doesn't plot the second line. I tried putting printf at every line, which shows that it IS executing. However, there is no output in my window

#include <GL/gl.h>
#include <GL/glut.h>
#include <stdio.h>

int choice = 0;

void DDA(x0, y0, x1, y1)
const x0, y0, x1, y1;
{
    glOrtho(-500, 500, -500, 500, -1, 1);
    float dx = x1 - x0;
    float dy = y1 - y0;
    int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
    float xInc = (float)steps/dx;
    float yInc = (float)steps/dy;
    int x = x0, y = y0;
    for(int i = 0; i < steps; i++) {
        glBegin(GL_POINTS);
            glColor3f(1.0, 3.0, 2.0);
            glVertex2i(x, y);
            x += xInc;
            y += yInc;
        glEnd();
        glFlush();
    }
}

void Bresenham(x0, y0, x1, y1)
const x0, y0, x1, y1;
{
    glOrtho(-500, 500, -500, 500, -1, 1);
    int x = x0;
    int y = y0;
    int dx = x1 - x0;
    int dy = y1 - y0;
    int p = 2*dy-dx;
    int m = dy / dx;
    glBegin(GL_POINTS); {
        glColor3f(2.0, 3.0, 5.0);
        while(x != x1) {
            if(m < 1) {
                glVertex2i(x, y);
                x++;
                if(p >= 0) {
                    p += 2*(dy - dx);
                    y++;
                }
                else {
                    p += 2*dy;
                }
            }
            else {
                glVertex2i(x, y);
                y++;
                if(p >= 0) {
                    p += 2*(dx - dy);
                    x++;
                }
                else {
                    p += 2*dx;
                }
            }
        }
        glVertex2i(x, y);
    }
    glEnd();
    glFlush();
}

void circle(x0, y0, r)
const x0, y0, r;
{

}

void renderDDA(void) {
    DDA(0, 0, 300, 400);
    DDA(0, 0, 200, 200);
}

void renderBresenham(void) {
    Bresenham(0, 0, 300, 100);
    Bresenham(0, 0, 500, 0);
}

void renderCircle(void) {

}

main(argc, argv)
char** argv;
{
redo:   
    printf("ENTER YOUR CHOICE: ");
    scanf("%d", &choice);
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(1920, 1680);
    glutCreateWindow(argv[1]);
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    switch (choice) {
        case 0:
            glutDisplayFunc(renderDDA);
            break;
        case 1:
            glutDisplayFunc(renderBresenham);
            break;
        case 2:
            glutDisplayFunc(renderCircle);
            break;
        default:
            printf("NO SUCH CHOICE!!");
            goto redo;
    }
    glutMainLoop();
return 0;
}

I also tried swapping the lines. Then it draws only the upper line. it does execute the second call however.


Solution

  • glOrtho does not set an orthographic projection, it defines an orthographic projection matrix and multiplies the current matrix by the orthographic projection matrix.

    You've to set the identity matrix before calling glOrtho:

    glLoadIdentity();
    glOrtho(-500, 500, -500, 500, -1, 1);
    

    Further there is an issue in the algorithm. The type of x and y has to be float. If you would trunc the result to int, then it is only possible to draw lines with angles that are aligned to multiples of 45 degreess, because x and y change exactly by 0 or 1 at each step:

    float x = x0, y = y0;
    for(int i = 0; i < steps; i++) {
        glBegin(GL_POINTS);
            glColor3f(1.0, 3.0, 2.0);
            glVertex2i((int)(x+0.5f), (int)(y+0.5f));
            x += xInc;
            y += yInc;
        glEnd();
    } 
    

    Note, changing the type from int to float causes that x and y are tracked with full precision. glVertex2i((int)(x+0.5f), (int)(y+0.5f)) ensures that coordinates (x, y) are rounded to the integral position when the point is draw.


    I recommend to move the setting of the projection matrix from and glFlush from DDA respectively Bresenham to renderDDA respectively renderBresenham:

    void DDA(float x0, float y0, float x1, float y1)
    {
        float dx = x1 - x0;
        float dy = y1 - y0;
        int steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
        float xInc = (float)steps/dx;
        float yInc = (float)steps/dy;
        float x = x0, y = y0;
        for(int i = 0; i < steps; i++) {
            glBegin(GL_POINTS);
                glColor3f(1.0, 3.0, 2.0);
                glVertex2i((int)(x+0.5f), (int)(y+0.5f));
                x += xInc;
                y += yInc;
            glEnd();
        }
    }
    
    void Bresenham(float x0, float y0, float x1, float y1)
    {
        int x = x0;
        int y = y0;
        int dx = x1 - x0;
        int dy = y1 - y0;
        int p = 2*dy-dx;
        int m = dy / dx;
        glBegin(GL_POINTS); {
            glColor3f(2.0, 3.0, 5.0);
            while(x != x1) {
                if(m < 1) {
                    glVertex2i(x, y);
                    x++;
                    if(p >= 0) {
                        p += 2*(dy - dx);
                        y++;
                    }
                    else {
                        p += 2*dy;
                    }
                }
                else {
                    glVertex2i(x, y);
                    y++;
                    if(p >= 0) {
                        p += 2*(dx - dy);
                        x++;
                    }
                    else {
                        p += 2*dx;
                    }
                }
            }
            glVertex2i(x, y);
        }
        glEnd();
    }
    
    void renderDDA(void) {
        glLoadIdentity();
        glOrtho(-500, 500, -500, 500, -1, 1);
        DDA(0, 0, 300, 400);
        DDA(0, 0, 200, 200);
        glFlush();
        glutSwapBuffers();
    }
    
    void renderBresenham(void) {
        glLoadIdentity();
        glOrtho(-500, 500, -500, 500, -1, 1);
        Bresenham(0, 0, 300, 100);
        Bresenham(0, 0, 500, 0);
        glFlush();
        glutSwapBuffers();
    }