[Projekt] GFX Game Engine / Framework

Hier könnt ihr euch selbst, eure Homepage, euren Entwicklerstammtisch, Termine oder eure Projekte vorstellen.
Forumsregeln
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.

Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.

This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
Antworten
Andy90
Beiträge: 63
Registriert: 08.10.2023, 13:02

[Projekt] GFX Game Engine / Framework

Beitrag von Andy90 »

Hallo, gerne möchte ich mein Hobbyprojekt vorstellen. Es handelt sich um eine einfache Game Engine, die ich vor einigen Jahren begonnen habe zu entwickeln. Anfangs war das Framework in Java geschrieben und verwendete den üblichen Graphics2D Context zur Darstellung von 2D-Grafiken. 3D-Unterstützung war zu diesem Zeitpunkt noch nicht geplant und ist es ehrlich gesagt bis heute nicht.

Allerdings entwickelt man sich im Laufe der Zeit weiter und möchte neue Dinge lernen und in das Framework integrieren. Daher habe ich vor 3-4 Jahren beschlossen, die alte Java Engine in JavaFX neu zu erstellen. Ein großer Vorteil war, dass automatisch die beste Render-Pipeline verwendet wurde. Allerdings brachte JavaFX auch neue Herausforderungen mit sich. Es war eine Herausforderung, Spiele, die damit erstellt wurden, zu veröffentlichen, besonders nachdem Oracle JavaFX aus dem SDK genommen und ein eigenständiges Modul daraus gemacht hatte.

Es war also schnell klar, dass ich, wenn ich das Framework wirklich für kleine und mittelgroße Projekte verwenden möchte, nicht um eine solide Programmiersprache und vor allem um einen geeigneten Grafikkontext herumkomme. Da ich bereits etwas Erfahrung mit OpenGL hatte, war DirectX schnell aus dem Rennen. Als Programmiersprachen standen C++ und C# zur Auswahl. Da ich plane, die Spiele, die ich mit dem Framework entwickeln möchte, nur für Windows zu veröffentlichen, habe ich mich für C# entschieden, um mir Arbeit zu ersparen.

Damit waren die Programmiersprache und der Renderer für die Neuauflage der Engine bzw. des Frameworks festgelegt und ich begann mit der Neuentwicklung. Ein wichtiger Aspekt war für mich, flexibel beim Rendern zu bleiben. Ich wollte keinen festen Renderer verwenden, sondern ein Template, das es mir ermöglicht, später auch andere APIs oder Render-Technologien zu nutzen, ohne die Engine komplett neu beginnen zu müssen. Nach wenigen Wochen war das Framework soweit, dass ich effektiv an kleinen Spielen arbeiten konnte, unterstützt durch Classic GL.

Heute arbeite ich immer noch an der Engine und bin gerade dabei, ein neues Render Device für OpenGL4 zu erstellen. Dies ermöglicht eine effizientere Darstellung von 2D-Szenen und vor allem auch die Erstellung von 3D-Szenen. Folgende Funktionen existieren zum aktuellen Zeitpunkt:
  • Rendern von 2D-Sprites mit ClassicGL und ModernGL
  • Rendern von 3D-Modellen mit ModernGL
  • Diffuses Licht in 3D-Szenen
  • Importieren von Wavefront-Modellen
  • Physiksimulation und Kollisionserkennung mit BulletSharp (ein Wrapper für Bullet)
  • Dynamisches Kamerasystem
  • Abstraktes Entity-System, bei dem jedem Entity (GameElement) beliebig viele Verhaltensweisen zugewiesen werden können.
  • Einfaches Asset-Loading
Dies bildet zwar noch nicht eine umfassende Liste, jedoch stellt es eine solide Grundlage für das Framework dar. Mein Ziel ist es schließlich nicht, eine Engine wie Unreal oder Unity zu entwickeln, sondern durch das Projekt selbst Neues zu lernen.

Screenshots
Screenshot 2023-10-31 153755.png
Screenshot 2023-10-31 152854.png
Screenshot 2023-10-31 152821.png
Screenshot 2023-10-31 012353.png
Screenshot 2023-10-30 165407.png
Beispiel Code

Code: Alles auswählen

using Genesis.Core;
using Genesis.Core.Prefabs;
using Genesis.Graphics;
using Genesis.Graphics.RenderDevice;
using Genesis.Math;
using Genesis.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using BulletSharp;
using BulletSharp.Math;
using System.Net.Security;
using Genesis.Core.Behaviors.Physics3D;
using Genesis.Physics;
using Genesis.Graphics.Shaders.OpenGL;

namespace _3DGame
{
    public partial class Form1 : Form
    {
        private Game game;

