Files
Prism/Sandbox/Sandbox/Layer/TestLayer.cpp

259 lines
11 KiB
C++

//
// Created by sfd on 25-11-23.
//
#include "TestLayer.h"
#include <memory>
#include "imgui.h"
#include "glm/gtc/type_ptr.hpp"
#include "Prism/Renderer/Renderer.h"
#include "Prism/Renderer/Shader.h"
static void EnableDockSpace(const bool enable)
{
if (enable)
{
static bool p_open = true;
static bool opt_fullscreen = true;
static bool opt_padding = false;
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
// We are using the ImGuiWindowFlags_NoDocking flag to make the parent window not dockable into,
// because it would be confusing to have two docking targets within each others.
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
if (opt_fullscreen)
{
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->WorkPos);
ImGui::SetNextWindowSize(viewport->WorkSize);
ImGui::SetNextWindowViewport(viewport->ID);
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove;
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
}
else
{
dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
}
// When using ImGuiDockNodeFlags_PassthruCentralNode, DockSpace() will render our background
// and handle the pass-thru hole, so we ask Begin() to not render a background.
if (dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode)
window_flags |= ImGuiWindowFlags_NoBackground;
// Important: note that we proceed even if Begin() returns false (aka window is collapsed).
// This is because we want to keep our DockSpace() active. If a DockSpace() is inactive,
// all active windows docked into it will lose their parent and become undocked.
// We cannot preserve the docking relationship between an active window and an inactive docking, otherwise
// any change of dockspace/settings would lead to windows being stuck in limbo and never being visible.
if (!opt_padding)
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("DockSpace Demo", &p_open, window_flags);
if (!opt_padding)
ImGui::PopStyleVar();
if (opt_fullscreen)
ImGui::PopStyleVar(2);
// Submit the DockSpace
// REMINDER: THIS IS A DEMO FOR ADVANCED USAGE OF DockSpace()!
// MOST REGULAR APPLICATIONS WILL SIMPLY WANT TO CALL DockSpaceOverViewport(). READ COMMENTS ABOVE.
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
{
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
}
// Show demo options and help
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Options"))
{
// Disabling fullscreen would allow the window to be moved to the front of other windows,
// which we can't undo at the moment without finer window depth/z control.
ImGui::MenuItem("Fullscreen", NULL, &opt_fullscreen);
ImGui::MenuItem("Padding", NULL, &opt_padding);
ImGui::Separator();
if (ImGui::MenuItem("Flag: NoDockingOverCentralNode", "",
(dockspace_flags & ImGuiDockNodeFlags_NoDockingOverCentralNode) != 0))
{
dockspace_flags ^= ImGuiDockNodeFlags_NoDockingOverCentralNode;
}
if (ImGui::MenuItem("Flag: NoDockingSplit", "",
(dockspace_flags & ImGuiDockNodeFlags_NoDockingSplit) != 0))
{
dockspace_flags ^= ImGuiDockNodeFlags_NoDockingSplit;
}
if (ImGui::MenuItem("Flag: NoUndocking", "", (dockspace_flags & ImGuiDockNodeFlags_NoUndocking) != 0))
{
dockspace_flags ^= ImGuiDockNodeFlags_NoUndocking;
}
if (ImGui::MenuItem("Flag: NoResize", "", (dockspace_flags & ImGuiDockNodeFlags_NoResize) != 0))
{
dockspace_flags ^= ImGuiDockNodeFlags_NoResize;
}
if (ImGui::MenuItem("Flag: AutoHideTabBar", "",
(dockspace_flags & ImGuiDockNodeFlags_AutoHideTabBar) != 0))
{
dockspace_flags ^= ImGuiDockNodeFlags_AutoHideTabBar;
}
if (ImGui::MenuItem("Flag: PassthruCentralNode", "",
(dockspace_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0, opt_fullscreen))
{
dockspace_flags ^= ImGuiDockNodeFlags_PassthruCentralNode;
}
ImGui::Separator();
if (ImGui::MenuItem("Close", NULL, false, p_open != false))
p_open = false;
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help"))
{
ImGui::TextUnformatted(
"This demo has nothing to do with enabling docking!" "\n"
"This demo only demonstrate the use of ImGui::DockSpace() which allows you to manually\ncreate a docking node _within_ another window."
"\n"
"Most application can simply call ImGui::DockSpaceOverViewport() and be done with it.");
ImGui::Separator();
ImGui::TextUnformatted(
"When docking is enabled, you can ALWAYS dock MOST window into another! Try it now!" "\n"
"- Drag from window title bar or their tab to dock/undock." "\n"
"- Drag from window menu button (upper-left button) to undock an entire node (all windows)." "\n"
"- Hold SHIFT to disable docking (if io.ConfigDockingWithShift == false, default)" "\n"
"- Hold SHIFT to enable docking (if io.ConfigDockingWithShift == true)");
ImGui::Separator();
ImGui::TextUnformatted("More details:");
ImGui::Bullet();
ImGui::SameLine();
ImGui::TextLinkOpenURL("Docking Wiki page", "https://github.com/ocornut/imgui/wiki/Docking");
ImGui::BulletText("Read comments in ShowExampleAppDockSpace()");
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
ImGui::End();
}
}
TestLayer::TestLayer()
:m_Camera(glm::perspectiveFov(glm::radians(45.0f), 1280.0f, 720.0f, 0.1f, 1000.0f))
{
}
void TestLayer::OnAttach()
{
m_FrameBuffer.reset(Prism::FrameBuffer::Create(1280, 720, Prism::FramebufferFormat::RGBA16F));
m_FinalPresentBuffer.reset(Prism::FrameBuffer::Create(1280, 720, Prism::FramebufferFormat::RGBA8));
static float QuadVertex[] = {
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
static unsigned int QuadIndices[] = {
0, 1, 2, 2, 3, 0
};
m_VertexBuffer = std::unique_ptr<Prism::VertexBuffer>(Prism::VertexBuffer::Create());
m_VertexBuffer->SetData(QuadVertex, sizeof(QuadVertex));
m_IndexBuffer = std::unique_ptr<Prism::IndexBuffer>(Prism::IndexBuffer::Create());
m_IndexBuffer->SetData(QuadIndices, sizeof(QuadIndices));
m_SkyBoxTextureCube.reset(Prism::TextureCube::Create("assets/textures/environments/Arches_E_PineTree_Radiance.tga"));
m_SkyboxShader = Prism::Shader::Create("assets/shaders/quad.glsl");
m_Shader = Prism::Shader::Create("assets/shaders/demo.glsl");
m_HDRShader = Prism::Shader::Create("assets/shaders/hdr.glsl");
m_Mesh = std::make_unique<Prism::Mesh>("assets/meshes/cerberus.fbx");
}
void TestLayer::OnDetach()
{
}
void TestLayer::OnUpdate(Prism::TimeStep deltaTime)
{
m_Camera.Update(deltaTime);
auto viewProjection = m_Camera.GetProjectionMatrix() * m_Camera.GetViewMatrix();
m_FrameBuffer->Bind();
Prism::Renderer::Clear(m_clearColor[0], m_clearColor[1], m_clearColor[2], m_clearColor[3]);
Prism::UniformBufferDeclaration<sizeof(glm::mat4), 1> skyboxShaderUB;
skyboxShaderUB.Push("u_InverseVP", inverse(viewProjection));
m_SkyboxShader->UploadUniformBuffer(skyboxShaderUB);
m_SkyboxShader->Bind();
m_SkyBoxTextureCube->Bind(0);
m_VertexBuffer->Bind();
m_IndexBuffer->Bind();
Prism::Renderer::DrawIndexed(m_IndexBuffer->GetCount(), false);
Prism::UniformBufferDeclaration<sizeof(glm::vec4) + sizeof(glm::mat4), 2> uniformbuffer;
uniformbuffer.Push("u_Color", m_TriangleColor);
uniformbuffer.Push("u_MVP", viewProjection);
m_Shader->UploadUniformBuffer(uniformbuffer);
m_Shader->Bind();
// m_Mesh->Render(deltaTime, m_Shader);
// m_VertexBuffer->Bind();
// m_IndexBuffer->Bind();
// m_Mesh->Render();
// Prism::Renderer::DrawIndexed(3, false);
m_FrameBuffer->Unbind();
// HDR
m_FinalPresentBuffer->Bind();
m_HDRShader->Bind();
m_HDRShader->SetFloat("u_Exposure", m_Exposure);
m_FrameBuffer->BindTexture();
m_VertexBuffer->Bind();
m_IndexBuffer->Bind();
Prism::Renderer::DrawIndexed(m_IndexBuffer->GetCount(), false);
m_FinalPresentBuffer->Unbind();
}
void TestLayer::OnImGuiRender()
{
EnableDockSpace(true);
ImGui::Begin("Settings");
ImGui::ColorEdit4("ClearColor", glm::value_ptr(m_clearColor));
ImGui::ColorEdit4("TriangleClearColor", glm::value_ptr(m_TriangleColor));
ImGui::DragFloat("Exposure", &m_Exposure, 0.01f, 0.0f);
const auto& position = m_Camera.GetPosition();
ImGui::Text("Camera: (%.2f, %.2f, %.2f)", position.x, position.y, position.z);
ImGui::End();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
ImGui::Begin("Viewport");
auto viewportSize = ImGui::GetContentRegionAvail();
m_FrameBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_FinalPresentBuffer->Resize((uint32_t)viewportSize.x, (uint32_t)viewportSize.y);
m_Camera.SetProjectionMatrix(glm::perspectiveFov(glm::radians(45.0f), viewportSize.x, viewportSize.y, 0.1f, 10000.0f));
ImGui::Image((ImTextureRef)m_FinalPresentBuffer->GetColorAttachmentRendererID(), viewportSize, {0, 1}, {1, 0});
ImGui::End();
ImGui::PopStyleVar();
}
void TestLayer::OnEvent(Prism::Event& e)
{
}