gpt4 book ai didi

c++ - 在 glOrtho 和 gluPerspective 之间切换

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:57:19 26 4
gpt4 key购买 nike

我在一个小的 OpenGL - GLUT 程序中工作(我完全是菜鸟),我在 gluPerspective 和 glOrtho 之间切换时遇到了很多问题,按下一个键(例如'p')。

我拍了一些截图来说明这个问题......使用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 View 中看到绿色的“地板”……我做错了什么??

附言。模型对象是老师下发的.obj文件。

编辑:

最后,glOrtho 正常工作。但是现在......我有另一个问题,我该怎么做才能最大化窗口并且(在 glOrtho 模式下)图像不变形?

在 changeSize() 函数中...当我使用 gluPerspective 时它工作正常,但使用 glOrtho 时不行!!

最佳答案

考虑到您设置模型 View 矩阵的方式,您实际上看不到带有正交投影的地板这一事实:发生这种情况是因为您的地板平行于 XZ 平面 - 并且您的 View vector 也是。

// 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。这两个点之间的 vector 是 View vector ,它的 y 分量为 0,这意味着它平行于 XZ,因此平行于你的地板。

如果你想看到地板 + 正投影,你必须倾斜相机使其向下看。

关于c++ - 在 glOrtho 和 gluPerspective 之间切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16559599/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com