纹理单位重叠?渲染了错误的纹理
Texture units overlap? Rendered the wrong texture
我想在我的片段着色器中使用 4 个纹理。一个是立方体贴图,一个是帧缓冲区上的渲染纹理,最后两个是从图像创建的。
当我尝试在我的片段着色器中调用它们时,无论我调用哪个着色器,我都会得到一个与我调用的着色器不同的着色器或相同的一个(取决于我尝试修复它时所做的不同迭代(。
这就是我得到它的方式
GLuint FramebufferName = 0;
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
GLuint renderedTexture;
glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);
GLenum DrawBuffers[1]={GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, DrawBuffers);
if ( glCheckFramebufferStatus ( GL_FRAMEBUFFER ) == GL_FRAMEBUFFER_COMPLETE )
{
glViewport(0, 0, 1024, 1024);
glClearColor( 0.4f, 0.4f, 0.4f, 1.0f );
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
ngl::ShaderLib* shader = ngl::ShaderLib::instance();
(*shader)["Normal"]->use();
m_transform.setPosition(0.0f, 0.0f, 0.0f);
loadMatricesToShader();
//drawing the quad
prim->draw("tex");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0,0,1024,768);
// grab an instance of the shader manager
ngl::ShaderLib* shader = ngl::ShaderLib::instance();
( *shader )[ "PBR" ]->use();
glUniform1i(renderedTexture, 1);
//initialize environment map
initEnvironment();
initTexture(2, m_glossMapTex, "images/gloss.png");
glUniform1i(m_glossMapTex, 2);
initTexture(3, m_textMap, "images/alege.png");
glUniform1i(m_textMap, 3);
还有 initTexture 和 initEnvironment
void NGLScene::initTexture(const GLuint& texUnit, GLuint &texId, const char *filename) {
glActiveTexture(GL_TEXTURE0 + texUnit);
// Load up the image using NGL routine
ngl::Image img(filename);
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexImage2D (
GL_TEXTURE_2D,
0,
img.format(),
img.width(),
img.height(),
0,
GL_RGB,
GL_UNSIGNED_BYTE,
img.getPixels());
// Set up parameters for our texture
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
void NGLScene::initEnvironment() {
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
glActiveTexture (GL_TEXTURE0);
glGenTextures (1, &m_envTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_envTex);
initEnvironmentSide(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, "images/sky_zneg.png");
initEnvironmentSide(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, "images/sky_zpos.png");
initEnvironmentSide(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, "images/sky_ypos.png");
initEnvironmentSide(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, "images/sky_yneg.png");
initEnvironmentSide(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, "images/sky_xneg.png");
initEnvironmentSide(GL_TEXTURE_CUBE_MAP_POSITIVE_X, "images/sky_xpos.png");
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_AUTO_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLfloat anisotropy;
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropy);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
// Set our cube map texture to on the shader so we can use it
ngl::ShaderLib *shader=ngl::ShaderLib::instance();
shader->use("PBR");
shader->setUniform("envMap", 0);
}
void NGLScene::initEnvironmentSide(GLenum target, const char *filename) {
// Load up the image using NGL routine
ngl::Image img(filename);
glTexImage2D (
target,
0,
img.format(),
img.width(),
img.height(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
img.getPixels()
);
}
我觉得我对纹理单位和制服设置的了解存在差距,或者我的片段着色器中的制服可能有问题。
在你的代码中有一个误解,即如何使用glUniform1i
。如果将值分配给制服,则必须通过制服位置索引标识制服。参见制服 (GLSL(
glUniform1i
的第一个参数必须是制服的位置,而不是命名的纹理对象。
制服的位置可以通过布局限定符在着色器中显式设置
例如
GLSL
layout(location = 7) uniform sampler2D u_gloss;
C++
initTexture(2, m_glossMapTex, "images/gloss.png");
glUniform1i(7, 2); // uniform location 7
如果制服的位置不是由布局限定符设置的,则在链接程序时会自动设置制服位置。您可以通过以下方式询问此位置glGetUniformLocation
:
例如
GLSL
uniform sampler2D u_gloss;
C++
GLuint program_obj = ... ; // ( *shader )[ "PBR" ]->???
GLint gloss_location = glGetUniformLocation(program_obj , "u_gloss");
initTexture(2, m_glossMapTex, "images/gloss.png");
glUniform1i(gloss_location, 2);
相关文章:
- 警告处理为错误这里有什么问题
- OpenGL 4.3 错误地将第 4 个纹理坐标映射到与第 3 个纹理坐标相同的位置
- 纹理单位重叠?渲染了错误的纹理
- 是什么导致 glTexSubImage1D() - 加载纹理时在此示例中出现GL_INVALID_VALUE错误?
- GL_INVALID_VALUE错误生成.纹理尺寸无效.在立方体贴图纹理 427*240*6 上
- 3D 纹理大小会影响程序输出,而不会引发错误
- OpenGL 透视投影裁剪多边形与顶点在视锥体之外 = 错误的纹理映射?
- 如何在OpenGL中使用纹理?(无效操作错误:1282)
- OpenGL3显示错误的纹理
- OpenCL/OpenGL 互操作性纹理段错误
- 利用Devil将纹理分段错误加载到OpenGL中
- 将RGBA32F纹理与帧缓冲抛出INVALID_ENUM错误一起使用
- Qt 5 OpenGL绑定纹理导致奇怪的错误
- 直接 X 11 纹理 FX 文件错误 X3004 未声明标识符"input"
- OpenGL纹理触发错误1281和奇怪的背景行为
- 加载纹理文件时出现分割错误"big"
- 碎片着色器的纹理值错误
- OpenGL -纹理使用glDrawElements被错误地映射
- c++ OpenGL错误的Collada纹理坐标
- OpenGL多重纹理加载错误