Skip to content

Commit

Permalink
Initial commit of debug ui
Browse files Browse the repository at this point in the history
  • Loading branch information
Ozaq committed Jan 16, 2024
1 parent cfdaf24 commit ae8bbca
Show file tree
Hide file tree
Showing 3,384 changed files with 836,704 additions and 1 deletion.
The diff you're trying to view is too large. We only load the first 3000 changed files.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ endif()
set(BUILD_BENCHMARKS OFF CACHE BOOL "Build micro benchmark")
print_var(BUILD_BENCHMARKS)

option(BUILD_JPS_UI "Build visualisation" OFF)

set(WITH_FORMAT OFF CACHE BOOL "Create format tools")
print_var(WITH_FORMAT)
if(WITH_FORMAT AND ${CMAKE_SYSTEM} MATCHES "Windows")
Expand Down Expand Up @@ -219,6 +221,9 @@ add_subdirectory(libjupedsim)
add_subdirectory(libcommon)
add_subdirectory(libsimulator)
add_subdirectory(python_bindings_jupedsim)
if(BUILD_JPS_UI)
add_subdirectory(jps-ui)
endif()

################################################################################
# Code formatting
Expand Down
29 changes: 29 additions & 0 deletions jps-ui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
add_executable(jps-ui
src/aabb.cpp
src/aabb.hpp
src/gui.cpp
src/gui.hpp
src/main.cpp
src/ortho_camera.cpp
src/ortho_camera.hpp
src/shader.cpp
src/shader.hpp
src/wkt.cpp
src/wkt.hpp
)

target_link_libraries(jps-ui
glfw
OpenGL::GL
GEOS::geos_c
CGAL::CGAL
imgui
imgui_filedialog
glm
)

target_compile_definitions(jps-ui PUBLIC
GL_SILENCE_DEPRECATION
GLFW_INCLUDE_GLCOREARB
)

23 changes: 23 additions & 0 deletions jps-ui/src/aabb.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "aabb.hpp"

float AABB::Aspect() const
{
const auto diff = max - min;
return diff.x / diff.y;
}

float AABB::Width() const
{
return max.x - min.x;
}

float AABB::Height() const
{
return max.y - min.y;
}
glm::vec2 AABB::Center() const
{
return min + (max - min) / 2.0f;
}
15 changes: 15 additions & 0 deletions jps-ui/src/aabb.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

#include <glm/vec2.hpp>

struct AABB {
glm::vec2 min;
glm::vec2 max;

float Aspect() const;
float Width() const;
float Height() const;
glm::vec2 Center() const;
};
82 changes: 82 additions & 0 deletions jps-ui/src/gui.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "gui.hpp"
#include "wkt.hpp"

#include <imgui_internal.h>

#include <ImGuiFileDialog.h>
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>

#include <filesystem>
#include <memory>

std::string to_shortcut(const ImGuiKeyChord key)
{
std::array<char, 32> shortcut{};
ImGui::GetKeyChordName(key, shortcut.data(), shortcut.size());
return {shortcut.data()};
}

void Gui::Draw()
{
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();

should_recenter = false;

if(ImGui::BeginMainMenuBar()) {
if(ImGui::BeginMenu("Menu")) {
static const auto open_shortcut = to_shortcut(ImGuiMod_Shortcut | ImGuiKey_O);
if(ImGui::MenuItem("Open", open_shortcut.c_str())) {
ImGuiFileDialog::Instance()->OpenDialog(
"ChooseFileDlgKey",
"Choose File",
".wkt",
".",
1,
nullptr,
ImGuiFileDialogFlags_Modal);
}
if(ImGui::MenuItem("Center View", "C")) {
should_recenter = true;
}
ImGui::Separator();
static const auto exit_shortcut = to_shortcut(ImGuiMod_Shortcut | ImGuiKey_O);
if(ImGui::MenuItem("Exit", exit_shortcut.c_str())) {
should_exit = true;
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}

if(ImGui::IsKeyChordPressed(ImGuiMod_Shortcut | ImGuiKey_O)) {
ImGuiFileDialog::Instance()->OpenDialog(
"ChooseFileDlgKey", "Choose File", ".wkt", ".", 1, nullptr, ImGuiFileDialogFlags_Modal);
}

if(ImGui::IsKeyChordPressed(ImGuiKey_C)) {
should_recenter = true;
}

if(ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey")) {
if(ImGuiFileDialog::Instance()->IsOk()) {
std::filesystem::path filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
std::filesystem::path filePath = ImGuiFileDialog::Instance()->GetCurrentPath();

const auto wkt = read_wkt(filePath / filePathName);
if(wkt) {
geo = std::make_unique<DrawableGEOS>(wkt);
should_recenter = true;
}
}
ImGuiFileDialog::Instance()->Close();
}

ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
}
24 changes: 24 additions & 0 deletions jps-ui/src/gui.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

#include "wkt.hpp"

#include <imgui.h>

class Gui
{
private:
std::unique_ptr<DrawableGEOS> geo{nullptr};
bool should_exit = false;
bool should_recenter = false;

public:
Gui() = default;
~Gui() = default;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
void Draw();
bool ShouldExit() const { return should_exit; }
bool RecenterOnGeometry() const { return should_recenter; }
const DrawableGEOS* Geometry() const { return geo.get(); }
};
149 changes: 149 additions & 0 deletions jps-ui/src/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "gui.hpp"
#include "ortho_camera.hpp"
#include "shader.hpp"
#include "wkt.hpp"

#include <GLFW/glfw3.h>
#include <OpenGL/OpenGL.h>
#include <geos_c.h>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/vec3.hpp>
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>

#include <cstdarg>
#include <cstdio>
#include <iostream>
#include <limits>
#include <vector>

using vec3 = glm::dvec3;

static void geos_msg_handler(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}

static void glfw_error_callback(int error, const char* description)
{
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
}

struct Mesh {
std::vector<vec3> vertices{};
std::vector<GLint> indices{};
};

struct ApplicationState {
};

const std::string vertex_shader_code = R"(
#version 330 core
layout (location = 0) in vec2 inPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(inPos.x, inPos.y, 0.0, 1.0);
}
)";

