Skip to content

zhangdoa/InnocenceEngine

Repository files navigation

Innocence Engine

Screen capture Trello website Codacy Badge CodeFactor GPL-3.0 licensed FOSSA Status Blog Twitter Follow

Appveyor Windows Appveyor macOS Appveyor Linux

"A poet once said, 'The whole universe is in a glass of wine.'" -- Richard Feynman, 1963

Simplified Architecture

Architecture

Features

  • Strict Entity–Component–System architecture, No OOP overhead/console-like programming experience/allow unlimited feature module extension.
// the "E"
auto l_testEntity = g_Engine->getEntityManager()->Spawn(false, ObjectLifespan::Scene, "testEntity/");

// the "C"
auto l_testTransformComponent = g_Engine->getComponentManager()->Spawn<TransformComponent>(l_testEntity, false, ObjectLifespan::Scene);

l_testTransformComponent->m_localTransformVector.m_pos = Vec4(42.0f, 1.0f, PI<float>, 1.0f);

// the engine has several "S" to handle the engine-side businesses, while users have the freedom to implement their own systems
class TestSystem : public ISystem {};
  • Custom container, string and math classes, minimum STL overhead/No 3rd-party math library dependency.
RingBuffer<float> l_testRingBuffer(32);
// All custom containers have a thread-safe version
Array<float, true> l_testThreadSafeArray;
FixedSizeString<64> l_testString;

l_testString = "Hello,World/";

for (size_t i = 0; i < l_testString.size(); i++)
{
	l_testRingBuffer.emplace_back((float)i);
}

l_testThreadSafeArray.reserve();
l_testThreadSafeArray.emplace_back(l_testRingBuffer[42]);

auto l_maxPoint = Vec4(l_testThreadSafeArray[0], l_testRingBuffer[1], l_testRingBuffer[16], 1.0f);
auto l_minPoint = Vec4(42.0f, l_testThreadSafeArray[0], -l_testRingBuffer[16], 1.0f);

auto l_testAABB = InnoMath::generateAABB(l_maxPoint, l_minPoint);
  • Job-graph based parallel task model, fully utilize modern hardware/lock-free in client logic code.
std::function<void()> f_JobA;
f_JobA = []()
{
	g_Engine->getLogSystem()->Log(LogLevel::Warning, "I'm worried that C++ would be quite a mess for me.");
};

auto f_JobB = [=](int val)
{
	g_Engine->getLogSystem()->Log(LogLevel::Success, "There are always some user-friendly programming languages waiting for you, just search for more than ", val, " seconds you'll find them.");
	return true;
};

// Job A will be executed on thread 5 as soon as possible
auto l_testTaskHandleA = g_Engine->getTaskSystem()->Submit("ANonSenseTask", 5, nullptr, f_JobA);

// Job B will be executed with a parameter just after Job A finished
auto l_testTaskHandleB = g_Engine->getTaskSystem()->Submit("NotANonSenseTask", 2, l_testTaskHandleA.m_Task, f_JobB, std::numeric_limits<int>::max());

// Blocking-wait on the caller thread
l_testTaskHandleB.m_Task->Wait();
// Or use with a Producer-Customer model
auto l_testResult = l_testTaskHandleB.m_Future->Get();
  • Object pool memory model, O(1) allocation/deallocation.
struct POD
{
	float m_Float;
	int m_Int;
	void* m_Ptr;
};

auto l_objectPoolInstance = TObjectPool<POD>::Create(65536);
auto l_PODInstance =l_objectPoolInstance->Spawn();
l_PODInstance->m_Float = 42.0f;
l_objectPoolInstance->Destroy(l_PODInstance);
TObjectPool<POD>::Destruct(l_objectPoolInstance);
  • Logic Client-as-a-plugin style, the only coding rule is using the engine's interfaces to write your gameplay code and write whatever you want.

  • The major graphics API support, from OpenGL 4.6 to DirectX 11, from DirectX 12 to Vulkan, and Metal, all supported by one unified interface.

  • Client-Server rendering architecture, supports any kind of user-designed rendering pipeline from the first triangle draw call to the last swap chain presentation.

