diff --git a/.gitignore b/.gitignore index 6a05f34..fdd7367 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ build/* libs/* include/* #orgfile.org -assets/* \ No newline at end of file +#assets/* \ No newline at end of file diff --git a/assets/models/default.pamesh b/assets/models/default.pamesh new file mode 100644 index 0000000..02803e3 Binary files /dev/null and b/assets/models/default.pamesh differ diff --git a/assets/shaders/common.glsl b/assets/shaders/common.glsl new file mode 100644 index 0000000..6e2de33 --- /dev/null +++ b/assets/shaders/common.glsl @@ -0,0 +1,5 @@ + +// Common Uniforms +// uniform vec4 ambientLight; +// uniform vec3 eyePos; +uniform vec4 diffuse_color; \ No newline at end of file diff --git a/assets/shaders/commonFrag.glsl b/assets/shaders/commonFrag.glsl new file mode 100644 index 0000000..7997fc3 --- /dev/null +++ b/assets/shaders/commonFrag.glsl @@ -0,0 +1,10 @@ + +// Common Inputs +in vec2 uv; +in vec3 normal; +in vec3 vertex; +//in vec3 vertCamSpace; +//in vec4 vertLightSpace; + +// Fragment Shader Output +out vec4 frag_color; diff --git a/assets/shaders/commonVert.glsl b/assets/shaders/commonVert.glsl new file mode 100644 index 0000000..e8894af --- /dev/null +++ b/assets/shaders/commonVert.glsl @@ -0,0 +1,32 @@ + +// Common inputs and outputs +in vec3 vPosition; +in vec3 vNormal; +in vec2 vUV; + +out vec2 uv; +out vec3 normal; +out vec3 vertex; +out vec3 vertCamSpace; +out vec4 vertLightSpace; + +// Common uniforms +uniform mat4 modelMat; +uniform mat4 viewMat; +uniform mat4 mvp; +uniform mat4 lightVPMat; + +vec4 transformPosition(vec3 position) +{ + return mvp * vec4(vPosition, 1.0); +} + +void setOutputs() +{ + uv = vUV; + //Normal and vertex sent to the fragment shader should be in the same space! + normal = vec4(modelMat * vec4(vNormal, 0.0)).xyz; + vertex = vec4(modelMat * vec4(vPosition, 1.0)).xyz; + vertCamSpace = vec4(viewMat * vec4(vPosition, 1.0)).xyz; + vertLightSpace = vec4((lightVPMat * modelMat) * vec4(vPosition, 1.0)); +} diff --git a/assets/shaders/fbo.frag b/assets/shaders/fbo.frag new file mode 100644 index 0000000..504eec8 --- /dev/null +++ b/assets/shaders/fbo.frag @@ -0,0 +1,13 @@ +//include version.glsl + +in vec2 uv; + +out vec4 frag_color; + +uniform sampler2D sampler; + +void main() +{ + frag_color = texture2D(sampler, uv); + //frag_color = vec4(1, 0, 0, 1); +} diff --git a/assets/shaders/fbo.vert b/assets/shaders/fbo.vert new file mode 100644 index 0000000..97202f6 --- /dev/null +++ b/assets/shaders/fbo.vert @@ -0,0 +1,15 @@ +//include version.glsl + +in vec2 vPosition; +in vec2 vUV; + +out vec2 uv; + +//uniform mat4 mvp; + +void main() +{ + uv = vUV; + //gl_Position = mvp * vec4(vPosition, 0, 1.0); + gl_Position = vec4(vPosition, 0, 1.0); +} diff --git a/assets/shaders/fog.glsl b/assets/shaders/fog.glsl new file mode 100644 index 0000000..f91ef59 --- /dev/null +++ b/assets/shaders/fog.glsl @@ -0,0 +1,41 @@ +struct Fog +{ + int fogMode; + float density; + float start; + float max; + vec4 color; +}; + +uniform Fog fog; + +const int FOG_NONE = 0; +const int FOG_LINEAR = 1; +const int FOG_EXPONENTIAL = 2; +const int FOG_EXPONENTIAL_SQRD = 3; + +vec4 applyFog(vec4 color) +{ + vec4 finalColor = color; + if(fog.fogMode != FOG_NONE) + { + float fogFactor; + float distFromEye = abs(length(vertex - eyePos)); + if(fog.fogMode == FOG_LINEAR) + { + fogFactor = (fog.max - distFromEye) / (fog.max - fog.start); + } + else if(fog.fogMode == FOG_EXPONENTIAL) + { + fogFactor = exp(fog.density * -distFromEye); + } + else if(fog.fogMode == FOG_EXPONENTIAL_SQRD) + { + fogFactor = exp(-pow(fog.density * distFromEye, 2)); + } + fogFactor = clamp(fogFactor, 0.0, 1.0); + finalColor = mix(fog.color, color, fogFactor); + } + return finalColor; +} + diff --git a/assets/shaders/phongCommon.glsl b/assets/shaders/phongCommon.glsl new file mode 100644 index 0000000..1ccaabe --- /dev/null +++ b/assets/shaders/phongCommon.glsl @@ -0,0 +1,230 @@ + +struct Light +{ + vec4 color; + vec3 direction; + vec3 position; + float intensity; + float outerAngle; + float innerAngle; + float falloff; + int radius; + int type; + int castShadow; + int pcfEnabled; + float depthBias; +}; + +struct Material +{ + float specular; + float diffuse; + float specularStrength; +}; + +#define EPSILON 0.00001 + +const int MAX_LIGHTS = 32; +const int LT_SPOT = 0; +const int LT_DIR = 1; +const int LT_POINT = 2; + +uniform Material material; +uniform int numLights; +uniform Light lightList[MAX_LIGHTS]; +uniform Light light; +uniform sampler2DShadow shadowMap0; +uniform sampler2DShadow shadowMap1; +uniform sampler2DShadow shadowMap2; +uniform sampler2DShadow shadowMap3; +uniform vec2 mapSize; +//uniform int selectedShadowMap; + +float calcShadowFactor(vec3 projCoords) +{ + float bias = 0.5; + vec2 uvCoords; + uvCoords.x = (projCoords.x * bias) + bias; + uvCoords.y = (projCoords.y * bias) + bias; + float z = (projCoords.z * bias) + bias; + float visibility = 1.0; + + //if uv outside shadowmap range then point out of shadow + if(uvCoords.x > 1.0 || uvCoords.x < 0.0 || uvCoords.y > 1.0 || uvCoords.y < 0.0) + { + return 1.0; + } + else + { + float dist = distance(eyePos, vertex); + int selectedShadowMap = 0; + if(dist <= 30) + selectedShadowMap = 0; + else if(dist > 30 && dist <= 80) + selectedShadowMap = 1; + else if(dist > 80 && dist <= 120) + selectedShadowMap = 2; + else + selectedShadowMap = 3; + + if(light.pcfEnabled == 0) + { + float depth = 0; + if(light.type == LT_DIR) + { + switch(selectedShadowMap) + { + case 0: depth = texture(shadowMap0, vec3(uvCoords, z + EPSILON)); break; + case 1: depth = texture(shadowMap1, vec3(uvCoords, z + EPSILON)); break; + case 2: depth = texture(shadowMap2, vec3(uvCoords, z + EPSILON)); break; + case 3: depth = texture(shadowMap3, vec3(uvCoords, z + EPSILON)); break; + } + } + else + { + depth = texture(shadowMap0, vec3(uvCoords, z + EPSILON)); + } + if((depth + light.depthBias) < z) + visibility = 0.5; + else + visibility = 1.0; + } + else + { + float xOffset = 1.0/mapSize.x; + float yOffset = 1.0/mapSize.y; + float Factor = 0.0; + + for (int y = -1 ; y <= 1 ; y++) + { + for (int x = -1 ; x <= 1 ; x++) + { + vec2 Offsets = vec2(x * xOffset, y * yOffset); + vec3 UVC = vec3(uvCoords + Offsets, z + EPSILON); + if(light.type == LT_DIR) + { + switch(selectedShadowMap) + { + case 0: Factor += texture(shadowMap0, UVC); break; + case 1: Factor += texture(shadowMap1, UVC); break; + case 2: Factor += texture(shadowMap2, UVC); break; + case 3: Factor += texture(shadowMap3, UVC); break; + } + } + else + { + Factor += texture(shadowMap0, UVC); + } + + } + } + + visibility = (0.5 + (Factor / 18.0)); + } + } + return visibility; +} + +vec4 calcDirLight(Light dirLight) +{ + vec4 diffuse = vec4(0.0); + vec4 specular = vec4(0.0); + vec3 normalizedNormal = normalize(normal); + float cosAngIncidence = dot(normalizedNormal, -dirLight.direction); + cosAngIncidence = clamp(cosAngIncidence, 0, 1); + float shadowFactor = 1.0; + + if(cosAngIncidence > 0) + { + diffuse = dirLight.color * material.diffuse * cosAngIncidence; + + vec3 vertexToEye = normalize(eyePos - vertex); + vec3 lightReflect = normalize(reflect(dirLight.direction, normalizedNormal)); + float specularFactor = max(0.0, dot(vertexToEye, lightReflect)); + specularFactor = pow(specularFactor, material.specularStrength); + specular = dirLight.color * material.specular * specularFactor; + if(light.castShadow == 1) + { + shadowFactor = calcShadowFactor(vertLightSpace.xyz); + } + } + // return dirLight.intensity * shadowFactor * (diffuse + specular); + return (dirLight.intensity * (diffuse + specular)) * shadowFactor; +} + +vec4 calcPointLight(Light pointLight) +{ + vec4 diffuse = vec4(0.0); + vec4 specular = vec4(0.0); + vec3 lightDirection = vertex - pointLight.position; + float distance = abs(length(lightDirection)); + + if(distance <= pointLight.radius) + { + lightDirection = normalize(lightDirection); + vec3 normalizedNormal = normalize(normal); + float cosAngIncidence = dot(normalizedNormal, -lightDirection); + cosAngIncidence = clamp(cosAngIncidence, 0, 1); + + if(cosAngIncidence > 0) + { + diffuse = pointLight.color * material.diffuse * cosAngIncidence; + vec3 vertexToEye = normalize(eyePos - vertex); + vec3 lightReflect = normalize(reflect(lightDirection, normalizedNormal)); + float specularFactor = max(0.0, dot(vertexToEye, lightReflect)); + specularFactor = pow(specularFactor, material.specularStrength); + specular = pointLight.color * material.specular * specularFactor; + } + float attenuation = pow(max(0.0, (1.0 - (distance / pointLight.radius))), pointLight.falloff + 1.0f); + return (((diffuse + specular) * attenuation) * pointLight.intensity); + } + else + { + return vec4(0.0); + } +} + +vec4 calcSpotLight(Light spotLight) +{ + vec4 color = vec4(0.0); + vec3 lightToSurface = vertex - spotLight.position; + float angle = dot(spotLight.direction, normalize(lightToSurface)); + if(acos(angle) < spotLight.outerAngle) + { + color = calcPointLight(spotLight); + color *= smoothstep(cos(spotLight.outerAngle), cos(spotLight.innerAngle), angle); + if(light.castShadow != 0) + { + float shadowFactor = calcShadowFactor(vertLightSpace.xyz / vertLightSpace.w); + color *= shadowFactor; + } + } + return color;// * shadowFactor; +} + +vec4 doForwardLightLoop() +{ + vec4 totalLightColor = vec4(0.0); + for(int i = 0; i < numLights; i++) + { + switch(lightList[i].type) + { + case LT_DIR: totalLightColor += calcDirLight(lightList[i]); break; + case LT_SPOT: totalLightColor += calcSpotLight(lightList[i]); break; + case LT_POINT: totalLightColor += calcPointLight(lightList[i]); break; + } + } + return totalLightColor; +} + +vec4 calculateLight() +{ + vec4 totalLightColor = vec4(0.0); + switch(light.type) + { + case LT_DIR: totalLightColor = calcDirLight(light); break; + case LT_SPOT: totalLightColor = calcSpotLight(light); break; + case LT_POINT: totalLightColor = calcPointLight(light); break; + } + return totalLightColor; +} diff --git a/assets/shaders/unshaded.frag b/assets/shaders/unshaded.frag new file mode 100644 index 0000000..d97ea77 --- /dev/null +++ b/assets/shaders/unshaded.frag @@ -0,0 +1,9 @@ +//include common.glsl commonFrag.glsl version.glsl + +uniform sampler2D diffuse_texture; + +void main() +{ + frag_color = diffuse_color * texture(diffuse_texture, uv); + //frag_color = vec4(1, 0, 0, 1); +} diff --git a/assets/shaders/unshaded.vert b/assets/shaders/unshaded.vert new file mode 100644 index 0000000..482a834 --- /dev/null +++ b/assets/shaders/unshaded.vert @@ -0,0 +1,7 @@ +//include commonVert.glsl version.glsl + +void main() +{ + gl_Position = transformPosition(vPosition); + setOutputs(); +} diff --git a/assets/shaders/version.glsl b/assets/shaders/version.glsl new file mode 100644 index 0000000..aa12d76 --- /dev/null +++ b/assets/shaders/version.glsl @@ -0,0 +1 @@ +#version 130 \ No newline at end of file diff --git a/assets/textures/default.tga b/assets/textures/default.tga new file mode 100644 index 0000000..7c7a8f7 Binary files /dev/null and b/assets/textures/default.tga differ diff --git a/build/linux/makefile b/build/linux/makefile index 82e288c..ffb5079 100644 --- a/build/linux/makefile +++ b/build/linux/makefile @@ -15,7 +15,5 @@ all: $(OBJS) $(CC) -c $< -o $@ clean: - @echo $(SRCS) - @echo $(OBJS) rm $(PROJECT_NAME) rm $(OBJS) diff --git a/src/game.c b/src/game.c index efdfdbd..47e97bc 100644 --- a/src/game.c +++ b/src/game.c @@ -1,9 +1,9 @@ #include #include #include -#include "GLFW/glfw3.h" -#include "game.h" +#include +#include "game.h" #include "window_system.h" #include "input.h" #include "renderer.h" @@ -37,7 +37,7 @@ void game_init(void) GLFWwindow* window = window_get_active(); /* Init systems */ input_init(window); - io_file_init("/mnt/Dev/Projects/Symmetry/assets/");/* TODO: Implement proper way of getting binary directory */ + io_file_init("/mnt/Dev/Projects/symmetry/assets/");/* TODO: Implement proper way of getting binary directory */ shader_init(); texture_init(); framebuffer_init();