2013-05-15 3 views
2

작은 OpenGL - GLUT 프로그램 (전 완전히 멍청 해요)에서 일하고 있는데, gluPerspective와 glOrtho 사이에서 전환하는 데 많은 문제가 있습니다 (예 : 'p'). 내가 gluPerspectiveglOrthoglOrtho와 gluPerspective 사이를 전환

를 사용하여 ... 문제를 설명하기 위해 몇 가지 screenhots을했습니다 그리고 여기 내 코드의

...

내가 그린 "바닥"을 참조해야 해야하는
#if defined(__APPLE__) 
    #include <OpenGL/OpenGL.h> 
    #include <GLUT/GLUT.h> 
#else 
    #include <GL/gl.h> 
    #include <GL/greeglut.h> 
#endif 

#include <iostream> 
#include <math.h> 
#include "model.h" 

using namespace std; 

// actual vector representing the camera\'s direction 
float lx = 0.0f,lz = -1.0f; 
// XZ position of the camera 
float x = 0.0f,z = 5.0f; 
// angle for rotating triangle 
float angle = 0.0f; 
float fov = 45.0; 

Model m; 
Model m1; 
Model m2; 
Model m3; 

double maxX, maxY, maxZ; 
double minX, minY, minZ; 
double centX, centY, centZ; 
double maxTam; 

bool persp = true; 

double min(double x, double y) { 
    if(x < y) return x; 
    return y; 
} 

double max(double x, double y) { 
    if(x > y) return x; 
    return y; 
} 

void setMinMaxXYZ(void) { 
    maxX = minX = m.vertices()[0]; 
    maxY = minY = m.vertices()[1]; 
    maxZ = minZ = m.vertices()[2]; 

    for(int i = 3; i < m.vertices().size(); i += 3) { 
     maxX = max(maxX,m.vertices()[i]); 
     minX = min(minX,m.vertices()[i]); 

     maxY = max(maxY,m.vertices()[i+1]); 
     minY = min(minY,m.vertices()[i+1]); 

     maxZ = max(maxZ,m.vertices()[i+2]); 
     minZ = min(minZ,m.vertices()[i+2]); 
    } 

    centX = ((maxX - minX)/2) + minX; 
    centY = ((maxY - minY)/2) + minY; 
    centZ = ((maxZ - minZ)/2) + minZ; 
} 

void changeView(void) { 
    int w = glutGet(GLUT_WINDOW_WIDTH); 
    int h = glutGet(GLUT_WINDOW_HEIGHT); 
    float ratio = w * 1.0/h; 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    if(persp) gluPerspective(fov, ratio, 0.1f, 100.0f); 
    else glOrtho(-1,1,-1,1,-0.5,100.0); 

    glMatrixMode(GL_MODELVIEW); 
} 

void changeSize(int w, int h) { 
    // Prevent a divide by zero, when window is too short 
    // (you cant make a window of zero width). 
    if(h == 0) h = 1; 
    if(w == 0) w = 1; 

    float ratio = w * 1.0/h; 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    if(persp) gluPerspective(fov, ratio, 0.1f, 100.0f); 
    else glOrtho(-1,1,-1,1,0.1,100.0); 

    glViewport(0,0,w,h); 

    glMatrixMode(GL_MODELVIEW); 

    glutPostRedisplay(); 
} 

void renderScene(void) { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // Reset transformations 
    glLoadIdentity(); 

    // Posicionament de la càmera 
    gluLookAt( x, 1.0f, z, 
       x+lx, 1.0f, z+lz, 
       0.0f, 1.0f, 0.0f); 

    glClearColor(0.5,0.5,1.0,1.0); 

    // dibuix terra 
    glColor3f(0.0f, 255.0f, 0.0f); 
    glBegin(GL_QUADS); 
     glVertex3f(-5.0f, 0.0f, -5.0f); 
     glVertex3f(-5.0f, 0.0f, 5.0f); 
     glVertex3f(5.0f, 0.0f, 5.0f); 
     glVertex3f(5.0f, 0.0f, -5.0f); 
    glEnd(); 

    // Models .obj 
    for (int i = 0; i < 3; ++i) { 

     float transX, transY, transZ; 
     if(i == 0) { 
      m = m1; 
      transX = -1.25; transY = 0.5; transZ = -2.0; 

     } else if(i == 1) { 
      m = m2; 
      transX = -0.5; transY = 0.5; transZ = 2.5; 

     } else { 
      m = m3; 
      transX = 2.5; transY = 0.25; transZ = -0.5; 
     } 

     setMinMaxXYZ(); 
     maxTam = max(max(maxX - minX, maxY - minY), maxZ - minZ); 

     glPushMatrix(); 
      glTranslated(-(centX/maxTam), -(centY/maxTam), -(centZ/maxTam)); 
      glTranslated(transX,transY,transZ); 
      glScaled(1.0/maxTam,1.0/maxTam,1.0/maxTam); 

      glBegin(GL_TRIANGLES); 
       for(int i = 0; i < m.faces().size(); i++){ 
        const Face &f = m.faces()[i]; 
        glColor3f(Materials[f.mat].diffuse[0],Materials[f.mat].diffuse[1],Materials[f.mat].diffuse[2]); 

        for(int j = 0; j < 3; j++) 
         glVertex3dv(&m.vertices()[f.v[j]]); 
        } 
      glEnd(); 
     glPopMatrix(); 
    } 

    glutSwapBuffers(); 
} 

