opengles3.0 纹理(七):

opengles3.0 纹理(七):

 

纹理对象和纹理加载:

       纹理有2D纹理,2D纹理数组,3D纹理,立方图纹理。

       2D纹理是一个图像数据的二维数组。用2D纹理渲染时,纹理坐标用做纹理图像中的索引。每个顶点都有一个纹理坐标。

       纹理图像的左下角由st坐标(0.0,0.0),右上角(1.0,1.0)

 

glGenTextures(GLsizei n, GLuint *texture)   //生成纹理ID

glBindTexture(GLenum target, GLuint texture)

target 将纹理对象绑定到GL_TEXTURE_2D,GL_TEXTURE_3D,GL_TEXTURE_2D_ARRAY,GL_TEXTURE_CUBE_MAP

glTexImage2D  加载2D和立方体纹理,纹理比较大的时候加载纹理会比较慢,因为它需要把数据传给GPU的自己的BUFFER.

 

 

 

texture:要绑定的纹理对象的句柄。

        

在纹理缩小模式中,只有GL_NEAREST和GL_LINEAR不需要为纹理指定完整的mip贴图链。

 

 

纹理坐标的包装:

    纹理包装模式用于指定纹理坐标超出【0.0,1.0】范围时所有发生的行为,用glTexParameter设置,这些模式可以为s,t,r坐标单独设置。

   GL_TEXTURE_WRAP_S  (s)

   GL_TEXTURE_WRAP_T  (t)

   GL_TEXTURE_WRAP_R  (r)

 

  GL_REPEAT    重复纹理

   GL_CLAMP_TO_EDGE              限定读取纹理边缘

  GL_MIRRORED_REPEAT            重复纹理和镜像

 

 

opengles3.0 支持的纹理格式:规范化的纹理格式、浮点纹理、整数纹理、共享指数纹理、sRGB纹理和深度纹理。

规范化格式的每个纹素可以用1-4个分量指定(R,RG,RGB或者RGBA),opengles3.0还引入了GL_RGB10_A2,允许纹理数据的规范对于每个(R,G,B)

值上有10bit,对于每个alpha值有2位。

 

 

 

// Initialize the shader and program object

//

int Init ( ESContext *esContext )

{

   UserData *userData = esContext->userData;

   char vShaderStr[] =

      "#version 300 es                            \n"

      "layout(location = 0) in vec4 a_position;   \n"

      "layout(location = 1) in vec2 a_texCoord;   \n"

      "out vec2 v_texCoord;                       \n"

      "void main()                                \n"

      "{                                          \n"

      "   gl_Position = a_position;               \n"

      "   v_texCoord = a_texCoord;                \n"  #纹理坐标

      "}                                          \n";

 

   char fShaderStr[] =

      "#version 300 es                                     \n"

      "precision mediump float;                            \n"

      "in vec2 v_texCoord;                                 \n"

      "layout(location = 0) out vec4 outColor;             \n"

      "uniform sampler2D s_texture;                        \n"

      "void main()                                         \n"

      "{                                                   \n"

      "  outColor = texture( s_texture, v_texCoord );      \n"   //s_texture纹理贴图,接口外面传进来,v_texCoord纹理坐标

      "}                                                   \n";

 

   // Load the shaders and get a linked program object

   userData->programObject = esLoadProgram ( vShaderStr, fShaderStr );

 

   // Get the sampler location

   userData->samplerLoc = glGetUniformLocation ( userData->programObject, "s_texture" );

 

   // Load the texture

   userData->textureId = CreateSimpleTexture2D ();

 

   glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f );

   return TRUE;

}

 

 

 

 

void Draw ( ESContext *esContext )

{

   UserData *userData = esContext->userData;

   GLfloat vVertices[] = { -0.5f,  0.5f, 0.0f,  // Position 0

                            0.0f,  0.0f,        // TexCoord 0

                           -0.5f, -0.5f, 0.0f,  // Position 1

                            0.0f,  1.0f,        // TexCoord 1

                            0.5f, -0.5f, 0.0f,  // Position 2

                            1.0f,  1.0f,        // TexCoord 2

                            0.5f,  0.5f, 0.0f,  // Position 3

                            1.0f,  0.0f         // TexCoord 3

                         };

   GLushort indices[] = { 0, 1, 2, 0, 2, 3 };   //顶点的画的顺序

 

   // Set the viewport

   glViewport ( 0, 0, esContext->width, esContext->height );

 

   // Clear the color buffer

   glClear ( GL_COLOR_BUFFER_BIT );

 

   // Use the program object

   glUseProgram ( userData->programObject );

 

   // Load the vertex position

   glVertexAttribPointer ( 0, 3, GL_FLOAT,

                           GL_FALSE, 5 * sizeof ( GLfloat ), vVertices );

   // Load the texture coordinate

   glVertexAttribPointer ( 1, 2, GL_FLOAT,

                           GL_FALSE, 5 * sizeof ( GLfloat ), &vVertices[3] );

 

   glEnableVertexAttribArray ( 0 );

   glEnableVertexAttribArray ( 1 );

 

   // Bind the texture

   glActiveTexture ( GL_TEXTURE0 );

   glBindTexture ( GL_TEXTURE_2D, userData->textureId );

 

   // Set the sampler texture unit to 0

   glUniform1i ( userData->samplerLoc, 0 );

 

   glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );

}

 

 

