Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ execute_process(COMMAND git rev-parse --short HEAD
OUTPUT_STRIP_TRAILING_WHITESPACE
)

find_package(GLEW REQUIRED)
if (NOT EMSCRIPTEN)
find_package(GLEW REQUIRED)
endif()
find_package(fmt REQUIRED)

include(cmake/utils.cmake)
Expand All @@ -21,6 +23,9 @@ option(ESSAGUI_EXAMPLES "Compile examples" ON)
option(ESSAGUI_UTIL_ONLY "Compile only EssaUtil (no GUI or Engine)" OFF)

include_directories(${Essa_SOURCE_DIR})
if (EMSCRIPTEN)
include_directories(${fmt_DIR}/../../../include)
endif()

add_subdirectory(EssaUtil)

Expand Down
5 changes: 0 additions & 5 deletions Essa/GUI/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,3 @@ set_target_properties(GUI PROPERTIES OUTPUT_NAME "essa-gui")
set_target_properties(GUI PROPERTIES SOVERSION ${ESSA_GIT_REVISION})
essautil_setup_target(GUI)
target_link_libraries(GUI PUBLIC Util LLGL-OpenGL LLGL-Window LLGL-Resources)

# FIXME: This breaks build of eml/AST.cpp somewhere in Value::string()
target_compile_options(GUI PRIVATE -Wno-restrict)
# FIXME: This breaks build of RadioGroup::add_widget().
target_compile_options(GUI PUBLIC -Wno-address)
14 changes: 8 additions & 6 deletions Essa/GUI/Debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ class DebugSwitch {
/*global*/ ::GUI::DebugSwitch __debug_##name { \
# name \
}
#define DBG_PRINTLN(name, fmtstr, ...) \
{ \
if (DBG_ENABLED(name)) { \
fmt::vprint(fmtstr "\n", fmt::make_format_args(__VA_ARGS__)); \
} \
}

