переключаться между glOrtho и gluPerspective

Я работаю в небольшой программе OpenGL — GLUT (я полностью нуб), и у меня много проблем с переключением между gluPerspective и glOrtho, нажимающим клавишу (например, «p»).

Я взял несколько скриншотов, чтобы проиллюстрировать проблему … используя gluPerspective а также glOrtho

А вот и мой код …

#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 … что я делаю не так ??

пс. Объектами модели являются файлы .obj, предоставленные преподавателем.

редактировать:

Наконец, glOrtho работает правильно. Но теперь … у меня есть еще один вопрос, как я могу сделать, чтобы максимизировать окно и (в режиме glOrtho) изображение не деформируется?

В функции changeSize () … когда я использую gluPerspective, он работает нормально, но не с glOrtho !!

2

Решение

тот факт, что вы не видите слово с ортогональной проекцией, на самом деле ожидается с учетом того, как вы настроили матрицу вида модели:
это происходит потому, что ваш пол параллелен плоскости XZ — и ваш вектор обзора тоже.

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

первые 3 аргумента gluLookAt — это xyz-компоненты положения камеры, следующие 3 аргумента — это xyz «центра интересов». вектор между этими двумя точками является вектором представления, а его y-компонент равен 0, что означает, что он параллелен XZ и, следовательно, вашему полу.

если вы хотите увидеть пол + ортографическую проекцию, вам придется наклонить камеру так, чтобы она смотрела вниз.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]