OpenGL纹理空间开辟与绑定

glActiveTexture和glBindTexture的关系
OpenGL API 之 glTexImage2D

glTexImage2D

  1. glTexImage2D 用于开辟真正的GPU内存空间!

函数原型如下:


void glTexImage2D( 
  GLenum   target,  
  GLint   level,  
  GLint   internalFormat,  
  GLsizei   width,  
  GLsizei   height,  
  GLint   border,  
  GLenum   format,  
  GLenum   type,  
  const GLvoid *   data
  );

参数介绍:
target : 指定纹理单元的类型是哪一种,必须指定为

  • GL_TEXTURE_2D, GL_PROXY_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, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, or GL_PROXY_TEXTURE_CUBE_MAP中的一个。

二维纹理需要指定为GL_TEXTURE_2D.

level:指定纹理单元的层次
非mipmap纹理level设置为0,mipmap纹理设置为纹理的层级

internalFormat:指定OpenGL是如何管理纹理单元中数据格式的。
网络上很多解释说这个参数必须和后面的format参数一样,这个说法是不正确的!!!

width:指定纹理单元的宽度

height:指定纹理单元的高度

border:指定纹理单元的边框,如果包含边框取值为1,不包含边框取值为0

format指定data所指向的数据的格式

type:指定data所指向的数据的类型

data:实际指向的数据是什么. 要么为NULL . 要么为纹理数据.

下面具体介绍一下:
internalFormat

internalFormat

以下是stackoverflow 中的一段解释:

The format and type parameters describe the data you are passing to OpenGL as part of a pixel transfer operation. The internalforamt describes the format of the texture. You’re telling OpenGL that you’re giving it takes that looks like X, and OpenGL is to store it in a texture where the data is Y. Theinternalformat is “Y”.

从描述中我们知道:

  • internalFormat用来指定OpenGL中纹理单元中的格式是什么样的,
  • 而参数中的后三个(format 、type、 data)是用来指定用来传输到OpenGL中纹理单元数据的格式是怎么样的。

上面的internalForamt参数指定的就是texID对应纹理单元中的数据格式(An Image Format describes the way that the images in Textures and renderbuffers store their data. They define the meaning of the image’s data.),它是对OpenGL硬件驱动的一种很强的提示,告诉驱动它里面的数据是怎么组织的。

因此如果我们将internalForamt中的格式指定的和format中格式一致就可以更快地进行传输,而不需要在二者之间进行转换。

format、type、data指定的是pBytes中数据是怎么样组织的(A Pixel Transfer operation is the act of taking pixel data from an unformatted memory buffer and copying it in OpenGL-owned storag)

参数format和type指定了pBytes中的像素数据该如何解译:
其中format指定了每一个像素所包含的成分以及这些成分的顺序是怎么样的,比如:GL_RGBA指定了每个像素包含RGBA四个部分,顺序是R、G、B、A 而如果我们指定GL_BGRA则说明每个像素包含四个部分,但是顺序却不一样;

type则指定每一个成分需要几个字节来表示,比如我们指定GL_UNSIGNED_BYTE在说明每个成分需要一个unsigned byte来表示也就是一个字节,type的取值还包括:

  • GL_(UNSIGNED_)BYTE​: 1 byte
  • GL_(UNSIGNED_)SHORT​: 2 bytes
  • GL_(UNSIGNED_)INT​: 4 bytes
  • GL_HALF_FLOAT​: 2 bytes
  • GL_FLOAT​: 4 bytes

glBindTexture

glBindTexture(GL_TEXTURE_2D, tex_id)
有以下几个涵义:

  1. 表示 tex_id是一个二维纹理,设置过一次后,tex_id的类型就不可变了
  2. opengl采用状态机的设计. glBindTexture告诉opengl说,我选择tex_id作为当前纹理,后续对纹理的操作都将作用在此纹理上。

glActiveTexture

我们已经通过 glGenTextures 在显卡上开辟了一张纹理,
然后使用 glBindTexture 将该纹理选为当前操作目标,
接着也调用了glTexParameter 函数族设置了纹理的属性

那么问题来了,纹理是怎么和glsl上的sampler2D关联起来的?

纹理与sampler2D变量的关联是通过索引来关联的

GLuint tex_loc = glGetUniformLocation(program, "tex");
glUniform1i(tex_loc, 1);

然后

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, tex_id);

将纹理与GL_TEXTURE1关联起来

tex_id与GL_TEXTUR1关联
GL_TEXTURE1又与值为1的sampler2D变量关联

所以tex_id 就这样间接地与sampler2D变量关联了

平时使用单张纹理怎么不需要glActiveTexture
sampler2D默认值为0,纹理也默认与GL_TEXTURE0关联

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值