顶点着色器以一个二分量纹理坐标作为顶点输入,并将其作为输出传递给片段着色器。片段着色器消费该纹理坐标

并将其用于纹理读取。片段着色器声明一个类型位sampler2D的统一变量s_texture.

采样器是用于从纹理贴图中读取的特殊统一变量。采样器统一变量将加载一个指定纹理绑定的纹理单元的数值。

例如,用数值0指定采样器表示从单元GL_TEXTURE0读取。

在shader中使用内建texture从纹理贴图中读取数据。

 

 

 

压缩纹理:

      opengles3.0还支持压缩纹理,glCompressedTexImage2D,加载压缩纹理

     一旦加载了压缩纹理,他就可以和五压缩纹理一样用于纹理处理。要所问题ETC压缩工具。

 

纹理子图像规范:

      用glTexImage2D上传纹理图像之后,可以更新图像之后,可以更新图像的各个部分,如果你只希望更新图像的一个子区域

      这种能力就很实用。加载2D纹理图像一部分的函数是glTexsubImage2D.

 

glTexSubImage2D函数

 

提供修改图像函数,因为修改一个纹理比重新创建一个纹理开销小得多,对于一些视频捕捉程序可以先将视频图像存储在更大的初始图像中(该图像大小要求是2的次方,OGL 2.0后没有这个限制),创建一个渲染用的纹理,然后反复调用glTexSubImage2D(修改的图像区域不用是2的次方)函数从图像视频图像区域读取数据到渲染纹理图像中。渲染用的纹理图像只需要创建一次即可。

函数原型:

glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);

target参数必须是glCopyTexImage2D中的对应的target可使用的值。

level 是mipmap等级。

xoffset,yoffset是要修改的图像的左下角偏移。width,height是要修改的图像宽高像素。修改的范围在原图之外并不受到影响。

format,type描述了图像数据的格式和类型,和glTexImage2D中的format, type一致。

pixels 是子图像的纹理数据,替换为的值。

子图像也受到glPixelStore*()和glPixelTransfer*()以及其它像素传输操作所设置模式的影响。

 

实例:

glBindTexture(GL_TEXTURE_2D, 0);

glBindTexture(GL_TEXTURE_2D, texName);

int offsetX = 0;// 12;

int offsetY = 0;// 44;

glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, subImageWidth,

subImageHeight, GL_RGBA,

GL_UNSIGNED_BYTE, subImage);

 

 

 

从颜色缓冲区复制纹理数据:

opengles3.0 中支持另一个纹理功能是从颜色缓冲区复制数据到一个纹理。如果你希望实用渲染的结果作为纹理中的数据,这一功能很实用。

作为复制图像数据来源的颜色换成哦过去可以用glReadBuffer函数设置。如果应用程序渲染到一个双缓冲区EGL的可显示表面。则glReadBuffer必须

设置为GL_BACK.

glCopyTexSubImage2D函数

 

 

glCopyTexSubImage2D函数

 

从帧缓存区GL_READ_BUFFER读取一块像素矩形,并替换一个现有的纹理数组的一部分或全部,相当于调用了glCopyTexImage2D和glTexSubImage2D函数。

原型:

glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);

glCopyTexSubImage2D — copy a two-dimensional texture subimage

target

Specifies the target texture. Must be GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,GL_TEXTURE_CUBE_MAP_POSITIVE_Z, or GL_TEXTURE_CUBE_MAP_NEGATIVE_Z.

像素是从当前的GL_READ_BUFFER读取的,它处理的过程像调用了glCopyPixels,但像素数据并不是放在帧缓存区中,而是放入纹理内存中。glPixelTransfer*和其它像素传输操作的设置也会对它产生作用。在OGL 3.0及以后的版本,应该可以使用帧缓存区对象直接渲染到纹理内存,从而高效的执行和glCopyTexSubImage2D相同的操作。

 

 

glGenTextures(1, &_iTexDepth);

 

glBindTexture(GL_TEXTURE_2D, _iTexDepth);

 

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

 

glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

 

glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

 

glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE

 

);

 

glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE

 

);

 

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, _w, _h, 0,

 

GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);

 

glBindTexture(GL_TEXTURE_2D, 0);

 

 

and prefare to render:

 

 

glViewport(0, 0, _w, _h);

 

glMatrixMode(GL_PROJECTION);

 

glLoadMatrixf(camera_proj);

 

glMatrixMode(GL_MODELVIEW);

 

glLoadMatrixf(camera_modelview);

 

glPushAttrib(GL_COLOR_BUFFER_BIT | GL_PIXEL_MODE_BIT);

 

glDrawBuffer(GL_BACK);

 

glReadBuffer(GL_BACK);

 

glClearColor(0, 0, 0, 1);

 

glClearDepth(1.0f);

 

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

 

and render something, and copy to texture :

 

 

glBindTexture(GL_TEXTURE_2D, _iTexDepth);

 

glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, _w, _h);

 

glBindTexture(GL_TEXTURE_2D, 0);

 

 

      

     

 

 

 

 

       

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值