OpenGL的几何变换2

我想实现的一个场景是:一个立方体,相机的坐标在立方体的中心点,相机不变,立方体旋转,可以站在立方体中心点查看立方体内部。

关于相机坐标和事物坐标,貌似都指向了下面几个函数:

1、观察变换函数gluLookAt(),寻找观察点;

2、旋转变换glRotatef(),全方位旋转立方体;

3、平移变换函数gluTranslatef(),创建立方体使用;

4、最后还少不了投影变换函数gluPerspective()

这是单纯的画立方体,而不是加载本地图片贴图,贴图是我最终目的,后期再跟上,先附上这次的代码:

  1 #include <stdio.h>
  2 #include <math.h>
  3 #include <Windows.h>
  4 #include "include\glut.h"
  5
  6 /*
  7  功能描述:使用OpenGL简单画立方体,在内部透视查看立方体内部
  8  */
  9
 10 //输出模式,0-单缓存模式;非0双缓存模式
 11 #define OUTPUT_MODE 1
 12
 13 //矩阵变换的坐标
 14 float oldx = 0;
 15 float oldy = 0;
 16
 17 //交叉点的坐标
 18 int cx = 0;
 19 int cy = 0;
 20
 21 int angle = 0;
 22
 23 void init(void)
 24 {
 25     const GLfloat LightAmbient[4] = {0.1, 0.1, 0.1, 1.0};
 26     const GLfloat LightDiffuse[4] = {0, 0.8, 0.8, 1.0};
 27     const GLfloat LightPosition[4]={0,0,1,0};
 28
 29     //glClearColor函数设置好清除颜色,glClear利用glClearColor函数设置好的当前清除颜色设置窗口颜色
 30     glClearColor(1.0, 1.0, 0.8, 1.0);
 31
 32     glShadeModel(GL_SMOOTH);//选择单位或平滑阴影
 33     glEnable(GL_DEPTH_TEST);
 34 }
 35
 36 #if (0)
 37 void display(void)
 38 {
 39     //printf("oldx=%f, oldy=%f\n", oldx, oldy);
 40     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 41
 42     static float rotate = 0;
 43     static int times = 0;
 44
 45     static float centerX = 0.0;
 46     static float centerY = 0.0;
 47     static float centerZ = 0.0;
 48     static bool add = TRUE;
 49
 50     glMatrixMode(GL_MODELVIEW);
 51     glLoadIdentity();
 52     glPushMatrix();
 53     {
 54         gluLookAt(0, 0, -10.0f, centerX, centerY, centerZ, 0, 1, 0);
 55         glTranslatef(0, 0, -10.0);    //平移
 56         glScalef(1, 1, 1);        //缩放
 57
 58         glRotatef(angle, 1, 1, 1);
 59
 60         //将立方体的八个顶点保存到一个数组里面
 61         static const float vertex_list[][3] =
 62         {
 63             //0        1        2
 64             -1.0f, -1.0f, -1.0f,//0
 65             1.0f, -1.0f, -1.0f,    //1
 66             -1.0f, 1.0f, -1.0f,    //2
 67             1.0f, 1.0f, -1.0f,    //3
 68             -1.0f, -1.0f, 1.0f,    //4
 69             1.0f, -1.0f, 1.0f,    //5
 70             -1.0f, 1.0f, 1.0f,    //6
 71             1.0f, 1.0f, 1.0f    //7
 72         };
 73
 74         //将要使用的顶点的序号保存到一个数组里面
 75         static const GLint index_list[][2] =
 76         {
 77             {0, 1},
 78             {2, 3},
 79             {4, 5},
 80             {6, 7},
 81             {0, 2},
 82             {1, 3},
 83             {4, 6},
 84             {5, 7},
 85             {0, 4},
 86             {1, 5},
 87             {7, 3},
 88             {2, 6}
 89         };
 90         float rgb[] = {0.1, 0.3, 1.0};
 91         int i,j;
 92         glBegin(GL_LINES);
 93         {
 94             for(i=0; i<12; ++i)    //12条线段
 95             {
 96                 for(j=0; j<2; ++j)    //每条线段2个顶点
 97                 {
 98                     printf("index : %d, [%d][%d], vertex : %.1f, %.1f, %.1f\n", index_list[i][j], i, j, vertex_list[index_list[i][j]][0], vertex_list[index_list[i][j]][1], vertex_list[index_list[i][j]][2]);
 99                     glColor3f (rgb[0], rgb[1], rgb[2]); //画笔颜色
100                     glVertex3fv(vertex_list[index_list[i][j]]);
101
102                     rgb[0] += 0.2;
103                     rgb[1] += 0.1;
104                     rgb[2] -= 0.1;
105                 }
106             }
107         }
108         glEnd();
109     }
110     glPopMatrix();
111
112     printf("centerX=%f, centerY=%f\n", centerX, centerY);
113     if (add)
114     {
115         centerX += 0.1;
116         centerY += 0.1;
117         centerZ += 0.1;
118     } else {
119         centerX -= 0.1;
120         centerY -= 0.1;
121         centerZ -= 0.1;
122     }
123     if (centerX > 10)
124     {
125         add = FALSE;
126     } else if (centerX < -10) {
127         add = TRUE;
128     }
129     angle += 1;
130     angle %= 360;
131
132     if (OUTPUT_MODE == 0) {
133         glFlush();//单缓存GLUT_SINGLE时使用
134     } else {
135         glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示
136     }
137 }
138
139 #else
140 void display(void)
141 {
142     //printf("oldx=%f, oldy=%f\n", oldx, oldy);
143     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
144
145     float rotatefs[][4] = {
146         {90.0, 1.0, 0.0, 0.0},    //top
147         {-90.0, 1.0, 0.0, 0.0},    //bottom
148         {90.0, 0.0, 0.0, 1.0},    //front
149         {-90.0, 0.0, 1.0, 0.0},    //left
150         {-90.0, 0.0, 0.0, 1.0},    //back
151         {90.0, 0.0, 1.0, 0.0},    //right
152     };
153
154     float translefs[][3] = {
155         {0.0, 0.5, 0.0}, //top
156         {0.0, -0.5, 0.0},//bottom
157         {0.0, 0.0, -0.5},//front
158         {-0.5, 0.0, 0.0},//left
159         {0.0, 0.0, 0.5}, //back
160         {0.5, 0.0, 0.0}     //right
161     };
162
163     glPushMatrix();    {
164         glColor3f (0, 0, 0);
165         glLoadIdentity();  //加载单位矩阵
166         glTranslatef(0.0f,0.0f,-10.0f);
167         glRectf(-1.0f, -1.0f, -0.5f, -0.5f);
168     }
169     glPopMatrix();
170
171     glMatrixMode(GL_MODELVIEW);
172     glLoadIdentity();  //加载单位矩阵
173     glPushMatrix();    {
174     glLoadIdentity();  //加载单位矩阵
175     static float centerX = 0.0;
176     static float centerY = 0.0;
177     static float centerZ = 0.0;
178     static bool add = TRUE;
179         gluLookAt(0, 0, -10.0f, centerX, centerY, centerZ, 0, 1, 0);
180         glTranslatef(0.0f,0.0f,-10.0f);
181         glRotatef(angle, 0, 1, 0);
182         glScalef(0.5, 0.5, 0.5);
183         float rgb[] = {0.1, 0.3, 1.0};
184         for(int i = 0; i < 6; i++) {
185             glPushMatrix();    {
186                 glTranslatef(translefs[i][0], translefs[i][1], translefs[i][2]);
187                 glRotatef(rotatefs[i][0], rotatefs[i][1], rotatefs[i][2], rotatefs[i][3]);
188                 //glScalef(-0.5, -0.5, -0.5);
189                 glColor3f (rgb[0], rgb[1], rgb[2]); //画笔颜色
190                 glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
191
192                 rgb[0] += 0.2;
193                 rgb[1] += 0.1;
194                 rgb[2] -= 0.1;
195             }
196             glPopMatrix();
197         }
198     }
199     glPopMatrix();
200
201     printf("centerX=%f, centerY=%f\n", centerX, centerY);
202     if (add)
203     {
204         centerX += 0.1;
205         centerY += 0.1;
206         centerZ += 0.1;
207     } else {
208         centerX -= 0.1;
209         centerY -= 0.1;
210         centerZ -= 0.1;
211     }
212     if (centerX > 10)
213     {
214         add = FALSE;
215     } else if (centerX < -10) {
216         add = TRUE;
217     }
218     //如果通过鼠标控制,可以把下面两行代码注视掉,留着也没关系
219     angle += 1;
220     angle %= 360;
221
222     if (OUTPUT_MODE == 0) {
223         glFlush();//单缓存GLUT_SINGLE时使用
224     } else {
225         glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示
226     }
227 }
228
229 #endif
230
231 //处理鼠标点击
232 void Mouse(int button, int state, int x, int y)
233 {
234     if(state == GLUT_DOWN) //第一次鼠标按下时,记录鼠标在窗口中的初始坐标
235     {
236         //记住鼠标点击后光标坐标
237         cx = x;
238         cy = y;
239         //printf("Mouse: x=%d, y=%d, oldx=%f, oldy=%f\n", x, y, oldx, oldy);
240     }
241 }
242
243 //处理鼠标拖动
244 void onMouseMove(int x, int y)
245 {
246     int offset = 5;
247     if (cx <= 200 && y < cy) {//左半边区:顺时针手势
248         angle -= offset;
249         printf("angle1=%d\n", angle);
250     } else if (cx > 200 && y > cy) {//右半边区:顺时针手势
251         angle -= offset;
252         printf("angle2=%d\n", angle);
253     } else if (cx <= 200 && y > cy) {//左半边区:逆时针手势
254         angle += offset;
255         printf("angle3=%d\n", angle);
256     } else if (cx > 200 && y < cy) {//右半边区:逆时针手势
257         angle += offset;
258         printf("angle4=%d\n", angle);
259     }
260     angle %= 360;
261
262     //计算拖动后的偏移量,然后进行xy叠加减
263     oldx += ((x - cx) * 0.01);
264     oldy -= ((y - cy) * 0.01);
265     //printf("Move: x=%d(%d)[%d], y=%d(%d)[%d], oldx=%f, oldy=%f\n", x, cx, x-cx, y, cy, y-cy, oldx, oldy);
266     glutPostRedisplay();
267
268     //保存好当前拖放后光标坐标点
269     cx = x;
270     cy = y;
271 }
272
273 void reshape(int w, int h)
274 {
275     int offset = 10;
276     int dis = (w > h ? h : w) - offset * 2;
277
278     //配置显示物体屏幕的大小
279     glViewport(offset, offset, (GLsizei)dis, (GLsizei)dis);
280     printf("reshape: w=%d, h=%d, dis=%d\n", w, h, dis);
281
282     glMatrixMode(GL_PROJECTION);
283     glLoadIdentity();
284
285     //glOrtho(-1.5, 1.5, -1.5, 1.5, 0, 100);
286     //gluOrtho2D(-1.5, 1.5, -1.5, 1.5);
287     gluPerspective(90.0f, (GLfloat)w/(GLfloat)h, 0.1f, 100.0f);
288
289     glMatrixMode(GL_MODELVIEW);
290     glLoadIdentity();
291 }
292
293 int main(int argc, char *argv[])
294 {
295     glutInit(&argc, argv);
296
297     glutInitDisplayMode(GLUT_RGB | (OUTPUT_MODE == 0 ? GLUT_SINGLE : GLUT_DOUBLE));
298     glutInitWindowPosition(100, 100);
299     glutInitWindowSize(400, 400);
300     glutCreateWindow("第一个 OpenGL 程序");
301
302     init();
303     glutDisplayFunc(&display);
304     glutIdleFunc(display);  //设置不断调用显示函数
305     glutReshapeFunc(reshape);
306     glutMouseFunc(Mouse);
307     glutMotionFunc(onMouseMove);
308     glutMainLoop();
309     return 0;
310 }