auto l_renderingServer = g_Engine->getRenderingServer();

// m_RPDC = l_renderingServer->AddRenderPassDataComponent("LightPass/");
l_renderingServer->CommandListBegin(m_RPDC, 0);
l_renderingServer->BindRenderPassDataComponent(m_RPDC);
l_renderingServer->CleanRenderTargets(m_RPDC);
l_renderingServer->BindGPUResource(m_RPDC, ShaderStage::Pixel, m_SDC, 17);
l_renderingServer->DrawIndexedInstanced(m_RPDC, m_quadMesh);
l_renderingServer->CommandListEnd(m_RPDC);

// Execute on separate threads
l_renderingServer->ExecuteCommandList(m_RPDC);
l_renderingServer->WaitForFrame(m_RPDC);
  • Physically-based lighting, photometry lighting interface with support of real life light measurements like color temperature, luminous flux and so on.

  • Default rendering client support features like:

    • Tiled-deferred rendering pipeline
    • Retro Blinn-Phong/Classic Cook-Torrance BRDF (Disney diffuse + Multi-scattering GGX specular) for opaque material
    • OIT rendering (w.r.t. transparency and thickness)
    • SSAO
    • CSM with VSM/PCF filters
    • Procedural sky
    • Large scale terrain rendering with cascaded tessellation
    • Motion Blur
    • TAA
    • ACES tone mapping
  • Real-time GI, baked PRT for the complex large scale scene or bake-free SVOGI for the limited small scale scene, fully dynamic and lightmap-free.

  • Unified asset management, using popular JSON format for all text data and support easy-to-use binary data I/O.

  • Physics simulation, NVIDIA's PhysX integrated.

  • GUI Editor, Qt-based, easy to extend, easy to modify.

And so on...

How to build?

All scripts are in /Script folder

Windows

Tested OS version: Windows 11 version 22H2

Prerequisites
  • MSVC 17.53+ (engine-only)
  • CMake 3.26+
  • Qt Creator 10.0.0+
  • MSVC 16.11.25+ (editor-only)

Build Engine

Run following scripts will build Debug and Release configurations in parallel:

SetupWin.ps1
BuildAssimpWin.ps1
BuildPhysXWin.ps1
BuildGLADWin.ps1
BuildEngineWin.ps1
PostBuildWin.ps1

Build Editor

  1. Open Source\Editor\InnoEditor\InnoEditor.pro with Qt Creator
  2. Change "Projects - Build Settings - General - Build directory" to ..\..\..\Bin for Debug, Profile and Release build configurations
  3. Change "Projects - Run Settings - Run - Working directory" to ..\..\..\Bin
  4. Build the project

Linux

Tested OS version: Ubuntu 18.04 LTS

Prerequisites
  • GCC 8.0 or Clang 7.0 or higher
  • CMake 3.10 or higher
  • OpenGL library(lGL)

Build Engine

Run following scripts:

echo | SetupLinux.sh
echo | BuildAssimpLinux.sh
echo | BuildGLADLinux.sh
echo | BuildEngineLinux.sh # or BuildLinux-Clang.sh or BuildLinux-CodeBlocks.sh
echo | PostBuildLinux.sh

macOS

Tested OS version : macOS 10.13.6, 10.15.4

Prerequisites
  • CMake 3.10 or higher
  • Apple Clang 10.0 or LLVM Clang 8.0 or higher

Build Engine

Run following scripts:

echo | SetupMac.sh
echo | BuildAssimpMac-Xcode.sh
echo | BuildGLADMac-Xcode.sh
echo | BuildEngineMac-Xcode.sh
echo | PostBuildMac.sh

How to use?

  1. Implement ILogicClient and IRenderingClient classes and put the implementation source file inside Source/Client/LogicClient and Source/Client/RenderingClient
  2. Change the CMake variable INNO_LOGIC_CLIENT and INNO_RENDERING_CLIENT in Source\CMakeLists.txt to your client modules class name
  3. Build engine and launch through Bin/${BuildConfig}/InnoEditor.exe or Bin/${BuildConfig}/InnoMain.exe on Windows, or corresponding executable file on Linux and macOS

