Merge remote-tracking branch 'origin/master' into gui

Conflicts:
	include/Core/Engine.h
	include/Core/RenderQueue.h
	include/Core/Renderer.h
	src/game/Core/Renderer.cpp
This commit is contained in:
2015-09-25 02:27:00 +02:00
24 changed files with 1716 additions and 83 deletions
+209 -9
View File
@@ -91,6 +91,12 @@ void dd::Renderer::LoadShaders()
//glBindFragDataLocation(m_SPDeferred2, 0, "FragmentLighting");
m_spDeferred2->Link();
//Water Pass
t_m_spWater = ResourceManager::Load<ShaderProgram>("Shaders/Deferred/water/");
t_m_spWater->Link();
t_m_spWater2 = ResourceManager::Load<ShaderProgram>("Shaders/Deferred/water2/");
t_m_spWater2->Link();
// Pass #3: Combining into final image
m_spDeferred3 = ResourceManager::Load<ShaderProgram>("Shaders/Deferred/3/");
m_spDeferred3->Link();
@@ -110,11 +116,13 @@ void dd::Renderer::LoadShaders()
void dd::Renderer::CreateBuffers()
{
//TODO: Make the most common cases of texture create and FBO create into a function so it's not so cluttered in here.
m_ScreenQuad = CreateQuad();
m_UnitQuad = ResourceManager::Load<Model>("Models/Core/UnitQuad.obj");
m_UnitSphere = ResourceManager::Load<Model>("Models/Core/UnitSphere.obj");
m_StandardNormal = ResourceManager::Load<Texture>("Textures/Core/NeutralNormalMap.png");
m_StandardSpecular = ResourceManager::Load<Texture>("Textures/Core/NeutralSpecularMap.png");
t_m_WhiteSphereTexture = ResourceManager::Load<Texture>("Textures/Test/Water.png");
glGenRenderbuffers(1, &m_rbDepthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_rbDepthBuffer);
@@ -149,6 +157,13 @@ void dd::Renderer::CreateBuffers()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glGenTextures(1, &t_m_Gwater);
glBindTexture(GL_TEXTURE_2D, t_m_Gwater);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Create first pass framebuffer
glGenFramebuffers(1, &m_fbDeferred1);
@@ -185,14 +200,75 @@ void dd::Renderer::CreateBuffers()
exit(EXIT_FAILURE);
}
//Fill Water Texture
glGenTextures(1, &t_m_Gwater);
glBindTexture(GL_TEXTURE_2D, t_m_Gwater);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//Fill water pass
glGenFramebuffers(1, &t_m_fbWater);
glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWater);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_Gwater, 0);
GLenum waterPassDrawBuffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, waterPassDrawBuffers);
if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus);
exit(EXIT_FAILURE);
}
//water Blur texture
glGenTextures(1, &t_m_BWater);
glBindTexture(GL_TEXTURE_2D, t_m_BWater);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Fill waterBlur pass
glGenFramebuffers(1, &t_m_fbWaterBlur);
glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_BWater, 0);
GLenum waterBlurDrawBuffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, waterBlurDrawBuffers);
if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus);
exit(EXIT_FAILURE);
}
//water Blur texture2
glGenTextures(1, &t_m_BWater2);
glBindTexture(GL_TEXTURE_2D, t_m_BWater2);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbDepthBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//Fill waterBlur pass2
glGenFramebuffers(1, &t_m_fbWaterBlur2);
glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur2);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, t_m_BWater2, 0);
GLenum waterBlur2DrawBuffers[] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, waterBlur2DrawBuffers);
if (GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
LOG_ERROR("m_fbDeferred2 incomplete: 0x%x\n", fbStatus);
exit(EXIT_FAILURE);
}
// Generate final deferred texture
glGenTextures(1, &m_tFinal);
glBindTexture(GL_TEXTURE_2D, m_tFinal);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Resolution.Width, m_Resolution.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Create third pass framebuffer
glGenFramebuffers(1, &m_fbDeferred3);
@@ -209,13 +285,13 @@ void dd::Renderer::CreateBuffers()
void dd::Renderer::Draw(RenderQueueCollection& rq)
{
DrawDeferred(rq.Deferred, rq.Lights);
rq.Forward.Jobs.sort(dd::Renderer::DepthSort);
DrawDeferred(rq.Deferred, rq.Lights);
DrawForward(rq.Forward, rq.Lights);
DrawGUI(rq.GUI);
// Finally: Draw the deferred+forward combined texture to the screen
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
@@ -257,7 +333,7 @@ void dd::Renderer::DrawDeferred(RenderQueue &objects, RenderQueue &lights)
glBlendFunc(GL_ONE, GL_ONE);
glDepthMask(GL_FALSE);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbDeferred2);
glClearColor(0, 0, 0, 1);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
m_spDeferred2->Bind();
DrawLightSpheres(lights);
@@ -266,7 +342,7 @@ void dd::Renderer::DrawDeferred(RenderQueue &objects, RenderQueue &lights)
glCullFace(GL_BACK);
glDisable(GL_BLEND);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbDeferred3);
glClearColor(0, 0, 0, 1);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
m_spDeferred3->Bind();
glUniform3fv(glGetUniformLocation(*m_spDeferred3, "La"), 1, glm::value_ptr(glm::vec3(0.5f)));
@@ -280,7 +356,6 @@ void dd::Renderer::DrawDeferred(RenderQueue &objects, RenderQueue &lights)
void dd::Renderer::DrawForward(RenderQueue &objects, RenderQueue &lights)
{
// Forward-render semi-transparent objects on top of the current framebuffer
glDisable(GL_CULL_FACE);
glCullFace(GL_BACK);
@@ -296,6 +371,19 @@ void dd::Renderer::DrawForward(RenderQueue &objects, RenderQueue &lights)
m_spForward->Bind();
DrawScene(objects, *m_spForward);
//WaterPass
glDisable(GL_CULL_FACE);
glCullFace(GL_BACK);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWater);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
t_m_spWater->Bind();
DrawWater(objects);
}
void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program)
@@ -311,6 +399,7 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program)
if (modelJob) {
glm::mat4 modelMatrix = modelJob->ModelMatrix;
MVP = PV * modelMatrix;
glUniform4fv(glGetUniformLocation(shaderProgramHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
@@ -318,7 +407,6 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program)
glUniform3fv(glGetUniformLocation(shaderProgramHandle, "LightSpecular"), 1, glm::value_ptr(glm::vec3(1.f)));
glUniform3fv(glGetUniformLocation(shaderProgramHandle, "LightDiffuse"), 1, glm::value_ptr(glm::vec3(1.f)));
glUniform1f(glGetUniformLocation(shaderProgramHandle, "LightRadius"), 40.0f);
glUniform1f(glGetUniformLocation(shaderProgramHandle, "MaterialShininess"), modelJob->Shininess);
glActiveTexture(GL_TEXTURE0);
@@ -339,7 +427,6 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program)
glBindTexture(GL_TEXTURE_2D, *m_StandardSpecular);
}
glBindVertexArray(modelJob->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, modelJob->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, modelJob->EndIndex - modelJob->StartIndex + 1, GL_UNSIGNED_INT, 0, modelJob->StartIndex);
@@ -355,6 +442,7 @@ void dd::Renderer::DrawScene(RenderQueue &objects, ShaderProgram &program)
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "M"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "V"), 1, GL_FALSE, glm::value_ptr(viewMatrix));
glUniform4fv(glGetUniformLocation(shaderProgramHandle, "Color"), 1, glm::value_ptr(modelJob->Color));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, spriteJob->DiffuseTexture);
@@ -409,6 +497,112 @@ void dd::Renderer::DrawLightSpheres(RenderQueue &lights)
}
}
void dd::Renderer::DrawWater(RenderQueue &rq)
{
GLuint shaderProgramHandle = *t_m_spWater;
glm::mat4 projectionMatrix = m_Camera->ProjectionMatrix();
glm::mat4 viewMatrix = m_Camera->ViewMatrix();
glm::mat4 PV = projectionMatrix * viewMatrix;
glm::mat4 MVP;
for ( auto &job : rq ) {
auto waterJob = std::dynamic_pointer_cast<WaterParticleJob>(job);
if (waterJob) {
glm::mat4 modelMatrix = waterJob->ModelMatrix;
MVP = PV * modelMatrix;
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "M"), 1, GL_FALSE,
glm::value_ptr(modelMatrix));
glUniformMatrix4fv(glGetUniformLocation(shaderProgramHandle, "V"), 1, GL_FALSE,
glm::value_ptr(viewMatrix));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, *t_m_WhiteSphereTexture);
glBindVertexArray(m_UnitQuad->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_UnitQuad->ElementBuffer);
glDrawElementsBaseVertex(GL_TRIANGLES, m_UnitQuad->m_Indices.size(), GL_UNSIGNED_INT, 0, 0);
}
}
//blur1
shaderProgramHandle = *t_m_spWater2;
glDisable(GL_CULL_FACE);
glDepthMask(GL_FALSE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindFramebuffer(GL_FRAMEBUFFER, t_m_fbWaterBlur);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
t_m_spWater2->Bind();
float radius = 3.f;
glUniform2fv(glGetUniformLocation(shaderProgramHandle, "dir"), 1, glm::value_ptr(glm::vec2(1.0f, 0.0f)));
glUniform1f(glGetUniformLocation(shaderProgramHandle, "res"), m_Resolution.Width);
glUniform1f(glGetUniformLocation(shaderProgramHandle, "radius"), radius);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, t_m_Gwater);
glBindVertexArray(m_ScreenQuad);
glDrawArrays(GL_TRIANGLES, 0, 6);
//blur2
shaderProgramHandle = *t_m_spWater2;
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbDeferred3);
t_m_spWater2->Bind();
glUniform2fv(glGetUniformLocation(shaderProgramHandle, "dir"), 1, glm::value_ptr(glm::vec2(0.0f, 1.0f)));
glUniform1f(glGetUniformLocation(shaderProgramHandle, "res"), m_Resolution.Height);
glUniform1f(glGetUniformLocation(shaderProgramHandle, "radius"), radius);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, t_m_BWater);
glBindVertexArray(m_ScreenQuad);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
GLuint dd::Renderer::CreateWaterParticleVAO(RenderQueue &particles)
{
float waterVerts[particles.Size()];
int i = 0;
for ( auto &job : particles ) {
auto waterJob = std::dynamic_pointer_cast<WaterParticleJob>(job);
if (!waterJob)
continue;
waterVerts[i ] = waterJob->Position.x;
waterVerts[i+1] = waterJob->Position.y;
waterVerts[i+2] = waterJob->Position.z;
i+3;
}
GLuint vbo[1], vao;
glGenBuffers(1, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, 3 * particles.Size() * sizeof(float), waterVerts, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
return vao;
}
GLuint dd::Renderer::CreateQuad()
{
float quadVertices[] =
@@ -472,6 +666,12 @@ void dd::Renderer::DebugKeys()
if (glfwGetKey(m_Window, GLFW_KEY_F6)) {
m_CurrentScreenBuffer = m_tLighting;
}
if (glfwGetKey(m_Window, GLFW_KEY_F7)) {
m_CurrentScreenBuffer = t_m_Gwater;
}
if (glfwGetKey(m_Window, GLFW_KEY_F8)) {
m_CurrentScreenBuffer = t_m_BWater;
}
}
void dd::Renderer::DrawGUI(dd::RenderQueue& rq)
+2
View File
@@ -24,6 +24,7 @@ layout (binding = 2) uniform sampler2D SpecularMap;
uniform mat4 V;
uniform float MaterialShininess;
uniform vec4 Color;
in VertexData
{
@@ -49,6 +50,7 @@ void main()
{
// Diffuse Texture
GDiffuse = texture(DiffuseTexture, Input.TextureCoord) * Input.DiffuseColor;
GDiffuse = GDiffuse * Color;
// G-buffer Position
GPosition = vec4(Input.Position.xyz, 1.0);
+90
View File
@@ -0,0 +1,90 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#version 440
layout (binding=0) uniform sampler2D DiffuseTexture;
layout (binding=1) uniform sampler2D NormalMap;
layout (binding=2) uniform sampler2D SpecularMap;
uniform mat4 MVP;
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform vec3 LightPosition;
uniform float LightRadius;
uniform vec3 LightSpecular;
uniform vec3 LightDiffuse;
in VertexData
{
vec3 Position;
vec3 Normal;
vec3 Tangent;
vec3 BiTangent;
vec2 TextureCoord;
vec4 DiffuseColor;
vec4 SpecularColor;
vec4 BoneIndices1;
vec4 BoneIndices2;
vec4 BoneWeights1;
vec4 BoneWeights2;
} Input;
out vec4 frag_Diffuse;
vec4 phong(vec3 position, vec3 normal, vec3 specular, float specularExponent)
{
// Diffuse
vec3 lightPos = vec3(V * vec4(LightPosition, 1.0));
vec3 distanceToLight = lightPos - position;
vec3 directionToLight = normalize(distanceToLight);
float dotProd = dot(directionToLight, normal);
dotProd = max(dotProd, 0.0);
vec3 Idiffuse = LightDiffuse * dotProd;
// Specular
//vec3 reflection = reflect(-directionToLight, normal);
vec3 surfaceToViewer = normalize(-position);
vec3 halfWay = normalize(surfaceToViewer + directionToLight);
float dotSpecular = max(dot(halfWay, normal), 0.0);
float specularFactor = pow(dotSpecular, specularExponent);
vec3 Ispecular = specular * LightSpecular * specularFactor;
//Attenuation
float dist = distance(lightPos, position);
//float attenuation = 1.0 - pow(dist / LightRadius, 2);
float attenuation = pow(max(0.0f, 1.0 - (dist / LightRadius)), 2);
return vec4((Idiffuse + Ispecular) * attenuation, 1.0);
}
void main()
{
vec4 normalTexel = texture(NormalMap, Input.TextureCoord);
mat3 TBN = mat3(Input.Tangent, Input.BiTangent, Input.Normal);
vec3 normal = normalize(vec4(TBN * normalTexel.xyz, 0.0).xyz);
vec4 specularTexel = texture(SpecularMap, Input.TextureCoord);
vec4 diffuseTexel = texture(DiffuseTexture, Input.TextureCoord);
vec4 La = vec4(0.3, 0.3, 0.3, 1.0);
vec4 light = phong(Input.Position, normalize(normal), specularTexel.rgb, specularTexel.a);
//frag_Diffuse = light;
frag_Diffuse = diffuseTexel;
}
+83
View File
@@ -0,0 +1,83 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#version 440
uniform mat4 MVP;
uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform mat4 Bones[100];
layout (location = 0) in vec3 Position;
layout (location = 1) in vec3 Normal;
layout (location = 2) in vec3 Tangent;
layout (location = 3) in vec3 BiTangent;
layout (location = 4) in vec2 TextureCoord;
layout (location = 5) in vec4 DiffuseColor;
layout (location = 6) in vec4 SpecularColor;
layout (location = 7) in vec4 BoneIndices1;
layout (location = 8) in vec4 BoneIndices2;
layout (location = 9) in vec4 BoneWeights1;
layout (location = 10) in vec4 BoneWeights2;
out VertexData
{
vec3 Position;
vec3 Normal;
vec3 Tangent;
vec3 BiTangent;
vec2 TextureCoord;
vec4 DiffuseColor;
vec4 SpecularColor;
vec4 BoneIndices1;
vec4 BoneIndices2;
vec4 BoneWeights1;
vec4 BoneWeights2;
} Output;
void main()
{
mat4 boneTransform = mat4(1);
if (length(BoneWeights1 + BoneWeights2) > 0) {
boneTransform = BoneWeights1[0] * Bones[int(BoneIndices1[0])]
+ BoneWeights1[1] * Bones[int(BoneIndices1[1])]
+ BoneWeights1[2] * Bones[int(BoneIndices1[2])]
+ BoneWeights1[3] * Bones[int(BoneIndices1[3])]
+ BoneWeights2[0] * Bones[int(BoneIndices2[0])]
+ BoneWeights2[1] * Bones[int(BoneIndices2[1])]
+ BoneWeights2[2] * Bones[int(BoneIndices2[2])]
+ BoneWeights2[3] * Bones[int(BoneIndices2[3])];
}
//gl_Position = MVP * boneTransform * vec4(Position, 1.0);
gl_Position = MVP * vec4(Position, 1.0);
//TODO: Make sure that boneTransform works here.
Output.Position = (V * M * boneTransform * vec4(Position, 1.0)).xyz;
Output.Normal = (inverse(transpose(V * M)) * boneTransform * vec4(Normal, 0.0)).xyz;
Output.Tangent = Tangent;
Output.BiTangent = BiTangent;
Output.TextureCoord = TextureCoord;
Output.DiffuseColor = DiffuseColor;
Output.SpecularColor = SpecularColor;
Output.BoneIndices1 = BoneIndices1;
Output.BoneIndices2 = BoneIndices2;
Output.BoneWeights1 = BoneWeights1;
Output.BoneWeights2 = BoneWeights2;
}
+70
View File
@@ -0,0 +1,70 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#version 440
uniform vec2 dir;
uniform float res;
uniform float radius;
layout (binding=0) uniform sampler2D WaterTexture;
in VertexData
{
vec3 Position;
vec2 TextureCoord;
} Input;
out vec4 frag_Diffuse;
void main()
{
vec4 WaterTexel = texture(WaterTexture, Input.TextureCoord);
vec4 sum = vec4(0.0);
vec2 tc = Input.TextureCoord;
//How much blur, 1 = blur by one pixel.
float blur = radius/res;
float hstep = dir.x;
float vstep = dir.y;
float Threshhold = 0.1;
//apply filter using a 9 tap filter with predefined gaussian weights
sum += texture(WaterTexture, vec2(tc.x - 4.0*blur*hstep, tc.y - 4.0*blur*vstep)) * 0.0162162162;
sum += texture(WaterTexture, vec2(tc.x - 3.0*blur*hstep, tc.y - 3.0*blur*vstep)) * 0.0540540541;
sum += texture(WaterTexture, vec2(tc.x - 2.0*blur*hstep, tc.y - 2.0*blur*vstep)) * 0.1216216216;
sum += texture(WaterTexture, vec2(tc.x - 1.0*blur*hstep, tc.y - 1.0*blur*vstep)) * 0.1945945946;
sum += texture(WaterTexture, vec2(tc.x, tc.y)) * 0.2270270270;
sum += texture(WaterTexture, vec2(tc.x + 1.0*blur*hstep, tc.y + 1.0*blur*vstep)) * 0.1945945946;
sum += texture(WaterTexture, vec2(tc.x + 2.0*blur*hstep, tc.y + 2.0*blur*vstep)) * 0.1216216216;
sum += texture(WaterTexture, vec2(tc.x + 3.0*blur*hstep, tc.y + 3.0*blur*vstep)) * 0.0540540541;
sum += texture(WaterTexture, vec2(tc.x + 4.0*blur*hstep, tc.y + 4.0*blur*vstep)) * 0.0162162162;
frag_Diffuse = vec4(sum.rgb, 1.0) * vec4(0.0, 0.6, 1.5, 1.0);
float avgColor = frag_Diffuse.r + frag_Diffuse.g + frag_Diffuse.b;
avgColor = avgColor/3;
if ( avgColor*dir.y > Threshhold ){
frag_Diffuse = vec4(0.0, 0.3, 1.0, 1.0);
}
}
+34
View File
@@ -0,0 +1,34 @@
/*
This file is part of Daydream Engine.
Copyright 2014 Adam Byléhn, Tobias Dahl, Simon Holmberg, Viktor Ljung
Daydream Engine is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Daydream Engine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with Daydream Engine. If not, see <http://www.gnu.org/licenses/>.
*/
#version 440
layout (location = 0) in vec3 Position;
out VertexData
{
vec3 Position;
vec2 TextureCoord;
} Output;
void main()
{
gl_Position = vec4(Position, 1.0);
Output.Position = Position;
Output.TextureCoord = (vec2(Position) + 1) / 2;
}
+2 -2
View File
@@ -72,6 +72,7 @@ void dd::Systems::PadSystem::Update(double dt)
transform->Velocity += acceleration * (float)dt;
transform->Velocity -= transform->Velocity * pad->SlowdownModifier * (float)dt;
if (Left()) {
acceleration.x = -pad->AccelerationSpeed;
} else if (Right()) {
@@ -188,10 +189,9 @@ bool dd::Systems::PadSystem::OnContact(const dd::Events::Contact &event)
//float movementX = (event.ContactPoint.x - transformPad->Position.x) * movementMultiplier;
float movementY = glm::cos((abs(movementX) / ((1.6f) * movementMultiplier)) * 3.14159265359f / 2)+ 0.2;
//std::cout << movementX << " " << movementY << std::endl;
float len = glm::length<float>(transformBall->Velocity);
//auto pointlight = m_World->AddComponent<Components::PointLight>(ent);
transformBall->Velocity += glm::vec3(transformPad->Velocity.x, 0, 0);
+313
View File
@@ -0,0 +1,313 @@
//
// Created by Adniklastrator on 2015-09-10.
//
#include "PrecompiledHeader.h"
#include "Game/PadSystem.h"
#include "Core/World.h"
#include <iostream>
#include <Game/CPad.h>
#include <Rendering/CPointLight.h>
void dd::Systems::PadSystem::Initialize()
{
Events::BindKey r;
r.KeyCode = GLFW_KEY_RIGHT;
r.Command = "right";
EventBroker->Publish(r);
Events::BindKey l;
l.KeyCode = GLFW_KEY_LEFT;
l.Command = "left";
EventBroker->Publish(l);
EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &PadSystem::OnKeyDown);
EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &PadSystem::OnKeyUp);
EVENT_SUBSCRIBE_MEMBER(m_EContact, &PadSystem::OnContact);
EVENT_SUBSCRIBE_MEMBER(m_EContactPowerUp, &PadSystem::OnContactPowerUp);
EVENT_SUBSCRIBE_MEMBER(m_EResetBall, &PadSystem::OnResetBall);
EVENT_SUBSCRIBE_MEMBER(m_EMultiBall, &PadSystem::OnMultiBall);
EVENT_SUBSCRIBE_MEMBER(m_EStageCleared, &PadSystem::OnStageCleared);
}
void dd::Systems::PadSystem::UpdateEntity(double dt, EntityID entity, EntityID parent)
{
auto ball = m_World->GetComponent<Components::Ball>(entity);
if (ball != nullptr) {
if (ReplaceBall() == true) {
SetReplaceBall(false);
auto transform = m_World->GetComponent<Components::Transform>(entity);
transform->Position = glm::vec3(0.0f, 0.26f, -10.f);
transform->Velocity = glm::vec3(0.0f, -ball->Speed, 0.f);
}
}
}
void dd::Systems::PadSystem::Update(double dt)
{
if (Entity() == 0) {
for (auto it = m_World->GetEntities()->begin(); it != m_World->GetEntities()->end(); it++) {
if (m_World->GetProperty<std::string>(it->first, "Name") == "Pad") {
SetEntity(it->first);
SetTransform(m_World->GetComponent<Components::Transform>(Entity()));
SetPad(m_World->GetComponent<Components::Pad>(Entity()));
break;
}
}
}
auto transform = Transform();
auto pad = Pad();
auto acceleration = Acceleration();
if (transform->Velocity.x < -pad->MaxSpeed) {
transform->Velocity.x = -pad->MaxSpeed;
}
else if (transform->Velocity.x > pad->MaxSpeed) {
transform->Velocity.x = pad->MaxSpeed;
}
transform->Position += transform->Velocity * (float)dt;
transform->Velocity += acceleration * (float)dt;
transform->Velocity -= transform->Velocity * pad->SlowdownModifier * (float)dt;
if (Left()) {
acceleration.x = -pad->AccelerationSpeed;
<<<<<<< HEAD
}
else if (Right()) {
=======
} else if (Right()) {
>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db
acceleration.x = pad->AccelerationSpeed;
} else {
acceleration.x = 0.f;
}
SetTransform(transform);
SetPad(pad);
SetAcceleration(acceleration);
if (MultiBall() == true) {
SetMultiBall(false);
Events::MultiBall e;
e.padTransform = transform;
EventBroker->Publish(e);
}
return;
}
EntityID dd::Systems::PadSystem::CreateBall()
{
auto ent = m_World->CreateEntity();
std::shared_ptr<Components::Transform> transform = m_World->AddComponent<Components::Transform>(ent);
transform->Position = glm::vec3(0.5f, 0.26f, -10.f);
transform->Scale = glm::vec3(0.5f, 0.5f, 0.5f);
auto model = m_World->AddComponent<Components::Model>(ent);
model->ModelFile = "Models/Test/Ball/Ballopus.obj";
//auto pointlight = m_World->AddComponent<Components::PointLight>(ent);
std::shared_ptr<Components::CircleShape> circleShape = m_World->AddComponent<Components::CircleShape>(ent);
std::shared_ptr<Components::Ball> cball = m_World->AddComponent<Components::Ball>(ent);
std::shared_ptr<Components::Physics> physics = m_World->AddComponent<Components::Physics>(ent);
physics->Static = false;
cball->Speed = 10;
m_World->CommitEntity(ent);
return ent;
}
bool dd::Systems::PadSystem::OnKeyDown(const dd::Events::KeyDown &event)
{
int val = event.KeyCode;
if (val == GLFW_KEY_UP) {
//std::cout << "Up!" << std::endl;
} else if (val == GLFW_KEY_DOWN) {
//std::cout << "Down!" << std::endl;
} else if (val == GLFW_KEY_LEFT) {
//std::cout << "Left!" << std::endl;
//acceleration.x = -0.01f;
SetLeft(true);
} else if (val == GLFW_KEY_RIGHT) {
//std::cout << "Right!" << std::endl;
//acceleration.x = 0.01f;
SetRight(true);
} else if (val == GLFW_KEY_R) {
SetReplaceBall(true);
} else if (val == GLFW_KEY_M) {
SetMultiBall(true);
} else if (val == GLFW_KEY_D) {
return false;
}
return true;
}
bool dd::Systems::PadSystem::OnKeyUp(const dd::Events::KeyUp &event)
{
int val = event.KeyCode;
if (val == GLFW_KEY_UP) {
} else if (val == GLFW_KEY_DOWN) {
} else if (val == GLFW_KEY_LEFT) {
SetLeft(false);
} else if (val == GLFW_KEY_RIGHT) {
SetRight(false);
}
return true;
}
bool dd::Systems::PadSystem::OnContact(const dd::Events::Contact &event)
{
/*
EntityID entityBall = event.Entity2;
auto ball = m_World->GetComponent<Components::Ball>(entityBall);
if (ball == NULL) {
return false;
}
EntityID entityPad = event.Entity1;
auto pad = m_World->GetComponent<Components::Pad>(entityPad);
if (pad == NULL) {
return false;
}
auto transformBall = m_World->GetComponent<Components::Transform>(entityBall);
auto transformPad = m_World->GetComponent<Components::Transform>(entityPad);
float movementMultiplier = 0.5f;
//float movementX = (event.ContactPoint.x - transformPad->Position.x) * movementMultiplier;
//float movementY = glm::cos((abs(movementX) / (3.2f * movementMultiplier)) * 3.14159265359f / 2) * 2.f;
if (whatX > 0) {
movementX = movementMultiplier * whatX;
//std::cout << "Right!" << std::endl;
} else {
movementX = movementMultiplier * whatX;
//std::cout << "Left!" << std::endl;
}
// std::cout << movementX << " " << movementY << std::endl;
//float movementX = (event.ContactPoint.x - transformPad->Position.x) * movementMultiplier;
<<<<<<< HEAD
float movementY = glm::cos((abs(movementX) / ((1.6f) * movementMultiplier)) * 3.14159265359f / 2) + 1;
=======
float movementY = glm::cos((abs(movementX) / ((1.6f) * movementMultiplier)) * 3.14159265359f / 2)+ 0.2;
>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db
//std::cout << movementX << " " << movementY << std::endl;
float len = glm::length<float>(transformBall->Velocity);
//auto pointlight = m_World->AddComponent<Components::PointLight>(ent);
transformBall->Velocity += glm::vec3(transformPad->Velocity.x, 0, 0);
transformBall->Velocity = glm::normalize(transformBall->Velocity) * len;
//transform->Velocity = glm::vec3(movementX, movementY, 0.f);
*/
}
bool dd::Systems::PadSystem::OnContactPowerUp(const dd::Events::Contact &event)
{
EntityID entityPower;
EntityID entityPad;
auto powerUp = m_World->GetComponent<Components::PowerUp>(event.Entity1);
auto pad = m_World->GetComponent<Components::Pad>(event.Entity2);
if (powerUp != nullptr) {
entityPower = event.Entity1;
} else {
powerUp = m_World->GetComponent<Components::PowerUp>(event.Entity2);
if (powerUp != nullptr) {
entityPower = event.Entity2;
}
}
if (pad != nullptr) {
entityPad = event.Entity2;
} else {
pad = m_World->GetComponent<Components::Pad>(event.Entity1);
if (pad != nullptr) {
entityPad = event.Entity1;
}
}
if (entityPower == NULL || entityPad == NULL) {
return false;
}
pad = m_World->GetComponent<Components::Pad>(entityPad);
if (pad == nullptr) {
return false;
}
m_World->RemoveComponent<Components::PowerUp>(entityPower);
m_World->RemoveComponent<Components::CircleShape>(entityPower);
m_World->RemoveComponent<Components::Physics>(entityPower);
m_World->RemoveEntity(entityPower);
Events::PowerUpTaken ep;
ep.Name = "Something";
EventBroker->Publish(ep);
Events::MultiBall e;
auto transform = m_World->GetComponent<Components::Transform>(entityPad);
e.padTransform = transform;
EventBroker->Publish(e);
return true;
}
bool dd::Systems::PadSystem::OnResetBall(const dd::Events::ResetBall &event)
{
SetReplaceBall(true);
return true;
}
bool dd::Systems::PadSystem::OnMultiBall(const dd::Events::MultiBall &event)
{
auto ent1 = CreateBall();
auto ent2 = CreateBall();
auto transform1 = m_World->GetComponent<Components::Transform>(ent1);
auto transform2 = m_World->GetComponent<Components::Transform>(ent2);
auto ball1 = m_World->GetComponent<Components::Ball>(ent1);
auto ball2 = m_World->GetComponent<Components::Ball>(ent2);
auto padTransform = event.padTransform;
float x1 = padTransform->Position.x - 2, x2 = padTransform->Position.x + 2;
if (x1 < -3.1) {
x1 = 3;
}
if (x2 > 3.1) {
x2 = -3;
}
transform1->Position = glm::vec3(x1, -5.5, -10);
transform2->Position = glm::vec3(x2, -5.5, -10);
transform1->Velocity = glm::normalize(glm::vec3(5, 5 ,0.f)) * ball1->Speed;
transform2->Velocity = glm::normalize(glm::vec3(-5, 5 ,0.f)) * ball2->Speed;
return true;
}
bool dd::Systems::PadSystem::OnStageCleared(const dd::Events::StageCleared &event)
{
auto entity = CreateBall();
return true;
}
bool dd::Systems::PadSystem::PadSteeringInputController::OnCommand(const Events::InputCommand &event)
{
std::string command = event.Command;
std::cout << "Command!" << std::endl;
if (command == "right") {
std::cout << "Right!" << std::endl;
} else if (command == "left") {
std::cout << "Left!" << std::endl;
}
return true;
}
+78 -16
View File
@@ -12,7 +12,7 @@ void dd::Systems::PhysicsSystem::Initialize()
{
m_ContactListener = new ContactListener(this);
m_Gravity = b2Vec2(0.f, 0.f);
m_Gravity = b2Vec2(0.f, -9.82f);
m_PhysicsWorld = new b2World(m_Gravity);
m_TimeStep = 1.f/60.f;
@@ -22,9 +22,19 @@ void dd::Systems::PhysicsSystem::Initialize()
m_PhysicsWorld->SetContactListener(m_ContactListener);
InitializeWater();
EVENT_SUBSCRIBE_MEMBER(m_SetImpulse, PhysicsSystem::SetImpulse);
}
void dd::Systems::PhysicsSystem::InitializeWater()
{
b2ParticleSystemDef m_ParticleSystemDef;
m_ParticleSystemDef.radius = 0.13f;
m_ParticleSystem = m_PhysicsWorld->CreateParticleSystem(&m_ParticleSystemDef);
}
bool dd::Systems::PhysicsSystem::SetImpulse(const Events::SetImpulse &event)
{
b2Body* body = m_EntitiesToBodies[event.Entity];
@@ -72,9 +82,6 @@ void dd::Systems::PhysicsSystem::Update(double dt)
body->SetTransform(position, angle);
body->SetLinearVelocity(b2Vec2(transformComponent->Velocity.x, transformComponent->Velocity.y));
}
}
@@ -82,8 +89,6 @@ void dd::Systems::PhysicsSystem::Update(double dt)
i.Body->ApplyLinearImpulse(i.Impulse, i.Point, true);
}
m_Impulses.clear();
m_Accumulator += dt;
while(m_Accumulator >= m_TimeStep)
{
@@ -91,7 +96,6 @@ void dd::Systems::PhysicsSystem::Update(double dt)
m_Accumulator -= dt;
}
for (auto i : m_EntitiesToBodies) {
EntityID entity = i.first;
b2Body* body = i.second;
@@ -104,7 +108,8 @@ void dd::Systems::PhysicsSystem::Update(double dt)
auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if (! transformComponent)
continue;
if (m_World->GetEntityParent(entity) == 0) {
auto parent = m_World->GetEntityParent(entity);
if (parent == 0) {
b2Vec2 position = body->GetPosition();
transformComponent->Position.x = position.x;
transformComponent->Position.y = position.y;
@@ -114,12 +119,24 @@ void dd::Systems::PhysicsSystem::Update(double dt)
transformComponent->Orientation = glm::quat(glm::vec3(0, 0, -angle));
b2Vec2 velocity = body->GetLinearVelocity();
transformComponent->Velocity.x = velocity.x;
transformComponent->Velocity.y = velocity.y;
}
}
b2Vec2* positionBuffer = m_ParticleSystem->GetPositionBuffer();
for (auto i : m_EntitiesToParticleHandle) {
EntityID entity = i.first;
b2ParticleHandle* particleH = i.second;
b2Vec2 positionB2 = positionBuffer[particleH->GetIndex()];
glm::vec2 position = glm::vec2(positionB2.x, positionB2.y);
EntityID entityParent = m_World->GetEntityParent(entity);
auto transform = m_World->GetComponent<Components::Transform>(entity);
auto transformParent = m_World->GetComponent<Components::Transform>(entityParent);
transform->Position = glm::vec3(position.x, position.y, -10) - transformParent->Position;
}
}
void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent)
@@ -127,12 +144,19 @@ void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, Entity
}
void dd::Systems::PhysicsSystem::OnEntityCommit(EntityID entity)
{
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
if(physicsComponent) {
auto waterComponent = m_World->GetComponent<Components::WaterVolume>(entity);
if (physicsComponent && waterComponent) {
LOG_ERROR("Entity has both water and physics component, this is illegal. The police has been alerted.");
return;
}
if (physicsComponent) {
CreateBody(entity);
} else if (waterComponent) {
CreateParticleGroup(entity);
}
}
@@ -189,7 +213,7 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity)
auto boxComponent = m_World->GetComponent<Components::RectangleShape>(entity);
if (boxComponent) {
b2PolygonShape* bShape = new b2PolygonShape();
bShape->SetAsBox(absoluteTransform.Scale.x/2, absoluteTransform.Scale.y/2); //TODO: THIS SUCKS DUDE 4?!?!?!?
bShape->SetAsBox(absoluteTransform.Scale.x/2, absoluteTransform.Scale.y/2);
pShape = bShape;
} else {
auto circleComponent = m_World->GetComponent<Components::CircleShape>(entity);
@@ -201,7 +225,7 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity)
if (absoluteTransform.Scale.x != absoluteTransform.Scale.y && absoluteTransform.Scale.y != absoluteTransform.Scale.z) {
LOG_WARNING("Circles has to be of uniform scale.");
}
pShape->m_radius = absoluteTransform.Scale.x/2; //TODO: THIS ALSO SUCKS 4 WTH
pShape->m_radius = absoluteTransform.Scale.x/2;
}
}
@@ -226,6 +250,44 @@ void dd::Systems::PhysicsSystem::CreateBody(EntityID entity)
m_BodiesToEntities.insert(std::make_pair(body, entity));
}
void dd::Systems::PhysicsSystem::CreateParticleGroup(EntityID e)
{
//TODO: Lägg alla pd i en lista
auto transform = m_World->GetComponent<Components::Transform>(e);
if (!transform) {
LOG_ERROR("No Transform component in CreateParticleGroup");
return;
}
b2ParticleGroupDef pd;
b2PolygonShape shape;
shape.SetAsBox(transform->Scale.x/2.f, transform->Scale.y/2.f);
pd.shape = &shape;
pd.flags = b2_tensileParticle;
pd.position.Set(transform->Position.x, transform->Position.y);
//TODO: PUT IN LIST
t_watergroup = m_ParticleSystem->CreateParticleGroup(pd);
b2Vec2* t_ParticlePositions = m_ParticleSystem->GetPositionBuffer();
for(int i = 0; i < m_ParticleSystem->GetParticleCount(); i++){
{
auto t_waterparticle = m_World->CreateEntity(e);
auto transformChild = m_World->AddComponent<Components::Transform>(t_waterparticle);
//auto sprite = m_World->AddComponent<Components::Sprite>(t_waterparticle);
transformChild->Position = glm::vec3(t_ParticlePositions[i].x - transform->Position.x, t_ParticlePositions[i].y - transform->Position.y, -9.5f);
transformChild->Scale = glm::vec3(m_ParticleSystem->GetRadius())/transform->Scale;
//sprite->SpriteFile = "Textures/Ball.png";
m_World->CommitEntity(t_waterparticle);
m_EntitiesToParticleHandle.insert(std::make_pair(t_waterparticle, m_ParticleSystem->GetParticleHandleFromIndex(i)));
m_ParticleHandleToEntities.insert(std::make_pair( m_ParticleSystem->GetParticleHandleFromIndex(i), t_waterparticle));
}
}
LOG_INFO("ParticleCount: %i", m_ParticleSystem->GetParticleCount());
}
dd::Systems::PhysicsSystem::~PhysicsSystem()
{
if (m_ContactListener != nullptr) {
+326
View File
@@ -0,0 +1,326 @@
#include "PrecompiledHeader.h"
#include "Physics/PhysicsSystem.h"
void dd::Systems::PhysicsSystem::RegisterComponents(ComponentFactory* cf)
{
cf->Register<Components::CircleShape>();
}
void dd::Systems::PhysicsSystem::Initialize()
{
m_ContactListener = new ContactListener(this);
m_Gravity = b2Vec2(0.f, -9.82f);
m_PhysicsWorld = new b2World(m_Gravity);
m_TimeStep = 1.f/60.f;
m_VelocityIterations = 6;
m_PositionIterations = 2;
m_Accumulator = 0.f;
m_PhysicsWorld->SetContactListener(m_ContactListener);
InitializeWater();
EVENT_SUBSCRIBE_MEMBER(m_SetImpulse, PhysicsSystem::SetImpulse);
}
void dd::Systems::PhysicsSystem::InitializeWater()
{
b2ParticleSystemDef m_ParticleSystemDef;
m_ParticleSystemDef.radius = 0.1f;
m_ParticleSystem = m_PhysicsWorld->CreateParticleSystem(&m_ParticleSystemDef);
}
bool dd::Systems::PhysicsSystem::SetImpulse(const Events::SetImpulse &event)
{
b2Body* body = m_EntitiesToBodies[event.Entity];
b2Vec2 impulse;
impulse.x = event.Impulse.x;
impulse.y = event.Impulse.y;
b2Vec2 point;
point.x = event.Point.x;
point.y = event.Point.y;
Impulse i;
i.Body = body;
i.Impulse = impulse;
i.Point = point;
m_Impulses.push_back(i);
return true;
}
void dd::Systems::PhysicsSystem::Update(double dt)
{
for (auto i : m_EntitiesToBodies) {
EntityID entity = i.first;
b2Body* body = i.second;
auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if (! transformComponent)
continue;
if (body == nullptr) {
//LOG_ERROR("This body should not exist");
continue;
}
<<<<<<< HEAD
if (m_World->GetEntityParent(entity) == 0) {
=======
if (m_World->GetEntityParent(entity) == 0) { //TODO: Make this work with childs too
>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db
b2Vec2 position;
position.x = transformComponent->Position.x;
position.y = transformComponent->Position.y;
float angle = -glm::eulerAngles(transformComponent->Orientation).z;
body->SetTransform(position, angle);
<<<<<<< HEAD
}
}
=======
body->SetLinearVelocity(b2Vec2(transformComponent->Velocity.x, transformComponent->Velocity.y));
}
}
for (auto i : m_Impulses) {
i.Body->ApplyLinearImpulse(i.Impulse, i.Point, true);
}
m_Impulses.clear();
>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db
m_Accumulator += dt;
while(m_Accumulator >= m_TimeStep)
{
m_PhysicsWorld->Step(m_TimeStep, m_VelocityIterations, m_PositionIterations);
m_Accumulator -= dt;
}
for (auto i : m_EntitiesToBodies) {
EntityID entity = i.first;
b2Body* body = i.second;
if (body == nullptr) {
//LOG_ERROR("This body should not exist");
continue;
}
auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if (! transformComponent)
continue;
<<<<<<< HEAD
auto parent = m_World->GetEntityParent(entity);
if (parent == 0) {
=======
if (m_World->GetEntityParent(entity) == 0) {
>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db
b2Vec2 position = body->GetPosition();
transformComponent->Position.x = position.x;
transformComponent->Position.y = position.y;
float angle = body->GetAngle();
transformComponent->Orientation = glm::quat(glm::vec3(0, 0, -angle));
<<<<<<< HEAD
=======
b2Vec2 velocity = body->GetLinearVelocity();
transformComponent->Velocity.x = velocity.x;
transformComponent->Velocity.y = velocity.y;
>>>>>>> 72413dc0a93bd3a2f6ab9fa7e19bbc3b846232db
}
}
b2Vec2* positionBuffer = m_ParticleSystem->GetPositionBuffer();
for (auto i : m_EntitiesToParticleHandle) {
EntityID entity = i.first;
b2ParticleHandle* particleH = i.second;
b2Vec2 positionB2 = positionBuffer[particleH->GetIndex()];
glm::vec2 position = glm::vec2(positionB2.x, positionB2.y);
EntityID entityParent = m_World->GetEntityParent(entity);
auto transform = m_World->GetComponent<Components::Transform>(entity);
auto transformParent = m_World->GetComponent<Components::Transform>(entityParent);
transform->Position = glm::vec3(position.x, position.y, -10) - transformParent->Position;
}
}
void dd::Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID parent)
{
}
void dd::Systems::PhysicsSystem::OnEntityCommit(EntityID entity)
{
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
auto waterComponent = m_World->GetComponent<Components::WaterVolume>(entity);
if (physicsComponent && waterComponent) {
LOG_ERROR("Entity has both water and physics component, this is illegal. The police has been alerted.");
return;
}
if (physicsComponent) {
CreateBody(entity);
} else if (waterComponent) {
CreateParticleGroup(entity);
}
}
void dd::Systems::PhysicsSystem::OnEntityRemoved(EntityID entity)
{
b2Body* body = m_EntitiesToBodies[entity];
if (body != nullptr) {
m_EntitiesToBodies.erase(entity);
m_BodiesToEntities.erase(body);
m_PhysicsWorld->DestroyBody(body);
}
}
void dd::Systems::PhysicsSystem::CreateBody(EntityID entity)
{
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity);
if(!physicsComponent){
LOG_ERROR("No PhysicsComponent in CreateBody");
return;
}
auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
if(!transformComponent) {
LOG_ERROR("No TransformComponent in CreateBody");
return;
}
auto absoluteTransform = m_World->GetSystem<Systems::TransformSystem>()->AbsoluteTransform(entity);
b2BodyDef bodyDef;
bodyDef.position.Set(absoluteTransform.Position.x, absoluteTransform.Position.y);
bodyDef.angle = -glm::eulerAngles(absoluteTransform.Orientation).z;
if (physicsComponent->Static) {
bodyDef.type = b2_staticBody;
} else {
bodyDef.type = b2_dynamicBody;
}
b2Body* body = m_PhysicsWorld->CreateBody(&bodyDef);
b2Shape* pShape;
auto boxComponent = m_World->GetComponent<Components::RectangleShape>(entity);
if (boxComponent) {
b2PolygonShape* bShape = new b2PolygonShape();
bShape->SetAsBox(absoluteTransform.Scale.x/2, absoluteTransform.Scale.y/2);
pShape = bShape;
} else {
auto circleComponent = m_World->GetComponent<Components::CircleShape>(entity);
if (circleComponent) {
pShape = new b2CircleShape();
pShape->m_radius = absoluteTransform.Scale.x;
if (absoluteTransform.Scale.x != absoluteTransform.Scale.y && absoluteTransform.Scale.y != absoluteTransform.Scale.z) {
LOG_WARNING("Circles has to be of uniform scale.");
}
pShape->m_radius = absoluteTransform.Scale.x/2;
}
}
if(physicsComponent->Static) {
body->CreateFixture(pShape, 0); //Density kanske ska vara 0 på statiska kroppar
}
else {
//TODO: FIX THIS SHIT INTO COMPONENTS
b2FixtureDef fixtureDef;
fixtureDef.shape = pShape;
fixtureDef.density = 1.f;
fixtureDef.restitution = 1.0f;
fixtureDef.friction = 0.0f;
body->CreateFixture(&fixtureDef);
}
delete pShape;
m_EntitiesToBodies.insert(std::make_pair(entity, body));
m_BodiesToEntities.insert(std::make_pair(body, entity));
}
void dd::Systems::PhysicsSystem::CreateParticleGroup(EntityID e)
{
//TODO: Lägg alla pd i en lista
auto transform = m_World->GetComponent<Components::Transform>(e);
if (!transform) {
LOG_ERROR("No Transform component in CreateParticleGroup");
return;
}
b2ParticleGroupDef pd;
b2PolygonShape shape;
shape.SetAsBox(transform->Scale.x/2.f, transform->Scale.y/2.f);
pd.shape = &shape;
pd.flags = b2_tensileParticle;
pd.linearVelocity = b2Vec2(0, 5.f);
pd.position.Set(transform->Position.x, transform->Position.y);
//TODO: PUT IN LIST
t_watergroup = m_ParticleSystem->CreateParticleGroup(pd);
b2Vec2* t_ParticlePositions = m_ParticleSystem->GetPositionBuffer();
for(int i = 0; i < m_ParticleSystem->GetParticleCount(); i++){
{
auto t_waterparticle = m_World->CreateEntity(e);
auto transformChild = m_World->AddComponent<Components::Transform>(t_waterparticle);
//auto sprite = m_World->AddComponent<Components::Sprite>(t_waterparticle);
transformChild->Position = glm::vec3(t_ParticlePositions[i].x - transform->Position.x, t_ParticlePositions[i].y - transform->Position.y, -9.5f);
transformChild->Scale = glm::vec3(m_ParticleSystem->GetRadius())/transform->Scale;
//sprite->SpriteFile = "Textures/Ball.png";
m_World->CommitEntity(t_waterparticle);
m_EntitiesToParticleHandle.insert(std::make_pair(t_waterparticle, m_ParticleSystem->GetParticleHandleFromIndex(i)));
m_ParticleHandleToEntities.insert(std::make_pair( m_ParticleSystem->GetParticleHandleFromIndex(i), t_waterparticle));
}
}
LOG_INFO("ParticleCount: %i", m_ParticleSystem->GetParticleCount());
}
dd::Systems::PhysicsSystem::~PhysicsSystem()
{
if (m_ContactListener != nullptr) {
delete m_ContactListener;
m_ContactListener = nullptr;
}
}