无法渲染到绑定到帧缓冲区的纹理

时间:2017-08-01 06:32:02

标签: c# opengl framebuffer opentk

我正在尝试设置渲染管道,因此,我正在尝试将渲染设置为纹理,以便稍后可以对其进行采样以进行模糊等。

我有一个顶点着色器,如下所示:

#version 400

//Heyy renderpasses
subroutine void RenderPass();
subroutine uniform RenderPass currentPass;

in vec3 ex_normal;
in vec3 ex_color;
in vec4 ShadowCoord;
in vec3 lightDir_cameraspace;
in vec3 normal_cameraspace;

layout(location=0) out vec4 color;
layout(location=1) out float depth;

uniform vec3 light_pos;
uniform sampler2D shadowMap;

void main()
{
    //Bootstrap for render pass
    currentPass();
}

//Render passes

subroutine(RenderPass)
void Default()
{
    //Config
    vec3 lightColor = vec3(1.0, 1.0, 1.0);
    float lightIntensity = 1.0;
    vec3 diffuseColor = ex_color;

    vec3 n = normalize( normal_cameraspace );
    // Direction of the light (from the fragment to the light)
    vec3 l = normalize( lightDir_cameraspace );

    float cosTheta = clamp( dot( n,l ), 0,1 );
    vec3 ambientLight = vec3(0.2, 0.2, 0.2);
    vec3 lightSum = ambientLight;
    float visibility = 1.0;
    float shadowSample = texture( shadowMap, ShadowCoord.xy ).z;

    float bias = 0.005*tan(acos(cosTheta)); // cosTheta is dot( n,l ), clamped between 0 and 1
    bias = clamp(bias, 0,0.01);

    if ( shadowSample  <  ShadowCoord.z-bias){ 
        visibility = 0.3;
    }

    color = vec4(ambientLight + (diffuseColor*visibility*lightColor*lightIntensity/*cosTheta*/), 1.0);

}

subroutine(RenderPass)
void Diffuse()
{
    color = vec4(ex_color, 1.0);
    depth = gl_FragCoord.z;
}

subroutine(RenderPass)
void Depth()
{
    depth = gl_FragCoord.z;
}

这在渲染到窗口/帧缓冲区0时工作正常。但是,当尝试渲染到自定义设置帧缓冲区时,为了方便起见,我已将其包装在类中:

    private GameWindow _gameWindow;
    private Texture _texture;
    private int _framebufferId;

    public Framebuffer(GameWindow window)
    {
        _gameWindow = window;

        _framebufferId = GL.GenFramebuffer();
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, _framebufferId);

        _texture = new Texture(GL.GenTexture());
        GL.BindTexture(TextureTarget.Texture2D, _texture.Handle);
        GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, window.Width, window.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)0);

        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);

        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);

        GL.FramebufferTexture(FramebufferTarget.DrawFramebuffer, FramebufferAttachment.ColorAttachment0, _texture.Handle, 0);

        GL.DrawBuffers(1, new DrawBuffersEnum[] { DrawBuffersEnum.ColorAttachment0 });

        GL.DrawBuffer(DrawBufferMode.None);

        if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
            throw new Exception("Framebuffer creation failed");
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
    }

    public Texture Texture
    {
        get
        {
            return _texture;
        }
    }

    public void BeginDraw()
    {
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, _framebufferId);
        GL.Viewport(0, 0, _gameWindow.Width, _gameWindow.Height);
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
    }
    public void EndDraw()
    {
        GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
    }

纹理最终变黑。我误解了一些关于将颜色数据传递到纹理中的事情吗?

1 个答案:

答案 0 :(得分:1)

正确设置帧缓冲区并正确设置颜色附件和绘图缓冲区,但是指定了使用DrawBufferMode.None绘制的颜色缓冲区。

删除此行:

GL.DrawBuffer(DrawBufferMode.None);

注意,由于绑定了帧缓冲区GL.DrawBuffer将指定绑定帧缓冲区的颜色缓冲区。

问题What does GL_COLOR_ATTACHMENT do? 的接受答案是:

  

默认值为GL_COLOR_ATTACHMENT0。

因此,您可以完全跳过指定颜色缓冲区。