Question

I'm working in a little OpenGL - GLUT program (i'm totally noob), and i'm having many problems switching between gluPerspective and glOrtho pressing a key (for example 'p').

I've take some screenhots to illustrate the problem... using gluPerspective and glOrtho

And here's my code...

#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;
}

It's supposed that i should see the green "floor" in the glOrtho view... what i'm doing wrong??

ps. Model objects are .obj files delivered by the teacher.

edit:

Finally, the glOrtho works properly. But now... i've got another question, how can i do to maximize the window and (in glOrtho mode) the image does not deform??

In changeSize() function... when i'm using gluPerspective it works fine, but not with glOrtho!!

Was it helpful?

Solution

the fact that you don't see the floor with orthographic projection is actually expected given the way you set up your modelview matrix: it happens because your floor is parallel to the XZ plane - and your view vector is, too.

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

the first 3 arguments of gluLookAt are the xyz-components of the camera position, the next 3 arguments are the xyz of the 'center of interest'. the vector between those 2 points is the view vector, and its y-component is 0, meaning it is parallel to XZ and thus your floor.

if you want to see the floor + orthographic projection, you'll have to tilt the camera so that it looks down.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top