opengl没有显示renderFunction的输出

问题描述 投票:1回答:1

我正在使用opengl实现这个dda算法。但是,由于某种原因,它没有绘制第二行。我尝试将printf放在每一行,这表明它正在执行。但是,我的窗口中没有输出

#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;
}

我也尝试过换线。然后它只画上线。但它会执行第二次调用。

c opengl glut bresenham opengl-compat
1个回答
1
投票

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))确保坐标(xy)在绘制点时四舍五入到整数位置。


我建议将glFlushDDA中的投影矩阵的设置分别从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();
}
© www.soinside.com 2019 - 2024. All rights reserved.