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
Showing
with 8862 additions and 171 deletions
......@@ -25,19 +25,19 @@ namespace fggl::gui {
FontLibrary::FontLibrary(data::Storage *storage) : m_context(nullptr), m_storage(storage) {
FT_Init_FreeType(&m_context);
m_defaultFont = getFont(DEFAULT_FONT_NAME);
}
FontLibrary::~FontLibrary() {
// free all fonts
for (auto &face : m_cache) {
face.second = nullptr;
}
m_defaultFont = nullptr;
m_cache.clear();
// shut the library down
FT_Done_FreeType(m_context);
}
GlyphMetrics &FontFace::populateMetrics(char letter) {
auto FontFace::populateMetrics(char letter) -> GlyphMetrics & {
if (FT_Load_Char(m_face, letter, FT_LOAD_RENDER)) {
// something bad happened
return m_metrics['?'];
......@@ -54,7 +54,7 @@ namespace fggl::gui {
return it.first->second;
}
void FontFace::texture(char letter, int &width, int &height, void **buff) {
void FontFace::texture(char letter, int &width, int &height, unsigned char **buff) {
if (FT_Load_Char(m_face, letter, FT_LOAD_RENDER)) {
// something bad happened
return;
......
/*
* 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 11/03/23.
//
#include "fggl/gui/model/parser.hpp"
#include <yaml-cpp/yaml.h>
namespace fggl::gui::model {
Widget* YamlToWidgetTree(WidgetFactory& factory, const YAML::Node& config) {
Widget* root;
if ( config["template"] ) {
root = factory.build( config["template"].as<std::string>());
} else {
root = factory.buildEmpty();
}
// deal with attrs
for ( auto attr : config["attrs"] ) {
root->set(attr.first.as<std::string>(), attr.second.as<std::string>());
}
// deal with child nodes
for ( auto child : config["children"] ) {
Widget* childWidget = YamlToWidgetTree(factory, child);
root->addChild(*childWidget);
}
// are we a template definition?
if ( config["define"] ) {
factory.push( config["define"].as<std::string>(), std::move(*root) );
return factory.getTemplate( config["define"].as<std::string>() );
}
return root;
}
inline Widget* parseFile(WidgetFactory& factory, const std::string& path) {
YAML::Node root = YAML::LoadFile(path);
if ( !root ){
return nullptr;
}
return YamlToWidgetTree(factory, root);
}
}
\ 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 11/03/23.
//
#include "fggl/gui/model/structure.hpp"
#include "fggl/gui/fonts.hpp"
#include <algorithm>
#include <utility>
#include <string>
namespace fggl::gui::model {
math::vec2 calcTextBounds(const std::string& value, std::shared_ptr<FontFace> face) {
if ( face == nullptr ){
debug::warning("No preferred font sent, cowardly refusing to process text");
return {};
}
math::vec2 max{0, 0};
for (auto letter : value) {
auto metrics = face->metrics(letter);
max.x += metrics.size.x + (metrics.advance >> 6);
max.y = std::max(max.y, metrics.size.y);
}
return max;
}
inline math::vec2 calcBoxContrib(const Widget& widget, const std::string& name) {
return math::vec2{
widget.get_or_default<float>( name + "::left") + widget.get_or_default<float>(name + "::right"),
widget.get_or_default<float>( name + "::top" ) + widget.get_or_default<float>( name + "::bottom" )
};
}
void Widget::calcPrefSize(std::shared_ptr<FontFace> face) {
if ( !m_dirty ){
return;
}
auto padding = calcBoxContrib( *this, "padding");
auto border = calcBoxContrib( *this, "border");
auto content = math::vec2{0,0};
if (hasAttr("text")) {
content += calcTextBounds( get<std::string>("text"), std::move(face) );
}
m_cachedSize = padding + content + content;
debug::info("my preferred size is: ({}, {})", m_cachedSize.x, m_cachedSize.y);
m_dirty = false;
}
}
\ 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 11/03/23.
//
#include "fggl/gui/renderer/renderer.hpp"
namespace fggl::gui::renderer {
constexpr int PADDING = 15;
void draw_box(gfx::Path2D &path, glm::vec2 topLeft, glm::vec2 bottomRight) {
path.moveTo({topLeft.x, topLeft.y});
path.pathTo({bottomRight.x, topLeft.y});
path.pathTo({bottomRight.x, bottomRight.y});
path.pathTo({topLeft.x, bottomRight.y});
path.pathTo({topLeft.x, topLeft.y});
}
void draw_border_patch(gfx::Paint& paint, Box& bounds, Box& size, math::vec3 colour) {
gfx::Path2D path({0,0});
path.colour(colour);
// draw edges
draw_box(path, {bounds.left + size.left, bounds.top}, {bounds.right - size.right, bounds.top + size.top} );
draw_box(path, {bounds.right - size.right, bounds.top + size.top}, {bounds.right, bounds.bottom - size.bottom} );
draw_box(path, {bounds.left + size.left, bounds.bottom - size.bottom}, {bounds.right - size.right, bounds.bottom} );
draw_box(path, {bounds.left, bounds.top + size.top}, {bounds.left + size.left, bounds.bottom - size.bottom} );
// draw-corners
draw_box(path, {bounds.left, bounds.top}, {bounds.left + size.left, bounds.top + size.top} );
draw_box(path, {bounds.right - size.right, bounds.top}, {bounds.right, bounds.top + size.top} );
draw_box(path, {bounds.left, bounds.bottom - size.bottom}, {bounds.left + size.left, bounds.bottom} );
draw_box(path, {bounds.right - size.right, bounds.bottom - size.bottom}, {bounds.right, bounds.bottom});
paint.fill(path);
}
void draw_border_solid(gfx::Paint& paint, Box& bounds, Box& size, math::vec3 colour) {
gfx::Path2D path({0,0});
path.colour(colour);
// draw edges
draw_box(path, {bounds.left, bounds.top}, {bounds.right, bounds.top + size.top} );
draw_box(path, {bounds.right - size.right, bounds.top + size.top}, {bounds.right, bounds.bottom - size.bottom} );
draw_box(path, {bounds.left, bounds.bottom - size.bottom}, {bounds.right, bounds.bottom} );
draw_box(path, {bounds.left, bounds.top + size.top}, {bounds.left + size.left, bounds.bottom - size.bottom} );
paint.fill(path);
}
void draw_background_solid(gfx::Paint& paint, Box& bounds, math::vec3 colour) {
gfx::Path2D path({0,0});
path.colour(colour);
draw_box(path, {bounds.left, bounds.top}, {bounds.right, bounds.bottom} );
paint.fill(path);
}
void layout(model::Widget& current) {
if ( current.isLeaf() ) {
// if the widget has a defined size, use that
if ( current.hasAttr("size") && !current.hasAttr("text") ) {
return;
}
// else, use the model's preferred size
auto preferred = current.preferredSize();
if ( preferred.has_value() ) {
current.set<math::vec2>("size", preferred.value() );
}
} else {
auto topPad = current.get_or_default<float>("border:top") + current.get_or_default<float>("padding::top");
auto leftPad = current.get_or_default<float>("border::left") + current.get_or_default<float>("padding::left");
math::vec2 size = {topPad, leftPad};
// layout all children
for ( auto& child : current ) {
layout(child);
auto childSize = child.get_or_default<math::vec2>("size");
size.x = std::max( childSize.x, size.x );
size.y += childSize.y;
child.set<math::vec2>("position", {leftPad, size.y});
}
// set our size based on that
current.set<math::vec2>("size", size );
}
}
void visit(const model::Widget& root, gfx::Paint& paint, Box offset) {
// get border size
auto border = get_box(root, "border");
// calculate box bounds
auto pos = get_vec2(root, "position");
auto size = get_vec2(root, "size");
auto bounds = getBounds(pos, size);
bounds.top += offset.top;
bounds.left += offset.left;
// deal with right hand size bounds
//bounds.right = std::min( size.x, offset.width() );
//bounds.right += offset.left;
// deal with bottom bounds
//bounds.bottom = std::min( size.y, offset.height() );
//bounds.bottom += offset.top;
auto background = bounds.trim(border);
draw_background_solid(paint, background, get_vec3_rgb(root, "colour"));
draw_border_patch(paint, bounds, border, get_vec3_rgb(root, "border::colour"));
auto padding = get_box(root, "padding");
background = background.trim(padding);
if ( root.hasAttr("text") ) {
auto text = root.get<std::string>("text");
paint.text(text, {background.left, background.top + PADDING});
}
for (const auto& child : root) {
visit(child, paint, background);
}
}
} // namespace fggl::gui:;renderer
\ No newline at end of file
......@@ -20,9 +20,9 @@
namespace fggl::gui {
void buttonBorder(gfx::Path2D &path, glm::vec2 pos, glm::vec2 size) {
void button_border(gfx::Path2D &path, glm::vec2 pos, glm::vec2 size) {
// outer box
path.colour({1.0f, 0.0f, 0.0f});
path.colour({1.0F, 0.0F, 0.0F});
path.pathTo({pos.x + size.x, pos.y});
path.pathTo({pos.x + size.x, pos.y + size.y});
path.pathTo({pos.x, pos.y + size.y});
......@@ -32,7 +32,7 @@ namespace fggl::gui {
math::vec2 innerTop{pos.x + 5, pos.y + 5};
math::vec2 innerBottom{pos.x + size.x - 5, pos.y + size.y - 5};
path.colour({1.0f, 1.0f, 0.0f});
path.colour({1.0F, 1.0F, 0.0F});
path.moveTo({innerTop.x, innerTop.y});
path.pathTo({innerBottom.x, innerTop.y});
path.pathTo({innerBottom.x, innerBottom.y});
......@@ -52,7 +52,7 @@ namespace fggl::gui {
const auto bottomRight{topLeft + size};
// background
path.colour({0.5f, 0.5f, 0.5f});
path.colour({0.5F, 0.5F, 0.5F});
draw_box(path, topLeft, bottomRight);
// fill
......@@ -65,13 +65,13 @@ namespace fggl::gui {
innerBottom.x = innerTop.x + barWidth;
// draw the bar
path.colour({0.8f, 0.0f, 0.0f});
path.colour({0.8F, 0.0F, 0.0F});
draw_box(path, innerTop, innerBottom);
// part of the bar that's not filled in
math::vec2 emptyTop{innerBottom.x, innerTop.y};
math::vec2 emptyBottom{trueBottom, innerBottom.y};
path.colour({0.4f, 0.0f, 0.0f});
path.colour({0.4F, 0.0F, 0.0F});
draw_box(path, emptyTop, emptyBottom);
}
......@@ -90,7 +90,7 @@ namespace fggl::gui {
math::vec2 selectorTop{innerTop.x + selectorValue - (selectorWidth / 2), topLeft.y};
math::vec2 selectorBottom{selectorTop.x + selectorWidth, bottomRight.y};
path.colour({1.0f, 1.0f, 1.0f});
path.colour({1.0F, 1.0F, 1.0F});
draw_box(path, selectorTop, selectorBottom);
}
......@@ -101,18 +101,18 @@ namespace fggl::gui {
math::vec2 innerTop{pos.x + 5, pos.y + 5};
math::vec2 innerBottom{pos.x + size.x - 5, pos.y + size.y - 5};
math::vec3 baseColour{0.5f, 0.5f, 0.5f};
math::vec3 baseColour{0.5F, 0.5F, 0.5F};
if (active) {
baseColour *= 1.2f;
baseColour *= 1.2F;
}
if (pressed) {
baseColour *= 0.8f;
baseColour *= 0.8F;
}
math::vec3 lightColour{baseColour * 1.2f};
math::vec3 darkColour{baseColour * 0.8f};
math::vec3 lightColour{baseColour * 1.2F};
math::vec3 darkColour{baseColour * 0.8F};
if (pressed) {
// flip light and dark for selected buttons
auto tmp = darkColour;
......
......@@ -55,7 +55,7 @@ namespace fggl::gui {
m_label.size(topLeft(), size());
}
std::string Button::label() const {
auto Button::label() const -> std::string {
return m_label.text();
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -13,7 +13,6 @@
*/
#include "fggl/math/triangulation.hpp"
#include <iostream>
namespace fggl::math {
......@@ -29,7 +28,7 @@ namespace fggl::math {
// deal with the indices
const auto nTris = polygon.size() - 2;
for (auto i = 0u; i < nTris; i++) {
for (auto i = 0U; i < nTris; i++) {
mesh.add_index(firstIdx);
mesh.add_index(prevIdx);
......
......@@ -20,7 +20,7 @@
namespace fggl::phys {
bool NullPhysics::factory(modules::ModuleService serviceName, modules::Services &serviceManager) {
auto NullPhysics::factory(modules::ServiceName serviceName, modules::Services &serviceManager) -> bool {
if (serviceName == phys::PhysicsProvider::service) {
serviceManager.bind<phys::PhysicsProvider, NullPhysicsProvider>();
return true;
......
This diff is collapsed.
......@@ -28,7 +28,7 @@ namespace fggl::scenes {
m_input = app.service<input::Input>();
}
void GameBase::update(float dt) {
void GameBase::update(float /*dt*/) {
// detect the user quitting
if (m_input != nullptr) {
bool escapePressed = m_input->keyboard.pressed(glfwGetKeyScancode(GLFW_KEY_ESCAPE));
......@@ -59,7 +59,7 @@ namespace fggl::scenes {
m_world.reset();
}
void Game::update(float dt) {
void Game::update(float /*dt*/) {
assert(m_world && "called game update, but there was no world - was activate called?");
if (m_input != nullptr) {
......@@ -67,18 +67,23 @@ namespace fggl::scenes {
if (escapePressed) {
m_owner.change_state(m_previous);
}
if ( m_input->keyboard.pressed(glfwGetKeyScancode(GLFW_KEY_F2)) ) {
m_debug = !m_debug;
}
}
if (m_phys != nullptr) {
m_phys->step();
}
// debug render toggle
//m_world->reapEntities();
}
void Game::render(fggl::gfx::Graphics &gfx) {
if (m_world != nullptr) {
gfx.drawScene(*m_world);
gfx.drawScene(*m_world, m_debug);
}
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -27,7 +27,7 @@ namespace fggl::util {
std::map<GUID, std::string> guidTable;
}
GUID internString(const char *str) {
auto intern_string(const char *str) -> GUID {
assert(str != nullptr);
GUID guid = make_guid(str);
......@@ -40,7 +40,7 @@ namespace fggl::util {
return guid;
}
std::string guidToString(GUID guid) {
auto guid_to_string(GUID guid) -> std::string {
auto tableValue = guidTable.find(guid);
if (tableValue != guidTable.end()) {
return tableValue->second;
......@@ -51,12 +51,12 @@ namespace fggl::util {
}
fggl::util::GUID operator "" _fid(const char *str) {
fggl::util::internString(str);
auto operator "" _fid(const char *str) -> fggl::util::GUID {
fggl::util::intern_string(str);
return fggl::util::make_guid(str);
}
fggl::util::GUID operator "" _fid(const char *str, std::size_t) {
fggl::util::internString(str);
auto operator "" _fid(const char *str, std::size_t) -> fggl::util::GUID {
fggl::util::intern_string(str);
return fggl::util::make_guid(str);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.