const std::string fragment_shader_code = R"(
#version 330 core
uniform vec4 color;
out vec4 outColor;
void main()
{
outColor = color;
}
)";

int main(int argc, char** argv)
{
glfwSetErrorCallback(glfw_error_callback);
initGEOS(geos_msg_handler, geos_msg_handler);
GLFWwindow* window;

/* Initialize the library */
if(!glfwInit())
return -1;

/* Create a windowed mode window and its OpenGL context */
const char* glsl_version = "#version 150";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
window = glfwCreateWindow(640, 480, "Mesh Viewer", NULL, NULL);

if(!window) {
glfwTerminate();
return 1;
}

/* Make the window's context current */
glfwMakeContextCurrent(window);
glfwSwapInterval(1);

IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
(void) io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;

ImGui::StyleColorsDark();
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glsl_version);

OrthoCamera cam{};
Shader shader(vertex_shader_code, fragment_shader_code);
shader.Activate();

shader.SetUniform("model", glm::mat4x4(1.0f));

Gui gui{};

/* Loop until the user closes the window */
while(!glfwWindowShouldClose(window)) {
/* Poll for and process events */
glfwPollEvents();
GLint display_w, display_h;
glfwGetFramebufferSize(window, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(
gui.clear_color.x * gui.clear_color.w,
gui.clear_color.y * gui.clear_color.w,
gui.clear_color.z * gui.clear_color.w,
gui.clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
if(gui.RecenterOnGeometry() && gui.Geometry() != nullptr) {
cam.CenterOn(gui.Geometry()->Bounds());
}
cam.Update(shader);
if(gui.Geometry()) {
gui.Geometry()->Draw(shader);
}
gui.Draw();

if(gui.ShouldExit()) {
glfwSetWindowShouldClose(window, gui.ShouldExit());
}

glfwSwapBuffers(window);
}

ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
48 changes: 48 additions & 0 deletions jps-ui/src/ortho_camera.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright © 2024 Forschungszentrum Jülich GmbH
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "ortho_camera.hpp"

#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/vec2.hpp>

#include <iostream>

OrthoCamera::OrthoCamera()
{
}

void OrthoCamera::CenterOn(AABB bounds)
{
const float padding = 1.05; // Pad view by 5% on most constraint axis
const float bounds_aspect = bounds.Aspect();
if(bounds_aspect < aspect) {
frustrum_half_width = bounds.Height() * padding / 2.0f * aspect;
} else {
frustrum_half_width = bounds.Width() * padding / 2.0f;
}

const glm::vec2 cp = bounds.Center();
eye = {cp, 0.0f};
center = {cp, -1.0f};
dirty = true;
}

void OrthoCamera::ChangeViewport(float width, float height)
{
aspect = width / height;
dirty = true;
}

void OrthoCamera::Update(Shader& shader)
{
if(dirty) {
view = glm::lookAt(eye, center, up);
const float frustrum_half_height = frustrum_half_width * (1 / aspect);
projection = glm::ortho(
-frustrum_half_width, frustrum_half_width, -frustrum_half_height, frustrum_half_height);
dirty = false;
}
shader.SetUniform("view", view);
shader.SetUniform("projection", projection);
}
Loading

0 comments on commit ae8bbca

Please sign in to comment.