在OpenGL ES中绘制一张图片需要使用到纹理(texture),绘制纹理步骤如下:
编写shader
绘制纹理的shader需要顶点数据、纹理顶点数据和纹理。Vertex Shader代码如下:
a_Position:顶点数据。
a_TexCoordinate:纹理顶点数据。
v_TexCoord:varying类型,v_TexCoord是a_TexCoordinate的值,传递给Fragment Shader使用。
Fragment Shader代码如下:
u_Texture:纹理,其类型是sampler2D。
v_TexCoord:Vertex Shader传递过来的纹理顶点数据,texture2D是OpenGL ES内置函数,称之为采样器,获取纹理上指定位置的颜色值。
创建program并获取参数句柄
创建program的过程在《OpenGL ES for Android 环境搭建》中详细介绍,这里不在介绍,直接使用封装好的工具类,代码如下:
bitmap_vs.glsl和bitmap_fs.glsl是assets/glsl目录下文件,分别代表顶点shader和纹理shader。
AssetsUtils.readAssetsTxt为工具类,读取asset文件下的文件返回String类型,代码如下:
program的创建要在GLThread线程(所有的OpenGL ES的相关操作都要在GLThread线程中运行),在Renderer的onSurfaceCreated回调中创建,代码如下:
program创建完成后获取顶点数据(a_Position)、纹理顶点数据(a_TexCoordinate)、纹理(u_Texture)的句柄,代码如下:
a_Poition、a_TexCoordinate、u_Texture对应Shader中的名称,mProgramHandle为program的句柄。
定义顶点数据
创建全屏的顶点数据代码如下:
这里有4个点,每个点包含3个float数据,代表x,y,z。4个顶点的位置如下图:
OpenGL ES中绘制任何形状都是通过绘制多个三角形而组成,所以我们将这4个点分为2个三角形,分布为(V1,V2,V3)和(V1,V3,V4),因此定义三角形索引数组代码如下:
将索引数组转为buffer,我们也将此方法封装在工具类里面,代码如下:
调用方式代码如下:
定义纹理顶点
纹理坐标系统如下图:
纹理坐标的原点是左上角,右下角是(1,1),将整张图片绘制的纹理顶点数据代码如下:
纹理坐标的顶点顺序不是随便定义的,要与定义的顶点数据一一对应,否则可能出现纹理错乱,对应顺序如下图:
如果将纹理顶点设置如下:
纹理将逆时针旋转90度,通过此方法可以旋转、镜像纹理,但我们一般不会使用此方法旋转、镜像纹理,可以通过OpenGL ES中著名的MVP矩阵进行此操作。
加载纹理
纹理的的来源是一张图片,将图片转为Bitmap,代码如下:
创建2D纹理id,代码如下(此方法将封装在工具类中):
GLES20.glGenTextures(count,array,offset):生成纹理,参数说明如下:
GLES20.glGenTextures():生成1个纹理,textures[0]存放纹理id。
GLES20.glTexParameteri:纹理映射方式。
纹理创建成功后返回纹理id,将Bitmap传递给此纹理,代码如下:
GLUtils是系统工具类,并不是我们自己写的工具类。
绘制纹理
GLES20.glUseProgram():启用当前program,mProgramHandle是启用program的句柄。
设置纹理,代码如下:
GLES20.glActiveTexture:激活纹理,GLES20.GL_TEXTURE0表示激活0号纹理,也可以是GLES20.GL_TEXTURE1、GLES20.GL_TEXTURE2等。
GLES20.glBindTexture:将纹理绑定到GL_TEXTURE_2D类型。
GLES20.glUniform1i(textureLoc, 0):设置纹理,textureLoc是Fragment Shader中纹理句柄,后面的参数0和GLES20.GL_TEXTURE0是对应的,如果启用GLES20.GL_TEXTURE1,那么使用GLES20.glUniform1i(textureLoc, 1)。
GLES20.glDrawElements是真正的绘制,函数结构如下:
参数说明如下:
mode:绘制方式,GLES20.GL_TRIANGLES表示绘制三角形。
count:顶点的个数
type:索引(indices)数组中的元素类型,注意不是顶点的类型,值必须是GL_UNSIGNED_BYTE或者GL_UNSIGNED_SHORT。
indices:索引数组
到此绘制纹理就完成了。
更多相关阅读:
本文分享自微信公众号 - 老孟Flutter(lao_meng_qd)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。