纹理采样器ID未映射到纹理单元

时间:2016-11-12 16:51:06

标签: opengl textures soil

我正在尝试在模型上使用3个纹理。我正在使用SOIL加载图像并将它们绑定到纹理单元1,2和3.但由于某些原因,当我将采样器1,2和3绑定到我的着色器时,1会生成绑定到GL_TEXTURE2的图像而2和3产生绑定到GL_TEXTURE3的图像。我在这里错过了一些简单的东西吗?

说明:

GLenum baseTextureUnitID = GL_TEXTURE1;
GLenum filterTextureUnitID = GL_TEXTURE2;
GLenum accentTextureUnitID = GL_TEXTURE3;
GLuint baseTextureSamplerValue = 1;
GLuint filterTextureSamplerValue = 2;
GLuint accentTextureSamplerValue = 3;

载入图片:

baseTextureID = SOIL_load_OGL_texture(baseImageFile,
    SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);
glActiveTexture(baseTextureUnitID);
glBindTexture(GL_TEXTURE_2D, baseTextureID);

filterTextureID = SOIL_load_OGL_texture(filterImageFile,
    SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);
glActiveTexture(filterTextureUnitID);
glBindTexture(GL_TEXTURE_2D, filterTextureID);

accentTextureID = SOIL_load_OGL_texture(accentImageFile,
    SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);
glActiveTexture(accentTextureUnitID);
glBindTexture(GL_TEXTURE_2D, accentTextureID);

获得统一的位置:

baseTextureSamplerID = glGetUniformLocation(shaderProgram, "baseTex");
filterTextureSamplerID = glGetUniformLocation(shaderProgram, "filterTex");
accentTextureSamplerID = glGetUniformLocation(shaderProgram, "accentTex");

设置制服:

glUniform1i(baseTextureSamplerID, baseTextureSamplerValue);
glUniform1i(filterTextureSamplerID, filterTextureSamplerValue);
glUniform1i(accentTextureSamplerID, accentTextureSamplerValue);

现在,如果我从baseTex中采样,我会得到滤镜Image,而filterTex和accentTex采样器会产生重音图像

2 个答案:

答案 0 :(得分:3)

您的问题在于加载纹理时的调用顺序。 SOIL_load_OGL_texture()将更改您当前的纹理绑定。它必须,因为它需要绑定新创建的纹理,以便它可以将数据加载到它。

只是想象一下你的代码序列中会发生什么:

glActiveTexture(baseTextureUnitID);
glBindTexture(GL_TEXTURE_2D, baseTextureID);

此时,baseTextureID绑定到预期的纹理单元。但下一行是:

filterTextureID = SOIL_load_OGL_texture(filterImageFile, ...);

在此调用中,新创建的纹理将绑定到当前纹理单元,该纹理单元是您计划用于基础纹理的单元。这就是在加载所有纹理时绑定了错误纹理的原因。

解决这个问题很简单。只需更改图像加载代码中调用的顺序,首先加载所有纹理,然后建立所有绑定:

baseTextureID = SOIL_load_OGL_texture(baseImageFile,
    SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);
filterTextureID = SOIL_load_OGL_texture(filterImageFile,
    SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);
accentTextureID = SOIL_load_OGL_texture(accentImageFile,
    SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y);

glActiveTexture(baseTextureUnitID);
glBindTexture(GL_TEXTURE_2D, baseTextureID);

glActiveTexture(filterTextureUnitID);
glBindTexture(GL_TEXTURE_2D, filterTextureID);

glActiveTexture(accentTextureUnitID);
glBindTexture(GL_TEXTURE_2D, accentTextureID);

答案 1 :(得分:-2)

我找到了解决这个问题的方法。当像我一样使用多个纹理时,你必须激活纹理单元,并在为采样器调用glUniform1i之前再次绑定纹理。

设置制服时,格式正确为:

glActiveTexture(baseTextureUnitID);
glBindTexture(GL_TEXTURE_2D, baseTextureID);
glUniform1i(baseTextureSamplerID, baseTextureSamplerValue);

glActiveTexture(filterTextureUnitID);
glBindTexture(GL_TEXTURE_2D, filterTextureID);
glUniform1i(filterTextureSamplerID, filterTextureSamplerValue);

glActiveTexture(accentTextureUnitID);
glBindTexture(GL_TEXTURE_2D, accentTextureID);
glUniform1i(accentTextureSamplerID, accentTextureSamplerValue);