#define DBG_PRINTLN(name, fmtstr, ...) \
do { \
if (DBG_ENABLED(name)) { \
const auto& vargs = fmt::make_format_args(__VA_ARGS__); \
fmt::vprint(fmtstr "\n", vargs); \
} \
} while (false)
2 changes: 1 addition & 1 deletion Essa/GUI/EML/AST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ template<class... Ts> struct overloaded : Ts... {

std::string Value::string() const {
return std::visit(
overloaded {
Util::Overloaded {
[](double d) -> std::string { return fmt::format("{}", d); },
[](bool b) -> std::string { return b ? "true" : "false"; },
[](Util::UString const& str) -> std::string { return "\"" + str.encode() + "\""; },
Expand Down
21 changes: 20 additions & 1 deletion Essa/GUI/EventLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#ifdef __linux__
# include <sys/prctl.h>
#elif defined(__EMSCRIPTEN__)
# include <emscripten.h>
#endif

using namespace std::chrono_literals;
Expand Down Expand Up @@ -39,8 +41,24 @@ void increase_system_timer_resolution() {
void EventLoop::run() {
auto old_event_loop = s_current_event_loop;
s_current_event_loop = this;
Util::ScopeGuard guard = [&]() { s_current_event_loop = old_event_loop; };
#ifdef __EMSCRIPTEN__
if (!old_event_loop) {
emscripten_set_main_loop(
[]() {
s_current_event_loop->tick();
if (!s_current_event_loop->m_running) {
// FIXME: Make this work properly with dialogs. It may require
// refactoring them to be asynchronous ?
emscripten_cancel_main_loop();
}
},
0, true
);
return;
}
#else

Util::ScopeGuard guard = [&]() { s_current_event_loop = old_event_loop; };
Util::Clock clock;

increase_system_timer_resolution();
Expand Down Expand Up @@ -73,6 +91,7 @@ void EventLoop::run() {
}
}
}
#endif
}

EventLoop::TimerHandle EventLoop::set_timeout(Timer::Clock::duration const& timeout, Timer::Callback&& callback) {
Expand Down
40 changes: 40 additions & 0 deletions Essa/GUI/Graphics/DefaultGUIShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,45 @@

namespace Gfx {

#ifdef __EMSCRIPTEN__
static std::string_view VertexShader = R"~~~(// Default GUI VS
precision highp float;
precision highp int;

attribute vec2 position;
attribute vec4 color;
attribute vec2 texCoords;

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 submodelMatrix;

varying vec4 fColor;
varying vec2 fTexCoords;

void main() {
fColor = color;
fTexCoords = texCoords;
gl_Position = projectionMatrix * (viewMatrix * (modelMatrix * (submodelMatrix * vec4(position, 0, 1))));
}
)~~~";

static std::string_view FragmentShader = R"~~~(// Default GUI FS
precision highp float;
precision highp int;

varying vec4 fColor;
varying vec2 fTexCoords;

uniform sampler2D texture;
uniform bool textureSet;

void main() {
gl_FragColor = textureSet ? fColor * texture2D(texture, fTexCoords.xy) : fColor;
}
)~~~";
#else
static std::string_view VertexShader = R"~~~(// Default GUI VS
#version 330 core

Expand Down Expand Up @@ -41,6 +80,7 @@ void main() {
gl_FragColor = textureSet ? fColor * texture2D(texture, fTexCoords.xy) : fColor;
}
)~~~";
#endif

std::string_view DefaultGUIShader::source(llgl::ShaderType type) const {
switch (type) {
Expand Down
1 change: 0 additions & 1 deletion Essa/GUI/Graphics/Drawing/Shape.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ class Shape {

private:
Shape const& m_shape;
size_t m_index = 0;
};

Points points() const { return Points { *this }; }
Expand Down
2 changes: 1 addition & 1 deletion Essa/GUI/Graphics/GUIBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class GUIBuilder : public llgl::Builder<Vertex, GUIBuilderRenderRange> {

virtual void
render_range(llgl::Renderer& renderer, llgl::VertexArray<Vertex> const& vao, GUIBuilderRenderRange const& range) const override {
static Gfx::DefaultGUIShader m_shader;
Gfx::DefaultGUIShader::Uniforms uniforms;
uniforms.set_transform(range.model.matrix(), range.view.matrix(), range.projection.matrix());
uniforms.set_texture(range.texture);
Expand All @@ -62,7 +63,6 @@ class GUIBuilder : public llgl::Builder<Vertex, GUIBuilderRenderRange> {
renderer.draw_vertices(vao, llgl::DrawState { m_shader, uniforms, range.type }, range.first, range.size);
}

mutable Gfx::DefaultGUIShader m_shader;
llgl::Projection m_projection;
llgl::Transform m_view;
llgl::Transform m_model;
Expand Down
2 changes: 2 additions & 0 deletions Essa/GUI/Graphics/ResourceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ llgl::TTFFont& ResourceManager::fixed_width_font() const {
static std::filesystem::path exec_path() {
#ifdef __linux__
return std::filesystem::read_symlink("/proc/" + std::to_string(getpid()) + "/exe").parent_path();
#elif __EMSCRIPTEN__
return "/";
#else
# error OS not supported (install linux)
#endif
Expand Down
15 changes: 9 additions & 6 deletions Essa/GUI/Overlays/FileExplorer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
#include <EssaUtil/Config.hpp>
#include <EssaUtil/UnitDisplay.hpp>
#include <EssaUtil/Units.hpp>
#include <chrono>
#include <filesystem>
#include <fmt/chrono.h>
#include <fstream>
#include <functional>
#include <iostream>
Expand Down Expand Up @@ -63,12 +65,13 @@ Variant FileModel::data(Node row, size_t column) const {
case 4: {
return Util::UString { file_type(file) };
}
case 3:
std::time_t cftime
= std::chrono::system_clock::to_time_t(std::chrono::file_clock::to_sys(std::filesystem::last_write_time(file.path)));
std::string string = std::asctime(std::localtime(&cftime));
string.pop_back(); // trailing \n
return Util::UString { string };
case 3: {
using namespace std::chrono_literals;
namespace ch = std::chrono;
// FIXME: Use clock cast when clang supports this.
auto time = ch::file_clock::to_sys(ch::time_point_cast<ch::sys_seconds::duration>(std::filesystem::last_write_time(file.path)));
return Util::UString { fmt::format("{:%x %X}", time) };
}
}
return "";
}
Expand Down
4 changes: 3 additions & 1 deletion Essa/GUI/Widgets/Container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,9 @@ void Container::dump(unsigned depth) {
for (unsigned i = 0; i < depth; i++)
std::cout << "- ";
if (m_layout) {
std::cout << "layout: " << typeid(*m_layout).name() << std::endl;
// Note: Temporary variable is a workaround for -Wpotentially-evaluated-expression on Clang
auto& layout = *m_layout;
std::cout << "layout: " << typeid(layout).name() << std::endl;
}
else {
std::cout << "layout: NONE!" << std::endl;
Expand Down
56 changes: 28 additions & 28 deletions Essa/GUI/Widgets/ListView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,34 +93,34 @@ void ListView::draw(Gfx::Painter& wnd) const {
// configurable

std::visit(
overloaded { [&](Util::UString const& data) {
Gfx::Text text { data, Application::the().bold_font() };
text.set_font_size(theme().label_font_size);
text.set_fill_color(c % 2 == 0 ? list_even.text : list_odd.text);
text.align(
Align::CenterLeft, { (cell_position + Util::Vector2i(5, 0)).cast<float>(), cell_size.cast<float>() }
);
text.draw(wnd);
},
[&](Gfx::RichText const& data) {
Gfx::RichTextDrawable drawable { data,
{
.default_font = Application::the().font(),
.font_size = static_cast<int>(theme().label_font_size),
.text_alignment = GUI::Align::CenterLeft,
} };
drawable.set_rect({ (cell_position + Util::Vector2i(5, 0)).cast<float>(), cell_size.cast<float>() });
drawable.draw(wnd);
},
[&](llgl::Texture const* data) {
Gfx::RectangleDrawOptions rect;
rect.texture = data;
wnd.deprecated_draw_rectangle(
{ { cell_position.x() + cell_size.x() / 2 - 8, cell_position.y() + cell_size.y() / 2 - 8 },
{ 16, 16 } },
rect
);
} },
Util::Overloaded {
[&](Util::UString const& data) {
Gfx::Text text { data, Application::the().bold_font() };
text.set_font_size(theme().label_font_size);
text.set_fill_color(c % 2 == 0 ? list_even.text : list_odd.text);
text.align(
Align::CenterLeft, { (cell_position + Util::Vector2i(5, 0)).cast<float>(), cell_size.cast<float>() }
);
text.draw(wnd);
},
[&](Gfx::RichText const& data) {
Gfx::RichTextDrawable drawable { data,
{
.default_font = Application::the().font(),
.font_size = static_cast<int>(theme().label_font_size),
.text_alignment = GUI::Align::CenterLeft,
} };
drawable.set_rect({ (cell_position + Util::Vector2i(5, 0)).cast<float>(), cell_size.cast<float>() });
drawable.draw(wnd);
},
[&](llgl::Texture const* data) {
Gfx::RectangleDrawOptions rect;
rect.texture = data;
wnd.deprecated_draw_rectangle(
{ { cell_position.x() + cell_size.x() / 2 - 8, cell_position.y() + cell_size.y() / 2 - 8 }, { 16, 16 } },
rect
);
} },
data
);
}
Expand Down
8 changes: 5 additions & 3 deletions Essa/LLGL/OpenGL/Error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@

#include <GL/glew.h>

#include <GL/glu.h>
#include <iostream>
#include <Essa/LLGL/Window/AbstractOpenGLHelper.hpp>
#include <iostream>

namespace llgl::opengl {

void enable_debug_output() {
ensure_glew();

#ifndef __EMSCRIPTEN__
OpenGL::Enable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(
[]([[maybe_unused]] GLenum source, GLenum type, [[maybe_unused]] GLuint id, [[maybe_unused]] GLenum severity,
[[maybe_unused]] GLsizei length, const GLchar* message, [[maybe_unused]] const void* user_param) {
[[maybe_unused]] GLsizei length, GLchar const* message, [[maybe_unused]] void const* user_param) {
if (type == GL_DEBUG_TYPE_ERROR)
std::cout << "GL Error: " << message << std::endl;
},
0
);
#endif
}

void handle_error(std::source_location location) {
Expand Down
20 changes: 14 additions & 6 deletions Essa/LLGL/OpenGL/FBO.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
#include "FBO.hpp"

#include <Essa/LLGL/Window/AbstractOpenGLHelper.hpp>
#include <Essa/LLGL/OpenGL/Extensions.hpp>
#include <Essa/LLGL/Window/AbstractOpenGLHelper.hpp>
#include <iostream>

namespace llgl::opengl {

FBO::FBO(Util::Size2u size) {
opengl::ensure_glew();
OpenGL::GenFramebuffers(1, &m_fbo);
FBOScope scope { *this };

resize(size);
FBOScope scope { *this };
OpenGL::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth_renderbuffer);

GLenum buffers[] = { GL_COLOR_ATTACHMENT0 };
OpenGL::DrawBuffers(1, buffers);
Expand Down Expand Up @@ -41,25 +39,35 @@ void FBO::bind(Target target) const {
}

void FBO::resize(Util::Size2u size) {
FBOScope scope { *this };
if (m_color_texture.size() == size)
return;

FBOScope scope { *this };

// Color
if (!m_color_texture.id())
m_color_texture = Texture::create_empty(size, Texture::Format::RGBA);
else
m_color_texture.recreate(size, Texture::Format::RGBA);
OpenGL::FramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_color_texture.id(), 0);

OpenGL::FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color_texture.id(), 0);

// Depth
if (m_depth_renderbuffer)
OpenGL::DeleteRenderbuffers(1, &m_depth_renderbuffer);

OpenGL::GenRenderbuffers(1, &m_depth_renderbuffer);
OpenGL::BindRenderbuffer(GL_RENDERBUFFER, m_depth_renderbuffer);
OpenGL::RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.x(), size.y());
OpenGL::FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth_renderbuffer);

// std::cout << "FBO: recreated with size " << size.x << "," << size.y << std::endl;
}

void FBO::set_label(std::string const& str) {
#ifndef __EMSCRIPTEN__
OpenGL::ObjectLabel(GL_FRAMEBUFFER, m_fbo, str.size(), str.data());
#endif
m_color_texture.set_label("FBO Texture: " + str);
}

Expand Down
Loading