Skip to content

Commit

Permalink
feat: add immediate mode GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
painfulexistence committed Dec 5, 2024
1 parent 446e606 commit 2b983be
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 45 deletions.
172 changes: 134 additions & 38 deletions AtmosphericEngine/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ void Application::LoadScene(SceneDef& scene)
script.Print("Materials created.");

for (const auto& go : scene.gameObjects) {
auto entity = CreateGameObject();
auto entity = CreateGameObject(go.position, go.rotation, go.scale);
entity->SetName(go.name);
if (go.camera.has_value()) {
entity->AddCamera(go.camera.value());
}
Expand Down Expand Up @@ -160,47 +161,142 @@ void Application::Render(const FrameData& props)

_window->BeginImGuiFrame();

ImGui::Begin("System Information");
{
ImGui::Text("OpenGL version: %s", glGetString(GL_VERSION));
ImGui::Text("GLSL version: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
ImGui::Text("Vendor: %s", glGetString(GL_VENDOR));
ImGui::Text("Renderer: %s", glGetString(GL_RENDERER));

GLint depth, stencil;
glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth);
glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil);
ImGui::Text("Depth bits: %d", depth);
ImGui::Text("Stencil bits: %d", stencil);

GLint maxVertUniforms, maxFragUniforms;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &maxVertUniforms);
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &maxFragUniforms);
ImGui::Text("Max vertex uniforms: %d bytes", maxVertUniforms / 4);
ImGui::Text("Max fragment uniforms: %d bytes", maxFragUniforms / 4);

GLint maxVertUniBlocks, maxFragUniBlocks;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &maxVertUniBlocks);
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &maxFragUniBlocks);
ImGui::Text("Max vertex uniform blocks: %d", maxVertUniBlocks);
ImGui::Text("Max fragment uniform blocks: %d", maxFragUniBlocks);

GLint maxElementIndices, maxElementVertices;
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxElementIndices);
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxElementVertices);
ImGui::Text("Max element indices: %d", maxElementIndices);
ImGui::Text("Max element vertices: %d", maxElementVertices);
if (ImGui::BeginMainMenuBar()) {
// if (ImGui::BeginMenu("File")) {
// if (ImGui::MenuItem("New Scene")) { }
// if (ImGui::MenuItem("Open Scene")) { }
// if (ImGui::MenuItem("Save Scene")) { }
// ImGui::EndMenu();
// }
if (ImGui::BeginMenu("View")) {
ImGui::MenuItem("System Info", nullptr, &_showSystemInfo);
ImGui::MenuItem("Engine", nullptr, &_showEngineView);
ImGui::MenuItem("Application", nullptr, &_showAppView);
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
ImGui::End();

ImGui::Begin("Engine Subsystems");
{
graphics.DrawImGui(dt);
for (auto subsystem : _subsystems) {
subsystem->DrawImGui(dt);
if (_showSystemInfo) {
ImGui::Begin("System Information");
{
ImGui::Text("OpenGL: %s", glGetString(GL_VERSION));
ImGui::Text("GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
ImGui::Text("Vendor: %s", glGetString(GL_VENDOR));
ImGui::Text("Renderer: %s", glGetString(GL_RENDERER));

GLint depth, stencil;
glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &depth);
glGetFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &stencil);
ImGui::Text("Depth bits: %d", depth);
ImGui::Text("Stencil bits: %d", stencil);

GLint maxVertUniforms, maxFragUniforms;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &maxVertUniforms);
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &maxFragUniforms);
ImGui::Text("Max vertex uniforms: %d bytes", maxVertUniforms / 4);
ImGui::Text("Max fragment uniforms: %d bytes", maxFragUniforms / 4);

GLint maxVertUniBlocks, maxFragUniBlocks;
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &maxVertUniBlocks);
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &maxFragUniBlocks);
ImGui::Text("Max vertex uniform blocks: %d", maxVertUniBlocks);
ImGui::Text("Max fragment uniform blocks: %d", maxFragUniBlocks);

GLint maxElementIndices, maxElementVertices;
glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxElementIndices);
glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxElementVertices);
ImGui::Text("Max element indices: %d", maxElementIndices);
ImGui::Text("Max element vertices: %d", maxElementVertices);
}
ImGui::End();
}

