使用Opengl库实现
实验一
一、实验目的
1.熟悉3D基本编程。
2.熟悉视点观察函数的设置和使用。3.熟悉投影变换函数的设置和使用。4.熟悉基本3D图元的绘制。
二、实验内容
1.读懂以下3D物体程序,并结合本书内容理解一些新的绘制函数和投影变换函数的含义:3D Cube.cpp(见后面参考程序)为正交投影下的旋转3D立方体,按下鼠标可实现不同方向的旋转,效果图参见实验图9-1,分析3D编程代码与程序结构。
对于以下操作需要记录不同效果图和修改的相应参数:
1)让静止的立方体绕Z轴不停旋转。
修改参数:
- // 设置旋转轴:两个三维的点确定的旋转轴
- GLfloat axis[][3] = {
- 0.5f,0.5f, 0.0f,
- 0.5f, 0.5f, 1.0f
- };
- // 设置绕给定的轴旋转
- glTranslatef(axis[0][0], axis[0][1], axis[0][2]);
- glRotatef(angle, axis[1][0] - axis[0][0], axis[1][1] - axis[0][1], axis[1][2] - axis[0][2]);
- glTranslatef(-axis[0][0], -axis[0][1], -axis[0][2]);
2)修改不同视点,目标点不变,观看显示效果。
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, -1, -1, 1); 相当于我们的脑袋位置在(0.0,0.0,5.0)处,眼睛望向(0.0,0.0,0.0),即原点。后面的三个参数(-1, -1, 1),不变
修改:gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, -1, -1, 1);
3)修改目标点,视点不动,观看显示效果。
修改:gluLookAt(2, 2, 2, 0.0, 0.0, 0.0, -1, -1, 1);
为:gluLookAt(2, 2, 2, 0.0, 1, 0.0, -1, -1, 1); 修改目标点,视点不动
结果如下:
4)视点与目标点同时修改,观看显示效果。
修改:gluLookAt(2, 2, 2, 0.0, 0.0, 0.0, -1, -1, 1);
为:gluLookAt(1, 2, 0, 0.0, 1, 0.0, -1, -1, 1);//修改目标点和视点
结果如下:
5)视点与目标点不变,修改观察体大小,观看显示效果。
//修改正方体大小即修改顶点位置,代码如下:
- static const GLfloat vertex[][3] = {
- 0.0f, 0.0f, 0.0f,
- 1.5f, 0.0f, 0.0f,
- 0.0f, 1.5f, 0.0f,
- 1.5f, 1.5f, 0.0f,
- 0.0f, 0.0f, 1.5f,
- 1.50f, 0.0f, 1.5f,
- 0.0f, 1.5f, 1.5f,
6)将正交投影观察体改为透视投影观察体,并设置其大小,观察显示效果。
核心代码更改:
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);//投影矩阵
glLoadIdentity();
gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);//切换回模型视图矩阵
//glLoadIdentity();
//gluLookAt(2, 2, 2, 0.0, 0.0, 0.0, -1, -1, 1);
}
//正交投影
void reshape_2(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);//投影矩阵
glLoadIdentity();
//使用正交投影
if (w <= h)
glOrtho(-2.0, 2.0, -2.0 * (GLfloat)h / (GLfloat)w,
2.0 * (GLfloat)h / (GLfloat)w, -10.0, 10.0);
else
glOrtho(-2.0 * (GLfloat)w / (GLfloat)h,
2.0 * (GLfloat)w / (GLfloat)h, -2.0, 2.0, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}
两者变化如下:
7)将立方体替换为茶壶,观看显示效果。
核心代码:
-
void displaytadpot(void) { // 设置背景为白色 glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); //画笔红色 glLoadIdentity(); //加载单位矩阵 gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotatef(angle, 0.0f, 1.0f, 0.0f); glRotatef(0.0, 1.0, 0.0, 0.0); glRotatef(0.0, 0.0, 1.0, 0.0); glRotatef(0.0, 0.0, 0.0, 1.0); glutWireTeapot(1.5); //rote += roate; //glRotatef(angle, 0.0, 1.0, 0.0); //angle += 1.0f; glEnd(); glutSwapBuffers(); }
实验结果:
8)将立方体替换为圆环,观看显示效果。
核心代码:
-
//画圆环: void display() { // 设置背景为白色 glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); //画笔红色 glLoadIdentity(); //加载单位矩阵 //视角 gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotatef(angle, 0.0f, 1.0f, 0.0f); glRotatef(0.0, 1.0, 0.0, 0.0); glRotatef(0.0, 0.0, 1.0, 0.0); glRotatef(0.0, 0.0, 0.0, 1.0); glutWireTorus(0.2, 1.5, 20, 40); glEnd(); glutSwapBuffers(); }
实验结果:
⒉.构思绘制茶壶和圆环造型程序Teapot_Torus.cpp。在紧挨着茶壶下方添加一个平行的圆环,茶壶和圆环不停绕中心轴旋转,观看显示效果,效果图参见实验图9-2。
实验结果:
文章来源:https://www.toymoban.com/news/detail-400544.html
三、最终代码文章来源地址https://www.toymoban.com/news/detail-400544.html
-
#include<GL/glut.h> #include<math.h> #include<iostream> #define COLOR 8.0 #define PIX ((GLfloat)(1.0 / COLOR)) #define STEP 1.0f #define PI acos(-1) //此处使用pai的值 using namespace std; // 旋转初始的角度 GLfloat angle = 0.0f; // 设置旋转轴:两个三维的点确定的旋转轴 GLfloat axis[][3] = { 0.5f,0.5f, 0.0f, 0.5f, 0.5f, 1.0f }; void display_2() { // 设置逆时针排列的点围成的平面为正面 glFrontFace(GL_CCW); // 设置不绘制背面,节省算力同时不会出现背面覆盖正面的情况 glCullFace(GL_BACK); glEnable(GL_CULL_FACE); // 设置背景为白色 glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); // 加载单位阵 glLoadIdentity(); // 设置相机的位置和视角 // 有关gluLookAt:https://blog.csdn.net/Augusdi/article/details/20470813 //gluLookAt(2, 2, 2, 0.0, 1, 0.0, -1, -1, 1);//修改目标点 //gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, -1, -1, 1);//修改视点 //gluLookAt(1, 2, 0, 0.0, 1, 0.0, -1, -1, 1);//修改目标点和视点 gluLookAt(2, 2, 2, 0.0, 0.0, 0.0, -1, -1, 1); // 设置绕给定的轴旋转 glTranslatef(axis[0][0], axis[0][1], axis[0][2]); glRotatef(angle, axis[1][0] - axis[0][0], axis[1][1] - axis[0][1], axis[1][2] - axis[0][2]); glTranslatef(-axis[0][0], -axis[0][1], -axis[0][2]); // 设置立方体的八个顶点坐标 static const GLfloat vertex[][3] = { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; /* //修改正方体大小 static const GLfloat vertex[][3] = { 0.0f, 0.0f, 0.0f, 1.5f, 0.0f, 0.0f, 0.0f, 1.5f, 0.0f, 1.5f, 1.5f, 0.0f, 0.0f, 0.0f, 1.5f, 1.50f, 0.0f, 1.5f, 0.0f, 1.5f, 1.5f, 1.5f, 1.5f, 1.5f }; */ // 设置绘制六个面时顶点的顺序 static const GLint index[][4] = { 0, 2, 3, 1, 0, 4, 6, 2, 0, 1, 5, 4, 4, 5, 7, 6, 1, 3, 7, 5, 2, 6, 7, 3 }; // 绘制六个面 glBegin(GL_QUADS); for (unsigned int i = 0; i < 6; i++) for (unsigned int j = 0; j < 4; j++) { // 每个顶点的RGB颜色值和其顶点位置坐标一致 glColor3fv(vertex[index[i][j]]); glVertex3fv(vertex[index[i][j]]); } glEnd(); // 双缓冲下的刷新帧缓存 glutSwapBuffers(); } //画茶壶 void displaytadpot(void) { // 设置背景为白色 glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); //画笔红色 glLoadIdentity(); //加载单位矩阵 gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotatef(angle, 0.0f, 1.0f, 0.0f); glRotatef(0.0, 1.0, 0.0, 0.0); glRotatef(0.0, 0.0, 1.0, 0.0); glRotatef(0.0, 0.0, 0.0, 1.0); glutWireTeapot(1.5); //rote += roate; //glRotatef(angle, 0.0, 1.0, 0.0); //angle += 1.0f; glEnd(); glutSwapBuffers(); } //画圆环: void displayTorus() { // 设置背景为白色 glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); //画笔红色 glLoadIdentity(); //加载单位矩阵 //视角 gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotatef(angle, 0.0f, 1.0f, 0.0f); glRotatef(0.0, 1.0, 0.0, 0.0); glRotatef(0.0, 0.0, 1.0, 0.0); glRotatef(0.0, 0.0, 0.0, 1.0); glutWireTorus(0.2, 1.5, 20, 40); glEnd(); glutSwapBuffers(); } //画圆环和茶狐混合绕一个轴旋转 void displayTeapot_Torus() { // 设置背景为白色 glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); //画笔红色 glLoadIdentity(); //加载单位矩阵 //视角 gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotatef(angle, 0.0f, 1.0f, 0.0f); glRotatef(0.0, 1.0, 0.0, 0.0); glRotatef(0.0, 0.0, 1.0, 0.0); glRotatef(0.0, 0.0, 0.0, 1.0); glutWireTorus(0.2, 1.5, 20, 40); glRotatef(90, 1, 0, 0);//旋转 glTranslatef(0, 0.9, 0);//平移 glutWireTeapot(1); glEnd(); glutSwapBuffers(); } // 绘制圆环 // 大半径Radius,小半径TubeRadius,边数Sides, 环数Rings // 动画所需的定时器回调函数 // 有关定时器回调函数:https://blog.csdn.net/shimazhuge/article/details/17894883 void timer_function(GLint value) { // 旋转角度增加 angle += STEP; // 若角度大于360转完一圈则清零 if (angle > 360.0) angle -= 360.0; glutPostRedisplay(); glutTimerFunc(50, timer_function, value); } // 窗口大小自适应函数,使得窗口大小改变时仍保持图形的比例不变 // 有关窗口自适应函数:http://blog.sina.com.cn/s/blog_5497dc110102w8qh.html //透视投影 void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION);//投影矩阵 glLoadIdentity(); gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW);//切换回模型视图矩阵 //glLoadIdentity(); //gluLookAt(2, 2, 2, 0.0, 0.0, 0.0, -1, -1, 1); } //正交投影 void reshape_2(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION);//投影矩阵 glLoadIdentity(); //使用正交投影 if (w <= h) glOrtho(-2.0, 2.0, -2.0 * (GLfloat)h / (GLfloat)w, 2.0 * (GLfloat)h / (GLfloat)w, -10.0, 10.0); else glOrtho(-2.0 * (GLfloat)w / (GLfloat)h, 2.0 * (GLfloat)w / (GLfloat)h, -2.0, 2.0, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); } int main(int argc, char** argv) { glutInit(&argc, argv); // 设置双缓冲和RGB颜色模式 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); // 设置窗口大小、位置和名称 glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow("实验九"); // 设置绘制函数、窗口大小自适应函数和定时器回调函数 glutDisplayFunc(displayTeapot_Torus); glutReshapeFunc(reshape); //glEnable(GL_DEPTH_TEST); //使用了深度缓存这行不能掉 glutTimerFunc(500, timer_function, 1); // 进入主循环 glutMainLoop(); return 0; }
到了这里,关于实验九3D编程基础的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!