OpenGL的几何变换2之内观察立方体

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

实际上就是立方体图像,这是在全景图片当作比较简单的方式,画面不会变形和扭曲,但是现在拍摄的全景图不会这样拍摄,更多的可点击先搞清楚全景视频是如何实现的查看

其实就是当下炒得火热的VR视频,而现在呢简单一些,查看全景图片,VR和全景是有区别的,可以去了解下一张图看懂360°全景和VR的区别

 

我们接下来全景图片,关于相机坐标和事物坐标,貌似都指向了下面几个函数:

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 }

没有录制,附上几张图

 

 

 

最后附上代码执行文件链接: https://pan.baidu.com/s/1hsS3vEk 密码: tmdg

posted @ 2016-07-11 18:12  追寻1024的程序猿  阅读(2026)  评论(0编辑  收藏  举报