0

I have been working on a render and it has been working OK for one texture but would not render a second. I seemed to have changed something and it stopped rendering anything but the background color. I am not sure what I changed and I cannot get it back to the way it was. I try not to post lots of code at once onto here but I do not know enough OpenGL to isolate the issue. If you can offer any help or hints, I would greatly appreciate it!

My guess is that it is either coming from the way I am binding the coordinate or the shader.

The following is the code:

Shaders:

       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);
                    }";

Vertexes:

    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)
    };

Shader setup:

        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);

Basic setup and binding:

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);

Loading and binding the texture:

        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);

Matrix Setup:

        //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);

Rendering

        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();
Serguei Fedorov
  • 7,763
  • 9
  • 63
  • 94
  • Two is for the size parameter. The vertexes are composed on Vector2, or 2 float coordinates. Am I understanding this correctly? – Serguei Fedorov Sep 08 '13 at 02:12
  • Yes, that is correct. I misread the API call, because I was too busy trying to figure out where `textureHandle` was defined (it was in a different code snippet). But the problem remains that you are using `attribute` when that is invalid in GLSL 330, use `in`. – Andon M. Coleman Sep 08 '13 at 02:16

1 Answers1

1

You are using the old attribute qualifier to declare texcoord in your vertex shader. This is invalid in GLSL 330, and I suspect if you read the program/shader info logs when you compile/link your GLSL program it includes this information in the log.

To correct this, replace attribute vec2 texcoord with in vec2 texcoord. Then you should get a valid location when you query the attribute location, which is required to set your vertex attribute pointer correctly.

varying is also invalid in GLSL 330. You need to declare f_texcoord as out in your vertex shader and in in your fragment shader for your program to properly link.

There is no error detecting code at all in your code listings. You should read the manual pages for glValidateProgram (...), glGetProgramInfoLog (...) and glGetShaderInfoLog (...), because I am pretty sure the GLSL compiler would have told you your exact problem if you read its output log.

Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • Hmmm, this does not solve my issue unfortunately unless I am miss understanding you. I have replaced the "attribute" with "in". The query is successful returning 1. I have traced the logs, by using: GL.GetShaderInfoLog(vertexShaderHandle); which returns nothing unfortunately... hmmm. Maybe my buffers are not being properly binding? – Serguei Fedorov Sep 08 '13 at 02:29
  • 1
    @SergueiFedorov: I should add to that that `varying` is also invalid. Replace `varying vec2 f_texcoord` with `out vec2 f_texcoord` in your vertex shader and `in vec2 f_texcoord` in your fragment shader. – Andon M. Coleman Sep 08 '13 at 02:31
  • Thank you for pointing out the invalid commands. I am fairly new to this and it seems like tutorials are a bit scattered as far as the shaders go. – Serguei Fedorov Sep 08 '13 at 02:33
  • Could it be that something to do with the sprite rendering off the screen? Hmmm... – Serguei Fedorov Sep 08 '13 at 02:37
  • 1
    @SergueiFedorov: That is a possibility too. Without knowing what you changed the only thing I can do is point out parts of your shaders that are invalid and hope they are to blame... version control would help a lot in the future if you change things you do not completely understand (e.g. if you make modifications from a working tutorial). A diff would pinpoint exactly where to focus your search. – Andon M. Coleman Sep 08 '13 at 02:44
  • Thanks a lot for your help! I found the issue; the issue is that the sprite was very small and scaled against the projection did not render. The issue now is that I when I try to render multiple sprites, they render in different locations (if I add vec4(pos, 0, 1) to the position), but they are flickering and disappearing... Thanks to you I have both the textures rendering now though with a slight issue – Serguei Fedorov Sep 08 '13 at 02:49