Changed Picking colors from vec2 to ivec2. Picking now working for multiple scenes (Solution not perfect in the editor, yet)

This commit is contained in:
viktorljung
2016-01-14 15:26:06 +01:00
parent e7f02f14a0
commit 96371a08c8
14 changed files with 133 additions and 34 deletions
+2
View File
@@ -25,6 +25,7 @@ public:
private: private:
IRenderer* m_Renderer; IRenderer* m_Renderer;
World* m_World = nullptr; World* m_World = nullptr;
Camera* m_Camera = nullptr;
bool m_Enabled; bool m_Enabled;
bool m_Visible; bool m_Visible;
@@ -56,6 +57,7 @@ private:
EntityID m_WidgetOrigin = EntityID_Invalid; EntityID m_WidgetOrigin = EntityID_Invalid;
glm::vec3 m_WidgetCurrentAxis; glm::vec3 m_WidgetCurrentAxis;
float m_WidgetPickingDepth = 0.f; float m_WidgetPickingDepth = 0.f;
glm::vec3 m_WidgetPickingPosition = glm::vec3(0);
EntityID m_Selection = EntityID_Invalid; EntityID m_Selection = EntityID_Invalid;
EntityID m_LastSelection = EntityID_Invalid; EntityID m_LastSelection = EntityID_Invalid;
+4
View File
@@ -27,7 +27,11 @@ public:
void SetOrientation(glm::quat val); void SetOrientation(glm::quat val);
glm::mat4 ProjectionMatrix() const { return m_ProjectionMatrix; } glm::mat4 ProjectionMatrix() const { return m_ProjectionMatrix; }
void SetProjectionMatrix(glm::mat4 val);
glm::mat4 ViewMatrix() const { return m_ViewMatrix; } glm::mat4 ViewMatrix() const { return m_ViewMatrix; }
void SetViewMatrix(glm::mat4 val);
float AspectRatio() const { return m_AspectRatio; } float AspectRatio() const { return m_AspectRatio; }
void SetAspectRatio(float val); void SetAspectRatio(float val);
+1
View File
@@ -15,6 +15,7 @@ struct PickData
EntityID Entity; EntityID Entity;
glm::vec3 Position; //World position glm::vec3 Position; //World position
float Depth; float Depth;
::Camera* Camera;
}; };
class IRenderer class IRenderer
+4 -1
View File
@@ -11,10 +11,11 @@
#include "RenderJob.h" #include "RenderJob.h"
#include "../Core/ResourceManager.h" #include "../Core/ResourceManager.h"
#include "Camera.h" #include "Camera.h"
#include "../Core/World.h"
struct ModelJob : RenderJob struct ModelJob : RenderJob
{ {
ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::Model::MaterialGroup texGroup, ComponentWrapper modelComponent) ModelJob(Model* model, Camera* camera, glm::mat4 matrix, ::Model::MaterialGroup texGroup, ComponentWrapper modelComponent, World* world)
: RenderJob() : RenderJob()
{ {
Model = model; Model = model;
@@ -27,6 +28,7 @@ struct ModelJob : RenderJob
Matrix = matrix; Matrix = matrix;
Color = modelComponent["Color"]; Color = modelComponent["Color"];
Entity = modelComponent.EntityID; Entity = modelComponent.EntityID;
World = world;
}; };
unsigned int TextureID; unsigned int TextureID;
@@ -42,6 +44,7 @@ struct ModelJob : RenderJob
const ::Model* Model = nullptr; const ::Model* Model = nullptr;
unsigned int StartIndex = 0; unsigned int StartIndex = 0;
unsigned int EndIndex = 0; unsigned int EndIndex = 0;
const World* World;
void CalculateHash() override void CalculateHash() override
{ {
+15 -5
View File
@@ -5,10 +5,9 @@
#include "PickingPassState.h" #include "PickingPassState.h"
#include "FrameBuffer.h" #include "FrameBuffer.h"
#include "ShaderProgram.h" #include "ShaderProgram.h"
#include "Util/UnorderedMapVec2.h" #include "Util/UnorderedMapiVec2.h"
#include "../Core/EventBroker.h" #include "../Core/EventBroker.h"
#include "../Core/World.h"
class PickingPass class PickingPass
{ {
@@ -20,11 +19,12 @@ public:
void InitializeShaderPrograms(); void InitializeShaderPrograms();
void Draw(RenderScene& scene); void Draw(RenderScene& scene);
void ClearPicking();
//Getters //Getters
const ShaderProgram& PickingProgram() const { return *m_PickingProgram; } const ShaderProgram& PickingProgram() const { return *m_PickingProgram; }
const std::unordered_map<glm::vec2, EntityID>& PickingColorsToEntity() const { return m_PickingColorsToEntity; } //const std::unordered_map<glm::ivec2, EntityID>& PickingColorsToEntity() const { return m_PickingColorsToEntity; }
GLuint PickingTexture() const { return m_PickingTexture; } GLuint PickingTexture() const { return m_PickingTexture; }
GLuint DepthBuffer() const { return m_DepthBuffer; } GLuint DepthBuffer() const { return m_DepthBuffer; }
const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; } const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; }
@@ -42,12 +42,22 @@ private:
ShaderProgram* m_PickingProgram; ShaderProgram* m_PickingProgram;
Camera* m_Camera; Camera* m_Camera;
std::unordered_map<glm::vec2, EntityID> m_PickingColorsToEntity; struct PickingInfo
{
EntityID Entity;
const ::World* World;
::Camera* Camera;
};
std::unordered_map<glm::ivec2, PickingInfo> m_PickingColorsToEntity;
GLuint m_PickingTexture; GLuint m_PickingTexture;
GLuint m_DepthBuffer; GLuint m_DepthBuffer;
FrameBuffer m_PickingBuffer; FrameBuffer m_PickingBuffer;
int m_ColorCounter[2];
std::map<std::tuple<EntityID, const World*, Camera*>, glm::ivec2> m_EntityColors;
}; };
#endif #endif
@@ -0,0 +1,24 @@
#pragma once
#ifndef UnorderedMapiVec2_h__
#define UnorderedMapiVec2_h__
#include <functional>
#include <boost/functional/hash.hpp>
#include <glm/vec2.hpp>
template<>
struct std::hash<glm::ivec2>
{
inline std::size_t operator()(const glm::ivec2 &v) const
{
return boost::hash<float>()(v.x) ^ boost::hash<float>()(v.y);
}
inline bool operator()(const glm::ivec2& a, const glm::ivec2& b)const
{
return a.x == b.x && a.y == b.y;
}
};
#endif
+5 -4
View File
@@ -127,7 +127,7 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e)
auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
glm::vec3 widgetOrientation = widgetTransform["Orientation"]; glm::vec3 widgetOrientation = widgetTransform["Orientation"];
glm::quat totalOrientation = m_Renderer->Camera()->Orientation() * glm::inverse(glm::quat(widgetOrientation)); glm::quat totalOrientation = m_Camera->Orientation() * glm::inverse(glm::quat(widgetOrientation));
int width; int width;
int height; int height;
@@ -139,14 +139,14 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e)
delta2, delta2,
m_WidgetPickingDepth, m_WidgetPickingDepth,
res, res,
m_Renderer->Camera()->ProjectionMatrix(), m_Camera->ProjectionMatrix(),
glm::toMat4(glm::inverse(totalOrientation)) glm::toMat4(glm::inverse(totalOrientation))
); );
glm::vec3 origin = ScreenCoords::ToWorldPos( glm::vec3 origin = ScreenCoords::ToWorldPos(
glm::vec2(res.Width / 2.f, res.Height / 2.f), glm::vec2(res.Width / 2.f, res.Height / 2.f),
m_WidgetPickingDepth, m_WidgetPickingDepth,
res, res,
m_Renderer->Camera()->ProjectionMatrix(), m_Camera->ProjectionMatrix(),
glm::toMat4(glm::inverse(totalOrientation)) glm::toMat4(glm::inverse(totalOrientation))
); );
deltaWorld = deltaWorld - origin; deltaWorld = deltaWorld - origin;
@@ -252,7 +252,7 @@ void EditorSystem::Picking()
(entity == m_WidgetZ) || (entity == m_WidgetOrigin) || (entity == m_WidgetPlaneX || entity == m_WidgetPlaneY) (entity == m_WidgetZ) || (entity == m_WidgetOrigin) || (entity == m_WidgetPlaneX || entity == m_WidgetPlaneY)
); );
m_WidgetPickingDepth = result.Depth; m_WidgetPickingDepth = result.Depth;
m_Camera = result.Camera;
//auto widgetTransform = m_World->GetComponent(m_Widget, "Transform"); //auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
//auto selectionTransform = m_World->GetComponent(m_Selection, "Transform"); //auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
//widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"]; //widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"];
@@ -263,6 +263,7 @@ void EditorSystem::Picking()
} }
setWidgetMode(m_WidgetMode); setWidgetMode(m_WidgetMode);
m_Selection = entity; m_Selection = entity;
m_Camera = result.Camera;
} }
} }
} }
+12
View File
@@ -50,6 +50,18 @@ void Camera::SetOrientation(glm::quat val)
UpdateViewMatrix(); UpdateViewMatrix();
} }
void Camera::SetProjectionMatrix(glm::mat4 val)
{
m_ProjectionMatrix = val;
}
void Camera::SetViewMatrix(glm::mat4 val)
{
m_ViewMatrix = val;
}
//void Camera::Pitch(float val) //void Camera::Pitch(float val)
//{ //{
// m_Pitch = val; // m_Pitch = val;
+1 -1
View File
@@ -28,7 +28,7 @@ void DrawScenePass::Draw(RenderScene& scene)
//glBindFramebuffer(GL_FRAMEBUFFER, 0); //glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLERROR("Renderer::Draw PickingPass"); GLERROR("Renderer::Draw PickingPass");
DrawScenePassState state; DrawScenePassState state = DrawScenePassState();
for (auto &job : scene.ForwardJobs) { for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job); auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
+2 -2
View File
@@ -10,8 +10,8 @@ DrawScenePassState::DrawScenePassState()
Enable(GL_CULL_FACE); Enable(GL_CULL_FACE);
Enable(GL_BLEND); Enable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f)); // ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f));
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
DrawScenePassState::~DrawScenePassState() DrawScenePassState::~DrawScenePassState()
+38 -16
View File
@@ -45,17 +45,15 @@ void PickingPass::InitializeShaderPrograms()
void PickingPass::Draw(RenderScene& scene) void PickingPass::Draw(RenderScene& scene)
{ {
m_PickingColorsToEntity.clear();
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
int r = 0;
int g = 0;
//TODO: Render: Add code for more jobs than modeljobs. //TODO: Render: Add code for more jobs than modeljobs.
GLuint ShaderHandle = m_PickingProgram->GetHandle(); GLuint ShaderHandle = m_PickingProgram->GetHandle();
m_PickingProgram->Bind(); m_PickingProgram->Bind();
std::map<EntityID, glm::vec2> entityColors;
m_Camera = scene.Camera; m_Camera = scene.Camera;
@@ -63,22 +61,28 @@ void PickingPass::Draw(RenderScene& scene)
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job); auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if (modelJob) { if (modelJob) {
int pickColor[2] = { r, g }; int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] };
auto color = entityColors.find(modelJob->Entity);
if (color != entityColors.end()) { PickingInfo pickInfo;
pickInfo.Entity = modelJob->Entity;
pickInfo.World = modelJob->World;
pickInfo.Camera = scene.Camera;
auto color = m_EntityColors.find(std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera));
if (color != m_EntityColors.end()) {
pickColor[0] = color->second[0]; pickColor[0] = color->second[0];
pickColor[1] = color->second[1]; pickColor[1] = color->second[1];
} else { } else {
entityColors[modelJob->Entity] = glm::vec2(pickColor[0], pickColor[1]); m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]);
if (r + 10 > 255) { if (m_ColorCounter[0] > 255) {
r = 0; m_ColorCounter[0] = 0;
g += 1; m_ColorCounter[1]++;;
} else { } else {
r += 1; m_ColorCounter[0]++;;
} }
} }
m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity;
m_PickingColorsToEntity[glm::ivec2(pickColor[0], pickColor[1])] = pickInfo;
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix()));
@@ -101,6 +105,19 @@ void PickingPass::Draw(RenderScene& scene)
void PickingPass::ClearPicking()
{
m_PickingColorsToEntity.clear();
m_EntityColors.clear();
m_ColorCounter[0] = 0;
m_ColorCounter[1] = 0;
m_PickingBuffer.Bind();
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_PickingBuffer.Unbind();
}
PickData PickingPass::Pick(glm::vec2 screenCoord) PickData PickingPass::Pick(glm::vec2 screenCoord)
{ {
int fbWidth; int fbWidth;
@@ -114,14 +131,19 @@ PickData PickingPass::Pick(glm::vec2 screenCoord)
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, &m_PickingBuffer, m_DepthBuffer); ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, &m_PickingBuffer, m_DepthBuffer);
pickData.Depth = data.Depth; pickData.Depth = data.Depth;
auto it = m_PickingColorsToEntity.find(glm::vec2(data.Color[0], data.Color[1])); PickingInfo pickInfo;
auto it = m_PickingColorsToEntity.find(glm::ivec2(data.Color[0], data.Color[1]));
if (it != m_PickingColorsToEntity.end()) { if (it != m_PickingColorsToEntity.end()) {
pickData.Entity = it->second; pickInfo = it->second;
} else { } else {
pickData.Entity = EntityID_Invalid; pickData.Entity = EntityID_Invalid;
} }
pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, resolution, m_Camera->ProjectionMatrix(), m_Camera->ViewMatrix()); pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, resolution, pickInfo.Camera->ProjectionMatrix(), pickInfo.Camera->ViewMatrix());
pickData.Entity = pickInfo.Entity;
pickData.Camera = pickInfo.Camera;
return pickData; return pickData;
} }
+2 -2
View File
@@ -10,8 +10,8 @@ PickingPassState::PickingPassState(GLuint frameBuffer)
Enable(GL_CULL_FACE); Enable(GL_CULL_FACE);
glm::vec4 clearColor = glm::vec4(0.f); glm::vec4 clearColor = glm::vec4(0.f);
ClearColor(clearColor); //ClearColor(clearColor);
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
PickingPassState::~PickingPassState() PickingPassState::~PickingPassState()
+18 -2
View File
@@ -93,7 +93,7 @@ void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World
glm::mat4 modelMatrix = Transform::ModelMatrix(modelComponent.EntityID, world); glm::mat4 modelMatrix = Transform::ModelMatrix(modelComponent.EntityID, world);
for (auto texGroup : model->TextureGroups) { for (auto texGroup : model->TextureGroups) {
std::shared_ptr<ModelJob> modelJob = std::shared_ptr<ModelJob>(new ModelJob(model, m_Camera, modelMatrix, texGroup, modelComponent)); std::shared_ptr<ModelJob> modelJob = std::shared_ptr<ModelJob>(new ModelJob(model, m_Camera, modelMatrix, texGroup, modelComponent, world));
jobs.push_back(modelJob); jobs.push_back(modelJob);
} }
} }
@@ -118,11 +118,25 @@ void RenderSystem::Update(World* world, double dt)
//Only supports opaque geometry atm //Only supports opaque geometry atm
m_RenderFrame->Clear(); m_RenderFrame->Clear();
RenderScene rs; RenderScene rs;
rs.Camera = m_Camera; rs.Camera = m_Camera;
rs.Viewport = Rectangle(1280, 720); rs.Viewport = Rectangle(1280, 720);
fillModels(rs.ForwardJobs, world); fillModels(rs.ForwardJobs, world);
m_RenderFrame->Add(rs); m_RenderFrame->Add(rs);
RenderScene rs2;
rs2.Camera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f);;
rs2.Camera->SetProjectionMatrix(glm::mat4(1));
rs2.Camera->SetViewMatrix(glm::mat4(1));
rs2.Viewport = Rectangle(1280, 720);
fillModels(rs2.ForwardJobs, world);
m_RenderFrame->Add(rs2);
} }
void RenderSystem::updateCamera(World* world, double dt) void RenderSystem::updateCamera(World* world, double dt)
@@ -167,7 +181,7 @@ void RenderSystem::updateCamera(World* world, double dt)
m_Camera->SetOrientation(orientation); m_Camera->SetOrientation(orientation);
updateProjectionMatrix(cameraComponent); updateProjectionMatrix(cameraComponent);
m_Camera->UpdateViewMatrix();
} }
} else { } else {
m_Camera = m_DefaultCamera; m_Camera = m_DefaultCamera;
@@ -186,5 +200,7 @@ void RenderSystem::updateCamera(World* world, double dt)
} }
} }
} }
m_Camera->UpdateViewMatrix();
} }
+5 -1
View File
@@ -91,11 +91,15 @@ void Renderer::Update(double dt)
void Renderer::Draw(RenderFrame& frame) void Renderer::Draw(RenderFrame& frame)
{ {
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_PickingPass->ClearPicking();
for (auto scene : frame.RenderScenes){ for (auto scene : frame.RenderScenes){
m_Camera = scene->Camera; // remove renderer camera when Editor uses the render scene cameras. m_Camera = scene->Camera; // remove renderer camera when Editor uses the render scene cameras.
m_PickingPass->Draw(*scene); m_PickingPass->Draw(*scene);
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f);
m_DrawScenePass->Draw(*scene); m_DrawScenePass->Draw(*scene);
GLERROR("Renderer::Draw m_DrawScenePass->Draw"); GLERROR("Renderer::Draw m_DrawScenePass->Draw");