【问题标题】:OpenGL 2d sprite not rendering (OpenTK)OpenGL 2d sprite 未渲染 (OpenTK)
【发布时间】:2013-09-08 10:34:12
【问题描述】:

我一直在进行渲染,它对一个纹理工作正常,但不会渲染第二个。我似乎改变了一些东西,它停止渲染除了背景颜色之外的任何东西。我不确定我改变了什么,我无法恢复原来的样子。我尽量不要一次在这里发布大量代码,但我不知道足够多的 OpenGL 来隔离问题。如果您能提供任何帮助或提示,我将不胜感激!

我的猜测是它要么来自我绑定坐标的方式,要么来自着色器。

以下是代码:

着色器:

       string vertexShaderSource = @"
                        #version 330

                        layout (location = 0) in vec3 Position;

                        uniform mat4 projectionmatrix;
                        uniform mat4 ModelMatrix;
                        uniform mat4 ViewMatrix;

                        attribute vec2 texcoord;
                        varying vec2 f_texcoord;

                        uniform vec2 pos;

                        void main()
                        {
                            f_texcoord = texcoord;
                            gl_Position = projectionmatrix * vec4(Position, 1);

                            //gl_Position = projectionmatrix * vec4(Position.xyz, 1.0);
                        }
                    ";

    string fragmentShaderSource = @"
                    #version 330

                    out vec4 FragColor;

                    varying vec2 f_texcoord;
                    uniform sampler2D mytexture;

                    void main()
                    {
                        FragColor = texture2D(mytexture, f_texcoord);
                        //FragColor = Vec4(0,0,0, 1);
                    }";

顶点:

    Vector2[] g_vertex_buffer_data ={
            new Vector2(-1.0f, 1.0f),
            new Vector2(1.0f, 1.0f),
            new Vector2(1.0f, -1.0f),
            new Vector2(-1.0f, -1.0f)
    };


    Vector2[] g_texture_coords = {
            new Vector2(0.0f, 0.0f),
            new Vector2(1.0f, 0.0f),
            new Vector2(1.0f, -1.0f),
            new Vector2(0.0f, -1.0f)
    };

着色器设置:

        shaderProgramHandle = GL.CreateProgram();

        vertexShaderHandle = GL.CreateShader(ShaderType.VertexShader);
        fragmentShaderHandle = GL.CreateShader(ShaderType.FragmentShader);

        GL.ShaderSource(vertexShaderHandle, vertexShaderSource);
        GL.ShaderSource(fragmentShaderHandle, fragmentShaderSource);

        GL.CompileShader(vertexShaderHandle);
        GL.CompileShader(fragmentShaderHandle);

        GL.AttachShader(shaderProgramHandle, vertexShaderHandle);
        GL.AttachShader(shaderProgramHandle, fragmentShaderHandle);

        GL.LinkProgram(shaderProgramHandle);
        GL.UseProgram(shaderProgramHandle);

基本设置和绑定:

GL.ClearColor(Color4.Red);

        //GL.LoadMatrix(ref projectionMatrix);

        GL.GenBuffers(2, out vertexbuffer);

        GL.BindBuffer(BufferTarget.ArrayBuffer, vertexbuffer);

        GL.BufferData<Vector2>(BufferTarget.ArrayBuffer,
                               new IntPtr(g_vertex_buffer_data.Length * Vector2.SizeInBytes),
                               g_vertex_buffer_data, BufferUsageHint.StaticDraw);

        //Shader Setup
        CreateShaders();

        Matrix4 projectionMatrix = Matrix4.CreateOrthographic(control.Width, control.Height, -1, 1);

        vertexShaderProjectionHandle = GL.GetUniformLocation(shaderProgramHandle, "projectionmatrix");
        GL.UniformMatrix4(vertexShaderProjectionHandle, false, ref projectionMatrix);

        GL.EnableVertexAttribArray(0);
        GL.BindBuffer(BufferTarget.ArrayBuffer, vertexbuffer);
        GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, 0);

