diff --git a/cw 7/shaders/shader_5_1.frag b/cw 7/shaders/shader_5_1.frag new file mode 100644 index 0000000..e3aa0de --- /dev/null +++ b/cw 7/shaders/shader_5_1.frag @@ -0,0 +1,70 @@ +#version 430 core + +uniform vec3 color; +uniform vec3 sunPos; +uniform vec3 sunColor; +uniform float sunLightExp; + +uniform vec3 cameraPos; +uniform float time; + +uniform vec3 reflectorPos; +uniform vec3 reflectorDir; +uniform vec3 reflectorColor; +uniform float reflectorAngle; +uniform float reflectorLightExp; + +vec3 normalizedVertexNormal; + +in vec3 vertexNormalOut; +in vec3 vertexPosOut; +out vec4 outColor; + +vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) { + vec3 lightDir = normalize(vertexPosOut - lightPos); + float lightDistance = length(vertexPosOut - lightPos); + vec3 newLightColor = lightColor / pow(lightDistance, 2); + + float intensity = dot(normalizedVertexNormal, -lightDir); + intensity = max(intensity, 0.0); + + vec3 viewDir = normalize(cameraPos - vertexPosOut); + vec3 reflectDir = reflect(lightDir, normalizedVertexNormal); + + float glossPow = 8; + float specular = pow(max(dot(viewDir, reflectDir), 0.0), glossPow); + + float diffuse = intensity; + vec3 resultColor = newLightColor * (fragColor * diffuse + specular ); + return vec4(1 - exp(-resultColor * lightExp), 1.0); +} + +vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, vec3 lightDir, float lightExp) { + vec3 reflectorLightDir = normalize(vertexPosOut - reflectorPos); + float angleCos = dot(reflectorLightDir, reflectorDir); + float reflectorOutAngle = reflectorAngle + radians(10); + float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle); + vec4 res = vec4(0, 0, 0, 1); + if (angleCos > cos(reflectorOutAngle)) { + float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0); + res = calcPointLight(fragColor, reflectorPos, reflectorColor, reflectorLightExp * intensity); + } + return res; +} + + +void main() +{ + normalizedVertexNormal = normalize(vertexNormalOut); + + outColor = calcPointLight(color, sunPos, sunColor, sunLightExp); + + vec3 reflectorLightDir = normalize(vertexPosOut - reflectorPos); + float angleCos = dot(reflectorLightDir, reflectorDir); + float reflectorOutAngle = reflectorAngle + radians(10); + float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle); + if (angleCos > cos(reflectorOutAngle)) { + float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0); + outColor += calcSpotLight(color, reflectorPos, reflectorColor, reflectorLightDir, reflectorLightExp * intensity); + } +} diff --git a/cw 7/shaders/shader_5_1.vert b/cw 7/shaders/shader_5_1.vert new file mode 100644 index 0000000..94ba36b --- /dev/null +++ b/cw 7/shaders/shader_5_1.vert @@ -0,0 +1,19 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; +layout(location = 1) in vec3 vertexNormal; +layout(location = 2) in vec2 vertexTexCoord; + +uniform mat4 transformation; +uniform mat4 modelMat; + +out vec3 vertexNormalOut; +out vec3 vertexPosOut; + +void main() +{ + gl_Position = transformation * vec4(vertexPosition, 1.0); + vec4 worldNormal = modelMat * vec4(vertexNormal, 0.0); + vertexNormalOut = worldNormal.xyz; + vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz; +} diff --git a/cw 7/shaders/shader_5_1_tex.frag b/cw 7/shaders/shader_5_1_tex.frag new file mode 100644 index 0000000..725da25 --- /dev/null +++ b/cw 7/shaders/shader_5_1_tex.frag @@ -0,0 +1,95 @@ +#version 430 core + +uniform sampler2D colorTexture; +uniform sampler2D normalSampler; + +uniform vec3 sunPos; +uniform vec3 sunColor; +uniform float sunLightExp; + +uniform vec3 cameraPos; +uniform float time; + +uniform vec3 reflectorPos; +uniform vec3 reflectorDir; +uniform vec3 reflectorColor; +uniform float reflectorAngle; +uniform float reflectorLightExp; + +vec3 normalizedVertexNormal; +mat3 TBN; + +in vec3 vertexNormalOut; +in vec3 vertexTangentOut; +in vec3 vertexBitangentOut; +in vec3 vertexPosOut; +in vec2 vertexTexCoordOut; + +out vec4 outColor; + +vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) { + vec3 lightDir = normalize(vertexPosOut - lightPos); + vec3 viewDir = normalize(cameraPos - vertexPosOut); + + // tangent space + vec3 viewDirTS = TBN * viewDir; + vec3 lightDirTS = TBN * lightDir; + + //tmp solution + viewDir = normalize(viewDirTS); + lightDir = normalize(lightDirTS); + + float lightDistance = length(vertexPosOut - lightPos); + vec3 newLightColor = lightColor / pow(lightDistance, 2); + + float intensity = dot(normalizedVertexNormal, -lightDir); + intensity = max(intensity, 0.0); + + vec3 reflectDir = reflect(lightDir, normalizedVertexNormal); + + + float glossPow = 8; + float specular = pow(max(dot(viewDir, reflectDir), 0.0), glossPow); + + float diffuse = intensity; + vec3 resultColor = newLightColor * (fragColor * diffuse + specular ); + return vec4(1 - exp(-resultColor * lightExp), 1.0); +} + +vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) { + vec3 reflectorLightDir = normalize(vertexPosOut - lightPos); + float angleCos = dot(reflectorLightDir, reflectorDir); + float reflectorOutAngle = reflectorAngle + radians(10); + float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle); + vec4 res = vec4(0, 0, 0, 1); + if (angleCos > cos(reflectorOutAngle)) { + float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0); + res = calcPointLight(fragColor, lightPos, lightColor, lightExp * intensity); + } + return res; +} + + +void main() +{ + TBN = transpose(mat3(vertexTangentOut, vertexBitangentOut, vertexNormalOut)); + + vec3 textureColor = texture2D(colorTexture, vertexTexCoordOut).rgb; + + normalizedVertexNormal = normalize(vertexNormalOut); + //get normal from normal sampler + vec3 samplerNormal = texture2D(normalSampler, vertexTexCoordOut).xyz; + samplerNormal = 2 * samplerNormal - 1;//since sampler has values from [0, 1], but we want [-1, 1] + normalizedVertexNormal = normalized(samplerNormal);// to avoid potential precision problems in sampler texture + + //tmp solution + //normalizedVertexNormal = vec3(0, 0, 1); + + outColor = calcPointLight(textureColor, sunPos, sunColor, sunLightExp); + + outColor += calcSpotLight(textureColor, reflectorPos, reflectorColor, reflectorLightExp); + + //Debug + //outColor = vec4(textureColor, 1); +} + diff --git a/cw 7/shaders/shader_5_1_tex.vert b/cw 7/shaders/shader_5_1_tex.vert new file mode 100644 index 0000000..73276e9 --- /dev/null +++ b/cw 7/shaders/shader_5_1_tex.vert @@ -0,0 +1,27 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; +layout(location = 1) in vec3 vertexNormal; +layout(location = 2) in vec2 vertexTexCoord; +layout(location = 3) in vec3 vertexTangent; +layout(location = 4) in vec3 vertexBitangent; + +uniform mat4 transformation; +uniform mat4 modelMat; + +out vec3 vertexNormalOut; +out vec3 vertexTangentOut; +out vec3 vertexBitangentOut; +out vec3 vertexPosOut; +out vec2 vertexTexCoordOut; + +void main() +{ + gl_Position = transformation * vec4(vertexPosition, 1.0); + vertexNormalOut = (modelMat * vec4(vertexNormal, 0.0)).xyz; + vertexTangentOut = (modelMat * vec4(vertexTangent, 0.0)).xyz; + vertexBitangentOut = (modelMat * vec4(vertexBitangent, 0.0)).xyz; + vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz; + vertexTexCoordOut = vertexTexCoord; +} + diff --git a/cw 7/shaders/shader_5_sun.frag b/cw 7/shaders/shader_5_sun.frag new file mode 100644 index 0000000..14782e4 --- /dev/null +++ b/cw 7/shaders/shader_5_sun.frag @@ -0,0 +1,21 @@ +#version 430 core + +uniform vec3 color; +uniform vec3 lightPos; +uniform vec3 lightColor; +uniform vec3 cameraPos; + +in vec3 interpNormal; +in vec3 vertexNormalOut; +in vec3 vertexPosOut; +out vec4 outColor; + +void main() +{ + vec3 normalizedVertexNormal = normalize(vertexNormalOut); + vec3 viewDir = normalize(cameraPos - vertexPosOut); + float angle = dot(viewDir, normalizedVertexNormal); + + vec3 red = vec3(1, 0, 0); + outColor = vec4(mix(red, color, angle), 1.0); +} diff --git a/cw 7/shaders/shader_5_sun.vert b/cw 7/shaders/shader_5_sun.vert new file mode 100644 index 0000000..94ba36b --- /dev/null +++ b/cw 7/shaders/shader_5_sun.vert @@ -0,0 +1,19 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; +layout(location = 1) in vec3 vertexNormal; +layout(location = 2) in vec2 vertexTexCoord; + +uniform mat4 transformation; +uniform mat4 modelMat; + +out vec3 vertexNormalOut; +out vec3 vertexPosOut; + +void main() +{ + gl_Position = transformation * vec4(vertexPosition, 1.0); + vec4 worldNormal = modelMat * vec4(vertexNormal, 0.0); + vertexNormalOut = worldNormal.xyz; + vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz; +} diff --git a/cw 7/shaders/shader_earth.frag b/cw 7/shaders/shader_earth.frag new file mode 100644 index 0000000..d3d96fc --- /dev/null +++ b/cw 7/shaders/shader_earth.frag @@ -0,0 +1,74 @@ +#version 430 core + +uniform sampler2D colorTexture; +uniform sampler2D clouds; + +uniform vec3 sunPos; +uniform vec3 sunColor; +uniform float sunLightExp; + +uniform vec3 cameraPos; +uniform float time; + +uniform vec3 reflectorPos; +uniform vec3 reflectorDir; +uniform vec3 reflectorColor; +uniform float reflectorAngle; +uniform float reflectorLightExp; + +vec3 normalizedVertexNormal; + +in vec3 vertexNormalOut; +in vec3 vertexPosOut; +in vec2 vertexTexCoordOut; + +out vec4 outColor; + +vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) { + vec3 lightDir = normalize(vertexPosOut - lightPos); + float lightDistance = length(vertexPosOut - lightPos); + vec3 newLightColor = lightColor / pow(lightDistance, 2); + + float intensity = dot(normalizedVertexNormal, -lightDir); + intensity = max(intensity, 0.0); + + vec3 viewDir = normalize(cameraPos - vertexPosOut); + vec3 reflectDir = reflect(lightDir, normalizedVertexNormal); + + float glossPow = 8; + float specular = pow(max(dot(viewDir, reflectDir), 0.0), glossPow); + + float diffuse = intensity; + vec3 resultColor = newLightColor * (fragColor * diffuse + specular ); + return vec4(1 - exp(-resultColor * lightExp), 1.0); +} + +vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, vec3 lightDir, + float innerCutOff, float outerCutOff, float lightExp) { + vec3 lightToFragDir = normalize(vertexPosOut - lightPos); + float angleCos = dot(lightToFragDir, lightDir); + float epsilon = cos(innerCutOff) - cos(outerCutOff); + vec4 res = vec4(0, 0, 0, 1); + if (angleCos > cos(outerCutOff)) { + float intensity = clamp((angleCos - cos(outerCutOff)) / epsilon, 0.0, 1.0); + res = calcPointLight(fragColor, lightPos, lightColor, reflectorLightExp * intensity); + } + return res; +} + + +void main() +{ + vec3 textureColor = texture2D(colorTexture, vertexTexCoordOut).rgb; + vec3 cloudColor = texture2D(clouds, vertexTexCoordOut).rgb; + + textureColor = mix(vec3(1), textureColor, cloudColor.r); + + normalizedVertexNormal = normalize(vertexNormalOut); + + outColor = calcPointLight(textureColor, sunPos, sunColor, sunLightExp); + + outColor += calcSpotLight(textureColor, reflectorPos, reflectorColor, reflectorDir, + reflectorAngle, reflectorAngle + radians(10), reflectorLightExp); + +} \ No newline at end of file diff --git a/cw 7/shaders/shader_earth.vert b/cw 7/shaders/shader_earth.vert new file mode 100644 index 0000000..954b887 --- /dev/null +++ b/cw 7/shaders/shader_earth.vert @@ -0,0 +1,22 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; +layout(location = 1) in vec3 vertexNormal; +layout(location = 2) in vec2 vertexTexCoord; + +uniform mat4 transformation; +uniform mat4 modelMat; + +out vec3 vertexNormalOut; +out vec3 vertexPosOut; +out vec2 vertexTexCoordOut; + +void main() +{ + gl_Position = transformation * vec4(vertexPosition, 1.0); + vec4 worldNormal = modelMat * vec4(vertexNormal, 0.0); + vertexNormalOut = worldNormal.xyz; + vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz; + vertexTexCoordOut = vertexTexCoord; + vertexTexCoordOut.y = 1 - vertexTexCoord.y;// corrects inversion (bottom at top) of the earth +} \ No newline at end of file diff --git a/cw 7/shaders/shader_proc_tex.frag b/cw 7/shaders/shader_proc_tex.frag new file mode 100644 index 0000000..09634a6 --- /dev/null +++ b/cw 7/shaders/shader_proc_tex.frag @@ -0,0 +1,86 @@ +#version 430 core + +uniform sampler2D colorTexture; +uniform sampler2D rust; +uniform sampler2D scratches; + +uniform vec3 sunPos; +uniform vec3 sunColor; +uniform float sunLightExp; + +uniform vec3 cameraPos; +uniform float time; + +uniform vec3 reflectorPos; +uniform vec3 reflectorDir; +uniform vec3 reflectorColor; +uniform float reflectorAngle; +uniform float reflectorLightExp; + +vec3 normalizedVertexNormal; + +in vec3 vertexNormalOut; +in vec3 vertexPosOut; +in vec2 vertexTexCoordOut; +in vec3 vertexLocPos; + +out vec4 outColor; + +vec4 calcPointLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, float lightExp) { + vec3 lightDir = normalize(vertexPosOut - lightPos); + float lightDistance = length(vertexPosOut - lightPos); + vec3 newLightColor = lightColor / pow(lightDistance, 2); + + float intensity = dot(normalizedVertexNormal, -lightDir); + intensity = max(intensity, 0.0); + + vec3 viewDir = normalize(cameraPos - vertexPosOut); + vec3 reflectDir = reflect(lightDir, normalizedVertexNormal); + + float glossPow = 8; + float specular = pow(max(dot(viewDir, reflectDir), 0.0), glossPow); + + float diffuse = intensity; + vec3 resultColor = newLightColor * (fragColor * diffuse + specular ); + return vec4(1 - exp(-resultColor * lightExp), 1.0); +} + +vec4 calcSpotLight(vec3 fragColor, vec3 lightPos, vec3 lightColor, vec3 lightDir, float lightExp) { + vec3 reflectorLightDir = normalize(vertexPosOut - reflectorPos); + float angleCos = dot(reflectorLightDir, reflectorDir); + float reflectorOutAngle = reflectorAngle + radians(10); + float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle); + vec4 res = vec4(0, 0, 0, 1); + if (angleCos > cos(reflectorOutAngle)) { + float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0); + res = calcPointLight(fragColor, reflectorPos, reflectorColor, reflectorLightExp * intensity); + } + return res; +} + + +void main() +{ + vec3 shipColor = texture2D(colorTexture, vertexTexCoordOut).rgb; + vec3 rustColor = texture2D(rust, vertexTexCoordOut).rgb; + vec3 scratchesColor = texture2D(scratches, vertexTexCoordOut).rgb; + vec3 textureColor = mix(rustColor, shipColor, scratchesColor .r); + + if (sin(vertexLocPos.y * vertexLocPos.x * vertexLocPos.z) > 0) { + textureColor = vec3(1, 0, 0); + } + + normalizedVertexNormal = normalize(vertexNormalOut); + + outColor = calcPointLight(textureColor, sunPos, sunColor, sunLightExp); + + vec3 reflectorLightDir = normalize(vertexPosOut - reflectorPos); + float angleCos = dot(reflectorLightDir, reflectorDir); + float reflectorOutAngle = reflectorAngle + radians(10); + float epsilon = cos(reflectorAngle) - cos(reflectorOutAngle); + if (angleCos > cos(reflectorOutAngle)) { + float intensity = clamp((angleCos - cos(reflectorOutAngle)) / epsilon, 0.0, 1.0); + outColor += calcSpotLight(textureColor, reflectorPos, reflectorColor, reflectorLightDir, reflectorLightExp * intensity); + } +} + diff --git a/cw 7/shaders/shader_proc_tex.vert b/cw 7/shaders/shader_proc_tex.vert new file mode 100644 index 0000000..f42775b --- /dev/null +++ b/cw 7/shaders/shader_proc_tex.vert @@ -0,0 +1,23 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; +layout(location = 1) in vec3 vertexNormal; +layout(location = 2) in vec2 vertexTexCoord; + +uniform mat4 transformation; +uniform mat4 modelMat; + +out vec3 vertexNormalOut; +out vec3 vertexPosOut; +out vec2 vertexTexCoordOut; +out vec3 vertexLocPos; + +void main() +{ + gl_Position = transformation * vec4(vertexPosition, 1.0); + vec4 worldNormal = modelMat * vec4(vertexNormal, 0.0); + vertexNormalOut = worldNormal.xyz; + vertexPosOut = (modelMat * vec4(vertexPosition, 1.0)).xyz; + vertexTexCoordOut = vertexTexCoord; + vertexLocPos = vertexPosition; +} diff --git a/cw 7/shaders/shader_skybox.frag b/cw 7/shaders/shader_skybox.frag new file mode 100644 index 0000000..44914bc --- /dev/null +++ b/cw 7/shaders/shader_skybox.frag @@ -0,0 +1,13 @@ +#version 430 core + +uniform samplerCube skybox; + +in vec3 texCoord; + +out vec4 out_color; + +void main() +{ + out_color = texture(skybox, texCoord); + //out_color = vec4(1, 0, 0, 1); +} \ No newline at end of file diff --git a/cw 7/shaders/shader_skybox.vert b/cw 7/shaders/shader_skybox.vert new file mode 100644 index 0000000..9fee19a --- /dev/null +++ b/cw 7/shaders/shader_skybox.vert @@ -0,0 +1,13 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; + +uniform mat4 transformation; + +out vec3 texCoord; + +void main() +{ + texCoord = vertexPosition; + gl_Position = transformation * vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/cw 7/src/ex_7_1.hpp b/cw 7/src/ex_7_1.hpp new file mode 100644 index 0000000..49d3c3c --- /dev/null +++ b/cw 7/src/ex_7_1.hpp @@ -0,0 +1,432 @@ +#include "glew.h" +#include +#include "glm.hpp" +#include "ext.hpp" +#include +#include +#include "Shader_Loader.h" +#include "Render_Utils.h" +#include "Texture.h" +#include "Box.cpp" +#include +#include +#include +#include +#include "SOIL/SOIL.h" + +namespace texture { + GLuint earth; + GLuint clouds; + GLuint moon; + GLuint ship; + GLuint scratches; + GLuint rust; + + GLuint grid; + + GLuint earthNormal; + GLuint asteroidNormal; + GLuint shipNormal; + + GLuint cubemap; +} + + +GLuint program; +GLuint programSun; +GLuint programTex; +GLuint programEarth; +GLuint programProcTex; +GLuint programSkyBox; +Core::Shader_Loader shaderLoader; + +Core::RenderContext shipContext; +Core::RenderContext sphereContext; +Core::RenderContext cubeContext; + +glm::vec3 cameraPos = glm::vec3(-4.f, 0, 0); +glm::vec3 cameraDir = glm::vec3(1.f, 0.f, 0.f); +glm::vec3 lightDir = glm::normalize(glm::vec3(1.f, 1.f, 1.f)); + +glm::vec3 sunLightColor = glm::vec3(1.f, 1.f, 1.f); +float sunLightExp = 100; + +glm::vec3 reflectorColor = glm::vec3(0.3f, 0.f, 0.f); +float reflectorAngle = glm::radians(25.f); +float reflectorLightExp = 5; + +glm::vec3 spaceshipPos = glm::vec3(-4.f, 0, 0); +glm::vec3 spaceshipDir = glm::vec3(1.f, 0.f, 0.f); +GLuint VAO, VBO; + +float aspectRatio = 1.f; + +float lastTime = -1.f; +float deltaTime = 0.f; + +void updateDeltaTime(float time) { + if (lastTime < 0) { + lastTime = time; + return; + } + + deltaTime = time - lastTime; + if (deltaTime > 0.1) deltaTime = 0.1; + lastTime = time; +} + +glm::mat4 createCameraMatrix() +{ + glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir, glm::vec3(0.f, 1.f, 0.f))); + glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide, cameraDir)); + glm::mat4 cameraRotrationMatrix = glm::mat4({ + cameraSide.x,cameraSide.y,cameraSide.z,0, + cameraUp.x,cameraUp.y,cameraUp.z ,0, + -cameraDir.x,-cameraDir.y,-cameraDir.z,0, + 0.,0.,0.,1., + }); + cameraRotrationMatrix = glm::transpose(cameraRotrationMatrix); + glm::mat4 cameraMatrix = cameraRotrationMatrix * glm::translate(-cameraPos); + + return cameraMatrix; +} + +glm::mat4 createPerspectiveMatrix() +{ + + glm::mat4 perspectiveMatrix; + float n = 0.05; + float f = 20.; + float a1 = glm::min(aspectRatio, 1.f); + float a2 = glm::min(1 / aspectRatio, 1.f); + perspectiveMatrix = glm::mat4({ + a2,0.,0.,0., + 0.,a1,0.,0., + 0.,0.,(f + n) / (n - f),2 * f * n / (n - f), + 0.,0.,-1.,0., + }); + + + perspectiveMatrix = glm::transpose(perspectiveMatrix); + + return perspectiveMatrix; +} + +void drawObjectColor(GLuint program, Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) { + glUseProgram(program); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); + glm::mat4 transformation = viewProjectionMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); + glUniformMatrix4fv(glGetUniformLocation(program, "modelMat"), 1, GL_FALSE, (float*)&modelMatrix); + glUniform3f(glGetUniformLocation(program, "color"), color.x, color.y, color.z); + //sun + //glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.z); + glUniform3f(glGetUniformLocation(program, "sunPos"), 0.f, 0.f, 0.f); + glUniform3f(glGetUniformLocation(program, "sunColor"), sunLightColor.x, sunLightColor.y, sunLightColor.z); + glUniform1f(glGetUniformLocation(program, "sunLightExp"), sunLightExp); + //spaceship reflector + glm::vec3 reflectorPos = spaceshipPos + 0.037f * spaceshipDir; + glUniform3f(glGetUniformLocation(program, "reflectorPos"), reflectorPos.x, reflectorPos.y, reflectorPos.z); + glUniform3f(glGetUniformLocation(program, "reflectorDir"), spaceshipDir.x, spaceshipDir.y, spaceshipDir.z); + glUniform1f(glGetUniformLocation(program, "reflectorAngle"), reflectorAngle); + glUniform3f(glGetUniformLocation(program, "reflectorColor"), + reflectorColor.x, reflectorColor.y, reflectorColor.z); + glUniform1f(glGetUniformLocation(program, "reflectorLightExp"), reflectorLightExp); + + glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); + //TEST + glUniform1f(glGetUniformLocation(program, "time"), lastTime); + + Core::DrawContext(context); + glUseProgram(0); + +} + +void drawObjectProc(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec3 color) { + program = programProcTex; + + glUseProgram(program); + Core::SetActiveTexture(texture::ship, "colorTexture", program, 0); + Core::SetActiveTexture(texture::rust, "rust", program, 1); + Core::SetActiveTexture(texture::scratches, "scratches", program, 2); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); + glm::mat4 transformation = viewProjectionMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); + glUniformMatrix4fv(glGetUniformLocation(program, "modelMat"), 1, GL_FALSE, (float*)&modelMatrix); + //sun + glUniform3f(glGetUniformLocation(program, "sunPos"), 0.f, 0.f, 0.f); + glUniform3f(glGetUniformLocation(program, "sunColor"), sunLightColor.x, sunLightColor.y, sunLightColor.z); + glUniform1f(glGetUniformLocation(program, "sunLightExp"), sunLightExp); + //spaceship reflector + glm::vec3 reflectorPos = spaceshipPos + 0.037f * spaceshipDir; + glUniform3f(glGetUniformLocation(program, "reflectorPos"), reflectorPos.x, reflectorPos.y, reflectorPos.z); + glUniform3f(glGetUniformLocation(program, "reflectorDir"), spaceshipDir.x, spaceshipDir.y, spaceshipDir.z); + glUniform1f(glGetUniformLocation(program, "reflectorAngle"), reflectorAngle); + glUniform3f(glGetUniformLocation(program, "reflectorColor"), + reflectorColor.x, reflectorColor.y, reflectorColor.z); + glUniform1f(glGetUniformLocation(program, "reflectorLightExp"), reflectorLightExp); + + glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); + + Core::DrawContext(context); + glUseProgram(0); + +} + +void drawObjectTexture(GLuint program, Core::RenderContext& context, glm::mat4 modelMatrix, GLuint textureId) { + glUseProgram(program); + Core::SetActiveTexture(textureId, "colorTexture", program, 0); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); + glm::mat4 transformation = viewProjectionMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); + glUniformMatrix4fv(glGetUniformLocation(program, "modelMat"), 1, GL_FALSE, (float*)&modelMatrix); + //sun + glUniform3f(glGetUniformLocation(program, "sunPos"), 0.f, 0.f, 0.f); + glUniform3f(glGetUniformLocation(program, "sunColor"), sunLightColor.x, sunLightColor.y, sunLightColor.z); + glUniform1f(glGetUniformLocation(program, "sunLightExp"), sunLightExp); + //spaceship reflector + glm::vec3 reflectorPos = spaceshipPos + 0.037f * spaceshipDir; + glUniform3f(glGetUniformLocation(program, "reflectorPos"), reflectorPos.x, reflectorPos.y, reflectorPos.z); + glUniform3f(glGetUniformLocation(program, "reflectorDir"), spaceshipDir.x, spaceshipDir.y, spaceshipDir.z); + glUniform1f(glGetUniformLocation(program, "reflectorAngle"), reflectorAngle); + glUniform3f(glGetUniformLocation(program, "reflectorColor"), + reflectorColor.x, reflectorColor.y, reflectorColor.z); + glUniform1f(glGetUniformLocation(program, "reflectorLightExp"), reflectorLightExp); + + glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); + + Core::DrawContext(context); + glUseProgram(0); + +} + +void drawEarth(Core::RenderContext& context, glm::mat4 modelMatrix) { + GLuint program = programEarth; + glUseProgram(program); + Core::SetActiveTexture(texture::earth, "colorTexture", program, 0); + Core::SetActiveTexture(texture::clouds, "clouds", program, 1); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); + glm::mat4 transformation = viewProjectionMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); + glUniformMatrix4fv(glGetUniformLocation(program, "modelMat"), 1, GL_FALSE, (float*)&modelMatrix); + //sun + glUniform3f(glGetUniformLocation(program, "sunPos"), 0.f, 0.f, 0.f); + glUniform3f(glGetUniformLocation(program, "sunColor"), sunLightColor.x, sunLightColor.y, sunLightColor.z); + glUniform1f(glGetUniformLocation(program, "sunLightExp"), sunLightExp); + //spaceship reflector + glm::vec3 reflectorPos = spaceshipPos + 0.037f * spaceshipDir; + glUniform3f(glGetUniformLocation(program, "reflectorPos"), reflectorPos.x, reflectorPos.y, reflectorPos.z); + glUniform3f(glGetUniformLocation(program, "reflectorDir"), spaceshipDir.x, spaceshipDir.y, spaceshipDir.z); + glUniform1f(glGetUniformLocation(program, "reflectorAngle"), reflectorAngle); + glUniform3f(glGetUniformLocation(program, "reflectorColor"), + reflectorColor.x, reflectorColor.y, reflectorColor.z); + glUniform1f(glGetUniformLocation(program, "reflectorLightExp"), reflectorLightExp); + + glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); + + Core::DrawContext(context); + glUseProgram(0); + +} + +void drawSkybox() { + GLuint program = programSkyBox; + + glUseProgram(program); + + glm::mat4 modelMatrix = glm::translate(cameraPos); + glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); + glm::mat4 transformation = viewProjectionMatrix * modelMatrix; + glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); + glBindTexture(GL_TEXTURE_CUBE_MAP, texture::cubemap); + Core::DrawContext(cubeContext); + + glUseProgram(0); +} + +void renderScene(GLFWwindow* window) +{ + glClearColor(0.0f, 0.3f, 0.3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glm::mat4 transformation; + float time = glfwGetTime(); + updateDeltaTime(time); + + glDisable(GL_DEPTH_TEST); + drawSkybox(); + glEnable(GL_DEPTH_TEST); + + time = 2; + + //sun + drawObjectColor(programSun, sphereContext, glm::mat4(), glm::vec3(1.0, 1.0, 0.3)); + + drawEarth(sphereContext, + glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::scale(glm::vec3(0.3f))); + + drawObjectTexture(programTex, sphereContext, + glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f)), + texture::grid); + + glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f))); + glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir)); + glm::mat4 spaceshipCameraRotrationMatrix = glm::mat4({ + spaceshipSide.x,spaceshipSide.y,spaceshipSide.z,0, + spaceshipUp.x,spaceshipUp.y,spaceshipUp.z ,0, + -spaceshipDir.x,-spaceshipDir.y,-spaceshipDir.z,0, + 0.,0.,0.,1., + }); + + + drawObjectProc(shipContext, + glm::translate(spaceshipPos) * spaceshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi()) * glm::scale(glm::vec3(0.2f)), + glm::vec3(0., 0., 1.) + ); + + glfwSwapBuffers(window); +} + +void framebuffer_size_callback(GLFWwindow* window, int width, int height) +{ + aspectRatio = width / float(height); + glViewport(0, 0, width, height); +} + +void loadModelToContext(std::string path, Core::RenderContext& context) +{ + Assimp::Importer import; + const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace); + + if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) + { + std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl; + return; + } + context.initFromAssimpMesh(scene->mMeshes[0]); +} + +void init_cubemap() { + glGenTextures(1, &texture::cubemap); + glBindTexture(GL_TEXTURE_CUBE_MAP, texture::cubemap); + + int w, h; + unsigned char* data; + std::vector cubeSideTestureFiles = { + "./textures/skybox/space_rt.png", + "./textures/skybox/space_lt.png", + "./textures/skybox/space_up.png", + "./textures/skybox/space_dn.png", + "./textures/skybox/space_bk.png", + "./textures/skybox/space_ft.png", + }; + for (unsigned int i = 0; i < 6; i++) + { + unsigned char* image = SOIL_load_image(cubeSideTestureFiles[i], &w, &h, 0, SOIL_LOAD_RGBA); + glTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, + 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image + ); + } + + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); +} + +void init(GLFWwindow* window) +{ + glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); + + glEnable(GL_DEPTH_TEST); + program = shaderLoader.CreateProgram("shaders/shader_5_1.vert", "shaders/shader_5_1.frag"); + programSun = shaderLoader.CreateProgram("shaders/shader_5_sun.vert", "shaders/shader_5_sun.frag"); + programTex = shaderLoader.CreateProgram("shaders/shader_5_1_tex.vert", "shaders/shader_5_1_tex.frag"); + programEarth = shaderLoader.CreateProgram("shaders/shader_earth.vert", "shaders/shader_earth.frag"); + programProcTex = shaderLoader.CreateProgram("shaders/shader_proc_tex.vert", "shaders/shader_proc_tex.frag"); + programSkyBox = shaderLoader.CreateProgram("shaders/shader_skybox.vert", "shaders/shader_skybox.frag"); + + loadModelToContext("./models/sphere.obj", sphereContext); + loadModelToContext("./models/spaceship.obj", shipContext); + loadModelToContext("./models/cube.obj", cubeContext); + + texture::earth = Core::LoadTexture("./textures/earth.png"); + texture::clouds = Core::LoadTexture("./textures/clouds.jpg"); + //moon.png doesn't load correctly + texture::moon = Core::LoadTexture("./textures/moon.png"); + texture::ship = Core::LoadTexture("./textures/spaceship.jpg"); + texture::scratches = Core::LoadTexture("./textures/scratches.jpg"); + texture::rust = Core::LoadTexture("./textures/rust.jpg"); + + texture::grid = Core::LoadTexture("./textures/grid_color.png"); + + texture::earthNormal = Core::LoadTexture("./textures/earth_normalmap.png"); + texture::asteroidNormal = Core::LoadTexture("./textures/rust_normal.jpg"); + texture::shipNormal = Core::LoadTexture("./textures/spaceship_normalmap.jpg"); + + init_cubemap(); +} + +void shutdown(GLFWwindow* window) +{ + shaderLoader.DeleteProgram(program); +} + +//obsluga wejscia +void processInput(GLFWwindow* window) +{ + glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f))); + glm::vec3 spaceshipUp = glm::vec3(0.f, 1.f, 0.f); + float angleSpeed = 0.05f * deltaTime * 60; + float moveSpeed = 0.05f * deltaTime * 60; + if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) { + angleSpeed *= 3; + moveSpeed *= 3; + } + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { + glfwSetWindowShouldClose(window, true); + } + if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) + spaceshipPos += spaceshipDir * moveSpeed; + if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) + spaceshipPos -= spaceshipDir * moveSpeed; + if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) + spaceshipPos += spaceshipSide * moveSpeed; + if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) + spaceshipPos -= spaceshipSide * moveSpeed; + if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) + spaceshipPos += spaceshipUp * moveSpeed; + if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) + spaceshipPos -= spaceshipUp * moveSpeed; + if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) + spaceshipDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(spaceshipDir, 0)); + if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) + spaceshipDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(spaceshipDir, 0)); + + cameraPos = spaceshipPos - 0.3f * spaceshipDir + glm::vec3(0, 1, 0) * 0.1f; + cameraDir = spaceshipDir; + + //cameraDir = glm::normalize(-cameraPos); + if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) + sunLightExp = glm::max(0.f, sunLightExp - 0.1f); + if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) + sunLightExp += 0.1f; + + if (glfwGetKey(window, GLFW_KEY_3) == GLFW_PRESS) + reflectorLightExp = glm::max(0.f, reflectorLightExp - 0.05f); + if (glfwGetKey(window, GLFW_KEY_4) == GLFW_PRESS) + reflectorLightExp += 0.05f; +} + +// funkcja jest glowna petla +void renderLoop(GLFWwindow* window) { + while (!glfwWindowShouldClose(window)) + { + processInput(window); + + renderScene(window); + glfwPollEvents(); + } +} +//} \ No newline at end of file