if (_showAppView) {
ImGui::Begin("Application");
{
ImGui::BeginChild("Scene", ImVec2(200, 400), true);
ImGui::Text("Scene (%d entities)", (uint32_t)_entities.size());
ImGui::Separator();
ImGui::BeginGroup();
for (auto& entity : _entities) {
bool selected = entity == _selectedEntity;
if (ImGui::Selectable(entity->GetName().c_str(), selected)) {
_selectedEntity = entity;
}
}
ImGui::EndGroup();
ImGui::EndChild();

ImGui::SameLine();

ImGui::BeginChild("Entity", ImVec2(300, 400), true);
ImGui::Text("Entity");
ImGui::Separator();
if (_selectedEntity) {
ImGui::Text("Name: %s", _selectedEntity->GetName().c_str());
if (ImGui::CollapsingHeader("Transform", ImGuiTreeNodeFlags_DefaultOpen)) {
glm::vec3 pos = _selectedEntity->GetPosition();
glm::vec3 rot = _selectedEntity->GetRotation();
glm::vec3 scale = _selectedEntity->GetScale();
if (ImGui::DragFloat3("Position", &pos.x, 0.1f))
_selectedEntity->SetPosition(pos);
if (ImGui::DragFloat3("Rotation", &rot.x, 1.0f))
_selectedEntity->SetRotation(rot);
if (ImGui::DragFloat3("Scale", &scale.x, 0.1f))
_selectedEntity->SetScale(scale);
}

auto impostor = static_cast<Impostor*>(_selectedEntity->GetComponent("Physics"));
if (impostor != nullptr) {
if (ImGui::CollapsingHeader("Physics", ImGuiTreeNodeFlags_DefaultOpen)) {
glm::vec3 vel = impostor->GetLinearVelocity();
ImGui::Text("Velocity: %.3f, %.3f, %.3f", vel.x, vel.y, vel.z);
}
}
auto light = static_cast<Light*>(_selectedEntity->GetComponent("Light"));
if (light != nullptr) {
if (light->type == LightType::Directional) {
if (ImGui::CollapsingHeader("Light", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::DragFloat3("direction", &light->direction.x);
ImGui::ColorEdit3("diffuse", &light->diffuse.r);
ImGui::ColorEdit3("spcular", &light->specular.r);
ImGui::ColorEdit3("ambient", &light->ambient.r);
ImGui::DragFloat("intensity", &light->intensity);
ImGui::Checkbox("castShadow", &light->castShadow);
}
} else if (light->type == LightType::Point) {
if (ImGui::CollapsingHeader("Light", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::DragFloat3("position", &light->position.x);
ImGui::ColorEdit3("diffuse", &light->diffuse.r);
ImGui::ColorEdit3("spcular", &light->specular.r);
ImGui::ColorEdit3("ambient", &light->ambient.r);
ImGui::DragFloat("intensity", &light->intensity);
ImGui::Checkbox("castShadow", &light->castShadow);
}
}
}
auto camera = static_cast<Camera*>(_selectedEntity->GetComponent("Camera"));
if (camera != nullptr) {
if (ImGui::CollapsingHeader("Camera", ImGuiTreeNodeFlags_DefaultOpen)) {
}
}
}
ImGui::EndChild();
}
ImGui::End();
}

if (_showEngineView) {
ImGui::Begin("Engine Subsystems");
{
graphics.DrawImGui(dt);
for (auto subsystem : _subsystems) {
subsystem->DrawImGui(dt);
}
}
ImGui::End();
}
ImGui::End();

_window->EndImGuiFrame();

Expand Down
6 changes: 6 additions & 0 deletions AtmosphericEngine/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Application
GameObject* GetDefaultGameObject() {
if (!_defaultGameObject) {
_defaultGameObject = CreateGameObject();
_defaultGameObject->SetName("__root__");
}
return _defaultGameObject;
}
Expand Down Expand Up @@ -90,6 +91,11 @@ class Application
std::vector<GameObject*> _entities;
GameObject* _defaultGameObject = nullptr;

bool _showSystemInfo = false;
bool _showAppView = true;
bool _showEngineView = true;
GameObject* _selectedEntity = nullptr;

void Log(std::string message);

void Tick();
Expand Down
45 changes: 41 additions & 4 deletions AtmosphericEngine/graphics_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,48 @@ void GraphicsServer::Render(float dt)
void GraphicsServer::DrawImGui(float dt)
{
if (ImGui::CollapsingHeader("Graphics", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Text("Frame rate: %.3f ms/frame (%.1f FPS)", 1000.0f * dt, 1.0f / dt);
ImGui::Text("Average frame rate: %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::ColorEdit3("Clear color", (float*)&clearColor);
//ImGui::Text("Entities count: %lu", entities.size());
ImGui::Text("Draw time: %.3f s/frame", dt);
ImGui::Text("Frame rate: %.1f FPS", 1.0f / dt);
//ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
if (ImGui::Button("Post-processing")) {
postProcessEnabled = !postProcessEnabled;
}

ImGui::Separator();

if (ImGui::TreeNode("Cameras")) {
for (auto c : cameras) {
ImGui::Text("%s (camera)", c->gameObject->GetName().c_str());
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Lights")) {
for (auto l : directionalLights) {
const std::string& name = l->gameObject->GetName();
if (ImGui::TreeNode(name.c_str(), "%s (light)", name.c_str())) {
ImGui::Text("Direction: %.3f, %.3f, %.3f", l->direction.x, l->direction.y, l->direction.z);
ImGui::Text("Ambient: %.3f, %.3f, %.3f", l->ambient.x, l->ambient.y, l->ambient.z);
ImGui::Text("Diffuse: %.3f, %.3f, %.3f", l->diffuse.x, l->diffuse.y, l->diffuse.z);
ImGui::Text("Specular: %.3f, %.3f, %.3f", l->specular.x, l->specular.y, l->specular.z);
ImGui::Text("Intensity: %.3f", l->intensity);
ImGui::Text("Cast shadow: %s", l->castShadow ? "true" : "false");
ImGui::TreePop();
}
}
for (auto l : pointLights) {
const std::string& name = l->gameObject->GetName();
if (ImGui::TreeNode(name.c_str(), "%s (light)", name.c_str())) {
ImGui::Text("Position: %.3f, %.3f, %.3f", l->position.x, l->position.y, l->position.z);
ImGui::Text("Ambient: %.3f, %.3f, %.3f", l->ambient.x, l->ambient.y, l->ambient.z);
ImGui::Text("Diffuse: %.3f, %.3f, %.3f", l->diffuse.x, l->diffuse.y, l->diffuse.z);
ImGui::Text("Specular: %.3f, %.3f, %.3f", l->specular.x, l->specular.y, l->specular.z);
ImGui::Text("Intensity: %.3f", l->intensity);
ImGui::Text("Cast shadow: %s", l->castShadow ? "true" : "false");
ImGui::TreePop();
}
}
ImGui::TreePop();
}
}
}

Expand Down
15 changes: 12 additions & 3 deletions AtmosphericEngine/script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,21 @@ SceneDef Script::GetScene(const sol::table& sceneData)
sol::table entityData = eVal;
GameObjectProps def = {
.name = eKey.as<std::string>(),
// .position = glm::vec3(entityData["position"][1], entityData["position"][2], entityData["position"][3]),
// .rotation = glm::vec3(entityData["rotation"][1], entityData["rotation"][2], entityData["rotation"][3]),
// .scale = glm::vec3(entityData["scale"][1], entityData["scale"][2], entityData["scale"][3]),
.camera = std::nullopt,
.light = std::nullopt
};
auto pos = entityData.get_or("position", sol::table());
if (pos.valid()) {
def.position = glm::vec3(pos[1], pos[2], pos[3]);
}
auto rot = entityData.get_or("rotation", sol::table());
if (rot.valid()) {
def.rotation = glm::vec3(rot[1], rot[2], rot[3]);
}
auto scale = entityData.get_or("scale", sol::table());
if (scale.valid()) {
def.scale = glm::vec3(scale[1], scale[2], scale[3]);
}
sol::table components = entityData["components"];
for (const auto& [cKey, cVal] : components) {
std::string componentType = cKey.as<std::string>();
Expand Down

0 comments on commit 2b983be

Please sign in to comment.