void processKeys(unsigned char key, int x, int y) { 
    if (key == 27) 
     exit(0); 

    else if(key == 'p'){ 
     persp = not persp; 
     changeView(); 
    } 
} 

void processSpecialKeys(int key, int xx, int yy) { 
    float fraction = 0.1f; 

    switch (key) { 
     case GLUT_KEY_LEFT : 
      angle -= 0.01f; 
      lx = sin(angle); 
      lz = -cos(angle); 
     break; 

     case GLUT_KEY_RIGHT : 
      angle += 0.01f; 
      lx = sin(angle); 
      lz = -cos(angle); 
     break; 

     case GLUT_KEY_UP : 
      x += lx * fraction; 
      z += lz * fraction; 
     break; 

     case GLUT_KEY_DOWN : 
      x -= lx * fraction; 
      z -= lz * fraction; 
     break; 
    } 
} 

void idle(void) { 
    glutPostRedisplay(); 
} 

void iniView(void) { 
    int w = glutGet(GLUT_WINDOW_WIDTH); 
    int h = glutGet(GLUT_WINDOW_HEIGHT); 
    float ratio = w * 1.0/h; 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    gluPerspective(45.0f, ratio, 0.1f, 100.0f); 
    //glOrtho(-1,1,-1,1,0.01,1000); 

    glMatrixMode(GL_MODELVIEW); 

} 

int main(int argc, char **argv) { 

    // init GLUT i creació finestra 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); 
    glutInitWindowPosition(100,100); 
    glutInitWindowSize(800,800); 
    glutCreateWindow("IDI: Bloc 3 - Càmeres i perspectives"); 

    // Carregar models .obj 
    m1.load("model/legoman-assegut.obj"); 
    m2.load("model/Shaun_Hastings.obj"); 
    m3.load("model/porsche.obj"); 

    // crides 
    glutDisplayFunc(renderScene); 
    glutReshapeFunc(changeSize); 
    glutIdleFunc(idle); 
    glutKeyboardFunc(processKeys); 
    glutSpecialFunc(processSpecialKeys); 

    iniView(); 

    // OpenGL init 
    glEnable(GL_DEPTH_TEST); 

    // loop 
    glutMainLoop(); 

    return 1; 
} 

glOrtho보기에서 ... 내가 뭘 잘못하고있어 ??

ps. 모델 개체는 교사가 제공 한 .obj 파일입니다.

편집 :

마지막으로, glOrtho가 제대로 작동합니다. 하지만 지금은 ... 또 다른 질문이 있습니다. 어떻게하면 창을 최대화 할 수 있습니까 (glOrtho 모드에서) 이미지가 변형되지 않습니다 ??

changeSize() 함수에서 ... gluPerspective를 사용할 때 잘 동작하지만 glOrtho가 아닙니다!

답변

0

직교 투영으로 바닥이 보이지 않는다는 사실은 실제로 모델 뷰 매트릭스를 설정하는 방법에 따라 예상됩니다 : 바닥이 XZ 평면에 평행하고 뷰 벡터가 너무 크기 때문에 발생합니다 . 하는 gluLookAt의

// Posicionament de la càmera 
gluLookAt( x, 1.0f, z, 
      x+lx, 1.0f, z+lz, 
      0.0f, 1.0f, 0.0f); 

처음 3 개 인수는 카메라 위치의 XYZ-구성 요소, 다음 3 개 인수는 '관심의 중심'의 XYZ 있습니다. 이 두 점 사이의 벡터는 뷰 벡터이고 Y- 구성 요소는 0입니다. 즉, XZ 및 그에 따라 바닥과 평행 함을 의미합니다.

바닥 + 정사영 투영을 보려면 카메라가 기울어 지도록 카메라를 기울여야합니다.

+0

대단히 감사합니다! : D 바닥이 나타납니다 !! haha – wrrzag

+0

음 ... 다른 질문이 있습니다. 어떻게 창을 최대화 할 수 있습니까? (glOrtho 모드에서) 이미지가 변형되지 않습니다 ?? – wrrzag