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初体验的更多相关文章

  1. [工作记录] Android OpenGL ES: non-square texture - continue

    previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...

  2. 【ES】ElasticSearch初体验之使用Java进行最基本的增删改查~

    好久没写博文了, 最近项目中使用到了ElaticSearch相关的一些内容, 刚好自己也来做个总结. 现在自己也只能算得上入门, 总结下自己在工作中使用Java操作ES的一些小经验吧. 本文总共分为三 ...

  3. OpenGL ES: 纹理采样 texture sample

    Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...

  4. [OpenGL ES 02]OpenGL ES渲染管线与着色器

    [OpenGL ES 02]OpenGL ES渲染管线与着色器 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循"署名-非商业用途-保持一致"创 ...

  5. [OpenGL ES 03]3D变换:模型,视图,投影与Viewport

    [OpenGL ES 03]3D变换:模型,视图,投影与Viewport 罗朝辉 (http://blog.csdn.net/kesalin) 本文遵循“署名-非商业用途-保持一致”创作公用协议 系列 ...

  6. 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 这 ...

  7. Android OpenGL ES(二)OpenGL ES管道(Pipeline) .

    大部分图形系统都可以比作工厂中的装配线(Assemble line)或者称为管道(Pipeline).前一道的输出作为下道工序的输入.主CPU发出一个绘图指令,然后可能由硬件部件完成坐标变换,裁剪,添 ...

  8. 一步步实现windows版ijkplayer系列文章之六——SDL2源码分析之OpenGL ES在windows上的渲染过程

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  9. OpenGL ES 3.0之VertexAttributes,Vertex Arrays,and Buffer Objects(九)

    顶点数据,也称为顶点属性,指每一个顶点数据.指能被用来描述每个顶点的数据,或能被所有顶点使用的常量值.例如你想绘制一个具有颜色的立方体三角形.你指定一个恒定的值用于三角形的所有三个顶点颜色.但三角形的 ...

随机推荐

  1. Angular2学习笔记(1)

    Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...

  2. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  3. 23种设计模式--观察者模式-Observer Pattern

    一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...

  4. MVC Core 网站开发(Ninesky) 2、栏目

    栏目是网站的常用功能,按照惯例栏目分常规栏目,单页栏目,链接栏目三种类型,这次主要做添加栏目控制器和栏目模型两个内容,控制器这里会用到特性路由,模型放入业务逻辑层中(网站计划分数据访问.业务逻辑和We ...

  5. .Net 分布式云平台基础服务建设说明概要

    1)  背景 建设云平台的基础框架,用于支持各类云服务的业务的构建及发展. 2)  基础服务 根据目前对业务的理解和发展方向,总结抽象出以下几个基础服务,如图所示 3)  概要说明 基础服务的发展会根 ...

  6. 初步认识TDD

    TDD,测试驱动开发(Test Driven Development)是极限编程中倡导的程序开发方法,以其倡导先写测试程序,然后编码实现其功能得名.本文将对TDD有一个较为系统的认识.    基础属性 ...

  7. 如何利用tcpdump对mysql进行抓包操作

    命令如下: tcpdump -s -l -w - dst -i eno16777736 |strings 其中-i指定监听的网络接口,在RHEL 7下,网络接口名不再是之前的eth0,而是 eno16 ...

  8. 一个表缺失索引发的CPU资源瓶颈案例

    背景 近几日,公司的应用团队反应业务系统突然变慢了,之前是一直比较正常.后与业务部门沟通了解详情,得知最近生意比较好,同时也在做大的促销活动,使得业务数据处理的量出现较大的增长,最终系统在处理时出现瓶 ...

  9. 移动应用App测试与质量管理一

    测试工程师 基于Html的WebApp测试, 现在一些移动App混Html5 HTML5性能测试 兼容性 整理后的脑图 测试招聘 弱化大量技术考察 看重看问题的高度 看重潜力 测试经验 质量管理 专项 ...

  10. SqlServer简单数据分页

    手边开发的后端项目一直以来都用的.NET MVC框架,访问数据库使用其自带的EF CodeFirst模式,写存储过程的能力都快退化了 闲来无事,自己写了条分页存储过程,网上类似的文章多的是,这里只列了 ...