From bc01e147c27f6a58937a7fd2498f37fcf2bd450e Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 3 Feb 2016 18:09:44 +0100 Subject: [PATCH] Some state stuff, some draw stuff, some QA map stuff --- include/Engine/Rendering/DrawFinalPass.h | 5 +- include/Engine/Rendering/DrawFinalPassState.h | 7 + include/Engine/Rendering/RenderState.h | 1 + .../Schema/Entities/QualityAssurance.xml | 185 ++++++++++++++---- resources/Schema/Types/Entity.xsd | 2 + resources/Shaders/ShieldStencil.frag.glsl | 15 ++ resources/Shaders/ShieldStencil.vert.glsl | 19 ++ src/Engine/Rendering/DrawFinalPass.cpp | 144 +++++++++++++- src/Engine/Rendering/DrawFinalPassState.cpp | 16 ++ src/Engine/Rendering/RenderState.cpp | 14 ++ 10 files changed, 369 insertions(+), 39 deletions(-) create mode 100644 resources/Shaders/ShieldStencil.frag.glsl create mode 100644 resources/Shaders/ShieldStencil.vert.glsl diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 4b2bcf1f..740c6ef6 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -31,7 +31,9 @@ private: void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const; - void DrawModelRenderQueues(std::list>& job, RenderScene& scene); + void DrawModelRenderQueues(std::list>& jobs, RenderScene& scene); + void DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene); + void DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene); void BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); void BindModelUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene); @@ -54,6 +56,7 @@ private: ShaderProgram* m_ForwardPlusProgram; ShaderProgram* m_ExplosionEffectProgram; + ShaderProgram* m_ShieldToStencilProgram; }; #endif \ No newline at end of file diff --git a/include/Engine/Rendering/DrawFinalPassState.h b/include/Engine/Rendering/DrawFinalPassState.h index 10b840e9..91fc4cf4 100644 --- a/include/Engine/Rendering/DrawFinalPassState.h +++ b/include/Engine/Rendering/DrawFinalPassState.h @@ -12,4 +12,11 @@ private: }; +class DrawStencilState : public RenderState +{ +public: + DrawStencilState(GLuint frameBuffer); + ~DrawStencilState(); +}; + #endif \ No newline at end of file diff --git a/include/Engine/Rendering/RenderState.h b/include/Engine/Rendering/RenderState.h index 688ef520..ae43c013 100644 --- a/include/Engine/Rendering/RenderState.h +++ b/include/Engine/Rendering/RenderState.h @@ -19,6 +19,7 @@ public: bool BindFramebuffer(GLint framebuffer); bool BlendEquation(GLenum mode); bool BlendFunc(GLenum sfactor, GLenum dfactor); + bool StencilFunc(GLenum sfail, GLenum dpfail, GLenum dppass); bool DepthMask(GLboolean flag); private: diff --git a/resources/Schema/Entities/QualityAssurance.xml b/resources/Schema/Entities/QualityAssurance.xml index cb75b7b3..11fbaf99 100644 --- a/resources/Schema/Entities/QualityAssurance.xml +++ b/resources/Schema/Entities/QualityAssurance.xml @@ -40,7 +40,7 @@ - + @@ -105,7 +105,7 @@ - + @@ -122,7 +122,7 @@ Run - + 1 @@ -138,7 +138,7 @@ Walk - + 1 @@ -188,7 +188,7 @@ - + @@ -196,7 +196,7 @@ Run - + 1 @@ -237,7 +237,7 @@ - + @@ -301,7 +301,7 @@ - + @@ -333,7 +333,7 @@ - + @@ -683,7 +683,7 @@ - + @@ -730,7 +730,7 @@ - + @@ -790,7 +790,7 @@ - + @@ -837,7 +837,7 @@ - + @@ -883,7 +883,7 @@ - + @@ -930,7 +930,7 @@ - + @@ -977,7 +977,7 @@ - + @@ -1350,6 +1350,19 @@ + + + + ExplosionEffect Test + Fonts/DroidSans.ttf,64 + + + + + + + + @@ -1377,7 +1390,7 @@ - + @@ -1386,7 +1399,7 @@ true - 0.75055150002244431 + 1.3668564709912516 3.7999999523162842 true @@ -1433,7 +1446,7 @@ - + @@ -1442,7 +1455,7 @@ - 1.2004572506365514 + 0.316796204374441 Models/Assault.mesh @@ -1485,7 +1498,7 @@ - + @@ -1493,14 +1506,14 @@ Walk - + 1 true - 0.68390303429648269 + 0.316796204374441 true @@ -1518,18 +1531,120 @@ - + - - ExplosionEffect Test - Fonts/DroidSans.ttf,64 - + + Models/Core/UnitCylinder.mesh + + - - + - + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + true + + + 0.95015514958004132 + 10 + + 3 + true + + + Models/Core/UnitSphere.mesh + + true + + + + + + + + + + + + + + + Models/Core/UnitCylinder.mesh + + + + + + + + + + + + + + + + + + + + 0.5 + + + + + + + + + + + true + + + 1.3501834109561059 + true + 5 + true + + + Models/Assault.mesh + + true + + + + + + + + + + @@ -1597,7 +1712,7 @@ - + 5 @@ -1608,7 +1723,7 @@ - + @@ -1691,7 +1806,7 @@ true - 0.0003117967054762083 + 1.3668564709912516 3.7999999523162842 true @@ -1736,7 +1851,7 @@ Hold Pos - + 1 diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 028af9e6..972a45e1 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -38,6 +38,8 @@ + + diff --git a/resources/Shaders/ShieldStencil.frag.glsl b/resources/Shaders/ShieldStencil.frag.glsl new file mode 100644 index 00000000..43a067c0 --- /dev/null +++ b/resources/Shaders/ShieldStencil.frag.glsl @@ -0,0 +1,15 @@ +#version 430 + +in VertexData{ + vec3 Position; +}Input; + + +out vec4 fragmentColor; + +void main() +{ + fragmentColor = vec4(0.5, 0.5, 0.5, 1.0); +} + + diff --git a/resources/Shaders/ShieldStencil.vert.glsl b/resources/Shaders/ShieldStencil.vert.glsl new file mode 100644 index 00000000..b6669f2c --- /dev/null +++ b/resources/Shaders/ShieldStencil.vert.glsl @@ -0,0 +1,19 @@ +#version 430 + +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; + +layout(location = 0) in vec3 Position; + + +out VertexData{ + vec3 Position; +}Output; + +void main() +{ + gl_Position = P * V * M * vec4(Position, 1.0); + + Output.Position = Position; +} \ No newline at end of file diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index 8e015373..d2d22514 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -55,6 +55,14 @@ void DrawFinalPass::InitializeShaderPrograms() m_ExplosionEffectProgram->BindFragDataLocation(1, "bloomColor"); m_ExplosionEffectProgram->Link(); GLERROR("Creating explosion program"); + + m_ShieldToStencilProgram = ResourceManager::Load("#ShieldToStencilProgram"); + m_ShieldToStencilProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/ShieldStencil.vert.glsl"))); + m_ShieldToStencilProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/ShieldStencil.frag.glsl"))); + m_ShieldToStencilProgram->Compile(); + m_ShieldToStencilProgram->Link(); + GLERROR("Creating Shield program"); + } void DrawFinalPass::Draw(RenderScene& scene) @@ -65,14 +73,30 @@ void DrawFinalPass::Draw(RenderScene& scene) if (scene.ClearDepth) { glClear(GL_DEPTH_BUFFER_BIT); } + //might need to clear stencil here DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); GLERROR("OpaqueObjects"); DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); GLERROR("TransparentObjects"); - delete state; + + DrawStencilState* stencilState = new DrawStencilState(m_FinalPassFrameBuffer.GetHandle()); + glClear(GL_STENCIL_BUFFER_BIT); + //Draw shields to stencil pass + DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene); + GLERROR("StencilPass"); + + //Draw Opaque shielded objects + DrawShieldedModelRenderQueue(scene.Jobs.OpaqueShieldedObjects, scene); + GLERROR("Shielded Opaque object"); + + //Draw Transparen Shielded objects + //DrawShieldedModelRenderQueue(scene.Jobs.TransparentShieldedObjects, scene); + GLERROR("Shielded Transparent objects"); + GLERROR("END"); + delete stencilState; } @@ -110,7 +134,7 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm: GLERROR("MipMap Texture initialization failed"); } -void DrawFinalPass::DrawModelRenderQueues(std::list>& job, RenderScene& scene) +void DrawFinalPass::DrawModelRenderQueues(std::list>& jobs, RenderScene& scene) { GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); GLERROR("forwardHandle"); @@ -121,7 +145,7 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); - for(auto &job : job) + for(auto &job : jobs) { auto explosionEffectJob = std::dynamic_pointer_cast(job); if(explosionEffectJob) { @@ -201,6 +225,120 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& } + +void DrawFinalPass::DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene) +{ + m_ShieldToStencilProgram->Bind(); + GLuint shaderHandle = m_ShieldToStencilProgram->GetHandle(); + + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "V"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "P"), 1, GL_FALSE, glm::value_ptr(scene.Camera->ProjectionMatrix())); + + for (auto &job : jobs) { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelJob->Matrix)); + + + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); + if (GLERROR("models end")) { + continue; + } + } + } +} + +void DrawFinalPass::DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene) +{ + GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); + GLERROR("forwardHandle"); + GLuint explosionHandle = m_ExplosionEffectProgram->GetHandle(); + GLERROR("explosionHandle"); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_LightCullingPass->LightSSBO()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); + + for (auto &job : jobs) { + auto explosionEffectJob = std::dynamic_pointer_cast(job); + if (explosionEffectJob) { + //Bind program + if (GLERROR("Prebind")) { + continue; + } + m_ExplosionEffectProgram->Bind(); + if (GLERROR("BindProgram")) { + continue; + } + + glDisable(GL_CULL_FACE); + + //Bind uniforms + BindExplosionUniforms(explosionHandle, explosionEffectJob, scene); + if (GLERROR("BindExplosionUniforms")) { + continue; + } + + if (explosionEffectJob->Model->m_RawModel->m_Skeleton != nullptr) { + + if (explosionEffectJob->Animation != nullptr) { + std::vector frameBones = explosionEffectJob->Skeleton->GetFrameBones(*explosionEffectJob->Animation, explosionEffectJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(explosionHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + if (GLERROR("Animation")) { + continue; + } + + //bind textures + BindExplosionTextures(explosionEffectJob); + if (GLERROR("BindExplosionTextures")) { + continue; + } + //draw + glBindVertexArray(explosionEffectJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, explosionEffectJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, explosionEffectJob->EndIndex - explosionEffectJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(explosionEffectJob->StartIndex*sizeof(unsigned int))); + glEnable(GL_CULL_FACE); + if (GLERROR("explosion effect end")) { + continue; + } + + } else { + auto modelJob = std::dynamic_pointer_cast(job); + if (modelJob) { + //bind forward program + m_ForwardPlusProgram->Bind(); + glUniform2f(glGetUniformLocation(forwardHandle, "ScreenDimensions"), m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + + //bind uniforms + BindModelUniforms(forwardHandle, modelJob, scene); + + //bind textures + BindModelTextures(modelJob); + + if (modelJob->Model->m_RawModel->m_Skeleton != nullptr) { + + if (modelJob->Animation != nullptr) { + std::vector frameBones = modelJob->Skeleton->GetFrameBones(*modelJob->Animation, modelJob->AnimationTime); + glUniformMatrix4fv(glGetUniformLocation(forwardHandle, "Bones"), frameBones.size(), GL_FALSE, glm::value_ptr(frameBones[0])); + } + } + + //draw + glBindVertexArray(modelJob->Model->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->Model->ElementBuffer); + glDrawElements(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, (void*)(modelJob->StartIndex*sizeof(unsigned int))); + if (GLERROR("models end")) { + continue; + } + } + } + } +} + void DrawFinalPass::BindExplosionUniforms(GLuint shaderHandle, std::shared_ptr& job, RenderScene& scene) { glUniformMatrix4fv(glGetUniformLocation(shaderHandle, "M"), 1, GL_FALSE, glm::value_ptr(job->Matrix)); diff --git a/src/Engine/Rendering/DrawFinalPassState.cpp b/src/Engine/Rendering/DrawFinalPassState.cpp index 3ebe320d..d85d476c 100644 --- a/src/Engine/Rendering/DrawFinalPassState.cpp +++ b/src/Engine/Rendering/DrawFinalPassState.cpp @@ -1,6 +1,7 @@ #include "Rendering/DrawFinalPassState.h" + DrawFinalPassState::DrawFinalPassState(GLuint frameBuffer) { BindFramebuffer(frameBuffer); @@ -15,3 +16,18 @@ DrawFinalPassState::~DrawFinalPassState() { } + +DrawStencilState::DrawStencilState(GLuint frameBuffer) +{ + BindFramebuffer(frameBuffer); + Enable(GL_STENCIL_TEST); + StencilFunc(GL_KEEP, GL_KEEP, GL_REPLACE); + Enable(GL_DEPTH_TEST); + ClearColor(glm::vec4(0.f)); +} + +DrawStencilState::~DrawStencilState() +{ + +} + diff --git a/src/Engine/Rendering/RenderState.cpp b/src/Engine/Rendering/RenderState.cpp index 1da2f0b1..d85b2b43 100644 --- a/src/Engine/Rendering/RenderState.cpp +++ b/src/Engine/Rendering/RenderState.cpp @@ -85,6 +85,20 @@ bool RenderState::BlendFunc(GLenum sfactor, GLenum dfactor) return !GLERROR("RenderState::BlendFunc"); } + +bool RenderState::StencilFunc(GLenum sfail, GLenum dpfail, GLenum dppass) +{ + GLint originalSFail; + glGetIntegerv(GL_STENCIL_FAIL, &originalSFail); + GLint originalDPFail; + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &originalDPFail); + GLint originalDPPass; + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &originalDPPass); + m_ResetFunctions.push_back(std::bind(glStencilOp, originalSFail, originalDPFail, originalDPPass)); + glStencilOp(sfail, dpfail, dppass); + return !GLERROR("StencilFunc"); +} + bool RenderState::DepthMask(GLboolean flag) { GLboolean original;