OpenTK / OpenGL: невозможно запустить шейдеры в VAO - PullRequest
2 голосов
/ 05 апреля 2020

Я пытаюсь запустить шейдер поверх себя sh. Прямо сейчас все 2D и довольно просто. Я думаю, что это просто недостаток знаний с моей стороны, это проблема, но после 4 часов Google и чтения учебников opentk / opengl я все еще застрял. Вот мой код шейдера по умолчанию:

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using BuildMe.Core;
using OpenTK.Graphics.OpenGL;

namespace BuildMe.Render.Shaders
{
    abstract class ShaderProgram
    {

        private static readonly string Loc = "Resources/Shaders/";

        // Shader ID
        private readonly int PID;

        // Vertex Shader ID
        private readonly int VSID;

        // Fragment Shader ID
        private readonly int FSID;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="FileName">Prefixed with the correct directories.</param>
        public ShaderProgram(String FileName)
        {
            // Compiling Vertex Shader
            VSID = CreateVertexShader(Loc + "Vertex/" + FileName + ".vert");

            // Compiling Fragment Shader
            FSID = CreateFragShader(Loc + "Fragment/" + FileName + ".frag");

            // Compiling Shader Program
            PID = GL.CreateProgram();
            GL.AttachShader(PID, VSID);
            GL.AttachShader(PID, FSID);
            BindAttributes();
            GL.LinkProgram(PID);
            GL.ValidateProgram(PID);

            if (GL.GetError() != ErrorCode.NoError)
                Console.WriteLine("Error Vaidating Program");

            RenderLoop.Shaders.Add(this);
        }

        public virtual void BindAttributes()
        {

        }

        private int CreateVertexShader(String Location)
        {
            int vsid = GL.CreateShader(ShaderType.VertexShader);

            GL.ShaderSource(vsid, File.ReadAllText(Location));
            GL.CompileShader(vsid);
            GL.GetShader(vsid, ShaderParameter.CompileStatus, out int status_code);
            if (status_code != 1)
                Console.WriteLine("Status Code : " + status_code);
            return (vsid);
        }

        private int CreateFragShader(String Location)
        {
            int fsid = GL.CreateShader(ShaderType.VertexShader);

            GL.ShaderSource(fsid, File.ReadAllText(Location));
            GL.CompileShader(fsid);
            GL.GetShader(fsid, ShaderParameter.CompileStatus, out int status_code);
            if (status_code != 1)
                Console.WriteLine("Status Code : " + status_code);
            return (fsid);
        }

        public virtual void BindAttribute(int attribute, String VariableName)
        {
            GL.BindAttribLocation(PID, attribute, VariableName);
        }

        public void UseShader()
        {
            GL.UseProgram(PID);
        }

        public void StopShader()
        {
            GL.UseProgram(0);
        }

        public void CleanUp()
        {
            // Cleaning Up
            GL.DetachShader(PID, VSID);
            GL.DetachShader(PID, FSID);
            GL.DeleteShader(VSID);
            GL.DeleteShader(FSID);
        }

    }
}

Вот дочерний класс, который я использую для себя sh:

using System;
using System.Collections.Generic;
using System.Text;

namespace BuildMe.Render.Shaders
{
    class StaticShader : ShaderProgram
    {

        public StaticShader() : base("2d")
        {

        }

        public override void BindAttributes()
        {
            BindAttribute(0, "position");
        }

    }
}

Вот мои два шейдера: Vertex:

#version 400 core

in vec3 position;

out vec3 colour;

void main(void)
{
    gl_Position = vec4(position, 1.0);
    colour = vec3(position.x + 0.5, 1, position.y + 0.5);

}

Фрагмент:

#version 400 core

in vec3 colour;

out vec4 out_Color;

void main(void)
{
    out_Color = vec4(colour, 1.0);
}

И вот где я использую шейдер:

        private void Render(object sender, FrameEventArgs e)
        {
            ss.UseShader();
            foreach (Mesh mesh in SceneMeshes)
                mesh.Render();
            ss.StopShader();
        }

Я не получаю никаких ошибок при компиляции шейдеров или шейдерной программы, так что я немного растерялся. Как я уже говорил, я подозреваю, что это просто что-то, что я пропустил или испортил из-за моей неопытности. Любая помощь приветствуется.

1 Ответ

3 голосов
/ 06 апреля 2020

Вы создаете 2 вершинных шейдера, но не фрагментный шейдер:

Поскольку в CreateFragShader используется тип шейдера ShaderType.VertexShader:

private int CreateFragShader(String Location)
{
  int fsid = GL.CreateShader(ShaderType.VertexShader);

Используйте ShaderType.FragmentShader для решения проблемы:

private int CreateFragShader(String Location)
{
    int fsid = GL.CreateShader(ShaderType.FragmentShader);
...