GithubHelp home page GithubHelp logo

sfederic / vengine Goto Github PK

View Code? Open in Web Editor NEW
51.0 4.0 3.0 378.69 MB

Game engine framework using DirectX 11, Direct2D, DirectWrite, Qt, FBX SDK, ImGui/ImGuizmo and PhysX

C++ 81.54% HLSL 0.27% C 16.30% Objective-C 0.22% Objective-C++ 1.17% Shell 0.01% GLSL 0.01% CMake 0.04% Kotlin 0.02% Makefile 0.30% HTML 0.03% Batchfile 0.10% GDB 0.01%
directx-11 direct2d xaudio2 win32 fbx-sdk qt5 imgui imguizmo physx directxtk

vengine's Introduction

VEngine

Note that this repository isn't for general use, it's more of an open source snapshot of an intermediate engine being developed alongside a game. Feel free to go through and take snippets of code and apply them to your own projects.

image

Build/Usage Notes

Helpful Fork [#3] to build using premake. Thanks to https://github.com/ignite720

  • Visual Studio 2022 17.8
  • Blender 3.4

Packages

DirectXTK (directxtk_desktop_win10) ver. 2021.8.2.1 - https://github.com/microsoft/DirectXTK

Third Party Libraries:

(The ImGui libs are already included in the repo)

Helpful Extensions

Overview

As this engine is more of a learning project for onlookers and myself, the techincal outset of the engine was to keep it simple and mostly in C++ with minimal use of other programming languages; that means usage of the C++ standard library and attempted usage of modern C++ concepts.

Below is a quick outline of various concepts the engine uses.

Game Object Model

Actors

The engine uses an Actor/Component model similar to Unity and Unreal. The inspiration came from Rare's presentation on Actor Ticks in UE4 in Sea of Thieves [https://www.youtube.com/watch?v=CBP5bpwkO54].

(A good starting reference on Game Object Models https://www.youtube.com/watch?v=jjEsB611kxs)

An inherited actor will be defined with a system via a macro.

struct Enemy : Actor
{
    //essentially defines 'inline static ActorSystem<Enemy> system;'
    ACTOR_SYSTEM(Enemy);

    void Tick(float deltaTime) override;
};

Actor Systems

Both Actors and Components have Systems. A system essentially looks like:

template <typename ActorType>
struct ActorSystem : IActorSystem
{
    std::vector<ActorType*> actors;

    void Tick(float deltaTime) override
    {
        for(auto actor : actors)
        {
            actor->Tick(deltaTime);
        }
    }
}

Worlds

A 'World' is the current view of the scene on-screen. Each World will have lists of the currently active Actor and Component systems.

struct World
{
    std::vector<IActorSystem*> actorSystems;
    std::vector<IComponentSystem*> componentSystems;

    void Tick(float deltaTime)
    {
        TickAllActorSystems(deltaTime);
        TickAllComponentSystems(deltaTime)
    }
}

Actor and Component Properties

For serialisiation, Actors and Components define their properties to be fetched at run-time.

struct Enemy : Actor
{
    int attack = 5;
    
    Properties GetProps() override
    {
        Properties props = Actor::GetProps();
        props.Add<int>("Attack", &attack);
        return props;
    }
}

Properties is a collection of Propertys. VEngine uses the typeid() from Properties::Add<T>() to infer the type.

struct Property
{
    std::optional<std::type_info> type;
    void* value;
}

struct Properties
{
    std::map<std::string, Property> propertyMap;

    template <typename T>
    void Add(std::string propertyName, T* propertyValue)
    {
        Property property;
        property.type = typeid(T);
        property.value = propertyValue;

        propertyMap.emplace(propertyName, property);
    }
}

Serialisation

Using Properties, serialisation infers property types by checking for a matching typeid().

void Serialiser::Serialise(Properties& properties)
{
    for (Property& property : properties)
    {
        if (property.type == typeid(int))
        {
            SerialiseInt<int>(property.value);    
        }
    }
}

World Save File

Files with the .vmap extension describe the layout of a level in-game. Below is an example of the text format to show how properties map to values.

Enemy  //This type name fetches the appropriate system (in this case an Actor class of 'Enemy').
13     //This is how many instances of the class to create.
Attack //Property name.
16     //Property value.
next   //Move onto the next Enemy instance...
Attack
3

Rendering

VEngine uses DirectX 11 for 3D/2D rendering and DirectWrite + Direct2D for in-game UI.

FBX Importing

VEngine uses the official FBX SDK to import models and animations. While not very robust, details can be gleamed in https://github.com/sfederic/VEngine/blob/7259295eb490466392d2f999852f023e92c7182a/VEngine/Code/Asset/FBXLoader.cpp

Game UI

For in-game UI, an immediate approach is used. An example in-game widget would be declared like so:

struct EnemyText : Widget
{
    std::string text;

    void Draw() override
    {
        Layout layout = AlignLayoutByScreenPercent(0.1, 0.9, 0.1, 0.2);
        DrawText(text, layout);
    }
}

Physically Based Shading

While not a huge component of the engine, the implementations were taken from EA's Frostbite engine [https://www.ea.com/frostbite/news/moving-frostbite-to-pb].

Global Illumination

VEngine uses a very simple Global Illumination technique using light probes spread around a level uniformly. Leveraging the DirectXSH spherical harmonics library (good reference for DirectX 11 [https://interplayoflight.wordpress.com/2021/12/31/occlusion-and-directionality-in-image-based-lighting-implementation-details/]), each probe takes a cubemap snapshot of its surroundings an encodes it using spherical harmonics. Actors then just find their closest probe and apply its colours per vertex normal.

References for this system were mainly taken from Bluepoint's Shadow of the Colossus [https://gdcvault.com/play/1027011/Advanced-Graphics-Summit-Lifting-the] and Sonic Unleashed [https://www.gdcvault.com/play/1428/Global-Illumination-in-SONIC].

Skeletal Animation (FBX) with Blender Workflow

To import skeletal .fbx animations via Blender:

  • Add an Armature and bone structure to a mesh in Blender

image

  • hit Ctrl+P to parent the mesh to the armature and automate the weights

image

  • Record the poses using the Timeline and Dope Sheet -> Action Editor windows

image

  • Use the Non-Linear Animation window to organise animations

image

  • Export as an FBX with these settings, including all animations

image

Setup Skeletal mesh in code

Note that a seperate .vmesh file of the mesh is needed without animations baked in (but with the same bone structure as the animations), assigned as the mesh of a SkeletalMeshComponent, where then the imported FBX animations are linked to.

For example:

class AnimCube : public Actor
{
public:
	AnimCube()
    {
        skeletalMesh = CreateComponent("Skeleton", SkeletalMeshComponent("anim_cube.vmesh", "texture jpg"));
        rootComponent = skeletalMesh;
    }

    void Start() override
    {
        skeletalMesh->PlayAnimation("move");
    }

private:
	SkeletalMeshComponent* skeletalMesh = nullptr;
}

References and Helpful Links

Below is a collection of the most influential articles, tutorials, talks and concepts for development of the engine over time.

Game Object Component Models

Global Illumination

Navigation

FBX SDK

Audio

Cameras

Animation

Mesh Slicing

Dialog Editor

Editor UI Design

Transform Gizmo

Shadow Mapping

vengine's People

Contributors

ignite720 avatar sfederic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

vengine's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.