GET STARTED

With the release of the GFX engine for .NET 8, setting up a new project is also much easier. With the exception of the native OpenAL libraries, all referenced content is provided as Nuget references. There are also the starter templates which can be downloaded from the website.

View the Source Code on Github

Create an new gfx project

You can also implement your own scenes, game elements and much more through interfaces so that you can create the enviroment your game needs. This short article will show you how to create your first project with GFX.

First, you should download a project template and add it to your Visual Studio templates. This already contains the required Nuget packages as references and has the advantage that you can use it for all your future projects.

Download 2D Template
Download 3D Template

Setup your game

After you have downloaded a template and added it to visual Studio, you can start setting up your project. In both templates you will find a starter asset and an example of how the engine can be used.

The first step you should take is to create the project for the first time. For this you can simply use the build command, Ctrl + B or however you like to create your projects. This will ensure that the linked packages are installed.

Then, if you want to use 3D sound, you should install OpenAL or put the native files in your build folder to the exe of your game. Installing is easier for you, but you should deliver the native libarys later together with your game. You can download OpenAL here: OpenAL: Cross Platform 3D Audio

Your project is now set up so that you can start creating your game. In the following code you will find the code of the game class from the 3D template so that you can see what the workflow might look like.

Example Code

C#
using LibGFX.Core.GameElements;
using LibGFX.Core;
using LibGFX.Graphics.Lights;
using LibGFX.Graphics.Materials;
using LibGFX.Graphics;
using LibGFX.Pyhsics;
using LibGFX;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK.Mathematics;
using Assimp;
using System.Diagnostics;
using LibGFX.Graphics.Enviroment;
using LibGFX.Graphics.Primitives;

namespace GFX3DGame
{
    public class Game
    {
        private Window _window;
        private GLRenderer _renderer;
        private PerspectiveCamera _camera;
        private Scene3D _scene;
        private PhysicsHandler3D _physicsHandler;

        public Game()
        {
            // Initialize game components here
        }

        public void Initialize()
        {
            // Create an new game window
            var viewport = new Viewport(800, 600);
            _window = GFX.Instance.CreateWindow("GFX", viewport, OpenTK.Windowing.Common.WindowState.Normal);

            // Create an OpenGL rendererw
            _renderer = new GLRenderer();
            _renderer.Init(_window);
            _renderer.UseVsync(true);

            // Create the camera for the rendering
            _camera = new PerspectiveCamera(new Vector3(0.0f, 5f, -7.0f), new Vector3(viewport.Width, viewport.Height, 0.0f));
            _camera.SetAsCurrent();

            // Create the scene with layers
            _scene = new Scene3D("BASE_LAYER", "AI_LAYER", "PLAYER_LAYER", "ITEM_LAYER");
            _scene.Enviroment = new ProceduralSky();
            _scene.SetDirectionalLight(new DirectionalLight(new Vector3(-0.2f, 1.0f, -0.3f), new Vector4(0.025f, 0.025f, 0.025f, 1.0f), 1.5f));
            _scene.AddPointLight(new PointLight3D(new Vector3(2f, 0f, 0f), new Vector4(0.8f, 0.0f, 0.0f, 1.0f), 4f, 30f));
            _scene.AddPointLight(new PointLight3D(new Vector3(-2f, 0f, 0f), new Vector4(0.0f, 0.8f, 0.0f, 1.0f), 4f, 30f));
            _scene.AddPointLight(new PointLight3D(new Vector3(0f, 2f, 0f), new Vector4(0.0f, 0.0f, 0.8f, 1.0f), 4f, 30f));

            // Load the assets
            var model = GFX.Instance.AssetManager.Load<Model>("D:/3D Modele/GFX/Sponza/scene.gltf");
            model.Transform.Position = new Vector3(0.0f, 0.0f, 0.0f);
            model.Transform.Rotate(0.0f, -90f, 0.0f);
            model.Transform.Scale = new Vector3(1.5f, 1.5f, 1.5f);
            model.Shader = _renderer.GetShaderProgram("MeshShader");
            model.AddBehavior(new FlyCam());
            _scene.AddGameElement("BASE_LAYER", model);
            _camera.LookAt(model.Transform.Position);


            // Create an 2D physics handler with zero gravity
            _physicsHandler = new PhysicsHandler3D(Vector3.Zero);
            _scene.PhysicsHandler = _physicsHandler;

            // Initialize game objects and resources here
            GFX.Instance.AssetManager.ForeachAsset<IMaterial>(material =>
            {
                material.Init(_renderer);
            });

            // Initialize the scene
            _scene.Init(_window.GetViewport(), _renderer);
        }

        public void Run()
        {
            // Main game loop
            while (!_window.RequestClose())
            {
                var viewport = _window.GetViewport();
                _window.ProcessEvents();

                Update();
                Render(viewport);
            }

            Dispose();
        }

        public void Stop()
        {
            _window.Close();
        }

        private void Update()
        {
            // Update game logic here
            _scene.UpdatePhysics();
            _scene.Update();
        }

        private void Render(Viewport viewport)
        {
            _camera.Transform.Scale = new Vector3(viewport.Width, viewport.Height, 0.0f);

            // Clear the screen
            _renderer.MakeCurrent();
            _renderer.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            _renderer.Clear(RenderFlags.ClearFlags.Color | RenderFlags.ClearFlags.Depth);

            // Render game graphics here
            _scene.Render(viewport, _renderer, _camera);

            // Swap buffers
            _renderer.Flush();
            _renderer.SwapBuffers();

            // Check for errors
            Debug.WriteLine($"Render Error {_renderer.GetError()}");
        }

        private void Dispose()
        {
            _scene.DisposeScene(_renderer);
            _renderer.Dispose();
        }

    }
}