How to debug

Windows

  1. Open the workspace folder in VSCode.
  2. Set debug launch arguments in ./vscode/launch.json.
  3. Start debug with "Launch" button (default F5)

Linux

  1. Use Atom to load the working copy folder
  2. Install gcc-compiler package
  3. Select build/makefile and hit "Compile and Debug" button (default F6)
  4. (Optional) Change launch arguments in Source/Engine/Platform/LinuxMain/CMakeLists.txt

macOS

  1. Open Build/InnocenceEngine.xcodeproj
  2. Select "Product" - "Run" (⌘ + R)

How to bake scene?

Windows

Run following script:

BakeScene.ps1 -sceneName [scene file name without extension]

Available launch arguments

-mode [value]
Value Notes
0 engine will handle the window creation and event management, for "slave-client" model like the normal game client
1 engine requires client providing an external window handle, for "host-client" model like the external editor
-renderer [value]
Value --- Notes
0 OpenGL Not available on macOS, currently supported version 4.6 (Deprecated)
1 DirectX 11 Only available on Windows, currently supported version 11.4 (Deprecated)
2 DirectX 12 Only available on Windows, currently supported version 12.1
3 Vulkan Not available on macOS, currently supported 1.1.92.1 (WIP)
4 Metal Only available on macOS, currently supported version 2 (WIP)
-loglevel [value]
Value Notes
0 print verbose level and all the other higher level log messages
1 only print success level and higher level log messages
2 only print warning level and higher level log messages
3 only print error level log messages

Shader languages compatibilities

You need DirectXShaderCompiler to generate compiled shader for runtime

  • Run Scripts/HLSL2DXIL.ps1 to generate DXIL file from HLSL shader file for DirextX 12
  • Run Scripts/HLSL2SPIR-V.ps1 to generate SPIR-V file from HLSL shader file for Vulkan
  • Run Scripts/ParseGLSL.bat then GLSL2SPIR-V.bat to generate SPIR-V file from GLSL shader file for OpenGL (Deprecated)

License

FOSSA Status

References & Dependencies

Third-party libraries

assimp

GLAD

dear imgui

stb

JSON for Modern C++

PhysX

Assets

Free3D

Musopen

Free PBR Materials

HDR Labs

Inspirations

Books

C++ Primer (4th Edition)

A Tour of C++

Effective C++: 55 Specific Ways to Improve Your Programs and Designs (3rd Edition)

Inside the C++ Object Model (1st Edition)

Effective Modern C++: 42 Specific Ways to Improve Your Use of C++11 and C++14

API Design for C++ (1st Edition)

Advanced C and C++ Compiling (1st Edition)

Data Structures and Algorithms in C++ (4th Edition)

Game Engine Architecture (1st Edition)

Game Programming Patterns

Game Coding Complete (4th Edition)

Real-Time Rendering (4th Edition)

Physically Based Rendering : From Theory to Implementation(2nd Edition)

Computer Graphics with Open GL (4th Edition)

OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 4.5 with SPIR-V (9th Edition)

Calculus (6th Edition)

Linear Algebra and Its Applications (3rd Edition)

And more...

Online tutorials & resources

cppreference.com

Standard C++

Modernes C++

Mathematics - Martin Baker

Wolfram MathWorld: The Web's Most Extensive Mathematics Resource

GameDev.net

Gamasutra

Scratchapixel

Advances in Real-Time Rendering in 3D Graphics and Games

OpenGL Wiki

Learn OpenGL

OpenGL Step by Step

DirectX 11 official documents

DirectX 12 official documents

RasterTek - DirectX 10, DirectX 11, and DirectX 12 tutorials

Vulkan official documents

Vulkan Tutorial

Metal official documents

Sébastien Lagarde's blog

Stephen Hill's blog

thebennybox's YouTube channel

Randy Gaul's Game Programming Blog

And more...