Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • gamedev/fggl
  • onuralpsezer/fggl
2 results
Show changes
Commits on Source (53)
Showing
with 598 additions and 60 deletions
...@@ -26,8 +26,8 @@ variables: ...@@ -26,8 +26,8 @@ variables:
.f34-ogl: .f34-ogl:
image: git.fossgalaxy.com:8042/gamedev/containers/fedora:36-opengl image: git.fossgalaxy.com:8042/gamedev/containers/fedora:36-opengl
before_script: before_script:
- dnf install -y pkgconfig\(dri\) pkgconfig\(glu\) pkgconfig\(x11\) pkgconfig\(xcursor\) pkgconfig\(xi\) pkgconfig\(xinerama\) pkgconfig\(xrandr\) doxygen - dnf install -y pkgconfig\(dri\) pkgconfig\(glu\) pkgconfig\(x11\) pkgconfig\(xcursor\) pkgconfig\(xi\) pkgconfig\(xinerama\) pkgconfig\(xrandr\) pkgconfig\(lua\) doxygen
- dnf install -y glm-devel glfw-devel openal-soft-devel spdlog-devel freetype-devel yaml-cpp-devel assimp-devel bullet-devel gtest-devel gmock-devel - dnf install -y glm-devel glfw-devel openal-soft-devel spdlog-devel freetype-devel yaml-cpp-devel assimp-devel gtest-devel gmock-devel
## ##
# Build Targets check it builds on popular Linux Distributions # Build Targets check it builds on popular Linux Distributions
...@@ -36,7 +36,7 @@ build:fedora: ...@@ -36,7 +36,7 @@ build:fedora:
extends: .f34-ogl extends: .f34-ogl
stage: build stage: build
script: script:
- cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug - cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DFGGL_EXT_BULLET=OFF
- cmake --build build - cmake --build build
artifacts: artifacts:
paths: paths:
...@@ -47,9 +47,9 @@ build:ubuntu: ...@@ -47,9 +47,9 @@ build:ubuntu:
stage: build stage: build
before_script: before_script:
- apt update && apt install -y build-essential cmake - apt update && apt install -y build-essential cmake
- apt install -y libglm-dev libglfw3-dev libopenal-dev libspdlog-dev libfreetype-dev libyaml-cpp-dev libassimp-dev libbullet-dev libbullet-extras-dev libgtest-dev libgmock-dev - apt install -y libglm-dev libglfw3-dev libopenal-dev libspdlog-dev libfreetype-dev libyaml-cpp-dev libassimp-dev libbullet-extras-dev libgtest-dev libgmock-dev liblua5.2-dev
script: script:
- cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug - cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DFGGL_EXT_BULLET=OFF -DFGGL_EXT_LUA=OFF
- cmake --build build - cmake --build build
......
...@@ -8,6 +8,9 @@ option(FGGL_EXAMPLES "Should we build examples or just the library" ON) ...@@ -8,6 +8,9 @@ option(FGGL_EXAMPLES "Should we build examples or just the library" ON)
option(FGGL_TESTS "Should we enable the testing suite?" ON) option(FGGL_TESTS "Should we enable the testing suite?" ON)
option(FGGL_DOCS "Should we build documentation?" ON) option(FGGL_DOCS "Should we build documentation?" ON)
option(FGGL_EXT_BULLET "Should we build the bullet module?" OFF)
option(FGGL_EXT_LUA "Should we build the lua module?" ON)
## ##
# Windows # Windows
# When on windows, integrate vcpkg # When on windows, integrate vcpkg
...@@ -66,17 +69,20 @@ endif() ...@@ -66,17 +69,20 @@ endif()
## ##
# 3rd party integrations # 3rd party integrations
add_subdirectory( integrations/bullet ) if ( FGGL_EXT_BULLET )
add_subdirectory( integrations/lua ) add_subdirectory( integrations/bullet )
endif()
if ( FGGL_EXT_LUA )
add_subdirectory( integrations/lua )
endif()
# Tools # Tools
add_subdirectory( tools/pack ) # add_subdirectory( tools/pack )
# Demo project # Demo project
if (FGGL_EXAMPLES) if (FGGL_EXAMPLES)
add_subdirectory(demo) add_subdirectory(demo EXCLUDE_FROM_ALL)
target_compile_options( demo PRIVATE -Wall -Wextra -Wodr -Wdouble-promotion -fno-strict-aliasing -fno-strict-overflow )
set_property(TARGET demo PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
endif() endif()
## ##
......
...@@ -12,6 +12,10 @@ On Ubuntu: ...@@ -12,6 +12,10 @@ On Ubuntu:
sudo apt install build-essential cmake sudo apt install build-essential cmake
sudo apt install -y libglm-dev libglfw3-dev libopenal-dev libspdlog-dev libfreetype-dev libyaml-cpp-dev libassimp-dev libbullet-dev sudo apt install -y libglm-dev libglfw3-dev libopenal-dev libspdlog-dev libfreetype-dev libyaml-cpp-dev libassimp-dev libbullet-dev
``` ```
On Fedora:
```bash
sudo dnf install -y glm-devel glfw-devel openal-soft-devel spdlog-devel freetype-devel yaml-cpp-devel assimp-devel bullet-devel gcc gcc-c++ cmake gtest-devel doxygen lua lua-devel gmock gmock-devel
```
### Building ### Building
It's designed to be a fairly standard cmake project, so the standard cmake steps should work: It's designed to be a fairly standard cmake project, so the standard cmake steps should work:
......
...@@ -10,8 +10,14 @@ add_executable(demo ...@@ -10,8 +10,14 @@ add_executable(demo
demo/grid.cpp demo/grid.cpp
demo/robot/programmer.cpp demo/robot/programmer.cpp
demo/models/viewer.cpp demo/models/viewer.cpp
demo/hexboard/board.cpp
demo/hexboard/camera.cpp
) )
# set build flags
target_compile_options( demo PRIVATE -Wall -Wextra -Wodr -Wdouble-promotion -fno-strict-aliasing -fno-strict-overflow )
set_property(TARGET demo PROPERTY INTERPROCEDURAL_OPTIMIZATION True)
target_include_directories(demo target_include_directories(demo
PRIVATE PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include
...@@ -19,7 +25,9 @@ target_include_directories(demo ...@@ -19,7 +25,9 @@ target_include_directories(demo
target_link_libraries( demo fggl ) target_link_libraries( demo fggl )
#target_link_libraries(demo fggl fgglbt) #target_link_libraries(demo fggl fgglbt)
target_link_libraries( demo fggl-lua ) if ( FGGL_EXT_LUA )
target_link_libraries( demo fggl-lua )
endif()
find_package(spdlog) find_package(spdlog)
target_link_libraries(demo spdlog::spdlog) target_link_libraries(demo spdlog::spdlog)
......
---
- define: label
attrs:
value: """
- define: button
children:
- template: label
- define: textinput
children:
- template: label
- define: checkbox
attrs:
state: False
- define: radio
attrs:
state: False
- define: frame
...@@ -35,7 +35,15 @@ struct DirectionalLight { ...@@ -35,7 +35,15 @@ struct DirectionalLight {
vec3 specular; vec3 specular;
}; };
struct Material {
vec3 emission;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform DirectionalLight light; uniform DirectionalLight light;
uniform Material material;
const int hasPos = 0; const int hasPos = 0;
...@@ -68,11 +76,11 @@ vec4 calcDirLight(DirectionalLight light, vec3 Normal, vec3 viewDir, vec4 specPx ...@@ -68,11 +76,11 @@ vec4 calcDirLight(DirectionalLight light, vec3 Normal, vec3 viewDir, vec4 specPx
void main() { void main() {
vec3 viewDir = normalize(-Position); vec3 viewDir = normalize(-Position);
vec4 diffPx = vec4(1, 1, 1, 1); vec4 diffPx = vec4(material.diffuse, 1);
vec4 specPx = vec4(1, 1, 1, 1); vec4 specPx = vec4(material.specular, 1);
if ( hasPos != 1) { if ( hasPos != 1) {
diffPx = texture(diffuseTexture, TexPos); diffPx *= texture(diffuseTexture, TexPos);
specPx = texture(specularTexture, TexPos); specPx *= texture(specularTexture, TexPos);
} }
FragColour = vec4(Colour, 1); FragColour = vec4(Colour, 1);
......
...@@ -30,7 +30,7 @@ camera_type cam_mode = cam_free; ...@@ -30,7 +30,7 @@ camera_type cam_mode = cam_free;
static void placeObject(fggl::entity::EntityManager& world, fggl::entity::EntityID floor, fggl::entity::EntityFactory* factory, fggl::util::GUID prototype, glm::vec3 targetPos) { static void placeObject(fggl::entity::EntityManager& world, fggl::entity::EntityID floor, fggl::entity::EntityFactory* factory, fggl::util::GUID prototype, glm::vec3 targetPos) {
#ifndef NDEBUG #ifndef NDEBUG
fggl::debug::trace("Creating object from prototype: {}", fggl::util::guidToString(prototype)); fggl::debug::trace("Creating object from prototype: {}", fggl::util::guid_to_string(prototype));
#endif #endif
auto obj = factory->create(prototype, world); auto obj = factory->create(prototype, world);
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#include "fggl/assets/loader.hpp" #include "fggl/assets/loader.hpp"
#include "fggl/entity/gridworld/zone.hpp" #include "fggl/entity/gridworld/zone.hpp"
#include "fggl/gui/model/parser.hpp"
#include "fggl/gui/renderer/renderer.hpp"
using namespace fggl::gfx::colours; using namespace fggl::gfx::colours;
namespace demo { namespace demo {
...@@ -94,8 +97,8 @@ namespace demo { ...@@ -94,8 +97,8 @@ namespace demo {
auto& manager = area->entities(); auto& manager = area->entities();
{ {
player = manager.create(); player = manager.create();
auto& cellPos = manager.add<CellPos>(player); manager.add<CellPos>(player);
auto& robotState = manager.add<RobotState>(player); manager.add<RobotState>(player);
} }
return player; return player;
...@@ -123,7 +126,7 @@ namespace demo { ...@@ -123,7 +126,7 @@ namespace demo {
fggl::math::vec2i size{32, 32}; fggl::math::vec2i size{32, 32};
auto btn = std::make_unique<fggl::gui::Button>(pos, size); auto btn = std::make_unique<fggl::gui::Button>(pos, size);
btn->label(action.name); btn->label(action.name);
btn->addCallback([=](){ btn->addCallback([=, this](){
this->m_program.m_instructions.push_back({action.name, action.callback}); this->m_program.m_instructions.push_back({action.name, action.callback});
}); });
btnGrid->add(std::move(btn)); btnGrid->add(std::move(btn));
...@@ -195,7 +198,7 @@ namespace demo { ...@@ -195,7 +198,7 @@ namespace demo {
constexpr float DRAW_HALF = DRAW_SIZE / 2.0F; constexpr float DRAW_HALF = DRAW_SIZE / 2.0F;
constexpr float WALL_HALF = 2.5F; constexpr float WALL_HALF = 2.5F;
static void render_grid(fggl::gfx::Paint& paint, fggl::entity::grid::Area2D<255, 255>& grid) { static void render_grid(fggl::gfx::Paint& paint, fggl::entity::grid::Area2D<255, 255>& grid, fggl::App& app) {
const fggl::math::vec2 wallOffsetNorth {0, -DRAW_HALF}; const fggl::math::vec2 wallOffsetNorth {0, -DRAW_HALF};
const fggl::math::vec2 wallOffsetWest {-DRAW_HALF, 0}; const fggl::math::vec2 wallOffsetWest {-DRAW_HALF, 0};
...@@ -223,6 +226,35 @@ namespace demo { ...@@ -223,6 +226,35 @@ namespace demo {
} }
} }
} }
// UI test
auto widgetFactory = app.service<fggl::gui::model::WidgetFactory>();
auto widget = widgetFactory->buildEmpty();
widget->set("position", fggl::math::vec2{200.0F, 100.F});
widget->set("size", fggl::math::vec2{500.0F, 300.F});
widget->set("colour", fggl::gfx::colours::BLANCHED_ALMOND);
fggl::gui::model::attr_box_set(*widget, "padding", 5.0F);
auto handle = widgetFactory->buildEmpty();
handle->set("border::bottom",5.0F);
handle->set("position", fggl::math::vec2{0.0F, 0.0F});
//handle->set("size", fggl::math::vec2{INFINITY, 50.0F});
handle->set("text", "hello, world!");
handle->set("colour", fggl::gfx::colours::ORANGE);
fggl::gui::model::attr_box_set(*handle, "padding", 5.0F);
widget->addChild(*handle);
delete handle;
auto content = widgetFactory->buildEmpty();
content->set("position", fggl::math::vec2{0.0F, 50.0F});
//content->set("size", fggl::gui::model::UNDEFINED_SIZE);
content->set("colour", fggl::gfx::colours::BURLYWOOD);
widget->addChild(*content);
delete content;
fggl::gui::renderer::layout(*widget);
fggl::gui::renderer::visit(*widget, paint);
} }
...@@ -325,7 +357,7 @@ namespace demo { ...@@ -325,7 +357,7 @@ namespace demo {
void GridScene::render(fggl::gfx::Graphics &gfx) { void GridScene::render(fggl::gfx::Graphics &gfx) {
fggl::gfx::Paint paint; fggl::gfx::Paint paint;
render_grid(paint, *m_grid); render_grid(paint, *m_grid, owner());
render_objects(paint, *m_grid); render_objects(paint, *m_grid);
m_canvas.render(paint); m_canvas.render(paint);
......
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 10/12/22.
//
#include "hexboard/scene.hpp"
namespace demo::hexboard {
constexpr float SCROLL_SPEED = 0.01F;
constexpr float HEX_SIZE = 64.0F;
constexpr std::array<fggl::grid::IntHex, 4> ISLAND_CENTERS {{
{2, 3},
{6, 7},
{9, 10},
{6, 3}
}};
Scene::Scene(fggl::App &app) : GameBase(app), m_board(nullptr), m_screen(1920.F, 1080.F) {
}
void Scene::activate() {
m_board = std::make_unique<fggl::grid::HexGrid>();
m_layout = std::make_unique<fggl::grid::Layout>( fggl::grid::Orientation::make_pointy(), HEX_SIZE );
//m_layout->m_origin = { 1920.0F * -0.5F, 1080.0F * -0.5F};
m_selections = std::make_unique<SelectionModel>();
const fggl::grid::TerrainType grass{
.data = std::make_shared<fggl::grid::MaterialData>()
};
grass.data->name = "grass";
grass.data->colour = {0.0F, 1.0F, 0.0};
for (auto islandPoint : ISLAND_CENTERS){
auto island = islandPoint.hexesInRange(2);
for (auto &hex : island) {
m_board->setTerrain(hex, grass);
}
}
m_camera = std::make_unique<Camera2D>();
}
void Scene::deactivate() {
m_board = nullptr;
m_selections = nullptr;
m_layout = nullptr;
}
void Scene::update(float delta) {
GameBase::update(delta);
// if the board is not set, abort
if ( m_board == nullptr ){
return;
}
// check if a button was pressed
auto& input = this->input();
{
const auto mouseNdc = fggl::input::mouse_axis(input.mouse);
const auto screenPos = ndc_to_screen(mouseNdc, m_screen);
// calculate what the user clicked on
auto worldPx = m_camera->unproject(screenPos);
m_selections->hover = fggl::grid::round2( m_layout->toGrid(worldPx) );
if (input.mouse.pressed(fggl::input::MouseButton::LEFT)) {
m_selections->selected = m_selections->hover;
m_camera->moveBy(mouseNdc * (m_screen * 0.5F) );
}
if ( input.mouse.down(fggl::input::MouseButton::RIGHT) ) {
if (input.mouse.pressed( fggl::input::MouseButton::RIGHT )) {
m_dragging = screenPos;
}
auto offset = screenPos - m_dragging.value();
m_camera->teleportBy(offset * SCROLL_SPEED);
} else if ( input.mouse.released(fggl::input::MouseButton::RIGHT) ) {
m_dragging = {};
}
}
m_camera->update(delta);
// flip y, because reasons
//auto offset = m_camera->getFocusLocation();
//m_layout->m_origin = -offset;
}
void Scene::drawGrid(fggl::gfx::Paint& paint) {
auto tiles = m_board->getAllTiles();
for ( const auto& tile : tiles ) {
auto terrain = m_board->getTerrain(tile);
if ( terrain.has_value() ) {
const auto& terrainData = terrain.value();
m_layout->paintHex(paint, tile, terrainData.colour, m_camera->getFocusLocation());
}
}
}
void Scene::drawSelections(fggl::gfx::Paint& paint) {
if ( m_selections == nullptr || m_dragging.has_value() ) {
return;
}
if ( m_selections->selected.has_value() ) {
m_layout->paintHex( paint, m_selections->selected.value(), fggl::gfx::colours::YELLOW, m_camera->getFocusLocation());
}
if ( m_selections->hover.has_value() ) {
m_layout->paintHex( paint, m_selections->hover.value(), fggl::gfx::colours::BLANCHED_ALMOND, m_camera->getFocusLocation());
}
}
void Scene::render(fggl::gfx::Graphics &gfx) {
// if the board is not set, abort
if ( m_board == nullptr ){
return;
}
// draw the grid
// FIXME don't hard-code the screen size
fggl::gfx::Paint paint;
drawGrid(paint);
drawSelections(paint);
gfx.draw2D(paint);
}
} // namespace demo::hexboard
\ No newline at end of file
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 02/01/23.
//
#include "hexboard/camera.hpp"
#include "fggl/math/fmath.hpp"
#include <cmath>
namespace demo::hexboard {
void Camera2D::update(float delta) {
m_location = fggl::math::smooth_add( m_location, m_target, m_scale );
if ( m_trauma > 0 ) {
m_trauma = std::max( m_trauma - TRAUMA_DECAY, 0.0F );
}
}
}
\ No newline at end of file
...@@ -39,34 +39,39 @@ ...@@ -39,34 +39,39 @@
#include "fggl/data/assimp/module.hpp" #include "fggl/data/assimp/module.hpp"
#include "fggl/assets/module.hpp" #include "fggl/assets/module.hpp"
#include "fggl/script/lua/module.hpp" #include "fggl/assets/packed/module.hpp"
#if __has_include("fggl/script/lua/module.hpp")
#include "fggl/script/lua/module.hpp"
#endif
#include "GameScene.h" #include "GameScene.h"
#include "rollball.hpp" #include "rollball.hpp"
#include "topdown.hpp" #include "topdown.hpp"
#include "grid.hpp" #include "grid.hpp"
#include "models/viewer.hpp" #include "models/viewer.hpp"
#include "hexboard/scene.hpp"
static void setup_menu(fggl::App& app) { static void setup_menu(fggl::App& app) {
auto *menu = app.addState<fggl::scenes::BasicMenu>("menu"); auto *menu = app.addState<fggl::scenes::BasicMenu>("menu");
// add some menu items for the game states // add some menu items for the game states
const std::array labels = {"terrain", "rollball", "Top Down", "Grid World", "Viewer"}; const std::array labels = {"terrain", "rollball", "Top Down", "Grid World", "Viewer", "gridworld"};
const std::array scenes = {"game", "rollball", "topdown", "gridworld", "viewer"}; const std::array scenes = {"game", "rollball", "topdown", "gridworld", "viewer", "hexboard"};
for (std::size_t i = 0; i < labels.size(); ++i) { for (std::size_t i = 0; i < labels.size(); ++i) {
std::string sceneName = scenes.at(i); std::string sceneName = scenes.at(i);
menu->add(labels.at(i), [&app, sceneName]() { menu->add(labels.at(i), [&app, sceneName]() {
auto* audio = app.service<fggl::audio::AudioService>(); auto* audio = app.service<fggl::audio::AudioService>();
audio->play("click.ogg", false); audio->play("ui/click.ogg", false);
app.change_state(sceneName); app.change_state(sceneName);
}); });
} }
menu->add("quit", [&app]() { menu->add("quit", [&app]() {
auto* audio = app.service<fggl::audio::AudioService>(); //auto* audio = app.service<fggl::audio::AudioService>();
audio->play("click.ogg", false); //audio->play("click.ogg", false);
app.running(false); app.running(false);
}); });
} }
...@@ -82,8 +87,12 @@ int main(int argc, const char* argv[]) { ...@@ -82,8 +87,12 @@ int main(int argc, const char* argv[]) {
moduleManager.use<fggl::gfx::OpenGL4>(); moduleManager.use<fggl::gfx::OpenGL4>();
moduleManager.use<fggl::display::GLFW>(); moduleManager.use<fggl::display::GLFW>();
moduleManager.use<fggl::assets::AssetFolders>(); moduleManager.use<fggl::assets::AssetFolders>();
moduleManager.use<fggl::assets::PackedAssets>();
moduleManager.use<fggl::entity::ECS>(); moduleManager.use<fggl::entity::ECS>();
moduleManager.use<fggl::script::Lua>();
#ifdef FGGL_HAS_LUA
moduleManager.use<fggl::script::Lua>();
#endif
// debug/testing use // debug/testing use
moduleManager.use<fggl::data::AssimpLoader>(); moduleManager.use<fggl::data::AssimpLoader>();
...@@ -98,6 +107,16 @@ int main(int argc, const char* argv[]) { ...@@ -98,6 +107,16 @@ int main(int argc, const char* argv[]) {
// create the application // create the application
fggl::App app( &moduleManager, "fggl-demo" ); fggl::App app( &moduleManager, "fggl-demo" );
// force asset loading
{
auto* assetFinder = app.service<fggl::assets::CheckinAdapted>();
assetFinder->discover("core");
auto* assets = app.service<fggl::assets::AssetManager>();
auto* loader = app.service<fggl::assets::Loader>();
loader->load("ui/click.ogg", fggl::audio::ASSET_CLIP_SHORT, assets);
}
auto* windowing = app.service<fggl::display::WindowService>(); auto* windowing = app.service<fggl::display::WindowService>();
// make a window for our application // make a window for our application
...@@ -113,6 +132,7 @@ int main(int argc, const char* argv[]) { ...@@ -113,6 +132,7 @@ int main(int argc, const char* argv[]) {
app.addState<demo::TopDown>("topdown"); app.addState<demo::TopDown>("topdown");
app.addState<demo::GridScene>("gridworld"); app.addState<demo::GridScene>("gridworld");
app.addState<demo::Viewer>("viewer"); app.addState<demo::Viewer>("viewer");
app.addState<demo::hexboard::Scene>("hexboard");
return app.run(argc, argv); return app.run(argc, argv);
} }
...@@ -32,13 +32,13 @@ ...@@ -32,13 +32,13 @@
namespace demo { namespace demo {
static fggl::entity::EntityID build_model(fggl::entity::EntityManager& manager, fggl::assets::AssetManager *assets){ static fggl::entity::EntityID build_model(fggl::entity::EntityManager& manager, fggl::assets::AssetManager *assets, fggl::assets::AssetID assetRef){
auto model = manager.create(); auto model = manager.create();
manager.add<fggl::math::Transform>(model); manager.add<fggl::math::Transform>(model);
auto& mesh = manager.add<fggl::mesh::StaticMultiMesh3D>(model); auto& mesh = manager.add<fggl::mesh::StaticMultiMesh3D>(model);
auto* meshData = assets->get<fggl::mesh::MultiMesh3D>("backpack/backpack.obj"); auto* meshData = assets->get<fggl::mesh::MultiMesh3D>( assetRef );
if ( meshData == nullptr ) { if ( meshData == nullptr ) {
fggl::debug::warning("loading model did not work!"); fggl::debug::warning("loading model did not work!");
} else { } else {
...@@ -46,7 +46,7 @@ namespace demo { ...@@ -46,7 +46,7 @@ namespace demo {
mesh.pipeline = "redbook/debug"; mesh.pipeline = "redbook/debug";
} }
auto& material = manager.add<fggl::gfx::PhongMaterial>(model); manager.add<fggl::gfx::PhongMaterial>(model);
return model; return model;
} }
...@@ -93,7 +93,7 @@ namespace demo { ...@@ -93,7 +93,7 @@ namespace demo {
static void setup_lighting(fggl::entity::EntityManager& ecs) { static void setup_lighting(fggl::entity::EntityManager& ecs) {
auto light = ecs.create(); auto light = ecs.create();
auto& transform = ecs.add<fggl::math::Transform>(light); ecs.add<fggl::math::Transform>(light);
auto& lightComp = ecs.add<fggl::gfx::DirectionalLight>(light); auto& lightComp = ecs.add<fggl::gfx::DirectionalLight>(light);
lightComp.position = fggl::math::vec3( 10.0F, 5.0F, 0.0F ); lightComp.position = fggl::math::vec3( 10.0F, 5.0F, 0.0F );
...@@ -109,22 +109,25 @@ namespace demo { ...@@ -109,22 +109,25 @@ namespace demo {
void Viewer::activate() { void Viewer::activate() {
Game::activate(); Game::activate();
// force load required data auto* assetFinder = m_owner.service<fggl::assets::CheckinAdapted>();
auto *loader = owner().service<fggl::assets::Loader>(); assetFinder->discover("viewer");
auto *manager = owner().service<fggl::assets::AssetManager>();
loader->load("backpack/backpack.obj", fggl::data::models::ASSIMP_MODEL, manager); // setup the assets we can select between
// TODO some form of introspection to automatically find declared/discovered assets of a given type
m_assets.clear();
m_assets.push_back( fggl::assets::make_asset_id_rt("viewer", "backpack/backpack.obj") );
m_assets.push_back( fggl::assets::make_asset_id_rt("viewer", "lowpoly_scifi/wallDoor_double.FBX") );
m_assets.push_back( fggl::assets::make_asset_id_rt("viewer", "lowpoly_scifi/wallDoor_double_end.FBX") );
m_assets.push_back( fggl::assets::make_asset_id_rt("viewer", "newell_teaset/teapot.obj") );
m_assets.push_back( fggl::assets::make_asset_id_rt("viewer", "humansanimatedpack/Paladin/Paladin.fbx") );
// create camera // create camera
setup_camera(world()); setup_camera(world());
setup_lighting(world()); setup_lighting(world());
// setup model // setup model
m_model = build_model(world(), manager); m_model = fggl::entity::INVALID;
cycleAsset(0);
// asset loader
//loader->
} }
void Viewer::deactivate() { void Viewer::deactivate() {
...@@ -138,6 +141,25 @@ namespace demo { ...@@ -138,6 +141,25 @@ namespace demo {
if ( input().keyboard.pressed(glfwGetKeyScancode(GLFW_KEY_F2)) ) { if ( input().keyboard.pressed(glfwGetKeyScancode(GLFW_KEY_F2)) ) {
m_debug = !m_debug; m_debug = !m_debug;
} }
if ( input().keyboard.pressed(glfwGetKeyScancode(GLFW_KEY_F3)) ) {
// trigger the asset cycle
m_lastAsset = (m_lastAsset + 1) % m_assets.size();
cycleAsset(m_lastAsset);
}
}
void Viewer::cycleAsset(uint64_t /*idx*/) {
auto *loader = owner().service<fggl::assets::Loader>();
auto *manager = owner().service<fggl::assets::AssetManager>();
auto nextAsset = m_assets[ m_lastAsset ];
loader->loadChain(nextAsset, manager);
if ( m_model != fggl::entity::INVALID) {
world().destroy(m_model);
}
m_model = build_model(world(), manager, nextAsset);
} }
void Viewer::render(fggl::gfx::Graphics &gfx) { void Viewer::render(fggl::gfx::Graphics &gfx) {
......
...@@ -46,7 +46,6 @@ namespace demo::robot { ...@@ -46,7 +46,6 @@ namespace demo::robot {
} }
void Timeline::renderInstructions(fggl::gfx::Paint& paint) { void Timeline::renderInstructions(fggl::gfx::Paint& paint) {
const auto size = this->size();
const fggl::math::vec2f barExtents{16, 16}; const fggl::math::vec2f barExtents{16, 16};
for ( auto track=0U; track < m_tracks.size(); ++track) { for ( auto track=0U; track < m_tracks.size(); ++track) {
......
...@@ -48,7 +48,7 @@ static void setup_camera(fggl::entity::EntityManager& world) { ...@@ -48,7 +48,7 @@ static void setup_camera(fggl::entity::EntityManager& world) {
world.add<fggl::gfx::Camera>(prototype); world.add<fggl::gfx::Camera>(prototype);
} }
static fggl::entity::EntityID setup_environment(fggl::entity::EntityManager& world, fggl::entity::EntityFactory* factory, const fggl::math::vec2& size, demo::RollState& state) { static fggl::entity::EntityID setup_environment(fggl::entity::EntityManager& world, fggl::entity::EntityFactory* /*factory*/, const fggl::math::vec2& /*size*/, demo::RollState& state) {
// ensure the state is clean // ensure the state is clean
state.closestPickup = fggl::entity::INVALID; state.closestPickup = fggl::entity::INVALID;
state.mode = demo::DebugMode::NORMAL; state.mode = demo::DebugMode::NORMAL;
...@@ -81,14 +81,15 @@ namespace demo { ...@@ -81,14 +81,15 @@ namespace demo {
m_phys = physService->create(&world(), entFactory); m_phys = physService->create(&world(), entFactory);
auto* scriptProvider = m_owner.service<fggl::script::ScriptProvider>(); auto* scriptProvider = m_owner.service<fggl::script::ScriptProvider>();
if ( scriptProvider != nullptr ) {
m_scripts = scriptProvider->create(); m_scripts = scriptProvider->create();
m_scripts->setGlobal("state", this); m_scripts->setGlobal("state", this);
}
// asset loader // asset loader
auto* assetLoader = m_owner.service<fggl::assets::Loader>(); auto* assetLoader = m_owner.service<fggl::assets::Loader>();
assetLoader->load("rollball.yml", fggl::entity::PROTOTYPE_ASSET, entFactory); assetLoader->load("rollball.yml", fggl::entity::ENTITY_PROTOTYPE, entFactory);
assetLoader->load("rollball.yml", fggl::entity::SCENE, this); assetLoader->loadChain( fggl::assets::make_asset_id_rt("core", "rollerball/rollball.yml"), this);
// collectable callbacks // collectable callbacks
/*auto* collectableCallbacks = world().get<fggl::phys::CollisionCallbacks>(prefabs.collectable); /*auto* collectableCallbacks = world().get<fggl::phys::CollisionCallbacks>(prefabs.collectable);
......
...@@ -54,7 +54,7 @@ namespace demo { ...@@ -54,7 +54,7 @@ namespace demo {
static void setup_lighting(fggl::entity::EntityManager& ecs) { static void setup_lighting(fggl::entity::EntityManager& ecs) {
auto light = ecs.create(); auto light = ecs.create();
auto& transform = ecs.add<fggl::math::Transform>(light); ecs.add<fggl::math::Transform>(light);
auto& lightComp = ecs.add<fggl::gfx::DirectionalLight>(light); auto& lightComp = ecs.add<fggl::gfx::DirectionalLight>(light);
lightComp.position = fggl::math::vec3( 10.0F, 5.0F, 0.0F ); lightComp.position = fggl::math::vec3( 10.0F, 5.0F, 0.0F );
...@@ -132,7 +132,7 @@ void TopDown::activate() { ...@@ -132,7 +132,7 @@ void TopDown::activate() {
fggl::debug::log(fggl::debug::Level::info, "TopDown::activate()"); fggl::debug::log(fggl::debug::Level::info, "TopDown::activate()");
auto* assetLoader = m_owner.service<fggl::assets::Loader>(); auto* assetLoader = m_owner.service<fggl::assets::Loader>();
assetLoader->load("topdown.yml", fggl::entity::PROTOTYPE_ASSET); assetLoader->load("topdown.yml", fggl::entity::ENTITY_PROTOTYPE);
auto* factory = m_owner.service<fggl::entity::EntityFactory>(); auto* factory = m_owner.service<fggl::entity::EntityFactory>();
//fggl::ecs3::load_prototype_file(world(), *storage, "topdown.yml"); //fggl::ecs3::load_prototype_file(world(), *storage, "topdown.yml");
......
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 10/12/22.
//
#ifndef FGGL_DEMO_INCLUDE_HEXBOARD_BOARD_HPP
#define FGGL_DEMO_INCLUDE_HEXBOARD_BOARD_HPP
#include <cstdint>
namespace demo::hexboard {
constexpr uint64_t NO_SELECTION{0};
struct SelectionModel {
uint64_t m_hover = NO_SELECTION;
};
} // namespace demo::hexboard
#endif //FGGL_DEMO_INCLUDE_HEXBOARD_BOARD_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 02/01/23.
//
#ifndef FGGL_DEMO_INCLUDE_HEXBOARD_CAMERA_HPP
#define FGGL_DEMO_INCLUDE_HEXBOARD_CAMERA_HPP
#include "fggl/math/types.hpp"
namespace demo::hexboard {
constexpr float TRAUMA_DECAY = 0.01F;
constexpr float TRAUMA_LARGE = 0.5F;
constexpr float TRAUMA_SMALL = 0.1F;
constexpr float SPEED_SLOW = 0.01F;
constexpr float SPEED_MEDIUM = 0.1F;
constexpr float SPEED_FAST = 0.5F;
constexpr fggl::math::vec2 ndc_to_screen(fggl::math::vec2 ndcPos, fggl::math::vec2 screenSize) {
return fggl::math::vec2(
fggl::math::rescale_ndc(ndcPos.x, 0, screenSize.x),
fggl::math::rescale_ndc(ndcPos.y, 0, screenSize.y)
);
}
/**
* A 2D 'juiced' camera for grid worlds.
*
* This camera is based on HexBoard, and the GDC talk around this concept. Many of the ideas implemented here
* come from that source.
*
* @see https://www.youtube.com/watch?v=tu-Qe66AvtY
*/
class Camera2D {
public:
using Point = fggl::math::vec2;
/**
* Apply active camera effects.
*
* This method must be called once per frame of the camera's visual effects are to be animated.
*
* @param delta the amount of time that has passed
*/
void update(float delta);
inline fggl::math::vec2 unproject(fggl::math::vec2 screenPos) const {
auto location = screenPos;
location.x += 1920/2.0F;
location.y += 1080/2.0F;
return location + m_location;
// return screenPos + m_location;
}
inline fggl::math::vec2 project(fggl::math::vec2 worldPos) const {
return worldPos - m_location;
}
/**
* Move the camera to a new location.
*
* This will apply any movement effects the camera has applied to it. As a result movement to the location
* will not be instantaneous.
*
* @param newTarget the new target location
*/
inline void moveTo(Point newTarget) {
m_target = newTarget;
}
/**
* Move the camera by a defined amount.
*
* This will apply any movement effects the camera has applied to it. As a result movement to the location
* will not be instantaneous.
*
* @param delta the amount to add to the target, negative values will subject from the target location
*/
inline void moveBy(Point delta) {
m_target += delta;
}
/**
* Instantaneously move the camera to a new location.
*
* @param the new camera location
*/
inline void teleportTo(Point newTarget) {
m_location = newTarget;
m_target = newTarget;
}
/**
* Instantaneously adjust the camera location.
*
* @param delta the amount to adjust the camera location by
*/
inline void teleportBy(Point delta) {
m_location += delta;
m_target = m_location;
}
/**
* Get the current view offset of this camera.
*
* @return the current location this camera is pointing at
*/
inline Point getFocusLocation() const {
auto offset = m_location;
offset.x += 1920/2.0F;
offset.y += 1080/2.0F;
return -offset;
}
private:
Point m_location;
Point m_target;
float m_trauma;
float m_scale = SPEED_MEDIUM;
};
}
#endif //FGGL_DEMO_INCLUDE_HEXBOARD_CAMERA_HPP
/*
* This file is part of FGGL.
*
* FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with FGGL.
* If not, see <https://www.gnu.org/licenses/>.
*/
//
// Created by webpigeon on 10/12/22.
//
#ifndef FGGL_DEMO_INCLUDE_HEXBOARD_SCENE_H
#define FGGL_DEMO_INCLUDE_HEXBOARD_SCENE_H
#include <memory>
#include <optional>
#include "fggl/scenes/game.hpp"
#include "fggl/grid/hexgrid.hpp"
#include "fggl/grid/layout.hpp"
#include "camera.hpp"
namespace demo::hexboard {
struct SelectionModel {
std::optional<fggl::grid::IntHex> selected;
std::optional<fggl::grid::IntHex> hover;
};
class Scene : public fggl::scenes::GameBase {
public:
explicit Scene(fggl::App& app);
void activate() override;
void deactivate() override;
void update(float delta) override;
void render(fggl::gfx::Graphics& gfx) override;
private:
std::unique_ptr<fggl::grid::HexGrid> m_board;
std::unique_ptr<fggl::grid::Layout> m_layout;
std::unique_ptr<SelectionModel> m_selections;
std::unique_ptr<Camera2D> m_camera;
fggl::math::vec2 m_screen;
std::optional<fggl::math::vec2> m_dragging;
void drawGrid(fggl::gfx::Paint&);
void drawSelections(fggl::gfx::Paint&);
};
} // namespace demo::hexboard
#endif //FGGL_DEMO_INCLUDE_HEXBOARD_SCENE_H
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define FGGL_DEMO_INCLUDE_MODELS_VIEWER_HPP #define FGGL_DEMO_INCLUDE_MODELS_VIEWER_HPP
#include "fggl/scenes/game.hpp" #include "fggl/scenes/game.hpp"
#include "fggl/assets/types.hpp"
namespace demo { namespace demo {
...@@ -35,9 +36,13 @@ namespace demo { ...@@ -35,9 +36,13 @@ namespace demo {
void render(fggl::gfx::Graphics& gfx) override; void render(fggl::gfx::Graphics& gfx) override;
private: private:
fggl::entity::EntityID m_model; fggl::entity::EntityID m_model = fggl::entity::INVALID;
std::vector< fggl::assets::AssetID> m_assets;
uint64_t m_lastAsset = 0;
bool m_debug = false; bool m_debug = false;
void cycleAsset(uint64_t asset);
}; };
} }
......
...@@ -36,6 +36,7 @@ endif () ...@@ -36,6 +36,7 @@ endif ()
# the important stuff everything else uses # the important stuff everything else uses
add_subdirectory(math) add_subdirectory(math)
add_subdirectory(util) add_subdirectory(util)
add_subdirectory(grid)
add_subdirectory(assets) add_subdirectory(assets)
add_subdirectory(phys) add_subdirectory(phys)
...@@ -55,12 +56,10 @@ target_sources(${PROJECT_NAME} ...@@ -55,12 +56,10 @@ target_sources(${PROJECT_NAME}
input/input.cpp input/input.cpp
input/mouse.cpp input/mouse.cpp
input/camera_input.cpp input/camera_input.cpp
)
gui/widget.cpp # GUI support
gui/widgets.cpp add_subdirectory(gui)
gui/containers.cpp
gui/fonts.cpp
)
# yaml-cpp for configs and storage # yaml-cpp for configs and storage
find_package(yaml-cpp) find_package(yaml-cpp)
...@@ -69,9 +68,6 @@ target_link_libraries(fggl PUBLIC yaml-cpp) ...@@ -69,9 +68,6 @@ target_link_libraries(fggl PUBLIC yaml-cpp)
# model loading # model loading
add_subdirectory(data/assimp) add_subdirectory(data/assimp)
find_package(Freetype)
target_link_libraries(${PROJECT_NAME} PUBLIC Freetype::Freetype)
# Graphics backend # Graphics backend
add_subdirectory(gfx) add_subdirectory(gfx)
add_subdirectory(audio) add_subdirectory(audio)
......