没有录制,附上几张图

时间: 2024-12-27 17:06:53

OpenGL的几何变换2的相关文章

OpenGL的几何变换3之内观察VR全景图

继续上一篇文章的例子:OpenGL的几何变换2之内观察立方体 上一篇是通过绘图方式得到的立方体,没有贴图,这次加上纹理贴图. 通过纹理贴图有两种方案: 1.图片分割化,即是把一张完整的VR图片(VR图片就是720度全景图片)人工的分隔成前后左右上下六张图片(静态),然后分别加载这六张图片: 2.数据分割化,即是保留一张完整的VR图片,加载图片以后,对图片数据进行上下左右前后进行数据切割,或者应该说进行图片切割(动态). 这一篇文章主要用到的技术点是纹理映射,具体不再累述,可以参考OpenGL的g

OpenGL的几何变换[转]

OpenGL的几何变换 1.实验目的: 理解掌握一个OpenGL程序平移.旋转.缩放变换的方法. 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移.旋转.缩放变换的方法: (2)根据示范代码,尝试完成实验作业: 3.实验原理: (1)OpenGL下的几何变换 在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义. 平移矩阵构造函数为glTranslate<f,d>(tx, ty, tz),作用是把当前矩阵和一个表示移动物体的矩阵相

OpenGL一些函数详解(二)

