From eb9c217eb4dcea8118f9878e34a5e4553ed82a2d Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 9 Dec 2015 10:44:06 +0100 Subject: [PATCH 01/65] 3D picking float value error fixed. --- include/Engine/Rendering/Util/ScreenCoords.h | 11 +++- resources/Shaders/Picking.frag.glsl | 2 +- src/Engine/Rendering/Renderer.cpp | 53 +++++++++++++------- src/Engine/Rendering/Util/ScreenCoords.cpp | 18 +++++-- 4 files changed, 58 insertions(+), 26 deletions(-) diff --git a/include/Engine/Rendering/Util/ScreenCoords.h b/include/Engine/Rendering/Util/ScreenCoords.h index 22c5b9e0..92e92bdc 100644 --- a/include/Engine/Rendering/Util/ScreenCoords.h +++ b/include/Engine/Rendering/Util/ScreenCoords.h @@ -11,6 +11,13 @@ class ScreenCoords { public: ScreenCoords() = delete; + + struct PixelData + { + int Color[2]; + float Depth; + }; + //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); @@ -18,8 +25,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, FrameBuffer* PickDataBuffer, GLuint DepthBuffer); - static glm::vec3 ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer); + static PixelData ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer); + static PixelData 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/resources/Shaders/Picking.frag.glsl b/resources/Shaders/Picking.frag.glsl index 11f529b0..8c95ead3 100644 --- a/resources/Shaders/Picking.frag.glsl +++ b/resources/Shaders/Picking.frag.glsl @@ -13,7 +13,7 @@ out vec4 TextureFragment; void main() { - TextureFragment = vec4(PickingColor, 0, 1); + TextureFragment = vec4(PickingColor/255, 0, 1); } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index f39580b7..aba512fd 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -117,21 +117,24 @@ 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::vec2 color = glm::vec2(data); - float depth = data.z; + ScreenCoords::PixelData data = ScreenCoords::ToPixelData(mousePosX, m_Resolution.Height - mousePosY, &m_PickingBuffer, m_DepthBuffer); - glm::vec3 viewPos = ScreenCoords::ToWorldPos(mousePosX, m_Resolution.Height - mousePosY, depth, m_Resolution, m_Camera->ProjectionMatrix(), m_Camera->ViewMatrix()); + glm::vec3 viewPos = ScreenCoords::ToWorldPos(mousePosX, m_Resolution.Height - mousePosY, data.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("R: %f, G: %f, Depth: %f\n", data.Color[0], data.Color[1], data.Depth); //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)) { - EntityID pickedEntity = m_PickingColorsToEntity[color]; - printf("Picked Entity: %i", pickedEntity); - - } + //printf("\n\n---------------------------\n"); + auto got = m_PickingColorsToEntity.find(glm::vec2(data.Color[0], data.Color[1])); + if (got == m_PickingColorsToEntity.end()) + printf("Color (R:%f, G:%f) not found.\n", data.Color[0], data.Color[1]); + else + printf("R:%f G:%f, EntityID: %i\n", got->first.r, got->first.g, got->second); + //printf("----\n"); + //for (auto i : m_PickingColorsToEntity) { + // printf("Entity: %i, Color: R: %f, G: %f\n", i.second, i.first.r, i.first.g); + //} + //printf("---------------------------\n\n"); } if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { @@ -213,10 +216,12 @@ void Renderer::DrawScene(RenderQueueCollection& rq) continue; } } + GLERROR("DrawScene Error"); } void Renderer::PickingPass(RenderQueueCollection& rq) { + m_PickingColorsToEntity.clear(); m_PickingBuffer.Bind(); glEnable(GL_DEPTH_TEST); @@ -225,7 +230,7 @@ void Renderer::PickingPass(RenderQueueCollection& rq) glClearColor(0.f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - int r = 30; + int r = 1; int g = 0; //TODO: Render: Add code for more jobs than modeljobs. @@ -237,8 +242,18 @@ void Renderer::PickingPass(RenderQueueCollection& rq) auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { - glm::vec2 pickColor = glm::vec2(r/255.f, g/255.f); - m_PickingColorsToEntity[pickColor] = modelJob->Entity; + //--------------- + //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. + //--------------- + int pickColor[2] = { r, g }; + for (auto i : m_PickingColorsToEntity) { + if(modelJob->Entity == i.second) { + pickColor[0] = i.first.x; + pickColor[1] = i.first.y; + r -= 1; + } + } + m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity; //Render picking stuff @@ -246,19 +261,21 @@ void Renderer::PickingPass(RenderQueueCollection& rq) 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)); + 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, 0, modelJob->StartIndex); - r+=50; + r += 1; if(r > 255) { r = 0; - g+=50; + g += 1; } } } m_PickingBuffer.Unbind(); + GLERROR("PickingPass Error"); + } @@ -300,7 +317,7 @@ void Renderer::InitializeTextures() */ GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, - glm::vec2(m_Resolution.Width, m_Resolution.Height), GL_RG8, GL_RG, GL_FLOAT); + glm::vec2(m_Resolution.Width, m_Resolution.Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE); } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) diff --git a/src/Engine/Rendering/Util/ScreenCoords.cpp b/src/Engine/Rendering/Util/ScreenCoords.cpp index aad94d67..e999c895 100644 --- a/src/Engine/Rendering/Util/ScreenCoords.cpp +++ b/src/Engine/Rendering/Util/ScreenCoords.cpp @@ -29,22 +29,30 @@ 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, FrameBuffer* PickDataBuffer, GLuint DepthBuffer) +ScreenCoords::PixelData ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer) { PickDataBuffer->Bind(); - glm::vec2 pixelData; - glReadPixels(x, y, 1, 1, GL_RG, GL_FLOAT, &pixelData); + unsigned char pdata[2]; + glReadPixels(x, y, 1, 1, GL_RG, GL_UNSIGNED_BYTE, &pdata); PickDataBuffer->Unbind(); + 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); + PixelData p; + p.Color[0] = (int)pdata[0]; + p.Color[1] = (int)pdata[1]; + p.Depth = depthData; + + GLERROR("ScreenCoords::ToPixelData Error"); + + return p; } -glm::vec3 ScreenCoords::ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer) +ScreenCoords::PixelData ScreenCoords::ToPixelData(glm::vec2 screenCoord, FrameBuffer* PickDataBuffer, GLuint DepthBuffer) { return ToPixelData(screenCoord.x, screenCoord.y, PickDataBuffer, DepthBuffer); } From 393a7741401e64558bbe4a5962281f4009b41940 Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 9 Dec 2015 14:50:39 +0100 Subject: [PATCH 02/65] Framework for Forward+ renderer, Buggy. --- include/Engine/Rendering/Renderer.h | 86 ++++++++++++++--- resources/Shaders/GridFrustum.comp.glsl | 118 ++++++++++++++++++++++++ resources/Shaders/cullLights.comp.glsl | 71 ++++++++++++++ src/Engine/Rendering/Renderer.cpp | 97 +++++++++++++++++-- 4 files changed, 354 insertions(+), 18 deletions(-) create mode 100644 resources/Shaders/GridFrustum.comp.glsl create mode 100644 resources/Shaders/cullLights.comp.glsl diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index b1b76468..b227f110 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -11,18 +11,30 @@ #include "FrameBuffer.h" #include "../Core/World.h" +#define TILE_SIZE 16 +#define NUM_LIGHTS 3 + + +enum lightType +{ + Point, + Spot, + Directional, + Area +}; + class Renderer : public IRenderer { public: - virtual void Initialize() override; - virtual void Update(double dt) override; - virtual void Draw(RenderQueueCollection& rq) override; + virtual void Initialize() override; + virtual void Update(double dt) override; + virtual void Draw(RenderQueueCollection& rq) override; private: - //----------------------Variables----------------------// - Texture* m_ErrorTexture; - Texture* m_WhiteTexture; - float m_CameraMoveSpeed; + //----------------------Variables----------------------// + Texture* m_ErrorTexture; + Texture* m_WhiteTexture; + float m_CameraMoveSpeed; FrameBuffer m_PickingBuffer; GLuint m_PickingTexture; GLuint m_DepthBuffer; @@ -32,26 +44,76 @@ private: Model* m_UnitSphere; - + std::unordered_map m_PickingColorsToEntity; - //----------------------Functions----------------------// - void InitializeWindow(); - void InitializeShaders(); + //----------------------Functions----------------------// + void InitializeWindow(); + void InitializeShaders(); void InitializeTextures(); void InitializeFrameBuffers(); + void InitializeSSBOs(); //TODO: Renderer: Get InputUpdate out of renderer - void InputUpdate(double dt); + void InputUpdate(double dt); void PickingPass(RenderQueueCollection& rq); void DrawScreenQuad(GLuint textureToDraw); void DrawScene(RenderQueueCollection& rq); + //----------------------Forward+-----------------------// + void CalculateFrustum(); + void CullLights(); + //Frustum + struct Plane + { + glm::vec3 Normal; + float d; + }; + + struct Frustum + { + Plane plane[4]; + }; + Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution + + //Lights + void TEMPCreateLights(); + //TODO: Renderer: Add Directionllights, spotlights and area lights to this as type. + struct PointLight { + glm::vec4 Position = glm::vec4(0.f); + glm::vec4 Color = glm::vec4(1.f); + float Radius = 5.f; + float Intensity = 0.8f; + float Falloff = 0.3f; + float Padding = 1337; + }; + PointLight m_PointLights[NUM_LIGHTS]; + + struct LightGrid { + int Amount; + int Start; + glm::vec2 Padding; + }; + LightGrid m_LightGrid[80*45]; + + int m_LightOffset = 0; + + int m_LightIndex[80*45*200]; + + //-------------------------SSBO------------------------// + GLuint m_FrustumSSBO; + GLuint m_LightSSBO; + GLuint m_LightGridSSBO; + GLuint m_LightOffsetSSBO; + GLuint m_LightIndexSSBO; void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); //--------------------ShaderPrograms-------------------// ShaderProgram m_BasicForwardProgram; ShaderProgram m_PickingProgram; ShaderProgram m_DrawScreenQuadProgram; + ShaderProgram m_CalculateFrustumProgram; + ShaderProgram m_LightCullProgram; + }; #endif \ No newline at end of file diff --git a/resources/Shaders/GridFrustum.comp.glsl b/resources/Shaders/GridFrustum.comp.glsl new file mode 100644 index 00000000..64f4d467 --- /dev/null +++ b/resources/Shaders/GridFrustum.comp.glsl @@ -0,0 +1,118 @@ +#version 430 + +#define TILE_SIZE 16 +#define NUM_TILES 3600 + +uniform mat4 P; +uniform vec2 ScreenDimensions; + +struct Plane { + vec3 Normal; + float d; +}; +struct Frustum { + Plane Planes[4]; +}; + +layout (std430, binding = 1) buffer FrustumBuffer +{ + Frustum Data[80*45]; +} Frustums; + + +struct PlaneNormals { + vec3 Normal1; + float pad1; + vec3 Normal2; + float Pad2; +}; + +struct FrustumNormals { + PlaneNormals Planes[4]; +}; + +layout (std430, binding = 2) buffer PlaneNormalBuffer +{ + FrustumNormals Data[80*45]; +} FrustumNorm; + + +vec4 ConvertToView(vec4 ScreenCoords) +{ + vec2 normalizedScreenCoords = ScreenCoords.xy / ScreenDimensions; + vec4 clipSpace = vec4( vec2(normalizedScreenCoords.x, normalizedScreenCoords.y) * 2.0 - 1.0, ScreenCoords.z, ScreenCoords.w); + vec4 view = inverse(P) * clipSpace; + view = view / view.w; + return view; +} + +Plane ComputePlane( vec3 p0, vec3 p1, vec3 p2 ) +{ + Plane plane; + + vec3 v0 = p1 - p0; + vec3 v2 = p2 - p0; + + plane.Normal = normalize( cross( v0, v2 ) ); + plane.d = dot( vec3(plane.Normal), p0 ); // Always 0 probably + return plane; +} + +layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; +void main () +{ + if(gl_GlobalInvocationID.x * TILE_SIZE < ScreenDimensions.x && gl_GlobalInvocationID.y * TILE_SIZE < ScreenDimensions.y) { + //Top-Left = 0 | Top-Right = 1 + //Bottom-Left = 2 | Bottom-Right = 3 + vec4 ScreenCoords[4]; + ScreenCoords[0] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y + 1 ) * TILE_SIZE, -1.0, 1.0); // Z-axis might need to be 1 + ScreenCoords[1] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y + 1) * TILE_SIZE, -1.0, 1.0); + ScreenCoords[2] = vec4(gl_GlobalInvocationID.x * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0); + ScreenCoords[3] = vec4((gl_GlobalInvocationID.x + 1) * TILE_SIZE, (gl_GlobalInvocationID.y) * TILE_SIZE, -1.0, 1.0); + + vec3 ViewVectors[4]; + for(int i = 0; i < 4; i++) { + ViewVectors[i] = vec3(ConvertToView(ScreenCoords[i])); + } + + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[0].Normal1 = (ViewVectors[2]); + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[0].Normal2 = (ViewVectors[0]); + + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[1].Normal1 = (ViewVectors[1]); + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[1].Normal2 = (ViewVectors[3]); + + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[2].Normal1 = (ViewVectors[0]); + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[2].Normal2 = (ViewVectors[1]); + + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[3].Normal1 = (ViewVectors[3]); + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[3].Normal2 = (ViewVectors[2]); + /* + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[0].Normal1 = vec3(ScreenCoords[2]); + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[0].Normal2 = vec3(ScreenCoords[0]); + + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[1].Normal1 = vec3(ScreenCoords[1]); + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[1].Normal2 = vec3(ScreenCoords[3]); + + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[2].Normal1 = vec3(ScreenCoords[0]); + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[2].Normal2 = vec3(ScreenCoords[1]); + + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[3].Normal1 = vec3(ScreenCoords[3]); + FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[3].Normal2 = vec3(ScreenCoords[2]); + +*/ + + + vec3 EyePos = vec3(0,0,0); + + Frustum f; + f.Planes[0] = ComputePlane(EyePos, ViewVectors[2], ViewVectors[0]); + f.Planes[1] = ComputePlane(EyePos, ViewVectors[1], ViewVectors[3]); + f.Planes[2] = ComputePlane(EyePos, ViewVectors[0], ViewVectors[1]); + f.Planes[3] = ComputePlane(EyePos, ViewVectors[3], ViewVectors[2]); + + + + + Frustums.Data[gl_GlobalInvocationID.x + gl_GlobalInvocationID.y*80] = f; + } +} \ No newline at end of file diff --git a/resources/Shaders/cullLights.comp.glsl b/resources/Shaders/cullLights.comp.glsl new file mode 100644 index 00000000..72d36ec1 --- /dev/null +++ b/resources/Shaders/cullLights.comp.glsl @@ -0,0 +1,71 @@ +#version 430 + +//in uvec3 gl_NumWorkGroups; +//in uvec3 gl_WorkGroupID; +//in uvec3 gl_LocalInvocationID; +//in uvec3 gl_GlobalInvocationID; +//in uint gl_LocalInvocationIndex; + +#define NUM_LIGHTS 3 +#define MAX_LIGHTS_PER_TILE 200 +#define NUM_TILES 3600 + +struct PointLight { + vec4 Position; + vec4 Color; + float Radius; + float Intensity; + vec2 Pad; +}; + +layout (std430, binding = 0) buffer PointLightBuffer +{ + PointLight PointLights[NUM_LIGHTS]; +}; + +struct Plane { + vec3 Normal; + float d; +}; + +struct Frustum { + Plane Planes[4]; +}; + +layout (std430, binding = 1) buffer FrustumBuffer +{ + Frustum Frustums[80*45]; +}; + +layout (std430, binding = 3) buffer LightIndexBuffer +{ + float LightIndexList[MAX_LIGHTS_PER_TILE*NUM_TILES]; +}; + +struct LightGrid +{ + int Amount; + int Start; + vec2 padding; +}; + +layout (std430, binding = 4) buffer LightGridBuffer +{ + LightGrid LightGrids[NUM_TILES]; +}; + +layout (std430, binding = 5) buffer LightOffsetCounter +{ + int GlobalLightOffsetCounter; +}; + + +layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; +void main () +{ + if(gl_LocalInvocationIndex == 0) { + LightIndexList[int(gl_WorkGroupID.x) + int(gl_WorkGroupID.y)*80] = int(gl_WorkGroupID.x); + } + + +} \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index aba512fd..36f260c5 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -10,11 +10,17 @@ void Renderer::Initialize() if (m_Camera == nullptr) { m_Camera = m_DefaultCamera; } + TEMPCreateLights(); glfwSwapInterval(m_VSYNC); InitializeShaders(); InitializeTextures(); InitializeFrameBuffers(); + InitializeSSBOs(); + CalculateFrustum(); + + + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); @@ -80,6 +86,13 @@ void Renderer::InitializeShaders() m_DrawScreenQuadProgram.Compile(); m_DrawScreenQuadProgram.Link(); + m_CalculateFrustumProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/GridFrustum.comp.glsl"))); + m_CalculateFrustumProgram.Compile(); + m_CalculateFrustumProgram.Link(); + + m_CalculateFrustumProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); + m_CalculateFrustumProgram.Compile(); + m_CalculateFrustumProgram.Link(); } void Renderer::InputUpdate(double dt) @@ -169,7 +182,8 @@ void Renderer::Draw(RenderQueueCollection& rq) { //TODO: Renderer: Kanske borde vara längst upp i update. PickingPass(rq); - DrawScreenQuad(m_PickingTexture); + //DrawScreenQuad(m_PickingTexture); + //CullLights(); DrawScene(rq); glfwSwapBuffers(m_Window); @@ -278,7 +292,6 @@ void Renderer::PickingPass(RenderQueueCollection& rq) } - void Renderer::DrawScreenQuad(GLuint textureToDraw) { glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -300,7 +313,6 @@ void Renderer::DrawScreenQuad(GLuint textureToDraw) , GL_UNSIGNED_INT, 0, m_ScreenQuad->TextureGroups[0].StartIndex); } - void Renderer::InitializeTextures() { m_ErrorTexture=ResourceManager::Load("Textures/Core/ErrorTexture.png"); @@ -332,8 +344,6 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin GLERROR("Texture initialization failed"); } - - void Renderer::InitializeFrameBuffers()//TODO: Renderer: Get this to a better location, as its really big { glGenRenderbuffers(1, &m_DepthBuffer); @@ -343,4 +353,79 @@ void Renderer::InitializeFrameBuffers()//TODO: Renderer: Get this to a better lo 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 +} + +void Renderer::InitializeSSBOs() +{ + glGenBuffers(1, &m_FrustumSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_Frustums), &m_Frustums, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + GLERROR("m_FrustumSSBO"); + + glGenBuffers(1, &m_LightSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_PointLights), &m_PointLights, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + GLERROR("m_LightSSBO"); + + + glGenBuffers(1, &m_LightGridSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightGrid), &m_LightGrid, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + GLERROR("m_LightGridSSBO"); + + + glGenBuffers(1, &m_LightOffsetSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + GLERROR("m_LightOffsetSSBO"); + + + glGenBuffers(1, &m_LightIndexSSBO); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightIndex), &m_LightIndex, GL_DYNAMIC_COPY); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + + GLERROR("m_LightIndexSSBO"); + +} + +void Renderer::CalculateFrustum() +{ + m_CalculateFrustumProgram.Bind(); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); + glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram.GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix())); + glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram.GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height); + glDispatchCompute(m_Resolution.Width / TILE_SIZE, m_Resolution.Height / TILE_SIZE, 1); + GLERROR("CalculateFrustum Error"); + +} + +void Renderer::TEMPCreateLights() +{ + for (int i = 0; i < NUM_LIGHTS; i++) { + m_PointLights[i].Position = glm::vec4(i, 0.f, 0.f, 0.f); + m_PointLights[i].Color = glm::vec4(1.f, 0.5f, 0.f + i*0.1f, 1.f); + } +} + +void Renderer::CullLights() +{ + m_LightCullProgram.Bind(); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO); + glDispatchCompute(m_Resolution.Width / TILE_SIZE, m_Resolution.Height / TILE_SIZE, 1); + GLERROR("CullLights Error"); + +} + From de6e74c0b18c4b78d8ae259483038908e7ec8ef0 Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 9 Dec 2015 17:36:03 +0100 Subject: [PATCH 03/65] Forward+ Debugging commit, dont try it. --- include/Engine/Rendering/Renderer.h | 19 ++++------ resources/Shaders/GridFrustum.comp.glsl | 49 +------------------------ resources/Shaders/cullLights.comp.glsl | 48 +++--------------------- src/Engine/Rendering/Renderer.cpp | 22 ++++++++--- 4 files changed, 33 insertions(+), 105 deletions(-) diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index b227f110..b0ddf870 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -63,15 +63,12 @@ private: void CalculateFrustum(); void CullLights(); //Frustum - struct Plane - { + struct Plane { glm::vec3 Normal; float d; }; - - struct Frustum - { - Plane plane[4]; + struct Frustum { + Plane Planes[4]; }; Frustum m_Frustums[80*45]; //TODO: Renderer: Make this change with resolution @@ -100,11 +97,11 @@ private: int m_LightIndex[80*45*200]; //-------------------------SSBO------------------------// - GLuint m_FrustumSSBO; - GLuint m_LightSSBO; - GLuint m_LightGridSSBO; - GLuint m_LightOffsetSSBO; - GLuint m_LightIndexSSBO; + GLuint m_FrustumSSBO = 0; + GLuint m_LightSSBO = 1; + GLuint m_LightGridSSBO = 2; + GLuint m_LightOffsetSSBO = 3; + GLuint m_LightIndexSSBO = 4; void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); //--------------------ShaderPrograms-------------------// diff --git a/resources/Shaders/GridFrustum.comp.glsl b/resources/Shaders/GridFrustum.comp.glsl index 64f4d467..27559370 100644 --- a/resources/Shaders/GridFrustum.comp.glsl +++ b/resources/Shaders/GridFrustum.comp.glsl @@ -14,29 +14,11 @@ struct Frustum { Plane Planes[4]; }; -layout (std430, binding = 1) buffer FrustumBuffer +layout (std430, binding = 0) buffer FrustumBuffer { - Frustum Data[80*45]; + Frustum Data[3600]; } Frustums; - -struct PlaneNormals { - vec3 Normal1; - float pad1; - vec3 Normal2; - float Pad2; -}; - -struct FrustumNormals { - PlaneNormals Planes[4]; -}; - -layout (std430, binding = 2) buffer PlaneNormalBuffer -{ - FrustumNormals Data[80*45]; -} FrustumNorm; - - vec4 ConvertToView(vec4 ScreenCoords) { vec2 normalizedScreenCoords = ScreenCoords.xy / ScreenDimensions; @@ -75,33 +57,6 @@ void main () ViewVectors[i] = vec3(ConvertToView(ScreenCoords[i])); } - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[0].Normal1 = (ViewVectors[2]); - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[0].Normal2 = (ViewVectors[0]); - - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[1].Normal1 = (ViewVectors[1]); - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[1].Normal2 = (ViewVectors[3]); - - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[2].Normal1 = (ViewVectors[0]); - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[2].Normal2 = (ViewVectors[1]); - - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[3].Normal1 = (ViewVectors[3]); - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[3].Normal2 = (ViewVectors[2]); - /* - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[0].Normal1 = vec3(ScreenCoords[2]); - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[0].Normal2 = vec3(ScreenCoords[0]); - - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[1].Normal1 = vec3(ScreenCoords[1]); - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[1].Normal2 = vec3(ScreenCoords[3]); - - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[2].Normal1 = vec3(ScreenCoords[0]); - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[2].Normal2 = vec3(ScreenCoords[1]); - - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[3].Normal1 = vec3(ScreenCoords[3]); - FrustumNorm.Data[gl_GlobalInvocationID.x + (80 * gl_GlobalInvocationID.y)].Planes[3].Normal2 = vec3(ScreenCoords[2]); - -*/ - - vec3 EyePos = vec3(0,0,0); Frustum f; diff --git a/resources/Shaders/cullLights.comp.glsl b/resources/Shaders/cullLights.comp.glsl index 72d36ec1..e9fa9a95 100644 --- a/resources/Shaders/cullLights.comp.glsl +++ b/resources/Shaders/cullLights.comp.glsl @@ -6,66 +6,30 @@ //in uvec3 gl_GlobalInvocationID; //in uint gl_LocalInvocationIndex; + + #define NUM_LIGHTS 3 #define MAX_LIGHTS_PER_TILE 200 #define NUM_TILES 3600 -struct PointLight { - vec4 Position; - vec4 Color; - float Radius; - float Intensity; - vec2 Pad; -}; - -layout (std430, binding = 0) buffer PointLightBuffer -{ - PointLight PointLights[NUM_LIGHTS]; -}; - struct Plane { vec3 Normal; float d; }; - struct Frustum { Plane Planes[4]; }; -layout (std430, binding = 1) buffer FrustumBuffer +layout (std430, binding = 0) buffer FrustumBuffer { - Frustum Frustums[80*45]; -}; + Frustum Data[3600]; +} Frustums; -layout (std430, binding = 3) buffer LightIndexBuffer -{ - float LightIndexList[MAX_LIGHTS_PER_TILE*NUM_TILES]; -}; - -struct LightGrid -{ - int Amount; - int Start; - vec2 padding; -}; - -layout (std430, binding = 4) buffer LightGridBuffer -{ - LightGrid LightGrids[NUM_TILES]; -}; - -layout (std430, binding = 5) buffer LightOffsetCounter -{ - int GlobalLightOffsetCounter; -}; layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; void main () { - if(gl_LocalInvocationIndex == 0) { - LightIndexList[int(gl_WorkGroupID.x) + int(gl_WorkGroupID.y)*80] = int(gl_WorkGroupID.x); + if(1 == 1) { } - - } \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 36f260c5..e9a35cba 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -90,9 +90,9 @@ void Renderer::InitializeShaders() m_CalculateFrustumProgram.Compile(); m_CalculateFrustumProgram.Link(); - m_CalculateFrustumProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); - m_CalculateFrustumProgram.Compile(); - m_CalculateFrustumProgram.Link(); + m_LightCullProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); + m_LightCullProgram.Compile(); + m_LightCullProgram.Link(); } void Renderer::InputUpdate(double dt) @@ -357,9 +357,11 @@ void Renderer::InitializeFrameBuffers()//TODO: Renderer: Get this to a better lo void Renderer::InitializeSSBOs() { + printf("Size: %i\n", sizeof(m_Frustums)); glGenBuffers(1, &m_FrustumSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_FrustumSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_Frustums), &m_Frustums, GL_DYNAMIC_COPY); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); GLERROR("m_FrustumSSBO"); @@ -367,6 +369,7 @@ void Renderer::InitializeSSBOs() glGenBuffers(1, &m_LightSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_PointLights), &m_PointLights, GL_DYNAMIC_COPY); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); GLERROR("m_LightSSBO"); @@ -375,6 +378,7 @@ void Renderer::InitializeSSBOs() glGenBuffers(1, &m_LightGridSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightGridSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightGrid), &m_LightGrid, GL_DYNAMIC_COPY); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); GLERROR("m_LightGridSSBO"); @@ -383,6 +387,7 @@ void Renderer::InitializeSSBOs() glGenBuffers(1, &m_LightOffsetSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightOffsetSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightOffset), &m_LightOffset, GL_DYNAMIC_COPY); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, m_LightOffsetSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); GLERROR("m_LightOffsetSSBO"); @@ -391,6 +396,7 @@ void Renderer::InitializeSSBOs() glGenBuffers(1, &m_LightIndexSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_LightIndexSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(m_LightIndex), &m_LightIndex, GL_DYNAMIC_COPY); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightIndexSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); GLERROR("m_LightIndexSSBO"); @@ -399,12 +405,18 @@ void Renderer::InitializeSSBOs() void Renderer::CalculateFrustum() { + GLERROR("CalculateFrustum Error-1"); m_CalculateFrustumProgram.Bind(); + + GLERROR("CalculateFrustum Error1"); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); + GLERROR("CalculateFrustum Error2"); glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram.GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix())); + GLERROR("CalculateFrustum Error3"); glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram.GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height); - glDispatchCompute(m_Resolution.Width / TILE_SIZE, m_Resolution.Height / TILE_SIZE, 1); - GLERROR("CalculateFrustum Error"); + GLERROR("CalculateFrustum Error4"); + glDispatchCompute(5, 3, 1); + GLERROR("CalculateFrustum Error5"); } From 9d3313e3ede581b485ed27febbd1cef0c53a9581 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 10 Dec 2015 10:46:27 +0100 Subject: [PATCH 04/65] Calculate frustrum removed from code untill Nvidia isn't shit. --- src/Engine/Rendering/Renderer.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index e9a35cba..c483cdc6 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -17,11 +17,7 @@ void Renderer::Initialize() InitializeTextures(); InitializeFrameBuffers(); InitializeSSBOs(); - CalculateFrustum(); - - - - + //CalculateFrustum(); m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); From 37cf42527b9de668c0e1e5834fa597423eb24bf4 Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 10 Dec 2015 16:03:48 +0100 Subject: [PATCH 05/65] RenderState class structure made. --- include/Engine/Rendering/RenderState.h | 22 +++++++ src/Engine/Rendering/RenderState.cpp | 81 ++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 include/Engine/Rendering/RenderState.h create mode 100644 src/Engine/Rendering/RenderState.cpp diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h new file mode 100644 index 00000000..76816308 --- /dev/null +++ b/include/Engine/Rendering/RenderState.h @@ -0,0 +1,22 @@ +#ifndef RenderState_h__ +#define RenderState_h__ + +#include "../Common.h" +#include "../OpenGL.h" +#include "../GLM.h" + +class RenderState +{ +public: + RenderState(); + ~RenderState(); + bool Enable(GLenum GLEnable); + bool CullFace(GLenum GlFaceToCull); + bool ClearColor(glm::vec4 color); + bool Clear(GLbitfield mask); +private: + std::vector m_Enables; + float m_preClearColor[4]; + GLenum m_preCullFace; +}; +#endif \ No newline at end of file diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp new file mode 100644 index 00000000..6844dbfd --- /dev/null +++ b/src/Engine/Rendering/RenderState.cpp @@ -0,0 +1,81 @@ +#include "Rendering/RenderState.h" + +RenderState::RenderState() +{ +} + +bool RenderState::Enable(GLenum GLEnable) +{ + if(glIsEnabled(GLEnable)) + { + LOG_WARNING("Trying to enable somthing that is already enabled."); + return false; + } + m_Enables.push_back(GLEnable); + glEnable(GLEnable); + if (GLERROR("RenderState::Enable")) + { + return false; + } + return true; +} + +bool RenderState::CullFace(GLenum GLCullFace) +{ + if(!glIsEnabled(GL_CULL_FACE)) + { + LOG_ERROR("Setting GL_CULL_FACE without enabling it."); + return false; + } + + GLint a; + glGetIntegerv(GL_CULL_FACE_MODE, &a); + if(a == GL_BACK) + { + LOG_INFO("Setting Cullface to back, unessesary since this is already default."); + } + m_preCullFace = a; + glCullFace(GLCullFace); + if (GLERROR("RenderState::CullFace")) + { + return false; + } + return true; +} + +bool RenderState::ClearColor(glm::vec4 color) +{ + glGetFloatv(GL_COLOR_CLEAR_VALUE, &m_preClearColor[0]); + glClearColor(color.r, color.g, color.b, color.a); + if (GLERROR("RenderState::ClearColor")) { + return false; + } + return true; +} + +bool RenderState::Clear(GLbitfield mask) +{ + glClear(mask); + if (GLERROR("RenderState::Clear")) { + return false; + } + return true; +} + +RenderState::~RenderState() +{ + //Set cullface to default + glCullFace(m_preCullFace); + + //Set color to default + glClearColor(m_preClearColor[0], m_preClearColor[1], m_preClearColor[2], m_preClearColor[3]); + + //Disable Enables + for (auto i : m_Enables) + { + glDisable(i); + } + + m_Enables.clear(); +} + From cefc4e525784370d34f868c695575c723b7f51cf Mon Sep 17 00:00:00 2001 From: Tleety Date: Thu, 10 Dec 2015 16:06:25 +0100 Subject: [PATCH 06/65] PickingPassState done. --- include/Engine/Rendering/PickingPassState.h | 15 +++++++++++++++ src/Engine/Rendering/PickingPassState.cpp | 14 ++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 include/Engine/Rendering/PickingPassState.h create mode 100644 src/Engine/Rendering/PickingPassState.cpp diff --git a/include/Engine/Rendering/PickingPassState.h b/include/Engine/Rendering/PickingPassState.h new file mode 100644 index 00000000..5902f9dc --- /dev/null +++ b/include/Engine/Rendering/PickingPassState.h @@ -0,0 +1,15 @@ +#ifndef PickingPassState_h__ +#define PickingPassState_h__ + +#include "Rendering/RenderState.h" + +class PickingPassState : public RenderState +{ +public: + PickingPassState(); + ~PickingPassState(); +private: + +}; + +#endif \ No newline at end of file diff --git a/src/Engine/Rendering/PickingPassState.cpp b/src/Engine/Rendering/PickingPassState.cpp new file mode 100644 index 00000000..9822c47e --- /dev/null +++ b/src/Engine/Rendering/PickingPassState.cpp @@ -0,0 +1,14 @@ +#include "Rendering/PickingPassState.h" + + +PickingPassState::PickingPassState() +{ + Enable(GL_DEPTH_TEST); + Enable(GL_CULL_FACE); + CullFace(GL_BACK); + + glm::vec4 clearColor = glm::vec4(0.f); + ClearColor(clearColor); + Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +} + From bb900c51105ed432e6c24ac4fae8a86b74049573 Mon Sep 17 00:00:00 2001 From: viktorljung Date: Thu, 10 Dec 2015 16:33:33 +0100 Subject: [PATCH 07/65] Added picking event --- include/Engine/Rendering/EPicking.h | 69 ++++++++++++++++++++++ include/Engine/Rendering/Renderer.h | 11 +++- src/Engine/Rendering/Renderer.cpp | 35 ++++------- src/Engine/Rendering/Util/ScreenCoords.cpp | 1 + src/Game/Game.cpp | 4 +- 5 files changed, 94 insertions(+), 26 deletions(-) create mode 100644 include/Engine/Rendering/EPicking.h diff --git a/include/Engine/Rendering/EPicking.h b/include/Engine/Rendering/EPicking.h new file mode 100644 index 00000000..df75854a --- /dev/null +++ b/include/Engine/Rendering/EPicking.h @@ -0,0 +1,69 @@ +#ifndef Events_Picking_h__ +#define Events_Picking_h__ + +#include "../OpenGL.h" +#include "../GLM.h" + +#include "../Core/EventBroker.h" +#include "Util/ScreenCoords.h" +#include "FrameBuffer.h" +#include "../Core/Entity.h" +#include "Util/UnorderedMapVec2.h" + +namespace Events +{ + +/** Thrown Every frame, use functions to pick*/ +struct Picking : Event +{ +public: + Picking(FrameBuffer* pickingBuffer, GLuint* depthBuffer, glm::mat4 projectionMatrix, glm::mat4 viewMatrix, Rectangle resolution, const std::unordered_map* pickingColorsToEntity) + : PickingBuffer(pickingBuffer) + , DepthBuffer(depthBuffer) + , ProjectionMatrix(projectionMatrix) + , ViewMatrix(viewMatrix) + , Resolution(resolution) + , PickingColorsToEntity(pickingColorsToEntity) + { } + + + + struct PickData + { + //Picked Entity + EntityID Entity; + //World position of the "pick" + glm::vec3 Position; + }; + + PickData Pick(glm::vec2 screenCoord) const + { + PickData pickData; + + ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer); + + auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1])); + if (it != PickingColorsToEntity->end()) { + pickData.Entity = it->second; + } else { + pickData.Entity = -1; + } + pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, Resolution.Width - screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix); + + return pickData; + } + + +private: + FrameBuffer* PickingBuffer; + GLuint* DepthBuffer; + const glm::mat4 ProjectionMatrix; + const glm::mat4 ViewMatrix; + const Rectangle Resolution; + const std::unordered_map* PickingColorsToEntity; + +}; + +} + +#endif diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index b1b76468..76de0818 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -11,15 +11,24 @@ #include "FrameBuffer.h" #include "../Core/World.h" +#include "../Core/EventBroker.h" +#include "EPicking.h" + class Renderer : public IRenderer { public: + Renderer(EventBroker* eventBroker) + : m_EventBroker(eventBroker) + { } + virtual void Initialize() override; virtual void Update(double dt) override; virtual void Draw(RenderQueueCollection& rq) override; private: //----------------------Variables----------------------// + EventBroker* m_EventBroker; + Texture* m_ErrorTexture; Texture* m_WhiteTexture; float m_CameraMoveSpeed; @@ -31,8 +40,6 @@ private: Model* m_UnitQuad; Model* m_UnitSphere; - - std::unordered_map m_PickingColorsToEntity; //----------------------Functions----------------------// diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index aba512fd..6f4235d2 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -3,7 +3,6 @@ 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, 10)); @@ -116,26 +115,6 @@ void Renderer::InputUpdate(double dt) static double mousePosX, mousePosY; glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); - if (glfwGetMouseButton(m_Window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) { - ScreenCoords::PixelData data = ScreenCoords::ToPixelData(mousePosX, m_Resolution.Height - mousePosY, &m_PickingBuffer, m_DepthBuffer); - - glm::vec3 viewPos = ScreenCoords::ToWorldPos(mousePosX, m_Resolution.Height - mousePosY, data.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", data.Color[0], data.Color[1], data.Depth); - //printf("view: x: %f, y: %f z: %f, Length: %f\n\n", viewPos.x, viewPos.y, viewPos.z, glm::length(viewPos)); - //printf("\n\n---------------------------\n"); - auto got = m_PickingColorsToEntity.find(glm::vec2(data.Color[0], data.Color[1])); - if (got == m_PickingColorsToEntity.end()) - printf("Color (R:%f, G:%f) not found.\n", data.Color[0], data.Color[1]); - else - printf("R:%f G:%f, EntityID: %i\n", got->first.r, got->first.g, got->second); - //printf("----\n"); - //for (auto i : m_PickingColorsToEntity) { - // printf("Entity: %i, Color: R: %f, G: %f\n", i.second, i.first.r, i.first.g); - //} - //printf("---------------------------\n\n"); - } if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { @@ -161,7 +140,8 @@ void Renderer::InputUpdate(double dt) void Renderer::Update(double dt) { - InputUpdate(dt); + m_EventBroker->Process(); + InputUpdate(dt); } @@ -276,6 +256,17 @@ void Renderer::PickingPass(RenderQueueCollection& rq) m_PickingBuffer.Unbind(); GLERROR("PickingPass Error"); + //Publish pick event every frame with the pick data that can be picked by the event + Events::Picking pickEvent = Events::Picking( + &m_PickingBuffer, + &m_DepthBuffer, + m_Camera->ProjectionMatrix(), + m_Camera->ViewMatrix(), + m_Resolution, + &m_PickingColorsToEntity); + + m_EventBroker->Publish(pickEvent); + } diff --git a/src/Engine/Rendering/Util/ScreenCoords.cpp b/src/Engine/Rendering/Util/ScreenCoords.cpp index e999c895..36dd08a1 100644 --- a/src/Engine/Rendering/Util/ScreenCoords.cpp +++ b/src/Engine/Rendering/Util/ScreenCoords.cpp @@ -56,3 +56,4 @@ ScreenCoords::PixelData ScreenCoords::ToPixelData(glm::vec2 screenCoord, FrameBu { return ToPixelData(screenCoord.x, screenCoord.y, PickDataBuffer, DepthBuffer); } + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 15dde3a0..bff6aebc 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -16,7 +16,7 @@ Game::Game(int argc, char* argv[]) m_RenderQueueFactory = new RenderQueueFactory(); // Create the renderer - m_Renderer = new Renderer(); + m_Renderer = new Renderer(m_EventBroker); m_Renderer->SetFullscreen(m_Config->Get("Video.Fullscreen", false)); m_Renderer->SetVSYNC(m_Config->Get("Video.VSYNC", false)); m_Renderer->SetResolution(Rectangle( @@ -65,12 +65,12 @@ void Game::Tick() m_EventBroker->Swap(); m_InputManager->Update(dt); - m_Renderer->Update(dt); m_EventBroker->Swap(); // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); testTick(dt); + m_Renderer->Update(dt); m_RenderQueueFactory->Update(m_World); m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); From 91edab34bc9156fe26800d5b47de606db8fd2ba5 Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 11 Dec 2015 11:18:30 +0100 Subject: [PATCH 08/65] PickingPass now sets state and clear it when done. PickingState now it's own class so renderer is a bit cleaner. --- include/Engine/Rendering/PickingPass.h | 45 ++++++ include/Engine/Rendering/Renderer.h | 13 +- include/Engine/Rendering/ShaderProgram.h | 4 + include/Engine/Rendering/Util/GLError.h | 2 +- src/Engine/Rendering/FrameBuffer.cpp | 10 +- src/Engine/Rendering/PickingPass.cpp | 105 +++++++++++++ src/Engine/Rendering/PickingPassState.cpp | 5 + src/Engine/Rendering/RenderState.cpp | 2 +- src/Engine/Rendering/Renderer.cpp | 182 +++++++++++----------- 9 files changed, 264 insertions(+), 104 deletions(-) create mode 100644 include/Engine/Rendering/PickingPass.h create mode 100644 src/Engine/Rendering/PickingPass.cpp diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h new file mode 100644 index 00000000..313751d5 --- /dev/null +++ b/include/Engine/Rendering/PickingPass.h @@ -0,0 +1,45 @@ +#ifndef PickingPass_h__ +#define PickingPass_h__ + +#include "IRenderer.h" +#include "PickingPassState.h" +#include "FrameBuffer.h" +#include "ShaderProgram.h" +#include "Util/UnorderedMapVec2.h" + +class PickingPass +{ +public: + PickingPass(IRenderer* renderer); + ~PickingPass(); + void InitializeTextures(); + void InitializeFrameBuffers(); + void InitializeShaderPrograms(); + + void Draw(RenderQueueCollection& rq); + + + //Getters + const ShaderProgram& PickingProgram() const { return m_PickingProgram; } + const std::unordered_map& PickingColorsToEntity() const { return m_PickingColorsToEntity; } + GLuint PickingTexture() const { return m_PickingTexture; } + GLuint DepthBuffer() const { return m_DepthBuffer; } + const FrameBuffer& PickingBuffer() const { return m_PickingBuffer; } + + +private: + void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; + + const IRenderer* m_Renderer; + + ShaderProgram m_PickingProgram; + + std::unordered_map m_PickingColorsToEntity; + + GLuint m_PickingTexture; + GLuint m_DepthBuffer; + + FrameBuffer m_PickingBuffer; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index b0ddf870..18f32a17 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -10,6 +10,8 @@ #include "Util/UnorderedMapVec2.h" #include "FrameBuffer.h" #include "../Core/World.h" +#include "PickingPass.h" + #define TILE_SIZE 16 #define NUM_LIGHTS 3 @@ -35,17 +37,12 @@ private: Texture* m_ErrorTexture; Texture* m_WhiteTexture; float m_CameraMoveSpeed; - FrameBuffer m_PickingBuffer; - GLuint m_PickingTexture; - GLuint m_DepthBuffer; Model* m_ScreenQuad; Model* m_UnitQuad; Model* m_UnitSphere; - - - std::unordered_map m_PickingColorsToEntity; + PickingPass* m_PickingPass; //----------------------Functions----------------------// void InitializeWindow(); @@ -53,9 +50,10 @@ private: void InitializeTextures(); void InitializeFrameBuffers(); void InitializeSSBOs(); + void InitializeRenderPasses(); //TODO: Renderer: Get InputUpdate out of renderer void InputUpdate(double dt); - void PickingPass(RenderQueueCollection& rq); + //void PickingPass(RenderQueueCollection& rq); void DrawScreenQuad(GLuint textureToDraw); void DrawScene(RenderQueueCollection& rq); @@ -106,7 +104,6 @@ private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); //--------------------ShaderPrograms-------------------// ShaderProgram m_BasicForwardProgram; - ShaderProgram m_PickingProgram; ShaderProgram m_DrawScreenQuadProgram; ShaderProgram m_CalculateFrustumProgram; ShaderProgram m_LightCullProgram; diff --git a/include/Engine/Rendering/ShaderProgram.h b/include/Engine/Rendering/ShaderProgram.h index 1b87650e..097e09c3 100644 --- a/include/Engine/Rendering/ShaderProgram.h +++ b/include/Engine/Rendering/ShaderProgram.h @@ -1,3 +1,5 @@ +#ifndef ShaderProgram_h__ +#define ShaderProgram_h__ #include "../Common.h" #include "../OpenGL.h" @@ -79,3 +81,5 @@ private: GLuint m_ShaderProgramHandle; std::vector> m_Shaders; }; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Util/GLError.h b/include/Engine/Rendering/Util/GLError.h index 8202f433..754623d1 100644 --- a/include/Engine/Rendering/Util/GLError.h +++ b/include/Engine/Rendering/Util/GLError.h @@ -9,7 +9,7 @@ inline bool _GLERROR(const char* info, const char* file, const char* func, unsig GLenum error = glGetError(); if (error != GL_NO_ERROR) { - _LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s %i %s", info, error, gluErrorString(error)); + _LOG(LOG_LEVEL_ERROR, file, func, line, "GL Error: %s, %i, %s", info, error, gluErrorString(error)); return true; } diff --git a/src/Engine/Rendering/FrameBuffer.cpp b/src/Engine/Rendering/FrameBuffer.cpp index 1b53d868..b2b29626 100644 --- a/src/Engine/Rendering/FrameBuffer.cpp +++ b/src/Engine/Rendering/FrameBuffer.cpp @@ -48,13 +48,21 @@ void FrameBuffer::Generate() switch ((*it)->m_ResourceType) { case GL_TEXTURE_2D: glFramebufferTexture2D(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle, 0); + GLERROR("FrameBuffer generate: glFramebufferTexture2D"); + break; case GL_RENDERBUFFER: glFramebufferRenderbuffer(GL_FRAMEBUFFER, (*it)->m_Attachment, (*it)->m_ResourceType, *(*it)->m_ResourceHandle); + GLERROR("FrameBuffer generate: glFramebufferRenderbuffer"); + if ( (*it)->m_Attachment != GL_COLOR_ATTACHMENT0 || + (*it)->m_Attachment != GL_DEPTH_ATTACHMENT || + (*it)->m_Attachment != GL_STENCIL_ATTACHMENT) + { + LOG_ERROR("RenderBuffer Attachment not valid."); + } break; } - GLERROR("FrameBuffer generate"); if ((*it)->m_Attachment != GL_DEPTH_ATTACHMENT) { attachments.push_back((*it)->m_Attachment); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp new file mode 100644 index 00000000..5b44cbf4 --- /dev/null +++ b/src/Engine/Rendering/PickingPass.cpp @@ -0,0 +1,105 @@ +#include "Rendering/PickingPass.h" + +PickingPass::PickingPass(IRenderer* renderer) +{ + m_Renderer = renderer; + InitializeTextures(); + InitializeFrameBuffers(); + InitializeShaderPrograms(); +} + +PickingPass::~PickingPass() +{ + +} + +void PickingPass::InitializeTextures() +{ + GenerateTexture(&m_PickingTexture, GL_CLAMP_TO_BORDER, GL_LINEAR, + glm::vec2(m_Renderer->Resolution().Width, m_Renderer->Resolution().Height), GL_RG8, GL_RG, GL_UNSIGNED_BYTE); +} + +void PickingPass::InitializeFrameBuffers() +{ + glGenRenderbuffers(1, &m_DepthBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->Resolution().Width, m_Renderer->Resolution().Height); + + 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(); +} + +void PickingPass::InitializeShaderPrograms() +{ + 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(); +} + +void PickingPass::Draw(RenderQueueCollection& rq) +{ + m_PickingColorsToEntity.clear(); + m_PickingBuffer.Bind(); + PickingPassState state; + + int r = 1; + int g = 0; + //TODO: Render: Add code for more jobs than modeljobs. + + + GLuint ShaderHandle = m_PickingProgram.GetHandle(); + m_PickingProgram.Bind(); + + for (auto &job : rq.Forward) { + auto modelJob = std::dynamic_pointer_cast(job); + + if (modelJob) { + //--------------- + //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. + //--------------- + int pickColor[2] = { r, g }; + for (auto i : m_PickingColorsToEntity) { + if (modelJob->Entity == i.second) { + pickColor[0] = i.first.x; + pickColor[1] = i.first.y; + r -= 1; + } + } + 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); + r += 1; + if (r > 255) { + r = 0; + g += 1; + } + } + } + m_PickingBuffer.Unbind(); + GLERROR("PickingPass Error"); +} + +void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const +{ + //TODO: Renderer: Make this in a sparate class + 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, nullptr);//TODO: Renderer: Fix the precision and Resolution + GLERROR("Texture initialization failed"); +} diff --git a/src/Engine/Rendering/PickingPassState.cpp b/src/Engine/Rendering/PickingPassState.cpp index 9822c47e..18f702ee 100644 --- a/src/Engine/Rendering/PickingPassState.cpp +++ b/src/Engine/Rendering/PickingPassState.cpp @@ -3,6 +3,7 @@ PickingPassState::PickingPassState() { + Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); CullFace(GL_BACK); @@ -12,3 +13,7 @@ PickingPassState::PickingPassState() Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } +PickingPassState::~PickingPassState() +{ + +} diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 6844dbfd..3db428e4 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -32,7 +32,7 @@ bool RenderState::CullFace(GLenum GLCullFace) glGetIntegerv(GL_CULL_FACE_MODE, &a); if(a == GL_BACK) { - LOG_INFO("Setting Cullface to back, unessesary since this is already default."); + //LOG_INFO("Setting Cullface to back, unessesary since this is already default."); } m_preCullFace = a; glCullFace(GLCullFace); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index c483cdc6..8316cfa7 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -11,6 +11,7 @@ void Renderer::Initialize() m_Camera = m_DefaultCamera; } TEMPCreateLights(); + InitializeRenderPasses(); glfwSwapInterval(m_VSYNC); InitializeShaders(); @@ -71,24 +72,18 @@ void Renderer::InitializeShaders() 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(); - m_CalculateFrustumProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/GridFrustum.comp.glsl"))); - m_CalculateFrustumProgram.Compile(); - m_CalculateFrustumProgram.Link(); + //m_CalculateFrustumProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/GridFrustum.comp.glsl"))); + //m_CalculateFrustumProgram.Compile(); + //m_CalculateFrustumProgram.Link(); - m_LightCullProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); - m_LightCullProgram.Compile(); - m_LightCullProgram.Link(); + //m_LightCullProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); + //m_LightCullProgram.Compile(); + //m_LightCullProgram.Link(); } void Renderer::InputUpdate(double dt) @@ -125,26 +120,26 @@ void Renderer::InputUpdate(double dt) static double mousePosX, mousePosY; glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); - if (glfwGetMouseButton(m_Window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) { - ScreenCoords::PixelData data = ScreenCoords::ToPixelData(mousePosX, m_Resolution.Height - mousePosY, &m_PickingBuffer, m_DepthBuffer); - - glm::vec3 viewPos = ScreenCoords::ToWorldPos(mousePosX, m_Resolution.Height - mousePosY, data.Depth, m_Resolution, m_Camera->ProjectionMatrix(), m_Camera->ViewMatrix()); - // glm::vec3 worldPos = glm::vec3(glm::inverse(m_Camera->ViewMatrix()) * glm::vec4(viewPos, 1.f)); + //if (glfwGetMouseButton(m_Window, GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) { + // ScreenCoords::PixelData data = ScreenCoords::ToPixelData(mousePosX, m_Resolution.Height - mousePosY, &m_PickingBuffer, m_DepthBuffer); + // + // glm::vec3 viewPos = ScreenCoords::ToWorldPos(mousePosX, m_Resolution.Height - mousePosY, data.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", data.Color[0], data.Color[1], data.Depth); - //printf("view: x: %f, y: %f z: %f, Length: %f\n\n", viewPos.x, viewPos.y, viewPos.z, glm::length(viewPos)); - //printf("\n\n---------------------------\n"); - auto got = m_PickingColorsToEntity.find(glm::vec2(data.Color[0], data.Color[1])); - if (got == m_PickingColorsToEntity.end()) - printf("Color (R:%f, G:%f) not found.\n", data.Color[0], data.Color[1]); - else - printf("R:%f G:%f, EntityID: %i\n", got->first.r, got->first.g, got->second); - //printf("----\n"); - //for (auto i : m_PickingColorsToEntity) { - // printf("Entity: %i, Color: R: %f, G: %f\n", i.second, i.first.r, i.first.g); - //} - //printf("---------------------------\n\n"); - } + // //printf("R: %f, G: %f, Depth: %f\n", data.Color[0], data.Color[1], data.Depth); + // //printf("view: x: %f, y: %f z: %f, Length: %f\n\n", viewPos.x, viewPos.y, viewPos.z, glm::length(viewPos)); + // //printf("\n\n---------------------------\n"); + // //auto got = m_PickingColorsToEntity.find(glm::vec2(data.Color[0], data.Color[1])); + // //if (got == m_PickingColorsToEntity.end()) + // // printf("Color (R:%f, G:%f) not found.\n", data.Color[0], data.Color[1]); + // //else + // // printf("R:%f G:%f, EntityID: %i\n", got->first.r, got->first.g, got->second); + // //printf("----\n"); + // //for (auto i : m_PickingColorsToEntity) { + // // printf("Entity: %i, Color: R: %f, G: %f\n", i.second, i.first.r, i.first.g); + // //} + // //printf("---------------------------\n\n"); + //} if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { @@ -177,8 +172,8 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderQueueCollection& rq) { //TODO: Renderer: Kanske borde vara längst upp i update. - PickingPass(rq); - //DrawScreenQuad(m_PickingTexture); + m_PickingPass->Draw(rq); + //DrawScreenQuad(m_PickingPass->PickingTexture()); //CullLights(); DrawScene(rq); @@ -229,64 +224,63 @@ void Renderer::DrawScene(RenderQueueCollection& rq) GLERROR("DrawScene Error"); } -void Renderer::PickingPass(RenderQueueCollection& rq) -{ - m_PickingColorsToEntity.clear(); - m_PickingBuffer.Bind(); +//void Renderer::PickingPass(RenderQueueCollection& rq) +//{ + //m_PickingColorsToEntity.clear(); + //m_PickingBuffer.Bind(); - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); + //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 = 1; - int g = 0; - //TODO: Render: Add code for more jobs than modeljobs. + //glClearColor(0.f, 0.f, 0.f, 1.f); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //int r = 1; + //int g = 0; + ////TODO: Render: Add code for more jobs than modeljobs. - GLuint ShaderHandle = m_PickingProgram.GetHandle(); - m_PickingProgram.Bind(); + //GLuint ShaderHandle = m_PickingProgram.GetHandle(); + //m_PickingProgram.Bind(); - for (auto &job : rq.Forward) { - auto modelJob = std::dynamic_pointer_cast(job); + //for (auto &job : rq.Forward) { + // auto modelJob = std::dynamic_pointer_cast(job); - if (modelJob) { - //--------------- - //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. - //--------------- - int pickColor[2] = { r, g }; - for (auto i : m_PickingColorsToEntity) { - if(modelJob->Entity == i.second) { - pickColor[0] = i.first.x; - pickColor[1] = i.first.y; - r -= 1; - } - } - m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity; - + // if (modelJob) { + // //--------------- + // //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. + // //--------------- + // int pickColor[2] = { r, g }; + // for (auto i : m_PickingColorsToEntity) { + // if(modelJob->Entity == i.second) { + // pickColor[0] = i.first.x; + // pickColor[1] = i.first.y; + // r -= 1; + // } + // } + // 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_Camera->ViewMatrix())); - glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_Camera->ProjectionMatrix())); - glUniform2fv(glGetUniformLocation(ShaderHandle, "PickingColor"), 1, glm::value_ptr(glm::vec2(pickColor[0], pickColor[1]))); + // //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_Camera->ViewMatrix())); + // glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_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, 0, modelJob->StartIndex); - r += 1; - if(r > 255) { - r = 0; - g += 1; - } - } - } - m_PickingBuffer.Unbind(); - GLERROR("PickingPass Error"); - -} + // 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 += 1; + // if(r > 255) { + // r = 0; + // g += 1; + // } + // } + //} + //m_PickingBuffer.Unbind(); + //GLERROR("PickingPass Error"); +//} void Renderer::DrawScreenQuad(GLuint textureToDraw) { @@ -323,9 +317,6 @@ void Renderer::InitializeTextures() 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_UNSIGNED_BYTE); } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) @@ -342,13 +333,13 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin 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); - - 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(); + //glGenRenderbuffers(1, &m_DepthBuffer); + //glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); + //glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Resolution.Width, m_Resolution.Height); + // + //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(); } void Renderer::InitializeSSBOs() @@ -399,6 +390,11 @@ void Renderer::InitializeSSBOs() } +void Renderer::InitializeRenderPasses() +{ + m_PickingPass = new PickingPass(this); +} + void Renderer::CalculateFrustum() { GLERROR("CalculateFrustum Error-1"); From 80f028edf2ebf9d69f30c4f06ea6441bce75b695 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 11 Dec 2015 13:45:19 +0100 Subject: [PATCH 09/65] Added a very basic PlayerSystem, and a PlayerComponent. --- include/Engine/Core/System.h | 7 ++-- include/Engine/Core/SystemPipeline.h | 4 +-- include/Game/Game.h | 1 + include/Game/PlayerSystem.h | 34 ++++++++++++++++++ include/Game/RaptorCopterSystem.h | 2 +- resources/Schema/Components/Player.xml | 4 +++ resources/Schema/Components/Player.xsd | 14 ++++++++ resources/Schema/Entities/Test.xml | 10 ++++++ src/Game/Game.cpp | 3 +- src/Game/PlayerSystem.cpp | 49 ++++++++++++++++++++++++++ 10 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 include/Game/PlayerSystem.h create mode 100644 resources/Schema/Components/Player.xml create mode 100644 resources/Schema/Components/Player.xsd create mode 100644 src/Game/PlayerSystem.cpp diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index 8e8c71b9..a79e025f 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -10,16 +10,17 @@ class System friend class SystemPipeline; public: - System(const EventBroker* eventBroker, std::string componentType) + System(EventBroker* eventBroker, std::string componentType) : m_EventBroker(eventBroker) , m_ComponentType(componentType) { } - + + virtual void Initialize(); virtual void Update(World* world, ComponentWrapper& component, double dt) = 0; private: - const EventBroker* m_EventBroker; std::string m_ComponentType; + EventBroker* m_EventBroker; }; #endif \ No newline at end of file diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index 24f98121..e4b8bb1f 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -9,7 +9,7 @@ class SystemPipeline { public: - SystemPipeline(const EventBroker* eventBroker) + SystemPipeline(EventBroker* eventBroker) : m_EventBroker(eventBroker) { } ~SystemPipeline() @@ -51,7 +51,7 @@ public: } private: - const EventBroker* m_EventBroker; + EventBroker* m_EventBroker; std::unordered_map> m_Systems; }; diff --git a/include/Game/Game.h b/include/Game/Game.h index 500ecf3a..bc66d62f 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -13,6 +13,7 @@ #include "Core/EntityXMLFile.h" #include "Core/SystemPipeline.h" #include "RaptorCopterSystem.h" +#include "PlayerSystem.h" class Game { diff --git a/include/Game/PlayerSystem.h b/include/Game/PlayerSystem.h new file mode 100644 index 00000000..c6a9f04b --- /dev/null +++ b/include/Game/PlayerSystem.h @@ -0,0 +1,34 @@ +#ifndef PlayerSystem_h__ +#define PlayerSystem_h__ + +#include +#include + +#include "Common.h" +#include "Core/System.h" +#include "Core/EventBroker.h" +#include "Core/EKeyDown.h" +#include "Core/EKeyUp.h" + +class PlayerSystem : public System +{ +public: + PlayerSystem(EventBroker* eventBroker) + : System(eventBroker, "Player") + { } + + void Initialize(); + virtual void Update(World* world, ComponentWrapper& player, double dt) override; + +private: + float m_Speed; + glm::vec3 m_Direction; + EventBroker* m_EventBroker; + + EventRelay m_EKeyDown; + bool OnKeyDown(const Events::KeyDown &event); + EventRelay m_EKeyUp; + bool OnKeyUp(const Events::KeyUp &event); +}; + +#endif \ No newline at end of file diff --git a/include/Game/RaptorCopterSystem.h b/include/Game/RaptorCopterSystem.h index 55647004..a25ca3df 100644 --- a/include/Game/RaptorCopterSystem.h +++ b/include/Game/RaptorCopterSystem.h @@ -4,7 +4,7 @@ class RaptorCopterSystem : public System { public: - RaptorCopterSystem(const EventBroker* eventBroker) + RaptorCopterSystem(EventBroker* eventBroker) : System(eventBroker, "RaptorCopter") { } diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml new file mode 100644 index 00000000..d2e5f3a7 --- /dev/null +++ b/resources/Schema/Components/Player.xml @@ -0,0 +1,4 @@ + + 0 + + \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd new file mode 100644 index 00000000..61f19646 --- /dev/null +++ b/resources/Schema/Components/Player.xsd @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 2c3ea18e..885ff3d2 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -31,6 +31,16 @@ + + + + + + + Models/Core/UnitCube.obj + + + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index bff6aebc..0fc913de 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -44,7 +44,8 @@ Game::Game(int argc, char* argv[]) // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); - m_SystemPipeline->AddSystem(); + m_SystemPipeline->AddSystem(); + m_SystemPipeline->AddSystem(); m_LastTime = glfwGetTime(); diff --git a/src/Game/PlayerSystem.cpp b/src/Game/PlayerSystem.cpp new file mode 100644 index 00000000..b8dadaee --- /dev/null +++ b/src/Game/PlayerSystem.cpp @@ -0,0 +1,49 @@ +#include "PlayerSystem.h" + +void PlayerSystem::Initialize() +{ + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp); +} + +void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt) +{ + m_EventBroker->Process(); + ComponentWrapper& transform = world->GetComponent(player.EntityID, "Transform"); + (glm::vec3&)player["Velocity"] = m_Speed * float(dt) * m_Direction; + (glm::vec3&)transform["Position"] += (glm::vec3)player["Velocity"]; +} + +bool PlayerSystem::OnKeyDown(const Events::KeyDown & event) +{ + if (event.KeyCode == GLFW_KEY_P) { + m_Direction.z == -1; + } + if (event.KeyCode == GLFW_KEY_LEFT) { + m_Direction.x == -1; + } + if (event.KeyCode == GLFW_KEY_DOWN) { + m_Direction.z == 1; + } + if (event.KeyCode == GLFW_KEY_RIGHT) { + m_Direction.x == 1; + } + return true; +} + +bool PlayerSystem::OnKeyUp(const Events::KeyUp & event) +{ + if (event.KeyCode == GLFW_KEY_UP) { + m_Direction.z == 0; + } + if (event.KeyCode == GLFW_KEY_LEFT) { + m_Direction.x == 0; + } + if (event.KeyCode == GLFW_KEY_DOWN) { + m_Direction.z == 0; + } + if (event.KeyCode == GLFW_KEY_RIGHT) { + m_Direction.x == 0; + } + return false; +} From 725a8896ceee6d6941a1130a60e869aa4454fecf Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 11 Dec 2015 13:51:08 +0100 Subject: [PATCH 10/65] PickingPass now publishes an event that others can listen to to get pickingdata. --- include/Engine/Rendering/PickingPass.h | 6 +++++- src/Engine/Rendering/PickingPass.cpp | 15 ++++++++++++++- src/Engine/Rendering/Renderer.cpp | 12 +----------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index 313751d5..78c195a5 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -6,11 +6,13 @@ #include "FrameBuffer.h" #include "ShaderProgram.h" #include "Util/UnorderedMapVec2.h" +#include "../Core/EventBroker.h" +#include "EPicking.h" class PickingPass { public: - PickingPass(IRenderer* renderer); + PickingPass(IRenderer* renderer, EventBroker* eb); ~PickingPass(); void InitializeTextures(); void InitializeFrameBuffers(); @@ -30,6 +32,8 @@ public: private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; + EventBroker* m_EventBroker; + const IRenderer* m_Renderer; ShaderProgram m_PickingProgram; diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 5b44cbf4..e254f379 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -1,8 +1,10 @@ #include "Rendering/PickingPass.h" -PickingPass::PickingPass(IRenderer* renderer) +PickingPass::PickingPass(IRenderer* renderer, EventBroker* eb) { m_Renderer = renderer; + m_EventBroker = eb; + InitializeTextures(); InitializeFrameBuffers(); InitializeShaderPrograms(); @@ -89,6 +91,17 @@ void PickingPass::Draw(RenderQueueCollection& rq) } m_PickingBuffer.Unbind(); GLERROR("PickingPass Error"); + + //Publish pick event every frame with the pick data that can be picked by the event + Events::Picking pickEvent = Events::Picking( + &m_PickingBuffer, + &m_DepthBuffer, + m_Renderer->Camera()->ProjectionMatrix(), + m_Renderer->Camera()->ViewMatrix(), + m_Renderer->Resolution(), + &m_PickingColorsToEntity); + + m_EventBroker->Publish(pickEvent); } void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index a3331414..b479acaf 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -263,16 +263,6 @@ void Renderer::DrawScene(RenderQueueCollection& rq) //m_PickingBuffer.Unbind(); //GLERROR("PickingPass Error"); - //Publish pick event every frame with the pick data that can be picked by the event - Events::Picking pickEvent = Events::Picking( - &m_PickingBuffer, - &m_DepthBuffer, - m_Camera->ProjectionMatrix(), - m_Camera->ViewMatrix(), - m_Resolution, - &m_PickingColorsToEntity); - - m_EventBroker->Publish(pickEvent); void Renderer::DrawScreenQuad(GLuint textureToDraw) { @@ -384,7 +374,7 @@ void Renderer::InitializeSSBOs() void Renderer::InitializeRenderPasses() { - m_PickingPass = new PickingPass(this); + m_PickingPass = new PickingPass(this, m_EventBroker); } void Renderer::CalculateFrustum() From 0b60979c7bda0a5240d471f177cc20a73351b0b9 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 11 Dec 2015 14:03:00 +0100 Subject: [PATCH 11/65] Added a Initialize function for systems. --- include/Engine/Core/System.h | 4 ++-- include/Engine/Core/SystemPipeline.h | 10 ++++++++++ include/Game/PlayerSystem.h | 3 +-- include/Game/RaptorCopterSystem.h | 2 ++ src/Game/Game.cpp | 4 ++++ src/Game/PlayerSystem.cpp | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index a79e025f..c4a33d94 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -15,10 +15,10 @@ public: , m_ComponentType(componentType) { } - virtual void Initialize(); + virtual void Initialize() { } virtual void Update(World* world, ComponentWrapper& component, double dt) = 0; -private: +protected: std::string m_ComponentType; EventBroker* m_EventBroker; }; diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index e4b8bb1f..a3dc4f36 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -21,6 +21,16 @@ public: } } + void Initialize() + { + for (auto& pair : m_Systems) { + auto& systems = pair.second; + for (auto& system : systems) { + system->Initialize(); + } + } + } + template void AddSystem(Arguments... args) { diff --git a/include/Game/PlayerSystem.h b/include/Game/PlayerSystem.h index c6a9f04b..92e8a7cc 100644 --- a/include/Game/PlayerSystem.h +++ b/include/Game/PlayerSystem.h @@ -17,13 +17,12 @@ public: : System(eventBroker, "Player") { } - void Initialize(); + virtual void Initialize(); virtual void Update(World* world, ComponentWrapper& player, double dt) override; private: float m_Speed; glm::vec3 m_Direction; - EventBroker* m_EventBroker; EventRelay m_EKeyDown; bool OnKeyDown(const Events::KeyDown &event); diff --git a/include/Game/RaptorCopterSystem.h b/include/Game/RaptorCopterSystem.h index a25ca3df..cdd6dd90 100644 --- a/include/Game/RaptorCopterSystem.h +++ b/include/Game/RaptorCopterSystem.h @@ -8,6 +8,8 @@ public: : System(eventBroker, "RaptorCopter") { } + virtual void Initialize() { } + virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override { ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform"); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 0fc913de..21f93e41 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -47,9 +47,13 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(); + + m_LastTime = glfwGetTime(); testIntialize(); + + m_SystemPipeline->Initialize(); } Game::~Game() diff --git a/src/Game/PlayerSystem.cpp b/src/Game/PlayerSystem.cpp index b8dadaee..024204b5 100644 --- a/src/Game/PlayerSystem.cpp +++ b/src/Game/PlayerSystem.cpp @@ -16,7 +16,7 @@ void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt) bool PlayerSystem::OnKeyDown(const Events::KeyDown & event) { - if (event.KeyCode == GLFW_KEY_P) { + if (event.KeyCode == GLFW_KEY_UP) { m_Direction.z == -1; } if (event.KeyCode == GLFW_KEY_LEFT) { From 094c7fbb444a6a12a6351974e0e144277285bdc5 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 11 Dec 2015 14:20:36 +0100 Subject: [PATCH 12/65] Added system to CMakeLists.txt. --- src/Game/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Game/CMakeLists.txt b/src/Game/CMakeLists.txt index c21aaa8a..18b80f93 100644 --- a/src/Game/CMakeLists.txt +++ b/src/Game/CMakeLists.txt @@ -19,6 +19,7 @@ file(GLOB SOURCE_FILES set(SOURCE_FILES ${SOURCE_FILES} "Game.cpp" + "PlayerSystem.cpp" ) set(LIBRARIES From 433331e752dd30357f6c29107cce01cebb364e02 Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 11 Dec 2015 14:22:54 +0100 Subject: [PATCH 13/65] DrawPass now moved to it's own class to make renderer cleaner. --- include/Engine/Rendering/DrawScenePass.h | 36 +++++++++ include/Engine/Rendering/DrawScenePassState.h | 15 ++++ include/Engine/Rendering/Renderer.h | 2 + src/Engine/Rendering/DrawScenePass.cpp | 61 +++++++++++++++ src/Engine/Rendering/DrawScenePassState.cpp | 16 ++++ src/Engine/Rendering/Renderer.cpp | 75 +------------------ 6 files changed, 133 insertions(+), 72 deletions(-) create mode 100644 include/Engine/Rendering/DrawScenePass.h create mode 100644 include/Engine/Rendering/DrawScenePassState.h create mode 100644 src/Engine/Rendering/DrawScenePass.cpp create mode 100644 src/Engine/Rendering/DrawScenePassState.cpp diff --git a/include/Engine/Rendering/DrawScenePass.h b/include/Engine/Rendering/DrawScenePass.h new file mode 100644 index 00000000..16ad224f --- /dev/null +++ b/include/Engine/Rendering/DrawScenePass.h @@ -0,0 +1,36 @@ +#ifndef DrawScenePass_h__ +#define DrawScenePass_h__ + +#include "IRenderer.h" +#include "DrawScenePassState.h" +#include "FrameBuffer.h" +#include "ShaderProgram.h" +#include "Util/UnorderedMapVec2.h" +#include "Texture.h" + +class DrawScenePass +{ +public: + DrawScenePass(IRenderer* renderer); + ~DrawScenePass() { } + void InitializeTextures(); + void InitializeFrameBuffers(); + void InitializeShaderPrograms(); + + void Draw(RenderQueueCollection& rq); + + //Getters + + +private: + void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; + + Texture* m_WhiteTexture; + + const IRenderer* m_Renderer; + + ShaderProgram m_BasicForwardProgram; + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/DrawScenePassState.h b/include/Engine/Rendering/DrawScenePassState.h new file mode 100644 index 00000000..7ce74006 --- /dev/null +++ b/include/Engine/Rendering/DrawScenePassState.h @@ -0,0 +1,15 @@ +#ifndef DrawScenePassState_h__ +#define DrawScenePassState_h__ + +#include "Rendering/RenderState.h" + +class DrawScenePassState : public RenderState +{ +public: + DrawScenePassState(); + ~DrawScenePassState(); +private: + +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index b9ad0d07..a3cb345a 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -11,6 +11,7 @@ #include "FrameBuffer.h" #include "../Core/World.h" #include "PickingPass.h" +#include "DrawScenePass.h" #define TILE_SIZE 16 @@ -52,6 +53,7 @@ private: Model* m_UnitSphere; PickingPass* m_PickingPass; + DrawScenePass* m_DrawScenePass; //----------------------Functions----------------------// void InitializeWindow(); diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp new file mode 100644 index 00000000..210b62f6 --- /dev/null +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -0,0 +1,61 @@ +#include "Rendering/DrawScenePass.h" + +DrawScenePass::DrawScenePass(IRenderer* renderer) +{ + m_Renderer = renderer; + InitializeTextures(); + InitializeShaderPrograms(); +} + +void DrawScenePass::InitializeTextures() +{ + m_WhiteTexture = ResourceManager::Load("Textures/Core/Blank.png"); + +} + +void DrawScenePass::InitializeShaderPrograms() +{ + //Gör så att shaders är en resource, tex som texture classen. Konstruktorn måste vara privat. + 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 DrawScenePass::Draw(RenderQueueCollection& rq) +{ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + DrawScenePassState state; + + //TODO: Render: Add code for more jobs than modeljobs. + 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(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())); + 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) { + 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; + } + } + GLERROR("DrawScene Error"); +} diff --git a/src/Engine/Rendering/DrawScenePassState.cpp b/src/Engine/Rendering/DrawScenePassState.cpp new file mode 100644 index 00000000..e0fb706f --- /dev/null +++ b/src/Engine/Rendering/DrawScenePassState.cpp @@ -0,0 +1,16 @@ +#include "Rendering/DrawScenePassState.h" + + +DrawScenePassState::DrawScenePassState() +{ + Enable(GL_DEPTH_TEST); + Enable(GL_CULL_FACE); + CullFace(GL_BACK); + 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() +{ + +} diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index b479acaf..634f66db 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -116,11 +116,8 @@ void Renderer::InputUpdate(double dt) m_CameraMoveSpeed = 0.5f; } - static double mousePosX, mousePosY; glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); - // //} - // //printf("---------------------------\n\n"); if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { @@ -158,7 +155,8 @@ void Renderer::Draw(RenderQueueCollection& rq) //DrawScreenQuad(m_PickingPass->PickingTexture()); //CullLights(); - DrawScene(rq); + //DrawScene(rq); + m_DrawScenePass->Draw(rq); glfwSwapBuffers(m_Window); } @@ -206,64 +204,6 @@ void Renderer::DrawScene(RenderQueueCollection& rq) GLERROR("DrawScene Error"); } -//void Renderer::PickingPass(RenderQueueCollection& rq) -//{ - //m_PickingColorsToEntity.clear(); - //m_PickingBuffer.Bind(); - - //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 = 1; - //int g = 0; - ////TODO: Render: Add code for more jobs than modeljobs. - - - //GLuint ShaderHandle = m_PickingProgram.GetHandle(); - //m_PickingProgram.Bind(); - - //for (auto &job : rq.Forward) { - // auto modelJob = std::dynamic_pointer_cast(job); - - // if (modelJob) { - // //--------------- - // //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. - // //--------------- - // int pickColor[2] = { r, g }; - // for (auto i : m_PickingColorsToEntity) { - // if(modelJob->Entity == i.second) { - // pickColor[0] = i.first.x; - // pickColor[1] = i.first.y; - // r -= 1; - // } - // } - // 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_Camera->ViewMatrix())); - // glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(m_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, 0, modelJob->StartIndex); - // r += 1; - // if(r > 255) { - // r = 0; - // g += 1; - // } - // } - //} - //m_PickingBuffer.Unbind(); - //GLERROR("PickingPass Error"); - - void Renderer::DrawScreenQuad(GLuint textureToDraw) { glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -289,16 +229,6 @@ 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_RG, GL_FLOAT, NULL);//TODO: Renderer: Fix the precision and Resolution - GLERROR("m_PickingTexture initialization failed"); - */ } void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) @@ -375,6 +305,7 @@ void Renderer::InitializeSSBOs() void Renderer::InitializeRenderPasses() { m_PickingPass = new PickingPass(this, m_EventBroker); + m_DrawScenePass = new DrawScenePass(this); } void Renderer::CalculateFrustum() From c2435fda2d8313a9d93da7fa2bf01267d138b247 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 11 Dec 2015 14:27:54 +0100 Subject: [PATCH 14/65] Added Component to Components.xsd and Entity.xsd --- resources/Schema/Components.xsd | 1 + resources/Schema/Components/Player.xml | 1 - resources/Schema/Components/Player.xsd | 1 - resources/Schema/Entities/Test.xml | 3 +++ resources/Schema/Types/Entity.xsd | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index d4160700..12fb870e 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -5,4 +5,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/Player.xml b/resources/Schema/Components/Player.xml index d2e5f3a7..91a3bb4e 100644 --- a/resources/Schema/Components/Player.xml +++ b/resources/Schema/Components/Player.xml @@ -1,4 +1,3 @@ - 0 \ No newline at end of file diff --git a/resources/Schema/Components/Player.xsd b/resources/Schema/Components/Player.xsd index 61f19646..78c5866b 100644 --- a/resources/Schema/Components/Player.xsd +++ b/resources/Schema/Components/Player.xsd @@ -6,7 +6,6 @@ - diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 885ff3d2..4b8fb132 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -33,6 +33,9 @@ + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 695ae7d1..92f7dc31 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -14,6 +14,7 @@ + From 4da33ff4ec16c1ad641ccdd60a5c41c3057d4bfa Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 11 Dec 2015 15:00:57 +0100 Subject: [PATCH 15/65] Fixed movement on a "player" cube. Very simple system atm --- include/Game/PlayerSystem.h | 11 +++++++- src/Game/PlayerSystem.cpp | 50 +++++++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/include/Game/PlayerSystem.h b/include/Game/PlayerSystem.h index 92e8a7cc..5966bb24 100644 --- a/include/Game/PlayerSystem.h +++ b/include/Game/PlayerSystem.h @@ -10,6 +10,14 @@ #include "Core/EKeyDown.h" #include "Core/EKeyUp.h" +struct KeyInput +{ + bool Forward = false; + bool Left = false; + bool Back = false; + bool Right = false; +}; + class PlayerSystem : public System { public: @@ -21,8 +29,9 @@ public: virtual void Update(World* world, ComponentWrapper& player, double dt) override; private: - float m_Speed; + float m_Speed = 5; glm::vec3 m_Direction; + KeyInput input; EventRelay m_EKeyDown; bool OnKeyDown(const Events::KeyDown &event); diff --git a/src/Game/PlayerSystem.cpp b/src/Game/PlayerSystem.cpp index 024204b5..17e18a9a 100644 --- a/src/Game/PlayerSystem.cpp +++ b/src/Game/PlayerSystem.cpp @@ -8,6 +8,24 @@ void PlayerSystem::Initialize() void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt) { + if (input.Forward) { + m_Direction.z = -1; + } + else if (input.Back) { + m_Direction.z = 1; + } + else { + m_Direction.z = 0; + } + if (input.Left) { + m_Direction.x = -1; + } + else if (input.Right) { + m_Direction.x = 1; + } + else { + m_Direction.x = 0; + } m_EventBroker->Process(); ComponentWrapper& transform = world->GetComponent(player.EntityID, "Transform"); (glm::vec3&)player["Velocity"] = m_Speed * float(dt) * m_Direction; @@ -16,34 +34,34 @@ void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt) bool PlayerSystem::OnKeyDown(const Events::KeyDown & event) { - if (event.KeyCode == GLFW_KEY_UP) { - m_Direction.z == -1; + if (event.KeyCode == GLFW_KEY_W) { + input.Forward = true; } - if (event.KeyCode == GLFW_KEY_LEFT) { - m_Direction.x == -1; + if (event.KeyCode == GLFW_KEY_A) { + input.Left = true; } - if (event.KeyCode == GLFW_KEY_DOWN) { - m_Direction.z == 1; + if (event.KeyCode == GLFW_KEY_S) { + input.Back = true; } - if (event.KeyCode == GLFW_KEY_RIGHT) { - m_Direction.x == 1; + if (event.KeyCode == GLFW_KEY_D) { + input.Right = true; } return true; } bool PlayerSystem::OnKeyUp(const Events::KeyUp & event) { - if (event.KeyCode == GLFW_KEY_UP) { - m_Direction.z == 0; + if (event.KeyCode == GLFW_KEY_W) { + input.Forward = false; } - if (event.KeyCode == GLFW_KEY_LEFT) { - m_Direction.x == 0; + if (event.KeyCode == GLFW_KEY_A) { + input.Left = false; } - if (event.KeyCode == GLFW_KEY_DOWN) { - m_Direction.z == 0; + if (event.KeyCode == GLFW_KEY_S) { + input.Back = false; } - if (event.KeyCode == GLFW_KEY_RIGHT) { - m_Direction.x == 0; + if (event.KeyCode == GLFW_KEY_D) { + input.Right = false; } return false; } From 16d636a87c0f9d134ca83afe73f42147aad01f05 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 11 Dec 2015 15:23:56 +0100 Subject: [PATCH 16/65] Removed Initialize function for systems. --- include/Engine/Core/System.h | 1 - include/Engine/Core/SystemPipeline.h | 10 ---------- include/Game/PlayerSystem.h | 6 ++++-- src/Game/Game.cpp | 2 -- src/Game/PlayerSystem.cpp | 5 ----- 5 files changed, 4 insertions(+), 20 deletions(-) diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index c4a33d94..cb4ccc26 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -15,7 +15,6 @@ public: , m_ComponentType(componentType) { } - virtual void Initialize() { } virtual void Update(World* world, ComponentWrapper& component, double dt) = 0; protected: diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index a3dc4f36..e4b8bb1f 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -21,16 +21,6 @@ public: } } - void Initialize() - { - for (auto& pair : m_Systems) { - auto& systems = pair.second; - for (auto& system : systems) { - system->Initialize(); - } - } - } - template void AddSystem(Arguments... args) { diff --git a/include/Game/PlayerSystem.h b/include/Game/PlayerSystem.h index 5966bb24..789b7549 100644 --- a/include/Game/PlayerSystem.h +++ b/include/Game/PlayerSystem.h @@ -23,9 +23,11 @@ class PlayerSystem : public System public: PlayerSystem(EventBroker* eventBroker) : System(eventBroker, "Player") - { } + { + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp); + } - virtual void Initialize(); virtual void Update(World* world, ComponentWrapper& player, double dt) override; private: diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 21f93e41..9eafd887 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -52,8 +52,6 @@ Game::Game(int argc, char* argv[]) m_LastTime = glfwGetTime(); testIntialize(); - - m_SystemPipeline->Initialize(); } Game::~Game() diff --git a/src/Game/PlayerSystem.cpp b/src/Game/PlayerSystem.cpp index 17e18a9a..a7b60011 100644 --- a/src/Game/PlayerSystem.cpp +++ b/src/Game/PlayerSystem.cpp @@ -1,10 +1,5 @@ #include "PlayerSystem.h" -void PlayerSystem::Initialize() -{ - EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown); - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp); -} void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt) { From 3da69c8a1b46246ce343561ff982dc25c01134ab Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 11 Dec 2015 15:29:57 +0100 Subject: [PATCH 17/65] Fixed indentation --- include/Engine/Core/EventBroker.h | 134 +++++++++++++++--------------- include/Engine/Core/System.h | 4 +- include/Game/PlayerSystem.h | 36 ++++---- src/Game/Game.cpp | 80 +++++++++--------- src/Game/PlayerSystem.cpp | 92 ++++++++++---------- 5 files changed, 171 insertions(+), 175 deletions(-) diff --git a/include/Engine/Core/EventBroker.h b/include/Engine/Core/EventBroker.h index 29d82c17..f04c7715 100644 --- a/include/Engine/Core/EventBroker.h +++ b/include/Engine/Core/EventBroker.h @@ -17,119 +17,119 @@ class EventBroker; class BaseEventRelay { -friend class EventBroker; + friend class EventBroker; protected: - BaseEventRelay(std::string contextTypeName, std::string eventTypeName) - : m_ContextTypeName(contextTypeName) - , m_EventTypeName(eventTypeName) - , m_Broker(nullptr) - { } - ~BaseEventRelay(); + BaseEventRelay(std::string contextTypeName, std::string eventTypeName) + : m_ContextTypeName(contextTypeName) + , m_EventTypeName(eventTypeName) + , m_Broker(nullptr) + { } + ~BaseEventRelay(); public: - virtual bool Receive(const std::shared_ptr event) = 0; + virtual bool Receive(const std::shared_ptr event) = 0; protected: - std::string m_ContextTypeName; - std::string m_EventTypeName; - EventBroker* m_Broker; + std::string m_ContextTypeName; + std::string m_EventTypeName; + EventBroker* m_Broker; }; template class EventRelay : public BaseEventRelay { public: - typedef std::function CallbackType; + typedef std::function CallbackType; - EventRelay() - : m_Callback(nullptr) - , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) - { } - EventRelay(CallbackType callback) - : m_Callback(callback) - , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) - { } + EventRelay() + : m_Callback(nullptr) + , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) + { } + EventRelay(CallbackType callback) + : m_Callback(callback) + , BaseEventRelay(typeid(ContextType).name(), typeid(EventType).name()) + { } protected: - bool Receive(const std::shared_ptr event) override; + bool Receive(const std::shared_ptr event) override; private: - CallbackType m_Callback; + CallbackType m_Callback; }; template bool EventRelay::Receive(const std::shared_ptr event) { - if (m_Callback != nullptr) { - return m_Callback(*static_cast(event.get())); - } else { - return false; - } + if (m_Callback != nullptr) { + return m_Callback(*static_cast(event.get())); + } else { + return false; + } } class EventBroker { -template friend class EventRelay; + template friend class EventRelay; public: - EventBroker() - { - m_EventQueueRead = std::make_shared(); - m_EventQueueWrite = std::make_shared(); - } + EventBroker() + { + m_EventQueueRead = std::make_shared(); + m_EventQueueWrite = std::make_shared(); + } - void Subscribe(BaseEventRelay &relay); - template - void Publish(const EventType &event); - /* - Process all events in a given context. - Returns: Number of events processed - */ - template - int Process(); - int Process(std::string contextTypeName); - void Swap(); - void Clear(); - void Unsubscribe(BaseEventRelay &relay); + void Subscribe(BaseEventRelay &relay); + template + void Publish(const EventType &event); + /* + Process all events in a given context. + Returns: Number of events processed + */ + template + int Process(); + int Process(std::string contextTypeName); + void Swap(); + void Clear(); + void Unsubscribe(BaseEventRelay &relay); private: - bool m_IsProcessing = false; + bool m_IsProcessing = false; - typedef std::string ContextTypeName_t; // typeid(ContextType).name() - typedef std::string EventTypeName_t; // typeid(EventType).name() + typedef std::string ContextTypeName_t; // typeid(ContextType).name() + typedef std::string EventTypeName_t; // typeid(EventType).name() - typedef std::unordered_multimap EventRelays_t; - typedef std::unordered_map ContextRelays_t; - ContextRelays_t m_ContextRelays; - std::vector m_RelaysToSubscribe; - std::vector m_RelaysToUnsubscribe; + typedef std::unordered_multimap EventRelays_t; + typedef std::unordered_map ContextRelays_t; + ContextRelays_t m_ContextRelays; + std::vector m_RelaysToSubscribe; + std::vector m_RelaysToUnsubscribe; - typedef std::list>> EventQueue_t; - std::shared_ptr m_EventQueueRead; - std::shared_ptr m_EventQueueWrite; + typedef std::list>> EventQueue_t; + std::shared_ptr m_EventQueueRead; + std::shared_ptr m_EventQueueWrite; - void subscribeImmediate(BaseEventRelay& relay); - void unsubscribeImmediate(BaseEventRelay& relay); + void subscribeImmediate(BaseEventRelay& relay); + void unsubscribeImmediate(BaseEventRelay& relay); }; template void EventBroker::Publish(const EventType &event) { - /*auto itpair = m_Subscribers.equal_range(typeid(EventType).name()); - for (auto it = itpair.first; it != itpair.second; ++it) - { - it->second->Receive(event); - }*/ + /*auto itpair = m_Subscribers.equal_range(typeid(EventType).name()); + for (auto it = itpair.first; it != itpair.second; ++it) + { + it->second->Receive(event); + }*/ - m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr(new EventType(event)))); + m_EventQueueWrite->push_back(std::make_pair(typeid(EventType).name(), std::shared_ptr(new EventType(event)))); } template int EventBroker::Process() { - const std::string contextTypeName = typeid(ContextType).name(); - return Process(contextTypeName); + const std::string contextTypeName = typeid(ContextType).name(); + return Process(contextTypeName); } #endif diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index cb4ccc26..37719c51 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -14,12 +14,12 @@ public: : m_EventBroker(eventBroker) , m_ComponentType(componentType) { } - + virtual void Update(World* world, ComponentWrapper& component, double dt) = 0; protected: std::string m_ComponentType; - EventBroker* m_EventBroker; + EventBroker* m_EventBroker; }; #endif \ No newline at end of file diff --git a/include/Game/PlayerSystem.h b/include/Game/PlayerSystem.h index 789b7549..18752ac6 100644 --- a/include/Game/PlayerSystem.h +++ b/include/Game/PlayerSystem.h @@ -12,33 +12,33 @@ struct KeyInput { - bool Forward = false; - bool Left = false; - bool Back = false; - bool Right = false; + bool Forward = false; + bool Left = false; + bool Back = false; + bool Right = false; }; class PlayerSystem : public System { public: - PlayerSystem(EventBroker* eventBroker) - : System(eventBroker, "Player") - { - EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown); - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp); - } + PlayerSystem(EventBroker* eventBroker) + : System(eventBroker, "Player") + { + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp); + } - virtual void Update(World* world, ComponentWrapper& player, double dt) override; + virtual void Update(World* world, ComponentWrapper& player, double dt) override; private: - float m_Speed = 5; - glm::vec3 m_Direction; - KeyInput input; + float m_Speed = 5; + glm::vec3 m_Direction; + KeyInput input; - EventRelay m_EKeyDown; - bool OnKeyDown(const Events::KeyDown &event); - EventRelay m_EKeyUp; - bool OnKeyUp(const Events::KeyUp &event); + EventRelay m_EKeyDown; + bool OnKeyDown(const Events::KeyDown &event); + EventRelay m_EKeyUp; + bool OnKeyUp(const Events::KeyUp &event); }; #endif \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 9eafd887..fa12bbc6 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -2,38 +2,38 @@ Game::Game(int argc, char* argv[]) { - ResourceManager::RegisterType("ConfigFile"); - ResourceManager::RegisterType("Model"); - ResourceManager::RegisterType("Texture"); + ResourceManager::RegisterType("ConfigFile"); + ResourceManager::RegisterType("Model"); + ResourceManager::RegisterType("Texture"); ResourceManager::RegisterType("EntityXMLFile"); - m_Config = ResourceManager::Load("Config.ini"); - LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); + m_Config = ResourceManager::Load("Config.ini"); + LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); - // Create the core event broker - m_EventBroker = new EventBroker(); + // Create the core event broker + m_EventBroker = new EventBroker(); m_RenderQueueFactory = new RenderQueueFactory(); - // Create the renderer - m_Renderer = new Renderer(m_EventBroker); - m_Renderer->SetFullscreen(m_Config->Get("Video.Fullscreen", false)); - m_Renderer->SetVSYNC(m_Config->Get("Video.VSYNC", false)); - m_Renderer->SetResolution(Rectangle( - 0, - 0, - m_Config->Get("Video.Width", 1280), - m_Config->Get("Video.Height", 720) - )); - m_Renderer->Initialize(); + // Create the renderer + m_Renderer = new Renderer(m_EventBroker); + m_Renderer->SetFullscreen(m_Config->Get("Video.Fullscreen", false)); + m_Renderer->SetVSYNC(m_Config->Get("Video.VSYNC", false)); + m_Renderer->SetResolution(Rectangle( + 0, + 0, + m_Config->Get("Video.Width", 1280), + m_Config->Get("Video.Height", 720) + )); + m_Renderer->Initialize(); - // Create input manager - m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); + // Create input manager + m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); - // Create the root level GUI frame - m_FrameStack = new GUI::Frame(m_EventBroker); - m_FrameStack->Width = m_Renderer->Resolution().Width; - m_FrameStack->Height = m_Renderer->Resolution().Height; + // Create the root level GUI frame + m_FrameStack = new GUI::Frame(m_EventBroker); + m_FrameStack->Width = m_Renderer->Resolution().Width; + m_FrameStack->Height = m_Renderer->Resolution().Height; // Create a world m_World = new World(); @@ -41,34 +41,34 @@ Game::Game(int argc, char* argv[]) if (!mapToLoad.empty()) { ResourceManager::Load(mapToLoad)->PopulateWorld(m_World); } - + // Create system pipeline m_SystemPipeline = new SystemPipeline(m_EventBroker); - m_SystemPipeline->AddSystem(); - m_SystemPipeline->AddSystem(); + m_SystemPipeline->AddSystem(); + m_SystemPipeline->AddSystem(); - m_LastTime = glfwGetTime(); + m_LastTime = glfwGetTime(); testIntialize(); } Game::~Game() { - delete m_FrameStack; - delete m_EventBroker; + delete m_FrameStack; + delete m_EventBroker; } void Game::Tick() { - double currentTime = glfwGetTime(); - double dt = currentTime - m_LastTime; - m_LastTime = currentTime; + double currentTime = glfwGetTime(); + double dt = currentTime - m_LastTime; + m_LastTime = currentTime; - m_EventBroker->Swap(); - m_InputManager->Update(dt); - m_EventBroker->Swap(); + m_EventBroker->Swap(); + m_InputManager->Update(dt); + m_EventBroker->Swap(); // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); @@ -76,12 +76,12 @@ void Game::Tick() m_Renderer->Update(dt); m_RenderQueueFactory->Update(m_World); - m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); + m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); - m_EventBroker->Swap(); - m_EventBroker->Clear(); + m_EventBroker->Swap(); + m_EventBroker->Clear(); - glfwPollEvents(); + glfwPollEvents(); } diff --git a/src/Game/PlayerSystem.cpp b/src/Game/PlayerSystem.cpp index a7b60011..736ea105 100644 --- a/src/Game/PlayerSystem.cpp +++ b/src/Game/PlayerSystem.cpp @@ -3,60 +3,56 @@ void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt) { - if (input.Forward) { - m_Direction.z = -1; - } - else if (input.Back) { - m_Direction.z = 1; - } - else { - m_Direction.z = 0; - } - if (input.Left) { - m_Direction.x = -1; - } - else if (input.Right) { - m_Direction.x = 1; - } - else { - m_Direction.x = 0; - } - m_EventBroker->Process(); - ComponentWrapper& transform = world->GetComponent(player.EntityID, "Transform"); - (glm::vec3&)player["Velocity"] = m_Speed * float(dt) * m_Direction; - (glm::vec3&)transform["Position"] += (glm::vec3)player["Velocity"]; + if (input.Forward) { + m_Direction.z = -1; + } else if (input.Back) { + m_Direction.z = 1; + } else { + m_Direction.z = 0; + } + if (input.Left) { + m_Direction.x = -1; + } else if (input.Right) { + m_Direction.x = 1; + } else { + m_Direction.x = 0; + } + m_EventBroker->Process(); + ComponentWrapper& transform = world->GetComponent(player.EntityID, "Transform"); + (glm::vec3&)player["Velocity"] = m_Speed * float(dt) * m_Direction; + (glm::vec3&)transform["Position"] += (glm::vec3)player["Velocity"]; } bool PlayerSystem::OnKeyDown(const Events::KeyDown & event) { - if (event.KeyCode == GLFW_KEY_W) { - input.Forward = true; - } - if (event.KeyCode == GLFW_KEY_A) { - input.Left = true; - } - if (event.KeyCode == GLFW_KEY_S) { - input.Back = true; - } - if (event.KeyCode == GLFW_KEY_D) { - input.Right = true; - } - return true; + if (event.KeyCode == GLFW_KEY_W) { + input.Forward = true; + } + if (event.KeyCode == GLFW_KEY_A) { + input.Left = true; + } + if (event.KeyCode == GLFW_KEY_S) { + input.Back = true; + } + if (event.KeyCode == GLFW_KEY_D) { + input.Right = true; + } + return true; } bool PlayerSystem::OnKeyUp(const Events::KeyUp & event) { - if (event.KeyCode == GLFW_KEY_W) { - input.Forward = false; - } - if (event.KeyCode == GLFW_KEY_A) { - input.Left = false; - } - if (event.KeyCode == GLFW_KEY_S) { - input.Back = false; - } - if (event.KeyCode == GLFW_KEY_D) { - input.Right = false; - } - return false; + if (event.KeyCode == GLFW_KEY_W) { + input.Forward = false; + } + if (event.KeyCode == GLFW_KEY_A) { + input.Left = false; + } + if (event.KeyCode == GLFW_KEY_S) { + input.Back = false; + } + if (event.KeyCode == GLFW_KEY_D) { + input.Right = false; + } + return false; } From 53d57364207cc7eaa1b3a73ed6a59f24cdbcbd38 Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 11 Dec 2015 16:07:12 +0100 Subject: [PATCH 18/65] Fixed a bugg with RenderState. Renderstate now also handles the Frambuffer binding. --- include/Engine/Rendering/PickingPassState.h | 4 +- include/Engine/Rendering/RenderState.h | 3 +- include/Engine/Rendering/Renderer.h | 2 +- src/Engine/Rendering/DrawScenePass.cpp | 5 +- src/Engine/Rendering/DrawScenePassState.cpp | 4 +- src/Engine/Rendering/PickingPass.cpp | 4 +- src/Engine/Rendering/PickingPassState.cpp | 7 +- src/Engine/Rendering/RenderState.cpp | 38 ++++++++- src/Engine/Rendering/Renderer.cpp | 93 +++++++++++---------- src/Game/Game.cpp | 3 +- 10 files changed, 100 insertions(+), 63 deletions(-) diff --git a/include/Engine/Rendering/PickingPassState.h b/include/Engine/Rendering/PickingPassState.h index 5902f9dc..4f6bfe40 100644 --- a/include/Engine/Rendering/PickingPassState.h +++ b/include/Engine/Rendering/PickingPassState.h @@ -6,10 +6,10 @@ class PickingPassState : public RenderState { public: - PickingPassState(); + PickingPassState(GLuint frameBuffer); ~PickingPassState(); -private: +private: }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index 76816308..e7ba2f80 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -14,9 +14,10 @@ public: bool CullFace(GLenum GlFaceToCull); bool ClearColor(glm::vec4 color); bool Clear(GLbitfield mask); + bool BindBuffer(GLint buffer); private: std::vector m_Enables; float m_preClearColor[4]; - GLenum m_preCullFace; + int m_preBuffer; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index a3cb345a..5ab10e2f 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -52,8 +52,8 @@ private: Model* m_UnitQuad; Model* m_UnitSphere; - PickingPass* m_PickingPass; DrawScenePass* m_DrawScenePass; + PickingPass* m_PickingPass; //----------------------Functions----------------------// void InitializeWindow(); diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp index 210b62f6..c780af1a 100644 --- a/src/Engine/Rendering/DrawScenePass.cpp +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -10,7 +10,6 @@ DrawScenePass::DrawScenePass(IRenderer* renderer) void DrawScenePass::InitializeTextures() { m_WhiteTexture = ResourceManager::Load("Textures/Core/Blank.png"); - } void DrawScenePass::InitializeShaderPrograms() @@ -24,10 +23,12 @@ void DrawScenePass::InitializeShaderPrograms() void DrawScenePass::Draw(RenderQueueCollection& rq) { - glBindFramebuffer(GL_FRAMEBUFFER, 0); + //glBindFramebuffer(GL_FRAMEBUFFER, 0); + GLERROR("Renderer::Draw PickingPass"); DrawScenePassState state; + //TODO: Render: Add code for more jobs than modeljobs. for (auto &job : rq.Forward) { auto modelJob = std::dynamic_pointer_cast(job); diff --git a/src/Engine/Rendering/DrawScenePassState.cpp b/src/Engine/Rendering/DrawScenePassState.cpp index e0fb706f..59654775 100644 --- a/src/Engine/Rendering/DrawScenePassState.cpp +++ b/src/Engine/Rendering/DrawScenePassState.cpp @@ -3,9 +3,11 @@ DrawScenePassState::DrawScenePassState() { + GLERROR("---"); + BindBuffer(0); + GLERROR("---"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); - CullFace(GL_BACK); ClearColor(glm::vec4(255.f / 255, 163.f / 255, 176.f / 255, 0.f)); Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index e254f379..6c4510f8 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -44,14 +44,12 @@ void PickingPass::InitializeShaderPrograms() void PickingPass::Draw(RenderQueueCollection& rq) { m_PickingColorsToEntity.clear(); - m_PickingBuffer.Bind(); - PickingPassState state; + PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); int r = 1; int g = 0; //TODO: Render: Add code for more jobs than modeljobs. - GLuint ShaderHandle = m_PickingProgram.GetHandle(); m_PickingProgram.Bind(); diff --git a/src/Engine/Rendering/PickingPassState.cpp b/src/Engine/Rendering/PickingPassState.cpp index 18f702ee..a52fa546 100644 --- a/src/Engine/Rendering/PickingPassState.cpp +++ b/src/Engine/Rendering/PickingPassState.cpp @@ -1,12 +1,13 @@ #include "Rendering/PickingPassState.h" -PickingPassState::PickingPassState() +PickingPassState::PickingPassState(GLuint frameBuffer) { - + GLERROR("---2"); + BindBuffer(frameBuffer); + GLERROR("---3"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); - CullFace(GL_BACK); glm::vec4 clearColor = glm::vec4(0.f); ClearColor(clearColor); diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 3db428e4..87f4a30d 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -2,6 +2,7 @@ RenderState::RenderState() { + } bool RenderState::Enable(GLenum GLEnable) @@ -30,12 +31,11 @@ bool RenderState::CullFace(GLenum GLCullFace) GLint a; glGetIntegerv(GL_CULL_FACE_MODE, &a); - if(a == GL_BACK) + if(a != GL_BACK) { //LOG_INFO("Setting Cullface to back, unessesary since this is already default."); + glCullFace(GLCullFace); } - m_preCullFace = a; - glCullFace(GLCullFace); if (GLERROR("RenderState::CullFace")) { return false; @@ -62,20 +62,50 @@ bool RenderState::Clear(GLbitfield mask) return true; } +bool RenderState::BindBuffer(GLint buffer) +{ + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_preBuffer); + if (buffer == m_preBuffer) + { + return true; + } + glBindFramebuffer(GL_FRAMEBUFFER, buffer); + if (GLERROR("RenderState::BindBuffer")) + { + printf("BufferID: %i\npreBufferID: %i\n", buffer, m_preBuffer); + return false; + } + return true; +} + RenderState::~RenderState() { + GLERROR("RenderState::~RenderState Pre"); + GLint n_buffer = -1; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &n_buffer); + //Set cullface to default - glCullFace(m_preCullFace); + if (glIsEnabled(GL_CULL_FACE)) { + glCullFace(GL_BACK); + } + GLERROR("RenderState::~RenderState glCullFace"); //Set color to default glClearColor(m_preClearColor[0], m_preClearColor[1], m_preClearColor[2], m_preClearColor[3]); + GLERROR("RenderState::~RenderState glClearColor"); //Disable Enables for (auto i : m_Enables) { glDisable(i); } + GLERROR("RenderState::~RenderState glDisable"); + if(m_preBuffer != 0) + { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } m_Enables.clear(); + GLERROR("RenderState::~RenderState glBindFramebuffer"); } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 634f66db..7e58728c 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -151,58 +151,61 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderQueueCollection& rq) { //TODO: Renderer: Kanske borde vara längst upp i update. + GLERROR("Renderer::Draw Pre"); m_PickingPass->Draw(rq); + GLERROR("Renderer::Draw PickingPass"); //DrawScreenQuad(m_PickingPass->PickingTexture()); //CullLights(); //DrawScene(rq); m_DrawScenePass->Draw(rq); + GLERROR("Renderer::Draw m_DrawScenePass->Draw"); 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 : 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(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) { - 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; - } - } - GLERROR("DrawScene Error"); -} +// +//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 : 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(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) { +// 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; +// } +// } +// GLERROR("DrawScene Error"); +//} void Renderer::DrawScreenQuad(GLuint textureToDraw) { @@ -304,8 +307,8 @@ void Renderer::InitializeSSBOs() void Renderer::InitializeRenderPasses() { - m_PickingPass = new PickingPass(this, m_EventBroker); m_DrawScenePass = new DrawScenePass(this); + m_PickingPass = new PickingPass(this, m_EventBroker); } void Renderer::CalculateFrustum() diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index bff6aebc..1ebfd72a 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -73,8 +73,9 @@ void Game::Tick() m_Renderer->Update(dt); m_RenderQueueFactory->Update(m_World); + GLERROR("Game::Tick m_RenderQueueFactory->Update"); m_Renderer->Draw(m_RenderQueueFactory->RenderQueues()); - + GLERROR("Game::Tick m_Renderer->Draw"); m_EventBroker->Swap(); m_EventBroker->Clear(); From 45b87ed6b1eb91a1f4eb92772d34c53d8f5465b6 Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 11 Dec 2015 16:53:46 +0100 Subject: [PATCH 19/65] ShaderProgram is now a Resource. All shaderprograms are now pointers and loaded with Resourcemanager. --- include/Engine/Rendering/DrawScenePass.h | 2 +- include/Engine/Rendering/PickingPass.h | 4 ++-- include/Engine/Rendering/Renderer.h | 8 ++++---- include/Engine/Rendering/ShaderProgram.h | 9 ++++++--- src/Engine/Rendering/DrawScenePass.cpp | 16 +++++++++------ src/Engine/Rendering/PickingPass.cpp | 16 ++++++++------- src/Engine/Rendering/Renderer.cpp | 25 ++++++++++++------------ src/Game/Game.cpp | 1 + 8 files changed, 45 insertions(+), 36 deletions(-) diff --git a/include/Engine/Rendering/DrawScenePass.h b/include/Engine/Rendering/DrawScenePass.h index 16ad224f..782c5a49 100644 --- a/include/Engine/Rendering/DrawScenePass.h +++ b/include/Engine/Rendering/DrawScenePass.h @@ -29,7 +29,7 @@ private: const IRenderer* m_Renderer; - ShaderProgram m_BasicForwardProgram; + ShaderProgram* m_BasicForwardProgram; }; diff --git a/include/Engine/Rendering/PickingPass.h b/include/Engine/Rendering/PickingPass.h index 78c195a5..e1bc42db 100644 --- a/include/Engine/Rendering/PickingPass.h +++ b/include/Engine/Rendering/PickingPass.h @@ -22,7 +22,7 @@ public: //Getters - const ShaderProgram& PickingProgram() const { return m_PickingProgram; } + const ShaderProgram& PickingProgram() const { return *m_PickingProgram; } const std::unordered_map& PickingColorsToEntity() const { return m_PickingColorsToEntity; } GLuint PickingTexture() const { return m_PickingTexture; } GLuint DepthBuffer() const { return m_DepthBuffer; } @@ -36,7 +36,7 @@ private: const IRenderer* m_Renderer; - ShaderProgram m_PickingProgram; + ShaderProgram* m_PickingProgram; std::unordered_map m_PickingColorsToEntity; diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 5ab10e2f..51a3c82d 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -114,10 +114,10 @@ private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type); //--------------------ShaderPrograms-------------------// - ShaderProgram m_BasicForwardProgram; - ShaderProgram m_DrawScreenQuadProgram; - ShaderProgram m_CalculateFrustumProgram; - ShaderProgram m_LightCullProgram; + ShaderProgram* m_BasicForwardProgram; + ShaderProgram* m_DrawScreenQuadProgram; + ShaderProgram* m_CalculateFrustumProgram; + ShaderProgram* m_LightCullProgram; }; diff --git a/include/Engine/Rendering/ShaderProgram.h b/include/Engine/Rendering/ShaderProgram.h index 097e09c3..ad01c029 100644 --- a/include/Engine/Rendering/ShaderProgram.h +++ b/include/Engine/Rendering/ShaderProgram.h @@ -3,6 +3,7 @@ #include "../Common.h" #include "../OpenGL.h" +#include "../Core/ResourceManager.h" #include class Shader @@ -62,11 +63,13 @@ public: : ShaderType(fileName) { } }; -class ShaderProgram +class ShaderProgram : public Resource { -public: - ShaderProgram() + friend class ResourceManager; +private: + ShaderProgram(std::string) : m_ShaderProgramHandle(0) { } +public: ~ShaderProgram(); void AddShader(std::shared_ptr shader); diff --git a/src/Engine/Rendering/DrawScenePass.cpp b/src/Engine/Rendering/DrawScenePass.cpp index c780af1a..559a0f58 100644 --- a/src/Engine/Rendering/DrawScenePass.cpp +++ b/src/Engine/Rendering/DrawScenePass.cpp @@ -15,10 +15,14 @@ void DrawScenePass::InitializeTextures() void DrawScenePass::InitializeShaderPrograms() { //Gör så att shaders är en resource, tex som texture classen. Konstruktorn måste vara privat. - 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(); + m_BasicForwardProgram = ResourceManager::Load("#BasicForwardProgram"); + + 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 DrawScenePass::Draw(RenderQueueCollection& rq) @@ -33,9 +37,9 @@ void DrawScenePass::Draw(RenderQueueCollection& rq) for (auto &job : rq.Forward) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { - GLuint ShaderHandle = m_BasicForwardProgram.GetHandle(); + GLuint ShaderHandle = m_BasicForwardProgram->GetHandle(); - m_BasicForwardProgram.Bind(); + 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(modelJob->ModelMatrix)); glUniformMatrix4fv(glGetUniformLocation(ShaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Renderer->Camera()->ViewMatrix())); diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 6c4510f8..7d4cb66f 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -34,11 +34,13 @@ void PickingPass::InitializeFrameBuffers() void PickingPass::InitializeShaderPrograms() { - 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_PickingProgram = ResourceManager::Load("#PickingProgram"); + + 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(); } void PickingPass::Draw(RenderQueueCollection& rq) @@ -50,8 +52,8 @@ void PickingPass::Draw(RenderQueueCollection& rq) int g = 0; //TODO: Render: Add code for more jobs than modeljobs. - GLuint ShaderHandle = m_PickingProgram.GetHandle(); - m_PickingProgram.Bind(); + GLuint ShaderHandle = m_PickingProgram->GetHandle(); + m_PickingProgram->Bind(); for (auto &job : rq.Forward) { auto modelJob = std::dynamic_pointer_cast(job); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 7e58728c..7f3e0166 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -66,15 +66,14 @@ void Renderer::InitializeWindow() 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(); + m_BasicForwardProgram = ResourceManager::Load("#m_BasicForwardProgram"); - 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(); + m_DrawScreenQuadProgram = ResourceManager::Load("#DrawScreenQuadProgram"); + + 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(); //m_CalculateFrustumProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/GridFrustum.comp.glsl"))); //m_CalculateFrustumProgram.Compile(); @@ -218,7 +217,7 @@ void Renderer::DrawScreenQuad(GLuint textureToDraw) glClear(GL_COLOR_BUFFER_BIT); - m_DrawScreenQuadProgram.Bind(); + m_DrawScreenQuadProgram->Bind(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureToDraw); @@ -314,14 +313,14 @@ void Renderer::InitializeRenderPasses() void Renderer::CalculateFrustum() { GLERROR("CalculateFrustum Error-1"); - m_CalculateFrustumProgram.Bind(); + m_CalculateFrustumProgram->Bind(); GLERROR("CalculateFrustum Error1"); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); GLERROR("CalculateFrustum Error2"); - glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram.GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix())); + glUniformMatrix4fv(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "P"), 1, false, glm::value_ptr(m_Camera->ProjectionMatrix())); GLERROR("CalculateFrustum Error3"); - glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram.GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height); + glUniform2f(glGetUniformLocation(m_CalculateFrustumProgram->GetHandle(), "ScreenDimensions"), m_Resolution.Width, m_Resolution.Height); GLERROR("CalculateFrustum Error4"); glDispatchCompute(5, 3, 1); GLERROR("CalculateFrustum Error5"); @@ -338,7 +337,7 @@ void Renderer::TEMPCreateLights() void Renderer::CullLights() { - m_LightCullProgram.Bind(); + m_LightCullProgram->Bind(); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_FrustumSSBO); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightSSBO); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightGridSSBO); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 1ebfd72a..318d21b3 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -6,6 +6,7 @@ Game::Game(int argc, char* argv[]) ResourceManager::RegisterType("Model"); ResourceManager::RegisterType("Texture"); ResourceManager::RegisterType("EntityXMLFile"); + ResourceManager::RegisterType("ShaderProgram"); m_Config = ResourceManager::Load("Config.ini"); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); From 59b261534ad35fd4c329e7b40e10ebcbe12b945b Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 11 Dec 2015 16:57:02 +0100 Subject: [PATCH 20/65] Cleaned some comments and random annoyances in Renderer --- src/Engine/Rendering/Renderer.cpp | 63 +------------------------------ 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 7f3e0166..42ec9018 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -69,16 +69,17 @@ void Renderer::InitializeShaders() m_BasicForwardProgram = ResourceManager::Load("#m_BasicForwardProgram"); m_DrawScreenQuadProgram = ResourceManager::Load("#DrawScreenQuadProgram"); - 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(); + //m_CalculateFrustumProgram = ResourceManager::Load("#CalculateFrustumProgram"); //m_CalculateFrustumProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/GridFrustum.comp.glsl"))); //m_CalculateFrustumProgram.Compile(); //m_CalculateFrustumProgram.Link(); + //m_LightCullProgram = ResourceManager::Load("#LightCullProgram"); //m_LightCullProgram.AddShader(std::shared_ptr(new ComputeShader("Shaders/cullLights.comp.glsl"))); //m_LightCullProgram.Compile(); //m_LightCullProgram.Link(); @@ -144,67 +145,18 @@ void Renderer::Update(double dt) { m_EventBroker->Process(); InputUpdate(dt); - } void Renderer::Draw(RenderQueueCollection& rq) { - //TODO: Renderer: Kanske borde vara längst upp i update. - GLERROR("Renderer::Draw Pre"); m_PickingPass->Draw(rq); - GLERROR("Renderer::Draw PickingPass"); //DrawScreenQuad(m_PickingPass->PickingTexture()); //CullLights(); - //DrawScene(rq); m_DrawScenePass->Draw(rq); GLERROR("Renderer::Draw m_DrawScenePass->Draw"); 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 : 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(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) { -// 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; -// } -// } -// GLERROR("DrawScene Error"); -//} void Renderer::DrawScreenQuad(GLuint textureToDraw) { @@ -245,17 +197,6 @@ void Renderer::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filterin 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); - // - //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(); -} - void Renderer::InitializeSSBOs() { printf("Size: %i\n", sizeof(m_Frustums)); From d406059c79ab5e4c5eab05ea4a6fa9425f69a5d6 Mon Sep 17 00:00:00 2001 From: Tleety Date: Fri, 11 Dec 2015 17:00:06 +0100 Subject: [PATCH 21/65] Small bugfix. --- include/Engine/Rendering/Renderer.h | 2 -- src/Engine/Rendering/Renderer.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 51a3c82d..886c98ca 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -59,14 +59,12 @@ private: void InitializeWindow(); void InitializeShaders(); void InitializeTextures(); - void InitializeFrameBuffers(); void InitializeSSBOs(); void InitializeRenderPasses(); //TODO: Renderer: Get InputUpdate out of renderer void InputUpdate(double dt); //void PickingPass(RenderQueueCollection& rq); void DrawScreenQuad(GLuint textureToDraw); - void DrawScene(RenderQueueCollection& rq); //----------------------Forward+-----------------------// void CalculateFrustum(); diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 42ec9018..f4897223 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -15,7 +15,6 @@ void Renderer::Initialize() glfwSwapInterval(m_VSYNC); InitializeShaders(); InitializeTextures(); - InitializeFrameBuffers(); InitializeSSBOs(); //CalculateFrustum(); From 7464facab9f132867562705d24ba9ec46192313a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 12 Dec 2015 03:38:17 +0100 Subject: [PATCH 22/65] Next generation raptor copter --- resources/Schema/Entities/Test.xml | 22 +++++---------------- src/Engine/Rendering/RenderQueueFactory.cpp | 2 +- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/resources/Schema/Entities/Test.xml b/resources/Schema/Entities/Test.xml index 4b8fb132..78494ce1 100644 --- a/resources/Schema/Entities/Test.xml +++ b/resources/Schema/Entities/Test.xml @@ -61,7 +61,7 @@ - + Models/Core/UnitRaptor.obj @@ -72,8 +72,8 @@ - - + + 20 @@ -84,19 +84,7 @@ - - - - - Models/Core/UnitCylinder.obj - - - - - - - - + @@ -109,7 +97,7 @@ - + diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/src/Engine/Rendering/RenderQueueFactory.cpp index 81d7391e..4b82647c 100644 --- a/src/Engine/Rendering/RenderQueueFactory.cpp +++ b/src/Engine/Rendering/RenderQueueFactory.cpp @@ -30,7 +30,7 @@ glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity) do { ComponentWrapper transform = world->GetComponent(entity, "Transform"); - position += AbsoluteOrientation(world, entity) * (glm::vec3)transform["Position"]; + position += (glm::vec3)transform["Position"]; entity = world->GetParent(entity); } while (entity != 0); From bffc97f31029b501fd49a7189228a7526d56bf9a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 11 Dec 2015 00:37:48 +0100 Subject: [PATCH 23/65] Groundwork for input command proxy --- include/Engine/Input/EBindOrigin.h | 22 ++ include/Engine/Input/EInputCommand.h | 2 +- include/Engine/Input/InputProxy.h | 146 +++++++++++++ include/Engine/Input/InputSystem.h | 78 ------- include/Engine/Input/KeyboardInputHandler.h | 67 ++++++ include/Game/Game.h | 3 + src/Engine/CMakeLists.txt | 2 +- src/Engine/Input/InputProxy.cpp | 221 ++++++++++++++++++++ src/Engine/Input/InputSystem.cpp | 221 -------------------- src/Game/Game.cpp | 8 + 10 files changed, 469 insertions(+), 301 deletions(-) create mode 100644 include/Engine/Input/EBindOrigin.h create mode 100644 include/Engine/Input/InputProxy.h delete mode 100644 include/Engine/Input/InputSystem.h create mode 100644 include/Engine/Input/KeyboardInputHandler.h create mode 100644 src/Engine/Input/InputProxy.cpp delete mode 100644 src/Engine/Input/InputSystem.cpp diff --git a/include/Engine/Input/EBindOrigin.h b/include/Engine/Input/EBindOrigin.h new file mode 100644 index 00000000..e39a6023 --- /dev/null +++ b/include/Engine/Input/EBindOrigin.h @@ -0,0 +1,22 @@ +#ifndef Events_BindOrigin_h__ +#define Events_BindOrigin_h__ + +#include "Core/EventBroker.h" + +namespace Events +{ + +/** Called to bind an input origin to an input command. */ +struct BindOrigin : Event +{ + /** The input origin to bind. */ + std::string Origin; + /** The command to send. */ + std::string Command; + /** The value to send for positive stimulation. */ + float Value = 1.f; +}; + +} + +#endif diff --git a/include/Engine/Input/EInputCommand.h b/include/Engine/Input/EInputCommand.h index 9c190a1e..9ec897d3 100644 --- a/include/Engine/Input/EInputCommand.h +++ b/include/Engine/Input/EInputCommand.h @@ -13,7 +13,7 @@ struct InputCommand : Event /** The command that was sent. */ std::string Command; /** The value of the command. */ - float Value; + float Value = 0; }; } diff --git a/include/Engine/Input/InputProxy.h b/include/Engine/Input/InputProxy.h new file mode 100644 index 00000000..1b0e213e --- /dev/null +++ b/include/Engine/Input/InputProxy.h @@ -0,0 +1,146 @@ +#ifndef InputSystem_h__ +#define InputSystem_h__ + +#include +#include + +#include + +#include "Core/EKeyUp.h" +#include "Core/EKeyDown.h" +#include "Core/EMousePress.h" +#include "Core/EMouseRelease.h" +#include "Core/EGamepadAxis.h" +#include "Core/EGamepadButton.h" +#include "Core/Util/EnumClassHash.h" +#include "EBindKey.h" +#include "EBindMouseButton.h" +#include "EBindGamepadAxis.h" +#include "EBindGamepadButton.h" +#include "EInputCommand.h" +#include "EBindOrigin.h" + +class InputProxy; + +class InputHandler +{ +public: + InputHandler(EventBroker* eventBroker, InputProxy* inputProxy) + : m_EventBroker(eventBroker) + , m_InputProxy(inputProxy) + { } + + virtual void Update(double dt) { } + virtual bool BindOrigin(std::string origin, std::string command, float value) = 0; + +protected: + EventBroker* m_EventBroker; + InputProxy* m_InputProxy; +}; + +class InputProxy +{ +public: + InputProxy(EventBroker* eventBroker) + : m_EventBroker(eventBroker) + { + EVENT_SUBSCRIBE_MEMBER(m_EBindOrigin, &InputProxy::OnBindOrigin); + } + + void Update(double dt) + { + m_EventBroker->Process(); + m_EventBroker->Process(); + for (auto& handler : m_Handlers) { + handler->Update(dt); + } + } + + void Process() + { + // Accumulate the input values of all unique commands published by input handlers + for (auto& pair : m_CommandQueue) { + Events::InputCommand e; + e.PlayerID = pair.first.first; + e.Command = pair.first.second; + e.Value = 0; + for (auto& value : pair.second) { + e.Value += value; + } + e.Value = std::max(-1.f, std::min(e.Value, 1.f)); + m_EventBroker->Publish(e); + LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + } + m_CommandQueue.clear(); + } + + template + void AddHandler() + { + m_Handlers.push_back(new T(m_EventBroker, this)); + } + + void Publish(const Events::InputCommand& e) + { + auto key = std::make_pair(e.PlayerID, e.Command); + m_CommandQueue[key].push_back(e.Value); + } + +protected: + EventBroker* m_EventBroker; + std::vector m_Handlers; + // Represents every unique command (has of PlayerID & Command) and all values reported for that command + std::map, std::vector> m_CommandQueue; + + EventRelay m_EBindOrigin; + bool OnBindOrigin(const Events::BindOrigin& e) + { + bool originBound = false; + for (auto& handler : m_Handlers) { + bool result = handler->BindOrigin(e.Origin, e.Command, e.Value); + if (result) { + if (originBound) { + LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str()); + } + originBound = true; + } + } + + if (!originBound) { + LOG_ERROR("No input handler responded to binding input origin \"%s\"!", e.Origin.c_str()); + } + + return originBound; + } + //std::unordered_map> m_CommandMouseButtonValues; // command string -> mouse button value for command + //std::unordered_map> m_CommandGamepadAxisValues; // command string -> gamepad axis value for command + //std::unordered_map> m_CommandGamepadButtonValues; // command string -> gamepad button value for command + //// Input binding tables + //std::unordered_multimap> m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string + //std::unordered_multimap, EnumClassHash> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value + //std::unordered_multimap, EnumClassHash> m_GamepadButtonBindings; // Gamepad::Button -> command string + + //// Input events + //EventRelay m_EMousePress; + //bool OnMousePress(const Events::MousePress &event); + //EventRelay m_EMouseRelease; + //bool OnMouseRelease(const Events::MouseRelease &event); + //EventRelay m_EGamepadAxis; + //bool OnGamepadAxis(const Events::GamepadAxis &event); + //EventRelay m_EGamepadButtonDown; + //bool OnGamepadButtonDown(const Events::GamepadButtonDown &event); + //EventRelay m_EGamepadButtonUp; + //bool OnGamepadButtonUp(const Events::GamepadButtonUp &event); + //// Input binding events + //EventRelay m_EBindMouseButton; + //bool OnBindMouseButton(const Events::BindMouseButton &event); + //EventRelay m_EBindGamepadAxis; + //bool OnBindGamepadAxis(const Events::BindGamepadAxis &event); + //EventRelay m_EBindGamepadButton; + //bool OnBindGamepadButton(const Events::BindGamepadButton &event); + + //float GetCommandTotalValue(std::string command); + //void PublishCommand(int playerID, std::string command, float value); +}; + +#endif diff --git a/include/Engine/Input/InputSystem.h b/include/Engine/Input/InputSystem.h deleted file mode 100644 index 2023880b..00000000 --- a/include/Engine/Input/InputSystem.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef InputSystem_h__ -#define InputSystem_h__ - -#include -#include - -#include "Core/System.h" -#include "Core/EKeyUp.h" -#include "Core/EKeyDown.h" -#include "Core/EMousePress.h" -#include "Core/EMouseRelease.h" -#include "Core/EGamepadAxis.h" -#include "Core/EGamepadButton.h" -#include "Core/Util/EnumClassHash.h" -#include "EBindKey.h" -#include "EBindMouseButton.h" -#include "EBindGamepadAxis.h" -#include "EBindGamepadButton.h" -#include "EInputCommand.h" - -namespace Systems -{ - -class InputSystem : public System -{ -public: - InputSystem(World* world, std::shared_ptr eventBroker) - : System(world, eventBroker) - { } - - void RegisterComponents(ComponentFactory* cf) override; - void Initialize() override; - - void Update(double dt) override; - -private: - std::unordered_map> m_CommandKeyboardValues; // command string -> keyboard key value for command - std::unordered_map> m_CommandMouseButtonValues; // command string -> mouse button value for command - std::unordered_map> m_CommandGamepadAxisValues; // command string -> gamepad axis value for command - std::unordered_map> m_CommandGamepadButtonValues; // command string -> gamepad button value for command - // Input binding tables - std::unordered_multimap> m_KeyBindings; // GLFW_KEY... -> command string & value - std::unordered_multimap> m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string - std::unordered_multimap, EnumClassHash> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value - std::unordered_multimap, EnumClassHash> m_GamepadButtonBindings; // Gamepad::Button -> command string - - // Input events - EventRelay m_EKeyDown; - bool OnKeyDown(const Events::KeyDown &event); - EventRelay m_EKeyUp; - bool OnKeyUp(const Events::KeyUp &event); - EventRelay m_EMousePress; - bool OnMousePress(const Events::MousePress &event); - EventRelay m_EMouseRelease; - bool OnMouseRelease(const Events::MouseRelease &event); - EventRelay m_EGamepadAxis; - bool OnGamepadAxis(const Events::GamepadAxis &event); - EventRelay m_EGamepadButtonDown; - bool OnGamepadButtonDown(const Events::GamepadButtonDown &event); - EventRelay m_EGamepadButtonUp; - bool OnGamepadButtonUp(const Events::GamepadButtonUp &event); - // Input binding events - EventRelay m_EBindKey; - bool OnBindKey(const Events::BindKey &event); - EventRelay m_EBindMouseButton; - bool OnBindMouseButton(const Events::BindMouseButton &event); - EventRelay m_EBindGamepadAxis; - bool OnBindGamepadAxis(const Events::BindGamepadAxis &event); - EventRelay m_EBindGamepadButton; - bool OnBindGamepadButton(const Events::BindGamepadButton &event); - - float GetCommandTotalValue(std::string command); - void PublishCommand(int playerID, std::string command, float value); -}; - -} - -#endif diff --git a/include/Engine/Input/KeyboardInputHandler.h b/include/Engine/Input/KeyboardInputHandler.h new file mode 100644 index 00000000..1ffaa067 --- /dev/null +++ b/include/Engine/Input/KeyboardInputHandler.h @@ -0,0 +1,67 @@ +#include +#include "InputProxy.h" +#include "Core/EKeyDown.h" +#include "Core/EKeyUp.h" + +class KeyboardInputHandler : public InputHandler +{ +public: + KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy) + : InputHandler(eventBroker, inputProxy) + { + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &KeyboardInputHandler::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &KeyboardInputHandler::OnKeyUp); + + m_OriginKeyCodes["R"] = GLFW_KEY_R; + } + + bool BindOrigin(std::string origin, std::string command, float value) override + { + auto originIt = m_OriginKeyCodes.find(origin); + if (originIt == m_OriginKeyCodes.end()) { + return false; + } + + int keyCode = originIt->second; + m_KeyBindings[keyCode] = std::make_tuple(command, value); + return true; + } + +private: + std::unordered_map m_OriginKeyCodes; + std::unordered_map> m_KeyBindings; // GLFW_KEY... -> command string & value + + EventRelay m_EKeyDown; + bool OnKeyDown(const Events::KeyDown& e) + { + auto it = m_KeyBindings.find(e.KeyCode); + if (it == m_KeyBindings.end()) { + return false; + } + + Events::InputCommand ic; + ic.PlayerID = 0; + std::tie(ic.Command, ic.Value) = it->second; + m_InputProxy->Publish(ic); + + return true; + } + + EventRelay m_EKeyUp; + bool OnKeyUp(const Events::KeyUp& e) + { + auto it = m_KeyBindings.find(e.KeyCode); + if (it == m_KeyBindings.end()) { + return false; + } + + Events::InputCommand ic; + ic.PlayerID = 0; + std::tie(ic.Command, std::ignore) = it->second; + ic.Value = 0; + m_InputProxy->Publish(ic); + + return true; + } + +}; \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index bc66d62f..04d14be0 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -9,6 +9,8 @@ #include "GUI/Frame.h" #include "Core/World.h" #include "Rendering/RenderQueueFactory.h" +#include "Input/InputProxy.h" +#include "Input/KeyboardInputHandler.h" #include "Core/EKeyDown.h" #include "Core/EntityXMLFile.h" #include "Core/SystemPipeline.h" @@ -30,6 +32,7 @@ private: EventBroker* m_EventBroker; IRenderer* m_Renderer; InputManager* m_InputManager; + InputProxy* m_InputProxy; GUI::Frame* m_FrameStack; World* m_World; SystemPipeline* m_SystemPipeline; diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index de24b9cf..97ed3e68 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -73,7 +73,7 @@ source_group(GUI FILES ${SOURCE_FILES_GUI}) set(SOURCE_FILES ${SOURCE_FILES_Core} ${SOURCE_FILES_Core_Util} - #${SOURCE_FILES_Input} + ${SOURCE_FILES_Input} ${SOURCE_FILES_Network} ${SOURCE_FILES_GUI} ${SOURCE_FILES_Rendering} diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp new file mode 100644 index 00000000..3a6626df --- /dev/null +++ b/src/Engine/Input/InputProxy.cpp @@ -0,0 +1,221 @@ +#include "Input/InputProxy.h" +#include "Core/World.h" + +//InputProxy::InputProxy(EventBroker* eventBroker) +// : m_EventBroker(eventBroker) +//{ +// // Subscribe to events +// EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &InputProxy::OnMousePress); +// EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &InputProxy::OnMouseRelease); +// EVENT_SUBSCRIBE_MEMBER(m_EGamepadAxis, &InputProxy::OnGamepadAxis); +// EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonDown, &InputProxy::OnGamepadButtonDown); +// EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonUp, &InputProxy::OnGamepadButtonUp); +// EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &InputProxy::OnBindKey); +// EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &InputProxy::OnBindMouseButton); +// EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadAxis, &InputProxy::OnBindGamepadAxis); +// EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadButton, &InputProxy::OnBindGamepadButton); +// +// SteamController()->Init(); +// +//} +// +//void InputProxy::Update(double dt) +//{ +// std::array controllers; +// int numControllers = SteamController()->GetConnectedControllers(controllers.data()); +// +// ControllerDigitalActionHandle_t debug_reload_handle = SteamController()->GetDigitalActionHandle("debug_reload"); +// SteamController()-> +//} +// +//bool InputProxy::OnKeyDown(const Events::KeyDown &event) +//{ +// auto range = m_KeyBindings.equal_range(event.KeyCode); +// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { +// std::string command; +// float value; +// std::tie(command, value) = bindingIt->second; +// m_CommandKeyboardValues[command][event.KeyCode] = value; +// PublishCommand(1, command, GetCommandTotalValue(command)); +// } +// +// return true; +//} +// +//bool InputProxy::OnKeyUp(const Events::KeyUp &event) +//{ +// auto range = m_KeyBindings.equal_range(event.KeyCode); +// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { +// std::string command; +// float value; +// std::tie(command, value) = bindingIt->second; +// m_CommandKeyboardValues[command][event.KeyCode] = 0; +// PublishCommand(1, command, GetCommandTotalValue(command));; +// } +// +// return true; +//} +// +//bool InputProxy::OnMousePress(const Events::MousePress &event) +//{ +// auto range = m_MouseButtonBindings.equal_range(event.Button); +// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { +// std::string command; +// float value; +// std::tie(command, value) = bindingIt->second; +// m_CommandMouseButtonValues[command][event.Button] = value; +// PublishCommand(1, command, GetCommandTotalValue(command)); +// } +// +// return true; +//} +// +//bool InputProxy::OnMouseRelease(const Events::MouseRelease &event) +//{ +// auto range = m_MouseButtonBindings.equal_range(event.Button); +// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { +// std::string command; +// float value; +// std::tie(command, value) = bindingIt->second; +// m_CommandMouseButtonValues[command][event.Button] = 0; +// PublishCommand(1, command, GetCommandTotalValue(command)); +// } +// +// return true; +//} +// +//bool InputProxy::OnGamepadAxis(const Events::GamepadAxis &event) +//{ +// auto range = m_GamepadAxisBindings.equal_range(event.Axis); +// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { +// std::string command; +// float value; +// std::tie(command, value) = bindingIt->second; +// m_CommandGamepadAxisValues[command][event.Axis] = event.Value * value; +// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); +// } +// +// return true; +//} +// +//bool InputProxy::OnGamepadButtonDown(const Events::GamepadButtonDown &event) +//{ +// auto range = m_GamepadButtonBindings.equal_range(event.Button); +// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { +// std::string command; +// float value; +// std::tie(command, value) = bindingIt->second; +// m_CommandGamepadButtonValues[command][event.Button] = value; +// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); +// } +// +// return true; +//} +// +//bool InputProxy::OnGamepadButtonUp(const Events::GamepadButtonUp &event) +//{ +// auto range = m_GamepadButtonBindings.equal_range(event.Button); +// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { +// std::string command; +// float value; +// std::tie(command, value) = bindingIt->second; +// m_CommandGamepadButtonValues[command][event.Button] = 0; +// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); +// } +// +// return true; +//} +// +//bool InputProxy::OnBindKey(const Events::BindKey &event) +//{ +// if (event.Command.empty()) { +// return false; +// } +// +// m_KeyBindings.insert(std::make_pair(event.KeyCode, std::make_tuple(event.Command, event.Value))); +// LOG_DEBUG("Input: Bound key %i to %s", event.KeyCode, event.Command.c_str()); +// +// return true; +//} +// +//bool InputProxy::OnBindMouseButton(const Events::BindMouseButton &event) +//{ +// if (event.Command.empty()) { +// return false; +// } +// +// m_MouseButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value))); +// LOG_DEBUG("Input: Bound mouse button %i to %s", event.Button, event.Command.c_str()); +// +// return true; +//} +// +//bool InputProxy::OnBindGamepadAxis(const Events::BindGamepadAxis &event) +//{ +// if (event.Command.empty()) { +// return false; +// } +// +// m_GamepadAxisBindings.insert(std::make_pair(event.Axis, std::make_tuple(event.Command, event.Value))); +// LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Axis, event.Command.c_str()); +// +// return true; +//} +// +//bool InputProxy::OnBindGamepadButton(const Events::BindGamepadButton &event) +//{ +// if (event.Command.empty()) { +// return false; +// } +// +// m_GamepadButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value))); +// LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Button, event.Command.c_str()); +// +// return true; +//} +// +//float InputProxy::GetCommandTotalValue(std::string command) +//{ +// float value = 0.f; +// +// auto keyboardIt = m_CommandKeyboardValues.find(command); +// if (keyboardIt != m_CommandKeyboardValues.end()) { +// for (auto &key : keyboardIt->second) { +// value += key.second; +// } +// } +// +// auto mouseButtonIt = m_CommandMouseButtonValues.find(command); +// if (mouseButtonIt != m_CommandMouseButtonValues.end()) { +// for (auto &button : mouseButtonIt->second) { +// value += button.second; +// } +// } +// +// auto gamepadAxisIt = m_CommandGamepadAxisValues.find(command); +// if (gamepadAxisIt != m_CommandGamepadAxisValues.end()) { +// for (auto &axis : gamepadAxisIt->second) { +// value += axis.second; +// } +// } +// +// auto gamepadButtonIt = m_CommandGamepadButtonValues.find(command); +// if (gamepadButtonIt != m_CommandGamepadButtonValues.end()) { +// for (auto &button : gamepadButtonIt->second) { +// value += button.second; +// } +// } +// +// return std::max(-1.f, std::min(value, 1.f)); +//} +// +//void InputProxy::PublishCommand(int playerID, std::string command, float value) +//{ +// Events::InputCommand e; +// e.PlayerID = playerID; +// e.Command = command; +// e.Value = value; +// m_EventBroker->Publish(e); +// +// LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, playerID); +//} diff --git a/src/Engine/Input/InputSystem.cpp b/src/Engine/Input/InputSystem.cpp deleted file mode 100644 index d11cd73d..00000000 --- a/src/Engine/Input/InputSystem.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "PrecompiledHeader.h" -#include "Input/InputSystem.h" -#include "Core/World.h" - -void Systems::InputSystem::RegisterComponents(ComponentFactory* cf) -{ - -} - -void Systems::InputSystem::Initialize() -{ - // Subscribe to events - EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Systems::InputSystem::OnKeyDown); - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Systems::InputSystem::OnKeyUp); - EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &Systems::InputSystem::OnMousePress); - EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &Systems::InputSystem::OnMouseRelease); - EVENT_SUBSCRIBE_MEMBER(m_EGamepadAxis, &Systems::InputSystem::OnGamepadAxis); - EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonDown, &Systems::InputSystem::OnGamepadButtonDown); - EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonUp, &Systems::InputSystem::OnGamepadButtonUp); - EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &Systems::InputSystem::OnBindKey); - EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &Systems::InputSystem::OnBindMouseButton); - EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadAxis, &Systems::InputSystem::OnBindGamepadAxis); - EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadButton, &Systems::InputSystem::OnBindGamepadButton); -} - -void Systems::InputSystem::Update(double dt) -{ - -} - -bool Systems::InputSystem::OnKeyDown(const Events::KeyDown &event) -{ - auto range = m_KeyBindings.equal_range(event.KeyCode); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandKeyboardValues[command][event.KeyCode] = value; - PublishCommand(1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnKeyUp(const Events::KeyUp &event) -{ - auto range = m_KeyBindings.equal_range(event.KeyCode); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandKeyboardValues[command][event.KeyCode] = 0; - PublishCommand(1, command, GetCommandTotalValue(command));; - } - - return true; -} - -bool Systems::InputSystem::OnMousePress(const Events::MousePress &event) -{ - auto range = m_MouseButtonBindings.equal_range(event.Button); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandMouseButtonValues[command][event.Button] = value; - PublishCommand(1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnMouseRelease(const Events::MouseRelease &event) -{ - auto range = m_MouseButtonBindings.equal_range(event.Button); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandMouseButtonValues[command][event.Button] = 0; - PublishCommand(1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnGamepadAxis(const Events::GamepadAxis &event) -{ - auto range = m_GamepadAxisBindings.equal_range(event.Axis); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandGamepadAxisValues[command][event.Axis] = event.Value * value; - PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnGamepadButtonDown(const Events::GamepadButtonDown &event) -{ - auto range = m_GamepadButtonBindings.equal_range(event.Button); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandGamepadButtonValues[command][event.Button] = value; - PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnGamepadButtonUp(const Events::GamepadButtonUp &event) -{ - auto range = m_GamepadButtonBindings.equal_range(event.Button); - for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { - std::string command; - float value; - std::tie(command, value) = bindingIt->second; - m_CommandGamepadButtonValues[command][event.Button] = 0; - PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); - } - - return true; -} - -bool Systems::InputSystem::OnBindKey(const Events::BindKey &event) -{ - if (event.Command.empty()) { - return false; - } - - m_KeyBindings.insert(std::make_pair(event.KeyCode, std::make_tuple(event.Command, event.Value))); - LOG_DEBUG("Input: Bound key %i to %s", event.KeyCode, event.Command.c_str()); - - return true; -} - -bool Systems::InputSystem::OnBindMouseButton(const Events::BindMouseButton &event) -{ - if (event.Command.empty()) { - return false; - } - - m_MouseButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value))); - LOG_DEBUG("Input: Bound mouse button %i to %s", event.Button, event.Command.c_str()); - - return true; -} - -bool Systems::InputSystem::OnBindGamepadAxis(const Events::BindGamepadAxis &event) -{ - if (event.Command.empty()) { - return false; - } - - m_GamepadAxisBindings.insert(std::make_pair(event.Axis, std::make_tuple(event.Command, event.Value))); - LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Axis, event.Command.c_str()); - - return true; -} - -bool Systems::InputSystem::OnBindGamepadButton(const Events::BindGamepadButton &event) -{ - if (event.Command.empty()) { - return false; - } - - m_GamepadButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value))); - LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Button, event.Command.c_str()); - - return true; -} - -float Systems::InputSystem::GetCommandTotalValue(std::string command) -{ - float value = 0.f; - - auto keyboardIt = m_CommandKeyboardValues.find(command); - if (keyboardIt != m_CommandKeyboardValues.end()) { - for (auto &key : keyboardIt->second) { - value += key.second; - } - } - - auto mouseButtonIt = m_CommandMouseButtonValues.find(command); - if (mouseButtonIt != m_CommandMouseButtonValues.end()) { - for (auto &button : mouseButtonIt->second) { - value += button.second; - } - } - - auto gamepadAxisIt = m_CommandGamepadAxisValues.find(command); - if (gamepadAxisIt != m_CommandGamepadAxisValues.end()) { - for (auto &axis : gamepadAxisIt->second) { - value += axis.second; - } - } - - auto gamepadButtonIt = m_CommandGamepadButtonValues.find(command); - if (gamepadButtonIt != m_CommandGamepadButtonValues.end()) { - for (auto &button : gamepadButtonIt->second) { - value += button.second; - } - } - - return std::max(-1.f, std::min(value, 1.f)); -} - -void Systems::InputSystem::PublishCommand(int playerID, std::string command, float value) -{ - Events::InputCommand e; - e.PlayerID = playerID; - e.Command = command; - e.Value = value; - EventBroker->Publish(e); - - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, playerID); -} diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index fa12bbc6..5451289e 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -29,6 +29,9 @@ Game::Game(int argc, char* argv[]) // Create input manager m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); + m_InputProxy = new InputProxy(m_EventBroker); + m_InputProxy->AddHandler(); + m_InputProxy->AddHandler(); // Create the root level GUI frame m_FrameStack = new GUI::Frame(m_EventBroker); @@ -66,9 +69,14 @@ void Game::Tick() double dt = currentTime - m_LastTime; m_LastTime = currentTime; + // Handle input in a weird looking but responsive way m_EventBroker->Swap(); m_InputManager->Update(dt); m_EventBroker->Swap(); + m_InputProxy->Update(dt); + m_EventBroker->Swap(); + m_InputProxy->Process(); + m_EventBroker->Swap(); // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); From 784a04b8ada504e080c5ec1b2b2caaa5d589a3a8 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 11 Dec 2015 10:58:32 +0100 Subject: [PATCH 24/65] Fixed bug in config file overriding. Previously it was silently overwriting the whole default config and relied on hardcoded values for defaults. --- src/Engine/Core/ConfigFile.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Engine/Core/ConfigFile.cpp b/src/Engine/Core/ConfigFile.cpp index 004ebc43..00ab4993 100644 --- a/src/Engine/Core/ConfigFile.cpp +++ b/src/Engine/Core/ConfigFile.cpp @@ -24,8 +24,11 @@ ConfigFile::ConfigFile(std::string path) if (boost::filesystem::exists(m_Path)) { try { boost::property_tree::ini_parser::read_ini(m_Path.string(), m_PTreeOverrides); - for (auto& node : m_PTreeOverrides) { - m_PTreeMerged.put_child(node.first, node.second); + for (auto& topLevelNode : m_PTreeOverrides) { + auto& mergedTopLevelNode = m_PTreeMerged.find(topLevelNode.first); + for (auto& childOverrideNode : topLevelNode.second) { + mergedTopLevelNode->second.put_child(childOverrideNode.first, childOverrideNode.second); + } } } catch (boost::property_tree::ptree_error& e) { LOG_ERROR("Failed to parse \"%s\":\n%s", m_Path.filename().string().c_str(), e.what()); From 5d46a10a4e35b3d9f273336f3a9d2bf336796ddd Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 11 Dec 2015 10:58:59 +0100 Subject: [PATCH 25/65] Added GetAll function to config file that returns a list of all top level keys in a config file --- include/Engine/Core/ConfigFile.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/include/Engine/Core/ConfigFile.h b/include/Engine/Core/ConfigFile.h index 28c34bd3..54bbbad4 100644 --- a/include/Engine/Core/ConfigFile.h +++ b/include/Engine/Core/ConfigFile.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "../Common.h" #include "ResourceManager.h" @@ -19,12 +20,14 @@ private: public: template T Get(std::string key, T defaultValue); + template + std::vector> GetAll(std::string key); template void Set(std::string key, T value); void SaveToDisk(); - private: +private: boost::filesystem::path m_Path; boost::property_tree::ptree m_PTreeDefaults; boost::property_tree::ptree m_PTreeOverrides; @@ -37,6 +40,21 @@ T ConfigFile::Get(std::string key, T defaultValue) return m_PTreeMerged.get(key, defaultValue); } +template +std::vector> ConfigFile::GetAll(std::string key) +{ + std::vector> out; + auto parent = m_PTreeMerged.find(key); + if (parent == m_PTreeMerged.not_found()) { + return out; + } + for (auto& child : parent->second) { + T value = boost::lexical_cast(child.second.data()); + out.push_back(std::make_pair(child.first, value)); + } + return out; +} + template void ConfigFile::Set(std::string key, T value) { From 35624008e74159d1ec3bd4cf5fc5d3bbf6af2a33 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 11 Dec 2015 11:39:20 +0100 Subject: [PATCH 26/65] InputProxy with a KeyboardInputHandler to translate keyboard keys to input commands. Input origins are bound to commands through the BindOrigin event, or through loading them from a config file. --- include/Engine/Input/EBindGamepadAxis.h | 24 -- include/Engine/Input/EBindGamepadButton.h | 26 -- include/Engine/Input/EBindKey.h | 25 -- include/Engine/Input/EBindMouseButton.h | 25 -- include/Engine/Input/InputHandler.h | 24 ++ include/Engine/Input/InputProxy.h | 149 ++-------- include/Engine/Input/KeyboardInputHandler.h | 61 +--- include/Game/Game.h | 8 +- resources/DefaultInput.ini | 9 + src/Engine/Input/InputProxy.cpp | 297 +++++--------------- src/Engine/Input/KeyboardInputHandler.cpp | 172 ++++++++++++ src/Game/Game.cpp | 16 +- tools/deploy.bat | 1 + 13 files changed, 328 insertions(+), 509 deletions(-) delete mode 100644 include/Engine/Input/EBindGamepadAxis.h delete mode 100644 include/Engine/Input/EBindGamepadButton.h delete mode 100644 include/Engine/Input/EBindKey.h delete mode 100644 include/Engine/Input/EBindMouseButton.h create mode 100644 include/Engine/Input/InputHandler.h create mode 100644 resources/DefaultInput.ini create mode 100644 src/Engine/Input/KeyboardInputHandler.cpp diff --git a/include/Engine/Input/EBindGamepadAxis.h b/include/Engine/Input/EBindGamepadAxis.h deleted file mode 100644 index 1f2665ad..00000000 --- a/include/Engine/Input/EBindGamepadAxis.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef Events_BindGamepadAxis_h__ -#define Events_BindGamepadAxis_h__ - -#include "Core/EventBroker.h" -#include "Core/EGamepadAxis.h" - -namespace Events -{ - -/** Called to bind a gamepad axis to an input command. */ -struct BindGamepadAxis : Event -{ - /** The axis to bind. */ - Gamepad::Axis Axis; - /** The command to send. */ - std::string Command; - /** The value to send for positive stimulation. - - Multiplied by the 0-1 clamped value of the axis. - */ - float Value; -}; - -} diff --git a/include/Engine/Input/EBindGamepadButton.h b/include/Engine/Input/EBindGamepadButton.h deleted file mode 100644 index 47dddf31..00000000 --- a/include/Engine/Input/EBindGamepadButton.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef Events_BindGamepadButton_h__ -#define Events_BindGamepadButton_h__ - -#include "Core/EventBroker.h" -#include "Core/EGamepadButton.h" - -namespace Events -{ - -/** Called to bind a gamepad button to an input command. */ -struct BindGamepadButton : Event -{ - /** The gamepad button to bind. */ - Gamepad::Button Button; - /** The command to send. */ - std::string Command; - /** The value to send for positive stimulation. - - Multiplied by the 0-1 clamped value of the button. - */ - float Value; -}; - -} - -#endif diff --git a/include/Engine/Input/EBindKey.h b/include/Engine/Input/EBindKey.h deleted file mode 100644 index fb1c199a..00000000 --- a/include/Engine/Input/EBindKey.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef Events_BindKey_h__ -#define Events_BindKey_h__ - -#include "Core/EventBroker.h" - -namespace Events -{ - -/** Called to bind a keyboard key to an input command. */ -struct BindKey : Event -{ - /** The GLFW key code to bind. */ - int KeyCode; - /** The command to send. */ - std::string Command; - /** The value to send for positive stimulation. - - Multiplied by the 0-1 clamped value of the key. - */ - float Value; -}; - -} - -#endif diff --git a/include/Engine/Input/EBindMouseButton.h b/include/Engine/Input/EBindMouseButton.h deleted file mode 100644 index 78b5dfa3..00000000 --- a/include/Engine/Input/EBindMouseButton.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef Events_BindMouseButton_h__ -#define Events_BindMouseButton_h__ - -#include "Core/EventBroker.h" - -namespace Events -{ - -/** Called to bind a mouse button to an input command. */ -struct BindMouseButton : Event -{ - /** The GLFW mouse button code to bind. */ - int Button; - /** The command to send. */ - std::string Command; - /** The value to send for positive stimulation. - - Multiplied by the 0-1 clamped value of the button. - */ - float Value; -}; - -} - -#endif diff --git a/include/Engine/Input/InputHandler.h b/include/Engine/Input/InputHandler.h new file mode 100644 index 00000000..c8ecb3af --- /dev/null +++ b/include/Engine/Input/InputHandler.h @@ -0,0 +1,24 @@ +#ifndef InputHandler_h__ +#define InputHandler_h__ + +#include "../Common.h" +#include "../Core/EventBroker.h" +#include "InputProxy.h" + +class InputHandler +{ +public: + InputHandler(EventBroker* eventBroker, InputProxy* inputProxy) + : m_EventBroker(eventBroker) + , m_InputProxy(inputProxy) + { } + + virtual void Update(double dt) { } + virtual bool BindOrigin(std::string origin, std::string command, float value) = 0; + +protected: + EventBroker* m_EventBroker; + InputProxy* m_InputProxy; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Input/InputProxy.h b/include/Engine/Input/InputProxy.h index 1b0e213e..d3ee57d9 100644 --- a/include/Engine/Input/InputProxy.h +++ b/include/Engine/Input/InputProxy.h @@ -1,146 +1,41 @@ -#ifndef InputSystem_h__ -#define InputSystem_h__ +#ifndef InputProxy_h__ +#define InputProxy_h__ -#include -#include - -#include - -#include "Core/EKeyUp.h" -#include "Core/EKeyDown.h" -#include "Core/EMousePress.h" -#include "Core/EMouseRelease.h" -#include "Core/EGamepadAxis.h" -#include "Core/EGamepadButton.h" -#include "Core/Util/EnumClassHash.h" -#include "EBindKey.h" -#include "EBindMouseButton.h" -#include "EBindGamepadAxis.h" -#include "EBindGamepadButton.h" +#include "../Common.h" +#include "../Core/ResourceManager.h" +#include "../Core/ConfigFile.h" #include "EInputCommand.h" #include "EBindOrigin.h" -class InputProxy; - -class InputHandler -{ -public: - InputHandler(EventBroker* eventBroker, InputProxy* inputProxy) - : m_EventBroker(eventBroker) - , m_InputProxy(inputProxy) - { } - - virtual void Update(double dt) { } - virtual bool BindOrigin(std::string origin, std::string command, float value) = 0; - -protected: - EventBroker* m_EventBroker; - InputProxy* m_InputProxy; -}; +class InputHandler; class InputProxy { public: - InputProxy(EventBroker* eventBroker) - : m_EventBroker(eventBroker) - { - EVENT_SUBSCRIBE_MEMBER(m_EBindOrigin, &InputProxy::OnBindOrigin); - } - - void Update(double dt) - { - m_EventBroker->Process(); - m_EventBroker->Process(); - for (auto& handler : m_Handlers) { - handler->Update(dt); - } - } - - void Process() - { - // Accumulate the input values of all unique commands published by input handlers - for (auto& pair : m_CommandQueue) { - Events::InputCommand e; - e.PlayerID = pair.first.first; - e.Command = pair.first.second; - e.Value = 0; - for (auto& value : pair.second) { - e.Value += value; - } - e.Value = std::max(-1.f, std::min(e.Value, 1.f)); - m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); - } - m_CommandQueue.clear(); - } - + InputProxy(EventBroker* eventBroker); + ~InputProxy(); + + void LoadBindings(std::string file); + void Update(double dt); + void Process(); template - void AddHandler() - { - m_Handlers.push_back(new T(m_EventBroker, this)); - } - - void Publish(const Events::InputCommand& e) - { - auto key = std::make_pair(e.PlayerID, e.Command); - m_CommandQueue[key].push_back(e.Value); - } + void AddHandler(); + void Publish(const Events::InputCommand& e); protected: EventBroker* m_EventBroker; std::vector m_Handlers; - // Represents every unique command (has of PlayerID & Command) and all values reported for that command + // Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame std::map, std::vector> m_CommandQueue; EventRelay m_EBindOrigin; - bool OnBindOrigin(const Events::BindOrigin& e) - { - bool originBound = false; - for (auto& handler : m_Handlers) { - bool result = handler->BindOrigin(e.Origin, e.Command, e.Value); - if (result) { - if (originBound) { - LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str()); - } - originBound = true; - } - } - - if (!originBound) { - LOG_ERROR("No input handler responded to binding input origin \"%s\"!", e.Origin.c_str()); - } - - return originBound; - } - //std::unordered_map> m_CommandMouseButtonValues; // command string -> mouse button value for command - //std::unordered_map> m_CommandGamepadAxisValues; // command string -> gamepad axis value for command - //std::unordered_map> m_CommandGamepadButtonValues; // command string -> gamepad button value for command - //// Input binding tables - //std::unordered_multimap> m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string - //std::unordered_multimap, EnumClassHash> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value - //std::unordered_multimap, EnumClassHash> m_GamepadButtonBindings; // Gamepad::Button -> command string - - //// Input events - //EventRelay m_EMousePress; - //bool OnMousePress(const Events::MousePress &event); - //EventRelay m_EMouseRelease; - //bool OnMouseRelease(const Events::MouseRelease &event); - //EventRelay m_EGamepadAxis; - //bool OnGamepadAxis(const Events::GamepadAxis &event); - //EventRelay m_EGamepadButtonDown; - //bool OnGamepadButtonDown(const Events::GamepadButtonDown &event); - //EventRelay m_EGamepadButtonUp; - //bool OnGamepadButtonUp(const Events::GamepadButtonUp &event); - //// Input binding events - //EventRelay m_EBindMouseButton; - //bool OnBindMouseButton(const Events::BindMouseButton &event); - //EventRelay m_EBindGamepadAxis; - //bool OnBindGamepadAxis(const Events::BindGamepadAxis &event); - //EventRelay m_EBindGamepadButton; - //bool OnBindGamepadButton(const Events::BindGamepadButton &event); - - //float GetCommandTotalValue(std::string command); - //void PublishCommand(int playerID, std::string command, float value); + bool OnBindOrigin(const Events::BindOrigin& e); }; +template +void InputProxy::AddHandler() +{ + m_Handlers.push_back(new T(m_EventBroker, this)); +} + #endif diff --git a/include/Engine/Input/KeyboardInputHandler.h b/include/Engine/Input/KeyboardInputHandler.h index 1ffaa067..53b08f7a 100644 --- a/include/Engine/Input/KeyboardInputHandler.h +++ b/include/Engine/Input/KeyboardInputHandler.h @@ -1,67 +1,26 @@ +#ifndef KeyboardInputHandler_h__ +#define KeyboardInputHandler_h__ + #include -#include "InputProxy.h" +#include "InputHandler.h" #include "Core/EKeyDown.h" #include "Core/EKeyUp.h" class KeyboardInputHandler : public InputHandler { public: - KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy) - : InputHandler(eventBroker, inputProxy) - { - EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &KeyboardInputHandler::OnKeyDown); - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &KeyboardInputHandler::OnKeyUp); + KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy); - m_OriginKeyCodes["R"] = GLFW_KEY_R; - } - - bool BindOrigin(std::string origin, std::string command, float value) override - { - auto originIt = m_OriginKeyCodes.find(origin); - if (originIt == m_OriginKeyCodes.end()) { - return false; - } - - int keyCode = originIt->second; - m_KeyBindings[keyCode] = std::make_tuple(command, value); - return true; - } + bool BindOrigin(std::string origin, std::string command, float value) override; private: std::unordered_map m_OriginKeyCodes; std::unordered_map> m_KeyBindings; // GLFW_KEY... -> command string & value EventRelay m_EKeyDown; - bool OnKeyDown(const Events::KeyDown& e) - { - auto it = m_KeyBindings.find(e.KeyCode); - if (it == m_KeyBindings.end()) { - return false; - } - - Events::InputCommand ic; - ic.PlayerID = 0; - std::tie(ic.Command, ic.Value) = it->second; - m_InputProxy->Publish(ic); - - return true; - } - + bool OnKeyDown(const Events::KeyDown& e); EventRelay m_EKeyUp; - bool OnKeyUp(const Events::KeyUp& e) - { - auto it = m_KeyBindings.find(e.KeyCode); - if (it == m_KeyBindings.end()) { - return false; - } + bool OnKeyUp(const Events::KeyUp& e); +}; - Events::InputCommand ic; - ic.PlayerID = 0; - std::tie(ic.Command, std::ignore) = it->second; - ic.Value = 0; - m_InputProxy->Publish(ic); - - return true; - } - -}; \ No newline at end of file +#endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 04d14be0..fbd4b017 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -38,11 +38,11 @@ private: SystemPipeline* m_SystemPipeline; RenderQueueFactory* m_RenderQueueFactory; - EventRelay m_EKeyUp; - bool testOnKeyUp(const Events::KeyUp& e); + EventRelay m_EInputCommand; + bool debugOnInputCommand(const Events::InputCommand& e); - void testIntialize(); - void testTick(double dt); + void debugInitialize(); + void debugTick(double dt); }; #endif diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini new file mode 100644 index 00000000..bc012c52 --- /dev/null +++ b/resources/DefaultInput.ini @@ -0,0 +1,9 @@ +[Bindings] +W=Forward +A=Left +S=Back +D=Right +R=Reload +Space=Jump +LeftControl=Crouch +LeftShift=Sprint diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp index 3a6626df..65f3f7b4 100644 --- a/src/Engine/Input/InputProxy.cpp +++ b/src/Engine/Input/InputProxy.cpp @@ -1,221 +1,80 @@ #include "Input/InputProxy.h" -#include "Core/World.h" +#include "Input/InputHandler.h" -//InputProxy::InputProxy(EventBroker* eventBroker) -// : m_EventBroker(eventBroker) -//{ -// // Subscribe to events -// EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &InputProxy::OnMousePress); -// EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &InputProxy::OnMouseRelease); -// EVENT_SUBSCRIBE_MEMBER(m_EGamepadAxis, &InputProxy::OnGamepadAxis); -// EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonDown, &InputProxy::OnGamepadButtonDown); -// EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonUp, &InputProxy::OnGamepadButtonUp); -// EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &InputProxy::OnBindKey); -// EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &InputProxy::OnBindMouseButton); -// EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadAxis, &InputProxy::OnBindGamepadAxis); -// EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadButton, &InputProxy::OnBindGamepadButton); -// -// SteamController()->Init(); -// -//} -// -//void InputProxy::Update(double dt) -//{ -// std::array controllers; -// int numControllers = SteamController()->GetConnectedControllers(controllers.data()); -// -// ControllerDigitalActionHandle_t debug_reload_handle = SteamController()->GetDigitalActionHandle("debug_reload"); -// SteamController()-> -//} -// -//bool InputProxy::OnKeyDown(const Events::KeyDown &event) -//{ -// auto range = m_KeyBindings.equal_range(event.KeyCode); -// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { -// std::string command; -// float value; -// std::tie(command, value) = bindingIt->second; -// m_CommandKeyboardValues[command][event.KeyCode] = value; -// PublishCommand(1, command, GetCommandTotalValue(command)); -// } -// -// return true; -//} -// -//bool InputProxy::OnKeyUp(const Events::KeyUp &event) -//{ -// auto range = m_KeyBindings.equal_range(event.KeyCode); -// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { -// std::string command; -// float value; -// std::tie(command, value) = bindingIt->second; -// m_CommandKeyboardValues[command][event.KeyCode] = 0; -// PublishCommand(1, command, GetCommandTotalValue(command));; -// } -// -// return true; -//} -// -//bool InputProxy::OnMousePress(const Events::MousePress &event) -//{ -// auto range = m_MouseButtonBindings.equal_range(event.Button); -// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { -// std::string command; -// float value; -// std::tie(command, value) = bindingIt->second; -// m_CommandMouseButtonValues[command][event.Button] = value; -// PublishCommand(1, command, GetCommandTotalValue(command)); -// } -// -// return true; -//} -// -//bool InputProxy::OnMouseRelease(const Events::MouseRelease &event) -//{ -// auto range = m_MouseButtonBindings.equal_range(event.Button); -// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { -// std::string command; -// float value; -// std::tie(command, value) = bindingIt->second; -// m_CommandMouseButtonValues[command][event.Button] = 0; -// PublishCommand(1, command, GetCommandTotalValue(command)); -// } -// -// return true; -//} -// -//bool InputProxy::OnGamepadAxis(const Events::GamepadAxis &event) -//{ -// auto range = m_GamepadAxisBindings.equal_range(event.Axis); -// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { -// std::string command; -// float value; -// std::tie(command, value) = bindingIt->second; -// m_CommandGamepadAxisValues[command][event.Axis] = event.Value * value; -// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); -// } -// -// return true; -//} -// -//bool InputProxy::OnGamepadButtonDown(const Events::GamepadButtonDown &event) -//{ -// auto range = m_GamepadButtonBindings.equal_range(event.Button); -// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { -// std::string command; -// float value; -// std::tie(command, value) = bindingIt->second; -// m_CommandGamepadButtonValues[command][event.Button] = value; -// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); -// } -// -// return true; -//} -// -//bool InputProxy::OnGamepadButtonUp(const Events::GamepadButtonUp &event) -//{ -// auto range = m_GamepadButtonBindings.equal_range(event.Button); -// for (auto bindingIt = range.first; bindingIt != range.second; bindingIt++) { -// std::string command; -// float value; -// std::tie(command, value) = bindingIt->second; -// m_CommandGamepadButtonValues[command][event.Button] = 0; -// PublishCommand(event.GamepadID + 1, command, GetCommandTotalValue(command)); -// } -// -// return true; -//} -// -//bool InputProxy::OnBindKey(const Events::BindKey &event) -//{ -// if (event.Command.empty()) { -// return false; -// } -// -// m_KeyBindings.insert(std::make_pair(event.KeyCode, std::make_tuple(event.Command, event.Value))); -// LOG_DEBUG("Input: Bound key %i to %s", event.KeyCode, event.Command.c_str()); -// -// return true; -//} -// -//bool InputProxy::OnBindMouseButton(const Events::BindMouseButton &event) -//{ -// if (event.Command.empty()) { -// return false; -// } -// -// m_MouseButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value))); -// LOG_DEBUG("Input: Bound mouse button %i to %s", event.Button, event.Command.c_str()); -// -// return true; -//} -// -//bool InputProxy::OnBindGamepadAxis(const Events::BindGamepadAxis &event) -//{ -// if (event.Command.empty()) { -// return false; -// } -// -// m_GamepadAxisBindings.insert(std::make_pair(event.Axis, std::make_tuple(event.Command, event.Value))); -// LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Axis, event.Command.c_str()); -// -// return true; -//} -// -//bool InputProxy::OnBindGamepadButton(const Events::BindGamepadButton &event) -//{ -// if (event.Command.empty()) { -// return false; -// } -// -// m_GamepadButtonBindings.insert(std::make_pair(event.Button, std::make_tuple(event.Command, event.Value))); -// LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Button, event.Command.c_str()); -// -// return true; -//} -// -//float InputProxy::GetCommandTotalValue(std::string command) -//{ -// float value = 0.f; -// -// auto keyboardIt = m_CommandKeyboardValues.find(command); -// if (keyboardIt != m_CommandKeyboardValues.end()) { -// for (auto &key : keyboardIt->second) { -// value += key.second; -// } -// } -// -// auto mouseButtonIt = m_CommandMouseButtonValues.find(command); -// if (mouseButtonIt != m_CommandMouseButtonValues.end()) { -// for (auto &button : mouseButtonIt->second) { -// value += button.second; -// } -// } -// -// auto gamepadAxisIt = m_CommandGamepadAxisValues.find(command); -// if (gamepadAxisIt != m_CommandGamepadAxisValues.end()) { -// for (auto &axis : gamepadAxisIt->second) { -// value += axis.second; -// } -// } -// -// auto gamepadButtonIt = m_CommandGamepadButtonValues.find(command); -// if (gamepadButtonIt != m_CommandGamepadButtonValues.end()) { -// for (auto &button : gamepadButtonIt->second) { -// value += button.second; -// } -// } -// -// return std::max(-1.f, std::min(value, 1.f)); -//} -// -//void InputProxy::PublishCommand(int playerID, std::string command, float value) -//{ -// Events::InputCommand e; -// e.PlayerID = playerID; -// e.Command = command; -// e.Value = value; -// m_EventBroker->Publish(e); -// -// LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, playerID); -//} +InputProxy::InputProxy(EventBroker* eventBroker) + : m_EventBroker(eventBroker) +{ + EVENT_SUBSCRIBE_MEMBER(m_EBindOrigin, &InputProxy::OnBindOrigin); +} + +InputProxy::~InputProxy() +{ + for (auto& handler : m_Handlers) { + delete handler; + } +} + +void InputProxy::LoadBindings(std::string file) +{ + auto config = ResourceManager::Load(file); + for (auto& origin : config->GetAll("Bindings")) { + Events::BindOrigin e; + e.Origin = origin.first; + e.Command = origin.second; + e.Value = 1.f; + OnBindOrigin(e); + } +} + +void InputProxy::Update(double dt) +{ + m_EventBroker->Process(); + m_EventBroker->Process(); + for (auto& handler : m_Handlers) { + handler->Update(dt); + } +} + +void InputProxy::Process() +{ + // Accumulate the input values of all unique commands published by input handlers + for (auto& pair : m_CommandQueue) { + Events::InputCommand e; + e.PlayerID = pair.first.first; + e.Command = pair.first.second; + e.Value = 0; + for (auto& value : pair.second) { + e.Value += value; + } + e.Value = std::max(-1.f, std::min(e.Value, 1.f)); + m_EventBroker->Publish(e); + LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + } + m_CommandQueue.clear(); +} + +void InputProxy::Publish(const Events::InputCommand& e) +{ + auto key = std::make_pair(e.PlayerID, e.Command); + m_CommandQueue[key].push_back(e.Value); +} + +bool InputProxy::OnBindOrigin(const Events::BindOrigin& e) +{ + bool originBound = false; + for (auto& handler : m_Handlers) { + bool result = handler->BindOrigin(e.Origin, e.Command, e.Value); + if (result) { + if (originBound) { + LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str()); + } + originBound = true; + } + } + + if (!originBound) { + LOG_ERROR("No input handler responded to binding input origin \"%s\"!", e.Origin.c_str()); + } + + return originBound; +} diff --git a/src/Engine/Input/KeyboardInputHandler.cpp b/src/Engine/Input/KeyboardInputHandler.cpp new file mode 100644 index 00000000..1686d8cd --- /dev/null +++ b/src/Engine/Input/KeyboardInputHandler.cpp @@ -0,0 +1,172 @@ +#include "Input/KeyboardInputHandler.h" + +KeyboardInputHandler::KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy) : InputHandler(eventBroker, inputProxy) +{ + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &KeyboardInputHandler::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &KeyboardInputHandler::OnKeyUp); + + m_OriginKeyCodes["Space"] = GLFW_KEY_SPACE; + m_OriginKeyCodes["Apostrophe"] = GLFW_KEY_APOSTROPHE; + m_OriginKeyCodes["Comma"] = GLFW_KEY_COMMA; + m_OriginKeyCodes["Minus"] = GLFW_KEY_MINUS; + m_OriginKeyCodes["Period"] = GLFW_KEY_PERIOD; + m_OriginKeyCodes["Slash"] = GLFW_KEY_SLASH; + m_OriginKeyCodes["0"] = GLFW_KEY_0; + m_OriginKeyCodes["1"] = GLFW_KEY_1; + m_OriginKeyCodes["2"] = GLFW_KEY_2; + m_OriginKeyCodes["3"] = GLFW_KEY_3; + m_OriginKeyCodes["4"] = GLFW_KEY_4; + m_OriginKeyCodes["5"] = GLFW_KEY_5; + m_OriginKeyCodes["6"] = GLFW_KEY_6; + m_OriginKeyCodes["7"] = GLFW_KEY_7; + m_OriginKeyCodes["8"] = GLFW_KEY_8; + m_OriginKeyCodes["9"] = GLFW_KEY_9; + m_OriginKeyCodes["Semicolon"] = GLFW_KEY_SEMICOLON; + m_OriginKeyCodes["Equal"] = GLFW_KEY_EQUAL; + m_OriginKeyCodes["A"] = GLFW_KEY_A; + m_OriginKeyCodes["B"] = GLFW_KEY_B; + m_OriginKeyCodes["C"] = GLFW_KEY_C; + m_OriginKeyCodes["D"] = GLFW_KEY_D; + m_OriginKeyCodes["E"] = GLFW_KEY_E; + m_OriginKeyCodes["F"] = GLFW_KEY_F; + m_OriginKeyCodes["G"] = GLFW_KEY_G; + m_OriginKeyCodes["H"] = GLFW_KEY_H; + m_OriginKeyCodes["I"] = GLFW_KEY_I; + m_OriginKeyCodes["J"] = GLFW_KEY_J; + m_OriginKeyCodes["K"] = GLFW_KEY_K; + m_OriginKeyCodes["L"] = GLFW_KEY_L; + m_OriginKeyCodes["M"] = GLFW_KEY_M; + m_OriginKeyCodes["N"] = GLFW_KEY_N; + m_OriginKeyCodes["O"] = GLFW_KEY_O; + m_OriginKeyCodes["P"] = GLFW_KEY_P; + m_OriginKeyCodes["Q"] = GLFW_KEY_Q; + m_OriginKeyCodes["R"] = GLFW_KEY_R; + m_OriginKeyCodes["S"] = GLFW_KEY_S; + m_OriginKeyCodes["T"] = GLFW_KEY_T; + m_OriginKeyCodes["U"] = GLFW_KEY_U; + m_OriginKeyCodes["V"] = GLFW_KEY_V; + m_OriginKeyCodes["W"] = GLFW_KEY_W; + m_OriginKeyCodes["X"] = GLFW_KEY_X; + m_OriginKeyCodes["Y"] = GLFW_KEY_Y; + m_OriginKeyCodes["Z"] = GLFW_KEY_Z; + m_OriginKeyCodes["LeftBracket"] = GLFW_KEY_LEFT_BRACKET; + m_OriginKeyCodes["Backslash"] = GLFW_KEY_BACKSLASH; + m_OriginKeyCodes["RightBracket"] = GLFW_KEY_RIGHT_BRACKET; + m_OriginKeyCodes["Accent"] = GLFW_KEY_GRAVE_ACCENT; + m_OriginKeyCodes["W1"] = GLFW_KEY_WORLD_1; + m_OriginKeyCodes["W2"] = GLFW_KEY_WORLD_2; + m_OriginKeyCodes["Escape"] = GLFW_KEY_ESCAPE; + m_OriginKeyCodes["Enter"] = GLFW_KEY_ENTER; + m_OriginKeyCodes["Tab"] = GLFW_KEY_TAB; + m_OriginKeyCodes["Backspace"] = GLFW_KEY_BACKSPACE; + m_OriginKeyCodes["Insert"] = GLFW_KEY_INSERT; + m_OriginKeyCodes["Delete"] = GLFW_KEY_DELETE; + m_OriginKeyCodes["Right"] = GLFW_KEY_RIGHT; + m_OriginKeyCodes["Left"] = GLFW_KEY_LEFT; + m_OriginKeyCodes["Down"] = GLFW_KEY_DOWN; + m_OriginKeyCodes["Up"] = GLFW_KEY_UP; + m_OriginKeyCodes["PgUp"] = GLFW_KEY_PAGE_UP; + m_OriginKeyCodes["PgDn"] = GLFW_KEY_PAGE_DOWN; + m_OriginKeyCodes["Home"] = GLFW_KEY_HOME; + m_OriginKeyCodes["End"] = GLFW_KEY_END; + m_OriginKeyCodes["CapsLock"] = GLFW_KEY_CAPS_LOCK; + m_OriginKeyCodes["ScrollLock"] = GLFW_KEY_SCROLL_LOCK; + m_OriginKeyCodes["NumLock"] = GLFW_KEY_NUM_LOCK; + m_OriginKeyCodes["PrintScreen"] = GLFW_KEY_PRINT_SCREEN; + m_OriginKeyCodes["Pause"] = GLFW_KEY_PAUSE; + m_OriginKeyCodes["F1"] = GLFW_KEY_F1; + m_OriginKeyCodes["F2"] = GLFW_KEY_F2; + m_OriginKeyCodes["F3"] = GLFW_KEY_F3; + m_OriginKeyCodes["F4"] = GLFW_KEY_F4; + m_OriginKeyCodes["F5"] = GLFW_KEY_F5; + m_OriginKeyCodes["F6"] = GLFW_KEY_F6; + m_OriginKeyCodes["F7"] = GLFW_KEY_F7; + m_OriginKeyCodes["F8"] = GLFW_KEY_F8; + m_OriginKeyCodes["F9"] = GLFW_KEY_F9; + m_OriginKeyCodes["F10"] = GLFW_KEY_F10; + m_OriginKeyCodes["F11"] = GLFW_KEY_F11; + m_OriginKeyCodes["F12"] = GLFW_KEY_F12; + m_OriginKeyCodes["F13"] = GLFW_KEY_F13; + m_OriginKeyCodes["F14"] = GLFW_KEY_F14; + m_OriginKeyCodes["F15"] = GLFW_KEY_F15; + m_OriginKeyCodes["F16"] = GLFW_KEY_F16; + m_OriginKeyCodes["F17"] = GLFW_KEY_F17; + m_OriginKeyCodes["F18"] = GLFW_KEY_F18; + m_OriginKeyCodes["F19"] = GLFW_KEY_F19; + m_OriginKeyCodes["F20"] = GLFW_KEY_F20; + m_OriginKeyCodes["F21"] = GLFW_KEY_F21; + m_OriginKeyCodes["F22"] = GLFW_KEY_F22; + m_OriginKeyCodes["F23"] = GLFW_KEY_F23; + m_OriginKeyCodes["F24"] = GLFW_KEY_F24; + m_OriginKeyCodes["F25"] = GLFW_KEY_F25; + m_OriginKeyCodes["KP0"] = GLFW_KEY_KP_0; + m_OriginKeyCodes["KP1"] = GLFW_KEY_KP_1; + m_OriginKeyCodes["KP2"] = GLFW_KEY_KP_2; + m_OriginKeyCodes["KP3"] = GLFW_KEY_KP_3; + m_OriginKeyCodes["KP4"] = GLFW_KEY_KP_4; + m_OriginKeyCodes["KP5"] = GLFW_KEY_KP_5; + m_OriginKeyCodes["KP6"] = GLFW_KEY_KP_6; + m_OriginKeyCodes["KP7"] = GLFW_KEY_KP_7; + m_OriginKeyCodes["KP8"] = GLFW_KEY_KP_8; + m_OriginKeyCodes["KP9"] = GLFW_KEY_KP_9; + m_OriginKeyCodes["KPDecimal"] = GLFW_KEY_KP_DECIMAL; + m_OriginKeyCodes["KPDivide"] = GLFW_KEY_KP_DIVIDE; + m_OriginKeyCodes["KPMultiply"] = GLFW_KEY_KP_MULTIPLY; + m_OriginKeyCodes["KPSubtract"] = GLFW_KEY_KP_SUBTRACT; + m_OriginKeyCodes["KPAdd"] = GLFW_KEY_KP_ADD; + m_OriginKeyCodes["KPEnter"] = GLFW_KEY_KP_ENTER; + m_OriginKeyCodes["KPEqual"] = GLFW_KEY_KP_EQUAL; + m_OriginKeyCodes["LeftShift"] = GLFW_KEY_LEFT_SHIFT; + m_OriginKeyCodes["LeftControl"] = GLFW_KEY_LEFT_CONTROL; + m_OriginKeyCodes["LeftAlt"] = GLFW_KEY_LEFT_ALT; + m_OriginKeyCodes["LeftSuper"] = GLFW_KEY_LEFT_SUPER; + m_OriginKeyCodes["RightShift"] = GLFW_KEY_RIGHT_SHIFT; + m_OriginKeyCodes["RightControl"] = GLFW_KEY_RIGHT_CONTROL; + m_OriginKeyCodes["RightAlt"] = GLFW_KEY_RIGHT_ALT; + m_OriginKeyCodes["RightSuper"] = GLFW_KEY_RIGHT_SUPER; + m_OriginKeyCodes["Menu"] = GLFW_KEY_MENU; +} + +bool KeyboardInputHandler::BindOrigin(std::string origin, std::string command, float value) +{ + auto originIt = m_OriginKeyCodes.find(origin); + if (originIt == m_OriginKeyCodes.end()) { + return false; + } + + int keyCode = originIt->second; + m_KeyBindings[keyCode] = std::make_tuple(command, value); + return true; +} + +bool KeyboardInputHandler::OnKeyDown(const Events::KeyDown& e) +{ + auto it = m_KeyBindings.find(e.KeyCode); + if (it == m_KeyBindings.end()) { + return false; + } + + Events::InputCommand ic; + ic.PlayerID = 0; + std::tie(ic.Command, ic.Value) = it->second; + m_InputProxy->Publish(ic); + + return true; +} + +bool KeyboardInputHandler::OnKeyUp(const Events::KeyUp& e) +{ + auto it = m_KeyBindings.find(e.KeyCode); + if (it == m_KeyBindings.end()) { + return false; + } + + Events::InputCommand ic; + ic.PlayerID = 0; + std::tie(ic.Command, std::ignore) = it->second; + ic.Value = 0; + m_InputProxy->Publish(ic); + + return true; +} + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 5451289e..5ae9295a 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -31,7 +31,7 @@ Game::Game(int argc, char* argv[]) m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); m_InputProxy = new InputProxy(m_EventBroker); m_InputProxy->AddHandler(); - m_InputProxy->AddHandler(); + m_InputProxy->LoadBindings("Input.ini"); // Create the root level GUI frame m_FrameStack = new GUI::Frame(m_EventBroker); @@ -54,7 +54,7 @@ Game::Game(int argc, char* argv[]) m_LastTime = glfwGetTime(); - testIntialize(); + debugInitialize(); } Game::~Game() @@ -80,7 +80,7 @@ void Game::Tick() // Iterate through systems and update world! m_SystemPipeline->Update(m_World, dt); - testTick(dt); + debugTick(dt); m_Renderer->Update(dt); m_RenderQueueFactory->Update(m_World); @@ -93,9 +93,9 @@ void Game::Tick() } -bool Game::testOnKeyUp(const Events::KeyUp& e) +bool Game::debugOnInputCommand(const Events::InputCommand& e) { - if (e.KeyCode == GLFW_KEY_R) { + if (e.Command == "DebugReload" && e.Value == 1) { std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); if (!mapToLoad.empty()) { delete m_World; @@ -108,12 +108,12 @@ bool Game::testOnKeyUp(const Events::KeyUp& e) return false; } -void Game::testIntialize() +void Game::debugInitialize() { - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Game::testOnKeyUp); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Game::debugOnInputCommand); } -void Game::testTick(double dt) +void Game::debugTick(double dt) { m_EventBroker->Process(); } diff --git a/tools/deploy.bat b/tools/deploy.bat index 5ef074ef..22d513e6 100755 --- a/tools/deploy.bat +++ b/tools/deploy.bat @@ -21,6 +21,7 @@ RMDIR /S /Q "%DeployLocation%\Shaders" MKLINK "%DeployLocation%\Shaders\" "resources\Shaders" /J :: Configuration files MKLINK "%DeployLocation%\DefaultConfig.ini" "resources\DefaultConfig.ini" /H +MKLINK "%DeployLocation%\DefaultInput.ini" "resources\DefaultInput.ini" /H :: Platform specific binaries IF "%~1"=="" GOTO :EOF From 013f911ae262f71e6679f9aa6282aabd023e63ca Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 11 Dec 2015 14:49:43 +0100 Subject: [PATCH 27/65] Added MouseInputHandler and firstPersonInputController to aid in creation of first person movement. --- include/Engine/Core/InputController.h | 11 +- .../Engine/Input/FirstPersonInputController.h | 40 ++++++ include/Engine/Input/MouseInputHandler.h | 33 +++++ include/Game/Game.h | 1 + resources/DefaultInput.ini | 4 + src/Engine/Input/InputProxy.cpp | 2 +- src/Engine/Input/MouseInputHandler.cpp | 121 ++++++++++++++++++ src/Game/Game.cpp | 1 + 8 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 include/Engine/Input/FirstPersonInputController.h create mode 100644 include/Engine/Input/MouseInputHandler.h create mode 100644 src/Engine/Input/MouseInputHandler.cpp diff --git a/include/Engine/Core/InputController.h b/include/Engine/Core/InputController.h index b91fb448..b87d1eff 100644 --- a/include/Engine/Core/InputController.h +++ b/include/Engine/Core/InputController.h @@ -11,25 +11,22 @@ template class InputController { public: - InputController(std::shared_ptr eventBroker) - : EventBroker(eventBroker) + InputController(EventBroker* eventBroker) + : m_EventBroker(eventBroker) { Initialize(); } virtual void Initialize() { EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &InputController::OnCommand); - EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &InputController::OnMouseMove); } - virtual bool OnCommand(const Events::InputCommand &event) { return false; } - virtual bool OnMouseMove(const Events::MouseMove &event) { return false; } + virtual bool OnCommand(const Events::InputCommand& e) { return false; } protected: - std::shared_ptr EventBroker; + EventBroker* m_EventBroker; private: EventRelay m_EInputCommand; - EventRelay m_EMouseMove; }; #endif diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h new file mode 100644 index 00000000..e8b832b5 --- /dev/null +++ b/include/Engine/Input/FirstPersonInputController.h @@ -0,0 +1,40 @@ +#ifndef FirstPersonInputController_h__ +#define FirstPersonInputController_h__ + +#include "../GLM.h" +#include "../Core/InputController.h" + +template +class FirstPersonInputController : public InputController +{ +public: + FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID) + : InputController(eventBroker) + , m_PlayerID(playerID) + { } + + const glm::quat Orientation() const { return m_Orientation; } + + virtual bool OnCommand(const Events::InputCommand& e) override + { + if (m_PlayerID != e.PlayerID) { + return false; + } + + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1, 0, 0)); + } + + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1, 0)) * m_Orientation; + } + } + +private: + const unsigned int m_PlayerID; + glm::quat m_Orientation; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Input/MouseInputHandler.h b/include/Engine/Input/MouseInputHandler.h new file mode 100644 index 00000000..39889755 --- /dev/null +++ b/include/Engine/Input/MouseInputHandler.h @@ -0,0 +1,33 @@ +#ifndef MouseInputHandler_h__ +#define MouseInputHandler_h__ + +#include +#include "InputHandler.h" +#include "Core/EMousePress.h" +#include "Core/EMouseRelease.h" +#include "Core/EMouseMove.h" + +class MouseInputHandler : public InputHandler +{ +public: + MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy); + + bool BindOrigin(std::string origin, std::string command, float value) override; + +private: + std::unordered_map m_OriginCodes; + std::unordered_map m_OriginAxes; + std::unordered_map> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value + std::unordered_map> m_Axes; // Axis -> command string & value + + EventRelay m_EMousePress; + bool OnMousePress(const Events::MousePress& e); + EventRelay m_EMouseRelease; + bool OnMouseRelease(const Events::MouseRelease& e); + EventRelay m_EMouseMove; + bool OnMouseMove(const Events::MouseMove& e); + + bool hasOrigin(std::string origin); +}; + +#endif diff --git a/include/Game/Game.h b/include/Game/Game.h index fbd4b017..57941e55 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -11,6 +11,7 @@ #include "Rendering/RenderQueueFactory.h" #include "Input/InputProxy.h" #include "Input/KeyboardInputHandler.h" +#include "Input/MouseInputHandler.h" #include "Core/EKeyDown.h" #include "Core/EntityXMLFile.h" #include "Core/SystemPipeline.h" diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index bc012c52..b6bbd20f 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -1,3 +1,7 @@ +[Mouse] +Sensitivity=0.5 +InvertPitch=false + [Bindings] W=Forward A=Left diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp index 65f3f7b4..430cb250 100644 --- a/src/Engine/Input/InputProxy.cpp +++ b/src/Engine/Input/InputProxy.cpp @@ -46,7 +46,7 @@ void InputProxy::Process() for (auto& value : pair.second) { e.Value += value; } - e.Value = std::max(-1.f, std::min(e.Value, 1.f)); + //e.Value = std::max(-1.f, std::min(e.Value, 1.f)); m_EventBroker->Publish(e); LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); } diff --git a/src/Engine/Input/MouseInputHandler.cpp b/src/Engine/Input/MouseInputHandler.cpp new file mode 100644 index 00000000..2e9c8137 --- /dev/null +++ b/src/Engine/Input/MouseInputHandler.cpp @@ -0,0 +1,121 @@ +#include "Input/MouseInputHandler.h" + +MouseInputHandler::MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy) + : InputHandler(eventBroker, inputProxy) +{ + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &MouseInputHandler::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &MouseInputHandler::OnMouseRelease); + EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &MouseInputHandler::OnMouseMove); + + m_OriginCodes["Mouse1"] = GLFW_MOUSE_BUTTON_1; + m_OriginCodes["MouseLeft"] = GLFW_MOUSE_BUTTON_LEFT; + m_OriginCodes["Mouse2"] = GLFW_MOUSE_BUTTON_2; + m_OriginCodes["MouseRight"] = GLFW_MOUSE_BUTTON_RIGHT; + m_OriginCodes["Mouse3"] = GLFW_MOUSE_BUTTON_3; + m_OriginCodes["MouseMiddle"] = GLFW_MOUSE_BUTTON_MIDDLE; + m_OriginCodes["Mouse4"] = GLFW_MOUSE_BUTTON_4; + m_OriginCodes["Mouse5"] = GLFW_MOUSE_BUTTON_5; + m_OriginCodes["Mouse6"] = GLFW_MOUSE_BUTTON_6; + m_OriginCodes["Mouse7"] = GLFW_MOUSE_BUTTON_7; + m_OriginCodes["Mouse8"] = GLFW_MOUSE_BUTTON_8; + + m_OriginAxes["MouseX"] = 'X'; + m_OriginAxes["MouseY"] = 'Y'; +} + +bool MouseInputHandler::BindOrigin(std::string origin, std::string command, float value) +{ + auto originCode = m_OriginCodes.find(origin); + if (originCode != m_OriginCodes.end()) { + int code = originCode->second; + m_Bindings[code] = std::make_tuple(command, value); + return true; + } + + auto originAxis = m_OriginAxes.find(origin); + if (originAxis != m_OriginAxes.end()) { + char axis = originAxis->second; + float multiplier = 1.f; + // Sensitivity + multiplier *= ResourceManager::Load("Input.ini")->Get("Mouse.Sensitivity", 1.f); + if (axis == 'Y') { + if (ResourceManager::Load("Input.ini")->Get("Mouse.InvertPitch", false)) { + multiplier *= -1.f; + } + } + m_Axes[axis] = std::make_tuple(command, value * multiplier); + return true; + } + + return false; +} + +bool MouseInputHandler::OnMousePress(const Events::MousePress& e) +{ + auto it = m_Bindings.find(e.Button); + if (it == m_Bindings.end()) { + return false; + } + + Events::InputCommand ic; + ic.PlayerID = 0; + std::tie(ic.Command, ic.Value) = it->second; + m_InputProxy->Publish(ic); + + return true; +} + +bool MouseInputHandler::OnMouseRelease(const Events::MouseRelease& e) +{ + auto it = m_Bindings.find(e.Button); + if (it == m_Bindings.end()) { + return false; + } + + Events::InputCommand ic; + ic.PlayerID = 0; + std::tie(ic.Command, std::ignore) = it->second; + ic.Value = 0; + m_InputProxy->Publish(ic); + + return true; +} + +bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e) +{ + if (std::abs(e.DeltaX) > 0) { + auto it = m_Axes.find('X'); + if (it != m_Axes.end()) { + Events::InputCommand ic; + ic.PlayerID = 0; + std::tie(ic.Command, ic.Value) = it->second; + ic.Value *= e.DeltaX; + m_InputProxy->Publish(ic); + } + } + + if (std::abs(e.DeltaY) > 0) { + auto it = m_Axes.find('Y'); + if (it != m_Axes.end()) { + Events::InputCommand ic; + ic.PlayerID = 0; + std::tie(ic.Command, ic.Value) = it->second; + ic.Value *= e.DeltaY; + m_InputProxy->Publish(ic); + } + } + + return true; +} + +bool MouseInputHandler::hasOrigin(std::string origin) +{ + if (m_OriginCodes.find(origin) == m_OriginCodes.end()) { + return false; + } + if (m_OriginAxes.find(origin) == m_OriginAxes.end()) { + return false; + } + return true; +} + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 5ae9295a..be988529 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -31,6 +31,7 @@ Game::Game(int argc, char* argv[]) m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); m_InputProxy = new InputProxy(m_EventBroker); m_InputProxy->AddHandler(); + m_InputProxy->AddHandler(); m_InputProxy->LoadBindings("Input.ini"); // Create the root level GUI frame From 2e7e8d3546f9248ca20b609b043b7727e946883e Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 11 Dec 2015 14:50:14 +0100 Subject: [PATCH 28/65] Clearing raw input events from event broker to encourage use of input commands instead --- src/Game/Game.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index be988529..b7391bac 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -76,6 +76,7 @@ void Game::Tick() m_EventBroker->Swap(); m_InputProxy->Update(dt); m_EventBroker->Swap(); + m_EventBroker->Clear(); m_InputProxy->Process(); m_EventBroker->Swap(); From 03e226ffeaa34d26fee2bd60fa9e6d0081418ab9 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 11 Dec 2015 17:15:33 +0100 Subject: [PATCH 29/65] Refactored InputProxy to gracefully handle cases where multiple origins send the same command --- .../Engine/Input/FirstPersonInputController.h | 48 ++++++++++++++---- include/Engine/Input/InputHandler.h | 3 +- include/Engine/Input/InputProxy.h | 8 ++- include/Engine/Input/KeyboardInputHandler.h | 2 + resources/DefaultInput.ini | 11 +++-- src/Engine/Input/InputProxy.cpp | 49 ++++++++++++------- src/Engine/Input/KeyboardInputHandler.cpp | 27 ++++++---- 7 files changed, 104 insertions(+), 44 deletions(-) diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index e8b832b5..d8584494 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -3,6 +3,7 @@ #include "../GLM.h" #include "../Core/InputController.h" +#include "../Core/ELockMouse.h" template class FirstPersonInputController : public InputController @@ -11,9 +12,26 @@ public: FirstPersonInputController(EventBroker* eventBroker, unsigned int playerID) : InputController(eventBroker) , m_PlayerID(playerID) - { } + { + EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &FirstPersonInputController::OnLockMouse); + EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &FirstPersonInputController::OnUnlockMouse); + } const glm::quat Orientation() const { return m_Orientation; } + + void LockMouse() + { + Events::LockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = true; + } + + void UnlockMouse() + { + Events::UnlockMouse e; + m_EventBroker->Publish(e); + m_MouseLocked = false; + } virtual bool OnCommand(const Events::InputCommand& e) override { @@ -21,20 +39,32 @@ public: return false; } - if (e.Command == "Pitch") { - float val = glm::radians(e.Value); - m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1, 0, 0)); + if (m_MouseLocked) { + if (e.Command == "Pitch") { + float val = glm::radians(e.Value); + m_Orientation = m_Orientation * glm::angleAxis(-val, glm::vec3(1, 0, 0)); + return true; + } + + if (e.Command == "Yaw") { + float val = glm::radians(e.Value); + m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1, 0)) * m_Orientation; + return true; + } } - if (e.Command == "Yaw") { - float val = glm::radians(e.Value); - m_Orientation = glm::angleAxis(-val, glm::vec3(0, 1, 0)) * m_Orientation; - } + return false; } -private: +protected: const unsigned int m_PlayerID; glm::quat m_Orientation; + bool m_MouseLocked = false; + + EventRelay m_ELockMouse; + bool OnLockMouse(const Events::LockMouse& e) { m_MouseLocked = true; return true; } + EventRelay m_EUnlockMouse; + bool OnUnlockMouse(const Events::UnlockMouse& e) { m_MouseLocked = false; return true; } }; #endif \ No newline at end of file diff --git a/include/Engine/Input/InputHandler.h b/include/Engine/Input/InputHandler.h index c8ecb3af..a9b3c038 100644 --- a/include/Engine/Input/InputHandler.h +++ b/include/Engine/Input/InputHandler.h @@ -13,8 +13,9 @@ public: , m_InputProxy(inputProxy) { } - virtual void Update(double dt) { } virtual bool BindOrigin(std::string origin, std::string command, float value) = 0; + virtual void Update(double dt) { } + virtual float GetCommandValue(std::string command) = 0; protected: EventBroker* m_EventBroker; diff --git a/include/Engine/Input/InputProxy.h b/include/Engine/Input/InputProxy.h index d3ee57d9..43c4940c 100644 --- a/include/Engine/Input/InputProxy.h +++ b/include/Engine/Input/InputProxy.h @@ -20,13 +20,17 @@ public: void Process(); template void AddHandler(); - void Publish(const Events::InputCommand& e); protected: EventBroker* m_EventBroker; std::vector m_Handlers; + std::map> m_CommandHandlers; + // Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame - std::map, std::vector> m_CommandQueue; + //std::map, std::vector> m_CommandQueue; + + std::map m_CurrentCommandValues; + std::map m_LastCommandValues; EventRelay m_EBindOrigin; bool OnBindOrigin(const Events::BindOrigin& e); diff --git a/include/Engine/Input/KeyboardInputHandler.h b/include/Engine/Input/KeyboardInputHandler.h index 53b08f7a..49597fce 100644 --- a/include/Engine/Input/KeyboardInputHandler.h +++ b/include/Engine/Input/KeyboardInputHandler.h @@ -12,10 +12,12 @@ public: KeyboardInputHandler(EventBroker* eventBroker, InputProxy* inputProxy); bool BindOrigin(std::string origin, std::string command, float value) override; + virtual float GetCommandValue(std::string command) override; private: std::unordered_map m_OriginKeyCodes; std::unordered_map> m_KeyBindings; // GLFW_KEY... -> command string & value + std::unordered_map m_CommandValues; EventRelay m_EKeyDown; bool OnKeyDown(const Events::KeyDown& e); diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index b6bbd20f..3be67287 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -3,10 +3,13 @@ Sensitivity=0.5 InvertPitch=false [Bindings] -W=Forward -A=Left -S=Back -D=Right +MouseLeft=PrimaryFire +MouseX=Yaw +MouseY=Pitch +W=+Forward +S=-Forward +D=+Right +A=-Right R=Reload Space=Jump LeftControl=Crouch diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp index 430cb250..3fe29b7d 100644 --- a/src/Engine/Input/InputProxy.cpp +++ b/src/Engine/Input/InputProxy.cpp @@ -22,7 +22,16 @@ void InputProxy::LoadBindings(std::string file) e.Origin = origin.first; e.Command = origin.second; e.Value = 1.f; - OnBindOrigin(e); + if (!e.Command.empty()) { + char prefix = e.Command.at(0); + if (prefix == '+' || prefix == '-') { + e.Command = e.Command.substr(1); + if (prefix == '-') { + e.Value *= -1.f; + } + } + OnBindOrigin(e); + } } } @@ -37,26 +46,26 @@ void InputProxy::Update(double dt) void InputProxy::Process() { - // Accumulate the input values of all unique commands published by input handlers - for (auto& pair : m_CommandQueue) { - Events::InputCommand e; - e.PlayerID = pair.first.first; - e.Command = pair.first.second; - e.Value = 0; - for (auto& value : pair.second) { - e.Value += value; + for (auto& pair : m_CommandHandlers) { + const std::string& command = pair.first; + auto handlers = pair.second; + m_CurrentCommandValues[command] = 0.f; + for (auto& handler : handlers) { + m_CurrentCommandValues[command] += handler->GetCommandValue(command); } - //e.Value = std::max(-1.f, std::min(e.Value, 1.f)); - m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); - } - m_CommandQueue.clear(); -} -void InputProxy::Publish(const Events::InputCommand& e) -{ - auto key = std::make_pair(e.PlayerID, e.Command); - m_CommandQueue[key].push_back(e.Value); + auto last = m_LastCommandValues.find(command); + float currentValue = m_CurrentCommandValues[command]; + if (last == m_LastCommandValues.end() || last->second != currentValue) { + Events::InputCommand e; + e.PlayerID = -1; + e.Command = command; + e.Value = currentValue; + m_EventBroker->Publish(e); + LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + m_LastCommandValues[command] = currentValue; + } + } } bool InputProxy::OnBindOrigin(const Events::BindOrigin& e) @@ -65,6 +74,8 @@ bool InputProxy::OnBindOrigin(const Events::BindOrigin& e) for (auto& handler : m_Handlers) { bool result = handler->BindOrigin(e.Origin, e.Command, e.Value); if (result) { + m_CommandHandlers[e.Command].insert(handler); + m_LastCommandValues[e.Command] = 0.f; if (originBound) { LOG_WARNING("Multiple handlers responded to binding input origin \"%s\"!", e.Origin.c_str()); } diff --git a/src/Engine/Input/KeyboardInputHandler.cpp b/src/Engine/Input/KeyboardInputHandler.cpp index 1686d8cd..0a0994aa 100644 --- a/src/Engine/Input/KeyboardInputHandler.cpp +++ b/src/Engine/Input/KeyboardInputHandler.cpp @@ -146,10 +146,10 @@ bool KeyboardInputHandler::OnKeyDown(const Events::KeyDown& e) return false; } - Events::InputCommand ic; - ic.PlayerID = 0; - std::tie(ic.Command, ic.Value) = it->second; - m_InputProxy->Publish(ic); + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] += value; return true; } @@ -161,12 +161,21 @@ bool KeyboardInputHandler::OnKeyUp(const Events::KeyUp& e) return false; } - Events::InputCommand ic; - ic.PlayerID = 0; - std::tie(ic.Command, std::ignore) = it->second; - ic.Value = 0; - m_InputProxy->Publish(ic); + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] -= value; return true; } +float KeyboardInputHandler::GetCommandValue(std::string command) +{ + auto it = m_CommandValues.find(command); + if (it != m_CommandValues.end()) { + return m_CommandValues[command]; + } else { + return 0.f; + } +} + From 30474b70df67aa57e5b6bde07350ada014d7e5eb Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Fri, 11 Dec 2015 18:03:48 +0100 Subject: [PATCH 30/65] MouseInputHandler --- include/Engine/Input/InputProxy.h | 3 +- include/Engine/Input/MouseInputHandler.h | 5 ++ .../Rendering/DebugCameraInputController.h | 48 +++++++++++++++++++ src/Engine/Input/InputProxy.cpp | 21 ++++++++ src/Engine/Input/MouseInputHandler.cpp | 34 ++++++++----- src/Engine/Rendering/Renderer.cpp | 31 +++--------- src/Game/Game.cpp | 1 + 7 files changed, 104 insertions(+), 39 deletions(-) create mode 100644 include/Engine/Rendering/DebugCameraInputController.h diff --git a/include/Engine/Input/InputProxy.h b/include/Engine/Input/InputProxy.h index 43c4940c..c7817c22 100644 --- a/include/Engine/Input/InputProxy.h +++ b/include/Engine/Input/InputProxy.h @@ -20,6 +20,7 @@ public: void Process(); template void AddHandler(); + void Publish(const Events::InputCommand& e); protected: EventBroker* m_EventBroker; @@ -27,7 +28,7 @@ protected: std::map> m_CommandHandlers; // Represents every unique command (has of PlayerID & Command) and all values reported for that command this frame - //std::map, std::vector> m_CommandQueue; + std::map, std::vector> m_CommandQueue; std::map m_CurrentCommandValues; std::map m_LastCommandValues; diff --git a/include/Engine/Input/MouseInputHandler.h b/include/Engine/Input/MouseInputHandler.h index 39889755..b9193a2d 100644 --- a/include/Engine/Input/MouseInputHandler.h +++ b/include/Engine/Input/MouseInputHandler.h @@ -13,12 +13,15 @@ public: MouseInputHandler(EventBroker* eventBroker, InputProxy* inputProxy); bool BindOrigin(std::string origin, std::string command, float value) override; + virtual float GetCommandValue(std::string command) override; private: std::unordered_map m_OriginCodes; std::unordered_map m_OriginAxes; std::unordered_map> m_Bindings; // GLFW_MOUSE_BUTTON... -> command string & value std::unordered_map> m_Axes; // Axis -> command string & value + std::unordered_map m_CommandValues; + std::unordered_map m_ContinuousCommandValues; EventRelay m_EMousePress; bool OnMousePress(const Events::MousePress& e); @@ -28,6 +31,8 @@ private: bool OnMouseMove(const Events::MouseMove& e); bool hasOrigin(std::string origin); + + }; #endif diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h new file mode 100644 index 00000000..551ae0f2 --- /dev/null +++ b/include/Engine/Rendering/DebugCameraInputController.h @@ -0,0 +1,48 @@ +#include "../Input/FirstPersonInputController.h" + +template +class DebugCameraInputController : public FirstPersonInputController +{ +public: + DebugCameraInputController(EventBroker* eventBroker, unsigned int playerID) + : FirstPersonInputController(eventBroker, playerID) + { } + + const glm::vec3 Position() const { return m_Position; } + void SetBaseSpeed(float speed) { m_BaseSpeed = speed; } + + virtual bool OnCommand(const Events::InputCommand& e) override + { + if (e.Command == "PrimaryFire") { + if (e.Value > 0) { + LockMouse(); + } else { + UnlockMouse(); + } + return false; + } + + if (e.Command == "Right") { + float value = std::max(-1.f, std::min(e.Value, 1.f)); + m_Velocity.x = value; + } + if (e.Command == "Forward") { + float value = std::max(-1.f, std::min(e.Value, 1.f)); + m_Velocity.z = -value; + } + + return FirstPersonInputController::OnCommand(e); + } + + void Update(double dt) + { + if (glm::length2(m_Velocity) > 0) { + m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_BaseSpeed); + } + } + +protected: + glm::vec3 m_Position = glm::vec3(0, 0, 0); + glm::vec3 m_Velocity = glm::vec3(0, 0, 0); + float m_BaseSpeed = 0.1f; +}; \ No newline at end of file diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp index 3fe29b7d..c3e4d669 100644 --- a/src/Engine/Input/InputProxy.cpp +++ b/src/Engine/Input/InputProxy.cpp @@ -66,6 +66,27 @@ void InputProxy::Process() m_LastCommandValues[command] = currentValue; } } + + // Accumulate the input values of all unique commands published by input handlers + for (auto& pair : m_CommandQueue) { + Events::InputCommand e; + e.PlayerID = pair.first.first; + e.Command = pair.first.second; + e.Value = 0; + for (auto& value : pair.second) { + e.Value += value; + } + //e.Value = std::max(-1.f, std::min(e.Value, 1.f)); + m_EventBroker->Publish(e); + LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + } + m_CommandQueue.clear(); +} + +void InputProxy::Publish(const Events::InputCommand& e) +{ + auto key = std::make_pair(e.PlayerID, e.Command); + m_CommandQueue[key].push_back(e.Value); } bool InputProxy::OnBindOrigin(const Events::BindOrigin& e) diff --git a/src/Engine/Input/MouseInputHandler.cpp b/src/Engine/Input/MouseInputHandler.cpp index 2e9c8137..5996b43d 100644 --- a/src/Engine/Input/MouseInputHandler.cpp +++ b/src/Engine/Input/MouseInputHandler.cpp @@ -50,6 +50,16 @@ bool MouseInputHandler::BindOrigin(std::string origin, std::string command, floa return false; } +float MouseInputHandler::GetCommandValue(std::string command) +{ + auto it = m_CommandValues.find(command); + if (it != m_CommandValues.end()) { + return m_CommandValues[command]; + } else { + return 0.f; + } +} + bool MouseInputHandler::OnMousePress(const Events::MousePress& e) { auto it = m_Bindings.find(e.Button); @@ -57,10 +67,10 @@ bool MouseInputHandler::OnMousePress(const Events::MousePress& e) return false; } - Events::InputCommand ic; - ic.PlayerID = 0; - std::tie(ic.Command, ic.Value) = it->second; - m_InputProxy->Publish(ic); + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] += value; return true; } @@ -72,11 +82,10 @@ bool MouseInputHandler::OnMouseRelease(const Events::MouseRelease& e) return false; } - Events::InputCommand ic; - ic.PlayerID = 0; - std::tie(ic.Command, std::ignore) = it->second; - ic.Value = 0; - m_InputProxy->Publish(ic); + std::string command; + float value; + std::tie(command, value) = it->second; + m_CommandValues[command] -= value; return true; } @@ -87,7 +96,7 @@ bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e) auto it = m_Axes.find('X'); if (it != m_Axes.end()) { Events::InputCommand ic; - ic.PlayerID = 0; + ic.PlayerID = -1; std::tie(ic.Command, ic.Value) = it->second; ic.Value *= e.DeltaX; m_InputProxy->Publish(ic); @@ -98,7 +107,7 @@ bool MouseInputHandler::OnMouseMove(const Events::MouseMove& e) auto it = m_Axes.find('Y'); if (it != m_Axes.end()) { Events::InputCommand ic; - ic.PlayerID = 0; + ic.PlayerID = -1; std::tie(ic.Command, ic.Value) = it->second; ic.Value *= e.DeltaY; m_InputProxy->Publish(ic); @@ -117,5 +126,4 @@ bool MouseInputHandler::hasOrigin(std::string origin) return false; } return true; -} - +} \ No newline at end of file diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 6f4235d2..3bc1d9da 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -1,4 +1,5 @@ #include "Rendering/Renderer.h" +#include "Rendering/DebugCameraInputController.h" void Renderer::Initialize() { @@ -83,6 +84,8 @@ void Renderer::InitializeShaders() void Renderer::InputUpdate(double dt) { + static DebugCameraInputController firstPersonInputController(m_EventBroker, -1); + glm::vec3 m_Position = m_Camera->Position(); if (glfwGetKey(m_Window, GLFW_KEY_O) == GLFW_PRESS) { @@ -112,37 +115,15 @@ void Renderer::InputUpdate(double dt) m_CameraMoveSpeed = 0.5f; } - - static double mousePosX, mousePosY; - glfwGetCursorPos(m_Window, &mousePosX, &mousePosY); - - if (glfwGetKey(m_Window, GLFW_KEY_SPACE) == GLFW_PRESS) { - - - 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); + firstPersonInputController.Update(dt); + m_Camera->SetOrientation(firstPersonInputController.Orientation()); + m_Camera->SetPosition(firstPersonInputController.Position()); } void Renderer::Update(double dt) { m_EventBroker->Process(); InputUpdate(dt); - } void Renderer::Draw(RenderQueueCollection& rq) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index b7391bac..026857d2 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -71,6 +71,7 @@ void Game::Tick() m_LastTime = currentTime; // Handle input in a weird looking but responsive way + m_EventBroker->Process(); m_EventBroker->Swap(); m_InputManager->Update(dt); m_EventBroker->Swap(); From e82911cb8bec91a28d2e9f8b2111fe92d5949919 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 11:39:13 +0100 Subject: [PATCH 31/65] Renderer FOV setting in Config.ini --- resources/DefaultConfig.ini | 3 ++- src/Game/Game.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index 535e109b..0d95de03 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -6,4 +6,5 @@ LoadMap= Fullscreen=false VSYNC=false Width=1280 -Height=720 \ No newline at end of file +Height=720 +FOV=45 \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 15dde3a0..5ad4084e 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -26,6 +26,7 @@ Game::Game(int argc, char* argv[]) m_Config->Get("Video.Height", 720) )); m_Renderer->Initialize(); + m_Renderer->Camera()->SetFOV(glm::radians(m_Config->Get("Video.FOV", 90.f))); // Create input manager m_InputManager = new InputManager(m_Renderer->Window(), m_EventBroker); From 653b4689b550c6bb2720e59c27b0f5ba11663f6e Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 12 Dec 2015 18:07:53 +0100 Subject: [PATCH 32/65] Added KeyboardChar event for keyboard text input --- include/Engine/Core/EKeyboardChar.h | 17 +++++++++++++++++ include/Engine/Core/InputManager.h | 4 ++++ src/Engine/Core/InputManager.cpp | 16 ++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 include/Engine/Core/EKeyboardChar.h diff --git a/include/Engine/Core/EKeyboardChar.h b/include/Engine/Core/EKeyboardChar.h new file mode 100644 index 00000000..8c1654ce --- /dev/null +++ b/include/Engine/Core/EKeyboardChar.h @@ -0,0 +1,17 @@ +#ifndef Events_KeyboardChar_h__ +#define Events_KeyboardChar_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct KeyboardChar : Event +{ + double Timestamp = 0.f; + unsigned int Char = 0; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Engine/Core/InputManager.h b/include/Engine/Core/InputManager.h index b8fe7f7a..063e691e 100644 --- a/include/Engine/Core/InputManager.h +++ b/include/Engine/Core/InputManager.h @@ -8,6 +8,7 @@ #include "EventBroker.h" #include "EKeyDown.h" #include "EKeyUp.h" +#include "EKeyboardChar.h" #include "EMousePress.h" #include "EMouseRelease.h" #include "EMouseMove.h" @@ -64,6 +65,9 @@ private: void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis); void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button); + + static std::vector CharCallbackQueue; + static void GLFWCharCallback(GLFWwindow* window, unsigned int c); }; #endif diff --git a/src/Engine/Core/InputManager.cpp b/src/Engine/Core/InputManager.cpp index 597fd7f6..4fd2e2a5 100644 --- a/src/Engine/Core/InputManager.cpp +++ b/src/Engine/Core/InputManager.cpp @@ -1,10 +1,13 @@ #include "Core/InputManager.h" +std::vector InputManager::CharCallbackQueue; + void InputManager::Initialize() { // TODO: Gamepad //m_LastGamepadAxisState = std::array(); //m_LastGamepadButtonState = std::array(); + glfwSetCharCallback(m_GLFWWindow, &InputManager::GLFWCharCallback); EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &InputManager::OnLockMouse); EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &InputManager::OnUnlockMouse); @@ -73,6 +76,14 @@ void InputManager::Update(double dt) m_EventBroker->Publish(e); } + for (unsigned int& c : CharCallbackQueue) { + Events::KeyboardChar e; + e.Timestamp = glfwGetTime(); + e.Char = c; + m_EventBroker->Publish(e); + } + CharCallbackQueue.clear(); + // // Lock mouse while holding LMB // if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT]) // { @@ -196,6 +207,11 @@ void InputManager::PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button } } +void InputManager::GLFWCharCallback(GLFWwindow* window, unsigned int c) +{ + CharCallbackQueue.push_back(c); +} + bool InputManager::OnLockMouse(const Events::LockMouse &event) { m_MouseLocked = true; From 7db1feac1719e4f870c2898fe3ce8e44ba4ed04e Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 12 Dec 2015 18:08:10 +0100 Subject: [PATCH 33/65] Added basic ImGui implementation --- deps | 2 +- include/Engine/Rendering/ImGuiRenderPass.h | 54 ++++ include/Engine/Rendering/Renderer.h | 2 + src/Engine/Rendering/ImGuiRenderPass.cpp | 320 +++++++++++++++++++++ src/Engine/Rendering/Renderer.cpp | 5 + src/Game/Game.cpp | 4 +- 6 files changed, 384 insertions(+), 3 deletions(-) create mode 100644 include/Engine/Rendering/ImGuiRenderPass.h create mode 100644 src/Engine/Rendering/ImGuiRenderPass.cpp diff --git a/deps b/deps index 1b478d31..f20b9cc1 160000 --- a/deps +++ b/deps @@ -1 +1 @@ -Subproject commit 1b478d3159f12273059a684ee8e187f4a25c89f0 +Subproject commit f20b9cc13bffa39c3b5144bacc5eacd34d43052c diff --git a/include/Engine/Rendering/ImGuiRenderPass.h b/include/Engine/Rendering/ImGuiRenderPass.h new file mode 100644 index 00000000..d28f1143 --- /dev/null +++ b/include/Engine/Rendering/ImGuiRenderPass.h @@ -0,0 +1,54 @@ +#include +#include "../OpenGL.h" +#include "IRenderer.h" +#include "../Core/EventBroker.h" +#include "../Core/EMousePress.h" +#include "../Core/EMouseRelease.h" +#include "../Core/EMouseMove.h" +#include "../Core/EKeyDown.h" +#include "../Core/EKeyUp.h" +#include "../Core/EKeyboardChar.h" + +class ImGuiRenderPass +{ +public: + ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker); + + void Update(double dt); + void Draw(); + +private: + IRenderer* m_Renderer; + EventBroker* m_EventBroker; + + GLFWwindow* g_Window; + double g_Time = 0.0; + GLuint g_FontTexture; + int g_ShaderHandle; + int g_VertHandle; + int g_FragHandle; + int g_AttribLocationTex; + int g_AttribLocationProjMtx; + int g_AttribLocationPosition; + int g_AttribLocationUV; + int g_AttribLocationColor; + GLuint g_VboHandle; + GLuint g_VaoHandle; + GLuint g_ElementsHandle; + + EventRelay m_EMousePress; + bool OnMousePress(const Events::MousePress& e); + EventRelay m_EMouseRelease; + bool OnMouseRelease(const Events::MouseRelease& e); + EventRelay m_EMouseMove; + bool OnMouseMove(const Events::MouseMove& e); + EventRelay m_EKeyDown; + bool OnKeyDown(const Events::KeyDown& e); + EventRelay m_EKeyUp; + bool OnKeyUp(const Events::KeyUp& e); + EventRelay m_EKeyboardChar; + bool OnKeyboardChar(const Events::KeyboardChar& e); + + bool createDeviceObjects(); + bool createFontsTexture(); +}; \ No newline at end of file diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 886c98ca..b4aae346 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -28,6 +28,7 @@ enum lightType #include "../Core/EventBroker.h" #include "EPicking.h" +#include "ImGuiRenderPass.h" class Renderer : public IRenderer { @@ -54,6 +55,7 @@ private: DrawScenePass* m_DrawScenePass; PickingPass* m_PickingPass; + ImGuiRenderPass* m_ImGuiRenderPass; //----------------------Functions----------------------// void InitializeWindow(); diff --git a/src/Engine/Rendering/ImGuiRenderPass.cpp b/src/Engine/Rendering/ImGuiRenderPass.cpp new file mode 100644 index 00000000..0acf9668 --- /dev/null +++ b/src/Engine/Rendering/ImGuiRenderPass.cpp @@ -0,0 +1,320 @@ +#include "Rendering/ImGuiRenderPass.h" + +ImGuiRenderPass::ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker) + : m_Renderer(renderer) + , m_EventBroker(eventBroker) +{ + g_Window = renderer->Window(); + + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + //io.RenderDrawListsFn = ImGui_ImplGlfwGL3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + //io.SetClipboardTextFn = ImGui_ImplGlfwGL3_SetClipboardText; + //io.GetClipboardTextFn = ImGui_ImplGlfwGL3_GetClipboardText; + + //if (install_callbacks) { + // glfwSetMouseButtonCallback(window, ImGui_ImplGlfwGL3_MouseButtonCallback); + // glfwSetScrollCallback(window, ImGui_ImplGlfwGL3_ScrollCallback); + // glfwSetKeyCallback(window, ImGui_ImplGlfwGL3_KeyCallback); + // glfwSetCharCallback(window, ImGui_ImplGlfwGL3_CharCallback); + //} + + createDeviceObjects(); + + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &ImGuiRenderPass::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &ImGuiRenderPass::OnMouseRelease); + EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &ImGuiRenderPass::OnMouseMove); + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &ImGuiRenderPass::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &ImGuiRenderPass::OnKeyUp); + EVENT_SUBSCRIBE_MEMBER(m_EKeyboardChar, &ImGuiRenderPass::OnKeyboardChar); +} + +void ImGuiRenderPass::Update(double dt) +{ + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); + + io.DeltaTime = dt; + + io.KeyCtrl = glfwGetKey(g_Window, GLFW_KEY_LEFT_CONTROL) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_CONTROL); + io.KeyShift = glfwGetKey(g_Window, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_SHIFT); + io.KeyAlt = glfwGetKey(g_Window, GLFW_KEY_LEFT_ALT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_ALT); + + ImGui::NewFrame(); + + static float val = 0.f; + ImGui::ShowTestWindow(); + //ImGui::LabelText("Label test", "Hi"); + ImGui::SliderFloat("float", &val, 0.f, 100.f); +} + +void ImGuiRenderPass::Draw() +{ + ImGuiIO& io = ImGui::GetIO(); + + ImGui::Render(); + + ImDrawData* draw_data = ImGui::GetDrawData(); + + // Backup GL state + GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); + GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); + GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); + GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); + GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + GLboolean last_enable_blend = glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); + + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glActiveTexture(GL_TEXTURE0); + + // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) + float fb_height = io.DisplaySize.y * io.DisplayFramebufferScale.y; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y); + const float ortho_projection[4][4] = + { + { 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, + { 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1.0f, 0.0f }, + { -1.0f, 1.0f, 0.0f, 1.0f }, + }; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); + glBindVertexArray(g_VaoHandle); + + for (int n = 0; n < draw_data->CmdListsCount; n++) { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const ImDrawIdx* idx_buffer_offset = 0; + + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.size() * sizeof(ImDrawVert), (GLvoid*)&cmd_list->VtxBuffer.front(), GL_STREAM_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx), (GLvoid*)&cmd_list->IdxBuffer.front(), GL_STREAM_DRAW); + + for (const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != cmd_list->CmdBuffer.end(); pcmd++) { + if (pcmd->UserCallback) { + pcmd->UserCallback(cmd_list, pcmd); + } else { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); + } + idx_buffer_offset += pcmd->ElemCount; + } + } + + // Restore modified GL state + glUseProgram(last_program); + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); + glBindVertexArray(last_vertex_array); + glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + glBlendFunc(last_blend_src, last_blend_dst); + if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); + if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); + if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); + if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +bool ImGuiRenderPass::OnMousePress(const Events::MousePress& e) +{ + ImGuiIO& io = ImGui::GetIO(); + io.MouseDown[e.Button] = true; + return false; +} + +bool ImGuiRenderPass::OnMouseRelease(const Events::MouseRelease& e) +{ + ImGuiIO& io = ImGui::GetIO(); + io.MouseDown[e.Button] = false; + return false; +} + +bool ImGuiRenderPass::OnMouseMove(const Events::MouseMove& e) +{ + ImGuiIO& io = ImGui::GetIO(); + io.MousePos.x = e.X; + io.MousePos.y = e.Y; + return true; +} + +bool ImGuiRenderPass::OnKeyDown(const Events::KeyDown& e) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[e.KeyCode] = true; + return true; +} + +bool ImGuiRenderPass::OnKeyUp(const Events::KeyUp& e) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeysDown[e.KeyCode] = false; + return true; +} + +bool ImGuiRenderPass::OnKeyboardChar(const Events::KeyboardChar& e) +{ + ImGuiIO& io = ImGui::GetIO(); + if (e.Char > 0 && e.Char < 0x10000) { + io.AddInputCharacter((unsigned short)e.Char); + return true; + } else { + return false; + } +} + +bool ImGuiRenderPass::createDeviceObjects() +{ + // Backup GL state + GLint last_texture, last_array_buffer, last_vertex_array; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); + + const GLchar *vertex_shader = + "#version 330\n" + "uniform mat4 ProjMtx;\n" + "in vec2 Position;\n" + "in vec2 UV;\n" + "in vec4 Color;\n" + "out vec2 Frag_UV;\n" + "out vec4 Frag_Color;\n" + "void main()\n" + "{\n" + " Frag_UV = UV;\n" + " Frag_Color = Color;\n" + " gl_Position = ProjMtx * vec4(Position.xy,0,1);\n" + "}\n"; + + const GLchar* fragment_shader = + "#version 330\n" + "uniform sampler2D Texture;\n" + "in vec2 Frag_UV;\n" + "in vec4 Frag_Color;\n" + "out vec4 Out_Color;\n" + "void main()\n" + "{\n" + " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" + "}\n"; + + g_ShaderHandle = glCreateProgram(); + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_VertHandle, 1, &vertex_shader, 0); + glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glCompileShader(g_VertHandle); + glCompileShader(g_FragHandle); + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationPosition = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + glGenBuffers(1, &g_VboHandle); + glGenBuffers(1, &g_ElementsHandle); + + glGenVertexArrays(1, &g_VaoHandle); + glBindVertexArray(g_VaoHandle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + +#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col)); +#undef OFFSETOF + + createFontsTexture(); + + // Restore modified GL state + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBindVertexArray(last_vertex_array); + + return true; +} + +bool ImGuiRenderPass::createFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + + io.Fonts->AddFontFromFileTTF("Fonts/DroidSans.ttf", 13.f); + io.Fonts->AddFontFromFileTTF("Fonts/ProggyClean.ttf", 13.f); + io.Fonts->AddFontFromFileTTF("Fonts/ProggyTiny.ttf", 10.f); + //io.Fonts->AddFontFromFileTTF("Fonts/Karla-Regular.ttf", 15.0f); + + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits for OpenGL3 demo because it is more likely to be compatible with user's existing shader. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + 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_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index c4fa33c4..76e687ee 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -22,6 +22,8 @@ void Renderer::Initialize() m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj"); + + m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker); } void Renderer::InitializeWindow() @@ -127,6 +129,8 @@ void Renderer::Update(double dt) { m_EventBroker->Process(); InputUpdate(dt); + m_EventBroker->Process(); + m_ImGuiRenderPass->Update(dt); } void Renderer::Draw(RenderQueueCollection& rq) @@ -137,6 +141,7 @@ void Renderer::Draw(RenderQueueCollection& rq) m_DrawScenePass->Draw(rq); GLERROR("Renderer::Draw m_DrawScenePass->Draw"); + m_ImGuiRenderPass->Draw(); glfwSwapBuffers(m_Window); } diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index af96eb29..71fa92a5 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -68,6 +68,8 @@ Game::~Game() void Game::Tick() { + glfwPollEvents(); + double currentTime = glfwGetTime(); double dt = currentTime - m_LastTime; m_LastTime = currentTime; @@ -94,8 +96,6 @@ void Game::Tick() GLERROR("Game::Tick m_Renderer->Draw"); m_EventBroker->Swap(); m_EventBroker->Clear(); - - glfwPollEvents(); } From 0c6ac1e060d7af33838f974001f3626049c1fe83 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 12 Dec 2015 18:14:42 +0100 Subject: [PATCH 34/65] Added ImGui to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 217cb69e..7b04f8ed 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Libraries bundled along with binaries for Windows (MSVC14), available as a submo | **[zlib](http://www.zlib.net)** | 1.28 | [zlib License](http://www.zlib.net/zlib_license.html) | | **[libpng](http://www.libpng.org/pub/png/libpng.html)** | 1.6.19 | [libpng License](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt) | | **[Xerces-C++](https://xerces.apache.org/xerces-c)** | 3.1.2 | [Apache License Version 2.0](https://www.apache.org/licenses/LICENSE-2.0) | +| **[ImGui](https://github.com/ocornut/imgui)** | 2015-12-12 | [MIT License](https://github.com/ocornut/imgui/blob/de3a154f3801de22c8e0bd2aeabf663a70c05972/LICENSE) | #### External libraries Libraries that are too big to be bundled with the project. From 0465fdb16d82dd38ff47d2af7b1c81d2f759d148 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 12 Dec 2015 18:18:10 +0100 Subject: [PATCH 35/65] Added ImGui for compilation --- src/Engine/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 97ed3e68..6ff723da 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -78,6 +78,9 @@ set(SOURCE_FILES ${SOURCE_FILES_GUI} ${SOURCE_FILES_Rendering} ${SOURCE_FILES_Rendering_Util} + ${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui.cpp + ${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_draw.cpp + ${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_demo.cpp ) set(LIBRARIES @@ -103,4 +106,4 @@ target_link_libraries(Engine ${LIBRARIES} ) #set_target_properties(Engine PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${INCLUDE_PATH}/PrecompiledHeader.h") -#cotire(Engine) \ No newline at end of file +#cotire(Engine) From af14d60493f8136ce241e66b2601f78209fcebf9 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 12 Dec 2015 18:30:50 +0100 Subject: [PATCH 36/65] Added MouseScroll event to input manager --- include/Engine/Core/EMouseScroll.h | 17 ++++++++++++++++ include/Engine/Core/InputManager.h | 5 ++++- src/Engine/Core/InputManager.cpp | 31 +++++++++++++++++++++++------- 3 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 include/Engine/Core/EMouseScroll.h diff --git a/include/Engine/Core/EMouseScroll.h b/include/Engine/Core/EMouseScroll.h new file mode 100644 index 00000000..8b2826a7 --- /dev/null +++ b/include/Engine/Core/EMouseScroll.h @@ -0,0 +1,17 @@ +#ifndef Events_MouseScroll_h__ +#define Events_MouseScroll_h__ + +#include "EventBroker.h" + +namespace Events +{ + +struct MouseScroll : Event +{ + double DeltaX; + double DeltaY; +}; + +} + +#endif diff --git a/include/Engine/Core/InputManager.h b/include/Engine/Core/InputManager.h index 063e691e..0d53169e 100644 --- a/include/Engine/Core/InputManager.h +++ b/include/Engine/Core/InputManager.h @@ -12,6 +12,7 @@ #include "EMousePress.h" #include "EMouseRelease.h" #include "EMouseMove.h" +#include "EMouseScroll.h" #include "ELockMouse.h" #include "EGamepadAxis.h" #include "EGamepadButton.h" @@ -66,8 +67,10 @@ private: void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis); void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button); - static std::vector CharCallbackQueue; + static std::vector GLFWCharCallbackQueue; static void GLFWCharCallback(GLFWwindow* window, unsigned int c); + static std::vector> GLFWScrollCallbackQueue; + static void GLFWScrollCallback(GLFWwindow* window, double xoffset, double yoffset); }; #endif diff --git a/src/Engine/Core/InputManager.cpp b/src/Engine/Core/InputManager.cpp index 4fd2e2a5..cb901cb8 100644 --- a/src/Engine/Core/InputManager.cpp +++ b/src/Engine/Core/InputManager.cpp @@ -1,6 +1,7 @@ #include "Core/InputManager.h" -std::vector InputManager::CharCallbackQueue; +std::vector InputManager::GLFWCharCallbackQueue; +std::vector> InputManager::GLFWScrollCallbackQueue; void InputManager::Initialize() { @@ -8,6 +9,7 @@ void InputManager::Initialize() //m_LastGamepadAxisState = std::array(); //m_LastGamepadButtonState = std::array(); glfwSetCharCallback(m_GLFWWindow, &InputManager::GLFWCharCallback); + glfwSetScrollCallback(m_GLFWWindow, &InputManager::GLFWScrollCallback); EVENT_SUBSCRIBE_MEMBER(m_ELockMouse, &InputManager::OnLockMouse); EVENT_SUBSCRIBE_MEMBER(m_EUnlockMouse, &InputManager::OnUnlockMouse); @@ -39,6 +41,15 @@ void InputManager::Update(double dt) } } + // Keyboard text input + for (unsigned int& c : GLFWCharCallbackQueue) { + Events::KeyboardChar e; + e.Timestamp = glfwGetTime(); + e.Char = c; + m_EventBroker->Publish(e); + } + GLFWCharCallbackQueue.clear(); + // Mouse buttons for (int i = 0; i <= GLFW_MOUSE_BUTTON_LAST; ++i) { m_CurrentMouseState[i] = glfwGetMouseButton(m_GLFWWindow, i); @@ -76,13 +87,13 @@ void InputManager::Update(double dt) m_EventBroker->Publish(e); } - for (unsigned int& c : CharCallbackQueue) { - Events::KeyboardChar e; - e.Timestamp = glfwGetTime(); - e.Char = c; + // Mouse scroll + for (auto& pair : GLFWScrollCallbackQueue) { + Events::MouseScroll e; + std::tie(e.DeltaX, e.DeltaY) = pair; m_EventBroker->Publish(e); } - CharCallbackQueue.clear(); + GLFWScrollCallbackQueue.clear(); // // Lock mouse while holding LMB // if (m_CurrentMouseState[GLFW_MOUSE_BUTTON_LEFT]) @@ -209,7 +220,13 @@ void InputManager::PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button void InputManager::GLFWCharCallback(GLFWwindow* window, unsigned int c) { - CharCallbackQueue.push_back(c); + GLFWCharCallbackQueue.push_back(c); +} + + +void InputManager::GLFWScrollCallback(GLFWwindow* window, double xoffset, double yoffset) +{ + GLFWScrollCallbackQueue.push_back(std::make_pair(xoffset, yoffset)); } bool InputManager::OnLockMouse(const Events::LockMouse &event) From c81a0546013c6e4ae22d94b364bf4900f4b88647 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 12 Dec 2015 18:31:03 +0100 Subject: [PATCH 37/65] Subscribed ImGui to MouseScroll event --- include/Engine/Rendering/ImGuiRenderPass.h | 4 ++++ src/Engine/Rendering/ImGuiRenderPass.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/Engine/Rendering/ImGuiRenderPass.h b/include/Engine/Rendering/ImGuiRenderPass.h index d28f1143..8b979bd0 100644 --- a/include/Engine/Rendering/ImGuiRenderPass.h +++ b/include/Engine/Rendering/ImGuiRenderPass.h @@ -5,6 +5,7 @@ #include "../Core/EMousePress.h" #include "../Core/EMouseRelease.h" #include "../Core/EMouseMove.h" +#include "../Core/EMouseScroll.h" #include "../Core/EKeyDown.h" #include "../Core/EKeyUp.h" #include "../Core/EKeyboardChar.h" @@ -23,6 +24,7 @@ private: GLFWwindow* g_Window; double g_Time = 0.0; + float g_MouseWheel = 0.f; GLuint g_FontTexture; int g_ShaderHandle; int g_VertHandle; @@ -42,6 +44,8 @@ private: bool OnMouseRelease(const Events::MouseRelease& e); EventRelay m_EMouseMove; bool OnMouseMove(const Events::MouseMove& e); + EventRelay m_EMouseScroll; + bool OnMouseScroll(const Events::MouseScroll& e); EventRelay m_EKeyDown; bool OnKeyDown(const Events::KeyDown& e); EventRelay m_EKeyUp; diff --git a/src/Engine/Rendering/ImGuiRenderPass.cpp b/src/Engine/Rendering/ImGuiRenderPass.cpp index 0acf9668..319eb98d 100644 --- a/src/Engine/Rendering/ImGuiRenderPass.cpp +++ b/src/Engine/Rendering/ImGuiRenderPass.cpp @@ -43,6 +43,7 @@ ImGuiRenderPass::ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker) EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &ImGuiRenderPass::OnMousePress); EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &ImGuiRenderPass::OnMouseRelease); EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &ImGuiRenderPass::OnMouseMove); + EVENT_SUBSCRIBE_MEMBER(m_EMouseScroll, &ImGuiRenderPass::OnMouseScroll); EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &ImGuiRenderPass::OnKeyDown); EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &ImGuiRenderPass::OnKeyUp); EVENT_SUBSCRIBE_MEMBER(m_EKeyboardChar, &ImGuiRenderPass::OnKeyboardChar); @@ -66,6 +67,9 @@ void ImGuiRenderPass::Update(double dt) io.KeyShift = glfwGetKey(g_Window, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_SHIFT); io.KeyAlt = glfwGetKey(g_Window, GLFW_KEY_LEFT_ALT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_ALT); + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0; + ImGui::NewFrame(); static float val = 0.f; @@ -184,6 +188,12 @@ bool ImGuiRenderPass::OnMouseMove(const Events::MouseMove& e) return true; } +bool ImGuiRenderPass::OnMouseScroll(const Events::MouseScroll& e) +{ + g_MouseWheel += (float)e.DeltaY; + return true; +} + bool ImGuiRenderPass::OnKeyDown(const Events::KeyDown& e) { ImGuiIO& io = ImGui::GetIO(); From 2e321e15a513e537efd69b00a09ee2b3955b9408 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sat, 12 Dec 2015 18:42:00 +0100 Subject: [PATCH 38/65] Cleaned up ImGuiRenderPass --- include/Engine/Rendering/ImGuiRenderPass.h | 4 +- src/Engine/Rendering/ImGuiRenderPass.cpp | 67 ++++++++++------------ 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/include/Engine/Rendering/ImGuiRenderPass.h b/include/Engine/Rendering/ImGuiRenderPass.h index 8b979bd0..1ca443e9 100644 --- a/include/Engine/Rendering/ImGuiRenderPass.h +++ b/include/Engine/Rendering/ImGuiRenderPass.h @@ -23,7 +23,7 @@ private: EventBroker* m_EventBroker; GLFWwindow* g_Window; - double g_Time = 0.0; + double g_DeltaTime = 0.0; float g_MouseWheel = 0.f; GLuint g_FontTexture; int g_ShaderHandle; @@ -55,4 +55,6 @@ private: bool createDeviceObjects(); bool createFontsTexture(); + + void newFrame(); }; \ No newline at end of file diff --git a/src/Engine/Rendering/ImGuiRenderPass.cpp b/src/Engine/Rendering/ImGuiRenderPass.cpp index 319eb98d..f47438fd 100644 --- a/src/Engine/Rendering/ImGuiRenderPass.cpp +++ b/src/Engine/Rendering/ImGuiRenderPass.cpp @@ -27,17 +27,6 @@ ImGuiRenderPass::ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker) io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - //io.RenderDrawListsFn = ImGui_ImplGlfwGL3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - //io.SetClipboardTextFn = ImGui_ImplGlfwGL3_SetClipboardText; - //io.GetClipboardTextFn = ImGui_ImplGlfwGL3_GetClipboardText; - - //if (install_callbacks) { - // glfwSetMouseButtonCallback(window, ImGui_ImplGlfwGL3_MouseButtonCallback); - // glfwSetScrollCallback(window, ImGui_ImplGlfwGL3_ScrollCallback); - // glfwSetKeyCallback(window, ImGui_ImplGlfwGL3_KeyCallback); - // glfwSetCharCallback(window, ImGui_ImplGlfwGL3_CharCallback); - //} - createDeviceObjects(); EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &ImGuiRenderPass::OnMousePress); @@ -47,35 +36,14 @@ ImGuiRenderPass::ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker) EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &ImGuiRenderPass::OnKeyDown); EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &ImGuiRenderPass::OnKeyUp); EVENT_SUBSCRIBE_MEMBER(m_EKeyboardChar, &ImGuiRenderPass::OnKeyboardChar); + + // Prime the first frame + newFrame(); } void ImGuiRenderPass::Update(double dt) { - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); - - io.DeltaTime = dt; - - io.KeyCtrl = glfwGetKey(g_Window, GLFW_KEY_LEFT_CONTROL) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_CONTROL); - io.KeyShift = glfwGetKey(g_Window, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_SHIFT); - io.KeyAlt = glfwGetKey(g_Window, GLFW_KEY_LEFT_ALT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_ALT); - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0; - - ImGui::NewFrame(); - - static float val = 0.f; - ImGui::ShowTestWindow(); - //ImGui::LabelText("Label test", "Hi"); - ImGui::SliderFloat("float", &val, 0.f, 100.f); + g_DeltaTime = dt; } void ImGuiRenderPass::Draw() @@ -164,6 +132,9 @@ void ImGuiRenderPass::Draw() if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); + + // Start next frame + newFrame(); } bool ImGuiRenderPass::OnMousePress(const Events::MousePress& e) @@ -328,3 +299,27 @@ bool ImGuiRenderPass::createFontsTexture() return true; } +void ImGuiRenderPass::newFrame() +{ + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); + + io.DeltaTime = g_DeltaTime; + + io.KeyCtrl = glfwGetKey(g_Window, GLFW_KEY_LEFT_CONTROL) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_CONTROL); + io.KeyShift = glfwGetKey(g_Window, GLFW_KEY_LEFT_SHIFT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_SHIFT); + io.KeyAlt = glfwGetKey(g_Window, GLFW_KEY_LEFT_ALT) || glfwGetKey(g_Window, GLFW_KEY_RIGHT_ALT); + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0; + + ImGui::NewFrame(); +} + From 8a6030bf571f5dfbd90dce58e71026b1e09dcc81 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 13:37:14 +0100 Subject: [PATCH 39/65] Added support for "Impure" systems, which only update once per frame and contain their own logic for manipulating the world, instead of relying on a single list of components. --- include/Engine/Core/System.h | 38 +++++++++++++++++++++------- include/Engine/Core/SystemPipeline.h | 33 +++++++++++++++++------- include/Game/PlayerSystem.h | 6 ++--- include/Game/RaptorCopterSystem.h | 8 +++--- src/Game/PlayerSystem.cpp | 3 +-- 5 files changed, 60 insertions(+), 28 deletions(-) diff --git a/include/Engine/Core/System.h b/include/Engine/Core/System.h index 37719c51..57b0d2cc 100644 --- a/include/Engine/Core/System.h +++ b/include/Engine/Core/System.h @@ -7,19 +7,39 @@ class System { - friend class SystemPipeline; - -public: - System(EventBroker* eventBroker, std::string componentType) +protected: + System(EventBroker* eventBroker) : m_EventBroker(eventBroker) - , m_ComponentType(componentType) { } - virtual void Update(World* world, ComponentWrapper& component, double dt) = 0; - -protected: - std::string m_ComponentType; EventBroker* m_EventBroker; }; +class PureSystem : public System +{ + friend class SystemPipeline; + +protected: + PureSystem(EventBroker* eventBroker, std::string componentType) + : System(eventBroker) + , m_ComponentType(componentType) + { } + + const std::string m_ComponentType; + + virtual void UpdateComponent(World* world, ComponentWrapper& component, double dt) = 0; +}; + +class ImpureSystem : public System +{ + friend class SystemPipeline; + +protected: + ImpureSystem(EventBroker* eventBroker) + : System(eventBroker) + { } + + virtual void Update(World* world, double dt) = 0; +}; + #endif \ No newline at end of file diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index e4b8bb1f..0f32b422 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -14,7 +14,7 @@ public: { } ~SystemPipeline() { - for (auto& pair : m_Systems) { + for (auto& pair : m_PureSystems) { for (auto& system : pair.second) { delete system; } @@ -25,17 +25,28 @@ public: void AddSystem(Arguments... args) { System* system = new T(m_EventBroker, args...); - if (!system->m_ComponentType.empty()) { - m_Systems[system->m_ComponentType].push_back(system); - } else { - LOG_ERROR("Failed to add system \"%s\": Missing component type!", typeid(T).name()); - delete system; + + if (std::is_base_of::value) { + PureSystem* pureSystem = static_cast(system); + if (!pureSystem->m_ComponentType.empty()) { + m_PureSystems[pureSystem->m_ComponentType].push_back(pureSystem); + } else { + LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name()); + if (std::is_base_of::value) { + delete system; + } + } + } + + if (std::is_base_of::value) { + ImpureSystem* impureSystem = static_cast(system); + m_ImpureSystems.push_back(impureSystem); } } void Update(World* world, double dt) { - for (auto& pair : m_Systems) { + for (auto& pair : m_PureSystems) { const std::string& componentName = pair.first; auto& systems = pair.second; const ComponentPool* pool = world->GetComponents(componentName); @@ -44,15 +55,19 @@ public: } for (auto& component : *pool) { for (auto& system : systems) { - system->Update(world, component, dt); + system->UpdateComponent(world, component, dt); } } } + for (auto& system : m_ImpureSystems) { + system->Update(world, dt); + } } private: EventBroker* m_EventBroker; - std::unordered_map> m_Systems; + std::unordered_map> m_PureSystems; + std::vector m_ImpureSystems; }; #endif \ No newline at end of file diff --git a/include/Game/PlayerSystem.h b/include/Game/PlayerSystem.h index 18752ac6..82dee6b8 100644 --- a/include/Game/PlayerSystem.h +++ b/include/Game/PlayerSystem.h @@ -18,17 +18,17 @@ struct KeyInput bool Right = false; }; -class PlayerSystem : public System +class PlayerSystem : public PureSystem { public: PlayerSystem(EventBroker* eventBroker) - : System(eventBroker, "Player") + : PureSystem(eventBroker, "Player") { EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PlayerSystem::OnKeyDown); EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PlayerSystem::OnKeyUp); } - virtual void Update(World* world, ComponentWrapper& player, double dt) override; + virtual void UpdateComponent(World* world, ComponentWrapper& player, double dt) override; private: float m_Speed = 5; diff --git a/include/Game/RaptorCopterSystem.h b/include/Game/RaptorCopterSystem.h index cdd6dd90..913efdb3 100644 --- a/include/Game/RaptorCopterSystem.h +++ b/include/Game/RaptorCopterSystem.h @@ -1,16 +1,14 @@ #include "Common.h" #include "Core/System.h" -class RaptorCopterSystem : public System +class RaptorCopterSystem : public PureSystem { public: RaptorCopterSystem(EventBroker* eventBroker) - : System(eventBroker, "RaptorCopter") + : PureSystem(eventBroker, "RaptorCopter") { } - virtual void Initialize() { } - - virtual void Update(World* world, ComponentWrapper& raptorCopter, double dt) override + virtual void UpdateComponent(World* world, ComponentWrapper& raptorCopter, double dt) override { ComponentWrapper& transform = world->GetComponent(raptorCopter.EntityID, "Transform"); (glm::vec3&)transform["Orientation"] += (float)(double)raptorCopter["Speed"] * (float)dt * (glm::vec3)raptorCopter["Axis"]; diff --git a/src/Game/PlayerSystem.cpp b/src/Game/PlayerSystem.cpp index 736ea105..db5fe067 100644 --- a/src/Game/PlayerSystem.cpp +++ b/src/Game/PlayerSystem.cpp @@ -1,7 +1,6 @@ #include "PlayerSystem.h" - -void PlayerSystem::Update(World * world, ComponentWrapper & player, double dt) +void PlayerSystem::UpdateComponent(World * world, ComponentWrapper & player, double dt) { if (input.Forward) { m_Direction.z = -1; From e5084e13eca48275e8e8289c17c4bc9029ec6fc0 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 13:37:32 +0100 Subject: [PATCH 40/65] Added EditorSystem --- include/Engine/Editor/EditorSystem.h | 11 +++++++++++ include/Game/Game.h | 1 + src/Engine/CMakeLists.txt | 8 +++++++- src/Engine/Editor/EditorSystem.cpp | 6 ++++++ src/Game/Game.cpp | 3 +-- 5 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 include/Engine/Editor/EditorSystem.h create mode 100644 src/Engine/Editor/EditorSystem.cpp diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h new file mode 100644 index 00000000..9520d2a6 --- /dev/null +++ b/include/Engine/Editor/EditorSystem.h @@ -0,0 +1,11 @@ +#include "../Core/System.h" + +class EditorSystem : public ImpureSystem +{ +public: + EditorSystem(EventBroker* eventBroker) + : ImpureSystem(eventBroker) + { } + + virtual void Update(World* world, double dt) override; +}; \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 57941e55..7933c8a1 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -17,6 +17,7 @@ #include "Core/SystemPipeline.h" #include "RaptorCopterSystem.h" #include "PlayerSystem.h" +#include "Editor/EditorSystem.h" class Game { diff --git a/src/Engine/CMakeLists.txt b/src/Engine/CMakeLists.txt index 6ff723da..99385d74 100644 --- a/src/Engine/CMakeLists.txt +++ b/src/Engine/CMakeLists.txt @@ -60,7 +60,6 @@ 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}) @@ -70,6 +69,12 @@ file(GLOB SOURCE_FILES_GUI ) source_group(GUI FILES ${SOURCE_FILES_GUI}) +file(GLOB SOURCE_FILES_Editor + "${INCLUDE_PATH}/Editor/*.h" + "Editor/*.cpp" +) +source_group(Editor FILES ${SOURCE_FILES_Editor}) + set(SOURCE_FILES ${SOURCE_FILES_Core} ${SOURCE_FILES_Core_Util} @@ -81,6 +86,7 @@ set(SOURCE_FILES ${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui.cpp ${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_draw.cpp ${CMAKE_SOURCE_DIR}/deps/include/imgui/imgui_demo.cpp + ${SOURCE_FILES_Editor} ) set(LIBRARIES diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp new file mode 100644 index 00000000..c1e359af --- /dev/null +++ b/src/Engine/Editor/EditorSystem.cpp @@ -0,0 +1,6 @@ +#include "Editor/EditorSystem.h" + +void EditorSystem::Update(World* world, double dt) +{ + +} diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 71fa92a5..e463cb07 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -52,8 +52,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline = new SystemPipeline(m_EventBroker); m_SystemPipeline->AddSystem(); m_SystemPipeline->AddSystem(); - - + m_SystemPipeline->AddSystem(); m_LastTime = glfwGetTime(); From b66cf47ff0cf6f8000b00b6550ae035d89110841 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 13:53:03 +0100 Subject: [PATCH 41/65] Revert "Clearing raw input events from event broker to encourage use of input commands instead" This reverts commit 2e7e8d3546f9248ca20b609b043b7727e946883e. --- src/Game/Game.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index e463cb07..061ac835 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -80,7 +80,6 @@ void Game::Tick() m_EventBroker->Swap(); m_InputProxy->Update(dt); m_EventBroker->Swap(); - m_EventBroker->Clear(); m_InputProxy->Process(); m_EventBroker->Swap(); From 2018ba27aef26c5f389772a49a4f051ea5d95ee5 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 19:59:25 +0100 Subject: [PATCH 42/65] Added KnowsEntity function to ComponentPool to query whether an entity has a component attached --- include/Engine/Core/ComponentPool.h | 2 ++ src/Engine/Core/ComponentPool.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/include/Engine/Core/ComponentPool.h b/include/Engine/Core/ComponentPool.h index f0d53864..8dd8dc29 100644 --- a/include/Engine/Core/ComponentPool.h +++ b/include/Engine/Core/ComponentPool.h @@ -54,6 +54,8 @@ public: ComponentWrapper Allocate(EntityID entity); // Get the component belonging to a specific entity ComponentWrapper GetByEntity(EntityID ent); + // Returns true if the pool contains a component for the specified entity + bool KnowsEntity(EntityID ent); // Delete a component and free its memory void Delete(ComponentWrapper& wrapper); diff --git a/src/Engine/Core/ComponentPool.cpp b/src/Engine/Core/ComponentPool.cpp index 146b33f6..ef7f9740 100644 --- a/src/Engine/Core/ComponentPool.cpp +++ b/src/Engine/Core/ComponentPool.cpp @@ -50,6 +50,12 @@ ComponentWrapper ComponentPool::GetByEntity(EntityID ent) return ComponentWrapper(m_ComponentInfo, m_EntityToComponent.at(ent)); } + +bool ComponentPool::KnowsEntity(EntityID ent) +{ + return m_EntityToComponent.find(ent) != m_EntityToComponent.end(); +} + void ComponentPool::Delete(ComponentWrapper& wrapper) { m_EntityToComponent.erase(wrapper.EntityID); From 91ace0d2a0e5582e874032d4b195d6c021ba8a90 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 19:59:50 +0100 Subject: [PATCH 43/65] Fixed bug in ComponentPool::Delete. Wasn't taking EntityID into account when freeing memory. --- src/Engine/Core/ComponentPool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engine/Core/ComponentPool.cpp b/src/Engine/Core/ComponentPool.cpp index ef7f9740..ca9cc801 100644 --- a/src/Engine/Core/ComponentPool.cpp +++ b/src/Engine/Core/ComponentPool.cpp @@ -59,7 +59,7 @@ bool ComponentPool::KnowsEntity(EntityID ent) void ComponentPool::Delete(ComponentWrapper& wrapper) { m_EntityToComponent.erase(wrapper.EntityID); - m_Pool.Free(wrapper.Data); + m_Pool.Free(wrapper.Data - sizeof(EntityID)); } ComponentPool::iterator ComponentPool::begin() const From 524af211e0b634e6613f352aac0486ba11033159 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 20:04:50 +0100 Subject: [PATCH 44/65] Made resource loading fail gracefully when a resource can't be loaded. Resources should now throw exceptions in their constuctor if the resource can't be loaded. This will result in ResourceManager::Load returning null. --- src/Engine/Core/ResourceManager.cpp | 16 +++++++++++----- src/Engine/Rendering/RawModel.cpp | 2 +- src/Engine/Rendering/RenderQueueFactory.cpp | 3 +++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Engine/Core/ResourceManager.cpp b/src/Engine/Core/ResourceManager.cpp index 81823dbf..62a60f14 100644 --- a/src/Engine/Core/ResourceManager.cpp +++ b/src/Engine/Core/ResourceManager.cpp @@ -100,7 +100,7 @@ Resource* ResourceManager::Load(std::string resourceType, std::string resourceNa LOG_WARNING("Hot-loading resource \"%s\"", resourceName.c_str()); } - return CreateResource(resourceType, resourceName, parent); + return CreateResource(resourceType, resourceName, parent); } Resource* ResourceManager::CreateResource(std::string resourceType, std::string resourceName, Resource* parent) @@ -112,10 +112,16 @@ Resource* ResourceManager::CreateResource(std::string resourceType, std::string } // Call the factory function - Resource* resource = facIt->second(resourceName); - // Store IDs - resource->TypeID = GetTypeID(resourceType); - resource->ResourceID = GetNewResourceID(resource->TypeID); + Resource* resource; + try { + resource = facIt->second(resourceName); + // Store IDs + resource->TypeID = GetTypeID(resourceType); + resource->ResourceID = GetNewResourceID(resource->TypeID); + } catch (const std::exception& e) { + resource = nullptr; + LOG_ERROR("Failed to load resource \"%s\" of type \"%s\": %s", resourceName.c_str(), resourceType.c_str(), e.what()); + } // Cache m_ResourceCache[std::make_pair(resourceType, resourceName)] = resource; m_ResourceFromName[resourceName] = resource; diff --git a/src/Engine/Rendering/RawModel.cpp b/src/Engine/Rendering/RawModel.cpp index 962c278f..5aec7f22 100644 --- a/src/Engine/Rendering/RawModel.cpp +++ b/src/Engine/Rendering/RawModel.cpp @@ -8,7 +8,7 @@ RawModel::RawModel(std::string fileName) if (scene == nullptr) { LOG_ERROR("Failed to load model \"%s\"", fileName.c_str()); LOG_ERROR("Assimp error: %s", importer.GetErrorString()); - return; + throw std::runtime_error("Failed to open model file."); } auto m = scene->mRootNode->mTransformation; diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/src/Engine/Rendering/RenderQueueFactory.cpp index 4b82647c..163a1f86 100644 --- a/src/Engine/Rendering/RenderQueueFactory.cpp +++ b/src/Engine/Rendering/RenderQueueFactory.cpp @@ -77,6 +77,9 @@ void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue) } glm::vec4 color = modelC["Color"]; Model* model = ResourceManager::Load(resource); + if (model == nullptr) { + model = ResourceManager::Load("Models/Core/Error.obj"); + } for (auto texGroup : model->TextureGroups) { ModelJob job; From 9a119f38bb7043832db29795e449008c36252b35 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 20:05:48 +0100 Subject: [PATCH 45/65] Added events processing to SystemPipeline --- include/Engine/Core/SystemPipeline.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/include/Engine/Core/SystemPipeline.h b/include/Engine/Core/SystemPipeline.h index 0f32b422..78ebc966 100644 --- a/include/Engine/Core/SystemPipeline.h +++ b/include/Engine/Core/SystemPipeline.h @@ -25,6 +25,7 @@ public: void AddSystem(Arguments... args) { System* system = new T(m_EventBroker, args...); + m_Systems[typeid(T).name()] = system; if (std::is_base_of::value) { PureSystem* pureSystem = static_cast(system); @@ -32,9 +33,6 @@ public: m_PureSystems[pureSystem->m_ComponentType].push_back(pureSystem); } else { LOG_ERROR("Failed to add pure system \"%s\": Missing component type!", typeid(T).name()); - if (std::is_base_of::value) { - delete system; - } } } @@ -46,6 +44,12 @@ public: void Update(World* world, double dt) { + // Process events + for (auto& pair : m_Systems) { + m_EventBroker->Process(pair.first); + } + + // Update for (auto& pair : m_PureSystems) { const std::string& componentName = pair.first; auto& systems = pair.second; @@ -66,7 +70,8 @@ public: private: EventBroker* m_EventBroker; - std::unordered_map> m_PureSystems; + std::map m_Systems; + std::map> m_PureSystems; std::vector m_ImpureSystems; }; From 5f3c234819aee25c3463e2b3a9f4dc23022519aa Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 20:05:57 +0100 Subject: [PATCH 46/65] Added DeleteComponent function to world --- src/Engine/Core/World.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index dfab23cd..0f07927c 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -41,6 +41,14 @@ ComponentWrapper World::GetComponent(EntityID entity, std::string componentType) return pool->GetByEntity(entity); } + +void World::DeleteComponent(EntityID entity, std::string componentType) +{ + ComponentPool* pool = m_ComponentPools.at(componentType); + ComponentWrapper c = pool->GetByEntity(entity); + return pool->Delete(c); +} + const ComponentPool* World::GetComponents(std::string componentType) { auto it = m_ComponentPools.find(componentType); From 2f3843e595934c5e4b7fbb79d6aacdd360642587 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 20:06:21 +0100 Subject: [PATCH 47/65] Editor version 1 --- assets | 2 +- include/Engine/Core/World.h | 4 + include/Engine/Editor/EditorSystem.h | 21 +- .../Rendering/DebugCameraInputController.h | 33 +++- include/Engine/Rendering/EPicking.h | 2 +- resources/Schema/Entities/EditorTestWorld.xml | 30 +++ src/Engine/Editor/EditorSystem.cpp | 181 ++++++++++++++++++ src/Engine/Rendering/ImGuiRenderPass.cpp | 17 ++ src/Engine/Rendering/Renderer.cpp | 1 - 9 files changed, 275 insertions(+), 16 deletions(-) create mode 100755 resources/Schema/Entities/EditorTestWorld.xml diff --git a/assets b/assets index b3746822..5874ddf3 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit b37468222e45ec0b2116f1543c578cb9784d43f2 +Subproject commit 5874ddf376e234d0c7de0878c940d3da439a19dd diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index 65dc3be7..39d27ca6 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -21,10 +21,14 @@ public: ComponentWrapper AttachComponent(EntityID entity, std::string componentType); // Get a component of an entity ComponentWrapper GetComponent(EntityID entity, std::string componentType); + // Delete a component off an entity + void DeleteComponent(EntityID entity, std::string componentType); // Get all components of the specified type const ComponentPool* GetComponents(std::string componentType); // Get entity parent EntityID GetParent(EntityID entity); + // Get all component pools + const std::unordered_map& GetComponentPools() const { return m_ComponentPools; } private: EntityID m_CurrentEntityID = 1; diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index 9520d2a6..da076942 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -1,11 +1,26 @@ +#include #include "../Core/System.h" +#include "../Core/EMousePress.h" +#include "../Rendering/EPicking.h" class EditorSystem : public ImpureSystem { public: - EditorSystem(EventBroker* eventBroker) - : ImpureSystem(eventBroker) - { } + EditorSystem(EventBroker* eventBroker); virtual void Update(World* world, double dt) override; + +private: + std::vector m_PickingQueue; + EntityID m_Widget = 0; + EntityID m_Selection = 0; + EntityID m_LastSelection = 0; + + EventRelay m_EMousePress; + bool OnMousePress(const Events::MousePress& e); + EventRelay m_EPicking; + bool OnPicking(const Events::Picking& e); + + void drawUI(World* world, double dt); + bool createDeleteButton(std::string componentType); }; \ No newline at end of file diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h index 551ae0f2..6d5908ef 100644 --- a/include/Engine/Rendering/DebugCameraInputController.h +++ b/include/Engine/Rendering/DebugCameraInputController.h @@ -1,3 +1,4 @@ +#include #include "../Input/FirstPersonInputController.h" template @@ -15,20 +16,31 @@ public: { if (e.Command == "PrimaryFire") { if (e.Value > 0) { - LockMouse(); + if (!ImGui::IsMouseHoveringAnyWindow()) { + LockMouse(); + } } else { UnlockMouse(); } return false; } - if (e.Command == "Right") { - float value = std::max(-1.f, std::min(e.Value, 1.f)); - m_Velocity.x = value; - } - if (e.Command == "Forward") { - float value = std::max(-1.f, std::min(e.Value, 1.f)); - m_Velocity.z = -value; + if (m_MouseLocked || e.Value == 0) { + if (e.Command == "Right") { + float value = std::max(-1.f, std::min(e.Value, 1.f)); + m_Velocity.x = value; + } + if (e.Command == "Forward") { + float value = std::max(-1.f, std::min(e.Value, 1.f)); + m_Velocity.z = -value; + } + if (e.Command == "Sprint") { + if (e.Value > 0.f) { + m_Speed = m_BaseSpeed * 2.f * (e.Value); + } else { + m_Speed = m_BaseSpeed; + } + } } return FirstPersonInputController::OnCommand(e); @@ -37,12 +49,13 @@ public: void Update(double dt) { if (glm::length2(m_Velocity) > 0) { - m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_BaseSpeed); + m_Position += m_Orientation * (glm::normalize(m_Velocity) * m_Speed * (float)dt); } } protected: glm::vec3 m_Position = glm::vec3(0, 0, 0); glm::vec3 m_Velocity = glm::vec3(0, 0, 0); - float m_BaseSpeed = 0.1f; + float m_BaseSpeed = 2.0f; + float m_Speed = m_BaseSpeed; }; \ No newline at end of file diff --git a/include/Engine/Rendering/EPicking.h b/include/Engine/Rendering/EPicking.h index df75854a..66530a01 100644 --- a/include/Engine/Rendering/EPicking.h +++ b/include/Engine/Rendering/EPicking.h @@ -46,7 +46,7 @@ public: if (it != PickingColorsToEntity->end()) { pickData.Entity = it->second; } else { - pickData.Entity = -1; + pickData.Entity = 0; } pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, Resolution.Width - screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix); diff --git a/resources/Schema/Entities/EditorTestWorld.xml b/resources/Schema/Entities/EditorTestWorld.xml new file mode 100755 index 00000000..6e1c0be5 --- /dev/null +++ b/resources/Schema/Entities/EditorTestWorld.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + Models/Core/UnitPlane.obj + + + + + + + + + + An error + + + + + \ No newline at end of file diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index c1e359af..b687fb6a 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -1,6 +1,187 @@ #include "Editor/EditorSystem.h" +#define IMGUI_DEFINE_MATH_OPERATORS +#include + +EditorSystem::EditorSystem(EventBroker* eventBroker) + : ImpureSystem(eventBroker) +{ + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EPicking, &EditorSystem::OnPicking); +} void EditorSystem::Update(World* world, double dt) { + if (m_Widget == 0) { + m_Widget = world->CreateEntity(); + world->AttachComponent(m_Widget, "Transform"); + auto& model = world->AttachComponent(m_Widget, "Model"); + model["Resource"] = "Models/TranslationWidget.obj"; + } + if (m_Selection != m_LastSelection) { + + } + + if (m_Selection != 0) { + auto selectionTransform = world->GetComponent(m_Selection, "Transform"); + auto widgetTransform = world->GetComponent(m_Widget, "Transform"); + + widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"]; + } + + drawUI(world, dt); +} + +bool EditorSystem::OnMousePress(const Events::MousePress& e) +{ + if (e.Button == GLFW_MOUSE_BUTTON_RIGHT) { + m_PickingQueue.push_back(glm::vec2(e.X, e.Y)); + } + return true; +} + +bool EditorSystem::OnPicking(const Events::Picking& e) +{ + for (auto& pos : m_PickingQueue) { + auto result = e.Pick(pos); + LOG_INFO("Selected %i", result.Entity); + m_Selection = result.Entity; + } + m_PickingQueue.clear(); + return true; +}; + +void EditorSystem::drawUI(World* world, double dt) +{ + //ImGui::ShowTestWindow(); + //ImGui::ShowStyleEditor(); + + if (ImGui::BeginMainMenuBar()) { + if (ImGui::BeginMenu("File")) { + + if (ImGui::MenuItem("New")) { } + if (ImGui::MenuItem("Open", "Ctrl+O")) { } + if (ImGui::MenuItem("Save", "Ctrl+S")) { } + if (ImGui::MenuItem("Save As...", "Ctrl+Shift+S")) { } + ImGui::Separator(); + if (ImGui::MenuItem("Close Editor", "F1")) { } + + ImGui::EndMenu(); + } + + ImGui::SameLine(); + if (ImGui::Button("Move")) { + auto& model = world->GetComponent(m_Widget, "Model"); + model["Resource"] = "Models/TranslationWidget.obj"; + } + ImGui::SameLine(); + if (ImGui::Button("Rotate")) { + auto& model = world->GetComponent(m_Widget, "Model"); + model["Resource"] = "Models/RotationWidget.obj"; + } + ImGui::SameLine(); + if (ImGui::Button("Scale")) { + auto& model = world->GetComponent(m_Widget, "Model"); + model["Resource"] = "Models/ScaleWidget.obj"; + } + + ImGui::EndMainMenuBar(); + } + + if (ImGui::Begin("Properties")) { + if (m_Selection != 0) { + auto& pools = world->GetComponentPools(); + + std::vector componentTypes; + for (auto& pair : pools) { + // Only add components the entity doesn't already have + if (!pair.second->KnowsEntity(m_Selection)) { + componentTypes.push_back(pair.first.c_str()); + } + } + int item = -1; + ImGui::PushItemWidth(ImGui::GetWindowContentRegionWidth() - 5.f); + if (ImGui::Combo("", &item, componentTypes.data(), componentTypes.size())) { + if (item != -1) { + std::string chosenType = std::string(componentTypes.at(item)); + world->AttachComponent(m_Selection, chosenType); + } + } + ImGui::PopItemWidth(); + + for (auto& pair : pools) { + const std::string& componentType = pair.first; + auto pool = pair.second; + if (!pool->KnowsEntity(m_Selection)) { + continue; + } + auto& ci = pool->ComponentInfo(); + + bool deletePressed = createDeleteButton(componentType); + if (deletePressed) { + world->DeleteComponent(m_Selection, componentType); + continue; + } + + if (ImGui::CollapsingHeader(componentType.c_str())) { + if (!ci.Meta.Annotation.empty()) { + ImGui::Text(ci.Meta.Annotation.c_str()); + } + + auto& component = world->GetComponent(m_Selection, componentType); + for (auto& pair : ci.FieldTypes) { + const std::string& field = pair.first; + const std::string& type = pair.second; + + if (type == "Vector") { + auto& val = component.Property(field); + if (field == "Scale") { + ImGui::DragFloat3(field.c_str(), glm::value_ptr(val), 0.1f, 0.f, 9999.f); + } else if (field == "Orientation") { + ImGui::SliderFloat3(field.c_str(), glm::value_ptr(val), 0.f, glm::pi()); + } else { + ImGui::InputFloat3(field.c_str(), glm::value_ptr(val)); + } + } else if (type == "Color") { + auto& val = component.Property(field); + ImGui::ColorEdit4(field.c_str(), glm::value_ptr(val), true); + } else if (type == "string") { + std::string& val = component.Property(field); + char tempString[1024]; + memcpy(tempString, val.c_str(), std::min(val.length() + 1, sizeof(tempString))); + if (ImGui::InputText(field.c_str(), tempString, sizeof(tempString))) { + val = std::string(tempString); + LOG_DEBUG("%s::%s changed!", componentType.c_str(), field.c_str()); + } + } else if (type == "double") { + float tempVal = static_cast(component.Property(field)); + if (ImGui::InputFloat(field.c_str(), &tempVal, 0.01f, 1.f)) { + component.SetProperty(field, static_cast(tempVal)); + } + } + } + } + } + } + + } + ImGui::End(); +} + +bool EditorSystem::createDeleteButton(std::string componentType) +{ + float width = ImGui::GetContentRegionAvailWidth(); + ImGuiWindow* window = ImGui::GetCurrentWindow(); + auto pos = ImGui::GetCursorScreenPos() + ImVec2(width - 14.f, 1); + ImRect bb = ImRect(pos, pos + ImVec2(14.f, 14.f)); + std::string idString = "#DELETE"; + idString += componentType; + ImGuiID id = window->GetID(idString.c_str()); + bool hovered; + bool held; + bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held); + //ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton); + ImU32 col = window->Color((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + window->DrawList->AddCircleFilled(bb.GetCenter(), 7.f, col, 16); + return pressed; } diff --git a/src/Engine/Rendering/ImGuiRenderPass.cpp b/src/Engine/Rendering/ImGuiRenderPass.cpp index f47438fd..1cb3ed8c 100644 --- a/src/Engine/Rendering/ImGuiRenderPass.cpp +++ b/src/Engine/Rendering/ImGuiRenderPass.cpp @@ -27,6 +27,21 @@ ImGuiRenderPass::ImGuiRenderPass(IRenderer* renderer, EventBroker* eventBroker) io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + ImGuiStyle& style = ImGui::GetStyle(); + style.Alpha = 1.f; + style.WindowPadding = ImVec2(8.f, 7.f); + style.WindowRounding = 4.f; + style.ChildWindowRounding = 0.f; + style.FramePadding = ImVec2(4.f, 2.f); + style.FrameRounding = 2.f; + style.ItemSpacing = ImVec2(6.f, 2.f); + style.ItemInnerSpacing = ImVec2(3.f, 4.f); + style.IndentSpacing = 16.f; + style.ScrollbarSize = 12; + style.ScrollbarRounding = 2.f; + style.GrabMinSize = 13.f; + style.GrabRounding = 3.f; + createDeviceObjects(); EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &ImGuiRenderPass::OnMousePress); @@ -320,6 +335,8 @@ void ImGuiRenderPass::newFrame() io.MouseWheel = g_MouseWheel; g_MouseWheel = 0; + m_EventBroker->Process(); + ImGui::NewFrame(); } diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 76e687ee..81926f4e 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -129,7 +129,6 @@ void Renderer::Update(double dt) { m_EventBroker->Process(); InputUpdate(dt); - m_EventBroker->Process(); m_ImGuiRenderPass->Update(dt); } From 7c1182c28fbffa7378a69a88cc654c9d05e55325 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 23:39:22 +0100 Subject: [PATCH 48/65] Fixed absolute positions once and for all (maybe?) --- include/Engine/Rendering/RenderQueueFactory.h | 10 +++---- src/Engine/Rendering/RenderQueueFactory.cpp | 26 +++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/include/Engine/Rendering/RenderQueueFactory.h b/include/Engine/Rendering/RenderQueueFactory.h index b273b672..be2c55ca 100644 --- a/include/Engine/Rendering/RenderQueueFactory.h +++ b/include/Engine/Rendering/RenderQueueFactory.h @@ -13,8 +13,12 @@ public: RenderQueueFactory(); void Update(World* world); - RenderQueueCollection RenderQueues() const { return m_RenderQueues; } + + static glm::vec3 AbsolutePosition(World* world, EntityID entity); + static glm::quat AbsoluteOrientation(World* world, EntityID entity); + static glm::vec3 AbsoluteScale(World* world, EntityID entity); + private: RenderQueueCollection m_RenderQueues; @@ -22,10 +26,6 @@ private: void FillLights(World* world, RenderQueue* renderQueue); glm::mat4 ModelMatrix(World* world, EntityID entity); - - glm::vec3 AbsolutePosition(World* world, EntityID entity); - glm::quat AbsoluteOrientation(World* world, EntityID entity); - glm::vec3 AbsoluteScale(World* world, EntityID entity); }; #endif \ No newline at end of file diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/src/Engine/Rendering/RenderQueueFactory.cpp index 163a1f86..7ec57ba4 100644 --- a/src/Engine/Rendering/RenderQueueFactory.cpp +++ b/src/Engine/Rendering/RenderQueueFactory.cpp @@ -23,15 +23,19 @@ glm::mat4 RenderQueueFactory::ModelMatrix(World* world, EntityID entity) return modelMatrix; } - glm::vec3 RenderQueueFactory::AbsolutePosition(World* world, EntityID entity) { glm::vec3 position; do { ComponentWrapper transform = world->GetComponent(entity, "Transform"); - position += (glm::vec3)transform["Position"]; - entity = world->GetParent(entity); + EntityID parent = world->GetParent(entity); + if (parent != 0) { + position += AbsoluteOrientation(world, parent) * (glm::vec3)transform["Position"]; + } else { + position += (glm::vec3)transform["Position"]; + } + entity = parent; } while (entity != 0); return position; @@ -52,15 +56,15 @@ glm::quat RenderQueueFactory::AbsoluteOrientation(World* world, EntityID entity) glm::vec3 RenderQueueFactory::AbsoluteScale(World* world, EntityID entity) { - ComponentWrapper transform = world->GetComponent(entity, "Transform"); - glm::vec3 scale = (glm::vec3)transform["Scale"]; + glm::vec3 scale(1.f); - EntityID parent = world->GetParent(entity); - if (parent != 0) { - return AbsoluteScale(world, parent) * scale; - } else { - return scale; - } + do { + ComponentWrapper transform = world->GetComponent(entity, "Transform"); + scale *= (glm::vec3)transform["Scale"]; + entity = world->GetParent(entity); + } while (entity != 0); + + return scale; } void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue) From 7bc492134dbaf75e55ecc69aa7830a90ad3715fe Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 23:39:37 +0100 Subject: [PATCH 49/65] Enabled rendering "transparency" --- src/Engine/Rendering/Renderer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 81926f4e..be884956 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -144,6 +144,10 @@ void Renderer::Draw(RenderQueueCollection& rq) glfwSwapBuffers(m_Window); } + glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); void Renderer::DrawScreenQuad(GLuint textureToDraw) { glBindFramebuffer(GL_FRAMEBUFFER, 0); From b8620eac26861db64f0ed89051bf537d372c190a Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 23:39:59 +0100 Subject: [PATCH 50/65] Made debug camera detect UI focus properly --- include/Engine/Rendering/DebugCameraInputController.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/Engine/Rendering/DebugCameraInputController.h b/include/Engine/Rendering/DebugCameraInputController.h index 6d5908ef..614b071c 100644 --- a/include/Engine/Rendering/DebugCameraInputController.h +++ b/include/Engine/Rendering/DebugCameraInputController.h @@ -14,9 +14,11 @@ public: virtual bool OnCommand(const Events::InputCommand& e) override { + ImGuiIO& io = ImGui::GetIO(); + if (e.Command == "PrimaryFire") { if (e.Value > 0) { - if (!ImGui::IsMouseHoveringAnyWindow()) { + if (!io.WantCaptureMouse) { LockMouse(); } } else { @@ -25,7 +27,7 @@ public: return false; } - if (m_MouseLocked || e.Value == 0) { + if (!io.WantCaptureKeyboard) { if (e.Command == "Right") { float value = std::max(-1.f, std::min(e.Value, 1.f)); m_Velocity.x = value; From 07c47444364a2ceace5f580903b74fbaeb3f9385 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 23:40:45 +0100 Subject: [PATCH 51/65] Added World DeleteEntity, HasComponent and GetEntityChildren --- include/Engine/Core/World.h | 6 +++++ src/Engine/Core/World.cpp | 44 ++++++++++++++++++++++++++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/include/Engine/Core/World.h b/include/Engine/Core/World.h index 39d27ca6..da31d369 100644 --- a/include/Engine/Core/World.h +++ b/include/Engine/Core/World.h @@ -14,11 +14,15 @@ public: // Create empty entity EntityID CreateEntity(EntityID parent = 0); + // Delete entity and all components within + void DeleteEntity(EntityID entity); // Register a component type and allocate space for it void RegisterComponent(ComponentInfo& ci); // Attach a component to an entity and fill it with default values ComponentWrapper AttachComponent(EntityID entity, std::string componentType); + // Check if an entity has a component + bool HasComponent(EntityID entity, std::string componentType); // Get a component of an entity ComponentWrapper GetComponent(EntityID entity, std::string componentType); // Delete a component off an entity @@ -29,6 +33,8 @@ public: EntityID GetParent(EntityID entity); // Get all component pools const std::unordered_map& GetComponentPools() const { return m_ComponentPools; } + // Get the entity children map + const std::unordered_multimap& GetEntityChildren() const { return m_EntityChildren; } private: EntityID m_CurrentEntityID = 1; diff --git a/src/Engine/Core/World.cpp b/src/Engine/Core/World.cpp index 0f07927c..7ee5e6a7 100644 --- a/src/Engine/Core/World.cpp +++ b/src/Engine/Core/World.cpp @@ -11,12 +11,43 @@ EntityID World::CreateEntity(EntityID parent /*= 0*/) { EntityID newEntity = generateEntityID(); m_EntityParents[newEntity] = parent; - if (parent != 0) { - m_EntityChildren.insert(std::make_pair(parent, newEntity)); - } + m_EntityChildren.insert(std::make_pair(parent, newEntity)); return newEntity; } + +void World::DeleteEntity(EntityID entity) +{ + // Delete components + for (auto& pair : m_ComponentPools) { + auto& pool = pair.second; + if (pool->KnowsEntity(entity)) { + auto& c = pool->GetByEntity(entity); + pool->Delete(c); + } + } + + // Loop through children + std::vector childrenToDelete; + auto children = m_EntityChildren.equal_range(entity); + for (auto it = children.first; it != children.second; ++it) { + childrenToDelete.push_back(it->second); + } + for (auto& child : childrenToDelete) { + DeleteEntity(child); + } + + EntityID parent = m_EntityParents.at(entity); + m_EntityParents.erase(entity); + auto parentChildren = m_EntityChildren.equal_range(parent); + for (auto it = parentChildren.first; it != parentChildren.second; ++it) { + if (it->second == entity) { + m_EntityChildren.erase(it); + break; + } + } +} + void World::RegisterComponent(ComponentInfo& ci) { m_ComponentPools[ci.Name] = new ComponentPool(ci); @@ -35,6 +66,13 @@ ComponentWrapper World::AttachComponent(EntityID entity, std::string componentTy return c; } + +bool World::HasComponent(EntityID entity, std::string componentType) +{ + ComponentPool* pool = m_ComponentPools.at(componentType); + return pool->KnowsEntity(entity); +} + ComponentWrapper World::GetComponent(EntityID entity, std::string componentType) { ComponentPool* pool = m_ComponentPools.at(componentType); From 545869e342c8f13a6b70a92074ba3ab900c4846f Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 13 Dec 2015 23:41:00 +0100 Subject: [PATCH 52/65] Added scene graph UI to Editor --- include/Engine/Editor/EditorSystem.h | 2 + src/Engine/Editor/EditorSystem.cpp | 61 +++++++++++++++++++++++----- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index da076942..28088823 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -2,6 +2,7 @@ #include "../Core/System.h" #include "../Core/EMousePress.h" #include "../Rendering/EPicking.h" +#include "../Rendering/RenderQueueFactory.h" class EditorSystem : public ImpureSystem { @@ -15,6 +16,7 @@ private: EntityID m_Widget = 0; EntityID m_Selection = 0; EntityID m_LastSelection = 0; + glm::vec3 m_Position; EventRelay m_EMousePress; bool OnMousePress(const Events::MousePress& e); diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index b687fb6a..bc879a11 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -23,19 +23,22 @@ void EditorSystem::Update(World* world, double dt) } if (m_Selection != 0) { - auto selectionTransform = world->GetComponent(m_Selection, "Transform"); - auto widgetTransform = world->GetComponent(m_Widget, "Transform"); + if (world->HasComponent(m_Selection, "Transform")) { + glm::vec3 pos = RenderQueueFactory::AbsolutePosition(world, m_Selection); + auto widgetTransform = world->GetComponent(m_Widget, "Transform"); + widgetTransform["Position"] = pos; + } else { + m_Selection = 0; + } + } - widgetTransform["Position"] = (glm::vec3)selectionTransform["Position"]; - } - drawUI(world, dt); } bool EditorSystem::OnMousePress(const Events::MousePress& e) { if (e.Button == GLFW_MOUSE_BUTTON_RIGHT) { - m_PickingQueue.push_back(glm::vec2(e.X, e.Y)); + m_PickingQueue.push_back(glm::vec2((int)e.X, (int)e.Y)); } return true; } @@ -53,7 +56,7 @@ bool EditorSystem::OnPicking(const Events::Picking& e) void EditorSystem::drawUI(World* world, double dt) { - //ImGui::ShowTestWindow(); + ImGui::ShowTestWindow(); //ImGui::ShowStyleEditor(); if (ImGui::BeginMainMenuBar()) { @@ -88,7 +91,7 @@ void EditorSystem::drawUI(World* world, double dt) ImGui::EndMainMenuBar(); } - if (ImGui::Begin("Properties")) { + if (ImGui::Begin("Components")) { if (m_Selection != 0) { auto& pools = world->GetComponentPools(); @@ -136,11 +139,19 @@ void EditorSystem::drawUI(World* world, double dt) if (type == "Vector") { auto& val = component.Property(field); if (field == "Scale") { - ImGui::DragFloat3(field.c_str(), glm::value_ptr(val), 0.1f, 0.f, 9999.f); + ImGui::DragFloat3(field.c_str(), glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits::max()); } else if (field == "Orientation") { - ImGui::SliderFloat3(field.c_str(), glm::value_ptr(val), 0.f, glm::pi()); + glm::vec3 times = val / glm::vec3(glm::pi()); + times.x = std::floor(times.x); + times.y = std::floor(times.y); + times.z = std::floor(times.z); + glm::vec3 tempVal = val - (times*glm::pi()); + if (ImGui::SliderFloat3(field.c_str(), glm::value_ptr(tempVal), 0.f, glm::pi())) { + val = tempVal; + } } else { - ImGui::InputFloat3(field.c_str(), glm::value_ptr(val)); + //ImGui::InputFloat3(field.c_str(), glm::value_ptr(val)); + ImGui::DragFloat3(field.c_str(), glm::value_ptr(val), 0.1f, std::numeric_limits::lowest(), std::numeric_limits::max()); } } else if (type == "Color") { auto& val = component.Property(field); @@ -166,6 +177,34 @@ void EditorSystem::drawUI(World* world, double dt) } ImGui::End(); + + if (ImGui::Begin("Entitites")) { + auto entityChildren = world->GetEntityChildren(); + std::function recurse = [&](EntityID parent) { + auto range = entityChildren.equal_range(parent); + for (auto it = range.first; it != range.second; it++) { + ImGui::SetNextTreeNodeOpened(true, ImGuiSetCond_Once); + if (ImGui::TreeNode((std::string("#") + std::to_string(it->second)).c_str())) { + if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(0)) { + m_Selection = it->second; + } + ImGui::SameLine(); + if (ImGui::Button("Add")) { + EntityID entity = world->CreateEntity(it->second); + world->AttachComponent(entity, "Transform"); + } + ImGui::SameLine(); + if (ImGui::Button("Delete")) { + world->DeleteEntity(it->second); + } + recurse(it->second); + ImGui::TreePop(); + } + } + }; + recurse(0); + } + ImGui::End(); } bool EditorSystem::createDeleteButton(std::string componentType) From 3a9577c9fb0cb14271c0e5be0ec4ed137bfdd5b3 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 14:08:05 +0100 Subject: [PATCH 53/65] fixup! Enabled rendering "transparency" --- src/Engine/Rendering/Renderer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index be884956..68402469 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -138,16 +138,16 @@ void Renderer::Draw(RenderQueueCollection& rq) //DrawScreenQuad(m_PickingPass->PickingTexture()); //CullLights(); + glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + m_DrawScenePass->Draw(rq); GLERROR("Renderer::Draw m_DrawScenePass->Draw"); m_ImGuiRenderPass->Draw(); glfwSwapBuffers(m_Window); } - glClearColor(255.f / 255, 163.f / 255, 176.f / 255, 1.f); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); void Renderer::DrawScreenQuad(GLuint textureToDraw) { glBindFramebuffer(GL_FRAMEBUFFER, 0); From 797036c20474acb9d97bf78bde298966767b2c11 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 14:19:45 +0100 Subject: [PATCH 54/65] Fixed picking event --- include/Engine/Rendering/EPicking.h | 4 +++- src/Engine/Rendering/PickingPass.cpp | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/Engine/Rendering/EPicking.h b/include/Engine/Rendering/EPicking.h index 66530a01..044a944b 100644 --- a/include/Engine/Rendering/EPicking.h +++ b/include/Engine/Rendering/EPicking.h @@ -40,6 +40,8 @@ public: { PickData pickData; + // Invert screen y coordinate + screenCoord.y = Resolution.Height - screenCoord.y; ScreenCoords::PixelData data = ScreenCoords::ToPixelData(screenCoord, PickingBuffer, *DepthBuffer); auto it = PickingColorsToEntity->find(glm::vec2(data.Color[0], data.Color[1])); @@ -48,7 +50,7 @@ public: } else { pickData.Entity = 0; } - pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, Resolution.Width - screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix); + pickData.Position = ScreenCoords::ToWorldPos(screenCoord.x, screenCoord.y, data.Depth, Resolution, ProjectionMatrix, ViewMatrix); return pickData; } diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 7d4cb66f..d45c0322 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -93,12 +93,15 @@ void PickingPass::Draw(RenderQueueCollection& rq) GLERROR("PickingPass Error"); //Publish pick event every frame with the pick data that can be picked by the event + 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(), - m_Renderer->Resolution(), + Rectangle(fbWidth, fbHeight), &m_PickingColorsToEntity); m_EventBroker->Publish(pickEvent); From 7719274a37c324e8446fe7c8ff9c1dec855b6dab Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 14:53:57 +0100 Subject: [PATCH 55/65] Correct asset reference for fonts --- assets | 2 +- src/Engine/Rendering/ImGuiRenderPass.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets b/assets index 5874ddf3..95823e12 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 5874ddf376e234d0c7de0878c940d3da439a19dd +Subproject commit 95823e122ab11135170d1d70ab2535ae1d332fdd diff --git a/src/Engine/Rendering/ImGuiRenderPass.cpp b/src/Engine/Rendering/ImGuiRenderPass.cpp index 1cb3ed8c..f2147ea8 100644 --- a/src/Engine/Rendering/ImGuiRenderPass.cpp +++ b/src/Engine/Rendering/ImGuiRenderPass.cpp @@ -288,8 +288,8 @@ bool ImGuiRenderPass::createFontsTexture() ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("Fonts/DroidSans.ttf", 13.f); - io.Fonts->AddFontFromFileTTF("Fonts/ProggyClean.ttf", 13.f); - io.Fonts->AddFontFromFileTTF("Fonts/ProggyTiny.ttf", 10.f); + //io.Fonts->AddFontFromFileTTF("Fonts/ProggyClean.ttf", 13.f); + //io.Fonts->AddFontFromFileTTF("Fonts/ProggyTiny.ttf", 10.f); //io.Fonts->AddFontFromFileTTF("Fonts/Karla-Regular.ttf", 15.0f); unsigned char* pixels; From bc6a211276b899983b3677bf5462100fb00b11e2 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 14:54:11 +0100 Subject: [PATCH 56/65] Removed RenderState log spam --- src/Engine/Rendering/RenderState.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 87f4a30d..34c88ece 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -9,7 +9,6 @@ bool RenderState::Enable(GLenum GLEnable) { if(glIsEnabled(GLEnable)) { - LOG_WARNING("Trying to enable somthing that is already enabled."); return false; } m_Enables.push_back(GLEnable); From fb2cd0c6ae0f5c601cd386538d51a8690f47b246 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 15:20:55 +0100 Subject: [PATCH 57/65] Fixed float angle wrapping --- include/Engine/Editor/EditorSystem.h | 1 + src/Engine/Editor/EditorSystem.cpp | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index 28088823..949795ff 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -1,4 +1,5 @@ #include +#include #include "../Core/System.h" #include "../Core/EMousePress.h" #include "../Rendering/EPicking.h" diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index bc879a11..80b41bf9 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -141,12 +141,8 @@ void EditorSystem::drawUI(World* world, double dt) if (field == "Scale") { ImGui::DragFloat3(field.c_str(), glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits::max()); } else if (field == "Orientation") { - glm::vec3 times = val / glm::vec3(glm::pi()); - times.x = std::floor(times.x); - times.y = std::floor(times.y); - times.z = std::floor(times.z); - glm::vec3 tempVal = val - (times*glm::pi()); - if (ImGui::SliderFloat3(field.c_str(), glm::value_ptr(tempVal), 0.f, glm::pi())) { + glm::vec3 tempVal = glm::fmod(val, glm::vec3(glm::two_pi())); + if (ImGui::SliderFloat3(field.c_str(), glm::value_ptr(tempVal), 0.f, glm::two_pi())) { val = tempVal; } } else { From 798c73132e458e51056c787849c1607aee893d7b Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 16:11:08 +0100 Subject: [PATCH 58/65] Fixed ScreenCoords::ToPixelData stack corruption --- src/Engine/Rendering/Util/ScreenCoords.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Engine/Rendering/Util/ScreenCoords.cpp b/src/Engine/Rendering/Util/ScreenCoords.cpp index 36dd08a1..36f1295e 100644 --- a/src/Engine/Rendering/Util/ScreenCoords.cpp +++ b/src/Engine/Rendering/Util/ScreenCoords.cpp @@ -32,11 +32,10 @@ glm::vec3 ScreenCoords::ToWorldPos(glm::vec2 screenCoord, float depth, float scr ScreenCoords::PixelData ScreenCoords::ToPixelData(float x, float y, FrameBuffer* PickDataBuffer, GLuint DepthBuffer) { PickDataBuffer->Bind(); - unsigned char pdata[2]; - glReadPixels(x, y, 1, 1, GL_RG, GL_UNSIGNED_BYTE, &pdata); + unsigned char pdata[3]; + glReadPixels(x, y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pdata); PickDataBuffer->Unbind(); - glBindFramebuffer(GL_FRAMEBUFFER, DepthBuffer); float depthData; glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthData); From f8d927cd917e67e52439258264340ad1e1083a1b Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 16:11:37 +0100 Subject: [PATCH 59/65] Don't render invisible model components --- src/Engine/Rendering/RenderQueueFactory.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Engine/Rendering/RenderQueueFactory.cpp b/src/Engine/Rendering/RenderQueueFactory.cpp index 7ec57ba4..8d5bb420 100644 --- a/src/Engine/Rendering/RenderQueueFactory.cpp +++ b/src/Engine/Rendering/RenderQueueFactory.cpp @@ -75,6 +75,10 @@ void RenderQueueFactory::FillModels(World* world, RenderQueue* renderQueue) } for (auto& modelC : *models) { + bool visible = modelC["Visible"]; + if (!visible) { + continue; + } std::string resource = modelC["Resource"]; if (resource.empty()) { continue; From ea239b19bdddc4ce89e3188c49758524effc084c Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 16:12:20 +0100 Subject: [PATCH 60/65] Fixed component type resolution order to prioritize custom types before native ones, since namespace information doesn't exist at that stage. --- resources/Schema/Components/Test.xml | 6 --- resources/Schema/Components/Test.xsd | 20 ------- src/Engine/Core/EntityXMLFile.cpp | 78 ++++++++++++++++------------ 3 files changed, 46 insertions(+), 58 deletions(-) delete mode 100644 resources/Schema/Components/Test.xml delete mode 100644 resources/Schema/Components/Test.xsd diff --git a/resources/Schema/Components/Test.xml b/resources/Schema/Components/Test.xml deleted file mode 100644 index 9e49d37a..00000000 --- a/resources/Schema/Components/Test.xml +++ /dev/null @@ -1,6 +0,0 @@ - - 1 - 1.333 - - - \ No newline at end of file diff --git a/resources/Schema/Components/Test.xsd b/resources/Schema/Components/Test.xsd deleted file mode 100644 index e31f83af..00000000 --- a/resources/Schema/Components/Test.xsd +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - ECS Test Component - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Engine/Core/EntityXMLFile.cpp b/src/Engine/Core/EntityXMLFile.cpp index b96e366e..bf8daceb 100644 --- a/src/Engine/Core/EntityXMLFile.cpp +++ b/src/Engine/Core/EntityXMLFile.cpp @@ -415,6 +415,7 @@ std::size_t EntityXMLFile::getTypeStride(std::string typeName) std::map typeStrides{ { "bool", sizeof(bool) }, { "int", sizeof(int) }, + { "float", sizeof(float) }, { "double", sizeof(double) }, { "string", sizeof(std::string) }, { "Vector", sizeof(glm::vec3) }, @@ -443,39 +444,52 @@ void EntityXMLFile::writeData(const xercesc::DOMElement* element, std::string ty { using namespace xercesc; - XSValue::DataType dataType = XSValue::getDataType(XSTR(typeName.c_str())); - if (dataType == XSValue::DataType::dt_MAXCOUNT) { - if (typeName == "Vector") { - glm::vec3 vec; - vec.x = getFloatAttribute(element, "X"); - vec.y = getFloatAttribute(element, "Y"); - vec.z = getFloatAttribute(element, "Z"); - memcpy(outData, reinterpret_cast(&vec), getTypeStride(typeName)); - } else if (typeName == "Color") { - glm::vec4 vec; - vec.r = getFloatAttribute(element, "R"); - vec.g = getFloatAttribute(element, "G"); - vec.b = getFloatAttribute(element, "B"); - vec.a = getFloatAttribute(element, "A"); - memcpy(outData, reinterpret_cast(&vec), getTypeStride(typeName)); - } else if (typeName == "Quaternion") { - glm::quat q; - q.x = getFloatAttribute(element, "X"); - q.y = getFloatAttribute(element, "Y"); - q.z = getFloatAttribute(element, "Z"); - q.w = getFloatAttribute(element, "W"); - memcpy(outData, reinterpret_cast(&q), getTypeStride(typeName)); - } - } else if (dataType == XSValue::DataType::dt_string) { - char* str = XMLString::transcode(element->getTextContent()); - std::string standardString(str); - new (outData) std::string(str); - XMLString::release(&str); - //memcpy(outData, reinterpret_cast(&standardString), getTypeStride(typeName)); - } else { + if (typeName == "Vector") { + glm::vec3 vec; + vec.x = getFloatAttribute(element, "X"); + vec.y = getFloatAttribute(element, "Y"); + vec.z = getFloatAttribute(element, "Z"); + memcpy(outData, reinterpret_cast(&vec), getTypeStride(typeName)); + } else if (typeName == "Color") { + glm::vec4 vec; + vec.r = getFloatAttribute(element, "R"); + vec.g = getFloatAttribute(element, "G"); + vec.b = getFloatAttribute(element, "B"); + vec.a = getFloatAttribute(element, "A"); + memcpy(outData, reinterpret_cast(&vec), getTypeStride(typeName)); + } else if (typeName == "Quaternion") { + glm::quat q; + q.x = getFloatAttribute(element, "X"); + q.y = getFloatAttribute(element, "Y"); + q.z = getFloatAttribute(element, "Z"); + q.w = getFloatAttribute(element, "W"); + memcpy(outData, reinterpret_cast(&q), getTypeStride(typeName)); + } else if (typeName == "float") { XSValue::Status status; - XSValue* val = XSValue::getActualValue(element->getTextContent(), dataType, status); - memcpy(outData, reinterpret_cast(&val->fData.fValue), getTypeStride(typeName)); + XSValue* val = XSValue::getActualValue(element->getTextContent(), xercesc::XSValue::DataType::dt_float, status); + memcpy(outData, reinterpret_cast(&val->fData.fValue.f_float), getTypeStride(typeName)); + } else if (typeName == "double") { + XSValue::Status status; + XSValue* val = XSValue::getActualValue(element->getTextContent(), xercesc::XSValue::DataType::dt_double, status); + memcpy(outData, reinterpret_cast(&val->fData.fValue.f_double), getTypeStride(typeName)); + } else if (typeName == "bool") { + XSValue::Status status; + XSValue* val = XSValue::getActualValue(element->getTextContent(), xercesc::XSValue::DataType::dt_boolean, status); + memcpy(outData, reinterpret_cast(&val->fData.fValue.f_bool), getTypeStride(typeName)); + } else { + XSValue::DataType dataType = XSValue::getDataType(XSTR(typeName.c_str())); + if (dataType == XSValue::DataType::dt_string) { + char* str = XMLString::transcode(element->getTextContent()); + std::string standardString(str); + new (outData) std::string(str); + XMLString::release(&str); + //memcpy(outData, reinterpret_cast(&standardString), getTypeStride(typeName)); + } else { + //XSValue::Status status; + //XSValue* val = XSValue::getActualValue(element->getTextContent(), dataType, status); + //memcpy(outData, reinterpret_cast(&val->fData.fValue), getTypeStride(typeName)); + LOG_WARNING("Unknown native data type: %s", typeName.c_str()); + } } } From cddd9026fb7c7ac6a4dcd9b5b9eff1f35f30ed0b Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 16:12:52 +0100 Subject: [PATCH 61/65] Toggle editor with "ToggleEditor" command. Enable editor with "Debug.EnableEditor" config variable. --- include/Engine/Editor/EditorSystem.h | 6 +++++ src/Engine/Editor/EditorSystem.cpp | 34 ++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/include/Engine/Editor/EditorSystem.h b/include/Engine/Editor/EditorSystem.h index 949795ff..92e237d1 100644 --- a/include/Engine/Editor/EditorSystem.h +++ b/include/Engine/Editor/EditorSystem.h @@ -2,6 +2,8 @@ #include #include "../Core/System.h" #include "../Core/EMousePress.h" +#include "../Core/ConfigFile.h" +#include "../Input/EInputCommand.h" #include "../Rendering/EPicking.h" #include "../Rendering/RenderQueueFactory.h" @@ -13,12 +15,16 @@ public: virtual void Update(World* world, double dt) override; private: + bool m_Enabled; + bool m_Visible; std::vector m_PickingQueue; EntityID m_Widget = 0; EntityID m_Selection = 0; EntityID m_LastSelection = 0; glm::vec3 m_Position; + EventRelay m_EInputCommand; + bool OnInputCommand(const Events::InputCommand& e); EventRelay m_EMousePress; bool OnMousePress(const Events::MousePress& e); EventRelay m_EPicking; diff --git a/src/Engine/Editor/EditorSystem.cpp b/src/Engine/Editor/EditorSystem.cpp index 80b41bf9..a56ba79c 100644 --- a/src/Engine/Editor/EditorSystem.cpp +++ b/src/Engine/Editor/EditorSystem.cpp @@ -5,12 +5,25 @@ EditorSystem::EditorSystem(EventBroker* eventBroker) : ImpureSystem(eventBroker) { + auto config = ResourceManager::Load("Config.ini"); + m_Enabled = config->Get("Debug.EditorEnabled", false); + m_Visible = m_Enabled; + + if (!m_Enabled) { + return; + } + + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &EditorSystem::OnInputCommand); EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &EditorSystem::OnMousePress); EVENT_SUBSCRIBE_MEMBER(m_EPicking, &EditorSystem::OnPicking); } void EditorSystem::Update(World* world, double dt) { + if (!m_Enabled) { + return; + } + if (m_Widget == 0) { m_Widget = world->CreateEntity(); world->AttachComponent(m_Widget, "Transform"); @@ -22,6 +35,8 @@ void EditorSystem::Update(World* world, double dt) } + auto& widgetModel = world->GetComponent(m_Widget, "Model"); + widgetModel["Visible"] = m_Visible; if (m_Selection != 0) { if (world->HasComponent(m_Selection, "Transform")) { glm::vec3 pos = RenderQueueFactory::AbsolutePosition(world, m_Selection); @@ -30,11 +45,24 @@ void EditorSystem::Update(World* world, double dt) } else { m_Selection = 0; } - } + } + + if (!m_Visible) { + return; + } drawUI(world, dt); } + +bool EditorSystem::OnInputCommand(const Events::InputCommand& e) +{ + if (e.Command == "ToggleEditor" && e.Value > 0) { + m_Visible = !m_Visible; + } + return true; +} + bool EditorSystem::OnMousePress(const Events::MousePress& e) { if (e.Button == GLFW_MOUSE_BUTTON_RIGHT) { @@ -146,7 +174,6 @@ void EditorSystem::drawUI(World* world, double dt) val = tempVal; } } else { - //ImGui::InputFloat3(field.c_str(), glm::value_ptr(val)); ImGui::DragFloat3(field.c_str(), glm::value_ptr(val), 0.1f, std::numeric_limits::lowest(), std::numeric_limits::max()); } } else if (type == "Color") { @@ -165,6 +192,9 @@ void EditorSystem::drawUI(World* world, double dt) if (ImGui::InputFloat(field.c_str(), &tempVal, 0.01f, 1.f)) { component.SetProperty(field, static_cast(tempVal)); } + } else if (type == "bool") { + auto& val = component.Property(field); + ImGui::Checkbox(field.c_str(), &val); } } } From 522679b14cffcd0ef3a1ce43a51570e22f8d6932 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 20:13:45 +0100 Subject: [PATCH 62/65] Added BlendEquation and BlendFunc to RenderState, and cleaned it up A LOT --- include/Engine/Rendering/RenderState.h | 18 ++- src/Engine/Rendering/DrawScenePassState.cpp | 2 +- src/Engine/Rendering/PickingPassState.cpp | 2 +- src/Engine/Rendering/RenderState.cpp | 145 +++++++++----------- 4 files changed, 80 insertions(+), 87 deletions(-) diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index e7ba2f80..c6eb8775 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -1,6 +1,7 @@ #ifndef RenderState_h__ #define RenderState_h__ +#include #include "../Common.h" #include "../OpenGL.h" #include "../GLM.h" @@ -8,16 +9,19 @@ class RenderState { public: - RenderState(); + RenderState() = default; ~RenderState(); - bool Enable(GLenum GLEnable); - bool CullFace(GLenum GlFaceToCull); + + bool Enable(GLenum cap); + bool Disable(GLenum cap); + bool CullFace(GLenum mode); bool ClearColor(glm::vec4 color); bool Clear(GLbitfield mask); - bool BindBuffer(GLint buffer); + bool BindFramebuffer(GLint framebuffer); + bool BlendEquation(GLenum mode); + bool BlendFunc(GLenum sfactor, GLenum dfactor); + private: - std::vector m_Enables; - float m_preClearColor[4]; - int m_preBuffer; + std::vector> m_ResetFunctions; }; #endif \ No newline at end of file diff --git a/src/Engine/Rendering/DrawScenePassState.cpp b/src/Engine/Rendering/DrawScenePassState.cpp index 59654775..9e7497a3 100644 --- a/src/Engine/Rendering/DrawScenePassState.cpp +++ b/src/Engine/Rendering/DrawScenePassState.cpp @@ -4,7 +4,7 @@ DrawScenePassState::DrawScenePassState() { GLERROR("---"); - BindBuffer(0); + BindFramebuffer(0); GLERROR("---"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); diff --git a/src/Engine/Rendering/PickingPassState.cpp b/src/Engine/Rendering/PickingPassState.cpp index a52fa546..1e28ea66 100644 --- a/src/Engine/Rendering/PickingPassState.cpp +++ b/src/Engine/Rendering/PickingPassState.cpp @@ -4,7 +4,7 @@ PickingPassState::PickingPassState(GLuint frameBuffer) { GLERROR("---2"); - BindBuffer(frameBuffer); + BindFramebuffer(frameBuffer); GLERROR("---3"); Enable(GL_DEPTH_TEST); Enable(GL_CULL_FACE); diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 34c88ece..631e7ff5 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -1,110 +1,99 @@ #include "Rendering/RenderState.h" -RenderState::RenderState() +bool RenderState::Enable(GLenum cap) { - -} - -bool RenderState::Enable(GLenum GLEnable) -{ - if(glIsEnabled(GLEnable)) - { + if (glIsEnabled(cap)) { return false; } - m_Enables.push_back(GLEnable); - glEnable(GLEnable); - if (GLERROR("RenderState::Enable")) - { - return false; - } - return true; + m_ResetFunctions.push_back(std::bind(glDisable, cap)); + glEnable(cap); + return !GLERROR("RenderState::Enable"); } -bool RenderState::CullFace(GLenum GLCullFace) +bool RenderState::Disable(GLenum cap) { - if(!glIsEnabled(GL_CULL_FACE)) - { + if (!glIsEnabled(cap)) { + return false; + } + m_ResetFunctions.push_back(std::bind(glEnable, cap)); + glDisable(cap); + return !GLERROR("RenderState::Disable"); +} + +bool RenderState::CullFace(GLenum mode) +{ + if (!glIsEnabled(GL_CULL_FACE)) { LOG_ERROR("Setting GL_CULL_FACE without enabling it."); return false; } - GLint a; - glGetIntegerv(GL_CULL_FACE_MODE, &a); - if(a != GL_BACK) - { - //LOG_INFO("Setting Cullface to back, unessesary since this is already default."); - glCullFace(GLCullFace); - } - if (GLERROR("RenderState::CullFace")) - { - return false; - } - return true; + GLint original; + glGetIntegerv(GL_CULL_FACE_MODE, &original); + m_ResetFunctions.push_back(std::bind(glCullFace, original)); + glCullFace(mode); + return !GLERROR("RenderState::CullFace"); } bool RenderState::ClearColor(glm::vec4 color) { - glGetFloatv(GL_COLOR_CLEAR_VALUE, &m_preClearColor[0]); + GLfloat original[4]; + glGetFloatv(GL_COLOR_CLEAR_VALUE, &original[0]); + m_ResetFunctions.push_back(std::bind(glClearColor, original[0], original[1], original[2], original[3])); glClearColor(color.r, color.g, color.b, color.a); - if (GLERROR("RenderState::ClearColor")) { - return false; - } - return true; + return !GLERROR("RenderState::ClearColor"); } bool RenderState::Clear(GLbitfield mask) { glClear(mask); - if (GLERROR("RenderState::Clear")) { - return false; - } - return true; + return !GLERROR("RenderState::Clear"); } -bool RenderState::BindBuffer(GLint buffer) +bool RenderState::BindFramebuffer(GLint framebuffer) { - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_preBuffer); - if (buffer == m_preBuffer) - { - return true; - } - glBindFramebuffer(GL_FRAMEBUFFER, buffer); - if (GLERROR("RenderState::BindBuffer")) - { - printf("BufferID: %i\npreBufferID: %i\n", buffer, m_preBuffer); - return false; - } - return true; + GLint originalRead; + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &originalRead); + GLint originalDraw; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &originalDraw); + m_ResetFunctions.push_back([originalRead, originalDraw]() { + glBindFramebuffer(GL_READ_FRAMEBUFFER, originalRead); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, originalDraw); + }); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + return !GLERROR("RenderState::BindBuffer"); +} + + +bool RenderState::BlendEquation(GLenum mode) +{ + GLint originalRGB; + glGetIntegerv(GL_BLEND_EQUATION_RGB, &originalRGB); + GLint originalAlpha; + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &originalAlpha); + m_ResetFunctions.push_back(std::bind(glBlendEquationSeparate, originalRGB, originalAlpha)); + glBlendEquation(mode); + return !GLERROR("RenderState::BlendEquation"); +} + +bool RenderState::BlendFunc(GLenum sfactor, GLenum dfactor) +{ + GLint originalSrcRGB; + glGetIntegerv(GL_BLEND_SRC_RGB, &originalSrcRGB); + GLint originalSrcAlpha; + glGetIntegerv(GL_BLEND_SRC_ALPHA, &originalSrcAlpha); + GLint originalDestRGB; + glGetIntegerv(GL_BLEND_DST_RGB, &originalDestRGB); + GLint originalDestAlpha; + glGetIntegerv(GL_BLEND_DST_ALPHA, &originalDestAlpha); + m_ResetFunctions.push_back(std::bind(glBlendFuncSeparate, originalSrcRGB, originalSrcAlpha, originalDestRGB, originalDestAlpha)); + glBlendFunc(sfactor, dfactor); + return !GLERROR("RenderState::BlendFunc"); } RenderState::~RenderState() { - GLERROR("RenderState::~RenderState Pre"); - GLint n_buffer = -1; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &n_buffer); - - //Set cullface to default - if (glIsEnabled(GL_CULL_FACE)) { - glCullFace(GL_BACK); + for (auto& f : m_ResetFunctions) { + f(); } - GLERROR("RenderState::~RenderState glCullFace"); - - //Set color to default - glClearColor(m_preClearColor[0], m_preClearColor[1], m_preClearColor[2], m_preClearColor[3]); - GLERROR("RenderState::~RenderState glClearColor"); - - //Disable Enables - for (auto i : m_Enables) - { - glDisable(i); - } - GLERROR("RenderState::~RenderState glDisable"); - - if(m_preBuffer != 0) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - m_Enables.clear(); - GLERROR("RenderState::~RenderState glBindFramebuffer"); } From 422e6f5264f028645cc638ecaccda192d5f18eb5 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 20:25:16 +0100 Subject: [PATCH 63/65] Created a RenderState for ImGuiRenderPass --- include/Engine/Rendering/ImGuiRenderPass.h | 17 ++++++++++ src/Engine/Rendering/ImGuiRenderPass.cpp | 39 ++-------------------- 2 files changed, 19 insertions(+), 37 deletions(-) diff --git a/include/Engine/Rendering/ImGuiRenderPass.h b/include/Engine/Rendering/ImGuiRenderPass.h index 1ca443e9..e9d359ba 100644 --- a/include/Engine/Rendering/ImGuiRenderPass.h +++ b/include/Engine/Rendering/ImGuiRenderPass.h @@ -1,6 +1,7 @@ #include #include "../OpenGL.h" #include "IRenderer.h" +#include "RenderState.h" #include "../Core/EventBroker.h" #include "../Core/EMousePress.h" #include "../Core/EMouseRelease.h" @@ -10,6 +11,22 @@ #include "../Core/EKeyUp.h" #include "../Core/EKeyboardChar.h" +class ImGuiRenderState : public RenderState +{ +public: + ImGuiRenderState() + : RenderState() + { + BindFramebuffer(0); + Enable(GL_BLEND); + BlendEquation(GL_FUNC_ADD); + BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + Disable(GL_CULL_FACE); + Disable(GL_DEPTH_TEST); + Enable(GL_SCISSOR_TEST); + } +}; + class ImGuiRenderPass { public: diff --git a/src/Engine/Rendering/ImGuiRenderPass.cpp b/src/Engine/Rendering/ImGuiRenderPass.cpp index f2147ea8..96f987d9 100644 --- a/src/Engine/Rendering/ImGuiRenderPass.cpp +++ b/src/Engine/Rendering/ImGuiRenderPass.cpp @@ -69,29 +69,8 @@ void ImGuiRenderPass::Draw() ImDrawData* draw_data = ImGui::GetDrawData(); - // Backup GL state - GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); - GLint last_element_array_buffer; glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &last_element_array_buffer); - GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - GLint last_blend_src; glGetIntegerv(GL_BLEND_SRC, &last_blend_src); - GLint last_blend_dst; glGetIntegerv(GL_BLEND_DST, &last_blend_dst); - GLint last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, &last_blend_equation_rgb); - GLint last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &last_blend_equation_alpha); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - GLboolean last_enable_blend = glIsEnabled(GL_BLEND); - GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); - GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); - GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); - - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); + // Set up render state + ImGuiRenderState state; glActiveTexture(GL_TEXTURE0); // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) @@ -134,20 +113,6 @@ void ImGuiRenderPass::Draw() } } - // Restore modified GL state - glUseProgram(last_program); - glBindTexture(GL_TEXTURE_2D, last_texture); - glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, last_element_array_buffer); - glBindVertexArray(last_vertex_array); - glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); - glBlendFunc(last_blend_src, last_blend_dst); - if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); - if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); - if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); - if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); - // Start next frame newFrame(); } From c296c4eb3b47bc12492e2e70cae7283859ce9b82 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 21:30:43 +0100 Subject: [PATCH 64/65] Fixed picking pass... again... --- src/Engine/Rendering/PickingPass.cpp | 30 +++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index d45c0322..148b272c 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -48,26 +48,31 @@ void PickingPass::Draw(RenderQueueCollection& rq) m_PickingColorsToEntity.clear(); PickingPassState* state = new PickingPassState(m_PickingBuffer.GetHandle()); - int r = 1; + 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 entityColors; + for (auto &job : rq.Forward) { auto modelJob = std::dynamic_pointer_cast(job); if (modelJob) { - //--------------- - //TODO: Renderer: IMPORTANT: Fixa detta så det inte loopar igenom listan varje frame. - //--------------- int pickColor[2] = { r, g }; - for (auto i : m_PickingColorsToEntity) { - if (modelJob->Entity == i.second) { - pickColor[0] = i.first.x; - pickColor[1] = i.first.y; - r -= 1; + 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 + 10 > 255) { + r = 0; + g += 1; + } else { + r += 1; } } m_PickingColorsToEntity[glm::vec2(pickColor[0], pickColor[1])] = modelJob->Entity; @@ -82,11 +87,6 @@ void PickingPass::Draw(RenderQueueCollection& rq) 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); - r += 1; - if (r > 255) { - r = 0; - g += 1; - } } } m_PickingBuffer.Unbind(); @@ -105,6 +105,8 @@ void PickingPass::Draw(RenderQueueCollection& rq) &m_PickingColorsToEntity); m_EventBroker->Publish(pickEvent); + + delete state; } void PickingPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const From 51dd627ae379d21ea211a84ceff98c8a4512e4d5 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Mon, 14 Dec 2015 22:32:20 +0100 Subject: [PATCH 65/65] Added Fonts to deploy.bat --- tools/deploy.bat | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/deploy.bat b/tools/deploy.bat index 22d513e6..f629058c 100755 --- a/tools/deploy.bat +++ b/tools/deploy.bat @@ -11,6 +11,8 @@ RMDIR "%DeployLocation%\Textures" MKLINK "%DeployLocation%\Textures\" "assets\Textures\" /J RMDIR "%DeployLocation%\Audio" MKLINK "%DeployLocation%\Audio\" "assets\Audio\" /J +RMDIR "%DeployLocation%\Fonts" +MKLINK "%DeployLocation%\Fonts\" "assets\Fonts\" /J ECHO Deploying resources to %DeployLocation% :: Schemas