Search code examples
c#openglgame-engineopentk

OpenTK doesn't render the color of my triangle


I am learning to program a game engine which is why I followed a tutorial, with that tutorial I have gotten this far and even though my code is identical to theirs (theirs did work in the videos) its not working the way it is meant to. The triangle stays black no matter what. There is not any errors.

Main Program Script:

      using System;
using OpenTK.Mathematics;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.Common;
using System.Drawing;
using OpenTK.Graphics.OpenGL4;
using System.IO;

namespace Game_Engine
{
    public static class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            GameWindowSettings gws = GameWindowSettings.Default;
            NativeWindowSettings nws = NativeWindowSettings.Default;
            gws.IsMultiThreaded = false;
            gws.RenderFrequency = 60;
            gws.UpdateFrequency = 60;

            nws.APIVersion = Version.Parse("4.1.0");
            nws.AutoLoadBindings = true;
            nws.Size = new Vector2i(1280, 720);
            nws.Title = "Horizon";
            


            GameWindow window = new GameWindow(gws, nws);

            window.UpdateFrame += (FrameEventArgs args) => {

                
            };

            ShaderProgram shaderProgram = new ShaderProgram(){id = 0};
            window.Load += () =>
            {
                Console.WriteLine("Hello");
                ShaderProgram shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
            };

            window.RenderFrame += (FrameEventArgs args) =>
            {
                GL.UseProgram( shaderProgram.id );

                GL.ClearColor(1.0f, 0.0f, 0.0f, 0.0f);
                GL.Clear(ClearBufferMask.ColorBufferBit);

                float[] verts = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f };
                float[] color = { 1f, 0, 0, 0, 1f ,0 ,0, 0, 1f };

                int vao = GL.GenVertexArray();
                int vertices = GL.GenBuffer();
                int colors = GL.GenBuffer();
                GL.BindVertexArray(vao);
                GL.BindBuffer(BufferTarget.ArrayBuffer, vertices);
                GL.BufferData( BufferTarget.ArrayBuffer, verts.Length * sizeof(float), verts, BufferUsageHint.StaticCopy);
                GL.EnableVertexAttribArray( 0 );
                GL.VertexAttribPointer( 0, 3, VertexAttribPointerType.Float, false, 0, 0 );

                GL.BindBuffer(BufferTarget.ArrayBuffer, colors);
                GL.BufferData(BufferTarget.ArrayBuffer, color.Length * sizeof(float), color, BufferUsageHint.StaticCopy);
                GL.EnableVertexAttribArray(1);
                GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0);



                GL.DrawArrays(PrimitiveType.Triangles, 0, 3);

                GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
                GL.BindVertexArray(0);
                GL.DeleteBuffer(vertices);
                GL.DeleteBuffer(colors);
                GL.DeleteVertexArray( vao );



                window.SwapBuffers();
            };

            window.Run();
            
        }



        private static Shader LoadShader(string shaderLocation, ShaderType type)
        {
            int shaderId = GL.CreateShader( type );
            GL.ShaderSource( shaderId, File.ReadAllText( shaderLocation ) );
            GL.CompileShader( shaderId );
            string infoLog = GL.GetShaderInfoLog( shaderId );
            if (!string.IsNullOrEmpty(infoLog))
            {
                throw new Exception(infoLog);
            }

            return new Shader() { id = shaderId };
        }

        private static ShaderProgram LoadShaderProgram( string vertextShaderLocation, string fragmentShaderLocation)
        {
            int shaderProgramId = GL.CreateProgram();

            Shader vertextShader = LoadShader(vertextShaderLocation, ShaderType.VertexShader);
            Shader fragmentShader = LoadShader(fragmentShaderLocation, ShaderType.FragmentShader);

            GL.AttachShader(shaderProgramId, vertextShader.id);
            GL.AttachShader(shaderProgramId, fragmentShader.id);
            GL.LinkProgram(shaderProgramId);
            GL.DetachShader(shaderProgramId, vertextShader.id);
            GL.DetachShader(shaderProgramId, fragmentShader.id);
            GL.DeleteShader(vertextShader.id);
            GL.DeleteShader(fragmentShader.id);

            string infoLog = GL.GetProgramInfoLog(shaderProgramId);
            if (!string.IsNullOrEmpty(infoLog))
            {
                throw new Exception(infoLog);
            }

            return new ShaderProgram() { id = shaderProgramId };
        }


        public struct Shader
        {
            public int id;
        }

        public struct ShaderProgram
        {
            public int id;
        }
    }
}

Fragment Shader (in glsl):

#version 400

in vec3 color_in;

out vec4 color_out;

void main(){
  color_out = vec4(color_in.r, color_in.g, color_in.b, 1);

}

VertexShader (in glsl):

#version 330


layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vColors;

out vec3 color_in;

void main() {
  color_in = vColors;
  gl_Position = vec4( vPosition, 1.0 );

}

I have tried everything I could with my very limited knowledge of OpenTK and nothing has changed. I have searched on the web and for answer they still have not helped


Solution

  • You actually assign the shader program to a local variable in the event callback function's scope. You need to assign it to the variable in scope of Main:

    ShaderProgram shaderProgram = new ShaderProgram() { id = 0 };
    window.Load += () =>
    {
        Console.WriteLine("Hello");
                    
        // ShaderProgram shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
        shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
    };