Qt的paintGL函数无法激活多纹理单元,G缓冲采样结果全部相同求助
问题原因及修复方案
1. 采样器Uniform设置无效(核心原因)
Qt的QOpenGLShaderProgram::setUniformValue仅对当前已绑定的着色器程序生效,你在initShaders中完成反射通道着色器链接后,没有先绑定程序就设置采样器对应的纹理单元,导致所有sampler2D uniform默认使用值0,所有采样操作都会读取GL_TEXTURE0单元的纹理,自然三个纹理采样结果完全相同。
修复方法:修改initShaders中反射通道的初始化逻辑:
shaderReflectPass.link(); // 新增:先绑定着色器程序再设置uniform shaderReflectPass.bind(); shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gPosition"), 0); shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gNormal"), 1); shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gColor"), 2);
2. paintGL中纹理绑定错误
你当前paintGL里的纹理绑定和你预设的采样器单元不匹配,且未绑定gPosition纹理:
GL_TEXTURE0对应gPosition,你错误绑定了gColorGL_TEXTURE2对应gColor,你重复绑定了gColor
修复方法:修改paintGL中的纹理绑定逻辑:
// 按采样器单元对应绑定纹理 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gPosition); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, gNormal); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, gColor);
3. 几何通道渲染逻辑错误
你目前仅在initializeGL中渲染一次几何数据到FBO,且渲染完成后没有解绑FBO,后续重绘、窗口 resize 时数据会丢失,且会渲染到离屏FBO而非窗口默认帧缓冲。
修复方法:将几何通道渲染逻辑挪到paintGL最前面,每次重绘先更新G缓冲数据,再做后期处理:
void fboTest::paintGL() { // ------------ 几何通道:渲染到G缓冲 ------------ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glEnable(GL_DEPTH_TEST); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); shaderGeoPass.bind(); QMatrix4x4 model; QMatrix4x4 view; QMatrix4x4 projection; view.lookAt({0, 0, 3}, {0, 0, 0}, {0, 1, 0}); projection.perspective(45.0f,static_cast<float>(SCR_WIDTH)/static_cast<float>(SCR_HEIGHT),0.1f,100.0f); // 渲染两个立方体 glBindVertexArray(cubeVAO); model.translate(QVector3D(-1.0f, 0.0f, -1.0f)); shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model); shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("view"), view); shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("projection"), projection); glDrawArrays(GL_TRIANGLES, 0, 36); model.setToIdentity(); model.translate(QVector3D(2.0f, 0.0f, 0.0f)); shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model); glDrawArrays(GL_TRIANGLES, 0, 36); // 渲染地面 glBindVertexArray(planeVAO); model.setToIdentity(); shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model); glDrawArrays(GL_TRIANGLES, 0, 6); // ------------ 后期通道:渲染到窗口默认帧缓冲 ------------ glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject()); glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 绑定G缓冲纹理 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, gPosition); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, gNormal); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, gColor); shaderReflectPass.bind(); glBindVertexArray(quadVAO); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }
同时删除initializeGL中原来的几何渲染相关代码,仅保留初始化逻辑即可。
内容的提问来源于stack exchange,提问作者laser_zd
相关产品推荐
相关产品推荐

