第一,什么是点精灵

openGL的图形由顶点构成,以后利用顶点进行纹理的映射。点精灵就是,一个顶点被当作一个精灵来处理。特别之处就是,一个顶点也可进行纹理贴出。比如,原来是个顶点构成的一个矩形,如今一个顶点就能够完毕了。瞬间我们就能够想想,粒子效果,那些云雾水流火花什么的用了点精灵,就能够瞬间降低3个顶点的计算,glDrawArrays使用GL_POINT就能够了,全然也不须要什么顶点索引了。这是很诱人的效率。

第二,点精灵的局限

一个顶点缩放都必须是矩形。而且大小的最大最小值是有范围的,每一个openGL的实现不一样须要查询获得。既然是一个纹理映射到一个顶点上,那么纹理映射就和原来全然不同,有些复杂。可能会抵消掉一些性能的优势。

第三,点精灵的使用

首先绘制的时候使用GL_POINT类型,那么在顶点着色器中就会有一个内置的仅仅读变量能够使用,叫做gl_PointSize。这个值控制了点精灵顶点的大小,是像素数值。这个数值的范围使用例如以下查询:

glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, glInfo.pointSizeRange);

logD("GL_ALIASED_POINT_SIZE_RANGE[%f, %f]", glInfo.pointSizeRange[0], glInfo.pointSizeRange[1]);

经过測试我发现不同的机器这个数值却别非常大,有的机器有500多像素,有的仅仅有1个像素,这确实是个问题。

接下来就是怎样在这个顶点上映射纹理了。在片段着色器中仍然有一个内置的仅仅读变量叫做gl_PointCoord。这个值是已经插值计算后的纹理坐标。就是纹理上每一个像素点的xy坐标。所以这个变量是一个vec2类型的。

特别须要说明的是,纹理映射的坐标是bottom left为00点,这里是top left为00点。那么片段着色器看起来就是这种。

gl_FragColor = texture2D(uSampler2D,gl_PointCoord);

这里曾经texture2D採样的是,我们计算出来的UV值,如今这个值是默认提供的,从左上角開始的坐标。片段着色器在每一个像素上运行,就会把一个默认的纹理绘制到顶点上。

第四,怎样旋转,缩放,移动纹理

这里能明显感到一个问题,就是曾经纹理映射到顶点上,对顶点进行矩阵运算就能够一起变化映射好的纹理了。但是如今压根就仅仅有一个顶点,一个默认的纹理坐标怎样完毕操作呢。

有一点须要有一个清晰的概念。曾经顶点和纹理是映射的,我们对顶点的矩阵操作就是对纹理的变换。如今须要区分开,矩阵对顶点的变换依旧有效,但是对纹理没有不论什么作用。所以,我们须要单独对纹理进行操作,也就是对纹理坐标的变换。

方法有2种:

1,我们直接对gl_PointCoord直接操作。 这个值是一个区间在[0,1]之间的数值,代表了纹理坐标,从左上点開始。我们能够尝试的这样:

gl_FragColor = texture2D(uSampler2D, gl_PointCoord + vec2(0.5));
gl_FragColor = texture2D(uSampler2D, gl_PointCoord - vec2(0.5));

尝试一下就会发现终于点精灵上的纹理发生了偏移。但我们要把偏移,旋转,用这个坐标计算是很麻烦的也不是不可能。可是复杂的算法放到片段着色器上,每一个像素点上都执行是不明智的。

2,既然矩阵能够把各种变化一次性施加到顶点上,那么我们相同能够用矩阵来变换gl_PointCoord的坐标。这样我们能够把纹理上的像素坐标看作是顶点,顺其自然的用矩阵来变换这些顶点。仅仅只是这些纹理顶点仅仅有xy2个坐标,而通常我们计算顶点的矩阵是xyzw坐标。

再一次强调,纹理gl_PointCoord坐标是从top left 为00点開始。可是我们的矩阵是用00点做中心点的。这就出现一个情况,纹理矩形的几何中心点没有和矩阵的中心点重合。为了正确旋转,我们须要把纹理矩形的中心点移动到矩阵的中心点。类似例如以下操作

