Merge remote-tracking branch 'origin/master' into Forward+

# Conflicts:
#	include/Engine/Rendering/PickingPass.h
#	include/Engine/Rendering/Renderer.h
#	resources/Schema/Entities/Test.xml
#	src/Engine/Rendering/DrawScenePass.cpp
#	src/Engine/Rendering/PickingPass.cpp
#	src/Engine/Rendering/RenderQueueFactory.cpp
#	src/Engine/Rendering/Renderer.cpp
This commit is contained in:
Tleety
2016-01-15 11:01:58 +01:00
61 changed files with 1240 additions and 945 deletions
+12 -9
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;
@@ -64,15 +76,6 @@ void Camera::SetOrientation(glm::quat val)
void Camera::UpdateProjectionMatrix()
{
// m_ProjectionMatrix = glm::ortho(
// -16.f,
// 16.f,
// -9.f,
// 9.f,
// m_NearClip,
// m_FarClip
// );
m_ProjectionMatrix = glm::perspective(m_FOV, m_AspectRatio, m_NearClip, m_FarClip);
}
+3 -3
View File
@@ -22,7 +22,7 @@ void DrawFinalPass::InitializeShaderPrograms()
m_ForwardPlusProgram->Link();
}
void DrawFinalPass::Draw(RenderQueueCollection& rq)
void DrawFinalPass::Draw(RenderScene& scene)
{
GLERROR("DrawFinalPass::Draw: Pre");
@@ -38,11 +38,11 @@ void DrawFinalPass::Draw(RenderQueueCollection& rq)
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix()));
//TODO: Render: Add code for more jobs than modeljobs.
for (auto &job : rq.Forward) {
for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if(modelJob) {
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix));
glUniform4fv(glGetUniformLocation(shaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
if(modelJob->DiffuseTexture != nullptr) {
+8 -15
View File
@@ -22,25 +22,23 @@ void DrawScenePass::InitializeShaderPrograms()
m_BasicForwardProgram->Link();
}
void DrawScenePass::Draw(RenderQueueCollection& rq)
void DrawScenePass::Draw(RenderScene& scene)
{
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLERROR("DrawScenePass::Draw: Pre");
DrawScenePassState state;
DrawScenePassState state = DrawScenePassState();
m_BasicForwardProgram->Bind();
//TODO: Render: Add code for more jobs than modeljobs.
for (auto &job : rq.Forward) {
for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if (modelJob) {
GLuint ShaderHandle = m_BasicForwardProgram->GetHandle();
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix()));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix()));
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, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform4fv(glGetUniformLocation(ShaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
//TODO: Renderer: bättre textur felhantering samt fler texturer stöd
@@ -56,14 +54,9 @@ void DrawScenePass::Draw(RenderQueueCollection& rq)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
continue;
//continue;
}
auto spriteJob = std::dynamic_pointer_cast<SpriteJob>(job);
if(spriteJob)
{
//Hello im a sprite, please draw me.
}
}
GLERROR("DrawScenePass::Draw: End");
}
+4 -2
View File
@@ -8,8 +8,10 @@ DrawScenePassState::DrawScenePassState()
GLERROR("---");
Enable(GL_DEPTH_TEST);
Enable(GL_CULL_FACE);
ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f));
Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
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);
}
DrawScenePassState::~DrawScenePassState()
+1 -8
View File
@@ -39,17 +39,10 @@ void DummyRenderer::Initialize()
exit(EXIT_FAILURE);
}
// Create default camera
m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(45.f), 0.01f, 5000.f);
m_DefaultCamera->SetPosition(glm::vec3(0, 0, 0));
if (m_Camera == nullptr) {
m_Camera = m_DefaultCamera;
}
glfwSwapInterval(m_VSYNC);
}
void DummyRenderer::Draw(RenderQueueCollection& rq)
void DummyRenderer::Draw(RenderFrame& rq)
{
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
+11 -7
View File
@@ -5,7 +5,7 @@ LightCullingPass::LightCullingPass(IRenderer* renderer)
m_Renderer = renderer;
InitializeSSBOs();
InitializeShaderPrograms();
GenerateNewFrustum();
//GenerateNewFrustum(TODO);
}
LightCullingPass::~LightCullingPass()
@@ -13,21 +13,24 @@ LightCullingPass::~LightCullingPass()
}
void LightCullingPass::GenerateNewFrustum()
void LightCullingPass::GenerateNewFrustum(RenderScene& scene)
{
if (scene.PointLightJobs.size() == 0)
return;
GLERROR("CalculateFrustum Error: Pre");
m_CalculateFrustumProgram->Bind();
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix()));
glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Renderer->Resolution().Width, m_Renderer->Resolution().Height);
glDispatchCompute(5, 3, 1); //TODO: Renderer: This needs change so resolution will be right.
GLERROR("CalculateFrustum Error: End");
}
void LightCullingPass::CullLights()
void LightCullingPass::CullLights(RenderScene& scene)
{
GLERROR("CullLights Error: Pre");
m_LightOffset = 0;
@@ -45,7 +48,7 @@ void LightCullingPass::CullLights()
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
m_LightCullProgram->Bind();
glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(m_Renderer->Camera()->ViewMatrix()));
glUniformMatrix4fv(glGetUniformLocation(m_LightCullProgram->GetHandle(), "V"), 1, false, glm::value_ptr(scene.Camera->ViewMatrix()));
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO);
@@ -56,10 +59,11 @@ void LightCullingPass::CullLights()
GLERROR("CullLights Error: End");
}
void LightCullingPass::FillLightList(RenderQueueCollection& rq)
void LightCullingPass::FillLightList(RenderScene& scene)
{
m_PointLights.clear();
for(auto &job : rq.Lights) {
for(auto &job : scene.PointLightJobs) {
auto pointLightjob = std::dynamic_pointer_cast<PointLightJob>(job);
if (pointLightjob) {
PointLight p;
+81 -42
View File
@@ -43,70 +43,109 @@ void PickingPass::InitializeShaderPrograms()
m_PickingProgram->Link();
}
void PickingPass::Draw(RenderQueueCollection& rq)
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;
for (auto &job : rq.Forward) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
m_Camera = scene.Camera;
if (modelJob) {
int pickColor[2] = { r, g };
auto color = entityColors.find(modelJob->Entity);
if (color != entityColors.end()) {
pickColor[0] = color->second[0];
pickColor[1] = color->second[1];
} else {
entityColors[modelJob->Entity] = glm::vec2(pickColor[0], pickColor[1]);
if (r + 1 > 255) {
r = 0;
g += 1;
for (auto &job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
if (modelJob) {
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 {
r += 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 {
m_ColorCounter[0]++;;
}
}
}
m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity;
//Render picking stuff
//TODO: Kolla upp "header/include/common" shader saken så man slipper skicka in asmycket uniforms
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix()));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex);
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()));
glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix()));
glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1])));
glBindVertexArray(modelJob->Model->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, nullptr, modelJob->StartIndex);
}
}
}
m_PickingBuffer.Unbind();
GLERROR("PickingPass Error");
//Publish pick event every frame with the pick data that can be picked by the event
delete state;
}
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;
int fbHeight;
glfwGetFramebufferSize(m_Renderer->Window(), &fbWidth, &fbHeight);
Events::Picking pickEvent = Events::Picking(
&m_PickingBuffer,
&m_DepthBuffer,
m_Renderer->Camera()->ProjectionMatrix(),
m_Renderer->Camera()->ViewMatrix(),
Rectangle(fbWidth, fbHeight),
&m_PickingColorsToEntity);
m_EventBroker->Publish(pickEvent);
Rectangle resolution = Rectangle(fbWidth, fbHeight);
PickData pickData;
// Invert screen y coordinate
screenCoord.y = resolution.Height - screenCoord.y;
ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, &m_PickingBuffer, m_DepthBuffer);
pickData.Depth = data.Depth;
delete state;
PickingInfo pickInfo;
auto it = m_PickingColorsToEntity.find(glm::ivec2(data.Color[0], data.Color[1]));
if (it != m_PickingColorsToEntity.end()) {
pickInfo = it->second;
} else {
pickData.Entity = EntityID_Invalid;
}
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;
pickData.World = pickInfo.World;
return pickData;
}
void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const
+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()
+4
View File
@@ -81,6 +81,9 @@ RawModel::RawModel(std::string fileName)
float opacity;
material->Get(AI_MATKEY_OPACITY, opacity);
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity);
desc.DiffuseVertexColor = glm::vec4(diffuse.r, diffuse.g, diffuse.b, opacity);
// Material specular color
aiColor3D specular;
material->Get(AI_MATKEY_COLOR_SPECULAR, specular);
@@ -134,6 +137,7 @@ RawModel::RawModel(std::string fileName)
matGroup.EndIndex = m_Indices.size() - 1;
// Material shininess
material->Get(AI_MATKEY_SHININESS, matGroup.Shininess);
material->Get(AI_MATKEY_OPACITY, matGroup.Transparency);
//LOG_DEBUG("Shininess: %f", matGroup.Shininess);
// Diffuse texture
//LOG_DEBUG("%i diffuse textures found", material->GetTextureCount(aiTextureType_DIFFUSE));
-150
View File
@@ -1,150 +0,0 @@
#include "Rendering/RenderQueueFactory.h"
RenderQueueFactory::RenderQueueFactory()
{
m_RenderQueues = RenderQueueCollection();
}
void RenderQueueFactory::Update(World* world)
{
m_RenderQueues.Clear();
FillModels(world, &m_RenderQueues.Forward);
FillLights(world, &m_RenderQueues.Lights);
}
glm::mat4 RenderQueueFactory::ModelMatrix(World* world, EntityID entity)
{
glm::vec3 position = AbsolutePosition(world, entity);
glm::quat orientation = AbsoluteOrientation(world, entity);
glm::vec3 scale = AbsoluteScale(world, entity);
glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(orientation) * glm::scale(scale);
return modelMatrix;
}
glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity)
{
glm::vec3 position;
while (entity != EntityID_Invalid) {
ComponentWrapper transform = world->GetComponent(entity, "Transform");
EntityID parent = world->GetParent(entity);
//if (parent != EntityID_Invalid) {
position += AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"];
//} else {
// position += (glm::vec3)transform["Position"];
//}
entity = parent;
}
return position;
}
glm::quat RenderQueueFactory::AbsoluteOrientation(World* world, EntityID entity)
{
glm::quat orientation;
while (entity != EntityID_Invalid) {
ComponentWrapper transform = world->GetComponent(entity, "Transform");
orientation = glm::quat((glm::vec3)transform["Orientation"]) * orientation;
entity = world->GetParent(entity);
}
return orientation;
}
glm::vec3 RenderQueueFactory::AbsoluteScale(World* world, EntityID entity)
{
glm::vec3 scale(1.f);
while (entity != EntityID_Invalid) {
ComponentWrapper transform = world->GetComponent(entity, "Transform");
scale *= (glm::vec3)transform["Scale"];
entity = world->GetParent(entity);
}
return scale;
}
void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue)
{
auto models = world->GetComponents("Model");
if (models == nullptr) {
return;
}
for (auto& modelC : *models) {
bool visible = modelC["Visible"];
if (!visible) {
continue;
}
std::string resource = modelC["Resource"];
if (resource.empty()) {
continue;
}
glm::vec4 color = modelC["Color"];
Model* model = ResourceManager::Load<Model>(resource);
if (model == nullptr) {
model = ResourceManager::Load<Model>("Models/Core/Error.obj");
}
auto transformC = world->GetComponent(modelC.EntityID, "Transform");
if(&transformC == nullptr)
{
return;
}
for (auto texGroup : model->TextureGroups) {
ModelJob job;
job.TextureID = (texGroup.Texture) ? texGroup.Texture->ResourceID : 0;
job.DiffuseTexture = texGroup.Texture.get();
job.NormalTexture = texGroup.NormalMap.get();
job.SpecularTexture = texGroup.SpecularMap.get();
job.Model = model;
job.StartIndex = texGroup.StartIndex;
job.EndIndex = texGroup.EndIndex;
job.ModelMatrix = model->m_Matrix * ModelMatrix(world, modelC.EntityID);
job.Color = color;
//TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this
job.Entity = modelC.EntityID;
renderQueue->Add(job);
}
}
}
void RenderQueueFactory::FillLights(World* world, RenderQueue* renderQueue)
{
auto pointLights = world->GetComponents("PointLight");
if(pointLights == nullptr) {
return;
}
for(auto& pointlightC : *pointLights) {
bool visible = pointlightC["Visible"];
if(!visible) {
continue;
}
auto transformC = world->GetComponent(pointlightC.EntityID, "Transform");
if(&transformC == nullptr) {
return;
}
glm::vec4 color = pointlightC["Color"];
float radius = (double)pointlightC["Radius"];
float intensity = (double)pointlightC["Intensity"];
float falloff = (double)pointlightC["Falloff"];
PointLightJob job;
job.Position = glm::vec4(AbsolutePosition(world, transformC.EntityID), 1.f);
job.Color = color;
job.Radius = radius;
job.Intensity = intensity;
job.Falloff = falloff;
renderQueue->Add(job);
}
}
+218
View File
@@ -0,0 +1,218 @@
#include "Rendering/RenderSystem.h"
#include "Rendering/DebugCameraInputController.h"
RenderSystem::RenderSystem(EventBroker* eventBrokerer, const IRenderer* renderer, RenderFrame* renderFrame) :ImpureSystem(eventBrokerer)
{
m_Renderer = renderer;
m_RenderFrame = renderFrame;
EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &RenderSystem::OnSetCamera);
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &RenderSystem::OnInputCommand);
m_DefaultCamera = new Camera((float)m_Renderer->Resolution().Width / m_Renderer->Resolution().Height, glm::radians(45.f), 0.01f, 5000.f);
m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10));
if (m_Camera == nullptr) {
m_Camera = m_DefaultCamera;
}
}
bool RenderSystem::OnSetCamera(const Events::SetCamera &event)
{
auto cameras = m_World->GetComponents("Camera");
if (cameras != nullptr) {
for (auto it = cameras->begin(); it != cameras->end(); it++) {
if ((std::string)(*it)["Name"] == event.Name) {
switchCamera((*it).EntityID);
}
}
}
return true;
}
void RenderSystem::switchCamera(EntityID entity)
{
if(m_World->HasComponent(entity, "Camera")) {
if (m_CurrentCamera != EntityID_Invalid) {
if (m_World->HasComponent(m_CurrentCamera, "Model")) {
m_World->GetComponent(m_CurrentCamera, "Model")["Visible"] = true;
}
}
if (m_World->HasComponent(entity, "Model")) {
m_World->GetComponent(entity, "Model")["Visible"] = false;
}
m_CurrentCamera = entity;
m_SwitchCamera = false;
} else {
LOG_ERROR("Entity %i does not have a CameraComponent", entity);
m_SwitchCamera = false;
}
}
void RenderSystem::updateProjectionMatrix(ComponentWrapper& cameraComponent)
{
double fov = cameraComponent["FOV"];
double aspectRatio = m_Renderer->Resolution().Width / m_Renderer->Resolution().Height;
double nearClip = cameraComponent["NearClip"];
double farClip = cameraComponent["FarClip"];
double fovY = atan(tan(glm::radians(fov)/2.0) * aspectRatio) * 2.0;
m_ProjectionMatrix = glm::perspective(fovY, aspectRatio, nearClip, farClip);
m_Camera->SetFOV(fovY);
m_Camera->SetAspectRatio(aspectRatio);
m_Camera->SetNearClip(nearClip);
m_Camera->SetFarClip(farClip);
m_Camera->UpdateProjectionMatrix();
}
void RenderSystem::fillModels(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
{
auto models = world->GetComponents("Model");
if (models == nullptr) {
return;
}
for (auto& modelComponent : *models) {
bool visible = modelComponent["Visible"];
if (!visible) {
continue;
}
std::string resource = modelComponent["Resource"];
if (resource.empty()) {
continue;
}
Model* model = ResourceManager::Load<::Model>(resource);
if (model == nullptr) {
model = ResourceManager::Load<::Model>("Models/Core/Error.obj");
}
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, world));
jobs.push_back(modelJob);
}
}
}
void RenderSystem::fillLight(std::list<std::shared_ptr<RenderJob>>& jobs, World* world)
{
auto pointLights = world->GetComponents("PointLight");
if (pointLights == nullptr) {
return;
}
for (auto& pointlightC : *pointLights) {
bool visible = pointlightC["Visible"];
if (!visible) {
continue;
}
auto transformC = world->GetComponent(pointlightC.EntityID, "Transform");
if (&transformC == nullptr) {
return;
}
std::shared_ptr<PointLightJob> pointLightJob = std::shared_ptr<PointLightJob>(new PointLightJob(transformC, pointlightC));
jobs.push_back(pointLightJob);
}
}
bool RenderSystem::OnInputCommand(const Events::InputCommand& e)
{
if (e.Command == "SwitchCamera" && e.Value > 0) {
m_SwitchCamera = true;
return true;
} else {
return false;
}
}
void RenderSystem::Update(World* world, double dt)
{
m_World = world;
m_EventBroker->Process<RenderSystem>();
updateCamera(world, dt);
//Only supports opaque geometry atm
m_RenderFrame->Clear();
RenderScene scene;
scene.Camera = m_Camera;
scene.Viewport = Rectangle(1280, 720);
fillModels(scene.ForwardJobs, world);
fillLight(scene.PointLightJobs, world);
m_RenderFrame->Add(scene);
}
void RenderSystem::updateCamera(World* world, double dt)
{
static DebugCameraInputController<RenderSystem> firstPersonInputController(m_EventBroker, -1);
if (m_SwitchCamera) {
auto cameras = world->GetComponents("Camera");
for (auto it = cameras->begin(); it != cameras->end(); it++) {
if ((*it).EntityID == m_CurrentCamera) {
it++;
if (it != cameras->end()) {
switchCamera((*it).EntityID);
} else {
switchCamera((*cameras->begin()).EntityID);
}
break;
}
}
ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera");
ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform");
firstPersonInputController.SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"]));
firstPersonInputController.SetPosition(cameraTransform["Position"]);
}
if (m_World->ValidEntity(m_CurrentCamera)) {
if (world->HasComponent(m_CurrentCamera, "Camera") && world->HasComponent(m_CurrentCamera, "Transform")) {
ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera");
ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform");
firstPersonInputController.Update(dt);
(glm::vec3&)cameraTransform["Orientation"] = glm::eulerAngles(firstPersonInputController.Orientation());
(glm::vec3&)cameraTransform["Position"] = firstPersonInputController.Position();
glm::vec3 position = Transform::AbsolutePosition(world, m_CurrentCamera);
glm::quat orientation = Transform::AbsoluteOrientation(world, m_CurrentCamera);
m_Camera->SetPosition(position);
m_Camera->SetOrientation(orientation);
updateProjectionMatrix(cameraComponent);
}
} else {
m_Camera = m_DefaultCamera;
auto cameras = world->GetComponents("Camera");
if (cameras != nullptr) {
if (cameras->begin() != cameras->end()) {
ComponentWrapper& cameraC = *cameras->begin();
switchCamera(cameraC.EntityID);
ComponentWrapper& cameraComponent = world->GetComponent(m_CurrentCamera, "Camera");
ComponentWrapper& cameraTransform = world->GetComponent(m_CurrentCamera, "Transform");
firstPersonInputController.SetOrientation(glm::quat((glm::vec3)cameraTransform["Orientation"]));
firstPersonInputController.SetPosition(cameraTransform["Position"]);
}
}
}
m_Camera->UpdateViewMatrix();
}
+47 -26
View File
@@ -3,13 +3,7 @@
void Renderer::Initialize()
{
InitializeWindow();
// Create default camera
m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(90.0f), 0.01f, 5000.f);
m_DefaultCamera->SetPosition(glm::vec3(0, 1, 10));
if (m_Camera == nullptr) {
m_Camera = m_DefaultCamera;
}
m_DebugCameraInputController = std::make_shared<DebugCameraInputController<Renderer>>(m_EventBroker, -1);
InitializeRenderPasses();
glfwSwapInterval(m_VSYNC);
@@ -21,6 +15,15 @@ void Renderer::Initialize()
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");
m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker);
// Create default camera
m_DefaultCamera = new ::Camera((float)m_Resolution.Width / m_Resolution.Height, glm::radians(45.f), 0.01f, 5000.f);
m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10));
if (m_Camera == nullptr) {
m_Camera = m_DefaultCamera;
}
}
void Renderer::InitializeWindow()
@@ -76,9 +79,7 @@ void Renderer::InitializeShaders()
void Renderer::InputUpdate(double dt)
{
m_DebugCameraInputController->Update(dt);
m_Camera->SetOrientation(m_DebugCameraInputController->Orientation());
m_Camera->SetPosition(m_DebugCameraInputController->Position());
}
void Renderer::Update(double dt)
@@ -88,22 +89,37 @@ void Renderer::Update(double dt)
m_ImGuiRenderPass->Update(dt);
}
void Renderer::Draw(RenderQueueCollection& rq)
void Renderer::Draw(RenderFrame& frame)
{
FillDepth(rq);
m_PickingPass->Draw(rq);
//DrawScreenQuad(m_PickingPass->PickingTexture());
m_LightCullingPass->FillLightList(rq);
m_LightCullingPass->CullLights();
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f);
//m_DrawScenePass->Draw(rq);
m_DrawFinalPass->Draw(rq);
glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f);
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
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.
FillDepth(*scene);
m_PickingPass->Draw(*scene);
m_LightCullingPass->GenerateNewFrustum(*scene);
m_LightCullingPass->FillLightList(*scene);
m_LightCullingPass->CullLights(*scene);
m_DrawFinalPass->Draw(*scene);
//m_DrawScenePass->Draw(rq);
GLERROR("Renderer::Draw m_DrawScenePass->Draw");
}
m_ImGuiRenderPass->Draw();
glfwSwapBuffers(m_Window);
}
PickData Renderer::Pick(glm::vec2 screenCoord)
{
return m_PickingPass->Pick(screenCoord);
}
void Renderer::DrawScreenQuad(GLuint textureToDraw)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -152,13 +168,18 @@ void Renderer::InitializeRenderPasses()
}
//Temp func
void Renderer::FillDepth(RenderQueueCollection& rq)
void Renderer::FillDepth(RenderScene& scene)
{
for(auto job : rq.Forward) {
for (auto job : scene.ForwardJobs) {
auto modelJob = std::dynamic_pointer_cast<ModelJob>(job);
glm::vec3 abspos = RenderQueueFactory::AbsolutePosition(m_World, modelJob->Entity);
glm::vec3 worldpos = glm::vec3(m_Camera->ViewMatrix() * glm::vec4(abspos, 1));
if(! modelJob) {
return;
}
glm::vec3 abspos = Transform::AbsolutePosition(modelJob->World, modelJob->Entity);
glm::vec3 worldpos = glm::vec3(scene.Camera->ViewMatrix() * glm::vec4(abspos, 1));
modelJob->Depth = worldpos.z;
}
rq.Forward.Jobs.sort(Renderer::DepthSort);
}
scene.ForwardJobs.sort(Renderer::DepthSort);
}