Commit 4b44a955 authored by Johannes Braun's avatar Johannes Braun
Browse files

Comfort improvements

parent 668bfcd7
......@@ -9,7 +9,7 @@ Size=302,900
Collapsed=0
[Settings]
Pos=1145,2
Pos=1145,1
Size=295,531
Collapsed=0
......@@ -29,7 +29,7 @@ Size=59,66
Collapsed=0
[akjshd]
Pos=687,98
Size=340,254
Pos=13,6
Size=930,616
Collapsed=0
<linespace version="1.0">
<item name="subdivisions" value="8"/>
<item name="grid-subdivisions" value="10"/>
<item name="grid-subdivisions" value="5"/>
<item name="radial-subdivision" value="50"/>
<item name="generator" value="gpu"/>
</linespace>
......@@ -11,6 +11,7 @@
#include <core/audio/sound_source.h>
#include <core/objects/skybox.h>
#include <core/res/res.h>
#include <core/system.h>
#include <raytrace/tracer/pathtracer.h>
......@@ -92,14 +93,6 @@ int main(int argc, char* argv[])
break;
}
if (pathtracer->collector())
{
ImGui::Begin("akjshd");
ImGui::Image(reinterpret_cast<void*>(pathtracer->renderTarget().textureAddress()), ImVec2(144, 90));
ImGui::End();
}
drawSceneWindow();
drawSettingsWindow();
drawSystemWindow();
......@@ -135,7 +128,7 @@ void loadScene(const fs::path& path, float scale)
console::prompt("Scene could not be loaded: " + path.string() + ". Press [ENTER] to exit.", 1);
}
std::shared_ptr<core::SceneNode> cam_node = core::Context::current().graph()->find<core::Camera>();
auto cam_node = core::Context::current().graph()->find<core::Camera>();
if (cam_node)
{
//If there are any cameras in the collada file, take the first one.
......@@ -181,7 +174,6 @@ void drawSystemWindow()
{
frametime = static_cast<float>(1000 * time / frame);
fps = 1000.f / frametime;
Log_Debug << std::to_string(frame) << " FPS | " << std::to_string(1000 * time / frame) << "ms/Frame";
time = 0;
frame = 0;
gl::getIntegerv(gl::GetParameter::eGpuMemoryDedicatedVidmemMax, &mem);
......@@ -209,24 +201,19 @@ void drawSystemWindow()
return ss.str();
};
#if _DEBUG
const std::string build_type = "Debug build";
#elif NDEBUG
const std::string build_type = "Release build";
#endif
ImGui::Text(build_type.c_str());
ImGui::Text(std::string(system::host_name) + ", " + std::string(system::build_name));
ImGui::Spacing();
ImGui::Title("Memory");
ImGui::ProgressBar((mem - left) / static_cast<float>(mem), ImVec2(-1, 0), (format_float(static_cast<float>(mem - left) / 1'000'000, 2) + "GB used").c_str());
ImGui::Text(("Total memory: " + format_float(static_cast<float>(mem) / 1'000'000, 2) + "GB").c_str());
ImGui::Text(("Available memory: " + format_float(static_cast<float>(left) / 1'000'000, 2) + "GB").c_str());
ImGui::PlotLines("", mem_fills.data(), mem_fills.size(), 0, "Filled Memory", 0, mem / 1'000'000.f, ImVec2(ImGui::GetContentRegionAvailWidth(), 64));
ImGui::Text("Total memory: " + format_float(static_cast<float>(mem) / 1'000'000, 2) + "GB");
ImGui::Text("Available memory: " + format_float(static_cast<float>(left) / 1'000'000, 2) + "GB");
ImGui::PlotLines("", mem_fills.data(), static_cast<int>(mem_fills.size()), 0, "Filled Memory", 0, mem / 1'000'000.f, ImVec2(ImGui::GetContentRegionAvailWidth(), 64));
ImGui::Spacing();
ImGui::Title("Performance");
ImGui::Value("Frames per second", fps);
ImGui::Text(("Frame time: " + format_float(frametime, 3) + "ms").c_str());
ImGui::PlotLines("", frametimes.data(), frametimes.size(), 0, "Frame times", 0, 100, ImVec2(ImGui::GetContentRegionAvailWidth(), 64));
ImGui::Text("Frame time: " + format_float(frametime, 3) + "ms");
ImGui::PlotLines("", frametimes.data(), static_cast<int>(frametimes.size()), 0, "Frame times", 0, 100, ImVec2(ImGui::GetContentRegionAvailWidth(), 64));
ImGui::End();
}
......
......@@ -107,7 +107,7 @@ namespace glare::core
// Direct initialization for either 1D, 2D or 3D target.
// I'll let it implicitly convertible for now, seems useful.
template<typename T> Texture(const Image<T>& image);
template<typename T> Texture(const Image<T>& image, Parameters parameters = Parameters());
template<typename T> Image<T> get() const;
......@@ -137,7 +137,7 @@ namespace glare::core
default: throw std::invalid_argument("Texture format not valid.");
}
}(value.length(), texture_type);
gl::clearTextureImage(m_handle, 0, texture_format, texture_type, &value);
}
......@@ -148,7 +148,7 @@ namespace glare::core
{
return (type == gl::Type::eInt || type == gl::Type::eUInt) ? gl::TextureFormat::eRedInt : gl::TextureFormat::eRed;
}(texture_type);
gl::clearTextureImage(m_handle, 0, texture_format, texture_type, &value);
}
......@@ -185,7 +185,8 @@ namespace glare::core
mutable uint64_t m_image_address = 0;
};
template<typename T> Texture::Texture(const Image<T>& image)
template <typename T>
Texture::Texture(const Image<T>& image, Parameters parameters)
: Texture([&image]() {
switch (image.dimensions())
{
......@@ -199,18 +200,18 @@ namespace glare::core
switch (m_target)
{
case Target::e1D:
set(SubTarget::e1D, image, m_latest_parameters);
set(SubTarget::e1D, image, parameters);
break;
case Target::e2D:
set(SubTarget::e2D, image, m_latest_parameters);
set(SubTarget::e2D, image, parameters);
break;
case Target::e3D:
set(SubTarget::e3D, image, m_latest_parameters);
set(SubTarget::e3D, image, parameters);
break;
default: throw std::invalid_argument("Target not defined as 1D, 2D or 3D. How exactly did you manage to come to this point???");
}
}
template<typename T> Image<T> Texture::get() const
{
if (m_target != gl::TextureType::e2D || m_components == -1)
......
#include "gui.h"
#include <util/offset_of.h>
#include <core/base/gl_state.h>
#include "system.h"
#define NOMINMAX
#ifdef _WIN32
......@@ -31,18 +32,17 @@ namespace gui
{
auto&& io = m_context->IO;
io.UserData = this;
//io.RenderDrawListsFn = renderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer.
io.SetClipboardTextFn = [](void* user_data, const char* clip) { glfwSetClipboardString(reinterpret_cast<Gui*>(user_data)->m_window, clip); };
io.GetClipboardTextFn = [](void* user_data) { return glfwGetClipboardString(reinterpret_cast<Gui*>(user_data)->m_window); };
#ifdef _WIN32
io.ImeWindowHandle = glfwGetWin32Window(m_window);
#endif
if constexpr(glare::system::host == glare::system::System::eWindows)
io.ImeWindowHandle = glfwGetWin32Window(m_window);
}
void Gui::initializeDrawRequirements()
{
if (static bool locker = true; locker) { locker = false; }
else { return; }
if (m_initialized) return;
m_initialized = true;
// Backup GL state
int last_texture, last_array_buffer, last_vertex_array;
......@@ -143,7 +143,7 @@ namespace gui
ImGui::NewFrame();
}
void Gui::render()
void Gui::render() const
{
ImGui::Render();
auto draw_data = ImGui::GetDrawData();
......@@ -201,7 +201,8 @@ namespace gui
else
{
// using bindless here.
m_program->uniform("gui_texture", reinterpret_cast<uint64_t>(pcmd.TextureId));
uint64_t address = reinterpret_cast<uint64_t>(pcmd.TextureId);
m_program->uniform("gui_texture", address);
gl::scissor(static_cast<int>(pcmd.ClipRect.x), static_cast<int>(fb_height - pcmd.ClipRect.w), static_cast<unsigned>(pcmd.ClipRect.z - pcmd.ClipRect.x), static_cast<unsigned>(pcmd.ClipRect.w - pcmd.ClipRect.y));
gl::drawElements(gl::PrimitiveType::eTriangles, static_cast<unsigned>(pcmd.ElemCount), gl::Type::eUShort, idx_buffer_offset);
}
......@@ -221,7 +222,7 @@ namespace gui
m_mouse_down[button] = down;
}
void Gui::notifyKeyPress(int key, int scancode, int action, int mods)
void Gui::notifyKeyPress(int key, int scancode, int action, int mods) const
{
auto&& io = m_context->IO;
if (action == GLFW_PRESS)
......@@ -234,14 +235,14 @@ namespace gui
io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT];
}
void Gui::notifyCharInput(const int c)
void Gui::notifyCharInput(const int c) const
{
auto&& io = m_context->IO;
if (c > 0 && c < 0x10000)
io.AddInputCharacter(static_cast<unsigned short>(c));
}
void Gui::mapKeys()
void Gui::mapKeys() const
{
// Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
auto&& io = m_context->IO;
......@@ -266,7 +267,7 @@ namespace gui
io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z;
}
void Gui::applyTheme()
void Gui::applyTheme() const
{
m_context->IO.Fonts->AddFontFromFileTTF(files::asset("/fonts/OpenSans-Semibold.ttf").string().c_str(), 14);
......@@ -331,17 +332,17 @@ namespace gui
style.Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(1.00f, 0.98f, 0.95f, 0.73f);
}
Gui::Style& Gui::style()
Gui::Style& Gui::style() const
{
return m_context->Style;
}
Gui::IO& Gui::io()
Gui::IO& Gui::io() const
{
return m_context->IO;
}
Gui::Context& Gui::context()
Gui::Context& Gui::context() const
{
return *m_context;
}
......
#ifndef INCLUDE_GUI_H
#define INCLUDE_GUI_H
#include "imgui.h"
#include <imgui/imgui.h>
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui_internal.h"
#include "imgui_orient.h"
#include <imgui/imgui_internal.h>
#include <imgui/imgui_orient.h>
#include <array>
#include <memory>
......@@ -34,21 +34,21 @@ namespace gui
explicit Gui(GLFWwindow* window, fs::path ini_file = "../assets/imgui/config.ini");
~Gui();
Style& style();
IO& io();
Context& context();
Style& style() const;
IO& io() const;
Context& context() const;
void newFrame();
void render();
void render() const;
void notifyMouseScroll(float x, float y);
void notifyMouseButton(int button, bool down);
void notifyKeyPress(int key, int scancode, int action, int mods);
void notifyCharInput(const int c);
void notifyKeyPress(int key, int scancode, int action, int mods) const;
void notifyCharInput(const int c) const;
private:
void applyTheme();
void mapKeys();
void applyTheme() const;
void mapKeys() const;
void addCallbacks();
void initializeDrawRequirements();
......@@ -63,6 +63,7 @@ namespace gui
glare::core::Buffer m_element_buffer;
std::unique_ptr<glare::core::Texture> m_font_texture;
bool m_initialized = false;
float m_scroll_y = 0.f;
std::array<bool, 3> m_mouse_down{ false, false, false };
};
......
#ifndef INCLUDE_SYSTEM_H
#define INCLUDE_SYSTEM_H
#include <string_view>
namespace glare::system
{
using namespace std::string_view_literals;
enum class System
{
eWindows,
eLinux,
eMac
};
enum class Build
{
eDebug,
eRelease
};
#ifdef __linux__
constexpr System host = System::eLinux;
constexpr std::string_view host_name = "Linux"sv;
static_assert(false, "Compiling on Linux is not supported.")
#elif __APPLE__
constexpr System host = System::eMac;
constexpr std::string_view host_name = "Mac"sv;
static_assert(false, "Compiling on Mac is not supported.")
#elif _WIN32
constexpr System host = System::eWindows;
constexpr std::string_view host_name = "Windows"sv;
#endif
#ifdef _DEBUG
constexpr Build build = Build::eDebug;
constexpr std::string_view build_name = "Debug"sv;
#else
constexpr Build build = Build::eRelease;
constexpr std::string_view build_name = "Release"sv;
#endif
}
#endif //!INCLUDE_SYSTEM_H
\ No newline at end of file
......@@ -4,25 +4,28 @@
#include <core/numeric/flags.h>
#include "time.h"
namespace glare::core{
Window::Window(unsigned int width, unsigned int height, std::string title) { initialize(width, height, title); }
namespace glare::core{ Window::Window(unsigned int width, unsigned int height, std::string title) { initialize(width, height, title); }
Window::Window() : m_main_window(nullptr), m_vsync(VSync::eOn60), m_width(0), m_height(0) {
} void Window::initialize(unsigned int width, unsigned int height, std::string title) {
m_width = width; m_height = height;
glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
}
void Window::initialize(unsigned int width, unsigned int height, std::string title) { m_width = width;
m_height = height;
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
// To enable some more debug messages and hints glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
// To enable robust buffer access on out-of-bounds accesses. glfwWindowHint(GLFW_CONTEXT_ROBUSTNESS, GLFW_NO_RESET_NOTIFICATION);
if (width * height == 0) glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
m_main_window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
glfwMakeContextCurrent(m_main_window); glewExperimental = true; glewInit(); m_gui = std::make_unique<gui::Gui>(m_main_window); glfwMakeContextCurrent(nullptr); }
void Window::makeCurrent() const
glfwMakeContextCurrent(m_main_window); glewExperimental = true; glewInit();
m_gui = std::make_unique<gui::Gui>(m_main_window);
glfwMakeContextCurrent(nullptr); }
void Window::makeCurrent() const { glfwMakeContextCurrent(m_main_window); }
bool Window::isClosing() const
{
glfwMakeContextCurrent(m_main_window);
return glfwWindowShouldClose(m_main_window) == 1;
}
bool Window::isClosing() const { return glfwWindowShouldClose(m_main_window) == 1; }
void Window::setVSync(VSync mode) { m_vsync = mode; glfwSwapInterval(int(mode)); }
VSync Window::getVSync() const { return m_vsync; }
void Window::setVSync(VSync mode) { m_vsync = mode; glfwSwapInterval(int(mode)); }
VSync Window::getVSync() const { return m_vsync; }
gui::Gui& Window::gui() const { return *m_gui; }
void Window::loop(loop_type loop_function) const { gl::clearColor(0, 0, 0, 0); setEnabled(gl::EnableParameter::eDepthTest); setEnabled(gl::EnableParameter::eCullFace);
glfwSwapInterval(0);
clampColor(gl::ClampColorTarget::eRead, false); cullFace(gl::Face::eBack);
......
......@@ -4,7 +4,7 @@
//std
#include <functional>
#include <imgui/gui.h>
#include "gui.h"
#include <core/numeric/geometry.h>
......@@ -51,8 +51,7 @@ namespace glare
GLFWwindow* glfw() const;
math::Rectangle windowRectangle() const;
VSync getVSync() const;
gui::Gui& gui() { return *m_gui; }
gui::Gui& gui() const;
private:
GLFWwindow *m_main_window;
......
......@@ -6,17 +6,25 @@
#include "imgui_glfw.h"
#include "imgui_internal.h"
#include <memory>
#include <util/files.h>
#include <util/color.h>
namespace ImGui {
std::map<ImU32, SelectableTree> nodes_cached;
void Text(const std::string& text)
{
ImGui::Text(text.c_str());
}
bool Combo(const char* label, int* current_item, const std::vector<std::string>& items, int height_in_items)
{
return Combo(label, current_item, [](void* data, int idx, const char** out_text) { *out_text = (*static_cast<const std::vector<std::string>*>(data))[idx].c_str(); return true; }, (void*)&items, int(items.size()), height_in_items);
const void* it = &items;
return Combo(label, current_item, [](void* data, int idx, const char** out_text)
{
*out_text = (*static_cast<const std::vector<std::string>*>(data))[idx].c_str(); return true;
}, const_cast<void*>(it), int(items.size()), height_in_items);
}
void Title(const char* label)
......@@ -47,19 +55,19 @@ namespace ImGui {
bool FeatureButton(const char* label, const ImVec2& size)
{
auto &&style = ImGui::GetStyle();
auto col_bt = style.Colors[ImGuiCol_Button];
auto col_bt_h = style.Colors[ImGuiCol_ButtonHovered];
auto col_bt_a = style.Colors[ImGuiCol_ButtonActive];
const auto col_bt = style.Colors[ImGuiCol_Button];
const auto col_bt_h = style.Colors[ImGuiCol_ButtonHovered];
const auto col_bt_a = style.Colors[ImGuiCol_ButtonActive];
auto color_bt = color::hex<color::rgba32f>("#4CAF50");
auto color_bt_h = color::hex<color::rgba32f>("#81C784");
auto color_bt_a = color::hex<color::rgba32f>("#2E7D32");
const auto color_bt = color::hex<color::rgba32f>("#4CAF50");
const auto color_bt_h = color::hex<color::rgba32f>("#81C784");
const auto color_bt_a = color::hex<color::rgba32f>("#2E7D32");
style.Colors[ImGuiCol_Button] = ImVec4(color_bt.r, color_bt.g, color_bt.b, color_bt.a);
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(color_bt_h.r, color_bt_h.g, color_bt_h.b, color_bt_h.a);
style.Colors[ImGuiCol_ButtonActive] = ImVec4(color_bt_a.r, color_bt_a.g, color_bt_a.b, color_bt_a.a);
bool active = ImGui::Button(label, size);
const bool active = ImGui::Button(label, size);
style.Colors[ImGuiCol_Button] = col_bt;
style.Colors[ImGuiCol_ButtonHovered] = col_bt_h;
......@@ -71,19 +79,19 @@ namespace ImGui {
bool AntiFeatureButton(const char* label, const ImVec2& size)
{
auto &&style = ImGui::GetStyle();
auto col_bt = style.Colors[ImGuiCol_Button];
auto col_bt_h = style.Colors[ImGuiCol_ButtonHovered];
auto col_bt_a = style.Colors[ImGuiCol_ButtonActive];
const auto col_bt = style.Colors[ImGuiCol_Button];
const auto col_bt_h = style.Colors[ImGuiCol_ButtonHovered];
const auto col_bt_a = style.Colors[ImGuiCol_ButtonActive];
auto color_bt = color::hex<color::rgba32f>("#D32F2F");
auto color_bt_h = color::hex<color::rgba32f>("#F44336");
auto color_bt_a = color::hex<color::rgba32f>("#B71C1C");
const auto color_bt = color::hex<color::rgba32f>("#D32F2F");
const auto color_bt_h = color::hex<color::rgba32f>("#F44336");
const auto color_bt_a = color::hex<color::rgba32f>("#B71C1C");
style.Colors[ImGuiCol_Button] = ImVec4(color_bt.r, color_bt.g, color_bt.b, color_bt.a);
style.Colors[ImGuiCol_ButtonHovered] = ImVec4(color_bt_h.r, color_bt_h.g, color_bt_h.b, color_bt_h.a);
style.Colors[ImGuiCol_ButtonActive] = ImVec4(color_bt_a.r, color_bt_a.g, color_bt_a.b, color_bt_a.a);
bool active = ImGui::Button(label, size);
const bool active = ImGui::Button(label, size);
style.Colors[ImGuiCol_Button] = col_bt;
style.Colors[ImGuiCol_ButtonHovered] = col_bt_h;
......@@ -96,4 +104,161 @@ namespace ImGui {
{
return CollapsingHeader((std::string(component_name) + " " + std::to_string(component_id)).c_str());
}
void EndTabs()
{
ImGui::PopStyleVar();
ImGui::EndChildFrame();
ImGui::PopStyleVar();
}
void EndTabbed()
{
ImGui::PopStyleVar();
ImGui::EndTabs();
ImGui::End();
ImGui::PopStyleVar();
}
bool Tab(const char* text, bool* v, float width)
{
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
ImVec4 color = style.Colors[ImGuiCol_Button];
ImVec4 color_hover = style.Colors[ImGuiCol_ButtonHovered];
color.w *= 0.5f;
if (*v)
{
color = style.Colors[ImGuiCol_ButtonActive];
color_hover = style.Colors[ImGuiCol_ButtonActive];
}
ImGui::PushStyleColor(ImGuiCol_Button, color);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, color_hover);
ImGui::PushID(text);
const bool ret = ImGui::Button(text, width > 0 ? ImVec2(width, 0) : ImVec2(0, 0));
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::PopID();
return ret;
}
bool VTab(const char* text, bool* v)
{
ImFont* font = GImGui->Font;
char c;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const float pad = style.FramePadding.x;
const ImVec2 text_size = CalcTextSize(text);
ImGuiWindow* window = GetCurrentWindow();
ImVec2 pos = window->DC.CursorPos + ImVec2(pad, text_size.x + pad);
const ImU32 text_color = ImGui::ColorConvertFloat4ToU32(style.Colors[ImGuiCol_Text]);
ImVec4 color = style.Colors[ImGuiCol_Button];
ImVec4 color_hover = style.Colors[ImGuiCol_ButtonHovered];
color.w *= 0.5f;
if (*v)
{
color = style.Colors[ImGuiCol_ButtonActive];
color_hover = style.Colors[ImGuiCol_ButtonActive];
}
ImGui::PushStyleColor(ImGuiCol_Button, color);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, color_hover);
ImGui::PushID(text);
const bool ret = ImGui::Button("", ImVec2(text_size.y + pad * 2,
text_size.x + pad * 2));
ImGui::PopStyleColor();
ImGui::PopStyleColor();
while ((c = *text++))
{
const ImFont::Glyph* glyph = font->FindGlyph(c);
if (!glyph) continue;
window->DrawList->PrimReserve(6, 4);
window->DrawList->PrimQuadUV(
pos + ImVec2(glyph->Y0, -glyph->X0),
pos + ImVec2(glyph->Y0, -glyph->X1),
pos + ImVec2(glyph->Y1, -glyph->X1),
pos + ImVec2(glyph->Y1, -glyph->X0),
ImVec2(glyph->U0, glyph->V0),
ImVec2(glyph->U1, glyph->V0),
ImVec2(glyph->U1, glyph->V1),
ImVec2(glyph->U0, glyph->V1),
text_color);
pos.y -= glyph->XAdvance;
}