varying mat4 vTextureMat;
void main()
{
gl_FragColor = texture2D(uSampler2D,
(vTextureMat * vec4(gl_PointCoord - vec2(0.5), 0.0, 1.0)).xy + vec2(0.5));
}

这是一个片段着色器脚本。我们能够当看到,vec4构造器把纹理坐标转换到mat4能够操作的大小。gl_PointCoord – vec2(0.5)就是把纹理矩形移动到矩阵的中心点。在做矩阵操作,以后在移动回去 + vec2(0.5), 偏移0.5是为了正确使用矩阵运算。纹理坐标必须在[0,1]之间才有像素值,否则是没有像素数据的。

如此这样,我们看到了仅仅要我们正确给出mat4 vTextureMat就能得到我们想要的一切。这个矩阵从哪里来,直接uniform传过来,或是顶点着色器varying过来都是能够的。

就像变换顶点一样,我们能够在client计算正确的mat4以后当纹理坐标移动,旋转,缩放。记住,这个mat4应该是和顶点变换的mvpMatrix是2个不同的矩阵。一个是为了变换顶点,一个是为了变换纹理坐标。顶点矩阵是model view projection的合体。 纹理坐标能够没有那么麻烦一个model就能够了。能够在顶点着色器计算这个矩阵,也能够在client算好传过来。

第五,怎样在一个大图上进行UV操作,让顶点纹理是大纹理的一个部分,这样就能够BatchDraw操作了。

在顶点图形UV映射的时候,我们经常会把UV映射到大纹理上面的区域,这样我们就能搞在一个绘制中,绘制多个不同的图形了。点精灵这里仅仅有一个顶点进行UV操作貌似没有门路。这就是问题的所在。

经过我的研究经过測试,进行UV是能够的,依旧是利用矩阵来进行变换。前提是,要首先理解gl_PointCoord真正的意义所在。texture2D对顶点纹理採样的时候,是00点到11点区域进行像素处理。gl_PointCoord的范围也是[0,1]之间。那假设採样的时候,我对gl_PointCoord * vec2(0.5)进行计算会怎样呢。这样就把纹理坐标映射到了[0, 0.5]之间。原来每一个gl_PointCoord坐标都乘以了0.5 结果就是纹理被放大了。同理,gl_PointCoord * vec2(2.0)就会缩小纹理。

进行UV基本思路就是,把大纹理上的须要的小纹理的区域中心点,通过矩阵移动到点精灵的中心点,以后在放大区域的倍数。就会得到设置gl_PointSize大小的区域纹理,当然我们会把gl_PointSize设置的和区域纹理一样大小。这样UV的操作事实上变成了矩阵的变换计算,移动,缩放就能够完毕UV了。

这样做的话,UV操作用掉了矩阵缩放,点精灵的自己的缩放就要通过gl_PointSize来设置大小。另一个问题,就是在一次性进行多个点精灵绘制的时候。针对每一个点精灵都会有自己的UV坐标点,那么纹理旋转矩阵开怎样是好呢,难道每一个点精灵上传一个mat4矩阵么,这种数据量太大尽管可行。我们事实上另一个选择在顶点着色器进行自己运算。

由于每一个点精灵仅仅有一个顶点,顶点着色器脚本智慧执行一次,所以在这里进行矩阵运算不会反复执行。那么旋转,缩放,平移,可能都须要去写着色器函数去实现。事实上就是把cpu的计算移到显卡,我认为速度应该更快。

最后, 点精灵有自己的局限也有效率上的优势,在研究过程中我发现点精灵能够完毕square图形全部的操作。仅仅是着色器会写的复杂一些。当中的取舍,使用的必要性,须要详细的情况去考量。

