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

GLES3多纹理异常:仅GL_TEXTURE0纹理可绘制问题求助

GLES3多纹理仅GL_TEXTURE0生效问题解决方案

核心问题

你在设置sampler2D类型的uniform时,错误使用了glUniform1ui(无符号整数),而GLSL中采样器要求有符号整数赋值,类型不匹配触发OpenGL错误,导致采样器始终默认使用0号纹理槽。

修复步骤

1. 替换uniform设置的函数

将所有针对sampler2D的glUniform1ui调用替换为glUniform1i:

  • 修改初始化代码中的行B:
    // 原错误代码
    // GLES30.glUniform1ui(locc, 1);
    // 改为
    GLES30.glUniform1i(locc, 1);
    
  • 更新ShaderProgram中的uniform设置方法(新增/修改为有符号整数版本):
    void setUniform1i(String name, int data) {
        int locc = GLES30.glGetUniformLocation(id, name);
        if (locc == -1){
            Log.e("UniformError", "Uniform not found: " + name);
        }
        GLES30.glUniform1i(locc, data);
    }
    
  • 调用时使用这个新方法:
    shader.setUniform1i("m_texture", ts2.slot);
    

2. 确保纹理激活与绑定的正确性

在绘制前重新绑定纹理(避免其他操作覆盖绑定状态),修改Texture类的activeToShader方法:

public void activeToShader(ShaderProgram sp, String nume){
    GLES30.glActiveTexture(GLES30.GL_TEXTURE0 + slot);
    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, id[0]); // 补充绑定步骤
    sp.setUniform1i(nume, slot);
}

验证方式

修改后初始化纹理到槽1并调用激活方法:

ts2 = new Texture(getBaseContext(), "apple.png", 1);
ts2.activeToShader(shader, "m_texture");

此时片段着色器就能正确采样槽1中的纹理,不会再出现黑屏。

关键规范说明

  • OpenGL明确要求:sampler2D等采样器类型的uniform,必须通过glUniform1i/glUniform1iv设置,因为采样器索引是有符号整数类型,无符号整数赋值会触发GL_INVALID_OPERATION错误(也就是你用glGetError查到的问题)。
  • 你测试的thing是float类型,用setUniform1ui能生效是因为OpenGL做了隐式类型转换,但采样器类型不支持这种转换,必须严格匹配。

内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 22:05:55