opengl не показывает вывод из renderFunction - PullRequest
1 голос
/ 25 апреля 2019

Я реализовывал этот алгоритм dda, используя opengl. Однако по какой-то причине он не отображает вторую линию. Я попытался поместить 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;
}

Я также пытался поменять местами. Тогда он рисует только верхнюю линию. однако он выполняет второй вызов.

1 Ответ

1 голос
/ 25 апреля 2019

glOrtho не устанавливает ортографическую проекцию, она определяет матрицу ортографической проекции и умножает текущую матрицу на матрицу ортографической проекции.

Вы должны установить матрицу тождественностиперед вызовом glOrtho:

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

Далее в алгоритме есть проблема.Тип x и y должен быть float.Если вы урежете результат до int, то можно будет рисовать только линии с углами, выровненными с кратными 45 градусам, потому что x и y меняются точно на 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 приводит к тому, что x и y отслеживаются с полной точностью.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();
}
...