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

继续上一篇文章的例子: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

时间: 2024-08-29 17:04:44

OpenGL的几何变换3之内观察VR全景图的相关文章

OpenGL的几何变换[转]

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

怎么样制作vr全景图

酷雷曼全景小编教你怎么样制作vr全景图?点"确定"至此,JPEG选项中.合成后的大图已经保存在文件夹中. 单反相机都可以拍摄, 一般的卡片相机.当然,如果你具有拍摄全景照片的相机那就更加方便了可以选择自己喜欢的景观,比如乡村当中的大型广场.旅游途中视野开阔的景点. 用自己在厦门拍摄的一组照片为例:拍摄时人站在景点的中心,为了便于介绍.双手平握相机,平行缓慢地转动相机,依次拍摄数张照片,为了便于接片,前后的照片之间必需留有一定的衔接局部,为了介绍的简单,只用了下面的三张照片,也可选用许多

OpenGL的几何变换2

我想实现的一个场景是:一个立方体,相机的坐标在立方体的中心点,相机不变,立方体旋转,可以站在立方体中心点查看立方体内部. 关于相机坐标和事物坐标,貌似都指向了下面几个函数: 1.观察变换函数gluLookAt(),寻找观察点: 2.旋转变换glRotatef(),全方位旋转立方体: 3.平移变换函数gluTranslatef(),创建立方体使用: 4.最后还少不了投影变换函数gluPerspective(). 这是单纯的画立方体,而不是加载本地图片贴图,贴图是我最终目的,后期再跟上,先附上这次的

Unity2017中VR全景图和全景视频设置

用SteamVR插件做好VR的摄像头后,创造一个sphere,设置合适的大小,放置在跟摄像头一样的位置,视频是在球的内壁上播放的,从球的内部看球的内壁. 拖一张全景图片到球上,sharder用此链接内的http://blog.csdn.net/wuyt2008/article/details/54313474(谢大神提供). 加VideoPlayer组件,在其下VedeoClip中加入想要播放的视频,RenderMode设为MaterialOverride. 使用Play(),Stop()等方法

一起学Google Daydream VR开发,快速入门开发基础教程一:Android端开发环境配置一

原文因涉及翻墙信息,被强制删除,此文为补发! 准备工作 进入Google Daydream开发者官网,开启准备工作,官网地址:https://vr.google.com/daydream/developers/ -------------------------------------------------------------------------------------------------------------------- Google Daydream开发者网址: https

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的坐

Google VR全景图片与视频功能开发详解

1. VR开发概述 时下关于"谷歌.Android与VR"的各种言论纷飞.VR群里有人在争论Android VR是不是一体机,是不是类似Android Wear.为VR打造的全新平台,是不是改良后的Android N. 随着vr设备的流行开来,各大招聘平台上也发布了不少关于andorid vr开发相关的Android工程师岗位,从这点来说掌握vr在项目中的实际应用要点,有助于大家为自己的开发经验上增加前沿技术的积累. 经过研发市面上的主流vr app 的功能,抽取并整合项目中的vr开发

【Android开发VR实战】三.开发一个寻宝类VR游戏TreasureHunt

转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53939303 本文出自[DylanAndroid的博客] [Android开发VR实战]三.开发一个寻宝类VR游戏TreasureHunt VR即Virtual Reality虚拟现实.虚拟现实技术是一种可以创建和体验虚拟世界的计算机仿真系统它利用计算机生成一种模拟环境是一种多源信息融合的交互式的三维动态视景和实体行为的系统仿真使用户沉浸到该环境中. 那么,如何在Androi

优秀游戏程序员学习资料推荐

这两天给单位的技术做的一次学习材料推荐培训,直接ppt上拷过来的. 优秀游戏程序员学习资料推荐 主讲人:臧旭 前言 今天提到的纯粹是我个人心得和理解,可能片面,可能以偏概全. 目的是给大家做一定的指引作用,想让大家知道自己还有哪些可以去学习,还有哪些不足,我们距离优秀还有多远. 对我今天提到的东西,如果大家有时间,一定要去深入了解,在技术的道路上才有可能看得远.走得稳.飞得高. 另外有一句对所有技术人员想说的话: 学无止境.切忌坐井观天.有一点小小的成就就沾沾自喜.止足不前. 扎实的基础 万丈高