Search code examples
c#openglopentk

OpenTK Shaders Triangle Vertex


I am trying to program a triangle with colored vertices using C++ and the OpenTK library. This is how I envision what I want to achieve: enter image description here

But when I compile the program, I get this, the triangle is white: enter image description here

Here is my code:

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using OpenTK.Graphics.OpenGL;
using OpenTK;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;

namespace BasicOpenTk
{
    public class Game : GameWindow
    {
        private int vertexBufferHandle;
        private int shaderProgramHandle;
        private int vertexArrayHandle;

        public Game(int width = 1280, int height = 768, string title = "Game1")
            : base(
                GameWindowSettings.Default, 
                new NativeWindowSettings()
                {
                    Title = title,
                    ClientSize = new Vector2i(width, height),
                    WindowBorder = WindowBorder.Fixed,
                    StartVisible = false,
                    StartFocused = true,
                    API = ContextAPI.OpenGL,
                    Profile = ContextProfile.Core,
                    APIVersion = new Version(3,3)
                })
        {
            this.CenterWindow(new Vector2i(1280,768));
        }
    protected override void OnResize(ResizeEventArgs e)
    {
        GL.Viewport(0,0,e.Width, e.Height);
        base.OnResize(e);
    }

    protected override void OnLoad(){


        this.IsVisible = true;

        GL.ClearColor(new Color4(0.3f, 0.4f, 0.5f, 1.0f));  

        float[] vertices = new float[]
        {
            0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
            0.4f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
            -0.4f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f
        };

        this.vertexBufferHandle = GL.GenBuffer();
        GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexBufferHandle);
        GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

        this.vertexArrayHandle = GL.GenVertexArray();
        GL.BindVertexArray(this.vertexArrayHandle);
        GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexBufferHandle);
        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 7 * sizeof(float), 0);
        GL.VertexAttribPointer(1, 4, VertexAttribPointerType.Float, false, 7 * sizeof(float), 3 * sizeof(float));
        GL.EnableVertexAttribArray(0);
        GL.EnableVertexAttribArray(1);
        GL.BindVertexArray(0);

        
        string vertexShaderCode =
        @"
        #version 330 core

            layout(location = 0) in vec3 aPosition;
            layout(location = 1) in vec4 aColor;
            out vec4 vColor;                

            void main(void)
            {
                gl_Position = vec4(aPosition, 1.0);
                vColor= aColor;
            }
        ";
        string pixelShaderCode =
        @"
        #version 330
        in vec4 vColor;
        out vec4 outputColor;

        void main()
        {
            outputColor = vColor;
        }
        ";


        int vertexShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
        GL.ShaderSource(vertexShaderHandle, vertexShaderCode);
        GL.CompileShader(vertexShaderHandle);

        int pixelShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
        GL.ShaderSource(pixelShaderHandle, pixelShaderCode);
        GL.CompileShader(pixelShaderHandle);

        this.shaderProgramHandle = GL.CreateProgram();

        // Después de compilar el shader
        int status;
        GL.GetShader(vertexShaderHandle, ShaderParameter.CompileStatus, out status);
        if (status != 1)
        {
            string infoLog = GL.GetShaderInfoLog(vertexShaderHandle);
            Console.WriteLine("Error compiling vertex shader: " + infoLog);
        }

        // Después de compilar el shader de píxeles
        GL.GetShader(pixelShaderHandle, ShaderParameter.CompileStatus, out status);
        if (status != 1)
        {
            string infoLog = GL.GetShaderInfoLog(pixelShaderHandle);
            Console.WriteLine("Error compiling pixel shader: " + infoLog);
        }


        GL.AttachShader(this.shaderProgramHandle, vertexShaderHandle);
        GL.AttachShader(this.shaderProgramHandle, pixelShaderHandle);

        GL.LinkProgram(this.shaderProgramHandle);

        GL.DetachShader(this.shaderProgramHandle, vertexShaderHandle);
        GL.DetachShader(this.shaderProgramHandle, pixelShaderHandle);

        GL.DeleteShader(vertexShaderHandle);
        GL.DeleteShader(pixelShaderHandle);

        base.OnLoad();
    }

    protected override void OnUnload()
    {

        GL.BindVertexArray(0);
        GL.DeleteVertexArray(this.vertexArrayHandle);

        GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        GL.DeleteBuffer(this.vertexBufferHandle);

        GL.UseProgram(0);
        GL.DeleteProgram(this.shaderProgramHandle);

        base.OnUnload();
    }

    protected override void OnUpdateFrame(FrameEventArgs args)
    {
        base.OnUpdateFrame(args);
    }

    protected override void OnRenderFrame(FrameEventArgs args)
    {
        GL.Clear(ClearBufferMask.ColorBufferBit);

        GL.UseProgram(this.shaderProgramHandle);
        GL.BindVertexArray(this.vertexArrayHandle);
        GL.DrawArrays(PrimitiveType.TriangleFan, 0,3);

        this.Context.SwapBuffers();
        base.OnRenderFrame(args);
    }
}
}

This is the error I'm getting:

Error compiling vertex shader: ERROR: 0:10: 'gl_Position' : undeclared identifier 
ERROR: 0:10: 'assign' :  cannot convert from '4-component vector of highp float' to 'highp float'

I guess something is wrong with my shader, and I don´t know what it is. I tried doing this:

string vertexShaderCode =
            @"
            #version 330 core

                layout(location = 0) in vec3 aPosition;
                layout(location = 1) in vec4 aColor;
                out vec4 vColor;                
                out vec4 gl_Position ;

                void main(void)
                {
                    gl_Position = vec4(aPosition, 1.0);
                    vColor= aColor;
                }
            ";

But it didn't work. Please help me!!!!


Solution

  • You are compiling the vertex as a fragment shader:

    int vertexShaderHandle = GL.CreateShader(ShaderType.FragmentShader);
    GL.ShaderSource(vertexShaderHandle, vertexShaderCode);
    GL.CompileShader(vertexShaderHandle);