Искаженный вывод, когда я применяю проекцию OpenGL - PullRequest
0 голосов
/ 16 декабря 2018

Я пытаюсь реализовать функциональность камеры в простой сцене, но вывод искажен.Я думаю, что это как-то связано с перспективной проекцией или, может быть, я неправильно использую функцию gluLookAt(), но я не могу точно определить проблему.Всякий раз, когда я нажимаю клавиши со стрелками, чтобы больше камеры, вид искажается.Код камеры отлично работает в другом примере.Я использовал точно такой же код с замененным дисплеем для моей сцены.Я пробовал разные аргументы для gluLookAt() и даже пробовал проекцию на орто, но ничего не помогло.

До внедрения камеры:

World View

После внедрения камеры:

After trying camera

Код:

#include <Windows.h>
#include <math.h>
#include "glut.h"
float angle = 0.0f;
float lx = 0.0f, lz = -0.1f;
float x = 0.0f, z = 0.5f;
float deltaAngle = 0.0f;
float deltaMove = 0;

double rot = 0;
double doorAngle = 0;
double carMove = -0.75; //Initially car positioned at the start of road

void myInit(void)
{
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(1000, 480);
    glutInitWindowPosition(100, 150);
    glutCreateWindow(" project part1 ");
    glClearColor(0.333, 0.725, 0.905, 0);
    glColor3f(0.0f, 0.0f, 0.0f);
}

void reshape(int w, int h) {
    if (h == 0)
        h = 1;
    float ratio = w* 1.0 / h;    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, w, h);
    gluPerspective(45.0f, ratio, 0.1f, 20.0f);
    glMatrixMode(GL_MODELVIEW);
}
void computePos(float deltaMove) //compute camera position
{
    x += deltaMove * lx * 0.1f;
    z += deltaMove * lz * 0.1f;
}

void computeDir(float deltaAngle)//compute camra direction
{
    angle += deltaAngle;
    lx = sin(angle);
    lz = -cos(angle);
}
void display(void)
{
    if (deltaMove)
        computePos(deltaMove);
    if (deltaAngle)
        computeDir(deltaAngle);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt(x, 0.0f, z, x + lx, 0.0f, z + lz, 0.0f, 1.0f, 0.0f);
    //display quads road
    glPushMatrix();
    glLineWidth(3.0);
    glColor3f(0.474, 0.552, 0.603);
    glBegin(GL_QUADS);//grey road

    glTexCoord2f(0.0, 0.0);
    glVertex3f(-1, 0, 0);

    glTexCoord2f(0.0, 1.0);
    glVertex3f(1, 0, 0);

    glTexCoord2f(1.0, 1.0);
    glVertex3f(1, -1, 0);

    glTexCoord2f(1.0, 0.0);
    glVertex3f(-1, -1, 0);

    glEnd();
    //green grass above
    glColor3f(0.305, 0.513, 0.341);
    glBegin(GL_QUADS);
    glVertex3f(-1, 0, 0);
    glVertex3f(1, 0, 0);
    glVertex3f(1, -0.1, 0);
    glVertex3f(-1, -0.1, 0);
    glEnd();
    //green grass below
    glColor3f(0.372, 0.407, 0.070);
    glBegin(GL_QUADS);
    glVertex3f(-1, -1, 0);
    glVertex3f(1, -1, 0);
    glVertex3f(1, -0.8, 0);
    glVertex3f(-1, -0.8, 0);
    glEnd();

    //white lines on road
    glColor3f(0.929, 0.850, 0.850);
    glPointSize(5.0);
    int factor = 10; GLushort pattern = 0x3333;
    glEnable(GL_LINE_STIPPLE);
    glLineStipple(factor, pattern);
    glBegin(GL_LINES);
    glVertex3f(1, -0.45, 0);
    glVertex3f(-1, -0.45, 0);
    glEnd();
    glDisable(GL_LINE_STIPPLE);

    glColor3f(0.929, 0.850, 0.850);
    glPointSize(5.0);
    glBegin(GL_LINES);
    glVertex3f(1, -0.75, 0);
    glVertex3f(-1, -0.75, 0);
    glVertex3f(1, -0.15, 0);
    glVertex3f(-1, -0.15, 0);
    glEnd();

    glPushMatrix();
    glTranslatef(-0.8, 0.4, 0);
    glScalef(0.5, 0.45, 0);
    building(0, 0.17, 0.394);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-0.35, 0.27, 0);
    glScalef(0.55, 0.3, 0);
    building(0.552, 0.266, 0.505);
    glPopMatrix();

    glPushMatrix();
    //glLoadIdentity();
    glTranslatef(0.2, 0.45, 0);
    glScalef(1.2, 0.5, 0);
    building(0.294, 0.337, 0.584);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0.75, 0.27, 0);
    glScalef(0.55, 0.3, 0);
    building(0.309, 0.396, 0.427);
    glPopMatrix();
    //building bases

    //car1
    glPushMatrix();
    glTranslatef(carMove, -0.2, 0);
    glScalef(0.5, 0.5, 0.5);
    car(0.65, 0, 0);
    glPopMatrix();

    glutSwapBuffers();
}
void pressKey(int key, int xx, int yy) {

    switch (key) {
    case GLUT_KEY_LEFT: 
        if (deltaAngle > 30)
            break;
        deltaAngle = -0.01f;
        glutPostRedisplay();
        break;
    case GLUT_KEY_RIGHT: deltaAngle = 0.01f; break;
    case GLUT_KEY_UP: deltaMove = 0.05f; break;
    case GLUT_KEY_DOWN: deltaMove = -0.05f; break;
    }
}


void releaseKey(int key, int x, int y) {
    switch (key) {
    case GLUT_KEY_LEFT:
    case GLUT_KEY_RIGHT: deltaAngle = 0.0f; break;
    case GLUT_KEY_UP:
    case GLUT_KEY_DOWN: deltaMove = 0; break;
    }
}

void main(int argc, char **argv)
{
    glutInit(&argc, argv);
    myInit();

    glutDisplayFunc(display);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(display);
    glutSpecialFunc(pressKey);
    glutSpecialUpFunc(releaseKey);
    glEnable(GL_DEPTH_TEST);
    glutMainLoop();
}

Примечание:
Код автомобиля и строительный код исключены из-за слишком большого размера, но они работают нормально, и я не думаю, что ониэта проблема.Если вам нужен полный рабочий код, пожалуйста, дайте мне знать, и я его выложу.Я застрял в этой проблеме некоторое время.Любая помощь приветствуется

1 Ответ

0 голосов
/ 16 декабря 2018

Это проблема Z-боя .

Чтобы решить эту проблему, вы должны отключить Проверка глубины и нарисовать объекты обратно наfront:

glEnable(GL_DEPTH_TEST)

Или вам нужно нарисовать объект с другими координатами z, которые определяют порядок z объекта.

Обратите внимание, что в пространстве вида ось z указывает на область просмотра.Поэтому, если координата z объекта больше, чем у другого объекта, тогда этот объект находится перед другим объектом.

Эффект перспективы может быть достигнут только в том случае, если глубина объектов различна,так что объект сзади выглядит меньше, чем тот объект, который находится ближе к точке зрения (положение глаза).

Но вы должны убедиться, что объекты не обрезаны.
Это означает (расстояние просмотра) z расстояние объекта до положения глаза (первые 3 параметра gluLookAt) должен находиться между ближней и дальней плоскостями (последние 2 параметра gluPerspective).

...