From 761b8e21e19525949bd52ab158e477bd40d47f57 Mon Sep 17 00:00:00 2001 From: Tleety Date: Wed, 28 May 2014 20:24:31 +0200 Subject: [PATCH] Added blendmap component Added renderque for models with a blendmap component Added shaders for blendmaps --- assets | 2 +- src/Components/BlendMap.h | 24 ++++++ src/GUI/WorldFrame.h | 39 ++++++++- src/GameWorld.cpp | 9 +- src/GameWorld.h | 1 + src/RenderQueue.h | 8 ++ src/Renderer.cpp | 49 +++++++++++ src/Renderer.h | 1 + src/Shaders/BlendMap.frag.glsl | 86 +++++++++++++++++++ src/Shaders/BlendMap.vert.glsl | 35 ++++++++ src/Shaders/Fragment.glsl | 26 ------ vs11/Returngeance/Returngeance.vcxproj | 3 + .../Returngeance/Returngeance.vcxproj.filters | 12 ++- 13 files changed, 260 insertions(+), 35 deletions(-) create mode 100644 src/Components/BlendMap.h create mode 100644 src/Shaders/BlendMap.frag.glsl create mode 100644 src/Shaders/BlendMap.vert.glsl diff --git a/assets b/assets index bc811a1..62d8e73 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit bc811a1b392782213d0823e418bc1d773e1a9641 +Subproject commit 62d8e73c689e993cb26dd35cfda253f2fba04bea diff --git a/src/Components/BlendMap.h b/src/Components/BlendMap.h new file mode 100644 index 0000000..c32cc13 --- /dev/null +++ b/src/Components/BlendMap.h @@ -0,0 +1,24 @@ +#ifndef Components_BlendMap_h__ +#define Components_BlendMap_h__ + +#include "Component.h" +#include "Entity.h" + +namespace Components +{ + struct BlendMap : Component + { + BlendMap() + : TextureRed("Textures/Ground/Asphalt") + , TextureGreen("Textures/Ground/Grass") + , TextureBlue("Textures/Ground/Sand") + , TextureRepeats(100.f) { } + + std::string TextureRed, TextureGreen, TextureBlue; + float TextureRepeats; + + virtual BlendMap* Clone() const override { return new BlendMap(*this); } + }; + +} +#endif // !Components_BlendMap_h__ \ No newline at end of file diff --git a/src/GUI/WorldFrame.h b/src/GUI/WorldFrame.h index 995b133..29f4314 100644 --- a/src/GUI/WorldFrame.h +++ b/src/GUI/WorldFrame.h @@ -11,6 +11,8 @@ #include "Components/Model.h" #include "Components/Sprite.h" #include "Components/PointLight.h" +#include "Components/BlendMap.h" + namespace GUI { @@ -56,7 +58,20 @@ public: glm::mat4 modelMatrix = glm::translate(glm::mat4(), absoluteTransform.Position) * glm::toMat4(absoluteTransform.Orientation) * glm::scale(absoluteTransform.Scale); - EnqueueModel(modelAsset, modelMatrix); + auto blendmapComponent = m_World->GetComponent(entity); + if (blendmapComponent) + { + auto textureRed = ResourceManager->Load("Texture", blendmapComponent->TextureRed); + auto textureGreen = ResourceManager->Load("Texture", blendmapComponent->TextureGreen); + auto textureBlue = ResourceManager->Load("Texture", blendmapComponent->TextureBlue); + float textureRepeat = blendmapComponent->TextureRepeats; + EnqueueBlendMapModel(modelAsset, textureRed, textureGreen, textureBlue, textureRepeat, modelMatrix); + } + else + { + EnqueueModel(modelAsset, modelMatrix); + } + } } @@ -134,6 +149,28 @@ private: } } + void EnqueueBlendMapModel(Model* model, Texture* textureRed, Texture* textureGreen, Texture* textureBlue, float textureRepeat, glm::mat4 modelMatrix) + { + for (auto texGroup : model->TextureGroups) + { + BlendMapModelJob job; + job.TextureID = texGroup.Texture->ResourceID; + job.DiffuseTexture = *texGroup.Texture; + job.NormalTexture = (texGroup.NormalMap) ? *texGroup.NormalMap : 0; + job.SpecularTexture = (texGroup.SpecularMap) ? *texGroup.SpecularMap : 0; + job.BlendMapTextureRed = (*textureRed); + job.BlendMapTextureGreen = (*textureGreen); + job.BlendMapTextureBlue = (*textureBlue); + job.TextureRepeat = textureRepeat; + job.VAO = model->VAO; + job.StartIndex = texGroup.StartIndex; + job.EndIndex = texGroup.EndIndex; + job.ModelMatrix = modelMatrix; + + RenderQueue.Add(job); + } + } + void EnqueueSprite(Texture* texture, glm::mat4 modelMatrix) { SpriteJob job; diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 4d50cc9..e2204f7 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -101,11 +101,10 @@ void GameWorld::Initialize() auto ground = CreateEntity(); auto transform = AddComponent(ground); transform->Position = glm::vec3(0, -50, 0); - //transform->Scale = glm::vec3(400.0f, 10.0f, 400.0f); transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f)); auto model = AddComponent(ground); - model->ModelFile = "Models/TestScene3/testScene.obj"; - //model->ModelFile = "Models/Placeholders/Terrain/Terrain2.obj"; + model->ModelFile = "Models/TerrainFiveIstles/Middle.obj"; + auto blendmap = AddComponent(ground); auto physics = AddComponent(ground); physics->Mass = 10; @@ -115,8 +114,7 @@ void GameWorld::Initialize() auto groundshape = CreateEntity(ground); auto transformshape = AddComponent(groundshape); auto meshShape = AddComponent(groundshape); - //meshShape->ResourceName = "Models/Placeholders/Terrain/Terrain2.obj"; - meshShape->ResourceName = "Models/TestScene3/testScene.obj"; + meshShape->ResourceName = "Models/TerrainFiveIstles/Middle.obj"; CommitEntity(groundshape); @@ -1256,6 +1254,7 @@ void GameWorld::RegisterComponents() m_ComponentFactory.Register([]() { return new Components::Template(); }); m_ComponentFactory.Register([]() { return new Components::Player(); }); m_ComponentFactory.Register([]() { return new Components::Flag(); }); + m_ComponentFactory.Register([]() { return new Components::BlendMap(); }); } void GameWorld::RegisterSystems() diff --git a/src/GameWorld.h b/src/GameWorld.h index d43c8ec..5467f8d 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -33,6 +33,7 @@ #include "Components/Template.h" #include "Components/Transform.h" #include "Components/Viewport.h" +#include "Components/BlendMap.h" #include "Components/Physics.h" #include "Components/SphereShape.h" diff --git a/src/RenderQueue.h b/src/RenderQueue.h index be2d18e..32bb29a 100644 --- a/src/RenderQueue.h +++ b/src/RenderQueue.h @@ -45,6 +45,14 @@ struct ModelJob : RenderJob } }; +struct BlendMapModelJob : ModelJob +{ + GLuint BlendMapTextureRed; + GLuint BlendMapTextureGreen; + GLuint BlendMapTextureBlue; + float TextureRepeat; +}; + struct SpriteJob : RenderJob { unsigned int ShaderID; diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 576857b..b839533 100755 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -108,6 +108,11 @@ void Renderer::LoadContent() m_ShaderProgramDebugAABB.Compile(); m_ShaderProgramDebugAABB.Link();*/ + m_BlendMapProgram.AddShader(std::shared_ptr(new VertexShader("Shaders/BlendMap.vert.glsl"))); + m_BlendMapProgram.AddShader(std::shared_ptr(new FragmentShader("Shaders/BlendMap.frag.glsl"))); + m_BlendMapProgram.Compile(); + m_BlendMapProgram.Link(); + m_ShaderProgramSkybox.AddShader(std::shared_ptr(new VertexShader("Shaders/Skybox.vert.glsl"))); m_ShaderProgramSkybox.AddShader(std::shared_ptr(new FragmentShader("Shaders/Skybox.frag.glsl"))); m_ShaderProgramSkybox.Compile(); @@ -1036,6 +1041,50 @@ void Renderer::DrawFBOScene(RenderQueue &rq) // continue; //} + + m_BlendMapProgram.Bind(); + GLuint ShaderProgramHandle = m_BlendMapProgram.GetHandle(); + + auto blendMapJob = std::dynamic_pointer_cast(job); + if(blendMapJob) + { + glm::mat4 modelMatrix = blendMapJob->ModelMatrix; + + MVP = cameraMatrix * modelMatrix; + depthMVP = depthCameraMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(ShaderProgramHandle, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); + glUniformMatrix4fv(glGetUniformLocation(ShaderProgramHandle, "DepthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVP)); + glUniformMatrix4fv(glGetUniformLocation(ShaderProgramHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix)); + glUniformMatrix4fv(glGetUniformLocation(ShaderProgramHandle, "V"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); + glUniformMatrix4fv(glGetUniformLocation(ShaderProgramHandle, "P"), 1, GL_FALSE, glm::value_ptr(cameraProjection)); + glUniform3fv(glGetUniformLocation(ShaderProgramHandle, "SunDirection_cameraspace"), 1, glm::value_ptr(sunDirection_cameraview)); + glUniform1f(glGetUniformLocation(ShaderProgramHandle, "TextureRepeats"), blendMapJob->TextureRepeat); + + glBindVertexArray(blendMapJob->VAO); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, blendMapJob->DiffuseTexture); + if (blendMapJob->NormalTexture != 0) + { + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, blendMapJob->NormalTexture); + } + if (blendMapJob->SpecularTexture) + { + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, blendMapJob->SpecularTexture); + } + + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, blendMapJob->BlendMapTextureRed); + glActiveTexture(GL_TEXTURE5); + glBindTexture(GL_TEXTURE_2D, blendMapJob->BlendMapTextureGreen); + glActiveTexture(GL_TEXTURE6); + glBindTexture(GL_TEXTURE_2D, blendMapJob->BlendMapTextureBlue); + + glDrawArrays(GL_TRIANGLES, blendMapJob->StartIndex, modelJob->EndIndex - modelJob->StartIndex + 1); + + continue; + } } } diff --git a/src/Renderer.h b/src/Renderer.h index ecdecfc..fe51f00 100755 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -173,6 +173,7 @@ private: ShaderProgram m_FinalPassProgram; ShaderProgram m_SunPassProgram; ShaderProgram m_ForwardRendering; + ShaderProgram m_BlendMapProgram; ShaderProgram m_ShaderProgramNormals; ShaderProgram m_ShaderProgramShadows; diff --git a/src/Shaders/BlendMap.frag.glsl b/src/Shaders/BlendMap.frag.glsl new file mode 100644 index 0000000..47bae51 --- /dev/null +++ b/src/Shaders/BlendMap.frag.glsl @@ -0,0 +1,86 @@ +#version 430 + +layout (binding=0) uniform sampler2D DiffuseTexture; +layout (binding=1) uniform sampler2D ShadowTexture; +layout (binding=2) uniform sampler2D NormalMapTexture; +layout (binding=3) uniform sampler2D SpecularMapTexture; + +//TerrainTextures +layout (binding=4) uniform sampler2D TextureRed; +layout (binding=5) uniform sampler2D TextureGreen; +layout (binding=6) uniform sampler2D TextureBlue; + +uniform float TextureRepeats; //Determines how many times the textures will loop over the terrain +uniform vec3 SunDirection_cameraspace; +uniform mat4 V; + +in VertexData +{ + vec3 Position; + vec3 Normal; + vec2 TextureCoord; + vec4 ShadowCoord; + vec3 Tangent; + vec3 BiTangent; +} Input; + +out vec4 frag_Diffuse; +out vec4 frag_Position; +out vec4 frag_Normal; +out vec4 frag_Specular; + +float Shadow(vec4 ShadowCoord, vec3 normal) +{ + return 1.0; + + if (Input.ShadowCoord.x < 0.0 || Input.ShadowCoord.x > 1.0 || Input.ShadowCoord.y < 0.0 || Input.ShadowCoord.y > 1.0) + return 0.9; + + //Variable bias + vec3 n = normalize(normal); + vec3 l = normalize(SunDirection_cameraspace); + float cosTheta = clamp(dot(n, l), 0.0, 1.0); + float bias = tan(acos(cosTheta)); + bias = clamp(bias, 0.0, 0.00003); + + //Fixed bias + bias = 0; + + if( texture(ShadowTexture, Input.ShadowCoord.xy).z < ShadowCoord.z + bias) + { + return 0.6; + } + else + { + return 1.0; + } +} + +void main() +{ + vec4 BlendMap = texture2D(DiffuseTexture, Input.TextureCoord.st); + + vec4 TextureRedTexel = texture2D(TextureRed, Input.TextureCoord.st * TextureRepeats); + vec4 TextureGreenTexel = texture2D(TextureGreen, Input.TextureCoord.st * TextureRepeats); + vec4 TextureBlueTexel = texture2D(TextureBlue, Input.TextureCoord.st * TextureRepeats); + + //Mix the Terrain-textures together + TextureRedTexel *= BlendMap.r; + TextureGreenTexel = mix(TextureRedTexel, TextureGreenTexel, BlendMap.g); + vec4 finalBlendTexel = mix(TextureGreenTexel, TextureBlueTexel, BlendMap.b); + + // G-buffer Position + frag_Position = vec4(Input.Position.xyz, 1.0); + + // G-buffer Normal + mat3 TBN = mat3(Input.Tangent, Input.BiTangent, Input.Normal); + frag_Normal = normalize(vec4(TBN * vec3(texture(NormalMapTexture, Input.TextureCoord)), 0.0)); + //frag_Diffuse = normalize(vec4(TBN * vec3(texture(NormalMapTexture, Input.TextureCoord)), 0.0)); + //frag_Normal = vec4(Input.Normal, 0.0); + + // Diffuse Texture + frag_Diffuse = finalBlendTexel * Shadow(Input.ShadowCoord, vec3(frag_Normal)); + + //G-buffer Specular + frag_Specular = texture(SpecularMapTexture, Input.TextureCoord); +} \ No newline at end of file diff --git a/src/Shaders/BlendMap.vert.glsl b/src/Shaders/BlendMap.vert.glsl new file mode 100644 index 0000000..4c63e0d --- /dev/null +++ b/src/Shaders/BlendMap.vert.glsl @@ -0,0 +1,35 @@ +#version 430 + +uniform mat4 MVP; +uniform mat4 M; +uniform mat4 V; +uniform mat4 P; +uniform mat4 DepthMVP; + +layout (location = 0) in vec3 Position; +layout (location = 1) in vec3 Normal; +layout (location = 2) in vec2 TextureCoord; +layout (location = 3) in vec3 Tangent; +layout (location = 4) in vec3 BiTangent; + +out VertexData +{ + vec3 Position; + vec3 Normal; + vec2 TextureCoord; + vec4 ShadowCoord; + vec3 Tangent; + vec3 BiTangent; +} Output; + +void main() +{ + gl_Position = MVP * vec4(Position, 1.0); + + Output.Position = vec3(V * M * vec4(Position, 1.0)); + Output.Normal = normalize(vec3(inverse(transpose(V * M)) * vec4(Normal, 0.0))); + Output.TextureCoord = TextureCoord; + Output.ShadowCoord = DepthMVP * vec4(Position, 1.0); + Output.Tangent = normalize(vec3(inverse(transpose(V * M)) * vec4(Tangent, 0.0))); + Output.BiTangent = normalize(vec3(inverse(transpose(V * M)) * vec4(BiTangent, 0.0))); +} \ No newline at end of file diff --git a/src/Shaders/Fragment.glsl b/src/Shaders/Fragment.glsl index 51a2cf5..439ef3a 100755 --- a/src/Shaders/Fragment.glsl +++ b/src/Shaders/Fragment.glsl @@ -5,13 +5,6 @@ layout (binding=1) uniform sampler2D ShadowTexture; layout (binding=2) uniform sampler2D NormalMapTexture; layout (binding=3) uniform sampler2D SpecularMapTexture; -//TerrainTextures -layout (binding=4) uniform sampler2D AsphaltTexture; -layout (binding=5) uniform sampler2D GrassTexture; -layout (binding=6) uniform sampler2D SandTexture; -layout (binding=7) uniform sampler2D BlendMap; - -uniform float texScale; //Determines how many times the textures will loop over the terrain uniform vec3 SunDirection_cameraspace; uniform mat4 V; @@ -59,25 +52,6 @@ float Shadow(vec4 ShadowCoord, vec3 normal) void main() { - //Fixa så den bara gör detta om modellen har en blend map - //vvvvvv - - vec4 Blend = texture2D(BlendMap, Input.TextureCoord.st ); - vec4 AsphaltTexel = texture2D(AsphaltTexture, Input.TextureCoord.st * texScale); - vec4 GrassTexel = texture2D(GrassTexture, Input.TextureCoord.st * texScale); - vec4 SandTexel = texture2D(SandTexture, Input.TextureCoord.st * texScale); - - //Mix the Terrain-textures together - AsphaltTexel *= Blend.r; - GrassTexel = mix(AsphaltTexel, GrassTexel, Blend.g); - vec4 tex = mix(GrassTexel, SandTexel, Blend.b); - - //^^^^^^ - //Fixa så den bara gör detta om modellen har en blend map - - - - // G-buffer Position frag_Position = vec4(Input.Position.xyz, 1.0); diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index e0a8c6f..678a4de 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -130,6 +130,7 @@ + @@ -233,6 +234,8 @@ + + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index a1bc062..fd91be8 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -169,8 +169,7 @@ {3c2ea0e5-41a1-4b11-a891-1d59ead7223c} - - + {a025d51e-594d-4844-983b-f683726bf1bf} @@ -473,6 +472,9 @@ GUI + + Rendering\Components + @@ -535,5 +537,11 @@ Shaders + + Shaders + + + Shaders + \ No newline at end of file