diff --git a/Editor/resources/Shaders/gbuffer.shader b/Editor/resources/Shaders/gbuffer.shader index c08d14cf..9d7aa722 100644 --- a/Editor/resources/Shaders/gbuffer.shader +++ b/Editor/resources/Shaders/gbuffer.shader @@ -40,6 +40,7 @@ void main() layout(location = 0) out vec4 gAlbedo; layout(location = 1) out vec4 gNormal; layout(location = 2) out vec4 gMaterial; +layout(location = 3) out int gEntityID; in vec3 FragPos; in vec2 UV; @@ -52,6 +53,7 @@ uniform sampler2D m_Roughness; uniform sampler2D m_AO; uniform sampler2D m_Normal; uniform sampler2D m_Displacement; +uniform int u_EntityID; layout(std140, binding = 32) uniform u_MaterialUniform { @@ -102,4 +104,6 @@ void main() gMaterial.r = finalMetalness; gMaterial.g = finalAO; gMaterial.b = finalRoughness; + + gEntityID = int(u_EntityID); } \ No newline at end of file diff --git a/Editor/src/Windows/EditorInterface.cpp b/Editor/src/Windows/EditorInterface.cpp index 5eb4614a..37edf0c6 100644 --- a/Editor/src/Windows/EditorInterface.cpp +++ b/Editor/src/Windows/EditorInterface.cpp @@ -231,11 +231,33 @@ namespace Nuake { tc.SetGlobalTransform(transform); } } + + if (m_IsHoveringViewport && Input::IsMouseButtonPressed(GLFW_MOUSE_BUTTON_1) && !ImGuizmo::IsUsing()) + { + const auto windowPosNuake = Vector2(windowPos.x, windowPos.y); + auto& gbuffer = Engine::GetCurrentScene()->mSceneRenderer->GetGBuffer(); + auto pixelPos = Input::GetMousePosition() - windowPosNuake; + pixelPos.y = gbuffer.GetSize().y - pixelPos.y; // imgui coords are inverted on the Y axis + + gbuffer.Bind(); + + if (const int result = gbuffer.ReadPixel(3, pixelPos); result > 0) + { + Selection = EditorSelection(Entity{ (entt::entity)(result - 1), Engine::GetCurrentScene().get()}); + } + else + { + Selection = EditorSelection(); // None + } + + gbuffer.Unbind(); + } } else { ImGui::PopStyleVar(); } + ImGui::End(); } diff --git a/Nuake/src/Rendering/Buffers/Framebuffer.cpp b/Nuake/src/Rendering/Buffers/Framebuffer.cpp index 1b6f5b1b..0c559944 100644 --- a/Nuake/src/Rendering/Buffers/Framebuffer.cpp +++ b/Nuake/src/Rendering/Buffers/Framebuffer.cpp @@ -126,6 +126,14 @@ namespace Nuake glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); } + int FrameBuffer::ReadPixel(uint32_t attachment, const Vector2 coords) + { + glReadBuffer(GL_COLOR_ATTACHMENT0 + attachment); + int pixelData; + glReadPixels((int)coords.x, (int)coords.y, 1, 1, GL_RED_INTEGER, GL_INT, &pixelData); + return pixelData; + } + void FrameBuffer::SetDrawBuffer(GLenum draw) { Bind(); diff --git a/Nuake/src/Rendering/Buffers/Framebuffer.h b/Nuake/src/Rendering/Buffers/Framebuffer.h index ead1fe22..b2eb76a8 100644 --- a/Nuake/src/Rendering/Buffers/Framebuffer.h +++ b/Nuake/src/Rendering/Buffers/Framebuffer.h @@ -38,6 +38,8 @@ namespace Nuake void SetSize(const Vector2& size) { m_Size = size; } void UpdateSize(Vector2 size); + + int ReadPixel(uint32_t attachment, const Vector2 coords); void SetDrawBuffer(GLenum draw); void SetReadBuffer(GLenum read); }; diff --git a/Nuake/src/Rendering/RenderList.h b/Nuake/src/Rendering/RenderList.h index 62747b00..e2f7e7e3 100644 --- a/Nuake/src/Rendering/RenderList.h +++ b/Nuake/src/Rendering/RenderList.h @@ -12,6 +12,7 @@ namespace Nuake { Ref Mesh; Matrix4 transform; + int32_t entityId; }; class RenderList @@ -22,14 +23,14 @@ namespace Nuake this->m_RenderList = std::map, std::vector>(); } - void AddToRenderList(Ref mesh, Matrix4 transform) + void AddToRenderList(Ref mesh, Matrix4 transform, const int32_t entityId = -1) { Ref material = mesh->GetMaterial(); if (m_RenderList.find(material) == m_RenderList.end()) m_RenderList[material] = std::vector(); - m_RenderList[material].push_back({mesh, transform}); + m_RenderList[material].push_back({mesh, transform, entityId}); } void Flush(Shader* shader, bool depthOnly = false) @@ -43,6 +44,7 @@ namespace Nuake for (auto& m : i.second) { shader->SetUniformMat4f("u_Model", m.transform); + shader->SetUniform1i("u_EntityID", m.entityId + 1); m.Mesh->Draw(shader, false); } } diff --git a/Nuake/src/Rendering/Renderer.cpp b/Nuake/src/Rendering/Renderer.cpp index b316d193..bcd2d449 100644 --- a/Nuake/src/Rendering/Renderer.cpp +++ b/Nuake/src/Rendering/Renderer.cpp @@ -108,14 +108,14 @@ namespace Nuake { } - void Renderer::SubmitMesh(Ref mesh, Matrix4 transform) + void Renderer::SubmitMesh(Ref mesh, Matrix4 transform, const int32_t entityId) { - m_RenderList.AddToRenderList(mesh, transform); + m_RenderList.AddToRenderList(mesh, transform, entityId); } void Renderer::SubmitCube(Matrix4 transform) { - m_RenderList.AddToRenderList(CubeMesh, transform); + m_RenderList.AddToRenderList(CubeMesh, transform, -1); } void Renderer::Flush(Shader* shader, bool depthOnly) diff --git a/Nuake/src/Rendering/Renderer.h b/Nuake/src/Rendering/Renderer.h index 54b89185..0b5de6ae 100644 --- a/Nuake/src/Rendering/Renderer.h +++ b/Nuake/src/Rendering/Renderer.h @@ -60,7 +60,7 @@ namespace Nuake static void LoadShaders(); static void BeginScene(); - static void SubmitMesh(Ref mesh, Matrix4 transform); + static void SubmitMesh(Ref mesh, Matrix4 transform, const int32_t entityId = -1); static void SubmitCube(Matrix4 transform); static void Flush(Shader* shader, bool depthOnly = false); diff --git a/Nuake/src/Rendering/SceneRenderer.cpp b/Nuake/src/Rendering/SceneRenderer.cpp index 14f4ad78..44bf3960 100644 --- a/Nuake/src/Rendering/SceneRenderer.cpp +++ b/Nuake/src/Rendering/SceneRenderer.cpp @@ -13,7 +13,7 @@ namespace Nuake { mGBuffer->SetTexture(CreateRef(defaultResolution, GL_RGB), GL_COLOR_ATTACHMENT0); mGBuffer->SetTexture(CreateRef(defaultResolution, GL_RGB), GL_COLOR_ATTACHMENT1); mGBuffer->SetTexture(CreateRef(defaultResolution, GL_RGB), GL_COLOR_ATTACHMENT2); - mGBuffer->SetTexture(CreateRef(defaultResolution, GL_RGB), GL_COLOR_ATTACHMENT3); + mGBuffer->SetTexture(CreateRef(defaultResolution, GL_RED_INTEGER, GL_R32I, GL_INT), GL_COLOR_ATTACHMENT3); mShadingBuffer = CreateScope(true, defaultResolution); mShadingBuffer->SetTexture(CreateRef(defaultResolution, GL_RGB, GL_RGB16F, GL_FLOAT)); @@ -223,7 +223,9 @@ namespace Nuake { if (mesh.ModelResource && visibility.Visible) { for (auto& m : mesh.ModelResource->GetMeshes()) - Renderer::SubmitMesh(m, transform.GetGlobalTransform()); + { + Renderer::SubmitMesh(m, transform.GetGlobalTransform(), (uint32_t)e); + } } } @@ -240,7 +242,9 @@ namespace Nuake { continue; for (auto& b : model.Meshes) - Renderer::SubmitMesh(b, transform.GetGlobalTransform()); + { + Renderer::SubmitMesh(b, transform.GetGlobalTransform(), (uint32_t)e); + } } Renderer::Flush(gBufferShader, false); } diff --git a/Nuake/src/Rendering/SceneRenderer.h b/Nuake/src/Rendering/SceneRenderer.h index 36bf4216..fa8adf1a 100644 --- a/Nuake/src/Rendering/SceneRenderer.h +++ b/Nuake/src/Rendering/SceneRenderer.h @@ -18,6 +18,12 @@ namespace Nuake { void RenderScene(Scene& scene, FrameBuffer& framebuffer); Scope mSSR; + + FrameBuffer& GetGBuffer() const + { + return *mGBuffer; + } + private: Matrix4 mProjection, mView; Vector3 mCamPos;