全景视频播放器中OpenGL的相关记录

一、OpenGL顶点数组

OpenGL顶点数组详细介绍.(可不看)

**OpenGL顶点数组的理解.
glVertex函数调用的开销会过大,而顶点数组就是将原来由一系列的glVertex*指定的顶点放在一个数组中(其意思就是顶点数据组成的数组)由顶点数组处理函数一次性指定。事实上,不仅如此,其一次性指定的不仅仅是数组,还可以是其他系列的东西,比如表面发现,RGBA 颜色,辅助颜色等。

顶点数组实际上是多个数组,顶点坐标、纹理坐标、法线向量、顶点颜色等等,顶点的每一个属性都可以指定一个数组,然后用统一的序号来进行访问。比如序号3,就表示取得颜色数组的第3个元素作为颜色、取得纹理坐标数组的第3个元素作为纹理坐标、取得法线向量数组的第3个元素作为法线向量、取得顶点坐标数组的第3个元素作为顶点坐标。把所有的数据综合起来,最终得到一个顶点。
一般代码:
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertex_list);
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_INT, index_list);

二、坐标系与投影

代码参考:glutReshapeFunc 改变窗口大小时保持图形比例.

OpenGl的glMatrixMode()函数理解.

参考:再议gluPerspective和gluLookAt的关系.注重原理讲解,讲的很不错。

首先:我们需要把显示的物体转换到观察坐标系
如果物体有自己的建模坐标系,则需要把这个转换到世界坐标系,然后再转换到观察坐标系.接下来进行投影
gluLookAt函数的作用,即封装了世界坐标系到观察坐标系的转换
 
正交投影和透视投影是两种不同的投影.类比光源
正交投影,就是有一排平行于观察平面的法线的方向的光源,它发出一组平行线,从而不管物体离观察平面的远近,大小都是一样的.

透视投影,类似于有个点光源,它会发出一组相交于一点的光线,从而相同的大小,近的物体投影的大小大,而远一些的就小一点.

投影之后,就在观察界面有了显示,这就是我们最终的成像了.观察平面从数学来说是无限大的,从我们实际使用角度,我们需要限制一个大小,这个大小也就决定了,我们哪些区域可以显示,其他投影在别的区域就忽略.
这就是很多书上说的裁剪窗口

这就引入以下函数:
gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar)

zNear,zFar是到观察原点的距离(沿着z的负轴方向),因此这两个数应该总数设定成正数.

从网上很多资料都在说,zNear和zFar做为一个深度的裁剪范围,在这个范围内的物体才能进行投影,否则就直接忽略.初学者到这个地方,也能够理解,但从我们上面的问题来看,我们不知道观察平面在哪呢? 其实opengl已经规定了,观察平面就在近平面这里,也就是zNear指定的地方, 观察平面是平行于观察坐标系的(X,Y),因此我们指定z轴,也就指定它的位置.

OK,我们的观察平面已经确定了,那观察平面的裁剪区域呢?

前面我们说过,观察平面的裁剪窗口的横纵比(w/h)最好和屏幕的一致(估计说的不准确,也就是视口的横纵比,从而只是等比例缩放而已). 因此,gluPerspective的第二个参数就是 aspect了,这样就把裁剪区域的宽度和高度的比例确定了.那剩下的是,我们目前还需要设定高度或者宽度.

gluPerspective的第一个参数是fovy,它是一个角度.其实通过fovy和zNear能够计算出裁剪窗口的高度.从而我们也就决定了裁剪窗口的大小了. fovy就是视锥体的上下平面的角度.裁剪窗口的高度 h = 2 * tan(fovy/2) * zNear.

从而我们也就明白了,上面有个网页上,把它比如成眼睛的睁开度,感觉有点牵强.
眼睛睁开度链接(有图).

三、坐标系相关函数

计算机图形学OpenGL中的glLoadIdentity、glTranslatef、glRotatef原理,用法 .(转).

  • OpenGL中的坐标用齐次坐标表示,即(x,y,z)表示成 (x’,y’,z’,h) ,其中x=x’/h; y=y’/h; z=z’/h. 通常h取1. 比如空间中的点(2,3,4),在OpenGL中将表示成(2,3,4,1). 齐次坐标表示方式适合于矩阵运算
  • OpenGL有个变换矩阵堆栈,堆栈就像子弹夹一样,先进的后出。OpenGL中的每个向量,在被定义之后进入到OpenGL世界中,都必须先乘以这个变换矩阵堆栈的栈顶变换矩阵。
  • 使用glPushMatrix和glPopMatrix的组合可以隔离这两个函数中的变换,使之不影响后面的点

变换坐标系的函数——glLoadIdentity()与glTranslatef()和glRotatef().

glLoadIdentity() 对应单位阵,将当前的用户坐标系的原点移到了屏幕中心:类似于一个复位操作

