我正在用 opengl 简单地展示一个 3d 模型。问题是它显示不正确。我在这段代码上工作了几天,当我开始时,我遇到了完全相同的问题,但我修复了它,后来又把它弄坏了,现在我完全不记得解决方案了,这让我很沮丧。如果我不太注意的话,这可能是一件愚蠢的事情。
我唯一记得它与视口和相机有关,我更改的唯一代码如下。
我真的很感激有人像我一样很久没有看这段代码。也许有人会注意到我做错了什么,谢谢。
生成的图像如下所示:
#include <windows.h> // for timeGetTime()
#include <mmsystem.h> // ditto
#include <iostream> // I/O
#include <glut.h> // GLUT
//#include <gl/glu.h> // for gluPerspective & gluLookAt
#include "model3DS.h" // 3DS model support
model3DS *teddyModel;
model3DS *mush;
void setupScene();
void updateScene();
void renderScene();
void exitScene();
void keypress(unsigned char key, int x, int y);
void setViewport(int width, int height);
int tetrahedronAngle=0;
bool wireframe=false;
int windowId;
int win_width=1024, win_height = 768;
GLuint textureId;
DWORD lastTickCount;
GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
GLfloat left_light_position[] = {1500,1500,1500, 1.0};
GLfloat right_light_position[] = {-1500,-1500,-1500, 1.0};
void renderScene(){
// Clear framebuffer & depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glEnable(GL_LIGHTING);
// Reset Modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set view position & direction
// (Camera at (0,0,5) looking down the negative Z-axis)
gluLookAt(0,0,5, 0,0,-1, 0,1,0);
// Draw textured tetrahedron
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,textureId);
glPushMatrix();
glTranslatef(0.0,0.0,-1000.0);
glRotatef(-1*tetrahedronAngle/2.f,0,1,0);
teddyModel->draw();
glPopMatrix();
glPushMatrix();
glTranslatef(-300.0,0.0,-1000.0);
glRotatef(-1*tetrahedronAngle/2.f,0,1,0);
mush->draw();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
// Swap double buffer for flicker-free animation
glutSwapBuffers();
}
void updateScene(){
// Wait until at least 16ms passed since start of last frame
// Effectively caps framerate at ~60fps
while(timeGetTime()-lastTickCount<16);
lastTickCount=timeGetTime();
// Increment angle for next frame
tetrahedronAngle+=2;
// Do any other updates here
// Draw the next frame
glutPostRedisplay();
}
void keypress(unsigned char key, int x, int y){
// Test if user pressed ESCAPE (ascii 27)
// If so, exit the program
if(key==27){
exitScene();
}
if(key == 'w' || key == 'W'){
wireframe=!wireframe;
if(wireframe){
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
// Other possible keypresses go here
//if(key == 'a'){...}
}
void setupScene(){
std::cout<<"Initializing scene..."<<std::endl;
//Set up Lighting Stuff
glLightfv(GL_LIGHT0, GL_POSITION, left_light_position);
glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
glLightfv(GL_LIGHT1, GL_POSITION, right_light_position);
glLightfv(GL_LIGHT1, GL_SPECULAR, white_light);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
glLightfv(GL_LIGHT1, GL_DIFFUSE, white_light);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
//Load the teddy model
teddyModel = new model3DS("teddy\\teddy.3ds", 2);
mush = new model3DS("mushfat\\mushroom.3ds", 2);
}
void exitScene(){
std::cout<<"Exiting scene..."<<std::endl;
// Close window
glutDestroyWindow(windowId);
// Free any allocated memory
// Exit program
exit(0);
}
void setViewport(int width, int height) {
// Work out window ratio, avoid divide-by-zero
if(height==0)height=1;
float ratio = float(width)/float(height);
// Reset projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Fill screen with viewport
glViewport(0, 0, width, height);
// Set a 45 degree perspective
gluPerspective(45, ratio, .1, 2000);
}
int main(int argc, char *argv[]){
// Initialise OpenGL
glutInit(&argc, argv);
// Set window position, size & create window
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(50,50);
glutInitWindowSize(win_width,win_height);
windowId = glutCreateWindow("Lab 4: Loading a textured model");
// Set GLUT callback functions
glutReshapeFunc(setViewport);
glutDisplayFunc(renderScene);
glutIdleFunc(updateScene);
glutKeyboardFunc(keypress);
// Setup OpenGL state & scene resources (models, textures etc)
setupScene();
// Show window & start update loop
glutMainLoop();
return 0;
}