Skip to content

FrodoAlaska/Freya

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

146 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The Freya Game Engine

A very capable, yet simple 2D game engine made entirely for hobby purposes. It is full of features that target 2D games/applications, with no plans to target 3D any time soon. It is purely a 2D game engine. It currently supports Windows with minimal Linux support.

Features

  • Cross-platform window creation with OpenGL and GLES.
  • Gamepad, keyboard, and mouse input support.
  • A flexible and configurable 2D renderer, using modern OpenGL (4.5+) and GLES3.
  • A fully-fledged audio system with both 2D and 3D spatialized audio.
  • A robust and easy-to-use game UI system, using HTML and CSS to decalre and style widgets.
  • A robust 2D physics engine, using the fantastic Box2D library.
  • A flexible Entity Component System (ECS) module, using the EnTT library.
  • Integrated ImGui support, featuring an abstracted editor layer for editing engine-specific types through a GUI.
  • A durable, but simple noise generation module for both 2D and 3D.
  • A simple tile map system for easily editing and adding tile maps.

Dependencies:

Build Instructions

Before proceeding with any build or compilation step, Freya needs to be cloned from the Git repo.

git clone https://github.com/FrodoAlaska/Freya.git

And now that Freya is cloned, we can start the build process...

In general there are two ways to build Freya. The first to use CMake commands just like any other C++ project. The second way is to use a handy build script to manage the build project for you.

Raw CMake

There are two main ways to build Freya. The first is to use the traditional CMake commands below:

mkdir build 
cd build 
cmake .. 

CMake will generate the required build files, but it will also fetch all of the dependencies mentioned above. This is all handled by CMake itself, so you don't have to worry about any specifics.

And then to build Freya you can use:

cmake --build . --config Debug --parallel 12

The command above will build Freya in the debug configuration, using 12 worker threads. You can omit the --parallel flag if you so wish. However, since Freya will build all of the dependencies itself, it might take a while.

The Build Script

Now the second way to build Freya is to use the build scripts found in the scripts directory. There are a few build scripts but there are only two important ones: build-freya.sh for Linux and build-freya.ps1 for Windows. Each script takes in a few flags to make both the development and build process easier.

[Usage]: .\build-freya.ps1 [options]
An easy to use build script to build Freya on Windows
   -clean          = Have a new fresh build
   -debug          = Build for the debug configuration
   -rel            = Build for the release configuration
   -jobs [threads] = Threads to use when building
   -run-testbed    = Run the testbed examples
   -help           = Display this help message

Currently, the -run flag can only run a single testbed, but there are plans to expand on this in the future.

The -debug and -rel must be used independently. Moreover, one of the flags have to be used to know which configuration to build for. If none of them are used, the script will default to a Debug build. Depending on which flag is passed to the build script, a build-debug and/or build-release will be created in the main directory. Any build artifacts generated by -run will be dumped into one of the previously mentioned directories.

Of course, the project can be built regardless of this build script. This is not a necessary step. It is only a convenience for the development process on our end.

Simple Example

Below is a simple example of the Freya Engine being used.

If the exmaple below is too simple, you can check out the testbed directory where more extensive examples exist. However, they are not as "educational" as the example below. Despite that, they do have a variety of use cases of Freya.

#include <freya.h>

struct App {
  freya::Window* window; 
  freya::Camera camera;
  freya::AssetGroupID group_id;
};
static App s_app;

bool app_init(const freya::Args& args, freya::Window* window) {
  // Carry the window just in case
  s_app.window = window;

  // Create a camera
  
  freya::CameraDesc cam_desc = {
    .position    = freya::Vec2(0.0f),
    .view_bounds = freya::window_get_size(s_app.window), 
    .zoom        = 1.0f,
  };
  freya::camera_create(s_app.camera, cam_desc);
  
  // Initialize the GUI
  freya::gui_init(window);
  
  // Create the application's asset group
  s_app.group_id = freya::asset_group_create("app_assets");

  //
  // Do other initialization stuff here...
  //

  // Nothing went wrong. Return true.
  return true;
}

void app_shutdown() {
  freya::asset_group_destroy(s_app.group_id);
  freya::gui_shutdown();
  
  //
  // Do other shutdown/cleanup stuff here...
  //
}

void app_update(freya::f32 dt) {
  // Quit the application when the specified exit key is pressed
  
  if(freya::input_key_pressed(freya::KEY_ESCAPE)) {
    freya::event_dispatch(freya::Event{.type = freya::EVENT_APP_QUIT});
    return;
  }
  
  // Enable/disable the GUI using the F1 key

  if(freya::input_key_pressed(freya::KEY_F1)) {
    freya::gui_toggle_active();
  }

  //
  // Update the world or other stuff before the render frame...
  //
}

void app_render() {
  // Render 2D stuff

  freya::renderer_begin(s_app.camera);

  //
  // Render commands go here...
  //

  freya::renderer_end();

  // Render UI elements
  
  freya::ui_renderer_begin();
  freya::ui_renderer_end();
}

void app_render_gui() {
  if(!freya::gui_is_active()) {
    return;
  }

  freya::gui_begin(); 

  // 
  // Insert GUI commands here... 
  //

  freya::gui_end(); 
}

// Main function _must_ have this exact signature, since the `FREYA_MAIN` macro will 
// expect it. However, if you wish to make a console application or do not want Freya to 
// hijack the main function, you can use the regular `main` function and omit `FREYA_MAIN` 
// at the bottom.
int engine_main(int argc, char* argv[]) {
  freya::AppDesc app_desc {
    .init_fn     = app_init,
    .shutdown_fn = app_shutdown,
    .update_fn   = app_update, 
    
    .render_fn     = app_render, 
    .render_gui_fn = app_render_gui, 

    .window_title  = "Freya Example", 
    .window_width  = 800, 
    .window_height = 600, 
    .window_flags  = (freya::i32)(freya::WINDOW_FLAGS_CENTER_MOUSE),

    .args_values = argv, 
    .args_count  = argc,
  };

  // Run the application in a loop and return the 
  // result once the applicatio exists.
  return freya::engine_run(app_desc);
}

// A macro to specify a main entry function depending on the platform.
// The given `engine_main` will be called inside the entry function.
FREYA_MAIN(engine_main)

Contributors

Languages