根据完整的OpenGL代码给出包含问题分析、实验步骤、实验结果等#include <GL/glut.h>
#include <SOIL/SOIL.h>
// 纹理ID数组
GLuint textures[3];
// 光照设置
void initLighting() {
// 启用光照和深度测试
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
// 光源1 (白色点光源)
GLfloat light0_ambient[] = {0.2, 0.2, 0.2, 1.0};
GLfloat light0_diffuse[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light0_specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light0_position[] = {2.0, 2.0, 2.0, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glEnable(GL_LIGHT0);
// 光源2 (蓝色方向光)
GLfloat light1_ambient[] = {0.1, 0.1, 0.3, 1.0};
GLfloat light1_diffuse[] = {0.3, 0.3, 1.0, 1.0};
GLfloat light1_specular[] = {0.5, 0.5, 1.0, 1.0};
GLfloat light1_position[] = {-2.0, -2.0, -1.0, 0.0};
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular);
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
glEnable(GL_LIGHT1);
}
// 加载纹理
void loadTexture(const char* filename, GLuint textureID) {
glBindTexture(GL_TEXTURE_2D, textureID);
// 设置纹理参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// 使用SOIL加载图像
int width, height;
unsigned char* image = SOIL_load_image(filename, &width, &height, 0, SOIL_LOAD_RGB);
if (image) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
printf("Texture loaded: %s\n", filename);
} else {
printf("Failed to load texture: %s\n", filename);
}
}
// 初始化纹理
void initTextures() {
glGenTextures(3, textures);
// 加载三个纹理图像
// 注意:实际运行时需要准备这三个纹理图片文件
loadTexture("texture1.jpg", textures[0]);
loadTexture("texture2.jpg", textures[1]);
loadTexture("texture3.jpg", textures[2]);
}
// 绘制立方体
void drawCube() {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textures[0]);
// 设置材质属性 (金色)
GLfloat mat_ambient[] = {0.24725, 0.1995, 0.0745, 1.0};
GLfloat mat_diffuse[] = {0.75164, 0.60648, 0.22648, 1.0};
GLfloat mat_specular[] = {0.628281, 0.555802, 0.366065, 1.0};
GLfloat shininess[] = {51.2};
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
// 绘制立方体
glBegin(GL_QUADS);
// 前面
glNormal3f(0.0, 0.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
// 后面
glNormal3f(0.0, 0.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
// 上面
glNormal3f(0.0, 1.0, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
// 下面
glNormal3f(0.0, -1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
// 右面
glNormal3f(1.0, 0.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -1.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
glTexCoord2f(0.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
// 左面
glNormal3f(-1.0, 0.0, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(1.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -1.0);
glEnd();
glDisable(GL_TEXTURE_2D);
}
// 绘制球体
void drawSphere() {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textures[1]);
// 设置材质属性 (银色)
GLfloat mat_ambient[] = {0.19225, 0.19225, 0.19225, 1.0};
GLfloat mat_diffuse[] = {0.50754, 0.50754, 0.50754, 1.0};
GLfloat mat_specular[] = {0.508273, 0.508273, 0.508273, 1.0};
GLfloat shininess[] = {51.2};
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shininess);
// 绘制球体
GLUquadricObj* quad = gluNewQuadric();
gluQuadricTexture(quad, GL_TRUE);
gluSphere(quad, 1.0, 32, 32);
gluDeleteQuadric(quad);
glDisable(GL_TEXTURE_2D);
}
// 显示回调函数
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// 设置视点
gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);
// 绘制立方体
glPushMatrix();
glTranslatef(-1.5, 0.0, 0.0);
drawCube();
glPopMatrix();
// 绘制球体
glPushMatrix();
glTranslatef(1.5, 0.0, 0.0);
drawSphere();
glPopMatrix();
glutSwapBuffers();
}
// 窗口大小改变回调函数
void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w/(float)h, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// 键盘回调函数
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case '1':
glShadeModel(GL_FLAT);
printf("Shading mode: GL_FLAT\n");
break;
case '2':
glShadeModel(GL_SMOOTH);
printf("Shading mode: GL_SMOOTH\n");
break;
case 27: // ESC键
exit(0);
break;
}
glutPostRedisplay();
}
// 主函数
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Realistic Graphics with OpenGL");
// 初始化
initLighting();
initTextures();
// 注册回调函数
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
// 设置背景色
glClearColor(0.0, 0.0, 0.0, 0.0);
// 默认使用平滑着色
glShadeModel(GL_SMOOTH);
glutMainLoop();
return 0;
}
最新发布