{"id":146,"date":"2016-10-06T07:17:13","date_gmt":"2016-10-06T05:17:13","guid":{"rendered":"http:\/\/robert-lindner.com\/blog\/?page_id=146"},"modified":"2025-12-18T02:15:40","modified_gmt":"2025-12-18T02:15:40","slug":"et_engine","status":"publish","type":"page","link":"https:\/\/leah-lindner.com\/blog\/et_engine\/","title":{"rendered":"Extra Terrestial Engine"},"content":{"rendered":"\n<figure class=\"wp-block-image\"><img decoding=\"async\" class=\"ls_lazyimg\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_250x250.gif\" file=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/banner.jpg\" alt=\"banner for open gl graphics framework showing parts of the gbuffer\"\/><noscript><img decoding=\"async\" src=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/banner.jpg\" alt=\"banner for open gl graphics framework showing parts of the gbuffer\"\/><\/noscript><\/figure>\n\n\n\n<p>This is my personal game engine implemented in C++, which I have been continuously plugging away at since 2016.<\/p>\n\n\n\n<p>The long term goal for this project is to have my own tech stack perfectly suited to serve as a baseline especially for space-sim games, but also be adaptable for other kinds of software projects and rendering tech demos. On the way there it has been an excellent testbed for me to test my programming ideas and lern new techniques. The codebase has grown to a considerable size over the years, and contains many systems which can be used for other projects &#8211; a lot of thought has been put into building a modular architecture that decouples systems so that they can be used on their own or replaced with others.<\/p>\n\n\n\n<p>Amongst it&#8217;s defining features is a planet rendering system that implements my own algorithm for smooth level of detail transitions (no popping) and consistent on-screen geometry density no matter the distance, which I adapted from planar CDLOD and wrote a <a href=\"https:\/\/www.leah-lindner.com\/img\/blog\/planet_renderer\/week5-6\/researchPaper.pdf\" target=\"_blank\" rel=\"noopener\">research paper<\/a> about.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignright is-resized\"><a href=\"https:\/\/github.com\/Illation\/ETEngine\"><img decoding=\"async\" class=\"ls_lazyimg\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_1x1.gif\" file=\"http:\/\/leah-lindner.com\/img\/graphics\/github.png\" alt=\"Link to the ETEngine github repository\" style=\"width:189px;height:auto\"\/><noscript><img decoding=\"async\" src=\"http:\/\/leah-lindner.com\/img\/graphics\/github.png\" alt=\"Link to the ETEngine github repository\" style=\"width:189px;height:auto\"\/><\/noscript><\/a><\/figure>\n<\/div>\n\n\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-64989fb1 wp-block-group-is-layout-flex\">\n<p>It has also contains a PBR scene renderer, a data driven asset conditioning pipeline and resource managment, and my own implementation of an archetype based Entity Component System with scene hierachy support &#8211; allowing for a data oriented development process. See below for a full feature breakdown, or <em>browse the codebase yourself on Github<\/em> &#8211;&gt;<\/p>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>The engine is written to be crossplatform and uses a render hardware interface that currently is implemented with OpenGL. You can find a full breakdown of all the libraries used <a href=\"https:\/\/github.com\/Illation\/ETEngine\/blob\/master\/Engine\/third_party\/README.md\" target=\"_blank\" rel=\"noopener\"><em>here<\/em><\/a>.<br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Features<\/h2>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"OpenGL Planet Renderer v3\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/a9mB9dGAXBs?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Rendering<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Realtime planet terrain generation (custom CDLOD)<\/li>\n\n\n\n<li>Precomputed atmospheric scattering based on Eric Brunetons <a href=\"https:\/\/github.com\/ebruneton\/precomputed_atmospheric_scattering\">implementation<\/a>.<\/li>\n\n\n\n<li>PBR and IBL pipeline<\/li>\n\n\n\n<li>Hierarchical Material System<\/li>\n\n\n\n<li>Deferred and forward rendering<\/li>\n\n\n\n<li>Cascading shadow maps<\/li>\n\n\n\n<li>Postprocessing shader support<br>(FXAA, Bloom, HDR)<\/li>\n\n\n\n<li>Environment Maps<\/li>\n\n\n\n<li>Starfield with real star data<\/li>\n\n\n\n<li>Frustum Culling<\/li>\n\n\n\n<li>GUI &amp; Distance field font rendering &#8211; Font generation from .TTF<\/li>\n\n\n\n<li>Stereoscopic normal encoding&nbsp;for optimization<\/li>\n\n\n\n<li>Texture Compression BC1-7<\/li>\n\n\n\n<li>Sprite and Primitve Rendering<\/li>\n\n\n\n<li>Abstract RHI with openGL backend, opengl state managment and automated texture binding<\/li>\n\n\n\n<li>Multi viewport support and generic scene rendering interface<\/li>\n\n\n\n<li>Render scene is decoupled from game scene to layout data optimized for rendering<\/li>\n\n\n\n<li>Mesh import with GLTF and Collada<\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"ETEngine Precomputed Atmospheric scattering\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/y8czF8O5XTU?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Framework<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Entity Component System\n<ul class=\"wp-block-list\">\n<li>Archetype based for cache friendly iteration<\/li>\n\n\n\n<li>Built in scene hierarchy<\/li>\n\n\n\n<li>Access patterns and dependency definitions allow automated execution order with support for MT<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Data driven asset conditioning pipeline\n<ul class=\"wp-block-list\">\n<li>Reflection system allows for automatic serialization and deserialization into both a binary format or JSON<\/li>\n\n\n\n<li>Resource manager with support for asset dependencies<\/li>\n\n\n\n<li>Content cooker converts from edit friendly formats to runtime optimized formats<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>GUI System built on top of RmlUI for weblike UI design<\/li>\n\n\n\n<li>WIP Editor with blender-like window managment and application framework<\/li>\n\n\n\n<li>3D audio with OpenAL &#8211; (.ogg(vorbis) and .vam(pcm) formats)<\/li>\n\n\n\n<li>Rigid Body Physics with BULLET<\/li>\n\n\n\n<li>Input manager<\/li>\n\n\n\n<li>Custom Math Library<\/li>\n<\/ul>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"ETEngine Bullet Physics Integration\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/-MHo11zFCOY?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Utility<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Extensive debug features:\n<ul class=\"wp-block-list\">\n<li>Trace and logging system collects logs from multiple executables on a single server<\/li>\n\n\n\n<li>ImGUI integration for debug features<\/li>\n\n\n\n<li>Debug console with various render debug commands<\/li>\n\n\n\n<li>Commandline commands<\/li>\n\n\n\n<li>HashStrings can be resolved back into regular strings for non shipping builds<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Memory managment with custom smart pointers<\/li>\n\n\n\n<li>Custom container types such as Slot maps and linear hash maps<\/li>\n\n\n\n<li>Platform Agnostic File System (currently Windows and Linux)<\/li>\n\n\n\n<li>Atomic types (int32, uint16)<\/li>\n\n\n\n<li>Performance measurment<\/li>\n\n\n\n<li>JSON and XML parsers<\/li>\n\n\n\n<li>Network Sockets<\/li>\n\n\n\n<li>Engine settings loaded from file<\/li>\n\n\n\n<li>Continous Integration on AppVeyor<\/li>\n\n\n\n<li>Unit testing with coverage for math, file &amp; asset IO, smart pointers, ECS<\/li>\n\n\n\n<li>CMake project generation<\/li>\n<\/ul>\n<\/div>\n<\/div>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image\"><img decoding=\"async\" class=\"ls_lazyimg\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_250x250.gif\" file=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/UpperAtmosphere.jpg\" alt=\"A screenshot showing deferred shading\"\/><noscript><img decoding=\"async\" src=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/UpperAtmosphere.jpg\" alt=\"A screenshot showing deferred shading\"\/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"317\" data-permalink=\"https:\/\/leah-lindner.com\/blog\/et_engine\/3dui\/\" data-orig-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI.jpg\" data-orig-size=\"1915,1075\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"3DUI\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-300x168.jpg\" data-large-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-1024x575.jpg\" data-id=\"317\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_250x250.gif\" file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-1024x575.jpg\" alt=\"\" class=\"wp-image-317 ls_lazyimg\"\/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"575\" data-attachment-id=\"317\" data-permalink=\"https:\/\/leah-lindner.com\/blog\/et_engine\/3dui\/\" data-orig-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI.jpg\" data-orig-size=\"1915,1075\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"3DUI\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-300x168.jpg\" data-large-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-1024x575.jpg\" data-id=\"317\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-1024x575.jpg\" alt=\"\" class=\"wp-image-317\" srcset=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-1024x575.jpg 1024w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-300x168.jpg 300w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-768x431.jpg 768w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-1536x862.jpg 1536w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI-1200x674.jpg 1200w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/3DUI.jpg 1915w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/noscript><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" data-attachment-id=\"316\" data-permalink=\"https:\/\/leah-lindner.com\/blog\/et_engine\/editor\/\" data-orig-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor.jpg\" data-orig-size=\"1921,1215\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Editor\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-300x190.jpg\" data-large-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-1024x648.jpg\" data-id=\"316\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_250x250.gif\" file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-1024x648.jpg\" alt=\"\" class=\"wp-image-316 ls_lazyimg\"\/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"648\" data-attachment-id=\"316\" data-permalink=\"https:\/\/leah-lindner.com\/blog\/et_engine\/editor\/\" data-orig-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor.jpg\" data-orig-size=\"1921,1215\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Editor\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-300x190.jpg\" data-large-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-1024x648.jpg\" data-id=\"316\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-1024x648.jpg\" alt=\"\" class=\"wp-image-316\" srcset=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-1024x648.jpg 1024w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-300x190.jpg 300w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-768x486.jpg 768w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-1536x971.jpg 1536w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor-1200x759.jpg 1200w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/Editor.jpg 1921w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><\/noscript><\/figure>\n<\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Architecture<\/h2>\n\n\n\n<p>Here is a rough overview of the engines architecture<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" data-attachment-id=\"319\" data-permalink=\"https:\/\/leah-lindner.com\/blog\/et_engine\/architecturediagram\/\" data-orig-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram.png\" data-orig-size=\"652,782\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"architectureDiagram\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram-250x300.png\" data-large-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram.png\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_250x250.gif\" file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram.png\" alt=\"\" class=\"wp-image-319 ls_lazyimg\"\/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"652\" height=\"782\" data-attachment-id=\"319\" data-permalink=\"https:\/\/leah-lindner.com\/blog\/et_engine\/architecturediagram\/\" data-orig-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram.png\" data-orig-size=\"652,782\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"architectureDiagram\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram-250x300.png\" data-large-file=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram.png\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram.png\" alt=\"\" class=\"wp-image-319\" srcset=\"https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram.png 652w, https:\/\/leah-lindner.com\/blog\/wp-content\/uploads\/2025\/12\/architectureDiagram-250x300.png 250w\" sizes=\"auto, (max-width: 652px) 85vw, 652px\" \/><\/noscript><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">History<\/h2>\n\n\n\n<p>This project started off in 2016 as an <a href=\"https:\/\/github.com\/Illation\/GLFramework\">OpenGL graphics framework<\/a> based on the &#8220;Overlord Engine&#8221; (Dx11) from the Graphics Programming course at <a href=\"https:\/\/www.digitalartsandentertainment.be\/\">Howest University<\/a><\/p>\n\n\n\n<p>In parallel I was writing my graduation work on <a href=\"https:\/\/github.com\/Illation\/PlanetRenderer\">realtime planet rendering<\/a>, and in 2017 I merged the two projects into this engine.<\/p>\n\n\n\n<p>Since then the engine has gone through a lot of foundational structural change in order to support a scalable game development approach, and the vast majority of code has been completely rewritten.<\/p>\n\n\n\n<p>I am pretty pleased with where the architecure is at now, the countless new quality of life features make working with the engine pleasant and fast, however there are a few things I would still like to complete until I consider the engine ready to support developing some smaller indie titles:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Roadmap<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Editor and UI<\/h3>\n\n\n\n<p>I am currently working on updating the editor from using GTK as a UI framework to using my own application and UI framework built on the runtime UI system running with RmlUI, as using GTK for crossplatform support has proven to be difficult to maintain on Windows, which is what most game developers use and should therefore be prioritized. This should also ensure that any UI features developed for the editor will be readily available for the game. The scene editor is also not complete, one of the primary features needed is property editing based on reflected data.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Framework<\/h3>\n\n\n\n<p>With the entity component system implemented, this is largely where it needs to be, however for future more complex games multithreading should be supported, which means implementing a job system and then plugging it into the ECS. This should go reasonably smoothly as ECS systems already differentiate between read and write access of components, which should make managing mutability straightforward to automate. I anticipate more work around asyncronous asset loading however. It would also be nice to use this to speed up content cooking.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rendering<\/h3>\n\n\n\n<p>To support more modern rendering techniques I intend to implement a DirectX 12 backend. This will require some changes to the RHI, including:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Introducing command lists as a concept. These will be written in a flat buffer and then consumed by each backend in order to be cache friendly and minimize virtual function calls.<\/li>\n\n\n\n<li>Introducting pipeline state objects. The RHI will consume backend agnostic PSO descriptors, and openGL will use this to manage its state, whereas DX12 will convert these descriptors to DX12 PSO descriptors and cache resulting PSOs based on these.<\/li>\n\n\n\n<li>Shaders are currently authored in GLSL and use individual uniforms. This will be switched to using HLSL and then translating shaders to GLSL using DXC and SPIRV-Cross. Uniforms will be replaced with CBVs and UAVs \/ their open GL equivalents, differentiating between Global \/ Per View \/ Per Material data etc. This will also help define a root signature for DX12 PSOs<\/li>\n\n\n\n<li>For DX12 memory managment including heaps and allocators will be implemented. To help I might use a library such as D3D12MA<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Other<\/h3>\n\n\n\n<p>The above summarises the main changes that will have foundational impact on the engines architecture. Most other features should be able to slot into the existing framework, and can therefore be implemented as needed by various projects. Some examples include controller support, a config data loader, particle systems or various modern rendering features.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Implementation<\/h2>\n\n\n\n<p>I occasionally document the implementation of various features on my blog, see various tags and categories if you&#8217;re interested:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Planet Rendering: <a href=\"https:\/\/leah-lindner.com\/blog\/category\/project\/planet-renderer\/\">https:\/\/leah-lindner.com\/blog\/category\/project\/planet-renderer\/<\/a><\/li>\n\n\n\n<li>Entity component system: <a href=\"https:\/\/leah-lindner.com\/blog\/tag\/entity-component-system\/\">https:\/\/leah-lindner.com\/blog\/tag\/entity-component-system\/<\/a><\/li>\n<\/ul>\n\n\n\n<p>Below are some semi outdated implementation details of how things where rendered in the past. I&#8217;m leaving them here for now because they are still somewhat interesting, however are due of an overhaul which I will probably do in the form of more blog posts.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deferred Rendering<\/h3>\n\n\n\n<p>Whether or not an object is rendered deferred depends on the material settings. Foreward rendering is supported to accomodate special shaders that don&#8217;t use the fixed shader workflow of the renderer, like for instance glass, emissive or toon shaders.<\/p>\n\n\n\n<p>In a first pass, all deferred objects render into the g-buffer, which splits the data into 3 rgb textures. The layout of this buffer is shown below. It takes data for position, normal, base color, black and white specular, black and white AO, metalness and roughness &#8211; in other words its designed to support physically based rendering.<\/p>\n\n\n\n<p>In order to use as little texture bandwidth as possible, the normal maps are encoded stereoscopically into two channels, and decoded in the second pass. An example of the first pass including normal map encoding can be found <a href=\"https:\/\/github.com\/Illation\/GLFramework\/blob\/master\/GLFramework\/Resources\/Shaders\/DefPBRMetShader.glsl\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/Illation\/GLFramework\/blob\/master\/GLFramework\/Resources\/Shaders\/PostDeferredComposite.glsl\" target=\"_blank\" rel=\"noopener\">In the second pass<\/a>, all the information is extracted from the g-buffer (the normal maps are decoded again) and used for whatever form of shading is required, including lighting information. This step is applied on a framebuffer.<\/p>\n\n\n\n<p>Once the deferred passes are complete, all objects with materials using forward rendering are rendered on top of this. In order tomake it look like they integrate seemlessly and are not just rendered on top, the z-buffer from the deferred render pass is copied so that the depth test fails if a forward rendered object is sitting behind a deferred rendered object. The <a href=\"https:\/\/github.com\/Illation\/GLFramework\/blob\/master\/GLFramework\/SceneGraph\/AbstractScene.cpp\" target=\"_blank\" rel=\"noopener\">rendering pipeline code<\/a> is executed in the root draw of each scene.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" class=\"ls_lazyimg\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_250x250.gif\" file=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/gbuffer.jpg\" alt=\"Graphic showing the layout of the Gbuffer in the open gl framework\"\/><noscript><img decoding=\"async\" src=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/gbuffer.jpg\" alt=\"Graphic showing the layout of the Gbuffer in the open gl framework\"\/><\/noscript><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Shading with multiple lights<\/h3>\n\n\n\n<p>The shading part of the framework is done with full support for Physically Based rendering.<\/p>\n\n\n\n<p>Currently it supports directional \/ sun lights and point lights with inverse square falloff. They are implemented as components of an entity, and when rendering they are rendered as volumes which enables the utilization of Frustum culling when the light source wouldn&#8217;t be visible from the cameras perspective.<\/p>\n\n\n\n<p>The rendering pipeline also supports the use of a single HDR environment map, which stores roughness information in its mipmaps for PBR support.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" class=\"ls_lazyimg\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_250x250.gif\" file=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/DeferredBloom.jpg\" alt=\"Screenshot of the open gl shading with multiple lights\"\/><noscript><img decoding=\"async\" src=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/DeferredBloom.jpg\" alt=\"Screenshot of the open gl shading with multiple lights\"\/><\/noscript><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Postprocessing<\/h3>\n\n\n\n<p>The postprocessing step utilizes <a href=\"https:\/\/github.com\/Illation\/GLFramework\/blob\/master\/GLFramework\/Graphics\/FrameBuffer.hpp\" target=\"_blank\" rel=\"noopener\">framebuffers<\/a> with glsl shaders similar to the other 3d shaders, but on a screenspace plane. All prior render passes are rendered to the framebuffer textures until the last postprocessing step has been applied, which in turn renders to the backbuffer and presents.<\/p>\n\n\n\n<p>This allows techniques such as <a href=\"https:\/\/github.com\/Illation\/GLFramework\/blob\/master\/GLFramework\/Resources\/Shaders\/PostHDR.glsl\" target=\"_blank\" rel=\"noopener\">high dynamic range rendering<\/a>, which in turn enables&nbsp;adjusting the camera exposure. It could come in handy when dealing with high contrast environments such as indoor vs outdoor settings or space scenes with a bright planet and sun but rather dark starfield.<\/p>\n\n\n\n<p>Further more gamma correction allows for a linear texture workflow for more accurate shading, and as a result all textures <a href=\"https:\/\/github.com\/Illation\/GLFramework\/blob\/master\/GLFramework\/Content\/TextureLoader.cpp\" target=\"_blank\" rel=\"noopener\">can be loaded<\/a> either in&nbsp;srgb or linear rgb mode.&nbsp;Less common effects such as toon shading (for instance a sobel filter for outlines) can also be applied.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" class=\"ls_lazyimg\" src=\"https:\/\/leah-lindner.com\/blog\/wp-content\/plugins\/images-lazyload-and-slideshow\/blank_250x250.gif\" file=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/PBR.jpg\" alt=\"Screenshot of the open gl postprocessing with tonemapping (gamma | exposure)\"\/><noscript><img decoding=\"async\" src=\"http:\/\/leah-lindner.com\/img\/projects\/gl_framework\/PBR.jpg\" alt=\"Screenshot of the open gl postprocessing with tonemapping (gamma | exposure)\"\/><\/noscript><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is my personal game engine implemented in C++, which I have been continuously plugging away at since 2016. The long term goal for this project is to have my own tech stack perfectly suited to serve as a baseline especially for space-sim games, but also be adaptable for other kinds of software projects and &hellip; <a href=\"https:\/\/leah-lindner.com\/blog\/et_engine\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Extra Terrestial Engine&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-146","page","type-page","status-publish","hentry"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/leah-lindner.com\/blog\/wp-json\/wp\/v2\/pages\/146","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/leah-lindner.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/leah-lindner.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/leah-lindner.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/leah-lindner.com\/blog\/wp-json\/wp\/v2\/comments?post=146"}],"version-history":[{"count":10,"href":"https:\/\/leah-lindner.com\/blog\/wp-json\/wp\/v2\/pages\/146\/revisions"}],"predecessor-version":[{"id":322,"href":"https:\/\/leah-lindner.com\/blog\/wp-json\/wp\/v2\/pages\/146\/revisions\/322"}],"wp:attachment":[{"href":"https:\/\/leah-lindner.com\/blog\/wp-json\/wp\/v2\/media?parent=146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}