四、纹理坐标

Android OpenGL es 纹理坐标设定与贴图规则.
OpenGL 纹理坐标 和 顶点坐标映射关系 详解.

在绘制纹理映射场景时,不仅要给每个顶点定义几何坐标,而且也要定义纹理坐标。经过多种变换后,几何坐标决定顶点在屏幕上绘制的位置,而纹理坐标决定纹理图像中的哪一个纹素赋予该顶点。

  • 纹理图像是方形数组,纹理坐标通常可定义成一、二、三或四维形式,称为s,t,r和q坐标,以区别于物体坐标(x, y, z, w)和其他坐标。一维纹理常用s坐标表示,二维纹理常用(s, t)坐标表示,目前忽略r坐标。q坐标像w一样,一般情况下其值几乎均为1,主要用于建立齐次坐标。
  • 注意:对于任何纹理,无论纹理的真正大小如何,其顶端(左下角)的纹理坐标恒为(0,0),右上角的纹理坐标恒为(1,1)。也就是说,纹理坐标应是一个介于0到1之间的一个小数。

纹理坐标和顶点坐标.

  • 纹理坐标是从0到1,它的坐标是x向右,y向下
    顶点坐标是从-1到-1,坐标是x向右,y向上

程序中坐标代码可参考:android opengl播放全景视频.

五、纹理过滤

纹理环绕方式给出了纹理坐标超出设置范围外的视觉输出效果。与之函数相似,有纹理过滤
由于纹理坐标不依赖与分辨率,也就是说OpenGL如果将一张照片映射到一个很大的面上则会清晰地看到像素点,这时候过滤就显得很重要了。

之前搞不清楚纹理过滤glShadeModel,以为纹理过滤可有可无,它和glShadeModel好像意思差不多,看完下面这篇文章才更深入理解了
openGL ES 常用接口剖析.

(一)
纹理过滤是对应着把纹理图像映射成像素,
图象从纹理图象空间映射到帧缓冲图象空间(映射需要重新构造纹理图像,这样就会造成应用到多边形上的图像失真),这时就可用glTexParmeteri()函数来确定如何把纹理象素映射成像素.

下面整理了纹理映射的基本步骤在这里插入图片描述
具体纹理映射分为

  • 指定纹理
  • 控制纹理
    控制纹理是控制纹理图像的纹理如何对应到屏幕上的像素,怎样通过纹理贴图实现纹理缩放和纹理重复等
    glTexParmeteri() 就是来确定如何把纹理象素映射成像素
  • 纹理对象
  • 纹理函数
  • 分配纹理坐标
    用glTexCoord函数

(二)
glShadeModel是说明两顶点之间的象素怎么处理的。把参数设置成GL_SMOOTH,即启用栅格化功能
在opengl流水线里头,有一个步骤是栅格化(Rasterization),它在顶点组合的几何信息处理后执行,目的是“插值”,vertex shader的varying变量就是在这里被栅格化(插值),然后再传入fragment shader作象素级别的处理。

六、深度缓冲区

OpenGL 深度缓冲区 Z缓冲区介绍.
不考虑绘制的顺序对于同一个像素遮挡的影响,启用深度测试可以决定何时覆盖或不覆盖一个像素。

为了启动深度缓冲区,必须先启动它,即glEnable(GL_DEPTH_TEST)。每次绘制场景之前,需要先清除深度缓冲区,即glClear(GL_DEPTH_BUFFER_BIT),然后以任意次序绘制场景中的物体。

七、OpenGL的glut库

glut库是主要干什么的?
OpenGL中的gl,glu,glut的区别.
GLUT及其函数的用法整理.

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的, 用于对该事件或条件进行响应

OpenGL函数功能glutTimerFunc()

OpenGL函数功能glutTimerFunc().
opengl之glutTimerFunc.(有代码示例)

此函数用于刷新,具体用法如下:
glutTimerFunc(unsigned int millis, void (*func)(int value), int value);
参数对应关系为:glutTimerFunc(毫秒数, 回调函数指针, 区别值). 用value区分是哪个定时器

  • 在函数里改变和位置有关的变量,然后调用glutPostRedisplay();用来重绘
  • 最后再次调用glutTimerFunc,因为glut的定时器是调用一次才产生一次定时,所以如果要持续产生定时的话,在定时函数末尾再次调用glutTimerFunc

做鼠标拖动时可以借鉴:
OpenGL的几何变换3之内观察全景图
.

glutMainLoop()循环什么?

让所有的与“事件”有关的函数调用无限循环。
参见

按照我的理解,是有两个线程并行,main函数中是主线程,其中 glutDisplayFunc(display)实现绘制,而子线程是FFmpeg实现解码,用缓冲区防止数据错乱

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值