opengl не показывает вывод из renderFunction

Я реализовывал этот алгоритм 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;
}

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


person Community    schedule 25.04.2019    source источник
comment
мои алгоритмы работают нормально.   -  person    schedule 25.04.2019


Ответы (1)


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();
}
person Rabbid76    schedule 25.04.2019
comment
Я пробовал это. Не сработало :(. А разве здесь не происходит именно это? Я имею в виду функцию рендеринга, которая после loadIdentity выполняет glOrtho. - person ; 25.04.2019
comment
@kesarling Терпение, есть более 1 проблемы. - person Rabbid76; 25.04.2019
comment
Ой, извини. Я также пытался сделать x и y плавающими. Теперь он рисует пунктирную линию. - person ; 25.04.2019
comment
и по-прежнему рисует только одну линию - person ; 25.04.2019
comment
@kesarling У меня 2 строчки. - person Rabbid76; 25.04.2019
comment
Ницца. после новой правки в renderFunction у меня получилось две строчки. Почему мой не работал? - person ; 25.04.2019
comment
@kesarling Поскольку x и y увеличиваются на -1, 0 или 1, это позволяет использовать только линии, выровненные по 45 градусам. - person Rabbid76; 25.04.2019
comment
Давайте продолжим обсуждение в чате. - person ; 25.04.2019
comment
Я имел в виду, как работает изменение этих двух конкретных строк для включения в renderFuntions? - person ; 25.04.2019
comment
@kesarling Изменение типа с int на float приводит к тому, что x и y отслеживаются с полной точностью. glVertex2i((int)(x+0.5f), (int)(y+0.5f)) обеспечивает округление координат x и y до целого числа. - person Rabbid76; 25.04.2019