You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

glActiveTexture超出GL_TEXTURE0时多纹理渲染失效问题求助

问题诊断与修复方案

嘿,我一眼就瞅出问题所在了——你没有把着色器里的sampler2D textures[32]数组元素和对应的OpenGL纹理单元(GL_TEXTURE0、GL_TEXTURE1这类)绑定起来。OpenGL默认会把所有未显式赋值的sampler变量都关联到纹理单元0,所以不管你用数组索引1还是其他值,最终采样的都是GL_TEXTURE0上绑定的纹理,这就是为啥所有方块都显示第一张图的原因。

具体修复步骤

1. 关联sampler数组与纹理单元

你需要在CPU端告诉OpenGL:textures[0]对应纹理单元0,textures[1]对应纹理单元1,以此类推。在你的main.cxx里,shader->Enable()之后添加这段代码:

// 获取sampler数组的uniform位置
GLuint textureArrayLoc = glGetUniformLocation(shader->GetProgramID(), "textures");
// 准备数组:索引i对应纹理单元i(GL_TEXTUREi)
GLint textureUnits[32];
for (int i = 0; i < 32; ++i) {
    textureUnits[i] = i;
}
// 将数组传递给着色器
glUniform1iv(textureArrayLoc, 32, textureUnits);

这里假设你的Shader类有GetProgramID()方法能返回着色器程序的ID,如果没有的话,你需要在Shader类里加一个这个方法,或者直接把程序ID存在一个变量里调用。

2. 修复Texture类的参数错误

在texture.cxx的Load方法里,你重复设置了GL_TEXTURE_MIN_FILTER两次:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

这明显是手滑了,第二个应该是GL_TEXTURE_MAG_FILTER(纹理放大过滤),不然放大纹理时的过滤参数没设置,可能会有显示问题:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

3. 确认顶点属性设置(可选但稳妥)

你的vbotid顶点属性设置是正确的,但再确认下:

glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(GLfloat), 0);

步长用sizeof(GLfloat)没问题,因为每个纹理ID都是单独的float,没有额外的填充数据。

为啥之前的调试没找到问题?

  • 你切换GL_TEXTURE0和GL_TEXTURE1时能显示对应纹理,说明纹理加载、绑定到纹理单元的流程是正常的,但sampler数组没和单元关联,所以不管索引多少都取单元0的纹理。
  • 硬编码索引没用,因为数组里的所有元素默认都指向单元0,所以不管你写textures[1]还是textures[31],采样的都是GL_TEXTURE0的纹理。

修改后的main.cxx关键片段

while (!window.ShouldClose()) {
 window.Clear();
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 // *********************************************************************
 shader->Enable();

 // 新增:绑定sampler数组到对应纹理单元
 GLuint textureArrayLoc = glGetUniformLocation(shader->GetProgramID(), "textures");
 GLint textureUnits[32];
 for (int i = 0; i < 32; ++i) {
     textureUnits[i] = i;
 }
 glUniform1iv(textureArrayLoc, 32, textureUnits);

 glActiveTexture(GL_TEXTURE0);
 glBindTexture(GL_TEXTURE_2D, tex1->GetTID());
 glActiveTexture(GL_TEXTURE1);
 glBindTexture(GL_TEXTURE_2D, tex2->GetTID());

 glBindVertexArray(vao);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
 glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, nullptr);
 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
 glBindVertexArray(0);
 // *********************************************************************
 window.Update();
}

这样改完之后,textures[0]就对应GL_TEXTURE0的黄色方块,textures[1]对应GL_TEXTURE1的蓝色方块,你的两个图形就能正常显示不同纹理啦!

内容的提问来源于stack exchange,提问作者Jae D. Nam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 14:52:40