Fragmentshader和framebuffer纯色

时间:2013-05-25 11:49:50

标签: c# glsl framebuffer opentk fragment-shader

亲爱的Stackoverflowers,

最近我一直在着色器世界里迈出第一步,在C#和OpenTK中使用GLSL和openGL,我偶然发现了一些我似乎无法解决的问题。

我开始使用一个着色器程序和一些快速实验着色器,它们工作得很好,给我以下结果(只是一个环绕三角形的绿色和红色光):

然后我想为此添加某种发光,我听说你必须通过将片段着色器应用于纹理来实现这一点。 所以我开始将场景渲染到帧缓冲区。然后我绑定了framebuffer纹理并画了一个四边形。这向我展示了我之前的相同场景,这意味着它有效。然后使用新的碎片器我在写入缓冲区之后和写入四元组之前用我的新程序替换了我的第一个着色器程序。现在的问题是,无论我做什么,屏幕只提供一种纯色,而不是像我想的那样进行任何操作。

这是我的绘图代码:

    protected override void OnRenderFrame(FrameEventArgs e)
    {
        GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, fboID);
        GL.UseProgram(shaderProgramHandle);
        GL.PushAttrib(AttribMask.ViewportBit);
        {
            GL.Viewport(0, 0, 600, 600);

            // clear the screen in green, to make it very obvious what the clear affected. only the FBO, not the real framebuffer
            GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);

            GL.PushAttrib(AttribMask.ColorBufferBit);

            // make sure no lingering textures are bound to draw vertices clearly.
            GL.BindTexture(TextureTarget.Texture2D, 0);

            GL.EnableVertexAttribArray(0);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0);
            GL.DrawArrays(BeginMode.Triangles, 0, 3);

            GL.DisableVertexAttribArray(0);

            GL.Begin(BeginMode.Points);
            GL.Vertex3(lmp);
            GL.Vertex3(lmp2);
            GL.End();

            GL.PopAttrib();
        }
        GL.PopAttrib();

        GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

        angle += 0.01f;
        angle2 -= 0.017f;
        lmp = new Vector3((float)(2f * Math.Cos(angle)), (float)(Math.Sin(angle) * 2f), 0f);
        lmp2 = new Vector3((float)(2f * Math.Cos(angle2)), (float)(Math.Sin(angle2) * 2f), 0f);
        GL.Uniform3(uniformLmp, lmp);
        GL.Uniform3(uniformLmp2, lmp2);

        GL.UseProgram(secondProgram);
        GL.Enable(EnableCap.Texture2D);
        GL.ActiveTexture(TextureUnit.Texture0);
        GL.BindTexture(TextureTarget.Texture2D, fboTex);
        GL.Uniform1(GL.GetUniformLocation(secondProgram, "tex"), fboTex);

        GL.Clear(ClearBufferMask.ColorBufferBit);

        GL.Begin(BeginMode.TriangleStrip);

        GL.TexCoord2(.0f, .0f);
        GL.Vertex3(-1f, -1f, 0f);

        GL.TexCoord2(1.0f, .0f);
        GL.Vertex3(1f, -1f, 0f);

        GL.TexCoord2(.0f, 1.0f);
        GL.Vertex3(-1f, 1f, 0f);

        GL.TexCoord2(1.0f, 1.0f);
        GL.Vertex3(1f, 1f, 0f);

        GL.End();
        GL.Disable(EnableCap.Texture2D);
        GL.UseProgram(0);

        SwapBuffers();
    }

这些是我的着色器:

//vertex shader
#version 330

layout (location = 0) in vec3 Position;
varying vec2 texCoord;

void main()
{
    gl_Position = vec4(Position.x, Position.y, Position.z, 1.0);
    texCoord = gl_TexCoord[0].st;
}

//fragment shader
#version 330

uniform sampler2D tex;
out vec4 FragColor;
varying vec2 texCoord;

void main()
{
    vec4 color = texture2D(tex, texCoord);
    color.r += 0.5f;
    FragColor = color;
}

这会产生纯红色,而不是使现有图像呈现红色。

有人能在这里发现问题吗?

1 个答案:

答案 0 :(得分:0)

事实证明我忘记了

GL.EnableClientState(ArrayCap.TextureCoordArray);

这意味着我的UV坐标不会传递到着色器,因此只需从(0,0)进行采样,解释了这种奇怪的行为。