From 798e42999d36ceeee8857d62311ee3db1b53a091 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 1 Dec 2015 10:34:53 +0100 Subject: [PATCH 01/12] Deploy now linking Shaders correctly --- tools/deploy.bat | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/deploy.bat b/tools/deploy.bat index b3f51c07..94692437 100755 --- a/tools/deploy.bat +++ b/tools/deploy.bat @@ -17,8 +17,6 @@ RMDIR "%DeployLocation%\Schema" MKLINK "%DeployLocation%\Schema\" "resources\Schema" /J :: Shaders RMDIR /S /Q "%DeployLocation%\Shaders" -MKDIR "%DeployLocation%\Shaders" -MKLINK "%DeployLocation%\Shaders\" "resources\Shaders" /J MKLINK "%DeployLocation%\Shaders\" "resources\Shaders" /J :: Configuration files MKLINK "%DeployLocation%\DefaultConfig.ini" "resources\DefaultConfig.ini" /H From 1fdf312af4885c73c6d10199c936cb2a8063dc28 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 1 Dec 2015 10:35:59 +0100 Subject: [PATCH 02/12] Set up Renderer base and shader compilation --- include/Engine/Rendering/Renderer.h | 23 ++++ include/Engine/Rendering/ShaderProgram.h | 91 ++++++++++++++ include/Game/Game.h | 2 +- resources/Shaders/BasicForward.frag.glsl | 25 ++++ resources/Shaders/BasicForward.vert.glsl | 24 ++++ src/Engine/Rendering/Renderer.cpp | 73 +++++++++++ src/Engine/Rendering/ShaderProgram.cpp | 153 +++++++++++++++++++++++ src/Game/Game.cpp | 2 +- 8 files changed, 391 insertions(+), 2 deletions(-) create mode 100644 include/Engine/Rendering/Renderer.h create mode 100644 include/Engine/Rendering/ShaderProgram.h create mode 100644 resources/Shaders/BasicForward.frag.glsl create mode 100644 resources/Shaders/BasicForward.vert.glsl create mode 100644 src/Engine/Rendering/Renderer.cpp create mode 100644 src/Engine/Rendering/ShaderProgram.cpp diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h new file mode 100644 index 00000000..74ed45bd --- /dev/null +++ b/include/Engine/Rendering/Renderer.h @@ -0,0 +1,23 @@ +#ifndef Renderer_h__ +#define Renderer_h__ + +#include + +#include "IRenderer.h" +#include "ShaderProgram.h" + +class Renderer : public IRenderer +{ +public: + virtual void Initialize() override; + virtual void Draw(RenderQueueCollection& rq) override; + +private: + void InitializeWindow(); + void InitializeShaders(); + + + ShaderProgram m_BasicForwardProgram; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/ShaderProgram.h b/include/Engine/Rendering/ShaderProgram.h new file mode 100644 index 00000000..edb0c1e5 --- /dev/null +++ b/include/Engine/Rendering/ShaderProgram.h @@ -0,0 +1,91 @@ + +#include + +#include "../Core/Util/Logging.h" +// OpenGL +#include +#define GLFW_INCLUDE_GLU +#include +#include +#include "Util/GLError.h" + +#include +#include + + +class Shader +{ +public: + static GLuint CompileShader(GLenum shaderType, std::string fileName); + + Shader(GLenum shaderType, std::string fileName); + + virtual ~Shader(); + + GLuint Compile(); + + GLenum GetType() const; + std::string GetFileName() const; + GLuint GetHandle() const; + bool IsCompiled() const; + +protected: + GLenum m_ShaderType; + std::string m_FileName; + GLint m_ShaderHandle; +}; + +template +class ShaderType : public Shader +{ +public: + ShaderType(std::string fileName) + : Shader(SHADERTYPE, fileName) { } +}; + +class VertexShader : public ShaderType +{ +public: + VertexShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class FragmentShader : public ShaderType +{ +public: + FragmentShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class GeometryShader : public ShaderType +{ +public: + GeometryShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class ComputeShader : public ShaderType +{ +public: + ComputeShader(std::string fileName) + : ShaderType(fileName) { } +}; + +class ShaderProgram +{ +public: + ShaderProgram() + : m_ShaderProgramHandle(0) { } + ~ShaderProgram(); + + void AddShader(std::shared_ptr shader); + void Compile(); + GLuint Link(); + GLuint GetHandle(); + void Bind(); + void Unbind(); + +private: + GLuint m_ShaderProgramHandle; + std::vector> m_Shaders; +}; diff --git a/include/Game/Game.h b/include/Game/Game.h index 6a942164..a5f24fd6 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -5,7 +5,7 @@ #include "Core/ConfigFile.h" #include "Core/EventBroker.h" -#include "Rendering/DummyRenderer.h" +#include "Rendering/Renderer.h" #include "Core/InputManager.h" #include "GUI/Frame.h" diff --git a/resources/Shaders/BasicForward.frag.glsl b/resources/Shaders/BasicForward.frag.glsl new file mode 100644 index 00000000..1461e51f --- /dev/null +++ b/resources/Shaders/BasicForward.frag.glsl @@ -0,0 +1,25 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +uniform sampler2D texture0; + + +in VertexData{ + vec3 VertexPosition; + vec3 Normal; + vec2 TextureCoordinate; +} Input; + +out vec4 fragmentColor; + + +void main() +{ + vec4 texel = texture2D(texture0, Input.TextureCoordinate); + fragmentColor = texel; +} + + diff --git a/resources/Shaders/BasicForward.vert.glsl b/resources/Shaders/BasicForward.vert.glsl new file mode 100644 index 00000000..e5f8e7ac --- /dev/null +++ b/resources/Shaders/BasicForward.vert.glsl @@ -0,0 +1,24 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec2 TextureCoord; +layout(location = 2) in vec3 Normal; + +out VertexData{ + vec3 VertexPosition; + vec3 Normal; + vec2 TextureCoordinate; +} Output; + +void main() +{ + gl_Position = P*V*M * vec4(Position, 1.0); + + Output.VertexPosition = Position; + Output.TextureCoordinate = TextureCoord; + Output.Normal = Normal; +} \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp new file mode 100644 index 00000000..2c1c6a1c --- /dev/null +++ b/src/Engine/Rendering/Renderer.cpp @@ -0,0 +1,73 @@ +#include "Rendering/Renderer.h" + +void Renderer::Initialize() +{ + InitializeWindow(); + + // 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); + + InitializeShaders(); +} + +void Renderer::InitializeWindow() +{ + // Initialize GLFW + if (!glfwInit()) { + LOG_ERROR("GLFW: Initialization failed"); + exit(EXIT_FAILURE); + } + + // Create a window + GLFWmonitor* monitor = nullptr; + if (m_Fullscreen) { + monitor = glfwGetPrimaryMonitor(); + } + //glfwWindowHint(GLFW_SAMPLES, 8); + m_Window = glfwCreateWindow(m_Resolution.Width, m_Resolution.Height, "daydream", monitor, nullptr); + if (!m_Window) { + LOG_ERROR("GLFW: Failed to create window"); + exit(EXIT_FAILURE); + } + glfwMakeContextCurrent(m_Window); + + // GL version info + glGetIntegerv(GL_MAJOR_VERSION, &m_GLVersion[0]); + glGetIntegerv(GL_MINOR_VERSION, &m_GLVersion[1]); + m_GLVendor = (GLchar*)glGetString(GL_VENDOR); + std::stringstream ss; + ss << m_GLVendor << " OpenGL " << m_GLVersion[0] << "." << m_GLVersion[1]; +#ifdef DEBUG + ss << " DEBUG"; +#endif + LOG_INFO(ss.str().c_str()); + glfwSetWindowTitle(m_Window, ss.str().c_str()); + + // Initialize GLEW + if (glewInit() != GLEW_OK) { + LOG_ERROR("GLEW: Initialization failed"); + exit(EXIT_FAILURE); + } +} + +void Renderer::InitializeShaders() +{ + m_BasicForwardProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/BasicForward.vert.glsl"))); + m_BasicForwardProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/BasicForward.frag.glsl"))); + m_BasicForwardProgram.Compile(); + m_BasicForwardProgram.Link(); +} + +void Renderer::Draw(RenderQueueCollection& rq) +{ + glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f); + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(m_Window); +} + diff --git a/src/Engine/Rendering/ShaderProgram.cpp b/src/Engine/Rendering/ShaderProgram.cpp new file mode 100644 index 00000000..5200ff22 --- /dev/null +++ b/src/Engine/Rendering/ShaderProgram.cpp @@ -0,0 +1,153 @@ +#include "Rendering/ShaderProgram.h" + +GLuint Shader::CompileShader(GLenum shaderType, std::string fileName) +{ + LOG_INFO("Compiling shader \"%s\"", fileName.c_str()); + + std::string shaderFile; + std::ifstream in(fileName, std::ios::in); + if (!in) { + LOG_ERROR("Error: Failed to open shader file \"%s\"", fileName.c_str()); + return 0; + } + in.seekg(0, std::ios::end); + shaderFile.resize((int)in.tellg()); + in.seekg(0, std::ios::beg); + in.read(&shaderFile[0], shaderFile.size()); + in.close(); + + GLuint shader = glCreateShader(shaderType); + if (GLERROR("glCreateShader")) + return 0; + + const GLchar* shaderFiles = shaderFile.c_str(); + const GLint length = shaderFile.length(); + glShaderSource(shader, 1, &shaderFiles, &length); + if (GLERROR("glShaderSource")) + return 0; + + glCompileShader(shader); + + GLint compileStatus; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); + if (compileStatus != GL_TRUE) { + LOG_ERROR("Shader compilation failed"); + GLsizei infoLogLength; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); + GLchar* infolog = new GLchar[infoLogLength]; + glGetShaderInfoLog(shader, infoLogLength, &infoLogLength, infolog); + LOG_ERROR(infolog); + delete[] infolog; + } + + if (GLERROR("glCompileShader")) + return 0; + + return shader; +} + +Shader::Shader(GLenum shaderType, std::string fileName) : m_ShaderType(shaderType), m_FileName(fileName) +{ + m_ShaderHandle = 0; +} + +Shader::~Shader() +{ + if (m_ShaderHandle != 0) { + glDeleteShader(m_ShaderHandle); + } +} + +GLuint Shader::Compile() +{ + m_ShaderHandle = CompileShader(m_ShaderType, m_FileName); + return m_ShaderHandle; +} + +GLenum Shader::GetType() const +{ + return m_ShaderType; +} + +std::string Shader::GetFileName() const +{ + return m_FileName; +} + +GLuint Shader::GetHandle() const +{ + return m_ShaderHandle; +} + +bool Shader::IsCompiled() const +{ + return m_ShaderHandle != 0; +} + +ShaderProgram::~ShaderProgram() +{ + if (m_ShaderProgramHandle != 0) { + glDeleteProgram(m_ShaderProgramHandle); + } +} + +void ShaderProgram::AddShader(std::shared_ptr shader) +{ + m_Shaders.push_back(shader); +} + +void ShaderProgram::Compile() +{ + if (m_ShaderProgramHandle == 0) + { + m_ShaderProgramHandle = glCreateProgram(); + } + + for (auto &shader : m_Shaders) + { + if (!shader->IsCompiled()) + { + shader->Compile(); + } + } +} + +GLuint ShaderProgram::Link() +{ + if (m_Shaders.size() == 0) + { + LOG_ERROR("Failed to link shader program: No shaders bound"); + return 0; + } + + LOG_INFO("Linking shader program"); + + for (auto &shader : m_Shaders) + { + glAttachShader(m_ShaderProgramHandle, shader->GetHandle()); + } + glLinkProgram(m_ShaderProgramHandle); + if (GLERROR("glLinkProgram")) + return 0; + m_Shaders.clear(); + + return m_ShaderProgramHandle; +} + +GLuint ShaderProgram::GetHandle() +{ + return m_ShaderProgramHandle; +} + +void ShaderProgram::Bind() +{ + if (m_ShaderProgramHandle == 0) + return; + + glUseProgram(m_ShaderProgramHandle); +} + +void ShaderProgram::Unbind() +{ + glActiveShaderProgram(0, 0); +} \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index c710e218..47aae53d 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -11,7 +11,7 @@ Game::Game(int argc, char* argv[]) m_EventBroker = new EventBroker(); // Create the renderer - m_Renderer = new DummyRenderer(); + m_Renderer = new Renderer(); m_Renderer->SetFullscreen(m_Config->Get("Video.Fullscreen", false)); m_Renderer->SetVSYNC(m_Config->Get("Video.VSYNC", false)); m_Renderer->SetResolution(Rectangle( From 04d10bf7af2ecdee8a678e7c0652134a29ee7e22 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 1 Dec 2015 14:07:10 +0100 Subject: [PATCH 03/12] Functioning basic renderer for models --- assets | 2 +- include/Engine/Rendering/IRenderer.h | 1 + include/Engine/Rendering/RenderQueue.h | 2 + include/Engine/Rendering/Renderer.h | 12 +++- include/Engine/Rendering/ShaderProgram.h | 14 +---- src/Engine/Rendering/Renderer.cpp | 78 +++++++++++++++++++++++- src/Game/Game.cpp | 3 + 7 files changed, 95 insertions(+), 17 deletions(-) diff --git a/assets b/assets index 6b30aa83..1edc2d9b 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6b30aa83cfe6bc7df6453e17dbb63da91100b7ec +Subproject commit 1edc2d9b73aae18d6e72ce57dad0bb2fa27311e9 diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index 3c35869d..6808f10f 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -6,6 +6,7 @@ #include "../Core/Util/Rectangle.h" #include "Camera.h" #include "RenderQueue.h" +#include "Model.h" class IRenderer { diff --git a/include/Engine/Rendering/RenderQueue.h b/include/Engine/Rendering/RenderQueue.h index f3125462..1bbeb7f6 100644 --- a/include/Engine/Rendering/RenderQueue.h +++ b/include/Engine/Rendering/RenderQueue.h @@ -13,6 +13,8 @@ class Skeleton; class Texture; class RenderQueue; +//TODO: Render: Remove obsolete RenderJobs and fix standard values on variables. + struct RenderJob { friend class RenderQueue; diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 74ed45bd..0054f796 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -5,6 +5,8 @@ #include "IRenderer.h" #include "ShaderProgram.h" +//TODO: Temp resourceManager +#include "../Core/ResourceManager.h" class Renderer : public IRenderer { @@ -13,10 +15,18 @@ public: virtual void Draw(RenderQueueCollection& rq) override; private: + //----------------------Variables----------------------// + RenderQueueCollection m_TempRQ; + Texture* m_ErrorTexture; + + //----------------------Functions----------------------// void InitializeWindow(); void InitializeShaders(); + //TODO: Render: Remove ModelsToDraw from Renderer. + void ModelsToDraw(); + void EnqueueModel(Model* model); - + //--------------------ShaderPrograms-------------------// ShaderProgram m_BasicForwardProgram; }; diff --git a/include/Engine/Rendering/ShaderProgram.h b/include/Engine/Rendering/ShaderProgram.h index edb0c1e5..97f64e60 100644 --- a/include/Engine/Rendering/ShaderProgram.h +++ b/include/Engine/Rendering/ShaderProgram.h @@ -1,17 +1,7 @@ -#include - -#include "../Core/Util/Logging.h" -// OpenGL -#include -#define GLFW_INCLUDE_GLU -#include -#include -#include "Util/GLError.h" - +#include "../Common.h" +#include "../OpenGL.h" #include -#include - class Shader { diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 2c1c6a1c..39bfefd7 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -6,14 +6,15 @@ void Renderer::Initialize() // 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)); + m_DefaultCamera->SetPosition(glm::vec3(0, 0, 10)); if (m_Camera == nullptr) { m_Camera = m_DefaultCamera; } glfwSwapInterval(m_VSYNC); - + m_ErrorTexture = ResourceManager::Load("Textures/Core/ErrorTexture.png"); InitializeShaders(); + ModelsToDraw(); } void Renderer::InitializeWindow() @@ -64,10 +65,81 @@ void Renderer::InitializeShaders() m_BasicForwardProgram.Link(); } + + +void Renderer::ModelsToDraw() +{ + Model *m = ResourceManager::Load("Models/translation_widget.obj"); + EnqueueModel(m); +} + +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::Draw(RenderQueueCollection& rq) { + //TODO: Render: Clean up draw code + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //TODO: Render: Add code for more jobs than modeljobs. + for (auto &job : m_TempRQ.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, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); + + //TODO: Renderer: bättre textur felhantering samt fler texturer stöd + if (modelJob->DiffuseTexture != nullptr) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); + } else { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_ErrorTexture->m_Texture); + } + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); + + continue; + } + } glfwSwapBuffers(m_Window); } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 47aae53d..a93e9b8d 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -3,6 +3,8 @@ Game::Game(int argc, char* argv[]) { ResourceManager::RegisterType("ConfigFile"); + ResourceManager::RegisterType("Model"); + ResourceManager::RegisterType("Texture"); m_Config = ResourceManager::Load("Config.ini"); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); @@ -49,6 +51,7 @@ void Game::Tick() m_InputManager->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); From 07d037ae57fbac9234cac1bf53c7014462744e5a Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 1 Dec 2015 15:56:26 +0100 Subject: [PATCH 04/12] Added Fly Camera and Vertex Colors --- include/Engine/Rendering/IRenderer.h | 2 + include/Engine/Rendering/Renderer.h | 6 ++- resources/Shaders/BasicForward.frag.glsl | 8 +-- resources/Shaders/BasicForward.vert.glsl | 22 +++++--- src/Engine/Rendering/Camera.cpp | 6 +++ src/Engine/Rendering/Renderer.cpp | 64 ++++++++++++++++++++++-- src/Game/Game.cpp | 1 + 7 files changed, 95 insertions(+), 14 deletions(-) diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index 6808f10f..1b6d945c 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -3,6 +3,7 @@ #include "../Common.h" #include "../OpenGL.h" +#include "../GLM.h" #include "../Core/Util/Rectangle.h" #include "Camera.h" #include "RenderQueue.h" @@ -29,6 +30,7 @@ public: } virtual void Initialize() = 0; + virtual void Update(double dt) = 0; virtual void Draw(RenderQueueCollection& rq) = 0; protected: diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 0054f796..423365f6 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -12,20 +12,22 @@ class Renderer : public IRenderer { public: virtual void Initialize() override; + virtual void Update(double dt) override; virtual void Draw(RenderQueueCollection& rq) override; private: //----------------------Variables----------------------// RenderQueueCollection m_TempRQ; Texture* m_ErrorTexture; - + Texture* m_WhiteTexture; + float m_CameraMoveSpeed = 3.f; //----------------------Functions----------------------// void InitializeWindow(); void InitializeShaders(); //TODO: Render: Remove ModelsToDraw from Renderer. void ModelsToDraw(); void EnqueueModel(Model* model); - + void InputUpdate(double dt); //--------------------ShaderPrograms-------------------// ShaderProgram m_BasicForwardProgram; }; diff --git a/resources/Shaders/BasicForward.frag.glsl b/resources/Shaders/BasicForward.frag.glsl index 1461e51f..a7b7cb1f 100644 --- a/resources/Shaders/BasicForward.frag.glsl +++ b/resources/Shaders/BasicForward.frag.glsl @@ -8,10 +8,12 @@ uniform sampler2D texture0; in VertexData{ - vec3 VertexPosition; + vec3 Position; vec3 Normal; vec2 TextureCoordinate; -} Input; + vec4 DiffuseColor; +}Input; + out vec4 fragmentColor; @@ -19,7 +21,7 @@ out vec4 fragmentColor; void main() { vec4 texel = texture2D(texture0, Input.TextureCoordinate); - fragmentColor = texel; + fragmentColor = texel * Input.DiffuseColor; } diff --git a/resources/Shaders/BasicForward.vert.glsl b/resources/Shaders/BasicForward.vert.glsl index e5f8e7ac..20ab9051 100644 --- a/resources/Shaders/BasicForward.vert.glsl +++ b/resources/Shaders/BasicForward.vert.glsl @@ -5,20 +5,30 @@ uniform mat4 V; uniform mat4 P; layout(location = 0) in vec3 Position; -layout(location = 1) in vec2 TextureCoord; -layout(location = 2) in vec3 Normal; +layout(location = 1) in vec3 Normal; +layout(location = 2) in vec3 Tangent; +layout(location = 3) in vec3 BiTangent; +layout(location = 4) in vec2 TextureCoords; +layout(location = 5) in vec4 DiffuseVertexColor; +layout(location = 6) in vec4 SpecularVertexColor; +layout(location = 7) in vec4 BoneIndices1; +layout(location = 8) in vec4 BoneIndices2; +layout(location = 9) in vec4 BoneWeights1; +layout(location = 10) in vec4 BoneWeights2; out VertexData{ - vec3 VertexPosition; + vec3 Position; vec3 Normal; vec2 TextureCoordinate; -} Output; + vec4 DiffuseColor; +}Output; void main() { gl_Position = P*V*M * vec4(Position, 1.0); - Output.VertexPosition = Position; - Output.TextureCoordinate = TextureCoord; + Output.Position = Position; + Output.TextureCoordinate = TextureCoords; Output.Normal = Normal; + Output.DiffuseColor = DiffuseVertexColor; } \ No newline at end of file diff --git a/src/Engine/Rendering/Camera.cpp b/src/Engine/Rendering/Camera.cpp index 8896b6a8..6ddf1c6c 100644 --- a/src/Engine/Rendering/Camera.cpp +++ b/src/Engine/Rendering/Camera.cpp @@ -17,6 +17,12 @@ glm::vec3 Camera::Forward() { return m_Orientation * glm::vec3(0, 0, -1); } + +glm::vec3 Camera::Right() +{ + return m_Orientation * glm::vec3(1, 0, 0); +} + // //glm::vec3 Camera::Right() //{ diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 39bfefd7..ec789f9c 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -13,6 +13,7 @@ void Renderer::Initialize() glfwSwapInterval(m_VSYNC); m_ErrorTexture = ResourceManager::Load("Textures/Core/ErrorTexture.png"); + m_WhiteTexture = ResourceManager::Load("Textures/Core/Blank.png"); InitializeShaders(); ModelsToDraw(); } @@ -65,8 +66,6 @@ void Renderer::InitializeShaders() m_BasicForwardProgram.Link(); } - - void Renderer::ModelsToDraw() { Model *m = ResourceManager::Load("Models/translation_widget.obj"); @@ -102,6 +101,65 @@ void Renderer::EnqueueModel(Model* model) } } +void Renderer::InputUpdate(double dt) +{ + glm::vec3 m_Position = m_Camera->Position(); + if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS) + { + m_Position = glm::vec3(0.f, 0.f, 5.f); + } + if (glfwGetKey(m_Window, GLFW_KEY_W) == GLFW_PRESS) + { + m_Position += m_Camera->Forward() * m_CameraMoveSpeed * (float)dt; + } + if (glfwGetKey(m_Window, GLFW_KEY_S) == GLFW_PRESS) + { + m_Position -= m_Camera->Forward() * m_CameraMoveSpeed * (float)dt; + } + if (glfwGetKey(m_Window, GLFW_KEY_D) == GLFW_PRESS) + { + m_Position += m_Camera->Right() * m_CameraMoveSpeed * (float)dt; + } + if (glfwGetKey(m_Window, GLFW_KEY_A) == GLFW_PRESS) + { + m_Position -= m_Camera->Right() * m_CameraMoveSpeed * (float)dt; + } + if (glfwGetKey(m_Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) + { + m_CameraMoveSpeed = 5.f; + } + else { + m_CameraMoveSpeed = 0.5f; + } + + if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { + static double mousePosX, mousePosY; + + glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); + double deltaX, deltaY; + deltaX = mousePosX - (float)Resolution().Width / 2; + deltaY = mousePosY - (float)Resolution().Height / 2; + + float rotationY = -deltaY / 300.f; + float rotationX = -deltaX / 300.f; + glm::quat orientation = m_Camera->Orientation(); + + + orientation = orientation * glm::angleAxis(rotationY, glm::vec3(1, 0, 0)); + orientation = glm::angleAxis(rotationX, glm::vec3(0, 1, 0)) * orientation; + + m_Camera->SetOrientation(orientation); + + glfwSetCursorPos(m_Window, Resolution().Width / 2, Resolution().Height / 2); + } + m_Camera->SetPosition(m_Position); +} + +void Renderer::Update(double dt) +{ + InputUpdate(dt); +} + void Renderer::Draw(RenderQueueCollection& rq) { //TODO: Render: Clean up draw code @@ -130,7 +188,7 @@ void Renderer::Draw(RenderQueueCollection& rq) glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); } else { glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_ErrorTexture->m_Texture); + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); } glBindVertexArray(modelJob->Model->VAO); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index a93e9b8d..5666db3a 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -49,6 +49,7 @@ void Game::Tick() m_EventBroker->Swap(); m_InputManager->Update(dt); + 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. From 1a963e823ee17f926f0624028c7597d7d0d5e2ef Mon Sep 17 00:00:00 2001 From: viktorljung Date: Tue, 1 Dec 2015 17:46:09 +0100 Subject: [PATCH 05/12] Scale, Rotate and Translate widgets up and working --- assets | 2 +- src/Engine/Rendering/Renderer.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/assets b/assets index 1edc2d9b..6428e252 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 1edc2d9b73aae18d6e72ce57dad0bb2fa27311e9 +Subproject commit 6428e2528c4a5692f277eed6041e97b9d8e70b2f diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index ec789f9c..d17eaeae 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -68,8 +68,12 @@ void Renderer::InitializeShaders() void Renderer::ModelsToDraw() { - Model *m = ResourceManager::Load("Models/translation_widget.obj"); + Model *m = ResourceManager::Load("Models/ScaleWidget.obj"); EnqueueModel(m); + Model *m2 = ResourceManager::Load("Models/TranslationWidget.obj"); + EnqueueModel(m2); + Model *m3 = ResourceManager::Load("Models/RotationWidget.obj"); + EnqueueModel(m3); } void Renderer::EnqueueModel(Model* model) From eb50a747faaec8709eac75989bcac9c2da6f827c Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 2 Dec 2015 17:59:21 +0100 Subject: [PATCH 06/12] Added Hash for Vec2 Unordered_Map --- .../Engine/Rendering/Util/UnorderedMapVec2.h | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 include/Engine/Rendering/Util/UnorderedMapVec2.h diff --git a/include/Engine/Rendering/Util/UnorderedMapVec2.h b/include/Engine/Rendering/Util/UnorderedMapVec2.h new file mode 100644 index 00000000..0247ac9d --- /dev/null +++ b/include/Engine/Rendering/Util/UnorderedMapVec2.h @@ -0,0 +1,23 @@ +#ifndef UnorderedMapVec2_h__ +#define UnorderedMapVec2_h__ + +#include +#include +#include + +template<> +struct std::hash +{ + inline std::size_t operator()(const glm::vec2 &v) const + { + return boost::hash()(v.x) ^ boost::hash()(v.y); + } + + inline bool operator()(const glm::vec2& a, const glm::vec2& b)const + { + return a.x == b.x && a.y == b.y; + } + +}; + +#endif \ No newline at end of file From 18b63c7ef38ff1a1189b8377ff03a90801b0da2e Mon Sep 17 00:00:00 2001 From: viktorljung Date: Wed, 2 Dec 2015 18:00:11 +0100 Subject: [PATCH 07/12] Added 3D picking of models to renderer --- assets | 2 +- include/Engine/Rendering/Renderer.h | 28 ++- include/Engine/Rendering/ShaderProgram.h | 2 +- resources/Shaders/DrawScreenQuad.frag.glsl | 19 ++ resources/Shaders/DrawScreenQuad.vert.glsl | 13 ++ resources/Shaders/Picking.frag.glsl | 19 ++ resources/Shaders/Picking.vert.glsl | 28 +++ src/Engine/Rendering/Renderer.cpp | 254 +++++++++++++++++---- src/Engine/Rendering/ShaderProgram.cpp | 12 +- 9 files changed, 329 insertions(+), 48 deletions(-) create mode 100644 resources/Shaders/DrawScreenQuad.frag.glsl create mode 100644 resources/Shaders/DrawScreenQuad.vert.glsl create mode 100644 resources/Shaders/Picking.frag.glsl create mode 100644 resources/Shaders/Picking.vert.glsl diff --git a/assets b/assets index 6428e252..a08447dd 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 6428e2528c4a5692f277eed6041e97b9d8e70b2f +Subproject commit a08447ddb3aaf9ebdc7e18979291567a7032b6a2 diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 423365f6..f9a51d4e 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -7,6 +7,7 @@ #include "ShaderProgram.h" //TODO: Temp resourceManager #include "../Core/ResourceManager.h" +#include "Util/UnorderedMapVec2.h" class Renderer : public IRenderer { @@ -20,16 +21,41 @@ private: RenderQueueCollection m_TempRQ; Texture* m_ErrorTexture; Texture* m_WhiteTexture; - float m_CameraMoveSpeed = 3.f; + float m_CameraMoveSpeed; + GLuint m_PickingBuffer; + GLuint m_PickingTexture; + GLuint m_DepthBuffer; + + Model* m_ScreenQuad; + Model* m_UnitQuad; + Model* m_UnitSphere; + + //Temporary + Model* m; + Model* m2; + Model* m3; + Model* MapModel; + + + std::unordered_map m_PickingColorsToModels; + //----------------------Functions----------------------// void InitializeWindow(); void InitializeShaders(); + void InitializeTextures(); + void InitializeFrameBuffers(); //TODO: Render: Remove ModelsToDraw from Renderer. void ModelsToDraw(); void EnqueueModel(Model* model); void InputUpdate(double dt); + void PickingPass(); + void DrawScreenQuad(GLuint textureToDraw); + glm::vec3 GetClickedPixelData(float x, float y); + void DrawScene(RenderQueueCollection& rq); //--------------------ShaderPrograms-------------------// ShaderProgram m_BasicForwardProgram; + ShaderProgram m_PickingProgram; + ShaderProgram m_DrawScreenQuadProgram; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/ShaderProgram.h b/include/Engine/Rendering/ShaderProgram.h index 97f64e60..1b87650e 100644 --- a/include/Engine/Rendering/ShaderProgram.h +++ b/include/Engine/Rendering/ShaderProgram.h @@ -18,7 +18,6 @@ public: std::string GetFileName() const; GLuint GetHandle() const; bool IsCompiled() const; - protected: GLenum m_ShaderType; std::string m_FileName; @@ -74,6 +73,7 @@ public: GLuint GetHandle(); void Bind(); void Unbind(); + void BindFragDataLocation(int index, std::string name); private: GLuint m_ShaderProgramHandle; diff --git a/resources/Shaders/DrawScreenQuad.frag.glsl b/resources/Shaders/DrawScreenQuad.frag.glsl new file mode 100644 index 00000000..17837a7b --- /dev/null +++ b/resources/Shaders/DrawScreenQuad.frag.glsl @@ -0,0 +1,19 @@ +#version 430 + +layout (binding = 0) uniform sampler2D Texture; + +in VertexData{ + vec2 TextureCoordinate; +}Input; + +out vec4 fragmentColor; + +void main() +{ + vec4 texel = texture(Texture, Input.TextureCoordinate); + + fragmentColor = texel; + //fragmentColor = vec4(1,0.5,0.7,1); +} + + diff --git a/resources/Shaders/DrawScreenQuad.vert.glsl b/resources/Shaders/DrawScreenQuad.vert.glsl new file mode 100644 index 00000000..346bc141 --- /dev/null +++ b/resources/Shaders/DrawScreenQuad.vert.glsl @@ -0,0 +1,13 @@ +#version 430 + +layout (location = 0) in vec3 Position; + +out VertexData{ + vec2 TextureCoordinate; +}Output; + +void main() +{ + gl_Position = vec4(Position, 1.0); + Output.TextureCoordinate = (vec2(Position) + 1) / 2; +} \ No newline at end of file diff --git a/resources/Shaders/Picking.frag.glsl b/resources/Shaders/Picking.frag.glsl new file mode 100644 index 00000000..11f529b0 --- /dev/null +++ b/resources/Shaders/Picking.frag.glsl @@ -0,0 +1,19 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform vec2 PickingColor; + +in VertexData{ + vec3 Position; +}Input; + +out vec4 TextureFragment; + +void main() +{ + TextureFragment = vec4(PickingColor, 0, 1); +} + + diff --git a/resources/Shaders/Picking.vert.glsl b/resources/Shaders/Picking.vert.glsl new file mode 100644 index 00000000..47c0ecd7 --- /dev/null +++ b/resources/Shaders/Picking.vert.glsl @@ -0,0 +1,28 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; +layout(location = 1) in vec3 Normal; +layout(location = 2) in vec3 Tangent; +layout(location = 3) in vec3 BiTangent; +layout(location = 4) in vec2 TextureCoords; +layout(location = 5) in vec4 DiffuseVertexColor; +layout(location = 6) in vec4 SpecularVertexColor; +layout(location = 7) in vec4 BoneIndices1; +layout(location = 8) in vec4 BoneIndices2; +layout(location = 9) in vec4 BoneWeights1; +layout(location = 10) in vec4 BoneWeights2; + +out VertexData{ + vec3 Position; +}Output; + +void main() +{ + gl_Position = P*V*M * vec4(Position, 1.0); + + Output.Position = Position; +} \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index d17eaeae..ef18d631 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -12,9 +12,9 @@ void Renderer::Initialize() } glfwSwapInterval(m_VSYNC); - m_ErrorTexture = ResourceManager::Load("Textures/Core/ErrorTexture.png"); - m_WhiteTexture = ResourceManager::Load("Textures/Core/Blank.png"); InitializeShaders(); + InitializeTextures(); + InitializeFrameBuffers(); ModelsToDraw(); } @@ -64,16 +64,35 @@ void Renderer::InitializeShaders() m_BasicForwardProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/BasicForward.frag.glsl"))); m_BasicForwardProgram.Compile(); m_BasicForwardProgram.Link(); + + m_PickingProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/Picking.vert.glsl"))); + m_PickingProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/Picking.frag.glsl"))); + m_PickingProgram.Compile(); + m_PickingProgram.BindFragDataLocation(0, "TextureFragment"); + m_PickingProgram.Link(); + + m_DrawScreenQuadProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/DrawScreenQuad.vert.glsl"))); + m_DrawScreenQuadProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/DrawScreenQuad.frag.glsl"))); + m_DrawScreenQuadProgram.Compile(); + m_DrawScreenQuadProgram.Link(); + } void Renderer::ModelsToDraw() { - Model *m = ResourceManager::Load("Models/ScaleWidget.obj"); + m = ResourceManager::Load("Models/ScaleWidget.obj"); EnqueueModel(m); - Model *m2 = ResourceManager::Load("Models/TranslationWidget.obj"); + m2 = ResourceManager::Load("Models/TranslationWidget.obj"); EnqueueModel(m2); - Model *m3 = ResourceManager::Load("Models/RotationWidget.obj"); + 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) @@ -136,10 +155,26 @@ void Renderer::InputUpdate(double dt) m_CameraMoveSpeed = 0.5f; } - if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { - static double mousePosX, mousePosY; - glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); + static double mousePosX, mousePosY; + glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); + if (glfwGetMouseButton(m_Window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) { + glm::vec3 data = GetClickedPixelData(mousePosX, m_Resolution.Height - mousePosY); + glm::vec2 pixelData = glm::vec2(data); + float depthData = data.z; + printf("R: %f, G: %f, Depth: %f\n", pixelData.r, pixelData.g, depthData); + + + if (pixelData != glm::vec2(0, 0)) { + const Model* pickModel = m_PickingColorsToModels[pixelData]; + + } + } + + + if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { + + double deltaX, deltaY; deltaX = mousePosX - (float)Resolution().Width / 2; deltaY = mousePosY - (float)Resolution().Height / 2; @@ -166,42 +201,173 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderQueueCollection& rq) { - //TODO: Render: Clean up draw code - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - - glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //TODO: Render: Add code for more jobs than modeljobs. - for (auto &job : m_TempRQ.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, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); - - //TODO: Renderer: bättre textur felhantering samt fler texturer stöd - if (modelJob->DiffuseTexture != nullptr) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); - } else { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); - } - - glBindVertexArray(modelJob->Model->VAO); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); - glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); - - continue; - } - } + //TODO: Renderer: Kanske borde vara längst upp i update. + PickingPass(); + DrawScreenQuad(m_PickingTexture); + //DrawScene(rq); glfwSwapBuffers(m_Window); } +void Renderer::DrawScene(RenderQueueCollection& rq) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + //TODO: Render: Clean up draw code + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //TODO: Render: Add code for more jobs than modeljobs. + for (auto &job : m_TempRQ.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, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); + + //TODO: Renderer: bättre textur felhantering samt fler texturer stöd + if (modelJob->DiffuseTexture != nullptr) { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, modelJob->DiffuseTexture->m_Texture); + } else { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_WhiteTexture->m_Texture); + } + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); + + continue; + } + } +} + +void Renderer::PickingPass() +{ + glBindFramebuffer(GL_FRAMEBUFFER, m_PickingBuffer); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glClearColor(0.f, 0.f, 0.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + int r = 30; + int g = 0; + //TODO: Render: Add code for more jobs than modeljobs. + + + GLuint ShaderHandle = m_PickingProgram.GetHandle(); + m_PickingProgram.Bind(); + + for (auto &job : m_TempRQ.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; + + //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, "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)); + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex); + r+=50; + if(r > 255) { + r = 0; + g+=50; + } + } + } + +} + + +void Renderer::DrawScreenQuad(GLuint textureToDraw) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + + glClearColor(0.f, 0.f, 0.f, 1.f); + glClear(GL_COLOR_BUFFER_BIT); + + + m_DrawScreenQuadProgram.Bind(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, textureToDraw); + + glBindVertexArray(m_ScreenQuad->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->TextureGroups[0].EndIndex - m_ScreenQuad->TextureGroups[0].StartIndex +1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->TextureGroups[0].StartIndex); +} + + + +// Will return a vec3 where RG is the PickColor and B is the Depth +glm::vec3 Renderer::GetClickedPixelData(float x, float y) +{ + glBindFramebuffer(GL_FRAMEBUFFER, m_PickingBuffer); + glm::vec2 pixelData; + glReadPixels(x, y, 1, 1, GL_RG, GL_FLOAT, &pixelData); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glBindFramebuffer(GL_FRAMEBUFFER, m_DepthBuffer); + float depthData; + glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + return glm::vec3(pixelData, depthData); +} + +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 + GLERROR("m_PickingTexture 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); + } + + +} \ No newline at end of file diff --git a/src/Engine/Rendering/ShaderProgram.cpp b/src/Engine/Rendering/ShaderProgram.cpp index 5200ff22..f713cd03 100644 --- a/src/Engine/Rendering/ShaderProgram.cpp +++ b/src/Engine/Rendering/ShaderProgram.cpp @@ -150,4 +150,14 @@ void ShaderProgram::Bind() void ShaderProgram::Unbind() { glActiveShaderProgram(0, 0); -} \ No newline at end of file +} + +void ShaderProgram::BindFragDataLocation(int index, std::string name) +{ + + if (m_ShaderProgramHandle == 0) + return; + + glBindFragDataLocation(m_ShaderProgramHandle, index, name.c_str()); +} + From 983ca485f5c41838917f457bbd0da1650620aa71 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 3 Dec 2015 14:50:14 +0100 Subject: [PATCH 08/12] Picking now returning world position --- include/Engine/Rendering/Camera.h | 10 ++++--- include/Engine/Rendering/Renderer.h | 5 ++++ src/Engine/Rendering/Renderer.cpp | 46 +++++++++++++++++++++++++---- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/include/Engine/Rendering/Camera.h b/include/Engine/Rendering/Camera.h index 6a1acdd8..660dfd49 100644 --- a/include/Engine/Rendering/Camera.h +++ b/include/Engine/Rendering/Camera.h @@ -46,10 +46,7 @@ public: float FarClip() const { return m_FarClip; } void SetFarClip(float val); - float m_AspectRatio; - float m_FOV; - float m_NearClip; - float m_FarClip; + private: void UpdateViewMatrix(); @@ -60,6 +57,11 @@ private: glm::mat4 m_ProjectionMatrix; glm::mat4 m_ViewMatrix; + + float m_AspectRatio; + float m_FOV; + float m_NearClip; + float m_FarClip; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index f9a51d4e..6fb0b10f 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -52,6 +52,11 @@ private: void DrawScreenQuad(GLuint textureToDraw); glm::vec3 GetClickedPixelData(float x, float y); void DrawScene(RenderQueueCollection& rq); + + //--------------------Utility functions----------------// + glm::vec3 ScreenCoordsToWorldPos(glm::vec2 screenCoord, float depth); + //EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth); + //--------------------ShaderPrograms-------------------// ShaderProgram m_BasicForwardProgram; ShaderProgram m_PickingProgram; diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index ef18d631..bbaab41e 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -80,12 +80,14 @@ 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"); @@ -160,18 +162,22 @@ void Renderer::InputUpdate(double dt) glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); if (glfwGetMouseButton(m_Window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) { glm::vec3 data = GetClickedPixelData(mousePosX, m_Resolution.Height - mousePosY); - glm::vec2 pixelData = glm::vec2(data); - float depthData = data.z; - printf("R: %f, G: %f, Depth: %f\n", pixelData.r, pixelData.g, depthData); + glm::vec2 color = glm::vec2(data); + float depth = data.z; + + glm::vec3 viewPos = ScreenCoordsToWorldPos(glm::vec2(mousePosX, m_Resolution.Height - mousePosY), depth); + // glm::vec3 worldPos = glm::vec3(glm::inverse(m_Camera->ViewMatrix()) * glm::vec4(viewPos, 1.f)); + + //printf("R: %f, G: %f, Depth: %f\n", color.r, color.g, depth); + printf("view: x: %f, y: %f z: %f, Length: %f\n", viewPos.x, viewPos.y, viewPos.z, glm::length(viewPos)); - if (pixelData != glm::vec2(0, 0)) { - const Model* pickModel = m_PickingColorsToModels[pixelData]; + if (color != glm::vec2(0, 0)) { + const Model* pickModel = m_PickingColorsToModels[color]; } } - if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { @@ -194,6 +200,33 @@ void Renderer::InputUpdate(double dt) m_Camera->SetPosition(m_Position); } + +// Utility functions should be moved to a better place +glm::vec3 Renderer::ScreenCoordsToWorldPos(glm::vec2 screenCoord, float depth) +{ + glm::vec4 pos; + float near = m_Camera->NearClip(); + float far = m_Camera->FarClip(); + + glm::vec3 ndc; + ndc.x = screenCoord.x / m_Resolution.Width; + ndc.y = screenCoord.y / m_Resolution.Height; + glm::vec4 clipSpace = glm::vec4(glm::vec2(ndc.x, ndc.y) * 2.0f - 1.0f, (depth) * 2.0f - 1.0f, 1.0f); + + glm::vec4 EyeSpace = glm::inverse(m_Camera->ProjectionMatrix()) * clipSpace; + glm::vec4 WorldSpace = glm::inverse(m_Camera->ViewMatrix()) * EyeSpace; + WorldSpace = glm::vec4(glm::vec3(WorldSpace) / WorldSpace.w, 1.f); + + return glm::vec3(WorldSpace); + +} + + +//EntityID Renderer::ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth) +//{ +// +//} + void Renderer::Update(double dt) { InputUpdate(dt); @@ -204,6 +237,7 @@ void Renderer::Draw(RenderQueueCollection& rq) //TODO: Renderer: Kanske borde vara längst upp i update. PickingPass(); DrawScreenQuad(m_PickingTexture); + //DrawScreenQuad(m_DepthBuffer); //DrawScene(rq); glfwSwapBuffers(m_Window); } From 64aa3a1064bf44fcef5264f73d316f47b8934df2 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 3 Dec 2015 15:02:14 +0100 Subject: [PATCH 09/12] rendering/util now added to CMakeLists.txt --- src/Engine/CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 861573a3..15d6b072 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -48,7 +48,13 @@ file(GLOB SOURCE_FILES_Rendering "${INCLUDE_PATH}/Rendering/*.h" "Rendering/*.cpp" ) +file(GLOB SOURCE_FILES_Rendering_Util + "${INCLUDE_PATH}/Rendering/Util/*.h" + "Rendering/Util/*.cpp" +) + source_group(Rendering FILES ${SOURCE_FILES_Rendering}) +source_group(Rendering\\Util FILES ${SOURCE_FILES_Rendering_Util}) file(GLOB SOURCE_FILES_GUI "${INCLUDE_PATH}/GUI/*.h" @@ -62,6 +68,7 @@ set(SOURCE_FILES #${SOURCE_FILES_Input} ${SOURCE_FILES_GUI} ${SOURCE_FILES_Rendering} + ${SOURCE_FILES_Rendering_Util} ) set(LIBRARIES From 4dc658ff65a2eab463e153e1356c75c6e0cdb000 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 3 Dec 2015 16:33:05 +0100 Subject: [PATCH 10/12] fixup! Added 3D picking of models to renderer --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index a08447dd..f800ba07 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit a08447ddb3aaf9ebdc7e18979291567a7032b6a2 +Subproject commit f800ba07f17fd9b65905971989e01e244239c48f From 6a24ed534a6956e9418f51fd226d34729d689069 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 3 Dec 2015 16:43:08 +0100 Subject: [PATCH 11/12] fixup! fixup! Added 3D picking of models to renderer --- assets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets b/assets index f800ba07..4bd902b6 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit f800ba07f17fd9b65905971989e01e244239c48f +Subproject commit 4bd902b697b8eef063da800102e6e9c3b29353eb From 1c06c06816b952710eff48c222fea19d30676121 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 3 Dec 2015 18:14:52 +0100 Subject: [PATCH 12/12] Added a ScreenCoords class with some util functions to clean up the Renderer class. --- include/Engine/Rendering/IRenderer.h | 1 + include/Engine/Rendering/Renderer.h | 8 +-- include/Engine/Rendering/Util/ScreenCoords.h | 29 +++++++++++ src/Engine/Rendering/Renderer.cpp | 51 ++------------------ src/Engine/Rendering/Util/ScreenCoords.cpp | 50 +++++++++++++++++++ 5 files changed, 85 insertions(+), 54 deletions(-) create mode 100644 include/Engine/Rendering/Util/ScreenCoords.h create mode 100644 src/Engine/Rendering/Util/ScreenCoords.cpp diff --git a/include/Engine/Rendering/IRenderer.h b/include/Engine/Rendering/IRenderer.h index 1b6d945c..1acb2454 100644 --- a/include/Engine/Rendering/IRenderer.h +++ b/include/Engine/Rendering/IRenderer.h @@ -5,6 +5,7 @@ #include "../OpenGL.h" #include "../GLM.h" #include "../Core/Util/Rectangle.h" +#include "Util/ScreenCoords.h" #include "Camera.h" #include "RenderQueue.h" #include "Model.h" diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 6fb0b10f..24dcb74b 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -44,19 +44,15 @@ private: void InitializeShaders(); void InitializeTextures(); void InitializeFrameBuffers(); - //TODO: Render: Remove ModelsToDraw from Renderer. + //TODO: Renderer: Remove ModelsToDraw from Renderer. void ModelsToDraw(); + //TODO: Renderer: Get EnqueueModel and InputUpdate out of renderer void EnqueueModel(Model* model); void InputUpdate(double dt); void PickingPass(); void DrawScreenQuad(GLuint textureToDraw); - glm::vec3 GetClickedPixelData(float x, float y); void DrawScene(RenderQueueCollection& rq); - //--------------------Utility functions----------------// - glm::vec3 ScreenCoordsToWorldPos(glm::vec2 screenCoord, float depth); - //EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth); - //--------------------ShaderPrograms-------------------// ShaderProgram m_BasicForwardProgram; ShaderProgram m_PickingProgram; diff --git a/include/Engine/Rendering/Util/ScreenCoords.h b/include/Engine/Rendering/Util/ScreenCoords.h new file mode 100644 index 00000000..51ad1051 --- /dev/null +++ b/include/Engine/Rendering/Util/ScreenCoords.h @@ -0,0 +1,29 @@ +#ifndef ScreenCoords_h__ +#define ScreenCoords_h__ + +#include "../../Common.h" +#include "../../OpenGL.h" +#include "../../GLM.h" +#include "../../Core/Util/Rectangle.h" + +class ScreenCoords +{ +public: + ScreenCoords() = delete; + //Return world position from given screenspace coordinates and depth value in viewspace. + static glm::vec3 ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat); + static glm::vec3 ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat); + static glm::vec3 ToWorldPos(glm::vec2 screenCoord, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat); + 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); + //Return EntityID of the clicked coordinate in given screenspace coordinates. + //EntityID ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth); + +private: + +}; + +#endif \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index bbaab41e..5a9fcba3 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -161,16 +161,15 @@ 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 = GetClickedPixelData(mousePosX, m_Resolution.Height - mousePosY); + glm::vec3 data = ScreenCoords::ToPixelData(mousePosX, m_Resolution.Height - mousePosY, m_PickingBuffer, m_DepthBuffer); glm::vec2 color = glm::vec2(data); float depth = data.z; - glm::vec3 viewPos = ScreenCoordsToWorldPos(glm::vec2(mousePosX, m_Resolution.Height - mousePosY), depth); + glm::vec3 viewPos = ScreenCoords::ToWorldPos(mousePosX, m_Resolution.Height - mousePosY, depth, m_Resolution, m_Camera->ProjectionMatrix(), m_Camera->ViewMatrix()); // glm::vec3 worldPos = glm::vec3(glm::inverse(m_Camera->ViewMatrix()) * glm::vec4(viewPos, 1.f)); //printf("R: %f, G: %f, Depth: %f\n", color.r, color.g, depth); - printf("view: x: %f, y: %f z: %f, Length: %f\n", viewPos.x, viewPos.y, viewPos.z, glm::length(viewPos)); - + //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]; @@ -200,33 +199,6 @@ void Renderer::InputUpdate(double dt) m_Camera->SetPosition(m_Position); } - -// Utility functions should be moved to a better place -glm::vec3 Renderer::ScreenCoordsToWorldPos(glm::vec2 screenCoord, float depth) -{ - glm::vec4 pos; - float near = m_Camera->NearClip(); - float far = m_Camera->FarClip(); - - glm::vec3 ndc; - ndc.x = screenCoord.x / m_Resolution.Width; - ndc.y = screenCoord.y / m_Resolution.Height; - glm::vec4 clipSpace = glm::vec4(glm::vec2(ndc.x, ndc.y) * 2.0f - 1.0f, (depth) * 2.0f - 1.0f, 1.0f); - - glm::vec4 EyeSpace = glm::inverse(m_Camera->ProjectionMatrix()) * clipSpace; - glm::vec4 WorldSpace = glm::inverse(m_Camera->ViewMatrix()) * EyeSpace; - WorldSpace = glm::vec4(glm::vec3(WorldSpace) / WorldSpace.w, 1.f); - - return glm::vec3(WorldSpace); - -} - - -//EntityID Renderer::ScreenCoordsToEntityID(glm::vec2 screenCoord, float depth) -//{ -// -//} - void Renderer::Update(double dt) { InputUpdate(dt); @@ -352,23 +324,6 @@ void Renderer::DrawScreenQuad(GLuint textureToDraw) } - -// Will return a vec3 where RG is the PickColor and B is the Depth -glm::vec3 Renderer::GetClickedPixelData(float x, float y) -{ - glBindFramebuffer(GL_FRAMEBUFFER, m_PickingBuffer); - glm::vec2 pixelData; - glReadPixels(x, y, 1, 1, GL_RG, GL_FLOAT, &pixelData); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - glBindFramebuffer(GL_FRAMEBUFFER, m_DepthBuffer); - float depthData; - glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - return glm::vec3(pixelData, depthData); -} - void Renderer::InitializeTextures() { m_ErrorTexture=ResourceManager::Load("Textures/Core/ErrorTexture.png"); diff --git a/src/Engine/Rendering/Util/ScreenCoords.cpp b/src/Engine/Rendering/Util/ScreenCoords.cpp new file mode 100644 index 00000000..103e576c --- /dev/null +++ b/src/Engine/Rendering/Util/ScreenCoords.cpp @@ -0,0 +1,50 @@ +#include "Rendering/Util/ScreenCoords.h" + +glm::vec3 ScreenCoords::ToWorldPos(float x, float y, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat) +{ + glm::vec3 ndc; + ndc.x = (x / screenWidth)*2.f - 1.f; + ndc.y = (y / screenHeight)*2.f - 1.f; + ndc.z = depth*2.f - 1.f; + glm::vec4 clipSpace = glm::vec4(ndc, 1.0f); + glm::vec4 EyeSpace = glm::inverse(cameraProjectionMat) * clipSpace; + glm::vec4 WorldSpace = glm::inverse(cameraViewMat) * EyeSpace; + WorldSpace = glm::vec4(glm::vec3(WorldSpace) / WorldSpace.w, 1.f); + + return glm::vec3(WorldSpace); +} + +glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat) +{ + return ToWorldPos(screenCoord.x, screenCoord.y, depth, resolution.Width, resolution.Height, cameraProjectionMat, cameraViewMat); +} + +glm::vec3 ScreenCoords::ToWorldPos(float x, float y, float depth, Rectangle resolution, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat) +{ + return ToWorldPos(x, y, depth, resolution.Width, resolution.Height, cameraProjectionMat, cameraViewMat); +} + +glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, float screenWidth, float screenHeight, glm::mat4 cameraProjectionMat, glm::mat4 cameraViewMat) +{ + return ToWorldPos(screenCoord.x, screenCoord.y, depth, screenWidth, screenHeight, cameraProjectionMat, cameraViewMat); +} + +glm::vec3 ScreenCoords::ToPixelData(float x, float y, GLuint PickDataBuffer, GLuint DepthBuffer) +{ + glBindFramebuffer(GL_FRAMEBUFFER, PickDataBuffer); + glm::vec2 pixelData; + glReadPixels(x, y, 1, 1, GL_RG, GL_FLOAT, &pixelData); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer); + float depthData; + glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + return glm::vec3(pixelData, depthData); +} + +glm::vec3 ScreenCoords::ToPixelData(glm::vec2 screenCoord, GLuint PickDataBuffer, GLuint DepthBuffer) +{ + return ToPixelData(screenCoord.x, screenCoord.y, PickDataBuffer, DepthBuffer); +}