diff --git a/include/Engine/Rendering/FrameBuffer.h b/include/Engine/Rendering/FrameBuffer.h new file mode 100644 index 00000000..cf63b6c6 --- /dev/null +++ b/include/Engine/Rendering/FrameBuffer.h @@ -0,0 +1,64 @@ +#ifndef FrameBuffer_h__ +#define FrameBuffer_h__ + +#include "../OpenGL.h" +#include "Util/GLError.h" + +class BufferResource +{ +public: + BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment); + + GLuint* m_ResourceHandle; + GLenum m_ResourceType; + GLenum m_Attachment; +private: + +}; + +template +class ResourceType : public BufferResource +{ +public: + ResourceType(GLuint* resourceHandle, GLenum attachment) + : BufferResource(resourceHandle, RESOURCETYPE, attachment) { } +}; + +class Texture2D : public ResourceType +{ +public: + Texture2D(GLuint* resourceHandle, GLenum attachment) + : ResourceType(resourceHandle, attachment) { }; + + ~Texture2D(); +}; + +class RenderBuffer : public ResourceType +{ +public: + RenderBuffer(GLuint* resourceHandle, GLenum attachment) + : ResourceType(resourceHandle, attachment) + { }; + + ~RenderBuffer(); +}; + +class FrameBuffer +{ +public: + FrameBuffer() + : m_BufferHandle(0) { } + ~FrameBuffer(); + + void AddResource(std::shared_ptr resource); + void Generate(); + void Bind(); + void Unbind(); + GLuint GetHandle(); + +private: + GLuint m_BufferHandle; + std::vector> m_Resources; +}; + +#endif diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index 1bbeb7f6..982b1813 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -7,6 +7,7 @@ #include "../Common.h" #include "../GLM.h" #include "../Core/Util/Rectangle.h" +#include "../Core/EntityWrapper.h" class Model; class Skeleton; @@ -37,6 +38,9 @@ struct ModelJob : RenderJob unsigned int ShaderID = 0; unsigned int TextureID = 0; + //TODO: RENDERER: Not sure if the best solution for pickingColor to entity link is this + EntityID Entity; + glm::mat4 ModelMatrix; const Texture* DiffuseTexture; const Texture* NormalTexture; @@ -82,30 +86,7 @@ struct PointLightJob : RenderJob glm::vec3 SpecularColor = glm::vec3(1, 1, 1); glm::vec3 DiffuseColor = glm::vec3(1, 1, 1); float Radius = 1.f; - - void CalculateHash() override - { - Hash = 0; - } -}; - -struct FrameJob : SpriteJob -{ - Rectangle Scissor; - Rectangle Viewport; - std::string Name; - - void CalculateHash() override - { - Hash = 0; - } -}; - -struct WaterParticleJob : RenderJob -{ - glm::vec3 Position; - glm::vec4 Color; - glm::mat4 ModelMatrix; + float Intensity = 0.8f; void CalculateHash() override { @@ -154,25 +135,19 @@ private: struct RenderQueueCollection { - RenderQueue Deferred; RenderQueue Forward; RenderQueue Lights; - RenderQueue GUI; void Clear() { - Deferred.Clear(); Forward.Clear(); Lights.Clear(); - GUI.Clear(); } void Sort() { - Deferred.Sort(); Forward.Sort(); Lights.Sort(); - GUI.Sort(); } }; diff --git a/include/Engine/Rendering/RenderQueueFactory.h b/include/Engine/Rendering/RenderQueueFactory.h new file mode 100644 index 00000000..918692ac --- /dev/null +++ b/include/Engine/Rendering/RenderQueueFactory.h @@ -0,0 +1,28 @@ +#ifndef RenderQueueFactory_h__ +#define RenderQueueFactory_h__ + +#include "../Core/World.h" +#include "RenderQueue.h" +#include "../Core/ResourceManager.h" +#include "Model.h" +#include "../GLM.h" + +class RenderQueueFactory +{ +public: + RenderQueueFactory(); + void Update(World* world); + + + RenderQueueCollection RenderQueues() const { return m_RenderQueues; } +private: + RenderQueueCollection m_RenderQueues; + + void FillModels(World* world, RenderQueue* renderQueue); + void FillLights(World* world, RenderQueue* renderQueue); + + glm::mat4 ModelMatrix(World* world, EntityID entity); + glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent); +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 24dcb74b..b1b76468 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -8,6 +8,8 @@ //TODO: Temp resourceManager #include "../Core/ResourceManager.h" #include "Util/UnorderedMapVec2.h" +#include "FrameBuffer.h" +#include "../Core/World.h" class Renderer : public IRenderer { @@ -18,11 +20,10 @@ public: private: //----------------------Variables----------------------// - RenderQueueCollection m_TempRQ; Texture* m_ErrorTexture; Texture* m_WhiteTexture; float m_CameraMoveSpeed; - GLuint m_PickingBuffer; + FrameBuffer m_PickingBuffer; GLuint m_PickingTexture; GLuint m_DepthBuffer; @@ -30,29 +31,23 @@ private: Model* m_UnitQuad; Model* m_UnitSphere; - //Temporary - Model* m; - Model* m2; - Model* m3; - Model* MapModel; - std::unordered_map m_PickingColorsToModels; + std::unordered_map m_PickingColorsToEntity; //----------------------Functions----------------------// void InitializeWindow(); void InitializeShaders(); void InitializeTextures(); void InitializeFrameBuffers(); - //TODO: Renderer: Remove ModelsToDraw from Renderer. - void ModelsToDraw(); - //TODO: Renderer: Get EnqueueModel and InputUpdate out of renderer - void EnqueueModel(Model* model); + //TODO: Renderer: Get InputUpdate out of renderer void InputUpdate(double dt); - void PickingPass(); + void PickingPass(RenderQueueCollection& rq); void DrawScreenQuad(GLuint textureToDraw); void DrawScene(RenderQueueCollection& rq); + + void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); //--------------------ShaderPrograms-------------------// ShaderProgram m_BasicForwardProgram; ShaderProgram m_PickingProgram; diff --git a/include/Engine/Rendering/Util/ScreenCoords.h b/include/Engine/Rendering/Util/ScreenCoords.h index 51ad1051..22c5b9e0 100644 --- a/include/Engine/Rendering/Util/ScreenCoords.h +++ b/include/Engine/Rendering/Util/ScreenCoords.h @@ -5,6 +5,7 @@ #include "../../OpenGL.h" #include "../../GLM.h" #include "../../Core/Util/Rectangle.h" +#include "../FrameBuffer.h" class ScreenCoords { @@ -17,8 +18,8 @@ public: static glm::vec3 ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat); //Return data from the given buffers at the coordinates given in screenspace. Buffer should probably have a texture that covers the screen. //Data is given as R = x, B = y, and - static glm::vec3 ToPixelData(glm::vec2 screenCoord, GLuint PickDataBuffer, GLuint DepthBuffer); - static glm::vec3 ToPixelData(float x, float y, GLuint PickDataBuffer, GLuint DepthBuffer); + static glm::vec3 ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer); + static glm::vec3 ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer); //Return EntityID of the clicked coordinate in given screenspace coordinates. //EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth); diff --git a/include/Game/Game.h b/include/Game/Game.h index 85c0d6c4..cd16a3dd 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -8,6 +8,7 @@ #include "Core/InputManager.h" #include "GUI/Frame.h" #include "Core/World.h" +#include "Rendering/RenderQueueFactory.h" class Game { @@ -26,6 +27,7 @@ private: InputManager* m_InputManager; GUI::Frame* m_FrameStack; World* m_World; + RenderQueueFactory* m_RenderQueueFactory; }; #endif diff --git a/include/Game/HardcodedTestWorld.h b/include/Game/HardcodedTestWorld.h index bf3f2f07..30cf8535 100644 --- a/include/Game/HardcodedTestWorld.h +++ b/include/Game/HardcodedTestWorld.h @@ -20,6 +20,7 @@ private: void registerTestComponents() { ComponentWrapperFactory f; + f = ComponentWrapperFactory("Test"); f.AddProperty("TestInteger", 1337); @@ -74,5 +75,31 @@ private: glm::vec3 scale = transform["Scale"]; std::cout << "Scale: " << scale.x << " " << scale.y << " " << scale.z << std::endl; } + + //Create some test widgets + { + EntityID entityScaleWidget = world.CreateEntity(); + ComponentWrapper transform = world.AttachComponent(entityScaleWidget, "Transform"); + transform["Position"] = glm::vec3(-1.5f, 0.f, 0.f); + ComponentWrapper model = world.AttachComponent(entityScaleWidget, "Model"); + model["Resource"] = "Models/ScaleWidget.obj"; + } + { + EntityID entityRotationWidget = world.CreateEntity(); + ComponentWrapper transform = world.AttachComponent(entityRotationWidget, "Transform"); + transform["Position"] = glm::vec3(1.5f, 0.f, 0.f); + ComponentWrapper model = world.AttachComponent(entityRotationWidget, "Model"); + model["Resource"] = "Models/RotationWidget.obj"; + } + { + EntityID entityDummyScene = world.CreateEntity(); + ComponentWrapper transform = world.AttachComponent(entityDummyScene, "Transform"); + transform["Position"] = glm::vec3(0, 0.f, 0.f); + ComponentWrapper model = world.AttachComponent(entityDummyScene, "Model"); + model["Resource"] = "Models/DummyScene.obj"; + } + + + } }; \ No newline at end of file diff --git a/resources/Shaders/BasicForward.frag.glsl b/resources/Shaders/BasicForward.frag.glsl index a7b7cb1f..274ec8d7 100644 --- a/resources/Shaders/BasicForward.frag.glsl +++ b/resources/Shaders/BasicForward.frag.glsl @@ -3,6 +3,7 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; +uniform vec4 Color; uniform sampler2D texture0; @@ -21,7 +22,7 @@ out vec4 fragmentColor; void main() { vec4 texel = texture2D(texture0, Input.TextureCoordinate); - fragmentColor = texel * Input.DiffuseColor; + fragmentColor = texel * Input.DiffuseColor * Color; } diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp new file mode 100644 index 00000000..1b53d868 --- /dev/null +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -0,0 +1,88 @@ + +#include "Rendering/FrameBuffer.h" + + +BufferResource::BufferResource(GLuint* resourceHandle, GLenum resourceType, GLenum attachment) +{ + m_ResourceHandle = resourceHandle; + m_ResourceType = resourceType; + m_Attachment = attachment; +} + +Texture2D::~Texture2D() +{ + if (m_ResourceHandle != 0) { + glDeleteTextures(1, m_ResourceHandle); + } +} + + +RenderBuffer::~RenderBuffer() +{ + if (m_ResourceHandle != 0) { + glDeleteRenderbuffers(1, m_ResourceHandle); + } +} + + +FrameBuffer::~FrameBuffer() +{ + if (m_BufferHandle != 0) { + glDeleteFramebuffers(1, &m_BufferHandle); + } +} + +void FrameBuffer::AddResource(std::shared_ptr resource) +{ + m_Resources.push_back(resource); +} + +void FrameBuffer::Generate() +{ + std::vector attachments; + + glGenFramebuffers(1, &m_BufferHandle); + glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle); + + for (auto it = m_Resources.begin(); it != m_Resources.end(); it++) { + switch ((*it)->m_ResourceType) { + case GL_TEXTURE_2D: + glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); + break; + case GL_RENDERBUFFER: + glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); + break; + } + + GLERROR("FrameBuffer generate"); + + if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) { + attachments.push_back((*it)->m_Attachment); + } + } + + + + GLenum* bufferTextures = &attachments[0]; + glDrawBuffers(1, bufferTextures); + + if (GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + LOG_ERROR("FrameBuffer incomplete: 0x%x\n", frameBufferStatus); + exit(EXIT_FAILURE); + } +} + +void FrameBuffer::Bind() +{ + glBindFramebuffer(GL_FRAMEBUFFER, m_BufferHandle); +} + +void FrameBuffer::Unbind() +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +GLuint FrameBuffer::GetHandle() +{ + return m_BufferHandle; +} diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/src/Engine/Rendering/RenderQueueFactory.cpp new file mode 100644 index 00000000..9a7d89a1 --- /dev/null +++ b/src/Engine/Rendering/RenderQueueFactory.cpp @@ -0,0 +1,67 @@ +#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) +{ + //should really return absolute model matrix based on parents position, scale and orientation + //GetAbsolutePosition(World* world, ComponentWrapper transformComponent) + + ComponentWrapper transformComponent = world->GetComponent(entity, "Transform"); + glm::vec3 position = transformComponent["Position"]; + glm::vec3 scale = transformComponent["Scale"]; + glm::quat oritentation = transformComponent["Orientation"]; + + glm::mat4 modelMatrix = glm::translate(glm::mat4(), position) * glm::toMat4(oritentation) * glm::scale(scale); + return modelMatrix; +} + +glm::vec3 GetAbsolutePosition(World* world, ComponentWrapper transformComponent) +{ + // positionComponent.EntityID + return glm::vec3(); +} + +void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue) +{ + for(auto& modelC : world->GetComponents("Model")) { + ModelJob job; + std::string resource = modelC["Resource"]; + glm::vec4 color = modelC["Color"]; + Model* model = ResourceManager::Load(resource); + + for (auto texGroup : model->TextureGroups) { + 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) +{ + +} + diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 5a9fcba3..f39580b7 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -15,7 +15,11 @@ void Renderer::Initialize() InitializeShaders(); InitializeTextures(); InitializeFrameBuffers(); - ModelsToDraw(); + + + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); + m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); + m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj"); } void Renderer::InitializeWindow() @@ -78,54 +82,6 @@ void Renderer::InitializeShaders() } -void Renderer::ModelsToDraw() -{ - - m = ResourceManager::Load("Models/ScaleWidget.obj"); - EnqueueModel(m); - m2 = ResourceManager::Load("Models/TranslationWidget.obj"); - EnqueueModel(m2); - m3 = ResourceManager::Load("Models/RotationWidget.obj"); - EnqueueModel(m3); - - m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj"); - EnqueueModel(m_UnitSphere); - m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); - m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); - - MapModel = ResourceManager::Load("Models/DummyScene.obj"); - EnqueueModel(MapModel); -} - -void Renderer::EnqueueModel(Model* model) -{ - 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; - //job.ModelMatrix = modelMatrix * model->m_Matrix; TODO: Render: Make sure modelMatrix work - //job.Color = modelComponent->Color; TODO: Render: Take color from kd in .mtl or a value from modelcomponent. - job.Color = glm::vec4(1.f); - - //TODO: Render: Skeleton animations - //if (model->m_Skeleton != nullptr && animationComponent != nullptr) { - // job.Skeleton = model->m_Skeleton; - // job.AnimationName = animationComponent->Name; - // job.AnimationTime = animationComponent->Time; - // job.NoRootMotion = animationComponent->NoRootMotion; - //} - - m_TempRQ.Forward.Add(job); - } -} - void Renderer::InputUpdate(double dt) { glm::vec3 m_Position = m_Camera->Position(); @@ -161,7 +117,7 @@ void Renderer::InputUpdate(double dt) static double mousePosX, mousePosY; glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); if (glfwGetMouseButton(m_Window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) { - glm::vec3 data = ScreenCoords::ToPixelData(mousePosX, m_Resolution.Height - mousePosY, m_PickingBuffer, m_DepthBuffer); + glm::vec3 data = ScreenCoords::ToPixelData(mousePosX, m_Resolution.Height - mousePosY, &m_PickingBuffer, m_DepthBuffer); glm::vec2 color = glm::vec2(data); float depth = data.z; @@ -172,7 +128,8 @@ void Renderer::InputUpdate(double dt) //printf("view: x: %f, y: %f z: %f, Length: %f\n\n", viewPos.x, viewPos.y, viewPos.z, glm::length(viewPos)); if (color != glm::vec2(0, 0)) { - const Model* pickModel = m_PickingColorsToModels[color]; + EntityID pickedEntity = m_PickingColorsToEntity[color]; + printf("Picked Entity: %i", pickedEntity); } } @@ -202,15 +159,16 @@ void Renderer::InputUpdate(double dt) void Renderer::Update(double dt) { InputUpdate(dt); + } void Renderer::Draw(RenderQueueCollection& rq) { //TODO: Renderer: Kanske borde vara längst upp i update. - PickingPass(); + PickingPass(rq); DrawScreenQuad(m_PickingTexture); - //DrawScreenQuad(m_DepthBuffer); - //DrawScene(rq); + + DrawScene(rq); glfwSwapBuffers(m_Window); } @@ -227,16 +185,17 @@ void Renderer::DrawScene(RenderQueueCollection& rq) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //TODO: Render: Add code for more jobs than modeljobs. - for (auto &job : m_TempRQ.Forward) { + for (auto &job : rq.Forward) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { GLuint ShaderHandle = m_BasicForwardProgram.GetHandle(); m_BasicForwardProgram.Bind(); //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(glm::mat4(1))); + glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix)); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); + glUniform4fv(glGetUniformLocation(ShaderHandle, "Color"), 1, glm::value_ptr(modelJob->Color)); //TODO: Renderer: bättre textur felhantering samt fler texturer stöd if (modelJob->DiffuseTexture != nullptr) { @@ -256,9 +215,9 @@ void Renderer::DrawScene(RenderQueueCollection& rq) } } -void Renderer::PickingPass() +void Renderer::PickingPass(RenderQueueCollection& rq) { - glBindFramebuffer(GL_FRAMEBUFFER, m_PickingBuffer); + m_PickingBuffer.Bind(); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -274,16 +233,17 @@ void Renderer::PickingPass() GLuint ShaderHandle = m_PickingProgram.GetHandle(); m_PickingProgram.Bind(); - for (auto &job : m_TempRQ.Forward) { + for (auto &job : rq.Forward) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { glm::vec2 pickColor = glm::vec2(r/255.f, g/255.f); - m_PickingColorsToModels[pickColor] = modelJob->Model; + m_PickingColorsToEntity[pickColor] = 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(glm::mat4(1))); + glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->ModelMatrix)); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(pickColor)); @@ -298,7 +258,7 @@ void Renderer::PickingPass() } } } - + m_PickingBuffer.Unbind(); } @@ -328,35 +288,42 @@ void Renderer::InitializeTextures() { m_ErrorTexture=ResourceManager::Load("Textures/Core/ErrorTexture.png"); m_WhiteTexture=ResourceManager::Load("Textures/Core/Blank.png"); - + /* glGenTextures(1, &m_PickingTexture); glBindTexture(GL_TEXTURE_2D, m_PickingTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGB, GL_FLOAT, NULL);//TODO: Renderer: Fix the precision and Resolution + glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, m_Resolution.Width, m_Resolution.Height, 0, GL_RG, GL_FLOAT, NULL);//TODO: Renderer: Fix the precision and Resolution GLERROR("m_PickingTexture initialization failed"); + */ + + GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, + glm::vec2(m_Resolution.Width, m_Resolution.Height), GL_RG8, GL_RG, GL_FLOAT); } +void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) +{ + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, NULL);//TODO: Renderer: Fix the precision and Resolution + GLERROR("Texture initialization failed"); +} + + + void Renderer::InitializeFrameBuffers()//TODO: Renderer: Get this to a better location, as its really big { glGenRenderbuffers(1, &m_DepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Resolution.Width, m_Resolution.Height); - - - glGenFramebuffers(1, &m_PickingBuffer); - glBindFramebuffer(GL_FRAMEBUFFER, m_PickingBuffer); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthBuffer); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_PickingTexture, 0); - GLenum PickingBufferTextures[] = { GL_COLOR_ATTACHMENT0 }; - glDrawBuffers(1, PickingBufferTextures); - - if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { - LOG_ERROR("m_FbDeferred2 incomplete: 0x%x\n", fbStatus); - exit(EXIT_FAILURE); - } - - + + m_PickingBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT))); + m_PickingBuffer.AddResource(std::shared_ptr(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0))); + m_PickingBuffer.Generate(); } \ No newline at end of file diff --git a/src/Engine/Rendering/Util/ScreenCoords.cpp b/src/Engine/Rendering/Util/ScreenCoords.cpp index 103e576c..aad94d67 100644 --- a/src/Engine/Rendering/Util/ScreenCoords.cpp +++ b/src/Engine/Rendering/Util/ScreenCoords.cpp @@ -29,12 +29,12 @@ glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, float scr return ToWorldPos(screenCoord.x, screenCoord.y, depth, screenWidth, screenHeight, cameraProjectionMat, cameraViewMat); } -glm::vec3 ScreenCoords::ToPixelData(float x, float y, GLuint PickDataBuffer, GLuint DepthBuffer) +glm::vec3 ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer) { - glBindFramebuffer(GL_FRAMEBUFFER, PickDataBuffer); + PickDataBuffer->Bind(); glm::vec2 pixelData; glReadPixels(x, y, 1, 1, GL_RG, GL_FLOAT, &pixelData); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + PickDataBuffer->Unbind(); glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer); float depthData; @@ -44,7 +44,7 @@ glm::vec3 ScreenCoords::ToPixelData(float x, float y, GLuint PickDataBuffer, GLu return glm::vec3(pixelData, depthData); } -glm::vec3 ScreenCoords::ToPixelData(glm::vec2 screenCoord, GLuint PickDataBuffer, GLuint DepthBuffer) +glm::vec3 ScreenCoords::ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer) { return ToPixelData(screenCoord.x, screenCoord.y, PickDataBuffer, DepthBuffer); } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 10d19baf..416b054e 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -13,6 +13,8 @@ Game::Game(int argc, char* argv[]) // Create the core event broker m_EventBroker = new EventBroker(); + m_RenderQueueFactory = new RenderQueueFactory(); + // Create the renderer m_Renderer = new Renderer(); m_Renderer->SetFullscreen(m_Config->Get("Video.Fullscreen", false)); @@ -56,9 +58,9 @@ void Game::Tick() m_Renderer->Update(dt); m_EventBroker->Swap(); - //TODO: Render: This is not used, but will be used later when we dont add models to RQ in renderer. - RenderQueueCollection rq; - m_Renderer->Draw(rq); + m_RenderQueueFactory->Update(m_World); + + m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); m_EventBroker->Swap(); m_EventBroker->Clear();