解密glActiveTexture

OpenGL 是一种跨平台的图形渲染API, 使用OpenGL 可以开发跨平台的图形应用程序。在OpenGL 的世界里,图像是被分为许多纹理的。

在这些纹理中,glActiveTexture 作为 OpenGL 函数之一,对于处理多个纹理非常重要。

一、glActiveTexture是什么

glActiveTexture 是一个 OpenGL 函数,用于指定当前活动的纹理单元。

    void glActiveTexture(GLenum texture);

其中,texture 是一个 GLenum 类型的参数,指定一个纹理单元,可以是下面这个参数之一:

  1. GL_TEXTUREi
  2. GL_TEXTURE0 + i

其中 i 的范围是从 0 到当前 OpenGL 实现支持的最大纹理单元数。

二、glActiveTexture的用途

1. 处理多纹理

OpenGL 允许用户绑定多个纹理到多个纹理单元上,glActiveTexture 函数就可以用于指定当前活动的纹理单元。

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture1);

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

上面的例子中,我们绑定了一个名为 texture1 的 2D 纹理到纹理单元 GL_TEXTURE0 中,以及一个名为 texture2 的 2D 纹理到纹理单元 GL_TEXTURE1 中。

2. 定义纹理单元

在显卡硬件资源有限的情况下,我们不可能无限制地向显卡中增加新的缓存区。为了最优化纹理的使用,我们可以将一张大的图像分成几部分储存在不同的纹理空间中。 glActiveTexture 可以用于定义纹理单元。

    GLuint textures[3];
    glGenTextures(3, textures);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    ...

上面的例子中,我们首先生成了 3 个纹理缓存,然后定义了纹理空间0 的缓存。

3. 显卡性能优化

我们使用多个纹理单元来提高显示性能,这是实现纹理功能的一种方法。

因为纹理一般储存在显存当中,显存的空间有限,所以我们在使用多纹理的时候,需要动态的开辟储存空间。

因此,合理使用 glActiveTexture 函数可以有效地避免空间浪费。

三、附加代码示例

// OpenGL 初始化纹理
GLuint texture1, texture2;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);

// 设置纹理参数
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

// 加载纹理图像
int width, height, nrChannels;
unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
if (data)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
    std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);

glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
if (data)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
    std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);

// 在shader中,使用下面的语句分别绑定纹理单元
uniform sampler2D texture1;
uniform sampler2D texture2;

...
glUseProgram(shaderProgram);
glUniform1i(glGetUniformLocation(shaderProgram, "texture1"), 0);
glUniform1i(glGetUniformLocation(shaderProgram, "texture2"), 1);

// 在绘制之前,将纹理关联到指定的纹理单元上
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);

...
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/285040.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝的头像小蓝
上一篇 2024-12-22 15:43
下一篇 2024-12-22 15:43

发表回复

登录后才能评论