码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-07-13 19:25:17      阅读:532      评论:0      收藏:0      [点我收藏+]

标签:

继续上一篇文章的例子:OpenGL的几何变换2之内观察立方体

上一篇是通过绘图方式得到的立方体,没有贴图,这次加上纹理贴图。

通过纹理贴图有两种方案:

1、图片分割化,即是把一张完整的VR图片(VR图片就是720度全景图片)人工的分隔成前后左右上下六张图片(静态),然后分别加载这六张图片;

2、数据分割化,即是保留一张完整的VR图片,加载图片以后,对图片数据进行上下左右前后进行数据切割,或者应该说进行图片切割(动态)。

这一篇文章主要用到的技术点是纹理映射,具体不再累述,可以参考OpenGL的glTexCoord2f纹理坐标配置

 

本篇文章的案例主要是采用第一种(图片分割化),先附上代码:

  1 #include <stdio.h>
  2 #include <windows.h>
  3 #include <gl/glut.h>    //引用相关包
  4 #include <gl/glaux.h>
  5 
  6 GLfloat  xangle = 0.0;    //X 旋转量
  7 GLfloat  yangle = 0.0;    //Y 旋转量
  8 GLfloat  zangle = 0.0;    //Z 旋转量
  9 GLuint  textureArr[6];    //存储6个纹理
 10 
 11 AUX_RGBImageRec *loadBMP(char *Filename)    //载入位图图象
 12 {
 13 
 14 
 15     FILE *File = NULL;    //文件句柄
 16     if (!Filename)    //确保文件名已提供
 17     {
 18         return NULL;    //如果没提供,返回 NULL
 19     }
 20 
 21     File = fopen(Filename,"r");    //尝试打开文件
 22     if (File)    //文件存在么?
 23     {
 24         fclose(File);    //关闭句柄
 25         return auxDIBImageLoadA(Filename);    //载入位图并返回指针
 26     }
 27     return NULL;    //如果载入失败,返回 NULL
 28 }
 29 
 30 //载入位图(调用上面的代码)并转换成纹理
 31 int loadGLTexture(void)
 32 {
 33     int Status = FALSE;    //状态指示器
 34     char *imgArr[6] = {
 35         "pano/pano_f.bmp",    //前面
 36         "pano/pano_b.bmp",    //后面 
 37         "pano/pano_u.bmp",     //顶面
 38         "pano/pano_d.bmp",     //底面
 39         "pano/pano_r.bmp",     //右面
 40         "pano/pano_l.bmp"    //左面
 41     };
 42     AUX_RGBImageRec *TextureImage[6];    //创建纹理的存储空间
 43 
 44     memset(textureArr, 0x0, sizeof(textureArr));
 45     memset(TextureImage,0,sizeof(TextureImage));    //将指针设为NULL
 46 
 47     for (int i = 0; i < 6; i++) {
 48         Status = FALSE;
 49         //载入位图,检查有无错误,如果位图没找到则退出
 50         if (TextureImage[i] = loadBMP(imgArr[i]))
 51         {
 52             Status = TRUE;    //将 Status 设为 TRUE
 53             glGenTextures(1, &textureArr[i]);    //创建纹理
 54 
 55             //使用来自位图数据生成 的典型纹理
 56             glBindTexture(GL_TEXTURE_2D, textureArr[i]);
 57             //生成纹理
 58             glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data);
 59 
 60             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);    //线形滤波
 61             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    //线形滤波
 62         }
 63 
 64         if (TextureImage[i])    //纹理是否存在
 65         {
 66             if (TextureImage[i]->data)    //纹理图像是否存在
 67             {
 68                 free(TextureImage[i]->data);    //释放纹理图像占用的内存
 69             }
 70             free(TextureImage[i]);    //释放图像结构
 71         }
 72         if (Status == FALSE) {
 73             break;
 74         }
 75     }
 76     return Status;    //返回 Status
 77 }
 78 
 79 void drawCube(void)    //从这里开始进行所有的绘制
 80 {
 81     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    //清除屏幕和深度缓存
 82     glMatrixMode(GL_MODELVIEW);
 83     glLoadIdentity();    //重置当前的模型观察矩阵
 84 
 85     glPushMatrix();
 86     {
 87         gluLookAt(0, 0, -5, 0, 0, 0, 0, 1, 0);
 88         glTranslatef(0.0f, 0.0f, -5.0f);    //移入屏幕 5 个单位
 89         glRotatef(xangle, 1.0f, 0.0f, 0.0f);    //绕X轴旋转
 90         glRotatef(-yangle, 0.0f, 1.0f, 0.0f);    //绕Y轴旋转
 91         glRotatef(zangle, 0.0f, 0.0f, 1.0f);    //绕Z轴旋转
 92 #if (0)    //显示反面
 93         glBindTexture(GL_TEXTURE_2D, textureArr[0]);    //选择纹理
 94         glBegin(GL_QUADS); {
 95             //前面:逆时针
 96             glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);    //纹理和四边形的左下
 97             glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);    //纹理和四边形的右下
 98             glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    //纹理和四边形的右上
 99             glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    //纹理和四边形的左上
100         }glEnd();
101     
102         glBindTexture(GL_TEXTURE_2D, textureArr[1]);    //选择纹理
103         glBegin(GL_QUADS); {
104             //后面:逆时针
105             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);    //纹理和四边形的左下
106             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);    //纹理和四边形的右下
107             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);    //纹理和四边形的右上
108             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);    //纹理和四边形的左上
109         }glEnd();
110     
111         glBindTexture(GL_TEXTURE_2D, textureArr[2]);    //选择纹理
112         glBegin(GL_QUADS); {
113             //顶面:逆时针
114             glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    //纹理和四边形的左下
115             glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    //纹理和四边形的右下
116             glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);    //纹理和四边形的右上
117             glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);    //纹理和四边形的左上
118         }glEnd();
119     
120         glBindTexture(GL_TEXTURE_2D, textureArr[3]);    //选择纹理
121         glBegin(GL_QUADS); {
122             //底面:逆时针
123             glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);    //纹理和四边形的左下
124             glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);    //纹理和四边形的右下
125             glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f,  1.0f);    //纹理和四边形的右上
126             glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f,  1.0f);    //纹理和四边形的左上
127         }glEnd();
128     
129         glBindTexture(GL_TEXTURE_2D, textureArr[4]);    //选择纹理
130         glBegin(GL_QUADS); {
131             //右面:逆时针
132             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);    //纹理和四边形的左下
133             glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);    //纹理和四边形的右下
134             glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);    //纹理和四边形的右上
135             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    //纹理和四边形的左上
136         }glEnd();
137     
138         glBindTexture(GL_TEXTURE_2D, textureArr[5]);    //选择纹理
139         glBegin(GL_QUADS); {
140             //左面:逆时针
141             glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);    //纹理和四边形的左下
142             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);    //纹理和四边形的右下
143             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    //纹理和四边形的右上
144             glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);    //纹理和四边形的左上
145         }glEnd();
146 #else    //显示正面
147         glBindTexture(GL_TEXTURE_2D, textureArr[0]);    //选择纹理
148         glBegin(GL_QUADS); {
149             //前面:纹理顺时针,立方体逆时针
150             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);    //纹理和四边形的左下
151             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    //纹理和四边形的左上
152             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    //纹理和四边形的右上
153             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);    //纹理和四边形的右下
154         }glEnd();
155     
156         glBindTexture(GL_TEXTURE_2D, textureArr[1]);    //选择纹理
157         glBegin(GL_QUADS); {
158             //后面:纹理顺时针,立方体逆时针
159             glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);    //纹理和四边形的左下
160             glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);    //纹理和四边形的左上
161             glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);    //纹理和四边形的右上
162             glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);    //纹理和四边形的右下
163         }glEnd();
164     
165         glBindTexture(GL_TEXTURE_2D, textureArr[2]);    //选择纹理
166         glBegin(GL_QUADS); {
167             //顶面:纹理顺时针,立方体逆时针
168             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    //纹理和四边形的左下
169             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);    //纹理和四边形的左上
170             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);    //纹理和四边形的右上
171             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    //纹理和四边形的右下
172         }glEnd();
173     
174         glBindTexture(GL_TEXTURE_2D, textureArr[3]);    //选择纹理
175         glBegin(GL_QUADS); {
176             //底面:纹理顺时针,立方体逆时针
177             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);    //纹理和四边形的左下
178             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f,  1.0f);    //纹理和四边形的左上
179             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f,  1.0f);    //纹理和四边形的右上
180             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);    //纹理和四边形的右下
181         }glEnd();
182     
183         glBindTexture(GL_TEXTURE_2D, textureArr[5]);    //选择纹理
184         glBegin(GL_QUADS); {
185             //右面:纹理顺时针,立方体逆时针
186             glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);    //纹理和四边形的左下
187             glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);    //纹理和四边形的左上
188             glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    //纹理和四边形的右上
189             glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);    //纹理和四边形的右下
190         }glEnd();
191     
192         glBindTexture(GL_TEXTURE_2D, textureArr[4]);    //选择纹理
193         glBegin(GL_QUADS); {
194             //左面:纹理顺时针,立方体逆时针
195 
196             glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);    //纹理和四边形的左下
197             glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    //纹理和四边形的左上
198             glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);    //纹理和四边形的右上
199             glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);    //纹理和四边形的右下
200         }glEnd();
201 #endif
202     }glPopMatrix();
203     glFlush();
204 }
205 
206 //初始化
207 void init(void)
208 {
209     glClearColor (0.0, 0.0, 0.0, 0.0);    //清理颜色,为黑色,(也可认为是背景颜色)
210 
211     glCullFace(GL_FRONT);    //前面裁剪(前面不可见)
212     glEnable(GL_CULL_FACE);    //启用裁剪
213     glEnable(GL_TEXTURE_2D);
214     loadGLTexture();    //载入纹理贴图
215 }
216 
217 void display(void)
218 {
219     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    //清楚颜色数据和深度数据(清屏)
220     glLoadIdentity();    //Reset The View
221 
222     drawCube();
223 
224     glutSwapBuffers();    //交换缓冲区。显示图形
225     
226     //xangle += 0.3f;
227     //yangle += 0.3f;
228     //zangle += 0.3f;
229     Sleep(10);
230 }
231 
232 //当窗口大小改变时,会调用这个函数
233 void reshape(GLsizei w,GLsizei h)
234 {
235     //这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关
236     //只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)
237     
238     glViewport(0,0,w,h);    //设置视口
239     glMatrixMode(GL_PROJECTION);    //设置矩阵模式为投影变换矩阵,
240     glLoadIdentity();    //变为单位矩阵
241     gluPerspective(90, (GLfloat)w / h, 0.1f, 100.0f);    //设置投影矩阵
242     glMatrixMode(GL_MODELVIEW);    //设置矩阵模式为视图矩阵(模型)
243     glLoadIdentity();    //变为单位矩阵
244 }
245 
246 //键盘输入事件函数
247 void keyboard(unsigned char key,int x,int y)
248 {
249     switch(key)
250     {
251         case x:        //当按下键盘上d时,以沿X轴旋转为主
252             xangle += 1.0f;    //设置旋转增量
253             glutPostRedisplay();    //重绘函数
254             break;
255         case y:
256             yangle += 1.0f;
257             glutPostRedisplay();
258             break;
259         case z:
260             zangle += 1.0f;
261             glutPostRedisplay();
262             break;
263         default:
264             break;
265     }
266 }
267 
268 int main(int argc, char *argv[])
269 {
270     printf("可通过xyz按键控制VR全景图绕哪个轴旋转\n");
271 
272     glutInit(&argc, argv);    //固定格式
273     glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); 
274     glutInitWindowSize(1024/2, 1024/2);    //显示框的大小
275     glutInitWindowPosition(100,100);    //确定显示框左上角的位置
276     glutCreateWindow("OpenGL纹理贴图");
277 
278     init();    //初始化资源,这里一定要在创建窗口以后,不然会无效。
279     glutDisplayFunc(display);
280     //glutIdleFunc(display);
281     glutReshapeFunc(reshape);    //绘制图形时的回调
282     glutKeyboardFunc(keyboard);
283     glutMainLoop();
284     return 0;
285 }

附上VR图片:

技术分享

附上代码运行结果:

技术分享技术分享

最后附上可执行的EXE链接: http://pan.baidu.com/s/1nvixGFZ 密码: 3cw2

 

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

标签:

原文地址:http://www.cnblogs.com/1024Planet/p/5667031.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!