openGL点精灵PointSprite具体解释: 纹理映射,旋转,缩放,移动的更多相关文章

  1. 【OpenGL(SharpGL)】支持任意相机可平移缩放的轨迹球实现

    [OpenGL(SharpGL)]支持任意相机可平移缩放的轨迹球 (本文PDF版在这里.) 在3D程序中,轨迹球(ArcBall)可以让你只用鼠标来控制模型(旋转),便于观察.在这里(http://w ...

  2. osg矩阵变换节点-----平移旋转缩放

    osg矩阵变换节点-----平移旋转缩放 转自:http://www.cnblogs.com/ylwn817/articles/1973396.html 平移旋转缩放这个三个是osg矩阵操作中,最常见 ...

  3. osg中使用MatrixTransform来实现模型的平移/旋转/缩放

    osg中使用MatrixTransform来实现模型的平移/旋转/缩放 转自:http://www.cnblogs.com/kekec/archive/2011/08/15/2139893.html# ...

  4. Blender模型导入进Unity,旋转缩放的调整

    Blender跟Unity的XYZ轴不同的原因,导致Blender模型导入Unity之后会发生模型朝向不对. 请先看看下边这个情况: 首先,Blender物体模式下,对模型进行 旋转 缩放,将会在右边 ...

  5. NeHe OpenGL教程 第六课:纹理映射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. OpenGL 4.0 GLSL 实现 投影纹理映射(Projective Texture Mapping) (转)

    http://blog.csdn.net/zhuyingqingfen/article/details/19331721   分类: GLSL  投影纹理映射 (projective texture ...

  7. OpenGL绘制简单场景,实现旋转缩放平移和灯光效果

    本项目实现了用OpenGL绘制一个简单场景,包括正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码.有具体凝视.适合刚開始学习的人熟悉opengl使用. 开发情况 开发环境V ...

  8. 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解

    最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...

  9. OpenGL ES: iOS 自定义 UIView 响应屏幕旋转

    iOS下使用OpenGL 如果使用GLKit View 那么不用担心屏幕旋转的问题,说明如下: If you change the size, scale factor, or drawable pr ...

随机推荐

  1. Delphi 模拟网站验证码(酷,把随机文字写道图片上)

    function TfrmLabelPages.PwdImg(img: Timage): string; var I,j,k: Integer; vPoint: TPoint; vLeft: Inte ...

  2. Photon的使用

    这几个月给公司一个正在做的半吊子游戏加pvp功能,一个人居然要2个多月弄个 PVP  类似 Dota 对战的游戏.我手里有套现成搭建服务端架构都没敢用起来,这服务器还是太初步了,只是验证了 Boost ...

  3. Delphi的指针 good

    Pointers are like jumps, leading wildly from one part of the data structure to another. Their introd ...

  4. [Python 学习]2.5版yield之学习心得 - limodou的学习记录 - limodou是一个程序员,他关心的焦点是Python, DocBook, Open Source …

    [Python 学习]2.5版yield之学习心得 - limodou的学习记录 - limodou是一个程序员,他关心的焦点是Python, DocBook, Open Source - [Pyth ...

  5. JAVA编程心得-JAVA实现CRC-CCITT(XMODEM)算法

    CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定. 1 byte checksum CRC ...

  6. 降低http请求次数

    80%的终于用户响应时间花在前端程序上.而其大部分时间则花在各种页面元素,如图像.样式表.脚本和Flash等的下载上. 降低页面元素将会降低HTTP请求次数.这是高速显示页面的关键所在. 1.Imag ...

  7. TWinControl的消息覆盖函数大全(41个WM_函数和31个CM_函数,它的WndProc就处理鼠标(转发)、键盘(取消拖动)、焦点、和WM_NCHITTEST一共4类消息)

    注意,这些函数只有Private一种形式(也就是不允许覆盖,但仍在动态表格中): 其中TWinControl对TControl有10个消息进行了覆盖(红色标记),其中有2个是WM_消息,8个是CM_消 ...

  8. [Cocos2d-x]节点的生命周期

    清楚的知道一个对象的生命周期,在开发时候是非常必要的,对于自身定义并且创建的对象而言,它的生命周期是由程序员控制,但是对于coco2d-x中的节点,我们必须弄清它的生命周期,这样才能在开发中得心应手. ...

  9. Opencv246+vs2012生成不依赖编译环境的exe文件

    我们都知道,vs2012编译项目有两个版本号:Debug和Release,这里我们在Release下生成exe文件,为什么要在Release以下生成呢,原因是你在Debug模式下生成的exe须要vs2 ...

  10. block存储区域——怎样验证block在栈上,还是堆上

    Block存储区域 首先,须要引入三个名词: ● _NSConcretStackBlock ● _NSConcretGlobalBlock ● _NSConcretMallocBlock 正如它们名字 ...