opengl 不显示 renderFunction 的输出

opengl not showing output from renderFunction

我正在使用 opengl 实现这个 dda 算法。但是,出于某种原因,它没有绘制第二条线。我试着把 printf 放在每一行,这表明它正在执行。但是,我的 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;
}

我也试过换行。然后它只绘制上面的线。但是它确实执行了第二个调用。

glOrtho没有设置正射投影,它定义了一个正射投影矩阵,并将当前矩阵乘以正射投影矩阵。

你必须在调用之前设置单位矩阵 glOrtho:

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

而且算法有问题。 xy 的类型必须是 float。如果将结果截断为 int,则只能绘制角度与 45 度的倍数对齐的线,因为 xy 恰好变化 0 或 1每一步:

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

请注意,将类型从 int 更改为 float 会导致 xy 被完全精确地跟踪。 glVertex2i((int)(x+0.5f), (int)(y+0.5f))确保坐标(x,y)在绘制点时四舍五入到整数位置。


我建议将投影矩阵的设置从 glFlush 分别从 DDA Bresenham 分别移动到 renderDDA 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();
}