3D Game Engine Written in C++
Some History
TLDR: I always wanted to create a game engine from scratch, but never had the time or know how. After programming for 8 years (at the time of writing this) and taking numerous related game dev courses, I feel like I have built up enough knowledge and confidence to start building a game engine from the ground up.
When I started school, I told myself that I wouldn’t go into game development. It seemed too far fetched and out of reach for me. However, as I started taking more advanced classes, I found the game related courses always to be the most interesting. The first game related class I took was a computer graphics course. We went over the graphics pipeline, modeling, animation, rendering, opengl programming, basic lighting and texturing, shader programming, ray tracing, etc. I was very interested that I got an A+ on this course somehow. The group project was a lot of fun (you can see the results here). I built a very basic 3d engine from scrath for my group to use. It was pretty simple, and lots of things were coded specifically for our problem. We didn’t have much time, so we had to take shortcuts.
After the graphics course, I just end up taking anything related to graphics and games development.
Related Courses:
- Computer Graphics
- Game Development I & II (Heavy focus on Game Design and AI)
- Image Processing
- Computer Vision
- Numerical Methods
- C++
- Compilers
While C++ is not related to games specifically, it is the standard in game development. So C++ seemed like a no brainer to take. On the other head, both Image Processing and Computer Vision have similarities to game development. Techniques learned in Image Processing can be used with shader programming and other graphic programming techniques. Computer Vision has a lot of overlap with computer graphics and 3D math. Compilers was the least related to games, but I think the class helped increase my programming proficiency. Understanding what compilers do and don’t do for you is very important for making things go fast. Knowing that the code you write has to be ran on a real machine with real constraints is important to know. Writing a compiler from scratch makes you learn a lot about programming and performance. It was very challenging and very fun as well.
Philosophy for writing this engine
- No libraries such as stl and boost. (No std::vector or std::string)
- Minimize dependencies
- Try to write everything from scratch as much as possible
- Program using Data Oriented Design
- Avoid OOP
- Program in C++, but avoid all the crazy modern C++ insanity
- Templates are used sparingly (Only containers), also to avoid bloated compile times
- Minimal use of operator overloading. Only used for Vectors, Matrices, and Quaternions
- No Virtuals, Inheritance, or OOP-ness
- No Friend declarations
- No new/delete. Try to use custom memory allocators for everything
- Avoid autos. Prefer fixed width int types (uint32_t/u32 over int)
- No C++ Exceptions
- No RTTI
- Try to think hard about object lifetime and ownership.
- Avoid too many layers of abstraction
- Be explicit rather than implicit. Code is easier to follow in the debugger
- Think about the data and data flow
- Be wary about memory latency, memory layout, and the memory hierarchy
- Understand that you are writing code for a real machine with constraints, finite resources and not some abstract machine
- How much memory does a system need?
- How much time does a system need to perform its task?
- Does this code need to be done now, or can it be done later?
- Write code that I need now and not in the future
- Write code that is easy to debug, understand, and easy to change
- Write code that can be multi-threaded easily
- Try to read the outputted assembly and try to understand what it is trying to do
- Understand what the compiler can and can’t do for me
Things I learned/Implemented
- Work Ethic, Self Discipline, and Consistency. I worked on this for at least an hour everyday.
- Physically Based Rendering with HDR Followed the learnopengl tutorial
- HDR Skybox for IBL(Image Based Lighting)
- ECS using a Data Oriented Design
- Material System (Cook Torrance) (Albedo, Normal, Metal, Roughness, AO maps)
- Software Rendering Followed the Tiny Renderer tutorial
- Built a platform layer (win32,linux) on top of SDL2
- Implemented own math library (Vectors, Matrices, Quaternions) in SIMD
- Custom Memory Allocators
- Faster Hashmap implementation. (Linear, Open Addressed)
- Custom FBX scene importer written from scratch
- Shadowmaps using PCF
- Experimenting/Learning about Renderer Architecture.
- Experimental Multi threaded Job System
- Proper Game loop with physics untied to framerate
- Implemented an entire Asset Management system. (Asset Ids/Handles, Asset Files, Asset Loading)
- Implemented Scene Hierarchy Management
- Logging System with different levels (INFO, WARN, FATAL, VERBOSE)
- Started integrating an editor using Qt(but moved to ImGui)
- Undo/Redo system for editor
- Drag and drop support
Some Screenshots
Some overly glossy marble material
Gold head, sphere, and plane to show reflections using IBL (Image Based Lighting)
Showing a painted cemented material
Showing a rusted iron material
Showing a wood material
An early prototype of the editor using QT
Editor moved and reimplemented in ImGui. (Early ui)
Editor with default layout
Editor with a 4 panel Layout
Basic scripting and animation of entities