2D-спрайт OpenGL не отображается (OpenTK)

Я работал над рендерингом, и он работал нормально для одной текстуры, но не отображал вторую. Кажется, я что-то изменил, и он перестал отображать что-либо, кроме цвета фона. Я не уверен, что я изменил, и я не могу вернуть его таким, каким он был. Я стараюсь не публиковать здесь сразу много кода, но я недостаточно знаю 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();

person Serguei Fedorov    schedule 08.09.2013    source источник
comment
Два для параметра размера. Вершины состоят из Vector2 или 2 координат с плавающей запятой. Я правильно это понимаю?   -  person Serguei Fedorov    schedule 08.09.2013
comment
Да, это правильно. Я неправильно понял вызов API, потому что был слишком занят, пытаясь выяснить, где было определено textureHandle (это было в другом фрагменте кода). Но проблема остается в том, что вы используете attribute, когда это недопустимо в GLSL 330, используйте in.   -  person Andon M. Coleman    schedule 08.09.2013


Ответы (1)


Вы используете старый квалификатор attribute для объявления texcoord в вершинном шейдере. Это недопустимо в GLSL 330, и я подозреваю, что если вы читаете журналы информации о программе/шейдере, когда вы компилируете/связываете свою программу GLSL, она включает эту информацию в журнал.

Чтобы исправить это, замените attribute vec2 texcoord на in vec2 texcoord. Затем вы должны получить действительное местоположение при запросе местоположения атрибута, которое требуется для правильной установки указателя атрибута вершины.

varying также недопустимо в GLSL 330. Вам нужно объявить f_texcoord как out в вершинном шейдере и in во фрагментном шейдере, чтобы ваша программа правильно компоновалась.

В ваших списках кодов вообще нет кода обнаружения ошибок. Вам следует прочитать справочные страницы для glValidateProgram (...), glGetProgramInfoLog (...) и glGetShaderInfoLog (...), потому что я почти уверен, что компилятор GLSL сообщил бы вам о вашей конкретной проблеме, если бы вы прочитали его выходной журнал.

person Andon M. Coleman    schedule 08.09.2013
comment
Хм, к сожалению, это не решает мою проблему, если только я не понимаю вас. Я заменил атрибут на in. Запрос успешно возвращает 1. Я проследил журналы, используя: GL.GetShaderInfoLog(vertexShaderHandle); который, к сожалению, ничего не возвращает... хммм. Может быть, мои буферы не привязаны должным образом? - person Serguei Fedorov; 08.09.2013
comment
@SergueiFedorov: я должен добавить к этому, что varying также недействителен. Замените varying vec2 f_texcoord на out vec2 f_texcoord в вершинном шейдере и in vec2 f_texcoord во фрагментном шейдере. - person Andon M. Coleman; 08.09.2013
comment
Спасибо за указание на недопустимые команды. Я новичок в этом, и кажется, что учебники немного разбросаны по шейдерам. - person Serguei Fedorov; 08.09.2013
comment
Может быть, это как-то связано с рендерингом спрайтов за пределами экрана? Хм... - person Serguei Fedorov; 08.09.2013
comment
@SergueiFedorov: Это тоже возможно. Не зная, что вы изменили, единственное, что я могу сделать, это указать на части ваших шейдеров, которые недействительны, и надеяться, что они виноваты ... контроль версий очень поможет в будущем, если вы измените вещи, которые вы не совсем понимаете (например, если вы вносите изменения из рабочего учебника). Дифференциал точно укажет, на чем сосредоточить поиск. - person Andon M. Coleman; 08.09.2013
comment
Спасибо большое за вашу помощь! Я нашел проблему; проблема в том, что спрайт был очень маленьким и не масштабировался по отношению к проекции. Теперь проблема в том, что когда я пытаюсь визуализировать несколько спрайтов, они отображаются в разных местах (если я добавляю vec4 (pos, 0, 1) в позицию), но они мерцают и исчезают... Благодаря вам у меня есть обе текстуры теперь рендерятся, хотя и с небольшой проблемой - person Serguei Fedorov; 08.09.2013