OpenGL ES顶点数据绘制技巧 在OpenGL中,绘制一个长方体,需要将每个顶点的坐标放在一个数组中.保存坐标时有一些技巧(由于字母下标不好表示,因此将下标表示为单引号,如A1将在后文中表示为A' ): (1)将对立面坐标保存在相邻的位置,如坐标的保存顺序为:前面(A'ABB'),后面(D'DCC'),上面(D'A'B'C'),下面(DABC),左面(D'A'AD),右面(C'B'BC).因为对立面的坐标除了其垂直的那根轴的坐标相反以外,其他坐标值一样:如前面和后面(垂直于z轴),x和y的坐

清华版CG 实验3 OpenGL几何变换

1.实验目的: 理解掌握OpenGL二维平移.旋转.缩放变换的方法. 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移.旋转.缩放变换的方法: (2)根据示范代码,尝试完成实验作业: 3.实验原理: (1)OpenGL下的几何变换 在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义. 平移矩阵构造函数为glTranslate<f,d>(tx, ty, tz),作用是把当前矩阵和一个表示移动物体的矩阵相乘.tx, ty,tz指定这

实验3 OpenGL几何变换

转自:http://www.cnblogs.com/opengl/archive/2012/10/30/2747130.html 1.实验目的: 理解掌握一个OpenGL程序平移.旋转.缩放变换的方法. 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移.旋转.缩放变换的方法: (2)根据示范代码,尝试完成实验作业: 3.实验原理: (1)OpenGL下的几何变换 在OpenGL的核心库中,每一种几何变换都有一个独立的函数,所有变换都在三维空间中定义. 平移矩阵构造函

[转载]详解OpenGL的坐标系、投影和几何变换

详解OpenGL的坐标系.投影和几何变换 转载http://blog.csdn.net/blues1021/article/details/51535398# OPengl的渲染流程是先全部设置好数据和状态,GL_MODELVIEW是将当前要变换的空间向量和模型视图矩阵当前最顶矩阵(会乘以摄像机变换乘投影矩阵的矩阵得最终变换矩阵)关联存储好包括状态设置,提交渲染时候glflush才会提交渲染数据和命令. glPushMatrix()和glPopMatrix()的配对使用目的是方便得到需要变换的最

OpenGL几何变换---翻译http://www.songho.ca/opengl/gl_projectionmatrix.html

Overview 几何数据——顶点位置,和法向量(normal vectors),在OpenGL 管道raterization 处理过程之前可通过顶点运算(Vertex Operation)和基本组合运算改变这些数据. Object Coordinates 对象的本地坐标系——任何变换之前的最初位置.为了变换(transformation)这些对象,可以调用glRotate(),glTranslatef(),glScalef()这些方法. Eye Coordinates 使用GL_MODELVI

OpenGL学习08_几何变换

OpenGL需要通过视图变换,模型变换,投影变换,视口变换,绘制场景这一系列步骤将图像绘制出来. 1.模型变换和视图变换 从"相对移动"的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性.在OpenGL中,实现这两种功能甚至使用的是同样的函数.由于模型和视图的变换都通过矩阵运算来实现,在进行变换前,应先设置当前操作的矩阵为"模型视图矩阵".设置的方法是以GL_MODELVIEW为参数调用glMatrixMode函数. glMatrixMode(G

OpenGL学习(四) 几何变换

线性变换 仿射变换:包括平移.旋转以及比例变换.这种变换能够保持直线建的平行性,并且可逆. 射影变换:包括透视变换等.由于这些变换都是将三维实体投影到二维空间,所以不可逆. 齐次坐标系     OpenGL实际是在四维坐标中定义的,坐标为(x,y,z,w)在三维点空间上显示为(x/w,y/w,z/w),不定义w的话,w默认为1. 故我们用于建模.观察以及投影的所有变换都可由4*4的矩阵直接作用于齐次坐标系中的点和向量得到. 模型-视图变换和投影变换     每个顶点都经过当前模型-视图矩阵和投影