OpenGL ES 2.0总结(2)-纹理

原创 2015年11月13日 15:10:35

OpenGL ES 2.0 - 纹理


1. 纹理初始化

1) glGenTextures()
生成纹理id,可以一次生成多个,后续操作纹理全靠这个id
2) glBindTexture()
操作纹理,传入纹理id作为参数,每次bind之后,后续操作的纹理都是该纹理
3) glTexParameteri()
指定纹理格式。这里包括纹理横向和纵向的重复方式
GL_TEXTURE_WRAP_S
GL_TEXTURE_WRAP_T

和纹理在放大和缩小(同样纹理离远和离近)时的处理,这种设置主要是为了避免同一个纹理反复使用时,远处的纹理反而比近处的清晰
GL_TEXTURE_MAG_FILTER
GL_TEXTURE_MIN_FILTER

4) GLUtils.texImage2D()
给纹理传入图像数据,至此,此纹理相关设置已经结束。后续想使用或者操作这个纹理,只要再glBindTexture这个纹理的id即可.

下面给一个较为完整的例子

int[] textureHandle = new int[1];
GLES20.glGenTextures(1, textureHandle, 0);
int TextureID = textureHandle[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, TextureID);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

2. 纹理单元

OpenGL可以同时使用多个纹理,这些纹理可以分别绑定到特定的纹理单元。每个纹理单元有其独立的图像、Filter参数等。

void glActiveTexture(GLenum texUnit)激活对应的纹理单元,之后所有的纹理操作都是针对这个纹理单元。参数GL_TEXTUREi,i取值0至k,最大值跟硬件相关。

绑定纹理到纹理单元举例:

   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE2D,tex1);
   glActiveTexture(GL_TEXTURE3);
   glBindTexture(GL_TEXTURE2D,tex2);

此时GL_TEXTURE0(默认纹理单元)下绑定的是tex1,GL_TEXTURE3下绑定的是tex2

使用时的语句完全相同。在激活和绑定其他纹理之前,使用的都是该纹理单元和纹理。

3. 多重纹理与shader

使用多个纹理时,主要分以下几步
1)首先需要编译好shader。
shader中的fragment.glsl中应该包括多个纹理的采样器

例如

    uniform sampler2D Map1;
    uniform sampler2D Map2;
2)在代码中获取到shader中改sampler的句柄
相当于建立起了代码和shader之间的通道,通过句柄可以给shader中的sampler赋值
mMap1= GLES20.glGetUniformLocation(Program, "Map1");
mMap2= GLES20.glGetUniformLocation(Program, "Map2");
3)后设置纹理单元与shader中sampler的关系
通过赋值,可以指定sampler与纹理单元的关系,想让sampler对哪个纹理单元GL_TEXTUREi中的纹理进行采样/处理,就给它赋值i,如果纹理是GL_TEXTURE0,就给sampler2D赋值为0,以此类推。
GLES20.glUniform1i(mMap1,0);
GLES20.glUniform1i(mMap2,3);

这里指定完毕之后,后续shader中的Map1的采样对象就是GL_TEXTURE0上绑定的纹理,而Map2的处理对象就是GL_TEXTURE3上绑定的纹理

4)绑定目标纹理
要使用相应的纹理,步骤和“2.纹理单元”中描述的完全一样(前提是这些纹理以已经完成了初始化),就是:
   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE2D,tex1);
   glActiveTexture(GL_TEXTURE3);
   glBindTexture(GL_TEXTURE2D,tex2);

此时GL_TEXTURE0上绑定的纹理是tex1,对应在shader中的sampler是Map1;GL_TEXTURE3上绑定的纹理是tex2,对应在shader中的sampler是Map2

4)使用shader处理
通过上述操作,直接在shader里调用vec4 texture2D(sampler,vec2)即可取到相应的像素值并做处理,例如
    vec4 color1 = texture2D(Map1,texCoord);
    vec4 color2 = texture2D(Map2,texCoord);

注意,返回的是vec4,无论纹理像素是什么格式的,都返回vec4类型,具体如下:

纹理图像类型 返回值
GL_RGB (R,G,B,1.0)
GL_RGBA (R,G,B,A)
GL_LUMINANCE (L,L,L,1.0)
GL_LUMINANCE_ALPHA (L,L,L,A)
GL_ALPHA (0.0, 0.0, 0.0, A)

