Skip to content

Your first OpenGL project

vlOd edited this page Jan 6, 2025 · 9 revisions

Create a new project

All of these steps will be done differently depending on your IDE, platform, etc
So to give you an idea, we will be doing all of them using the dotnet CLI
These steps will be done on Linux, but they are pretty similiar to Windows

1. Create a new folder for your project

$ mkdir MyFirstGLGame
$ cd MyFirstGLGame

2. Initialize a Git repository and link QuickGL

The recommended way to use QuickGL is to add it as a Git submodule

$ git init
$ git submodule add https://github.com/vlOd2/QuickGL.git

You may also directly clone QuickGL inside your working tree

$ git clone https://github.com/vlOd2/QuickGL.git

3. Setup a .NET solution and project

$ dotnet new sln
$ dotnet new console -o MyFirstGLGame/ -f net8.0 --use-program-main
$ dotnet sln add MyFirstGLGame/MyFirstGLGame.csproj

4. Configure .NET project

We need to configure the .NET project we just created in order to reference QuickGL and enable unsafe code Open up MyFirstGLGame.csproj inside the MyFirstGLGame folder with your favourite text editor

Add the following to the end of the only PropertyGroup block:

<ItemGroup>
  <ProjectReference Include="..\QuickGL\QuickGL\QuickGL.csproj" />
</ItemGroup>

Tip

Make sure to keep the spacing consistent

Then, right before the end of the previously mentioned PropertyGroup block, add the following:

<AllowUnsafeBlocks>true</AllowUnsafeBlocks>

Your project file should look like this in the end:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\QuickGL\QuickGL\QuickGL.csproj" />
  </ItemGroup>

</Project>

5. Write your code

Now with the setup out of the way, let's write some code!
Open up Program.cs inside your favourite editor or IDE, and write the following:

Important

The following example uses OpenGL 1.1 (immediate mode)
It is outdated and slow compared to OpenGL 3.0 and higher in core mode
For a more advanced example using that, check out ExampleGame inside the repository

namespace MyFirstGLGame;

using QuickGLNS;
using QuickGLNS.Bindings;
using static QuickGLNS.Bindings.GLFW;
using static QuickGLNS.Bindings.GL10;
using static QuickGLNS.Bindings.GL11;

public unsafe class Program
{
    public static void Main(string[] args)
    {
        int windowWidth = 640;
        int windowHeight = 480;

        // Load GLFW and initialize it
        QuickGL.Init();
        if (glfwInit() == GLFW_FALSE) throw new Exception("Failed to initialize GLFW");
        
        // Create a window and OpenGL context
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
        nint window = glfwCreateWindow(windowWidth, windowHeight, new QGLString("Game"), 0, 0);
        if (window == nint.Zero) throw new Exception("Failed to create a window");
        glfwMakeContextCurrent(window);
        QuickGL.LoadGL();

        // Create a input helper for the window
        Input.Create(window);

        // Setup OpenGL
        glViewport(0, 0, windowWidth, windowHeight);
        glClearColor(0.3F, 0.5F, 0.8F, 1.0F);

        while (glfwWindowShouldClose(window) == GLFW_FALSE)
        {
            // Handle keyboard input
            IKeyboard keyboard = Input.GetKeyboard(window);
            while (keyboard.Next())
            {
                // Handle keys only when you press them
                if (!keyboard.IsPressedEvent) continue;

                // Exit when the you press escape
                if (keyboard.EventKey == GLFW_KEY_ESCAPE)
                    glfwSetWindowShouldClose(window, GL_TRUE);
            }

            // Clear the screen
            glClear(GL_COLOR_BUFFER_BIT);

            // Draw a white, centered triangle
            glColor3f(1.0F, 1.0F, 1.0F);
            glBegin(GL_TRIANGLES);
            glVertex2f(-0.5F, -0.5F);
            glVertex2f(0.5F, -0.5F);
            glVertex2f(0.0F, 0.5F);
            glEnd();

            // End the current frame
            glfwPollEvents();
            glfwSwapBuffers(window);
        }

        // Clean-up
        Input.Destroy(window);
        glfwDestroyWindow(window);
        glfwTerminate();
        QuickGL.Destroy();
    }
}

6. Finishing up

You're almost there!

Commit your changes to the git repository:

$ git commit -m "Initial Commit"

Build the project:

$ cd MyFirstGLGame
$ dotnet build

Important

Make sure to copy the built GLFW native to the output folder
This usually is bin/Debug/<framework> (inside your project)
In this case, it would be bin/Debug/net8.0

7. Done

You're done! Run your game with the following command:

$ dotnet run

You should see a white triangle on a blue background
You can close the game by pressing escape or closing the window