Giter Site home page Giter Site logo

kyle-emmerich / blueshift-engine Goto Github PK

View Code? Open in Web Editor NEW
9.0 9.0 1.0 55.76 MB

High performance C++ game engine in early development

Home Page: https://noxastra.com/engine

License: BSD 3-Clause "New" or "Revised" License

C++ 54.98% C 0.09% C# 5.98% Shell 9.48% SuperCollider 0.22% Batchfile 0.45% GLSL 13.92% Lua 9.25% Objective-C 5.63%

blueshift-engine's People

Contributors

kyle-emmerich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

takaaptech

blueshift-engine's Issues

Event system

There is an experimental class under Experiments/EventStream that can store event objects for another system to read. Right now, it supports basic synchronization in that it can only read OR write; not both.

Features:

  • Circular buffer for storing events
  • Basic synchronization
  • Filtered delegates
  • Simultaneous read/write
  • Dynamic heuristic-driven buffer sizing

Since this will be a very core concept for Blueshift, it needs to be very fast and must avoid cache misses when possible. Much of this is dependent on user code though; slow event processing will lead to a lot of thread preemption by the operating system and will thrash the cache.

Engine Core

The engine core needs to be finished before all else. This includes the runtime loop, subsystem instantiation, and configuration loading.

  • Runtime loop
  • Timing library
  • Subsystem instantiation
  • Config. loading

Model loading

Blueshift should be limited in model format support in order to keep codebase size down. Very seldom will anyone actually need to load any format at runtime. Models should be compiled to the simplest binary form and loaded almost 1 to 1 to the GPU for maximum runtime performance; perhaps even gzipped.

Therefore, Blueshift will support exactly one model format: its own compiled binary format. For everything else, there will be command-line tools to compile other formats into this.

  • Loading of Blueshift Binary Model (.bbm) format (see issue #9)
  • Compilation of OBJ -> BBM
  • Compilation of IQM -> BBM
  • Compilation of IQE -> BBM
  • Compilation of FBX - > BBM

Math Library

The math library is an important part of any game engine and has a profound effect on the game developer's impression of the engine. Our API must be good, and it also must be fast.

Therefore, C++11 and greater will be used for full effect.

  • Vector2, Vector3, Vector4
  • Matrix3, Matrix4
  • Quaternion
  • AABB
  • AABB to AABB intersection
  • Ray to AABB intersection
  • OBB

Start using issues again

Issues are useful for keeping a roadmap but can be a hassle to keep up with. It is worth it to maintain this though.

Lua Bindings

Gotta bind it all!

Math library:

  • Vector4
  • Matrix4
  • Quaternion
  • ColorRGBA8
  • Coordinate
  • Ray

Core:

  • Engine
  • ConfigFile
  • Timer
  • Event
  • Exceptions(?)
  • UUID
  • DebugConsole(?)

Scene graph:

  • SceneGraph
  • Object
  • CameraComponent
  • MeshComponent
  • ScriptableComponent

Physics:

  • TBD

Graphics:

  • TBD

Input:

  • TBD

Platform:

  • TBD

Core Shader library

In order to provide photorealistic rendering in Blueshift, an extensive shader library is in order. It should provide things like functions to produce realistic lighting on a surface or process reflection data.

  • Cook-Torrance BRDF
  • Post-processing effect tools

Loading BBM format

The Blueshift Binary Model format is a simple 3D model format that is designed for minimal runtime processing in order to maximize performance. As such, it may be sent to the GPU almost straight from storage.

The format will begin with a "magic" combination of four bytes:

'B', 'B', 'M', 0x0

The last byte denotes the revision number; the format is not expected to be compatible across revisions as it is compiled from other formats.

After the magic header, the info header will follow. It will be a simple structure, defined as follows:

struct BBMHeader {
    uint64_t SizeInBytes;
    uint16_t NumGroups;
    uint8_t Flags;
};

One may infer that there are more information structures following this one. However, for the sake of brevity, please see the code to see their definitions.

Input subsystem

The input subsystem is important because a game without input is just a simulator. It goes without saying that the input subsystem should be at least in a prototype stage before the first usability test occurs.

There are multiple input devices that the game engine should register and provide access to:
(in order of importance, descending)

  • Mouse
  • Keyboard
  • Xbox 360 controller
  • Joystick
  • VR headset

However, exposing access to individual input devices is not enough. Games typically have actions triggered by input. By implementing this at the engine level and doing it properly, game developers can be saved a lot of headaches. However, this is one of those things that most devs don't trust the engine to do, so it has to be really damn good.

The input system implements devices as generic interfaces implementing certain capabilities. Because of this, devices may be passed unsafely at runtime to a manager that can read the capabilities implemented and allow action triggers to be fired by the device. The manager should handle bindings in a generic way and allow any action to be bound to any device capable of triggering it in one way or another.

The input system must also save these bindings in a configuration file that can be copied for each user profile. By providing these tools, the game developer must only develop a compatible interface for modifying bindings and the rest will be simple.

Rendering subsystem

The rendering subsystem encompasses a lot of different things and serves as an abstraction layer between the rendering library (bgfx) and the game engine's scene management.

Since Blueshift is intended to be of extreme performance with photorealistic graphics, special considerations must be made that are as of yet undecided. However, certain things are universal and will be parameterized below:

  • Load model from formats, see issue #8
  • Model format -> vertex buffer
  • Shader building (bgfx's shaderc)
  • Basic indexed rendering
  • Core Shader library

Code Reflection

The problem

In order to maximize serialization performance for networking and storage of data, the engine must include a mechanism for turning game objects into raw data.

Usually, one could simply transfer data to a C++ Plain Old Data (POD) type, but we want to be able to apply extra functionality to these types. To demonstrate this, review the parameters for a POD type in C++:

A Plain Old Data Structure in C++ is an aggregate class that contains only PODS as members, has no user-defined destructor, no user-defined copy assignment operator, and no nonstatic members of pointer-to-member type.

The important parts here:

  • contains only PODs as members
  • no user-defined destructor
  • no user-defined copy assignment operator

Essentially, a plain C++ struct; not very useful. For networking objects, we'll definitely want a user-defined destructor and copy assignment operator. For everything else, we definitely want non-PODs as members.

The case for a custom solution

The existing solutions out there are not that great. Google's protobuf is one of the best, but it suffers from being difficult to setup, and the bindings are written in separate files. This is okay if you're writing an application that uses it, but a middleware level piece of software like a game engine can't do that.

Therefore, Blueshift will have its own inline reflection, much like Unreal Engine 4. We will also be using an automated build tool that will run before compilation in order to expand special macros and generate runtime-usable reflection data from classes.

This means low overhead during runtime, but slightly longer compilation times. If the tool is sufficiently optimized, this is unimportant.

Input subsystem redesign

I've learned a lot developing this project, and now it's time to apply said knowledge. The input subsystem needs to be redesigned with a better API and better consciousness of thread safety and performance.

However, there are still a few things that need to happen before this. Most importantly, the event stream system. I will revisit this issue and assess the situation when that's done.

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.