iWas-Coder / wge

A multithreaded, high performance, fully functional game engine written in pure C, similar in speed to a Wildebeest™.
https://iwas-coder.github.io/wge
GNU General Public License v3.0
1 stars 1 forks source link
3d c cli cpp game-dev game-development game-engine gamedev go golang vulkan vulkan-api vulkan-engine vulkan-game-engine vulkan-renderer

+AUTHOR: Wasym A. Alonso

+TITLE: WGE: Wildebeest Game Engine™

+CAPTION: WGE logo

[[assets/logo.png]]

Buy Me A Coffee

+begin_html

Buy Me A Coffee

+end_html

Repository info badges

+begin_html

GNU GPL v3.0 Code QA LoC Files

+end_html

Repository workflow badges

+begin_html

WGE CI: Build & Test WGE CI: Build & Push image that builds WGE WGE CI: Build & Push image that builds WGE

+end_html

+begin_html

⛔ DEPRECATED: this project got superseeded by sparky-game/volt (check it out here => https://github.com/sparky-game/volt)

+end_html

GNU GPLv3+ License notice

+BEGIN_QUOTE

This work and all its documentation is licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) License. @@html:
@@ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. @@html:
@@ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

+END_QUOTE

** Platform support

Linux and Windows.

** Tech stack

** Project structure

+begin_src mermaid

mindmap root(("Engine (shared)")) ("Hot-reloadable code (shared)") ("Game (exec)") ("Test (exec)") ("Editor (exec)")

+end_src

** Features

*** High-level product features

*** Feature roadmap

**** General

| Feature | Status | Feature | Status | Feature | Status | |----------------------------------+--------+-------------------------------+--------+---------------------------------+--------| | Platform layer | ✅ | Keyboard support | ✅ | Texture format conversion tool | ❌ | | Desktop GNU/Linux support | ✅ | Mouse support | ❌ | Resource hot-reloading | ❌ | | Desktop Windows support | ❌ | Gamepad support | ❌ | Entity Component System (ECS) | ❌ | | Desktop macOS support | ❌ | Touchscreen/mobile support | ❌ | Scenes | ❌ | | Mobile Android support (runtime) | ❌ | String library (basic) | ✅ | Scene format | ❌ | | Mobile iOS support (runtime) | ❌ | String library (struct based) | ❌ | Scene load/save procedures | ❌ | | Dynamic array | ✅ | Math library | ✅ | Prefabs | ❌ | | Free list | ❌ | SIMD support for math library | ❌ | Raycasting | ❌ | | Hash table | ✅ | Linear allocator | ✅ | Object picking | ❌ | | Stack | ❌ | Dynamic allocator | ❌ | Gizmos | ❌ | | Queue | ❌ | Pool allocator | ❌ | Editor (world) | ❌ | | Ring | ❌ | System manager & interface | ❌ | Audio | ❌ | | Pool | ❌ | Multithreading | ❌ | Physics | ❌ | | Binary Search Tree (BST) | ❌ | Job system | ❌ | Networking | ❌ | | Logger (basic) | ✅ | Resource system | ✅ | Profiling | ❌ | | Multithreaded logging | ❌ | Binary resource loader | ✅ | Game/editor logic hot-reloading | ❌ | | Logger channel grouping | ❌ | Text resource loader | ✅ | Keymaps/keybindings | ❌ | | Clock (basic) | ✅ | Image resource loader | ✅ | Configurable global settings | ❌ | | Clock (advanced) | ❌ | Material resource loader | ✅ | Configurable engine settings | ❌ | | Events (basic) | ✅ | Bitmap font resource loader | ❌ | Timeline system | ❌ | | Event broadcast | ❌ | System font resource loader | ❌ | Skeletal animation system | ❌ | | Event polling | ❌ | Scene resource loader | ❌ | Terrain | ❌ | | Multithreaded events | ❌ | Texture format (binary) | ❌ | Skybox & skysphere | ❌ |

**** Renderer

| Feature | Status | Feature | Status | |-------------------------------------+--------+--------------------------------------------+--------| | Renderer front/backend architecture | ✅ | 2D/3D geometry generation | ❌ | | Vulkan API backend support | ✅ | Multiple renderpass support | ✅ | | OpenGL API backend support | ❌ | Configurable renderpasses | ❌ | | Direct3D API backend support | ❌ | Phong reflection/lighting model | ❌ | | Metal API backend support | ❌ | Specular maps | ❌ | | Textures | ✅ | Normal maps | ❌ | | Geometry | ✅ | Physically Based Rendering (PBR) | ❌ | | Materials (basic) | ✅ | Multithreading support for Vulkan renderer | ❌ | | Materials (advanced) | ❌ | Multithreading support for D3D12 renderer | ❌ | | Render targets/textures support | ✅ | 2D/3D batch rendering | ❌ |

**** UI