参考
opengles2.0中的纹理
http://blog.csdn.net/ldpxxx/article/details/9253603
gles官方文档
https://www.khronos.org/opengles/sdk/docs/man/
OpenGL ES2.0 生成Mipmap纹理
http://xiaxveliang.blog.163.com/blog/static/297080342013467552467/

Android OpenGLES2.0(八)——纹理贴图之显示图片

前面几篇博客,我们将了Android中利用OpenGL ES 2.0绘制各种形体,并在上一篇博客中专门讲了GLSL语言。但是我们看到的基于OpenGL开发的应用和游戏,可不仅仅是那些规则形体和一些简单...
  • junzia
  • junzia
  • 2016-10-23 01:15:49
  • 9586

OpenGL绘制纹理时,glGenTextures()函数带来的内存泄露,使程序被杀死。

项目中,我需要定时的去更换纹理图片,贴到指定的位置。我就理所当然的写了一个函数,然后定时去执行一次该函数。 函数中有代码:             glPixelStorei(GL_UNPACK_...
  • gagabook
  • gagabook
  • 2016-09-02 13:58:55
  • 2061

Android OpenGLES2.0(十五)——利用EGL后台处理图像

在Android OpenGLES2.0(十二)——FBO离屏渲染中,记录了采用FBO进行离屏渲染的方式来进行后台处理图像,但是在使用时,示例中还是用到了GLSurfaceView控件来提供GL环境。...
  • junzia
  • junzia
  • 2017-02-20 10:36:27
  • 4604

Android OpenGL ES 应用(二) 纹理

上一篇讲了基础入门 OpenGL (一) ,这一次主要学习OpenGL 纹理基本学习总结 要是做复杂的OpenGL应用程序,一定会用到纹理技术。纹理说白了就是把图片或者视频图像绘制到OpenGL空间中...
  • birdsaction
  • birdsaction
  • 2015-03-17 14:03:08
  • 1828

Android上使用OpenGLES2.0显示YUV数据

楼主收到这样的任务,在Android上用OpenGLES来显示YUV图像,之所以这样做,是因为: 1.Android本身也不能直接显示YUV图像,YUV转成RGB还是必要的; 2.YUV手动转RG...
  • ueryueryuery
  • ueryueryuery
  • 2013-12-27 11:44:20
  • 26937

Android之GLES2.0显示图片测试代码

public class MainActivity extends Activity { private GLSurfaceView mEffectView; @Override p...
  • chenyefei
  • chenyefei
  • 2016-06-09 09:56:35
  • 777

OpenGL ES之glUniform函数

函数名: glUniform 功能: 为当前程序对象指定Uniform变量的值。(译者注:注意,由于OpenGL ES由C语言编写,但是C语言不支持函数的重载,所以会有很多名字相同后...
  • wangyuchun_799
  • wangyuchun_799
  • 2012-07-13 09:38:11
  • 36920

使用OpenGLES 在 android 上显示摄像头滤镜效果

这是一份 使用opengles 绘制摄像头数据的代码,并使用滤镜处理了摄像头的效果,使用GPU绘制,减少cpu的占用...
  • chylove5
  • chylove5
  • 2015-11-04 14:26:52
  • 4800

Android OpenGLES2.0(十二)——FBO离屏渲染

之前的博客我们所做的示例都是直接渲染到屏幕上的,如果我们并不需要渲染到屏幕上,也就是离屏渲染,该怎么做呢?FBO离屏渲染是一个很好的选择。在这篇博客中,我们将以渲染摄像头数据为例,使用FBO进行离屏渲...
  • junzia
  • junzia
  • 2016-12-24 18:36:06
  • 9214

OpenGLES2.0绘制2D图片详解(附完整demo)

前段时间项目中有用到OpenGLES进行开发的部分,因此花了2周的时间研究了下OpenGLES,写了个绘制2D图片的Demo,OpenGLES提供了android访问OpenGL的接口,也就是我们熟知...
  • liuxu841911548
  • liuxu841911548
  • 2017-02-08 15:23:36
  • 1747
收藏助手
不良信息举报
您举报文章:OpenGL ES 2.0总结(2)-纹理
举报原因:
原因补充:

(最多只允许输入30个字)