2013-05-15 72 views
2

我在一個小的OpenGL工作之間切換。glOrtho和gluPerspective

我已經採取一些screenhots使用gluPerspectiveglOrtho

來說明這個問題...這是我的代碼...

#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平面平行 - 你的視圖矢量也是。

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

gluLookAt的前3個參數是相機位置的XYZ組件,接下來3個參數是「感興趣的中心」的XYZ。這兩個點之間的向量是視圖向量,其y分量爲0,這意味着它與XZ平行,因此也是平行的。

,如果你想看到的地板+正投影,你必須傾斜相機,使得它看起來下來。

+0

坦克你這麼多! :D地板出現!哈哈 – wrrzag

+0

呃...我有另一個問題,我怎麼做最大化窗口和(在glOrtho模式)圖像不變形? – wrrzag