加载和绑定纹理:

        GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
        GL.Enable(EnableCap.Blend);

        GL.ActiveTexture(TextureUnit.Texture0 + texture.textureID);
        GL.BindTexture(TextureTarget.Texture2D, texture.textureID);

        textureHandle = GL.GetAttribLocation(shaderProgramHandle, "texcoord");

        GL.GenBuffers(1, out textureBufferHandle);
        GL.BindBuffer(BufferTarget.ArrayBuffer, textureBufferHandle);
        GL.BufferData<Vector2>(BufferTarget.ArrayBuffer, new IntPtr(Vector2.SizeInBytes * 4), g_texture_coords, BufferUsageHint.StaticDraw);

矩阵设置:

        //rotation += MathHelper.DegreesToRadians(1);

        float displayRatio = ((float)control.Height / (float)control.Width);

        Matrix4 ViewMatrix = Matrix4.Identity;

        int ViewMatrixHandle = GL.GetUniformLocation(shaderProgramHandle, "ViewMatrix");
        GL.UniformMatrix4(ViewMatrixHandle, true, ref ViewMatrix);

        Matrix4 ModelMatrix = Matrix4.Identity;

        int modelMatrixHandle = GL.GetUniformLocation(shaderProgramHandle, "ModelMatrix");
        GL.UniformMatrix4(modelMatrixHandle, true, ref ModelMatrix);


        int posHandle = GL.GetUniformLocation(shaderProgramHandle, "pos");
        GL.Uniform2(posHandle, ref offset);

渲染

        GL.Viewport(0, 0, control.Width, control.Height);

        //GL.Enable(EnableCap.Texture2D);

        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

        GL.BindVertexArray(0);

        GL.EnableVertexAttribArray(textureHandle);
        GL.BindBuffer(BufferTarget.ArrayBuffer, textureBufferHandle);

        GL.VertexAttribPointer(textureHandle, 2, VertexAttribPointerType.Float, false, 0, 0);

        GL.DrawArrays(BeginMode.Quads, 0, 4);

        GL.Flush();
        control.SwapBuffers();

【问题讨论】:

  • 两个用于大小参数。顶点由 Vector2 或 2 个浮点坐标组成。我理解正确吗?
  • 是的,没错。我误读了 API 调用,因为我正忙于弄清楚 textureHandle 的定义位置(它在不同的代码 sn-p 中)。但是问题仍然存在,当您使用 attribute 在 GLSL 330 中无效时,请使用 in

标签: c# opengl graphics opentk


【解决方案1】:

您正在使用旧的attribute 限定符在顶点着色器中声明texcoord。这在 GLSL 330 中无效,我怀疑如果您在编译/链接 GLSL 程序时阅读程序/着色器信息日志,它会在日志中包含此信息。

要更正此问题,请将attribute vec2 texcoord 替换为in vec2 texcoord。那么你在查询属性位置时应该会得到一个有效的位置,这是正确设置你的顶点属性指针所必需的。

varying 在 GLSL 330 中也是无效的。您需要在顶点着色器中将 f_texcoord 声明为 out,在片段着色器中声明 in,以便您的程序正确链接。

您的代码清单中根本没有错误检测代码。你应该阅读glValidateProgram (...)glGetProgramInfoLog (...)glGetShaderInfoLog (...) 的手册页,因为我很确定如果你阅读它的输出日志,GLSL 编译器会告诉你确切的问题。

【讨论】:

  • 嗯,不幸的是,这并不能解决我的问题,除非我想念你。我已将“属性”替换为“in”。查询成功返回 1。我使用以下方法跟踪了日志: GL.GetShaderInfoLog(vertexShaderHandle);不幸的是,它什么也没返回……嗯。也许我的缓冲区没有正确绑定?
  • @SergueiFedorov:我应该补充一点,varying 也是无效的。在顶点着色器中将varying vec2 f_texcoord 替换为out vec2 f_texcoord,在片段着色器中替换为in vec2 f_texcoord
  • 感谢您指出无效命令。我对此相当陌生,就着色器而言,教程似乎有点分散。
  • 这可能与屏幕上的精灵渲染有关吗?嗯...
  • @SergueiFedorov:这也是一种可能。在不知道你改变了什么的情况下,我唯一能做的就是指出你的着色器部分是无效的,并希望他们受到指责......如果你改变你不完全理解的东西(例如如果您从工作教程中进行修改)。差异将准确指出您的搜索重点。
猜你喜欢
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
  • 2019-04-02
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多