SFML C# OpenGL. Draw a triangle using shaders

Published June 16, 2020
Advertisement

We will use OpenTK 4 version because it supports .NET Core.

Install VSCode and .NET Core SDK. Follow the instruction: https://code.visualstudio.com/docs/languages/dotnet

Create and an empty folder (with a name, for example: SfmlNetAndOpenTK4DotNetCore) and go to it:

cd SfmlNetAndOpenTK4DotNetCore

Create a new console application by executing this command:

dotnet new console

Add packages: SFML.NET and OpenTK 4 using this commands:

dotnet add package SFML.Net --version 2.5.0
dotnet add package OpenTK --version 4.0.0-pre9.1

Open VSCode by typing the command in the console:

code .

Copy and pasta the code below and run the app using the command:

dotnet run

Program.cs

using SFML.Window;
using SFML.Graphics;
using SFML.System;
using OpenToolkit.Graphics.OpenGL;
using OpenToolkit.Windowing.Desktop;
using System.IO;
using System;

namespace SfmlNetAndOpenTK4DotNetCore
{
    class Program
    {
        static RenderWindow window;
        static int program;

        static void Main(string[] args)
        {
            GameWindowSettings gameWindowSettings = new GameWindowSettings();
            NativeWindowSettings nativeWindow = new NativeWindowSettings();
            // nativeWindow.StartVisible = false;

            nativeWindow.APIVersion = System.Version.Parse("3.1");
            nativeWindow.Profile = OpenToolkit.Windowing.Common.ContextProfile.Any;

            GameWindow gameWindow = new GameWindow(gameWindowSettings, nativeWindow);
            gameWindow.IsVisible = false;

            window = new RenderWindow(new VideoMode(280, 280), "SFML.NET+OpenTK4");

            window.Closed += (obj, e) => { window.Close(); };
            window.Resized +=
                (obj, e) =>
                {
                    window.SetView(new View(new FloatRect(0, 0, e.Width, e.Height)));
                    GL.Viewport(0, 0, (int)e.Width, (int)e.Height);
                };

            window.SetActive(true);

            GL.Viewport(0, 0, (int)window.Size.X, (int)window.Size.Y);
            GL.ClearColor(0f, 0.3f, 0.1f, 1f);

            program = LoadShaders();

            float[] positions = new float[] {
                0f, 1f, 0f,
                -1f, 0f, 0f,
                1f, 0f, 0f
            };

            float[] colors = new float[] {
                1f, 0f, 0f,
                1f, 0f, 0f,
                1f, 0f, 0f
            };

            int vboPos;
            GL.GenBuffers(1, out vboPos);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vboPos);
            GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * positions.Length,
                          positions, BufferUsageHint.StaticDraw);

            int aPositionLoc = GL.GetAttribLocation(program, "aPosition");
            GL.VertexAttribPointer(aPositionLoc, 3, VertexAttribPointerType.Float, false, 0, 0);
            GL.EnableVertexAttribArray(aPositionLoc);

            int vboColor;
            GL.GenBuffers(1, out vboColor);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vboColor);
            GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * colors.Length,
                          colors, BufferUsageHint.StaticDraw);

            int aColorLoc = GL.GetAttribLocation(program, "aColor");
            GL.VertexAttribPointer(aColorLoc, 3, VertexAttribPointerType.Float, false, 0, 0);
            GL.EnableVertexAttribArray(aColorLoc);

            while (window.IsOpen)
            {
                window.DispatchEvents();
                GL.Clear(ClearBufferMask.ColorBufferBit);
                GL.DrawArrays(OpenToolkit.Graphics.OpenGL.PrimitiveType.Triangles, 0, 3);
                window.Display();
            }
        }

        private static int LoadShaders()
        {
            int vShader = GL.CreateShader(ShaderType.VertexShader);
            int fShader = GL.CreateShader(ShaderType.FragmentShader);

            #region Vertex Shader Loading
            // string source = File.ReadAllText("Shaders/vShader.glsl");
            string vSource = string.Join(
                Environment.NewLine,
                "#version 140",
                "in vec3 aPosition;",
                "in vec3 aColor;",
                "out vec3 vColor;",
                "void main()",
                "{",
                "    gl_Position = vec4(aPosition, 1.0);",
                "    vColor = aColor;",
                "}");

            GL.ShaderSource(vShader, vSource);
            GL.CompileShader(vShader);

            int status;
            GL.GetShader(vShader, ShaderParameter.CompileStatus, out status);

            if (status == 0)
            {
                string info = GL.GetShaderInfoLog(vShader);
                Console.WriteLine("Vertex Shader Error: " + info);
                return -1;
            }
            #endregion

            #region Fragment Shader Loading
            // source = File.ReadAllText("Shaders/fShader.glsl");
            string fSource = string.Join(
                Environment.NewLine,
                "#version 140",
                "in vec3 vColor;",
                "out vec4 fragColor;",
                "void main()",
                "{",
                "    fragColor = vec4(vColor, 1.0);",
                "}");
            GL.ShaderSource(fShader, fSource);
            GL.CompileShader(fShader);

            GL.GetShader(fShader, ShaderParameter.CompileStatus, out status);

            if (status == 0)
            {
                string info = GL.GetShaderInfoLog(fShader);
                Console.WriteLine("Fragment Shader Error: " + info);
                return -1;
            }
            #endregion

            #region Creating Shader Program
            int program = GL.CreateProgram();
            GL.AttachShader(program, vShader);
            GL.AttachShader(program, fShader);
            GL.LinkProgram(program);

            GL.GetProgram(program, GetProgramParameterName.LinkStatus, out status);
            if (status == 0)
            {
                string info = GL.GetProgramInfoLog(program);
                Console.WriteLine("Program Error: " + info);
                return -1;
            }
            #endregion

            GL.UseProgram(program);
            GL.DeleteShader(vShader);
            GL.DeleteShader(fShader);

            return program;
        }
    }
}
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement