Giter Site home page Giter Site logo

sigmarik / graphics-engine Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 0.0 2.97 MB

Tiny game development framework.

License: MIT License

C++ 90.41% C 8.87% Makefile 0.17% GLSL 0.30% CMake 0.09% Python 0.17%
3d framework gamedev graphics opengl physics

graphics-engine's Introduction

  A_,,,_A   
 ((O)V(O))     Psst, here, have a game dev framework: https://github.com/Sigmarik/graphics-engine
(w\W|W|W/w) 
 \v|W|W|v/ 
   "|v|"   
    ^ ^    

graphics-engine's People

Contributors

nerfiti avatar sigmarik avatar

Stargazers

 avatar

Watchers

 avatar

graphics-engine's Issues

Skeletal animation

The ability to import, play, blend and modify skeletal animations.

The feature is rather massive and could require a separate subsystem to manage animations.

Animation behaviour classes for individual pose management would probably do the trick, but the classic approach of interpolation spaces is also worth considering.

Animation behaviour draft:

struct AbstractAnimator {
    virtual ~AbstractAnimator() = default;

    virtual void solve(Pose& pose) const = 0;
};

struct LinearPlayback : public AbstractAnimator {
    void solve(Pose& pose) const override;

    void set_animation(const Animation& animation);
    void set_playback_time(double time);

    . . .
};

<template class Dot = glm::vec2>
struct BlendSpace : public AbstractAnimator {
    void solve(Pose& pose) const override;

    void set_playback_time(double time);
    void set_blend_position(const Dot& position);
    void add_animation(const Animation& animation, const Dot& position);

    . . .
};

struct InverseKinematicsSolver : public AbstractAnimator {
    void solve(Pose& pose) const override;

    void set_target(const glm::vec3& target);
    void set_root(const Armature::BoneId& root_id);

    . . .
};

Collision boxes bug out if their transform is not a unit matrix

Box collider transformation matrix does not get applied to the response vector, meaning the function returns local space response while reading input in world space coordinates.

Bug source:

Intersection SphereCollider::intersect_box(const BoxCollider& box) const {
    glm::mat4 world_to_collider = glm::inverse(box.get_transform());

    glm::vec4 local_center = world_to_collider * glm::vec4(origin_, 1.0);
    // Transition to the local space and response calculations are fine

    . . .

    // But no inverse calculation gets performed on the collision response
    return closest;
}

Mesh group import

It would be cool to have an importer able to import complete models with multiple parts and materials.

// MultiModel is a draft name and should be changed

MultiModel* model = AssetManager::request<MultiModel>("models/oak_01.obj");

Possible interface

Assimp allows to read material names and basic properties. Properties are kind of useless, as the framework implements completely different material system, but the name can be used as a path to the material representation inside the framework.

For example, if a tree model is supposed to use two materials (materials/leaves.material.xml and materials/bark.material.xml), it could have placeholder materials named "materials/leaves.material.xml" and "materials/bark.material.xml" inside its native representation, which will be replaced with actual materials during import.

# tree.obj

o TreeLeaves
. . .
usemtl materials/leaves.material.xml
. . .

o TreeStem
. . .
usemtl materials/bark.material.xml
. . .
<!-- materials/leaves.material.xml -->

<material>
    <shader path="shaders/wavy.shader.xml"></shader>
    <texture uniform="albedo" path="textures/leaves.png"></texture>
</material>
<!-- materials/bark.material.xml -->

<material>
    <shader path="shaders/solid.shader.xml"></shader>

    <texture uniform="albedo" path="textures/bark.png"></texture>
    <texture uniform="normal" path="textures/bark_nm.png"></texture>
    <texture uniform="roughness" path="textures/bark_rs.png"></texture>
    <texture uniform="ao_map" path="textures/oak_01_ao.png"></texture>
    <texture uniform="mtl_ao_map" path="textures/bark_ao.png"></texture>

    <!-- other material uniforms -->

</material>

Grid search data structure

A structure that would improve area-based object handling.

Something like a grid system of the physics engine, but for abstract bounding box - able objects.

Draft:

// `Box T::get_bounding_box() const` should exist
template<class T>
struct Grid {
    Grid(const Box& boundary, const glm::vec3& cell_size);

    void register(const T& object);
    Grid<T>::Iterator request(const Box& search_box);

    void remove(const T& object);

    void prepare_shift(const T& object);
    void process_shifts();
}

External material uniform specification

It is impossible to define material uniform from outside of the material itself, which is a problem, considering materials exist as assets and their modification is prohibited.

Material instances may be the solution.

Sound system

An entirely new framework subsystem for "advanced" audio playback.

Should implement audio scene (with stereo sound?), sound emitters and modifiers, optional compositors.

This feature request requires some research about sound systems before anyone could proceed with the designing and coding part.

Collider importer

Implement static collision importers, be that direct read from a model file or from an xml descriptor.

IMPORTER(BoxGroup, "obj") {
    // Detect defining model parts
    // Boxes labeled with a `_box_` prefix?
}

IMPORTER(BoxGroup, "collision") {
    // Directly read collision box group data defined in xml format
}

Rewrite the README of the project

The project is not just a mini-billiard. It is a framework that uses the described game as a showcase project, and the README.md file should reflect that.

Surface decalability

There should be exceptions to the rule that decals apply to anything.

It is theoretically possible to store an 8-bit binary mask in the 4-th channel of the surface g-buffer, yet true-false decalability would probably also be sufficient.

Surface g-buffer:
[ Roughness | Specular | AO | Decal mask ]
Decal mask:
[ DT0 | DT1 | DT2 | DT3 | DT4 | DT5 | DT6 | DT7 ]

--- or ---

Surface g-buffer:
[ Roughness | Specular | AO | Decalability ]
Decalability:
~ 1.0 - decals should stain the surface
~ 0.0 - decals should have no affect on the surface

DTi - i-th decal type bit. Determines if i-th decal type can stain the surface.

Make asset manager return `std::optional<const T&>` instead of `const T*`

Asset manager denies request for an asset if it can not find the asset or an importer that could process it. Thus, the AssetManager::request<T>(const char*) method returns pointer to the asset or nullptr.
This would be a reasonable behaviour for a module written in C, but the AssetManager is probably the least C-like module of the framework.

Float, vector and other constant material uniforms in asset files

Having to define even the smallest constant material parameters through textures is annoying and inefficient.

Such change would require a Material class refactor in order to support uniform mappings, not to mention importer modification, but it is a mush-have feature for advanced material definition.

Flag scene import/export

We need some way to edit scenes, but we are too lazy to design level editor ourselves. The solution - use already existing program.
This way we will need to implement only the transition from the editor program to the framework.

Blender allows object to have user defined properties, as well as has support for python-based custom exporters.
That means that it is possible to interpret blender scene objects with specific properties as framework-defined objects and treat them as such during export to custom .xml scene descriptor.

Asset flow

[.blend file defining a bunch of semi-empty models (flags) with lists of object-defining properties]

=> blender-sided python script =>

[.xml scene descriptor]

<!-- scene descriptor draft -->
<!-- REQUIRES REVIEW AND CONFIRMATION -->

<scene>
    <collider name="_box_house_wall_south">
        <size x="1.0" y="1.0" z="1.0">
        <transform>
            . . .
        </transform>
    </collider>

    <static_mesh name="tree_1024">
        <!-- expands to object group -->
        <file path="models/tree.obj"></file>
        <transform>
            . . .
        </transform>
    </mesh>
    
    <static_mesh name="rock_516">
        <!-- expands to object group -->
        <file path="models/rock.obj"></file>
        <transform>
            . . .
        </transform>
    </mesh>
    
    <spawner name="gazebo_spawner">
        . . .

        <send when="dead" target="fireworks_trigger">
            <set var="state" value="active"></set>
        </send>
    </spawner>

    <box_trigger name="fireworks_trigger">
        <size xyz = . . .><\size>
        <transform>
            . . .
        </transform>
        
        <filter>
            <player></player>
            <entity guid="$shopkeeper_spawner.last_spawned"></entity>
            <entities guids="$gazebo_spawner.fight_participants"></entities>
            
            <effect type="explosion"><\effect>
            <effect type="fire"><\effect>
        </filter>

        <activity state="inactive"></active>
        <send when="enter" target="celebratory_fireworks">
            <trigger event="shoot"></trigger>
        </send>
    </box_trigger>
    
    . . .
</scene>
// Loadable level initialization draft
// REQUIRES REVIEW AND CONFIRMATION

// spawner.h
struct Spawner : public SceneComponent {
    Spawner(const tinyxml2::XMLElement* descriptor);

    . . .
};

// loadable_level.h
struct LoadableLevel : public Scene {
    // Some overridable way of object registration by its descriptor.

   protected:
    friend void read_spawner(LoadableLevel& level, const tinyxml2::XMLElement* descriptor);

    ComponentRegistry<Spawner> spawners_;
};
// loadable_level.cpp

void LoadableLevel::pseudo_constructor() {
    register_reader("spawner", read_spawner);
}

read_spawner(LoadableLevel& level, const tinyxml2::XMLElement* descriptor) {
    Spawner* spawner = level.spawners_.insert(Spawner(descriptor));

    // void Scene::register_component(SceneComponent& component);
    level.register_component(*spawner);
}

Define project inheritance rules

We should make it easier to fork the project and pull changes from it without having to deal with merge conflicts in src.

There is no way to make a fork of the project and be able to pull changes to the framework from the main repo without resetting everything in the src folder without tediously picking files to ignore.

I think moving current game-related assets to the separate repository would be a wise thing to do in this case.

This solution is not ideal, as it would require careful manipulations with remotes while pushing something from a local project to the framework, but this issue appears to be solvable with the right GH actions setup.

  framework  |  some_fw_based_project
assets       | assets
lib          | lib
make         | make
lib.flist    | lib.flist
. . .        | . . .
             |
             | src
             | src.flist
             | . . .

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.