8.纹理

种类

2D纹理
2D纹理数组:独立切片
3D纹理:切片关联依赖
立方图纹理

2D纹理

就是一个图像数据的二维数组。一个纹理的单独数据元素称作纹素,纹素通过基本格式和数据类型确定的。
基本格式描述
GL_RED
GL_RG红绿
GL_RGB红绿蓝
GL_RGBA红绿蓝、alpha
GL_LUMINANCE亮度
GL_LUMINANCE_ALPHA亮度、alpha
GL_ALPHAalpha
GL_DEPTH_COMPONENT深度
GL_DEPTH_STENCIL深度、模板
GL_RED_INTEGER整数红
GL_RG_INTEGER整数红绿
GL_RGB_INTEGER整数红绿蓝
GL_RGBA_INTEGER整数红绿蓝、alpha

纹理对象和纹理的加载

void glGenTextures(GLsizei n, GLuint *textures)
    //GL_TEXTURE_2D 
    //GL_TEXTURE_3D
    //GL_TEXTURE_2D_ARRAY
    //GL_TEXTURE_CUBE_MAP
void glBindTexture(GLenum targtet, GLuint texture)
void glTexImage2D(GLenum target, 
                  GLint level, 
                  Genum internalFormat, //纹理存储的内部格式
                  GLsizei with,
                  GLsizei height, 
                  GLint border, //忽略,值为0
                  GLenum format, //输出的纹理格式
                  GLenum type, //输入像素数据的类型GL_UNSIGNED_BYTE GL_BYTE GL_UNSIGNED_SHORT……
                  const void* pixedls)//包含实际图像的像素数据
void glDeleteTextures(GLsizei n, GLuint *textures)
 
// Texture object handle
GLuint textureId;
// 2x2 Image, 3 bytes per pixel (R, G, B)
GLubyte pixels[4 * 3] =
{
   255,   0,   0, // Red
     0, 255,   0, // Green
     0,   0, 255, // Blue
   255, 255,   0  // Yellow
};
//设置解包对齐。通过glTexImage2D上传纹理数据时,像素行被认定为对齐到GL_UNPACK_ALIGNMENT设置的值
//默认情况下,该值为4,意味着像素行被认定为从4字节的编边界开始。
//此处设置为1,意味着每个像素行从字节编解开始(紧密打包)。
//几乎不使用GL_UNPACK_ALIGNMENT之外的选项
//打包选项由glReadPixedls使用·
glPixelStorei ( GL_UNPACK_ALIGNMENT, 1 );
// Generate a texture object
glGenTextures ( 1, &textureId );
// Bind the texture object
glBindTexture ( GL_TEXTURE_2D, textureId );
// Load the texture
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels );
// Set the filtering mode
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

纹理过滤和mip贴图

mip贴图链始于原来指定的图像,后续的每个图像在每个维度上是前一个图像的一半,一直持续到最后达到链底部的1x1纹理。mip贴图级别可以编程生成,一个mip级别中的每个像素通常根据上一级别中相同位置的4个像素的平均值计算(盒式过滤)----目的是解决伪像,减少性能损失。

纹理坐标包装

glTexParameter[i|f][v]设置
  • GL_TEXTURE_WRAP_S:设置s坐标
  • GL_TEXTURE_WRAP_T:设置t坐标
  • GL_TEXTURE_WRAP_R:设置r坐标,只用于3D纹理和2D纹理数组
纹理包装模式
  • GL_REPEAT:重复纹理
  • GL_CLAMP_TO_EDGE:限定读取纹理的边缘
  • GL_MIRRORED_REPEAT:重复纹理和镜像
   //简单调用
   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT );
   glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT );

着色器程序中使用2D纹理

 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"
      "}                                                   \n";

GLuint textId;
//创建program,textureId过程省略
//…………
//获取坐标
GLuint tex_position = glGetUniformLocation ( program, "s_texture" );
//指定0代表指定采样器从GL_TEXTURE0读取数据,指定1则代表TEXTURE1
glUniform1i(tex_position, 0);
//指定活动单元
glActiveTexture(GL_TEXURE0);
//绑定textId到活动单元
glBindTexture(GL_TEXTURE_2D, textId);
//后续可对纹理进行缩放包装处理

立方图纹理使用

使用samplerCube声明三个分量的纹理坐标,代码相似度较高

3D纹理和2D纹理数组

使用glTexImage3D加载纹理数组,代码相似度较高

压缩纹理

  • 可减少内存占用;
  • 节约了着色器中读取纹理时耗时的内存宽带;
  • 较少必须储存的图像数据,减少应用程序的下载大小;
2.0未定义压缩的纹理图像格式,所以各厂商可能实现不同的纹理压缩格式。
3.0定义了厂商必须支持的标准纹理压缩格式,ETC2和EAC(不支持3D纹理,只支持2D纹理和2D纹理数组)。
glCompressedTexImage2D:用于加载2D纹理和立方图压缩图像数据。
glCompressedTexImage3D: 2D纹理数组,可用于加载供应商专用的3D纹理压缩格式

更新纹理部分区域

glTexSubImage2D() :更新图像的一个子区域
target  纹理目标
level  指定更新的mip级别,纹理贴图level
xoffset 纹理数据的偏移x 
yoffset 纹理数据的偏移y 
width   
height  
format  像素数据的颜色格式
type    颜色分量的数据类型
pixels  包含图像子区域的实际像素数据
glCompressedTexSubImage2D:更新压缩的2D纹理图像的子区域
glTexSubImage3D:更新3D纹理和2D纹理数组的子区域

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

注:帧缓冲区对象提供了渲染-纹理转换的快速方法,比复制图像数据更快,性能高。
glReadBuffer(GLenum mode): GL_BACK  GL_COLOR_ATTACHMEMTi  GL_NONE
glCopyTexImage2D、glCopuTexSubImage2D、glCopyTexSubImage3D 
复制颜色缓冲区的数据时,可以转换为分量较少的格式,但不能转换为分量较多的格式。

采样器对象(3.0):为了改善性能

2.0频繁使用glTexParameter指定纹理参数时会造成不必要的开销,因为程序中会有大量纹理使用相同的设置。
3.0引入了采样器对象,将采样器状态与纹理状态分离,一次函数调用中与纹理单元绑定使用。采样器对象可用于很多纹理。
api基本见名知意
glGenSamplers(GLsizei n, GLuint *samplers);
glDeleteSamplers;
glBindSampler;
glSamplerParameteri;
glSamplerParameteriv;
glSamplerParameterf;
glSamplerParameterfv;

不可变纹理3.0:为了改善性能

应用程序在加载数据之前指定纹理的格式和大小。
glBindTexture绑定纹理后,使用glTexStorage2D、glTexStorage3D分配不可变存储。
生成不可变纹理后,调用gltexImage*、glCompressedTexImage*、glCopuTexImage*、glTexStorage*将无效,生成GL_INVALID_OPERATION错误。
但可以使用glTexSubImage2D、glTexSubImage3D、glGenerateMipMap或者渲染到纹理加载图像数据。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值