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:
IRenderer* m_Renderer;
World* m_World = nullptr;
Camera* m_Camera = nullptr;
bool m_Enabled;
bool m_Visible;
@@ -56,6 +57,7 @@ private:
EntityID m_WidgetOrigin = EntityID_Invalid;
glm::vec3 m_WidgetCurrentAxis;
float m_WidgetPickingDepth = 0.f;
glm::vec3 m_WidgetPickingPosition = glm::vec3(0);
EntityID m_Selection = EntityID_Invalid;
EntityID m_LastSelection = EntityID_Invalid;
+4
View File
@@ -27,7 +27,11 @@ public:
void SetOrientation(glm::quat val);
glm::mat4 ProjectionMatrix() const { return m_ProjectionMatrix; }
void SetProjectionMatrix(glm::mat4 val);
glm::mat4 ViewMatrix() const { return m_ViewMatrix; }
void SetViewMatrix(glm::mat4 val);
float AspectRatio() const { return m_AspectRatio; }
void SetAspectRatio(float val);
+1
View File
@@ -15,6 +15,7 @@ struct PickData
EntityID Entity;
glm::vec3 Position; //World position
float Depth;
::Camera* Camera;
};
class IRenderer
+4 -1
View File
@@ -11,10 +11,11 @@
#include "RenderJob.h"
#include "../Core/ResourceManager.h"
#include "Camera.h"
#include "../Core/World.h"
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()
{
Model = model;
@@ -27,6 +28,7 @@ struct ModelJob : RenderJob
Matrix = matrix;
Color = modelComponent["Color"];
Entity = modelComponent.EntityID;
World = world;
};
unsigned int TextureID;
@@ -42,6 +44,7 @@ struct ModelJob : RenderJob
const ::Model* Model = nullptr;
unsigned int StartIndex = 0;
unsigned int EndIndex = 0;
const World* World;
void CalculateHash() override
{
+15 -5
View File
@@ -5,10 +5,9 @@
#include "PickingPassState.h"
#include "FrameBuffer.h"
#include "ShaderProgram.h"
#include "Util/UnorderedMapVec2.h"
#include "Util/UnorderedMapiVec2.h"
#include "../Core/EventBroker.h"
#include "../Core/World.h"
class PickingPass
{
@@ -20,11 +19,12 @@ public:
void InitializeShaderPrograms();
void Draw(RenderScene& scene);
void ClearPicking();
//Getters
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 DepthBuffer() const { return m_DepthBuffer; }
const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; }
@@ -42,12 +42,22 @@ private:
ShaderProgram* m_PickingProgram;
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_DepthBuffer;
FrameBuffer m_PickingBuffer;
int m_ColorCounter[2];
std::map<std::tuple<EntityID, const World*, Camera*>, glm::ivec2> m_EntityColors;
};
#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");
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 height;
@@ -139,14 +139,14 @@ bool EditorSystem::OnMouseMove(const Events::MouseMove& e)
delta2,
m_WidgetPickingDepth,
res,
m_Renderer->Camera()->ProjectionMatrix(),
m_Camera->ProjectionMatrix(),
glm::toMat4(glm::inverse(totalOrientation))
);
glm::vec3 origin = ScreenCoords::ToWorldPos(
glm::vec2(res.Width / 2.f, res.Height / 2.f),
m_WidgetPickingDepth,
res,
m_Renderer->Camera()->ProjectionMatrix(),
m_Camera->ProjectionMatrix(),
glm::toMat4(glm::inverse(totalOrientation))
);
deltaWorld = deltaWorld - origin;
@@ -252,7 +252,7 @@ void EditorSystem::Picking()
(entity == m_WidgetZ) || (entity == m_WidgetOrigin) || (entity == m_WidgetPlaneX || entity == m_WidgetPlaneY)
);
m_WidgetPickingDepth = result.Depth;
m_Camera = result.Camera;
//auto widgetTransform = m_World->GetComponent(m_Widget, "Transform");
//auto selectionTransform = m_World->GetComponent(m_Selection, "Transform");
//widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"];
@@ -263,6 +263,7 @@ void EditorSystem::Picking()
}
setWidgetMode(m_WidgetMode);
m_Selection = entity;
m_Camera = result.Camera;
}
}
}
+12
View File
@@ -50,6 +50,18 @@ void Camera::SetOrientation(glm::quat val)
UpdateViewMatrix();
}
void Camera::SetProjectionMatrix(glm::mat4 val)
{
m_ProjectionMatrix = val;
}
void Camera::SetViewMatrix(glm::mat4 val)
{
m_ViewMatrix = val;
}
//void Camera::Pitch(float val)
//{
// m_Pitch = val;
+1 -1
View File
@@ -28,7 +28,7 @@ void DrawScenePass::Draw(RenderScene& scene)
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLERROR("Renderer::Draw PickingPass");
DrawScenePassState state;
DrawScenePassState state = DrawScenePassState();
for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
+2 -2
View File
@@ -10,8 +10,8 @@ DrawScenePassState::DrawScenePassState()
Enable(GL_CULL_FACE);
Enable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f));
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f));
// Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
DrawScenePassState::~DrawScenePassState()
+38 -16
View File
@@ -45,17 +45,15 @@ void PickingPass::InitializeShaderPrograms()
void PickingPass::Draw(RenderScene& scene)
{
m_PickingColorsToEntity.clear();
PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle());
int r = 0;
int g = 0;
//TODO: Render: Add code for more jobs than modeljobs.
GLuint ShaderHandle = m_PickingProgram->GetHandle();
m_PickingProgram->Bind();
std::map<EntityID, glm::vec2> entityColors;
m_Camera = scene.Camera;
@@ -63,22 +61,28 @@ void PickingPass::Draw(RenderScene& scene)
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if (modelJob) {
int pickColor[2] = { r, g };
auto color = entityColors.find(modelJob->Entity);
if (color != entityColors.end()) {
int pickColor[2] = { m_ColorCounter[0], m_ColorCounter[1] };
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[1] = color->second[1];
} else {
entityColors[modelJob->Entity] = glm::vec2(pickColor[0], pickColor[1]);
if (r + 10 > 255) {
r = 0;
g += 1;
m_EntityColors[std::make_tuple(pickInfo.Entity, pickInfo.World, pickInfo.Camera)] = glm::ivec2(pickColor[0], pickColor[1]);
if (m_ColorCounter[0] > 255) {
m_ColorCounter[0] = 0;
m_ColorCounter[1]++;;
} 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, "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)
{
int fbWidth;
@@ -114,14 +131,19 @@ PickData PickingPass::Pick(glm::vec2 screenCoord)
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, &m_PickingBuffer, m_DepthBuffer);
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()) {
pickData.Entity = it->second;
pickInfo = it->second;
} else {
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;
}
+2 -2
View File
@@ -10,8 +10,8 @@ PickingPassState::PickingPassState(GLuint frameBuffer)
Enable(GL_CULL_FACE);
glm::vec4 clearColor = glm::vec4(0.f);
ClearColor(clearColor);
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//ClearColor(clearColor);
//Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
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);
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);
}
}
@@ -118,11 +118,25 @@ void RenderSystem::Update(World* world, double dt)
//Only supports opaque geometry atm
m_RenderFrame->Clear();
RenderScene rs;
rs.Camera = m_Camera;
rs.Viewport = Rectangle(1280, 720);
fillModels(rs.ForwardJobs, world);
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)
@@ -167,7 +181,7 @@ void RenderSystem::updateCamera(World* world, double dt)
m_Camera->SetOrientation(orientation);
updateProjectionMatrix(cameraComponent);
m_Camera->UpdateViewMatrix();
}
} else {
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)
{
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){
m_Camera = scene->Camera; // remove renderer camera when Editor uses the render scene cameras.
m_PickingPass->Draw(*scene);
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f);
m_DrawScenePass->Draw(*scene);
GLERROR("Renderer::Draw m_DrawScenePass->Draw");