OpenGL ES: Array Texture初体验
Array Texture这个东西的意思是,一个纹理对象,可以存储不止一张图片信息,就是说是是一个数组,每个元素都是一张图片。这样免了频繁地去切换当前需要bind的纹理,而且可以节省系统资源。本文主要讨论的是2D array textures. 1D的使用很少 不讨论。
那么,在shader里面应该怎么去访问我想要的纹理呢?普通的纹理坐标是 (x,y) 这里就不够了,这里需要 (x,y,z) 三个值,XY代表2d纹理坐标,Z值代表选择读取哪一张纹理的数据,从0开始。
初始化Array Texture
普通 2D texture对象
初始化一个普通的2D纹理对象的方式是这样的:
genTexture-->BindTexture-->指定图片信息(使用 glTexImage2D 函数)
2D texture array对象
前两步一样的,指定图片信息的时候不一样。这里需要两歩操作,开辟存储空间和上传数据。
第一步,开辟空间:
爲纹理开辟内存,确定存储的结构
glTexImage3D (这个和glTexImage2D长得很像的函数)
target :GL_TEXTURE_2D_ARRAY
depth: 用于指定我们的数组的长度(若是3D texture就是纹理的深度信息了,我们用的是2D texture array)。
mipmap的level,一般我们给0,也就是說每次只能确定一个mipmap的level.
需要注意的是,我们生成普通纹理的时候数据是在这个地方指定的,同样,这个函数的最后一个参数也代表源像素数据,但是这里可以指定也可以写NULL,后面再上传数据。我推荐这样做。
以上是旧的做法,目前官方更推荐使用 glTexStorage3D 函数,功能类似。
glTexStorage3D — simultaneously specify storage for all levels of a three-dimensional or two-dimensional array texture
void glTexStorage3D( GLenum target,
GLsizei levels,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLsizei depth);
参数和上面的相同,需要注意:levels 最小设置爲1;
这个函数比上面的好在什么地方呢?根据大牛的解释,glTexImage3D生成的纹理对象是不完整的,比如缺少mipmap的信息,缺少环绕方式等等,而且是可变的,这一秒创建好下一秒被改的乱七八糟了。而这个函数生成一个完整的不可变的对象,更可靠更安全。而且不用再显式地去调用glGenerateMipmap 。它已经自动帮你做好了处理。
第二步,指定数据
glTexSubImage3D
这个函数用于上传真正的纹理数据,参数较多,可以参考官方的文档。提供指定xyz的offset,即偏移量。一般xy的设置0,z方向的便宜就代表了是第几张纹理,所以这个需要按需要设置。后面的设置宽高很简单,然后是depth,这一次调用上传的数据的depth,如果两张纹理图片放在一起,然后一起上传(这样只需要调用一次这个函数),那么需要設爲2.后面再设置format data等等即可。如果需要指定mipmap(level大于1) 那么还需要把每个level的数据都上传。
Example:
TexStorage3D(...3... W, H, 2);
// allocates W x H x 2 level0, W/2 x H/2 x 2 level1, W/4 x H/4 x 2 level2.
// Contents are undefined at this point.
TexSubImage3D(...level0, 0, 0, 0, W, H, 1... lod0_slice0_pixels);
TexSubImage3D(...level0, 0, 0, 1, W, H, 1... lod0_slice1_pixels);
TexSubImage3D(...level1, 0, 0, 0, W/2, H/2, 1... lod1_slice0_pixels);
TexSubImage3D(...level1, 0, 0, 1, W/2, H/2, 1... lod1_slice1_pixels);
TexSubImage3D(...level2, 0, 0, 0, W/4, H/4, 1... lod2_slice0_pixels);
TexSubImage3D(...level2, 0, 0, 1, W/4, H/4, 1... lod2_slice1_pixels);
// all slices of all mipmaps now transferred
如果相同mipmap的两张纹理是前后相连地存储在一起的,可以这样做:
TexSubImage3D(...level0, 0, 0, 0, W, H, 2... lod0_slice0and1_pixels);
TexSubImage3D(...level1, 0, 0, 0, W/2, H/2, 2... lod1_slice0and1_pixels);
TexSubImage3D(...level2, 0, 0, 0, W/4, H/4, 2... lod2_slice0and1_pixels);
shader内访问
需要定义2darray的sampler,然后还是调用texture函数,但是第二个参数需要三维的纹理坐标,z值代表在第几张纹理上面取值,从 0 开始。
"precision mediump sampler2DArray;\n"
"uniform sampler2DArray texture_array;\n"
...
...
" color = texture(texture_array, vec3(texCoord.xy, layer));\n"
注意:如果上传三维的纹理坐标,假设我们有两张纹理图片,我们上传的z值只有 0 和 1 两个,但是在光栅化阶段的插值计算会生成一些处于0和1之间的非整数的z值,这不是我们想要的,所以不能使用三维纹理坐标。我们需要单独上传这个数据,然后在shader内构造出一个新的三维的向量,这个时候z值就只有0、1两个值了。
参考资料:Array-Texture-confusion 讨论帖子
例子1--zwqxin
例子2--老外的
OpenGL ES: Array Texture初体验的更多相关文章
- [工作记录] Android OpenGL ES: non-square texture - continue
previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...
- 【ES】ElasticSearch初体验之使用Java进行最基本的增删改查~
好久没写博文了, 最近项目中使用到了ElaticSearch相关的一些内容, 刚好自己也来做个总结. 现在自己也只能算得上入门, 总结下自己在工作中使用Java操作ES的一些小经验吧. 本文总共分为三 ...
- OpenGL ES: 纹理采样 texture sample
Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...
- [OpenGL ES 02]OpenGL ES渲染管线与着色器
[OpenGL ES 02]OpenGL ES渲染管线与着色器 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循"署名-非商业用途-保持一致"创 ...
- [OpenGL ES 03]3D变换:模型,视图,投影与Viewport
[OpenGL ES 03]3D变换:模型,视图,投影与Viewport 罗朝辉 (http://blog.csdn.net/kesalin) 本文遵循“署名-非商业用途-保持一致”创作公用协议 系列 ...
- Android OpenGL ES(十四)gl10方法解析
Android 支持 OpenGL 列表 1.GL 2.GL 10 3.GL 10 EXT 4.GL 11 5.GL 11 EXT 6.GL 11 ExtensionPack 我们将使用 GL10 这 ...
- Android OpenGL ES(二)OpenGL ES管道(Pipeline) .
大部分图形系统都可以比作工厂中的装配线(Assemble line)或者称为管道(Pipeline).前一道的输出作为下道工序的输入.主CPU发出一个绘图指令,然后可能由硬件部件完成坐标变换,裁剪,添 ...
- 一步步实现windows版ijkplayer系列文章之六——SDL2源码分析之OpenGL ES在windows上的渲染过程
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
- OpenGL ES 3.0之VertexAttributes,Vertex Arrays,and Buffer Objects(九)
顶点数据,也称为顶点属性,指每一个顶点数据.指能被用来描述每个顶点的数据,或能被所有顶点使用的常量值.例如你想绘制一个具有颜色的立方体三角形.你指定一个恒定的值用于三角形的所有三个顶点颜色.但三角形的 ...
随机推荐
- 07.LoT.UI 前后台通用框架分解系列之——轻巧的文本编辑器
LoT.UI汇总:http://www.cnblogs.com/dunitian/p/4822808.html#lotui 上次说的是强大的百度编辑器 http://www.cnblogs.com/d ...
- [C#] 剖析 AssemblyInfo.cs - 了解常用的特性 Attribute
剖析 AssemblyInfo.cs - 了解常用的特性 Attribute [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5944391.html 序 ...
- C#中如何给Excel添加水印
我们知道Microsoft Excel并没有内置的功能直接给Excel表添加水印,但是其实我们可以用其他变通的方式来解决此问题,如通过添加页眉图片或艺术字的方法来模仿水印的外观.所以在这篇文章中,我将 ...
- .NET应用和AEAI CAS集成详解
1 概述 数通畅联某综合SOA集成项目的统一身份认证工作,需要第三方系统配合进行单点登录的配置改造,在项目中有需要进行单点登录配置的.NET应用系统,本文专门记录.NET应用和AEAI CAS的集成过 ...
- 手机web如何实现多平台分享
话说App一般都带有分享到社交平台的入口,web网页的分享也有很不错的框架,但是随着HTML5的不断发展,手机web页面越来越多的进入到我们的生活中,那如何在我们的手机上完成分享呢?话说各大分享平台都 ...
- Android 在Android代码中执行命令行
1.路径最好不要是自己拼写的路径/mnt/shell/emulated/0/wifidog.conf 最好是通过方法获取的路径,不然可能导致命令无效 (挂载点的原因) public static f ...
- Android开发学习—— Fragment
#Fragment* 用途:在一个Activity里切换界面,切换界面时只切换Fragment里面的内容* 生命周期方法跟Activity一致,可以理解把其为就是一个Activity* 定义布局文件作 ...
- DevOps对于企业IT的价值
其实从敏捷延展开的 DevOps 概念很早就已经被提出,不过由于配套的技术成熟度水平层次不齐, DevOps 的价值一直没有有效地发挥出来.现如今,随着容器技术的发展, DevOps 在企业中的实践难 ...
- css实现文本框和下拉框结合的案例
html 代码部分 <div id="list-name-input" class="list-name-input"> <select ty ...
- 搞了我一下午竟然是web.config少写了一个点
Safari手机版居然有个这么愚蠢的bug,浪费了我整个下午,使尽浑身解数,国内国外网站搜索解决方案,每一行代码读了又想想了又读如此不知道多少遍,想破脑袋也想不通到底哪里出了问题,结果竟然是web.c ...