OpenGL - 绑定不同的FBO时访问立方体贴图

时间:2016-07-31 15:30:23

标签: c# opengl glsl opentk

我将阴影贴图实现从前向渲染切换到延迟渲染时遇到困难。我找到了问题,并且没有将立方体图发送到着色器。我怀疑这是因为我的“GBuffer”FBO被绑定而不是立方体贴图FBO。

如果GLSL可以在一次抽奖通话中访问两个不同FBO的彩色附件,我想走那条路,这可能吗?

下面是工作转发渲染代码。

int maxValue(double[][] arr, int row, int col) {
    if (outOfBounds) return 0; 

    int value = arr[row][col];
    int leftDiag = maxValue(arr, row +1,col - 1);
    int rightDiag = maxValue(arr, row + 1, col + 1);
    return value + Math.max(leftDiag, rightDiag);
} 

在这里,失败的延迟渲染修改

public void NormalPass(Shader shader)
{
    // Reset state
    GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
    GL.BindTexture(TextureTarget.Texture2D, 0);

    GL.UseProgram(shader.ID);
    GL.Viewport(0, 0, Width, Height);
    GL.CullFace(CullFaceMode.Back);
    GL.ClearColor(0.5f, 0.5f, 0.5f, 1f);

    // Uniforms
    Matrix4 viewMatrix = player.GetViewMatrix();
    Matrix4 projectionMatrix;
    Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, (float)Width / (float)Height, 0.1f, 100.0f, out projectionMatrix);
    GL.UniformMatrix4(shader.viewMatrixLocation, false, ref viewMatrix); 
    GL.UniformMatrix4(shader.projectionMatrixLocation, false, ref projectionMatrix);
    GL.Uniform3(shader.lightPositionLocation, lightPos);

    GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);
    DrawScene(shader, false);                               // False = Not shadowpass
    GL.BindTexture(TextureTarget.TextureCubeMap, 0);
}

很高兴根据要求提供更多信息。

1 个答案:

答案 0 :(得分:2)

  

如果GLSL可以在一次抽奖通话中访问两个不同FBO的彩色附件,我想走那条路,这可能吗?

这个问题表明对正在发生的事情缺乏了解。 GLSL访问纹理,而不是FBO的颜色附件。

现在显然,纹理可以用作颜色附件。但区别很重要,因为无论如何,GLSL都在访问绑定纹理,而不是FBO中的任何内容。

OpenGL关于从作为颜色附件附加到FBO的纹理读取的唯一规则是:只要这些纹理实际上没有附加到渲染命令期间作为活动绘制帧缓冲区的特定帧缓冲区,它就会起作用。即便如此,OpenGL will only care if you break the feedback loop rules

因此,您对读取帧缓冲区的绑定毫无意义。这不是让纹理可供阅读或某些东西;这不是读取帧缓冲区绑定点的用途。它仅用于framebuffer reading commandsframebuffer blitting operations

所以简单地将默认帧缓冲区绑定到FramebufferTarget.Framebuffer,就像你在前进案例中所做的那样,一切都会好的。

你的主要问题是:

GL.BindTexture(TextureTarget.TextureCubeMap, cubeTex);

您没有使用glActiveTexture指定将该立方体贴图绑定到的纹理单元。这意味着它将使用您设置的最后一个纹理单元:TextureUnit.Texture1,并且您已经在那里绑定了一个2D纹理。在GLSL中从同一纹理单元读取两种不同类型的两种纹理是非法的。

所以很有可能这不是你的意思。在任何glActiveTexture来电之前,始终使用glBindTexture。除非您使用glBindTextures from GL 4.4/ARB_multibindglBindTextureUnit from GL 4.5/ARB_DSA