| Feature | Status | Feature | Status | |------------------------------------+--------+-------------------------------+--------| | UI system | ❌ | Text (basic) control | ❌ | | Layering | ❌ | Text (rich) control | ❌ | | UI file format | ❌ | Button control | ❌ | | Load/save procedures | ❌ | Checkbox control | ❌ | | Editor (UI) | ❌ | Radio button control | ❌ | | Control focus (TAB-ing) | ❌ | Tab control | ❌ | | Docking | ❌ | Window/modal control | ❌ | | Drag-and-Drop support | ❌ | Resizable multi-panel control | ❌ | | Base control (show/hide, position) | ❌ | Scrollbar control | ❌ | | Panel control | ❌ | Scroll container control | ❌ | | Image box control | ❌ | Textbox/textarea control | ❌ | | Viewport control | ❌ | In-game debug console control | ❌ |

**** Miscellany

| Feature | Status | |--------------------------------------------------------------------+--------| | README-type documentation | ✅ | | White paper | ❌ | | Reference Manual (Info, HTML, PostScript, PDF) | ❌ | | API auto-generated code documentation (Man, HTML, PostScript, PDF) | ❌ |

** Architecture

+CAPTION: Engine architecture diagram

[[assets/engine-arch-diagram.png]]

** Renderer

(...)

*** Architecture

+CAPTION: Renderer architecture diagram

[[assets/renderer-arch-diagram.png]]

(...)

*** Lifecycle

+begin_src mermaid

flowchart TB A[Initialization] --> B[Prepare frame] B --> C[Set state on GPU] C --> D[Present to screen] D --> E{Still running?} E --> |Yes| B E --> |No| F[Shutdown]

+end_src

(...)

*** Phases

*** Graphics pipeline

+begin_src mermaid

flowchart TB A[Vertex & Index Buffers] --> |Input Assembler| B[Vertex Shader] B --> C[Tessellation] C --> D[Geometry Shader] D --> |Rasterization| E[Fragment Shader] E --> |Color Blending| F[Framebuffer]

+end_src

(...)

**** Shader modules

+begin_src mermaid

flowchart TB A[SPIR-V] B[GLSL] --> A C[HLSL] --> A

+end_src

(...)

**** Vertex shader

+CAPTION: Renderer vertex shader coordinates transformations

[[assets/renderer-vertex-shader-coordinates.png]]

(...)

**** Fragment shader

(...)

** Data structures

(...)

*** Dynamic array (~darray~)

(...)

*** Free list

A free list is a data structure which mantains the locations and sizes of memory blocks as they are allocated and freed. Effectively, it only tracks the actual allocations themselves.

It uses a linked list internally, which typically means dynamic allocations have to occur for each node. However, in this implementation it only happens a single time and up front, to likely reduce the overhead.

+CAPTION: Free list diagram

[[assets/free-list-diagram-1.png]]

There are two possible ways to implement an allocation:

  1. First fit: Use the first block of memory that can hold the requested amount. It is fast to perform the allocation, and it stops searching at the first match. However, it can lead to memory fragmentation quite often.
  2. Best fit: Search all blocks of memory for the closest match in size. It is slow to perform the allocation, as it has to search through the entire list. However, it can be slightly better at preventing memory fragmentation depending on the specific setup.

After research and testing, the theoretical benefits of a /best fit/ solution doesn't outweight the costs, so the selected method has been the /first fit/ (1).

**** Allocation

+CAPTION: Free list allocation operation diagram

[[assets/free-list-diagram-2.png]]

  1. When a request comes in for memory allocation, the system checks the free list to see if there's an available block that can fulfill the request. This is done by iterating over the free list until a suitable block is found.

  2. Once a suitable block is found, it is removed from the free list. This means updating the links between the other blocks in the list to exclude the newly allocated block.

  3. The block is then marked as being in use. This could involve changing a status flag or similar mechanism.

  4. Finally, the address of the allocated block, or in this case an offset, is returned to the requester.

**** Free

+CAPTION: Free list allocation operation diagram

[[assets/free-list-diagram-3.png]]

  1. When a block is no longer in use and needs to be returned to the free list, it is first marked as available again. This might involve clearing a status flag or similar mechanism.

  2. The block is then added back to the free list. This involves updating the links between the other blocks in the list to include the newly freed block.

  3. Finally, the system may need to perform some form of compaction operation to ensure that the free list remains efficient. This could involve moving the freed block to a different location in memory if doing so would make the free list more compact or efficient.

*** Hash table

(...)

*** Stack

(...)

*** Queue

(...)

*** Ring

(...)

*** Pool

(...)

*** Binary Search Tree (BST)

(...)

(...)

(...)

** Get the code

(...)

+begin_src sh

$ git clone --recurse-submodules https://github.com/iwas-coder/wge

+end_src

(...)

+begin_src sh

$ git clone https://github.com/iwas-coder/wge && cd wge $ git submodule init $ git submodule update

+end_src

** Build

WGE ships with a ready-to-go ~Makefile~, so GNU Make is needed in order to build the engine. It is as simple as doing:

+begin_src sh

$ make

+end_src

By default, it targets the Linux platform (e.g. /GNU/Linux/). In order to build the project for Windows, it will be needed the MinGW-w64 compiler suite in order to cross-compile it. With all that setup, it can be specified by doing:

+begin_src sh

$ make TARGET=windows

+end_src

(...)