        public Form1()
        {
            InitializeComponent();
            String modelspath = new System.IO.FileInfo(System.Reflection.Assembly.GetEntryAssembly().Location).Directory + "\\Resources";

            //Create a new game
            this.game = new Game(new ModernGL(this.Handle), new Genesis.Graphics.Viewport(this.ClientSize.Width, this.ClientSize.Height));
            this.game.TargetFPS = 150;
            this.game.AssetManager.LoadTextures();
            this.game.AssetManager.LoadFonts();

            Light sun = new Light("Sun", new Vec3(0,1000f,0));
            sun.Intensity = 0.15f;

            //Create the scene and a physics handler
            Scene baseScene = new LightScene("BaseScene", sun);
            PhysicsHandler3D physicsHandler = new PhysicsHandler3D(0f, -9.81f, 0f);
            baseScene.PhysicHandler = physicsHandler;

            baseScene.AddLayer("BaseLayer");
            baseScene.Camera = new PerspectiveCamera(new Vec3(0.0f, 0.0f, -1.0f), new Vec3(this.ClientSize.Width, this.ClientSize.Height), 0.1f, 100f);
               
            //Add the sponza scene to the scene
            Element3D element = new Element3D("Sponza",modelspath + "\\sponza\\sponza.obj", new Vec3(0f, -1f, 0f), new Vec3(0f,0f,0f), new Vec3(0.01f));
            element.Shader = new Genesis.Graphics.Shaders.OpenGL.DiffuseLightning();
            var convexHullRigidbody = element.AddBehavior(new StaticMeshBehavior());
            convexHullRigidbody.CreateRigidBody(baseScene.PhysicHandler, 0f);
            baseScene.AddGameElement("BaseLayer", element);
                
            //Add the qube to the scene
            Element3D qube = new Element3D("Test", modelspath + "\\Qube\\Qube1.obj", new Vec3(0f, 10f, 0f), new Vec3(45f, 0f, 0.0f), new Vec3(0.5f));
            qube.Shader = new DiffuseLightning();
            var qubeRigidBody = qube.AddBehavior(new ConvexHullBehavior());
            qubeRigidBody.CreateRigidBody(baseScene.PhysicHandler, 1f);
            RigidBody bdy = (RigidBody)qubeRigidBody.GetPhysicsObject();
            baseScene.AddGameElement("BaseLayer", qube);

            qubeRigidBody.OnCollide += (scene, game, collisionObject) =>
            {
                if(collisionObject == convexHullRigidbody.GetPhysicsObject())
                {
                    Console.WriteLine("Hey my qube is collidng!");
                }
                
            };

            //Add the scene to the game and set the selected scene
            game.AddScene(baseScene);
            this.game.SelectedScene = baseScene;
            this.game.Start();

            game.OnInit += (game, renderer) =>
            {
                physicsHandler.PhysicsWorld.DebugDrawer = new BulletDebugDrawer((ModernGL)this.game.RenderDevice);
            };

            game.OnRenderEnd += (game, renderer) =>
            {
                physicsHandler.PhysicsWorld.DebugDrawWorld();
            };

            //Use the OnUpdate callback to move the camera arround
            game.OnUpdate += (game, renderer) =>
            {
                
                //float dt = (float)(game.DeltaTime / 1000f);
                //World.StepSimulation((float)dt);
                //int numManifolds = physicsHandler.PhysicsWorld.Dispatcher.NumManifolds;
                //for (int i = 0; i < numManifolds; i++)
                //{
                //    PersistentManifold contactManifold = physicsHandler.PhysicsWorld.Dispatcher.GetManifoldByIndexInternal(i);
                //    CollisionObject obA = contactManifold.Body0 as CollisionObject;
                //    CollisionObject obB = contactManifold.Body1 as CollisionObject;


                //}

                //if(numManifolds <= 0)
                //{
                //    Console.WriteLine("No Collision");
                //    qubeRigidBody.RigidBody.Activate();
                //}

                PerspectiveCamera camera = (PerspectiveCamera) baseScene.Camera;
                float cameraSpeed = 0.05f;

                if (Input.IsKeyDown(Keys.W))
                {
                    camera.MoveForward(cameraSpeed);
                }
                else if(Input.IsKeyDown(Keys.S)) {
                    camera.MoveBackward(cameraSpeed);
                }
                else if (Input.IsKeyDown(Keys.A))
                {
                    camera.MoveLeft(cameraSpeed);
                }
                else if (Input.IsKeyDown(Keys.D))
                {
                    camera.MoveRight(cameraSpeed);
                }
                else if (Input.IsKeyDown(Keys.Up))
                {
                    baseScene.Camera.Rotation.X -= 0.5f;
                }
                else if (Input.IsKeyDown(Keys.Down))
                {
                    baseScene.Camera.Rotation.X += 0.5f;
                }
                else if (Input.IsKeyDown(Keys.Q))
                {
                    baseScene.Camera.Rotation.Y -= 0.5f;
                }
                else if (Input.IsKeyDown(Keys.E))
                {
                    baseScene.Camera.Rotation.Y += 0.5f;
                }
                else if (Input.IsKeyDown(Keys.PageUp))
                {
                    baseScene.Camera.Location += new Vec3(0.0f, 0.5f, 0.0f);
                }
                else if (Input.IsKeyDown(Keys.PageDown))
                {
                    baseScene.Camera.Location -= new Vec3(0.0f, 0.5f, 0.0f);
                }
                else if (Input.IsKeyDown(Keys.Enter))
                {
                    qubeRigidBody.RigidBody.Activate();
                }
                else if(Input.IsKeyDown(Keys.Left))
                {
                    qube.Location.X += 0.1f;
                    qubeRigidBody.UpdateRigidBody();
                }

                //qube.Location = Vec3.Towards3D(camera.Rotation, camera.Location, 5f);
                //qubeRigidBody.UpdateRigidBody();

            };

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// Set the new viewport for the scene
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Resize(object sender, EventArgs e)
        {
            game.Viewport.SetNewViewport(ClientSize.Width, ClientSize.Height);
            game.SelectedScene.Camera.Size = new Vec3(ClientSize.Width, ClientSize.Height);
        }

        /// <summary>
        /// Stop the game
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            game.Stop();
        }
    }
}

NytroX
Establishment
Beiträge: 364
Registriert: 03.10.2003, 12:47

Re: [Projekt] GFX Game Engine / Framework

Beitrag von NytroX »

Schick, sieht gut aus.
Hast du auch schon eine Idee/Ziel was du mit deinem Framework machen willst? Oder erstmal nur zum Lernen?
Antworten