aboutsummaryrefslogtreecommitdiff
path: root/07-july
diff options
context:
space:
mode:
Diffstat (limited to '07-july')
-rw-r--r--07-july/Makefile20
-rw-r--r--07-july/resources/shaders/passShader.frag13
-rw-r--r--07-july/resources/shaders/passShader.vert15
-rw-r--r--07-july/resources/shaders/shader.frag53
-rw-r--r--07-july/resources/shaders/shader.vert38
-rw-r--r--07-july/resources/shaders/terrainShader.frag73
-rw-r--r--07-july/resources/shaders/terrainShader.vert37
-rw-r--r--07-july/resources/stall.obj1696
-rw-r--r--07-july/resources/textures/blendmap.pngbin0 -> 477441 bytes
-rw-r--r--07-july/resources/textures/gato.pngbin0 -> 5393444 bytes
-rw-r--r--07-july/resources/textures/heightmap.pngbin0 -> 26460 bytes
-rw-r--r--07-july/resources/textures/soil1.pngbin0 -> 89463 bytes
-rw-r--r--07-july/resources/textures/soil2.pngbin0 -> 39820 bytes
-rw-r--r--07-july/resources/textures/soil3.pngbin0 -> 75458 bytes
-rw-r--r--07-july/resources/textures/soil4.pngbin0 -> 90142 bytes
-rw-r--r--07-july/resources/textures/spaceship.pngbin0 -> 360 bytes
-rw-r--r--07-july/resources/textures/stall.pngbin0 -> 50242 bytes
-rw-r--r--07-july/src/camera.c85
-rw-r--r--07-july/src/camera.h32
-rw-r--r--07-july/src/game.h42
-rw-r--r--07-july/src/graphics/shaders.c134
-rw-r--r--07-july/src/graphics/shaders.h46
-rw-r--r--07-july/src/graphics/video.c14
-rw-r--r--07-july/src/graphics/video.h7
-rw-r--r--07-july/src/graphics/window.c44
-rw-r--r--07-july/src/graphics/window.h20
-rw-r--r--07-july/src/gui/gui_renderer.c0
-rw-r--r--07-july/src/gui/gui_renderer.h9
-rw-r--r--07-july/src/gui/widget.c17
-rw-r--r--07-july/src/gui/widget.h13
-rw-r--r--07-july/src/input.c21
-rw-r--r--07-july/src/input.h11
-rw-r--r--07-july/src/light.c1
-rw-r--r--07-july/src/light.h13
-rw-r--r--07-july/src/main.c227
-rw-r--r--07-july/src/math/math_util.c10
-rw-r--r--07-july/src/math/math_util.h9
-rw-r--r--07-july/src/math/matrix4x4.c180
-rw-r--r--07-july/src/math/matrix4x4.h35
-rw-r--r--07-july/src/math/vector2f.c60
-rw-r--r--07-july/src/math/vector2f.h20
-rw-r--r--07-july/src/math/vector3f.c65
-rw-r--r--07-july/src/math/vector3f.h20
-rw-r--r--07-july/src/math/vector4f.c70
-rw-r--r--07-july/src/math/vector4f.h20
-rw-r--r--07-july/src/player.c62
-rw-r--r--07-july/src/player.h17
-rw-r--r--07-july/src/renderer/entity.c18
-rw-r--r--07-july/src/renderer/entity.h20
-rw-r--r--07-july/src/renderer/renderer.c98
-rw-r--r--07-july/src/renderer/renderer.h15
-rw-r--r--07-july/src/renderer/shape.c302
-rw-r--r--07-july/src/renderer/shape.h25
-rw-r--r--07-july/src/terrain.c163
-rw-r--r--07-july/src/terrain.h27
-rw-r--r--07-july/src/texture.c47
-rw-r--r--07-july/src/texture.h18
-rw-r--r--07-july/src/util/util.c49
-rw-r--r--07-july/src/util/util.h19
-rw-r--r--07-july/src/util/util_time.c52
-rw-r--r--07-july/src/util/util_time.h13
-rw-r--r--07-july/src/vertex.h21
62 files changed, 4136 insertions, 0 deletions
diff --git a/07-july/Makefile b/07-july/Makefile
new file mode 100644
index 0000000..4619f3c
--- /dev/null
+++ b/07-july/Makefile
@@ -0,0 +1,20 @@
+SRC=$(wildcard src/*.c)\
+ $(wildcard src/math/*.c)\
+ $(wildcard src/graphics/*.c)\
+ $(wildcard src/renderer/*.c)\
+ $(wildcard src/util/*.c)
+OBJ=$(SRC:%.c=%.o)
+TARGET=game
+LDFLAGS=-lSDL2 -lGL -lGLEW -lm -lSDL2_image
+
+%.o : %.c
+ $(CC) -c $< -o $@
+
+$(TARGET) : $(OBJ)
+ $(CC) $(OBJ) -o $(TARGET) $(LDFLAGS)
+
+all : $(TARGET)
+
+.PHONY : clean
+clean:
+ rm -rf $(TARGET) $(OBJ)
diff --git a/07-july/resources/shaders/passShader.frag b/07-july/resources/shaders/passShader.frag
new file mode 100644
index 0000000..4c8dec1
--- /dev/null
+++ b/07-july/resources/shaders/passShader.frag
@@ -0,0 +1,13 @@
+#version 420
+
+in vec4 Fragment_Color;
+in vec2 Fragment_Uv;
+
+out vec4 out_color;
+
+uniform sampler2D Texture;
+
+void main()
+{
+ out_color = Fragment_Color * texture(Texture, Fragment_Uv);
+}
diff --git a/07-july/resources/shaders/passShader.vert b/07-july/resources/shaders/passShader.vert
new file mode 100644
index 0000000..964d13e
--- /dev/null
+++ b/07-july/resources/shaders/passShader.vert
@@ -0,0 +1,15 @@
+#version 420
+
+in layout(location=0) vec2 Model_Position;
+
+uniform mat4 Matrix_totalTransform;
+
+out vec4 Fragment_Color;
+out vec2 Fragment_Uv;
+
+void main()
+{
+ Fragment_Color = vec4(1.0, 1.0, 1.0, 1.0);
+ Fragment_Uv = vec2( (Model_Position.x + 1.0)/2.0, 1.0 - (Model_Position.y + 1.0)/2.0 );
+ gl_Position = Matrix_totalTransform * vec4(Model_Position, 0.0, 1.0);
+}
diff --git a/07-july/resources/shaders/shader.frag b/07-july/resources/shaders/shader.frag
new file mode 100644
index 0000000..406d004
--- /dev/null
+++ b/07-july/resources/shaders/shader.frag
@@ -0,0 +1,53 @@
+#version 420
+
+in vec3 World_Normal;
+in vec2 Fragment_UV;
+in vec4 Fragment_Color;
+in vec3 toLightVector[4];
+in vec3 toEyeVector;
+
+out vec4 out_color;
+
+uniform vec4 lightColor[4];
+uniform vec3 attenuation[4];
+uniform sampler2D Texture;
+
+void main()
+{
+ vec4 totalDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
+ vec4 totalSpecular = vec4(0.0, 0.0, 0.0, 1.0);
+
+ for(int i = 0; i < 4; i++)
+ {
+ /*Light Attenuation*/
+ float dist = length(toLightVector[i]);
+ float attFactor = attenuation[i].x + (attenuation[i].y * dist) + (attenuation[i].z * dist * dist);
+ vec3 unitToLightVector = normalize(toLightVector[i]);
+
+ /*Diffuse lighting*/
+
+ /*La intensidad es el cos entre la normal y el vector hacia la luz*/
+ float brightness = dot(unitToLightVector, normalize(World_Normal));
+ /*No queremos luz negativa ni mayor a 1*/
+ brightness = max(brightness, 0.0);
+ totalDiffuse = totalDiffuse + (brightness * lightColor[i]) / attFactor;
+
+ /* Specular lighting */
+
+ /* Reflejamos el vector hacia la luz (su inverso) en la normal */
+ vec3 Vector_ReflectedLight = reflect(-unitToLightVector, World_Normal);
+
+ /* La luz especular es el cos del angulo entre el vector hacia el ojo y la luz reflectada en la normal */
+ float specularity = clamp( dot(Vector_ReflectedLight, toEyeVector), 0, 1 );
+ float reflectivity = 1;
+ /* Que tan grande es el specular highlight */
+ specularity = pow(specularity, 10);
+ totalSpecular = totalSpecular + clamp( reflectivity * specularity * lightColor[i], 0, 1) / attFactor;
+ }
+
+ /* Ambient Light */
+ totalDiffuse = max(totalDiffuse, 0.2);
+
+ /* Juntamos todo para el color final*/
+ out_color = totalDiffuse * texture(Texture, Fragment_UV) + totalSpecular;
+}
diff --git a/07-july/resources/shaders/shader.vert b/07-july/resources/shaders/shader.vert
new file mode 100644
index 0000000..b8f10e6
--- /dev/null
+++ b/07-july/resources/shaders/shader.vert
@@ -0,0 +1,38 @@
+#version 420
+
+in layout(location=0) vec3 Model_Position;
+in layout(location=1) vec4 in_color;
+in layout(location=2) vec2 Texture_UV;
+in layout(location=3) vec3 Model_Normal;
+
+uniform mat4 Matrix_totalTransform;
+uniform mat4 Matrix_modelToWorld;
+
+uniform vec3 lightPosition[4];
+uniform vec3 World_eyePosition;
+
+out vec2 Fragment_UV;
+out vec3 World_Normal;
+out vec4 Fragment_Color;
+out vec3 toLightVector[4];
+out vec3 toEyeVector;
+
+void main()
+{
+ vec3 World_Position = vec3(Matrix_modelToWorld * vec4(Model_Position, 1.0));
+
+ for(int i = 0; i < 4; i++)
+ {
+ /* vector que apunta hacia la luz*/
+ toLightVector[i] = lightPosition[i] - World_Position;
+ }
+ /* Vector hacia el ojo*/
+ toEyeVector = normalize(World_eyePosition - World_Position);
+
+ gl_Position = Matrix_totalTransform * vec4(Model_Position, 1.0);
+ /*We add a 0 on the vec4 so we can remove the translation from the matrix
+ (WE DONT WANT THE NORMAL TO BE TRANSLATED) */
+ World_Normal = vec3(Matrix_modelToWorld * vec4(Model_Normal, 0.0));
+ Fragment_UV = vec2(Texture_UV.x, 1 - Texture_UV.y); /*Invert y axis*/
+ Fragment_Color = in_color;
+}
diff --git a/07-july/resources/shaders/terrainShader.frag b/07-july/resources/shaders/terrainShader.frag
new file mode 100644
index 0000000..be9c773
--- /dev/null
+++ b/07-july/resources/shaders/terrainShader.frag
@@ -0,0 +1,73 @@
+#version 420
+
+in vec2 Fragment_UV;
+in vec3 World_Normal;
+in vec4 Fragment_Color;
+in vec3 toLightVector[4];
+in vec3 toEyeVector;
+
+out vec4 out_color;
+
+uniform vec4 lightColor[4];
+uniform vec3 attenuation[4];
+uniform vec3 World_eyePosition;
+
+uniform sampler2D Texture_Background;
+uniform sampler2D Texture_R;
+uniform sampler2D Texture_G;
+uniform sampler2D Texture_B;
+uniform sampler2D Texture_BlendMap;
+
+void main()
+{
+ vec4 totalDiffuse = vec4(0.0, 0.0, 0.0, 1.0);
+ vec4 totalSpecular = vec4(0.0, 0.0, 0.0, 1.0);
+
+ for(int i = 0; i < 4; i++)
+ {
+ /*Light Attenuation*/
+ float dist = length(toLightVector[i]);
+ float attFactor = attenuation[i].x + (attenuation[i].y * dist) + (attenuation[i].z * dist * dist);
+ vec3 unitToLightVector = normalize(toLightVector[i]);
+ /*Diffuse lighting*/
+
+ /*La intensidad es el cos entre la normal y el vector hacia la luz*/
+ float brightness = dot(unitToLightVector, normalize(World_Normal));
+ /*No queremos luz negativa ni mayor a 1*/
+ brightness = max(brightness, 0.0);
+ totalDiffuse = totalDiffuse + (brightness * lightColor[i]) / attFactor;
+
+ /* Specular lighting */
+
+ /* Reflejamos el vector hacia la luz (su inverso) en la normal */
+ vec3 Vector_ReflectedLight = reflect(-unitToLightVector, World_Normal);
+
+ /* La luz especular es el cos del angulo entre el vector hacia el ojo y la luz reflectada en la normal */
+ float specularity = clamp( dot(Vector_ReflectedLight, toEyeVector), 0, 1 );
+ float reflectivity = 1;
+ /* Que tan grande es el specular highlight */
+ specularity = pow(specularity, 10);
+ totalSpecular = totalSpecular + clamp( reflectivity * specularity * lightColor[i], 0, 1) / attFactor;
+ }
+
+ /* Ambient Light */
+ totalDiffuse = max(totalDiffuse, 0.2);
+
+ /*Terrain color*/
+ /*The color of the current fragment from the blendmap*/
+ vec4 blendMapColor = texture(Texture_BlendMap, Fragment_UV);
+ /*We want the background color when we have black in the blend map*/
+ float backTextureAmount = 1 - (blendMapColor.r + blendMapColor.g + blendMapColor.b);
+ /*So we dont lose image quality from the tiles textures (Fragment_UV make the terrain look less HD)*/
+ vec2 Tiled_UV = Fragment_UV * 50.0f;
+ /*We get the color of each map tile (soil1, soil2, etc)*/
+ vec4 backgroundTextureColor = texture(Texture_Background, Tiled_UV) * backTextureAmount;
+ vec4 rTextureColor = texture(Texture_R, Tiled_UV) * blendMapColor.r;
+ vec4 gTextureColor = texture(Texture_G, Tiled_UV) * blendMapColor.g;
+ vec4 bTextureColor = texture(Texture_B, Tiled_UV) * blendMapColor.b;
+ /*We mix them corresponding with the blendmap*/
+ vec4 totalColor = backgroundTextureColor + rTextureColor + gTextureColor + bTextureColor;
+
+ /*Our final color for the fragment*/
+ out_color = totalDiffuse * totalColor + totalSpecular;
+}
diff --git a/07-july/resources/shaders/terrainShader.vert b/07-july/resources/shaders/terrainShader.vert
new file mode 100644
index 0000000..6abdddb
--- /dev/null
+++ b/07-july/resources/shaders/terrainShader.vert
@@ -0,0 +1,37 @@
+#version 420
+
+in layout(location=0) vec3 Model_Position;
+in layout(location=1) vec4 in_color;
+in layout(location=2) vec2 Texture_UV;
+in layout(location=3) vec3 Model_Normal;
+
+uniform mat4 Matrix_totalTransform;
+uniform mat4 Matrix_modelToWorld;
+
+uniform vec3 lightPosition[4];
+uniform vec3 World_eyePosition;
+
+out vec2 Fragment_UV;
+out vec3 World_Normal;
+out vec4 Fragment_Color;
+out vec3 toLightVector[4];
+out vec3 toEyeVector;
+
+void main()
+{
+ vec3 World_Position = vec3(Matrix_modelToWorld * vec4(Model_Position, 1.0));
+
+ for(int i = 0; i < 4; i++)
+ {
+ /* vector que apunta hacia la luz*/
+ toLightVector[i] = lightPosition[i] - World_Position;
+ }
+ /* Vector hacia el ojo*/
+ toEyeVector = normalize(World_eyePosition - World_Position);
+
+ gl_Position = Matrix_totalTransform * vec4(Model_Position, 1.0);
+ /*We add a 0 on the vec4 so we can remove the translation from the matrix
+ (WE DONT WANT THE NORMAL TO BE TRANSLATED) */
+ World_Normal = vec3(Matrix_modelToWorld * vec4(Model_Normal, 0.0));
+ Fragment_UV = vec2(Texture_UV.x, 1 - Texture_UV.y); /*Invert y axis*/
+}
diff --git a/07-july/resources/stall.obj b/07-july/resources/stall.obj
new file mode 100644
index 0000000..210f90b
--- /dev/null
+++ b/07-july/resources/stall.obj
@@ -0,0 +1,1696 @@
+# Blender v2.67 (sub 0) OBJ File: 'stall.blend'
+# www.blender.org
+o Cube
+v 3.227124 -0.065127 -1.000000
+v 3.227124 -0.065127 1.000000
+v -3.227125 -0.065127 1.000000
+v -3.227123 -0.065127 -1.000000
+v 3.227126 1.934873 -0.999999
+v 3.227122 1.934873 1.000001
+v -3.227126 1.934873 1.000000
+v -3.227124 1.934873 -1.000000
+v 3.558682 1.924610 -1.102740
+v 3.558677 1.924610 1.511141
+v -3.558681 1.924610 1.511140
+v -3.558679 1.924610 -1.102740
+v 3.558682 2.083301 -1.102740
+v 3.558677 2.083301 1.511141
+v -3.558681 2.083301 1.511140
+v -3.558679 2.083301 -1.102740
+v 3.227124 -0.065127 -1.000000
+v 3.227126 1.934873 -0.999999
+v 3.227126 1.934873 -0.999999
+v 3.227126 1.934873 -0.999999
+v 3.227124 -0.065127 1.000000
+v 3.227122 1.934873 1.000001
+v 3.227122 1.934873 1.000001
+v 3.227122 1.934873 1.000001
+v -3.227125 -0.065127 1.000000
+v -3.227126 1.934873 1.000000
+v -3.227126 1.934873 1.000000
+v -3.227126 1.934873 1.000000
+v -3.227123 -0.065127 -1.000000
+v -3.227124 1.934873 -1.000000
+v -3.227124 1.934873 -1.000000
+v -3.227124 1.934873 -1.000000
+v 3.558682 1.924610 -1.102740
+v 3.558677 1.924610 1.511141
+v 3.558677 1.924610 1.511141
+v 3.558677 1.924610 1.511141
+v -3.558681 1.924610 1.511140
+v -3.558681 1.924610 1.511140
+v -3.558681 1.924610 1.511140
+v -3.558679 1.924610 -1.102740
+v -3.558679 1.924610 -1.102740
+v 3.558682 2.083301 -1.102740
+v 3.558677 2.083301 1.511141
+v 3.558677 2.083301 1.511141
+v -3.558679 2.083301 -1.102740
+v -3.558679 2.083301 -1.102740
+v -3.558681 2.083301 1.511140
+v -3.558681 2.083301 1.511140
+v -3.975889 5.109764 -0.703744
+v -3.975889 -0.001038 -0.703744
+v 4.035702 -0.001038 -0.703744
+v 4.035702 5.109764 -0.703744
+v 4.136954 -0.001038 -0.645286
+v 4.136954 5.109764 -0.645286
+v 4.136954 -0.001038 -0.528370
+v 4.136954 5.109764 -0.528370
+v 4.035702 -0.001038 -0.469912
+v 4.035702 5.109764 -0.469912
+v 3.934450 -0.001038 -0.528370
+v 3.934450 5.109764 -0.528370
+v 3.934450 -0.001038 -0.645286
+v 3.934450 5.109764 -0.645286
+v -3.874637 -0.001038 -0.645286
+v -3.874637 5.109764 -0.645286
+v -3.874637 -0.001038 -0.528370
+v -3.874637 5.109764 -0.528370
+v -3.975889 -0.001038 -0.469912
+v -3.975889 5.109764 -0.469912
+v -4.077142 -0.001038 -0.528370
+v -4.077142 5.109764 -0.528370
+v -4.077142 -0.001038 -0.645286
+v -4.077142 5.109764 -0.645286
+v -4.518063 -0.025686 3.868089
+v -4.518063 -0.025686 3.580229
+v 4.401308 -0.025686 3.580229
+v 4.401308 -0.025686 3.868089
+v -4.518063 3.617208 3.868089
+v -4.518063 3.617208 3.580229
+v 4.401308 3.617208 3.580229
+v 4.401308 3.617208 3.868089
+v -4.518063 4.016335 3.710218
+v -4.518063 3.792680 3.528995
+v 4.401308 3.792680 3.528995
+v 4.401308 4.016335 3.710218
+v -4.518063 4.490533 3.232638
+v -4.518063 4.260199 3.059984
+v 4.401308 4.260199 3.059984
+v 4.401308 4.490533 3.232638
+v -4.518063 5.251897 -0.749037
+v -4.518063 5.051156 -0.716959
+v 4.401308 5.051156 -0.716959
+v 4.401308 5.251897 -0.749037
+v -4.518063 4.733114 -1.423512
+v -4.518063 4.593092 -1.289192
+v 4.401308 4.593092 -1.289192
+v 4.401308 4.733114 -1.423512
+v -3.874637 5.109764 -0.528370
+v -3.874637 -0.001038 -0.528370
+v 3.934450 5.109764 -0.528370
+v 3.934450 -0.001038 -0.528370
+v 3.077599 2.080430 -1.292466
+v 3.486084 2.080430 0.000798
+v 1.220706 2.080430 0.716330
+v 0.812221 2.080430 -0.576934
+v 3.077599 2.174018 -1.292466
+v 3.486084 2.174018 0.000798
+v 1.220706 2.174018 0.716330
+v 0.812221 2.174018 -0.576934
+v 0.866186 2.174018 -0.491315
+v 1.241163 2.174018 0.695864
+v 1.353509 2.174018 0.660380
+v 0.978532 2.174018 -0.526800
+v 0.866186 2.080430 -0.491315
+v 1.241163 2.080430 0.695864
+v 1.353509 2.080430 0.660380
+v 0.978532 2.080430 -0.526800
+v 0.866186 2.545954 -0.491315
+v 1.241163 2.545954 0.695864
+v 1.353509 2.545954 0.660380
+v 0.978532 2.545954 -0.526800
+v 0.844122 2.174018 -0.561169
+v 0.956468 2.174018 -0.596654
+v 0.844122 2.080430 -0.561169
+v 0.956468 2.080430 -0.596654
+v 0.844122 2.545954 -0.561169
+v 0.956468 2.545954 -0.596654
+v 3.012783 2.174018 -1.169330
+v 3.012783 2.080430 -1.169330
+v 3.012783 2.545954 -1.169330
+v 2.990720 2.174018 -1.239183
+v 2.990720 2.080430 -1.239183
+v 2.990720 2.545954 -1.239183
+v 3.092841 2.174018 -1.194616
+v 3.092841 2.080430 -1.194616
+v 3.092841 2.545954 -1.194616
+v 3.070777 2.174018 -1.264470
+v 3.070777 2.080430 -1.264470
+v 3.070777 2.545954 -1.264470
+v 3.376227 2.174018 -0.018666
+v 3.376227 2.080430 -0.018666
+v 3.376227 2.545954 -0.018666
+v 3.456284 2.174018 -0.043953
+v 3.456284 2.080430 -0.043953
+v 3.456284 2.545954 -0.043953
+v 3.077599 2.174018 -1.292466
+v 3.077599 2.174018 -1.292466
+v 3.486084 2.174018 0.000798
+v 3.486084 2.174018 0.000798
+v 3.486084 2.080430 0.000798
+v 3.486084 2.080430 0.000798
+v 3.077599 2.080430 -1.292466
+v 3.077599 2.080430 -1.292466
+v 1.220706 2.174018 0.716330
+v 1.220706 2.174018 0.716330
+v 1.220706 2.080430 0.716330
+v 1.220706 2.080430 0.716330
+v 0.812221 2.174018 -0.576934
+v 0.812221 2.174018 -0.576934
+v 0.812221 2.080430 -0.576934
+v 0.812221 2.080430 -0.576934
+v 0.978532 2.080430 -0.526800
+v 0.978532 2.080430 -0.526800
+v 0.978532 2.080430 -0.526800
+v 0.978532 2.080430 -0.526800
+v 0.866186 2.080430 -0.491315
+v 0.866186 2.080430 -0.491315
+v 0.866186 2.080430 -0.491315
+v 0.844122 2.080430 -0.561169
+v 0.844122 2.080430 -0.561169
+v 1.241163 2.080430 0.695864
+v 1.241163 2.080430 0.695864
+v 0.866186 2.174018 -0.491315
+v 0.866186 2.174018 -0.491315
+v 0.866186 2.174018 -0.491315
+v 1.241163 2.174018 0.695864
+v 1.241163 2.174018 0.695864
+v 1.241163 2.174018 0.695864
+v 1.353509 2.080430 0.660380
+v 1.353509 2.080430 0.660380
+v 1.353509 2.174018 0.660380
+v 1.353509 2.174018 0.660380
+v 1.353509 2.174018 0.660380
+v 0.978532 2.174018 -0.526800
+v 0.978532 2.174018 -0.526800
+v 0.978532 2.174018 -0.526800
+v 0.866186 2.545954 -0.491315
+v 0.866186 2.545954 -0.491315
+v 0.866186 2.545954 -0.491315
+v 0.978532 2.545954 -0.526800
+v 0.978532 2.545954 -0.526800
+v 0.978532 2.545954 -0.526800
+v 0.978532 2.545954 -0.526800
+v 1.241163 2.545954 0.695864
+v 1.241163 2.545954 0.695864
+v 1.353509 2.545954 0.660380
+v 1.353509 2.545954 0.660380
+v 0.956468 2.080430 -0.596654
+v 0.956468 2.080430 -0.596654
+v 0.956468 2.080430 -0.596654
+v 0.844122 2.174018 -0.561169
+v 0.844122 2.174018 -0.561169
+v 0.844122 2.174018 -0.561169
+v 0.956468 2.174018 -0.596654
+v 0.956468 2.174018 -0.596654
+v 0.956468 2.174018 -0.596654
+v 0.844122 2.545954 -0.561169
+v 0.844122 2.545954 -0.561169
+v 0.956468 2.545954 -0.596654
+v 0.956468 2.545954 -0.596654
+v 0.956468 2.545954 -0.596654
+v 3.012783 2.174018 -1.169330
+v 3.012783 2.174018 -1.169330
+v 3.012783 2.174018 -1.169330
+v 3.012783 2.080430 -1.169330
+v 3.012783 2.080430 -1.169330
+v 3.012783 2.080430 -1.169330
+v 3.012783 2.080430 -1.169330
+v 3.012783 2.545954 -1.169330
+v 3.012783 2.545954 -1.169330
+v 3.012783 2.545954 -1.169330
+v 3.012783 2.545954 -1.169330
+v 2.990720 2.080430 -1.239183
+v 2.990720 2.080430 -1.239183
+v 2.990720 2.080430 -1.239183
+v 2.990720 2.174018 -1.239183
+v 2.990720 2.174018 -1.239183
+v 2.990720 2.174018 -1.239183
+v 2.990720 2.545954 -1.239183
+v 2.990720 2.545954 -1.239183
+v 2.990720 2.545954 -1.239183
+v 3.070777 2.174018 -1.264470
+v 3.070777 2.174018 -1.264470
+v 3.070777 2.174018 -1.264470
+v 3.092841 2.080430 -1.194616
+v 3.092841 2.080430 -1.194616
+v 3.092841 2.080430 -1.194616
+v 3.092841 2.174018 -1.194616
+v 3.092841 2.174018 -1.194616
+v 3.092841 2.174018 -1.194616
+v 3.092841 2.545954 -1.194616
+v 3.092841 2.545954 -1.194616
+v 3.092841 2.545954 -1.194616
+v 3.070777 2.080430 -1.264470
+v 3.070777 2.080430 -1.264470
+v 3.070777 2.545954 -1.264470
+v 3.070777 2.545954 -1.264470
+v 3.376227 2.174018 -0.018666
+v 3.376227 2.174018 -0.018666
+v 3.376227 2.174018 -0.018666
+v 3.376227 2.080430 -0.018666
+v 3.376227 2.080430 -0.018666
+v 3.376227 2.545954 -0.018666
+v 3.376227 2.545954 -0.018666
+v 3.456284 2.080430 -0.043953
+v 3.456284 2.080430 -0.043953
+v 3.456284 2.174018 -0.043953
+v 3.456284 2.174018 -0.043953
+v 3.456284 2.174018 -0.043953
+v 3.456284 2.545954 -0.043953
+v 3.456284 2.545954 -0.043953
+v 1.510815 2.137595 0.037730
+v 1.349035 2.290844 -0.140367
+v 1.591464 2.172901 -0.233612
+v 1.784266 2.190338 -0.024086
+v 1.660990 2.319058 0.198652
+v 1.392003 2.381173 0.126783
+v 1.522500 2.438301 -0.312256
+v 1.791486 2.376186 -0.240387
+v 1.834455 2.466515 0.026763
+v 1.592026 2.584458 0.120008
+v 1.399223 2.567021 -0.089519
+v 1.672674 2.619764 -0.151334
+v 2.497889 2.137595 -0.044384
+v 2.336109 2.290844 -0.222481
+v 2.578538 2.172901 -0.315726
+v 2.771340 2.190338 -0.106200
+v 2.648064 2.319058 0.116538
+v 2.379078 2.381173 0.044669
+v 2.509574 2.438301 -0.394370
+v 2.778560 2.376186 -0.322502
+v 2.821529 2.466515 -0.055351
+v 2.579100 2.584458 0.037894
+v 2.386297 2.567021 -0.171633
+v 2.659748 2.619764 -0.233449
+v 2.006507 2.137595 -0.316138
+v 1.844727 2.290844 -0.494235
+v 2.087156 2.172901 -0.587479
+v 2.279958 2.190338 -0.377954
+v 2.156682 2.319058 -0.155216
+v 1.887695 2.381173 -0.227085
+v 2.018192 2.438301 -0.666124
+v 2.287179 2.376186 -0.594255
+v 2.330147 2.466515 -0.327105
+v 2.087718 2.584458 -0.233860
+v 1.894915 2.567021 -0.443387
+v 2.168366 2.619764 -0.505202
+v 2.833736 2.426006 -0.583306
+v 2.684991 2.845636 -1.079525
+v 2.757221 2.366194 -0.574572
+v 2.608476 2.785824 -1.070790
+v 2.749703 2.246832 -0.600498
+v 2.600958 2.666462 -1.096717
+v 2.818701 2.187281 -0.635161
+v 2.669955 2.606911 -1.131379
+v 2.895216 2.247093 -0.643896
+v 2.746471 2.666724 -1.140114
+v 2.902734 2.366456 -0.617969
+v 2.753989 2.786086 -1.114187
+v 3.047219 2.426006 -0.650736
+v 2.898475 2.845636 -1.146955
+v 2.970704 2.366194 -0.642001
+v 2.821959 2.785824 -1.138220
+v 2.963186 2.246832 -0.667928
+v 2.814442 2.666462 -1.164147
+v 3.032184 2.187281 -0.702591
+v 2.883439 2.606911 -1.198809
+v 3.108700 2.247093 -0.711326
+v 2.959954 2.666724 -1.207544
+v 3.116217 2.366456 -0.685399
+v 2.967472 2.786086 -1.181617
+v -1.172064 2.145742 0.102815
+v -1.274777 2.145742 0.043514
+v -1.274777 2.075523 -0.065804
+v -1.274777 2.111542 -0.065804
+v -1.077392 2.075523 0.048156
+v -1.077392 2.111542 0.048156
+v -1.077392 2.075523 0.276076
+v -1.077392 2.111542 0.276076
+v -1.274777 2.075523 0.390036
+v -1.274777 2.111542 0.390036
+v -1.472162 2.075523 0.276076
+v -1.472162 2.111542 0.276076
+v -1.472162 2.075523 0.048156
+v -1.472162 2.111542 0.048156
+v -1.172064 2.145742 0.221418
+v -1.274777 2.145742 0.280719
+v -1.377490 2.145742 0.221418
+v -1.377490 2.145742 0.102815
+v -1.238618 2.209867 0.141240
+v -1.274777 2.209867 0.120363
+v -1.238618 2.209867 0.182993
+v -1.274777 2.209867 0.203870
+v -1.310936 2.209867 0.182993
+v -1.310936 2.209867 0.141240
+v -1.238618 2.579231 0.141240
+v -1.274777 2.579231 0.120363
+v -1.238618 2.579231 0.182993
+v -1.274777 2.579231 0.203870
+v -1.310936 2.579231 0.182993
+v -1.310936 2.579231 0.141240
+v -1.188232 2.648486 0.112150
+v -1.274777 2.648486 0.062183
+v -1.188232 2.648486 0.212083
+v -1.274777 2.648486 0.262050
+v -1.361322 2.648486 0.212083
+v -1.361322 2.648486 0.112150
+v -1.124406 2.740827 0.075299
+v -1.274777 2.740827 -0.011518
+v -1.124406 2.740827 0.248933
+v -1.274777 2.740827 0.335750
+v -1.425149 2.740827 0.248933
+v -1.425149 2.740827 0.075299
+v -1.080861 2.912683 0.050158
+v -1.274777 2.912683 -0.061799
+v -1.080861 2.912683 0.274074
+v -1.274777 2.912683 0.386032
+v -1.468694 2.912683 0.274074
+v -1.468694 2.912683 0.050158
+v -1.080861 3.117886 0.050158
+v -1.274777 3.117886 -0.061799
+v -1.080861 3.117886 0.274074
+v -1.274777 3.117886 0.386032
+v -1.468694 3.117886 0.274074
+v -1.468694 3.117886 0.050158
+v -1.099921 3.127254 0.059737
+v -1.278856 3.127254 -0.043571
+v -1.099921 3.127254 0.266354
+v -1.278856 3.127254 0.369662
+v -1.457792 3.127254 0.266354
+v -1.457792 3.127254 0.059737
+v -1.278856 2.680948 0.163046
+v -1.922013 2.145742 -0.643475
+v -2.024726 2.145742 -0.702776
+v -2.024726 2.075523 -0.812093
+v -2.024726 2.111542 -0.812093
+v -1.827342 2.075523 -0.698134
+v -1.827342 2.111542 -0.698134
+v -1.827342 2.075523 -0.470213
+v -1.827342 2.111542 -0.470213
+v -2.024726 2.075523 -0.356253
+v -2.024726 2.111542 -0.356253
+v -2.222111 2.075523 -0.470213
+v -2.222111 2.111542 -0.470213
+v -2.222111 2.075523 -0.698134
+v -2.222111 2.111542 -0.698134
+v -1.922013 2.145742 -0.524872
+v -2.024726 2.145742 -0.465571
+v -2.127439 2.145742 -0.524872
+v -2.127439 2.145742 -0.643475
+v -1.988567 2.209867 -0.605050
+v -2.024726 2.209867 -0.625927
+v -1.988567 2.209867 -0.563297
+v -2.024726 2.209867 -0.542420
+v -2.060886 2.209867 -0.563297
+v -2.060886 2.209867 -0.605050
+v -1.988567 2.579231 -0.605050
+v -2.024726 2.579231 -0.625927
+v -1.988567 2.579231 -0.563297
+v -2.024726 2.579231 -0.542420
+v -2.060886 2.579231 -0.563297
+v -2.060886 2.579231 -0.605050
+v -1.938182 2.648486 -0.634140
+v -2.024726 2.648486 -0.684107
+v -1.938182 2.648486 -0.534207
+v -2.024726 2.648486 -0.484240
+v -2.111271 2.648486 -0.534207
+v -2.111271 2.648486 -0.634140
+v -1.874355 2.740827 -0.670991
+v -2.024726 2.740827 -0.757808
+v -1.874355 2.740827 -0.497356
+v -2.024726 2.740827 -0.410539
+v -2.175098 2.740827 -0.497356
+v -2.175098 2.740827 -0.670991
+v -1.830810 2.912683 -0.696131
+v -2.024726 2.912683 -0.808089
+v -1.830810 2.912683 -0.472216
+v -2.024726 2.912683 -0.360258
+v -2.218643 2.912683 -0.472216
+v -2.218643 2.912683 -0.696131
+v -1.830810 3.117886 -0.696131
+v -2.024726 3.117886 -0.808089
+v -1.830810 3.117886 -0.472216
+v -2.024726 3.117886 -0.360258
+v -2.218643 3.117886 -0.472216
+v -2.218643 3.117886 -0.696131
+v -1.849871 3.127254 -0.686552
+v -2.028805 3.127254 -0.789860
+v -1.849871 3.127254 -0.479936
+v -2.028805 3.127254 -0.376628
+v -2.207741 3.127254 -0.479936
+v -2.207741 3.127254 -0.686552
+v -2.028805 2.680948 -0.583244
+v -3.080822 2.145742 0.848455
+v -3.183535 2.145742 0.789153
+v -3.183535 2.075523 0.679836
+v -3.183535 2.111542 0.679836
+v -2.986151 2.075523 0.793796
+v -2.986151 2.111542 0.793796
+v -2.986151 2.075523 1.021716
+v -2.986151 2.111542 1.021716
+v -3.183535 2.075523 1.135676
+v -3.183535 2.111542 1.135676
+v -3.380919 2.075523 1.021716
+v -3.380919 2.111542 1.021716
+v -3.380919 2.075523 0.793796
+v -3.380919 2.111542 0.793796
+v -3.080822 2.145742 0.967057
+v -3.183535 2.145742 1.026358
+v -3.286248 2.145742 0.967057
+v -3.286248 2.145742 0.848455
+v -3.147376 2.209867 0.886879
+v -3.183535 2.209867 0.866003
+v -3.147376 2.209867 0.928633
+v -3.183535 2.209867 0.949509
+v -3.219694 2.209867 0.928633
+v -3.219694 2.209867 0.886879
+v -3.147376 2.579231 0.886879
+v -3.183535 2.579231 0.866003
+v -3.147376 2.579231 0.928633
+v -3.183535 2.579231 0.949509
+v -3.219694 2.579231 0.928633
+v -3.219694 2.579231 0.886879
+v -3.096991 2.648486 0.857789
+v -3.183535 2.648486 0.807823
+v -3.096991 2.648486 0.957723
+v -3.183535 2.648486 1.007689
+v -3.270080 2.648486 0.957723
+v -3.270080 2.648486 0.857789
+v -3.033164 2.740827 0.820939
+v -3.183534 2.740827 0.734122
+v -3.033164 2.740827 0.994573
+v -3.183534 2.740827 1.081390
+v -3.333907 2.740827 0.994573
+v -3.333907 2.740827 0.820939
+v -2.989619 2.912683 0.795798
+v -3.183534 2.912683 0.683840
+v -2.989619 2.912683 1.019714
+v -3.183534 2.912683 1.131672
+v -3.377452 2.912683 1.019714
+v -3.377452 2.912683 0.795798
+v -2.989619 3.117886 0.795798
+v -3.183534 3.117886 0.683840
+v -2.989619 3.117886 1.019714
+v -3.183534 3.117886 1.131672
+v -3.377452 3.117886 1.019714
+v -3.377452 3.117886 0.795798
+v -3.008679 3.127254 0.805377
+v -3.187614 3.127254 0.702069
+v -3.008679 3.127254 1.011994
+v -3.187614 3.127254 1.115302
+v -3.366550 3.127254 1.011994
+v -3.366550 3.127254 0.805377
+v -3.187614 2.680948 0.908685
+v 4.401308 3.617208 3.580229
+v 4.401308 -0.025686 3.580229
+v 4.401308 3.792680 3.528995
+v 4.401308 4.260199 3.059984
+v 4.401308 5.051156 -0.716959
+v 4.401308 4.593092 -1.289192
+vt 0.905299 0.942320
+vt 0.533523 0.942320
+vt 0.905299 0.919749
+vt 0.890688 0.972537
+vt 0.606224 0.972537
+vt 0.905301 0.957852
+vt 0.863038 0.512341
+vt 0.863038 0.667779
+vt 0.707599 0.667779
+vt 0.915821 0.578064
+vt 0.915821 0.985620
+vt 0.508265 0.985620
+vt 0.707599 0.979117
+vt 0.707599 0.823679
+vt 0.863038 0.979117
+vt 0.863038 0.668010
+vt 0.863038 0.823448
+vt 0.707599 0.823448
+vt 0.606226 0.942743
+vt 0.890679 0.942743
+vt 0.533523 0.957429
+vt 0.700713 0.854870
+vt 0.985176 0.854869
+vt 0.905300 0.896755
+vt 0.636824 0.703297
+vt 0.921287 0.703296
+vt 0.935900 0.776011
+vt 0.535960 0.512341
+vt 0.707368 0.512341
+vt 0.535960 0.715489
+vt 0.533523 0.896755
+vt 0.905300 0.919326
+vt 0.999789 0.869555
+vt 0.999789 0.892126
+vt 0.599209 0.831876
+vt 0.912899 0.831876
+vt 0.599209 0.854446
+vt 0.710700 0.504901
+vt 0.710700 0.981434
+vt 0.702383 0.504933
+vt 0.699950 0.504898
+vt 0.699800 0.981445
+vt 0.691482 0.981475
+vt 0.691633 0.504928
+vt 0.680581 0.981472
+vt 0.702383 0.981467
+vt 0.691482 0.504933
+vt 0.674847 0.504998
+vt 0.674847 0.981532
+vt 0.663946 0.981532
+vt 0.680731 0.504924
+vt 0.672263 0.981502
+vt 0.691482 0.981467
+vt 0.683164 0.504966
+vt 0.683164 0.981499
+vt 0.672414 0.504954
+vt 0.664096 0.504984
+vt 0.708268 0.504868
+vt 0.708118 0.981416
+vt 0.719169 0.504872
+vt 0.719019 0.981419
+vt 0.719017 0.504868
+vt 0.719018 0.981402
+vt 0.657579 0.583164
+vt 0.894968 0.583164
+vt 0.894968 0.599545
+vt 0.746642 0.950201
+vt 0.875496 0.950201
+vt 0.875496 0.966582
+vt 0.894968 0.624058
+vt 0.657579 0.624058
+vt 0.894968 0.607677
+vt 0.875496 0.983360
+vt 0.746642 0.983360
+vt 0.875496 0.966979
+vt 0.528328 0.755451
+vt 0.765717 0.755451
+vt 0.765717 0.884305
+vt 0.528328 0.755055
+vt 0.528328 0.517666
+vt 0.657182 0.517666
+vt 0.875496 0.755055
+vt 0.657579 0.755055
+vt 0.657579 0.689953
+vt 0.746642 0.983757
+vt 0.964561 0.983757
+vt 0.964561 0.990147
+vt 0.888717 0.600889
+vt 0.888718 0.607280
+vt 0.875895 0.600889
+vt 0.957855 0.949804
+vt 0.739939 0.949804
+vt 0.957855 0.933423
+vt 0.895502 0.534047
+vt 0.889111 0.534047
+vt 0.889111 0.517666
+vt 0.528328 0.950201
+vt 0.746245 0.950201
+vt 0.746245 0.966582
+vt 0.657579 0.600889
+vt 0.875499 0.600890
+vt 0.875499 0.607280
+vt 0.765717 0.884702
+vt 0.765717 0.891093
+vt 0.752895 0.891092
+vt 0.889006 0.755451
+vt 0.895396 0.755451
+vt 0.895396 0.820553
+vt 0.657579 0.517666
+vt 0.875496 0.517666
+vt 0.657579 0.582767
+vt 0.895502 0.582767
+vt 0.889112 0.582767
+vt 0.895502 0.566386
+vt 0.882219 0.755451
+vt 0.888609 0.755451
+vt 0.882219 0.820553
+vt 0.881822 0.886448
+vt 0.881822 0.899271
+vt 0.766114 0.899271
+vt 0.888715 0.517666
+vt 0.888715 0.582767
+vt 0.875892 0.517666
+vt 0.881822 0.820950
+vt 0.881822 0.886052
+vt 0.766114 0.886052
+vt 0.895231 0.641232
+vt 0.895231 0.657614
+vt 0.882409 0.641232
+vt 0.901828 0.891002
+vt 0.889006 0.891002
+vt 0.889006 0.886449
+vt 0.893665 0.738673
+vt 0.893665 0.755055
+vt 0.889112 0.738673
+vt 0.984897 0.624454
+vt 0.984897 0.640836
+vt 0.869190 0.624454
+vt 0.984897 0.673175
+vt 0.984897 0.689556
+vt 0.869190 0.689556
+vt 0.881822 0.755451
+vt 0.881822 0.820553
+vt 0.766114 0.755451
+vt 0.984897 0.659956
+vt 0.984897 0.672778
+vt 0.869190 0.672778
+vt 0.875892 0.755055
+vt 0.875893 0.689953
+vt 0.888715 0.689953
+vt 0.869190 0.657614
+vt 0.869190 0.641232
+vt 0.882012 0.641232
+vt 0.657579 0.689556
+vt 0.657579 0.624454
+vt 0.868793 0.624454
+vt 0.893559 0.820950
+vt 0.893559 0.886052
+vt 0.889006 0.820950
+vt 0.889111 0.544658
+vt 0.901934 0.544658
+vt 0.889111 0.549212
+vt 0.528328 0.949804
+vt 0.528328 0.884702
+vt 0.739542 0.949804
+vt 0.882219 0.886051
+vt 0.882219 0.820950
+vt 0.886772 0.820950
+vt 0.889111 0.565989
+vt 0.889112 0.549608
+vt 0.893665 0.549608
+vt 0.528328 0.976483
+vt 0.528328 0.971929
+vt 0.739540 0.971929
+vt 0.528328 0.971533
+vt 0.528328 0.966979
+vt 0.739540 0.966979
+vt 0.739939 0.916248
+vt 0.739939 0.899867
+vt 0.951152 0.916248
+vt 0.739939 0.933026
+vt 0.739939 0.916645
+vt 0.951152 0.916645
+vt 0.288599 0.586905
+vt 0.263686 0.622200
+vt 0.255994 0.605150
+vt 0.308778 0.621073
+vt 0.416738 0.556495
+vt 0.402006 0.581949
+vt 0.401971 0.548587
+vt 0.410397 0.513377
+vt 0.328955 0.603326
+vt 0.288644 0.660434
+vt 0.256022 0.650593
+vt 0.361632 0.586905
+vt 0.401971 0.598571
+vt 0.381766 0.626266
+vt 0.329010 0.596747
+vt 0.336674 0.625139
+vt 0.328982 0.648769
+vt 0.401943 0.644014
+vt 0.328982 0.642190
+vt 0.423079 0.513377
+vt 0.431506 0.548587
+vt 0.361587 0.660434
+vt 0.431470 0.581949
+vt 0.058872 0.514455
+vt 0.033648 0.579711
+vt 0.060007 0.526490
+vt 0.057959 0.590632
+vt 0.101326 0.507643
+vt 0.098280 0.547934
+vt 0.058446 0.652807
+vt 0.059718 0.615219
+vt 0.102501 0.569863
+vt 0.125087 0.582568
+vt 0.097551 0.631974
+vt 0.100043 0.648601
+vt 0.288599 0.513377
+vt 0.263686 0.548671
+vt 0.255994 0.531621
+vt 0.308778 0.547544
+vt 0.431506 0.630024
+vt 0.416774 0.655477
+vt 0.416738 0.622116
+vt 0.425165 0.586905
+vt 0.328955 0.529797
+vt 0.288644 0.586905
+vt 0.256022 0.577064
+vt 0.361632 0.513377
+vt 0.401971 0.525042
+vt 0.381766 0.552738
+vt 0.329010 0.523218
+vt 0.336674 0.551611
+vt 0.328982 0.575240
+vt 0.401943 0.570485
+vt 0.328982 0.568661
+vt 0.408312 0.586905
+vt 0.416738 0.622115
+vt 0.401971 0.630023
+vt 0.361588 0.586905
+vt 0.416703 0.655477
+vt 0.373139 0.405595
+vt 0.266846 0.405755
+vt 0.372364 0.382592
+vt 0.265891 0.382261
+vt 0.380766 0.365849
+vt 0.274024 0.364779
+vt 0.390004 0.372272
+vt 0.283166 0.370938
+vt 0.390970 0.395797
+vt 0.284319 0.394978
+vt 0.382504 0.412368
+vt 0.276129 0.412304
+vt 0.387980 0.449935
+vt 0.281849 0.450540
+vt 0.387016 0.426417
+vt 0.280686 0.426474
+vt 0.395511 0.409928
+vt 0.288902 0.409221
+vt 0.405043 0.417158
+vt 0.298351 0.416223
+vt 0.406207 0.441227
+vt 0.299725 0.440869
+vt 0.397635 0.457505
+vt 0.291436 0.457923
+vt 0.125099 0.179064
+vt 0.140481 0.179064
+vt 0.135498 0.187381
+vt 0.147570 0.174628
+vt 0.118010 0.174628
+vt 0.162351 0.169957
+vt 0.162351 0.174628
+vt 0.148172 0.179064
+vt 0.138205 0.187381
+vt 0.110516 0.153916
+vt 0.102583 0.168696
+vt 0.102583 0.154518
+vt 0.147570 0.169957
+vt 0.127375 0.187381
+vt 0.130082 0.187381
+vt 0.130082 0.235286
+vt 0.118010 0.169957
+vt 0.103229 0.174628
+vt 0.094650 0.124355
+vt 0.102583 0.109575
+vt 0.098455 0.131444
+vt 0.103229 0.169957
+vt 0.110516 0.124355
+vt 0.106711 0.131444
+vt 0.117408 0.179064
+vt 0.094650 0.153916
+vt 0.098455 0.146827
+vt 0.127375 0.235286
+vt 0.126310 0.244268
+vt 0.138205 0.235286
+vt 0.135498 0.235286
+vt 0.119829 0.244268
+vt 0.110270 0.256245
+vt 0.139270 0.244268
+vt 0.144050 0.256245
+vt 0.121530 0.256245
+vt 0.147311 0.278534
+vt 0.145751 0.244268
+vt 0.155310 0.256245
+vt 0.118269 0.278534
+vt 0.147311 0.305148
+vt 0.101543 0.235066
+vt 0.072502 0.235066
+vt 0.073503 0.236281
+vt 0.103749 0.278534
+vt 0.118269 0.305148
+vt 0.161831 0.278534
+vt 0.161831 0.305148
+vt 0.102583 0.110094
+vt 0.110377 0.124615
+vt 0.109611 0.125616
+vt 0.110377 0.153656
+vt 0.102583 0.168177
+vt 0.109611 0.152414
+vt 0.116063 0.235066
+vt 0.100301 0.236281
+vt 0.057981 0.235066
+vt 0.086902 0.178396
+vt 0.060104 0.236281
+vt 0.113699 0.236281
+vt 0.102583 0.123753
+vt 0.533523 0.919749
+vt 0.533523 0.957852
+vt 0.707599 0.512341
+vt 0.508265 0.578064
+vt 0.863038 0.823679
+vt 0.707599 0.668010
+vt 0.905292 0.957429
+vt 0.622211 0.776012
+vt 0.707368 0.715489
+vt 0.533523 0.919326
+vt 0.912899 0.854447
+vt 0.663946 0.504998
+vt 0.657579 0.599545
+vt 0.746642 0.966582
+vt 0.657579 0.607677
+vt 0.746642 0.966979
+vt 0.528328 0.884305
+vt 0.657182 0.755055
+vt 0.875496 0.689953
+vt 0.746642 0.990146
+vt 0.875896 0.607280
+vt 0.739939 0.933423
+vt 0.895502 0.517666
+vt 0.528328 0.966582
+vt 0.657579 0.607279
+vt 0.752895 0.884702
+vt 0.889006 0.820553
+vt 0.875496 0.582767
+vt 0.889111 0.566386
+vt 0.888609 0.820553
+vt 0.766114 0.886448
+vt 0.875892 0.582767
+vt 0.766114 0.820950
+vt 0.882409 0.657614
+vt 0.901828 0.886449
+vt 0.889112 0.755055
+vt 0.869190 0.640836
+vt 0.869190 0.673175
+vt 0.766114 0.820553
+vt 0.869190 0.659956
+vt 0.888715 0.755055
+vt 0.882012 0.657614
+vt 0.868793 0.689556
+vt 0.889006 0.886052
+vt 0.901934 0.549212
+vt 0.739542 0.884702
+vt 0.886772 0.886051
+vt 0.893665 0.565989
+vt 0.739540 0.976483
+vt 0.739540 0.971533
+vt 0.951152 0.899867
+vt 0.951152 0.933026
+vt 0.106711 0.146827
+vt 0.103749 0.305148
+vt 0.102419 0.112218
+vt 0.102419 0.165813
+vt 0.176655 0.902678
+vt 0.177195 0.893095
+vt 0.017048 0.894869
+vt 0.175049 0.789769
+vt 0.175642 0.911615
+vt 0.019454 0.789409
+vt 0.172299 0.777935
+vt 0.019488 0.777616
+vt 0.194225 0.892858
+vt 0.188367 0.779011
+vt 0.220229 0.892814
+vt 0.185989 0.902579
+vt 0.183371 0.911603
+vt 0.212963 0.780571
+vt 0.379965 0.900404
+vt 0.183492 0.789933
+vt 0.210776 0.911687
+vt 0.218479 0.901319
+vt 0.367145 0.793339
+vt 0.391357 0.794319
+vt 0.213720 0.792797
+vt 0.370492 0.908704
+vt 0.367608 0.800840
+vt 0.406722 0.906137
+vt 0.410730 0.918007
+vt 0.394868 0.799588
+vt 0.378842 0.909853
+vt 0.013364 0.906932
+vt 0.017669 0.909263
+vt 0.396496 0.908115
+vn -1.000000 0.000000 0.000000
+vn 0.030915 -0.999512 0.000000
+vn 1.000000 0.000000 0.000000
+vn 0.000000 0.000000 1.000000
+vn -0.999969 0.000000 0.000000
+vn 0.000000 0.000000 -1.000000
+vn -0.030915 -0.999512 0.000000
+vn 0.000000 -0.995025 0.099399
+vn 0.707327 -0.135258 -0.693808
+vn 0.000000 -0.999786 -0.020051
+vn 0.000000 0.999969 0.000000
+vn 0.000000 1.000000 0.000000
+vn 0.707083 0.000000 -0.707083
+vn 0.000000 -0.191351 -0.981506
+vn 0.000000 0.000000 -0.999969
+vn -0.866024 0.000000 0.499985
+vn 0.866024 0.000000 -0.499985
+vn 0.866024 0.000000 0.499985
+vn -0.866024 0.000000 -0.499985
+vn -0.499985 0.000000 0.866024
+vn 0.499985 0.000000 0.866024
+vn 0.953551 0.000000 -0.301187
+vn 0.301187 0.000000 0.953551
+vn -0.953551 0.000000 0.301187
+vn -0.301187 0.000000 -0.953551
+vn 0.000000 -1.000000 0.000000
+vn 0.000000 -0.999969 0.000000
+vn 0.301157 0.000000 0.953551
+vn -0.953551 0.000000 0.301157
+vn 0.953551 0.000000 -0.301157
+vn -0.298288 -0.888577 0.348430
+vn -0.894589 -0.323740 -0.307993
+vn -0.001007 -0.758446 -0.651692
+vn -0.736198 0.009186 0.676656
+vn 0.709586 -0.694174 0.120579
+vn 0.255226 -0.219733 0.941557
+vn -0.709586 0.694174 -0.120579
+vn -0.255226 0.219733 -0.941557
+vn 0.736198 -0.009186 -0.676656
+vn 0.894589 0.323740 0.307993
+vn 0.001007 0.758446 0.651692
+vn 0.298288 0.888577 -0.348430
+vn 0.251289 0.471114 0.845485
+vn -0.060549 0.978484 -0.197150
+vn -0.463698 0.077792 0.882565
+vn -0.814905 0.548326 -0.187719
+vn -0.577136 -0.550829 0.602893
+vn -0.871090 -0.080203 -0.484451
+vn 0.060549 -0.978484 0.197150
+vn -0.251289 -0.471114 -0.845485
+vn 0.814905 -0.548326 0.187719
+vn 0.463698 -0.077792 -0.882565
+vn 0.871090 0.080203 0.484451
+vn 0.577136 0.550829 -0.602893
+vn 0.369091 0.904630 0.213080
+vn 0.369091 0.904630 -0.213080
+vn 0.756615 0.486465 -0.436842
+vn -0.741844 0.515915 -0.428297
+vn -0.741844 0.515915 0.428297
+vn -0.369091 0.904630 -0.213080
+vn 0.000000 -0.609973 -0.792383
+vn 0.000000 0.515915 -0.856624
+vn 0.741844 0.515915 -0.428297
+vn 0.000000 0.904630 -0.426191
+vn 0.000000 0.486465 -0.873653
+vn 0.686239 -0.609973 -0.396191
+vn 0.741844 0.515915 0.428297
+vn 0.000000 0.486465 0.873653
+vn 0.756615 0.486465 0.436842
+vn 0.799799 -0.383435 0.461776
+vn 0.686239 -0.609973 0.396191
+vn 0.000000 0.515915 0.856624
+vn -0.369091 0.904630 0.213080
+vn 0.000000 -0.609973 0.792383
+vn -0.686239 -0.609973 0.396191
+vn -0.686239 -0.609973 -0.396191
+vn 0.000000 0.904630 0.426191
+vn -0.756615 0.486465 -0.436842
+vn 0.000000 -0.383435 0.923551
+vn 0.671407 -0.631581 0.387646
+vn 0.000000 -0.383435 -0.923551
+vn -0.756615 0.486465 0.436842
+vn -0.799799 -0.383435 0.461776
+vn 0.799799 -0.383435 -0.461776
+vn -0.799799 -0.383435 -0.461776
+vn 0.000000 -0.631581 0.775292
+vn 0.000000 -0.437361 0.899258
+vn 0.671407 -0.631581 -0.387646
+vn -0.671407 -0.631581 -0.387646
+vn -0.671407 -0.631581 0.387646
+vn -0.778771 -0.437361 -0.449629
+vn -0.778771 -0.437361 0.449629
+vn -0.857967 -0.135868 -0.495346
+vn 0.000000 -0.631581 -0.775292
+vn 0.000000 -0.437361 -0.899258
+vn 0.778771 -0.437361 -0.449629
+vn -0.857967 -0.135868 0.495346
+vn -0.779931 0.421735 -0.462386
+vn 0.778771 -0.437361 0.449629
+vn 0.857967 -0.135868 0.495346
+vn 0.857967 -0.135868 -0.495346
+vn -0.787530 0.409497 0.460494
+vn -0.009552 0.999756 -0.018677
+vn 0.000000 -0.135868 0.990722
+vn 0.765709 0.473769 0.434980
+vn 0.000000 -0.135868 -0.990722
+vn 0.010376 0.459670 -0.887997
+vn 0.761406 0.479019 -0.436720
+vn 0.012177 0.444380 0.895718
+vn -0.108676 0.993500 -0.033326
+vn -0.111728 0.992309 0.052675
+vn -0.008026 0.998871 0.046297
+vn -0.051759 0.997345 -0.051119
+vn -0.043825 0.995819 0.080111
+vn 0.000000 0.486465 -0.873684
+vn 0.671438 -0.631581 0.387646
+vn 0.756615 0.486496 -0.436842
+vn 0.756615 0.486496 0.436842
+vn -0.051790 0.997345 -0.051088
+vn 0.667287 0.139409 0.731620
+vn 0.707083 0.000000 0.707083
+vn -0.740379 -0.095126 -0.665365
+vn 0.000000 -0.141545 -0.989929
+vn -0.707083 0.000000 -0.707083
+vn -0.667287 0.139409 0.731620
+vn -0.707083 0.000000 0.707083
+vn 0.663778 0.411603 0.624439
+vn -0.663778 0.411603 0.624439
+vn 0.646870 0.674490 0.355785
+vn 0.000000 -0.510300 -0.859981
+vn -0.646870 0.674490 0.355785
+vn 0.625416 0.759117 -0.180425
+vn -0.767602 -0.327036 -0.551164
+vn 0.000000 -0.879910 -0.475112
+vn 0.999969 0.000000 0.000000
+vn -0.625416 0.759117 -0.180425
+vn -0.571825 0.061678 -0.818018
+vn -0.777123 -0.553728 -0.298990
+vn 0.000000 -0.972655 0.232154
+vn -0.816797 -0.561113 0.133915
+vn 0.571825 0.061678 -0.818018
+vn 0.726402 -0.475723 -0.495926
+vn -0.582202 -0.811274 -0.053255
+vn 0.000000 -0.780663 0.624897
+s 1
+f 41/1/1 38/2/1 45/3/1
+f 31/4/2 27/5/2 40/6/2
+f 1/7/3 5/8/3 6/9/3
+f 21/10/4 22/11/4 7/12/4
+f 25/13/1 26/14/5 29/15/1
+f 18/16/6 17/17/6 4/18/6
+f 23/19/7 19/20/7 10/21/7
+f 20/22/8 32/23/8 33/24/9
+f 28/25/10 24/26/10 34/27/10
+f 13/28/11 16/29/12 14/30/12
+f 35/31/3 33/24/9 42/32/13
+f 33/24/9 12/33/14 46/34/15
+f 39/35/4 36/36/4 48/37/4
+f 67/38/4 68/39/4 69/40/16
+f 51/41/6 52/42/6 54/43/17
+f 53/44/17 54/43/17 56/45/18
+f 69/40/16 70/46/16 71/47/19
+f 63/48/17 64/49/17 66/50/3
+f 55/51/18 56/45/18 58/52/4
+f 71/47/19 72/53/19 50/54/6
+f 50/54/6 49/55/6 64/49/17
+f 57/56/4 58/52/4 59/57/20
+f 61/58/19 62/59/19 51/41/6
+f 100/60/1 99/61/1 61/58/19
+f 98/62/21 97/63/21 68/39/4
+f 105/64/22 106/65/22 102/66/22
+f 147/67/23 107/68/23 103/69/23
+f 153/70/24 108/71/24 155/72/24
+f 157/73/25 145/74/25 159/75/25
+f 152/76/26 150/77/26 156/78/27
+f 158/79/12 154/80/12 148/81/12
+f 180/82/22 183/83/22 189/84/22
+f 116/85/27 115/86/27 114/87/26
+f 117/88/12 120/89/12 125/90/11
+f 110/91/24 109/92/24 170/93/24
+f 111/94/28 175/95/28 171/96/28
+f 112/97/22 182/98/22 179/99/22
+f 186/100/12 118/101/12 119/102/12
+f 162/103/26 165/104/26 123/105/27
+f 176/106/28 181/107/28 196/108/28
+f 172/109/24 177/110/24 187/111/24
+f 121/112/25 122/113/25 168/114/25
+f 203/115/25 200/116/25 208/117/25
+f 209/118/12 190/119/12 218/120/12
+f 173/121/29 188/122/29 201/123/29
+f 192/124/23 184/125/23 127/126/23
+f 167/127/29 174/128/29 169/129/29
+f 214/130/26 222/131/26 243/132/26
+f 131/133/25 130/134/25 137/135/25
+f 198/136/25 204/137/25 223/138/25
+f 185/139/23 163/140/23 128/141/23
+f 205/142/25 210/143/25 225/144/25
+f 164/145/26 199/146/26 224/147/27
+f 135/148/30 237/149/30 231/150/30
+f 133/151/30 134/152/30 244/153/30
+f 238/154/22 241/155/22 144/156/22
+f 227/157/25 229/158/25 232/159/25
+f 230/160/12 219/161/12 246/162/12
+f 220/163/24 212/164/24 141/165/24
+f 252/166/23 248/167/23 257/168/23
+f 247/169/23 140/170/23 143/171/23
+f 215/172/26 235/173/27 254/174/26
+f 242/175/12 221/176/12 253/177/11
+f 213/178/24 216/179/24 249/180/24
+f 236/181/22 239/182/22 258/183/22
+f 261/184/31 262/185/32 263/186/33
+f 262/185/32 261/184/31 266/187/34
+f 261/188/31 263/189/33 264/190/35
+f 261/188/31 264/190/35 265/191/36
+f 261/184/31 265/192/36 266/187/34
+f 262/185/32 266/187/34 271/193/37
+f 263/186/33 262/185/32 267/194/38
+f 264/195/35 263/196/33 268/197/39
+f 265/198/36 264/195/35 269/199/40
+f 266/187/34 265/192/36 270/200/41
+f 262/185/32 271/193/37 267/194/38
+f 263/196/33 267/201/38 268/197/39
+f 264/195/35 268/197/39 269/199/40
+f 265/198/36 269/199/40 270/202/41
+f 266/187/34 270/200/41 271/193/37
+f 267/203/38 271/204/37 272/188/42
+f 268/197/39 267/201/38 272/205/42
+f 269/199/40 268/197/39 272/205/42
+f 270/202/41 269/199/40 272/205/42
+f 271/204/37 270/206/41 272/188/42
+f 273/207/31 274/208/32 275/209/33
+f 274/208/32 273/207/31 278/210/34
+f 273/207/31 275/209/33 276/211/35
+f 273/207/31 276/211/35 277/212/36
+f 273/207/31 277/212/36 278/210/34
+f 274/208/32 278/210/34 283/213/37
+f 275/209/33 274/208/32 279/214/38
+f 276/211/35 275/209/33 280/215/39
+f 277/212/36 276/211/35 281/216/40
+f 278/210/34 277/212/36 282/217/41
+f 274/208/32 283/213/37 279/214/38
+f 275/209/33 279/214/38 280/215/39
+f 276/211/35 280/215/39 281/216/40
+f 277/212/36 281/216/40 282/217/41
+f 278/210/34 282/217/41 283/213/37
+f 279/214/38 283/213/37 284/218/42
+f 280/215/39 279/214/38 284/218/42
+f 281/216/40 280/215/39 284/218/42
+f 282/217/41 281/216/40 284/218/42
+f 283/213/37 282/217/41 284/218/42
+f 285/219/31 286/220/32 287/221/33
+f 286/220/32 285/219/31 290/222/34
+f 285/223/31 287/224/33 288/225/35
+f 285/223/31 288/225/35 289/226/36
+f 285/219/31 289/227/36 290/222/34
+f 286/220/32 290/222/34 295/228/37
+f 287/221/33 286/220/32 291/229/38
+f 288/230/35 287/231/33 292/232/39
+f 289/233/36 288/230/35 293/234/40
+f 290/222/34 289/227/36 294/235/41
+f 286/220/32 295/228/37 291/229/38
+f 287/231/33 291/236/38 292/232/39
+f 288/230/35 292/232/39 293/234/40
+f 289/233/36 293/234/40 294/237/41
+f 290/222/34 294/235/41 295/228/37
+f 291/238/38 295/239/37 296/240/42
+f 292/232/39 291/236/38 296/241/42
+f 293/234/40 292/232/39 296/241/42
+f 294/237/41 293/234/40 296/241/42
+f 295/239/37 294/242/41 296/240/42
+f 297/243/43 298/244/44 299/245/45
+f 299/245/45 300/246/46 301/247/47
+f 301/247/47 302/248/48 303/249/49
+f 303/249/49 304/250/50 305/251/51
+f 302/248/48 306/252/52 304/250/50
+f 307/253/53 308/254/54 297/243/43
+f 305/251/51 306/252/52 307/253/53
+f 297/243/43 299/245/45 307/253/53
+f 309/255/43 310/256/44 311/257/45
+f 311/257/45 312/258/46 313/259/47
+f 313/259/47 314/260/48 315/261/49
+f 315/261/49 316/262/50 317/263/51
+f 314/260/48 318/264/52 316/262/50
+f 319/265/53 320/266/54 309/255/43
+f 317/263/51 318/264/52 319/265/53
+f 309/255/43 311/257/45 319/265/53
+f 335/267/55 321/268/56 339/269/57
+f 334/270/58 332/271/59 338/268/60
+f 323/272/61 324/273/62 326/270/63
+f 322/274/64 338/268/60 340/275/65
+f 326/276/63 324/277/62 322/278/64
+f 325/279/66 326/270/63 328/271/67
+f 342/280/68 341/281/69 347/282/70
+f 328/271/67 326/270/63 321/268/56
+f 327/283/71 328/271/67 330/284/72
+f 332/285/59 330/286/72 337/287/73
+f 321/268/56 322/274/64 339/269/57
+f 329/288/74 330/284/72 331/283/75
+f 330/286/72 328/289/67 335/290/55
+f 333/279/76 334/270/58 323/272/61
+f 331/283/75 332/271/59 333/279/76
+f 336/291/77 335/267/55 341/281/69
+f 324/277/62 334/292/58 338/293/60
+f 323/277/61 325/276/66 333/292/76
+f 337/267/73 336/291/77 342/280/68
+f 338/268/60 337/267/73 344/269/78
+f 348/294/79 347/282/70 353/295/80
+f 339/269/57 340/275/65 346/296/81
+f 340/275/65 344/269/78 346/296/81
+f 343/281/82 342/280/68 349/282/83
+f 341/281/69 339/269/57 345/297/84
+f 344/269/78 343/281/82 350/297/85
+f 354/298/86 353/295/80 360/299/87
+f 345/297/84 346/296/81 351/300/88
+f 346/296/81 350/297/85 356/300/89
+f 349/282/83 348/294/79 355/295/90
+f 347/282/70 345/297/84 351/300/88
+f 350/297/85 349/282/83 356/300/89
+f 362/301/91 361/302/92 368/303/93
+f 351/300/88 352/304/94 358/305/95
+f 352/304/94 356/300/89 358/305/95
+f 355/295/90 354/298/86 361/302/92
+f 353/295/80 351/300/88 357/301/96
+f 356/300/89 355/295/90 362/301/91
+f 368/303/93 367/306/97 374/307/98
+f 360/299/87 359/302/99 365/306/100
+f 357/301/96 358/305/95 363/303/101
+f 358/305/95 362/301/91 368/303/93
+f 361/302/92 360/299/87 367/306/97
+f 359/302/99 357/301/96 363/303/101
+f 374/308/98 373/309/102 379/310/103
+f 366/311/104 365/306/100 371/312/105
+f 363/303/101 364/313/106 370/314/107
+f 364/313/106 368/303/93 370/314/107
+f 367/306/97 366/311/104 373/312/102
+f 365/306/100 363/303/101 369/307/108
+f 372/315/109 371/316/105 377/317/110
+f 369/318/108 370/319/107 375/320/111
+f 370/321/107 374/308/98 380/322/112
+f 373/309/102 372/323/109 379/310/103
+f 371/309/105 369/308/108 375/322/111
+f 380/322/112 379/310/103 381/324/12
+f 378/325/113 377/310/110 381/324/12
+f 375/322/111 376/326/114 381/324/12
+f 376/326/114 380/322/112 381/324/12
+f 379/310/103 378/325/113 381/324/12
+f 377/310/110 375/322/111 381/324/12
+f 396/267/55 382/268/56 400/269/57
+f 395/270/58 393/271/59 399/268/60
+f 384/272/61 385/273/62 387/270/63
+f 383/274/64 399/268/60 401/275/115
+f 387/276/63 385/277/62 383/278/64
+f 386/279/66 387/270/63 389/271/67
+f 403/280/68 402/281/69 408/282/70
+f 389/271/67 387/270/63 382/268/56
+f 388/283/71 389/271/67 391/284/72
+f 393/285/59 391/286/72 398/287/73
+f 382/268/56 383/274/64 400/269/57
+f 390/288/74 391/284/72 392/283/75
+f 391/286/72 389/289/67 397/327/77
+f 394/279/76 395/270/58 384/272/61
+f 392/283/75 393/271/59 394/279/76
+f 397/291/77 396/267/55 402/281/69
+f 385/277/62 395/292/58 383/278/64
+f 384/277/61 386/276/66 394/292/76
+f 398/267/73 397/291/77 404/281/82
+f 399/268/60 398/267/73 405/269/78
+f 409/294/79 408/282/70 414/295/116
+f 400/269/57 401/275/115 407/296/81
+f 401/275/115 405/269/78 407/296/81
+f 404/281/82 403/280/68 410/282/83
+f 402/281/69 400/269/57 406/297/84
+f 405/269/78 404/281/82 411/297/85
+f 415/298/86 414/295/116 420/302/99
+f 406/297/84 407/296/81 412/300/88
+f 407/296/81 411/297/85 417/300/89
+f 410/282/83 409/294/79 416/295/90
+f 408/282/70 406/297/84 412/300/88
+f 411/297/85 410/282/83 417/300/89
+f 423/301/91 422/302/92 429/303/93
+f 412/300/88 413/304/94 419/305/95
+f 413/304/94 417/300/89 423/301/91
+f 416/295/90 415/298/86 422/302/92
+f 414/295/116 412/300/88 418/301/96
+f 417/300/89 416/295/90 423/301/91
+f 429/303/93 428/306/97 435/307/98
+f 421/299/87 420/302/99 426/306/100
+f 418/301/96 419/305/95 425/313/106
+f 419/305/95 423/301/91 425/313/106
+f 422/302/92 421/299/87 428/306/97
+f 420/302/99 418/301/96 424/303/101
+f 435/308/98 434/309/102 440/310/103
+f 427/311/104 426/306/100 432/312/105
+f 424/303/101 425/313/106 431/314/107
+f 425/313/106 429/303/93 431/314/107
+f 428/306/97 427/311/104 434/312/102
+f 426/306/100 424/303/101 430/307/108
+f 433/315/109 432/316/105 438/317/110
+f 430/318/108 431/319/107 436/320/111
+f 431/321/107 435/308/98 441/322/112
+f 434/309/102 433/323/109 440/310/103
+f 432/309/105 430/308/108 436/322/111
+f 441/322/112 440/310/103 442/324/12
+f 439/325/113 438/310/110 442/324/12
+f 436/322/111 437/326/114 442/324/12
+f 437/326/114 441/322/112 442/324/12
+f 440/310/103 439/325/113 442/324/12
+f 438/310/110 436/322/111 442/324/12
+f 457/267/55 443/268/56 461/269/117
+f 456/270/58 454/271/59 460/268/60
+f 445/272/61 446/273/62 448/270/63
+f 444/274/64 460/268/60 462/275/65
+f 448/276/63 446/277/62 444/278/64
+f 447/279/66 448/270/63 450/271/67
+f 464/280/68 463/281/118 469/282/70
+f 450/271/67 448/270/63 443/268/56
+f 449/283/71 450/271/67 452/284/72
+f 454/285/59 452/286/72 459/287/73
+f 443/268/56 444/274/64 461/269/117
+f 451/288/74 452/284/72 453/283/75
+f 452/286/72 450/289/67 458/327/77
+f 455/279/76 456/270/58 445/272/61
+f 453/283/75 454/271/59 455/279/76
+f 458/291/77 457/267/55 463/281/118
+f 446/277/62 456/292/58 444/278/64
+f 445/277/61 447/276/66 455/292/76
+f 459/267/73 458/291/77 464/280/68
+f 460/268/60 459/267/73 466/269/78
+f 470/294/79 469/282/70 475/295/80
+f 461/269/117 462/275/65 468/296/81
+f 462/275/65 466/269/78 468/296/81
+f 465/281/82 464/280/68 471/282/83
+f 463/281/118 461/269/117 467/297/84
+f 466/269/78 465/281/82 472/297/85
+f 476/298/86 475/295/80 482/299/87
+f 467/297/84 468/296/81 473/300/88
+f 468/296/81 472/297/85 478/300/89
+f 471/282/83 470/294/79 477/295/90
+f 469/282/70 467/297/84 473/300/88
+f 472/297/85 471/282/83 478/300/89
+f 484/301/91 483/302/92 490/303/93
+f 473/300/88 474/304/94 480/305/95
+f 474/304/94 478/300/89 480/305/95
+f 477/295/90 476/298/86 483/302/92
+f 475/295/80 473/300/88 479/301/96
+f 478/300/89 477/295/90 484/301/91
+f 490/303/93 489/306/97 496/307/98
+f 482/299/87 481/302/99 487/306/100
+f 479/301/96 480/305/95 485/303/101
+f 480/305/95 484/301/91 486/313/106
+f 483/302/92 482/299/87 489/306/97
+f 481/302/99 479/301/96 485/303/101
+f 496/308/98 495/309/102 501/310/103
+f 488/311/104 487/306/100 493/312/105
+f 485/303/101 486/313/106 492/314/107
+f 486/313/106 490/303/93 492/314/107
+f 489/306/97 488/311/104 495/312/102
+f 487/306/100 485/303/101 491/307/108
+f 494/315/109 493/316/105 499/317/110
+f 491/318/108 492/319/107 497/320/111
+f 492/321/107 496/308/98 502/322/112
+f 495/309/102 494/323/109 501/310/103
+f 493/309/105 491/308/108 497/322/111
+f 502/322/112 501/310/103 503/324/11
+f 500/325/119 499/310/110 503/324/11
+f 497/322/111 498/326/114 503/324/11
+f 498/326/114 502/322/112 503/324/11
+f 501/310/103 500/325/119 503/324/11
+f 499/310/110 497/322/111 503/324/11
+f 38/2/1 47/328/1 45/3/1
+f 27/5/2 37/329/2 40/6/2
+f 2/330/3 1/7/3 6/9/3
+f 3/331/4 21/10/4 7/12/4
+f 26/14/5 8/332/5 29/15/1
+f 30/333/6 18/16/6 4/18/6
+f 19/20/7 9/334/7 10/21/7
+f 32/23/8 12/33/14 33/24/9
+f 11/335/10 28/25/10 34/27/10
+f 16/29/12 15/336/12 14/30/12
+f 43/337/3 35/31/3 42/32/13
+f 42/32/13 33/24/9 46/34/15
+f 36/36/4 44/338/4 48/37/4
+f 68/39/4 70/46/16 69/40/16
+f 53/44/17 51/41/6 54/43/17
+f 55/51/18 53/44/17 56/45/18
+f 70/46/16 72/53/19 71/47/19
+f 65/339/3 63/48/17 66/50/3
+f 57/56/4 55/51/18 58/52/4
+f 72/53/19 49/55/6 50/54/6
+f 63/48/17 50/54/6 64/49/17
+f 58/52/4 60/50/20 59/57/20
+f 62/59/19 52/42/6 51/41/6
+f 99/61/1 62/59/19 61/58/19
+f 67/38/4 98/62/21 68/39/4
+f 101/340/22 105/64/22 102/66/22
+f 149/341/23 147/67/23 103/69/23
+f 108/71/24 104/342/24 155/72/24
+f 145/74/25 151/343/25 159/75/25
+f 160/344/26 152/76/26 156/78/27
+f 146/345/12 158/79/12 148/81/12
+f 195/346/22 180/82/22 189/84/22
+f 113/347/26 116/85/27 114/87/26
+f 120/89/12 126/348/12 125/90/11
+f 109/92/24 166/349/24 170/93/24
+f 178/350/28 111/94/28 171/96/28
+f 161/351/22 112/97/22 179/99/22
+f 191/352/12 186/100/12 119/102/12
+f 124/353/26 162/103/26 123/105/27
+f 193/354/28 176/106/28 196/108/28
+f 177/110/24 194/355/24 187/111/24
+f 122/113/25 197/356/25 168/114/25
+f 200/116/25 206/357/25 208/117/25
+f 228/358/11 209/118/12 218/120/12
+f 188/122/29 207/359/29 201/123/29
+f 129/360/23 192/124/23 127/126/23
+f 174/128/29 202/361/29 169/129/29
+f 234/362/26 214/130/26 243/132/26
+f 130/134/25 136/363/25 137/135/25
+f 204/137/25 226/364/25 223/138/25
+f 211/365/23 185/139/23 128/141/23
+f 210/143/25 132/366/25 225/144/25
+f 217/367/26 164/145/26 224/147/27
+f 138/368/30 135/148/30 231/150/30
+f 233/369/30 133/151/30 244/153/30
+f 256/370/22 238/154/22 144/156/22
+f 229/158/25 245/371/25 232/159/25
+f 219/161/12 240/372/12 246/162/12
+f 212/164/24 139/373/24 141/165/24
+f 259/374/23 252/166/23 257/168/23
+f 142/375/23 247/169/23 143/171/23
+f 250/376/26 215/172/26 254/174/26
+f 260/377/11 242/175/12 253/177/11
+f 216/179/24 251/378/24 249/180/24
+f 255/379/22 236/181/22 258/183/22
+f 298/244/44 300/246/46 299/245/45
+f 300/246/46 302/248/48 301/247/47
+f 302/248/48 304/250/50 303/249/49
+f 304/250/50 306/252/52 305/251/51
+f 302/248/48 300/246/46 306/252/52
+f 300/246/46 298/244/44 306/252/52
+f 298/244/44 308/254/54 306/252/52
+f 308/254/54 298/244/44 297/243/43
+f 306/252/52 308/254/54 307/253/53
+f 299/245/45 301/247/47 307/253/53
+f 301/247/47 303/249/49 305/251/51
+f 307/253/53 301/247/47 305/251/51
+f 310/256/44 312/258/46 311/257/45
+f 312/258/46 314/260/48 313/259/47
+f 314/260/48 316/262/50 315/261/49
+f 316/262/50 318/264/52 317/263/51
+f 314/260/48 320/266/54 318/264/52
+f 312/258/46 310/256/44 314/260/48
+f 310/256/44 320/266/54 314/260/48
+f 320/266/54 310/256/44 309/255/43
+f 318/264/52 320/266/54 319/265/53
+f 311/257/45 313/259/47 319/265/53
+f 313/259/47 315/261/49 317/263/51
+f 319/265/53 313/259/47 317/263/51
+f 341/281/69 335/267/55 339/269/57
+f 332/271/59 337/267/73 338/268/60
+f 325/279/66 323/272/61 326/270/63
+f 338/268/60 344/269/78 340/275/65
+f 321/380/56 326/276/63 322/278/64
+f 327/283/71 325/279/66 328/271/67
+f 348/294/79 342/280/68 347/282/70
+f 335/267/55 328/271/67 321/268/56
+f 329/288/74 327/283/71 330/284/72
+f 330/286/72 336/327/77 337/287/73
+f 322/274/64 340/275/65 339/269/57
+f 330/284/72 332/271/59 331/283/75
+f 336/327/77 330/286/72 335/290/55
+f 334/270/58 324/273/62 323/272/61
+f 332/271/59 334/270/58 333/279/76
+f 342/280/68 336/291/77 341/281/69
+f 322/278/64 324/277/62 338/293/60
+f 325/276/66 327/289/71 333/292/76
+f 327/289/71 329/286/74 331/285/75
+f 333/292/76 327/289/71 331/285/75
+f 343/281/82 337/267/73 342/280/68
+f 337/267/73 343/281/82 344/269/78
+f 354/298/86 348/294/79 353/295/80
+f 345/297/84 339/269/57 346/296/81
+f 344/269/78 350/297/85 346/296/81
+f 342/280/68 348/294/79 349/282/83
+f 347/282/70 341/281/69 345/297/84
+f 343/281/82 349/282/83 350/297/85
+f 353/295/80 359/302/99 360/299/87
+f 346/296/81 352/304/94 351/300/88
+f 352/304/94 346/296/81 356/300/89
+f 348/294/79 354/298/86 355/295/90
+f 353/295/80 347/282/70 351/300/88
+f 349/282/83 355/295/90 356/300/89
+f 361/302/92 367/306/97 368/303/93
+f 357/301/96 351/300/88 358/305/95
+f 356/300/89 362/301/91 358/305/95
+f 354/298/86 360/299/87 361/302/92
+f 359/302/99 353/295/80 357/301/96
+f 355/295/90 361/302/92 362/301/91
+f 367/306/97 373/312/102 374/307/98
+f 366/311/104 360/299/87 365/306/100
+f 358/305/95 364/313/106 363/303/101
+f 364/313/106 358/305/95 368/303/93
+f 360/299/87 366/311/104 367/306/97
+f 365/306/100 359/302/99 363/303/101
+f 380/322/112 374/308/98 379/310/103
+f 372/381/109 366/311/104 371/312/105
+f 369/307/108 363/303/101 370/314/107
+f 368/303/93 374/307/98 370/314/107
+f 366/311/104 372/381/109 373/312/102
+f 371/312/105 365/306/100 369/307/108
+f 378/382/113 372/315/109 377/317/110
+f 370/319/107 376/383/114 375/320/111
+f 376/326/114 370/321/107 380/322/112
+f 372/323/109 378/325/113 379/310/103
+f 377/310/110 371/309/105 375/322/111
+f 402/281/69 396/267/55 400/269/57
+f 393/271/59 398/267/73 399/268/60
+f 386/279/66 384/272/61 387/270/63
+f 399/268/60 405/269/78 401/275/115
+f 382/380/56 387/276/63 383/278/64
+f 388/283/71 386/279/66 389/271/67
+f 409/294/79 403/280/68 408/282/70
+f 396/267/55 389/271/67 382/268/56
+f 390/288/74 388/283/71 391/284/72
+f 391/286/72 397/327/77 398/287/73
+f 383/274/64 401/275/115 400/269/57
+f 391/284/72 393/271/59 392/283/75
+f 389/289/67 396/290/55 397/327/77
+f 395/270/58 385/273/62 384/272/61
+f 393/271/59 395/270/58 394/279/76
+f 403/280/68 397/291/77 402/281/69
+f 395/292/58 399/293/60 383/278/64
+f 386/276/66 388/289/71 394/292/76
+f 388/289/71 390/286/74 392/285/75
+f 394/292/76 388/289/71 392/285/75
+f 397/291/77 403/280/68 404/281/82
+f 398/267/73 404/281/82 405/269/78
+f 415/298/86 409/294/79 414/295/116
+f 406/297/84 400/269/57 407/296/81
+f 405/269/78 411/297/85 407/296/81
+f 403/280/68 409/294/79 410/282/83
+f 408/282/70 402/281/69 406/297/84
+f 404/281/82 410/282/83 411/297/85
+f 421/299/87 415/298/86 420/302/99
+f 407/296/81 413/304/94 412/300/88
+f 413/304/94 407/296/81 417/300/89
+f 409/294/79 415/298/86 416/295/90
+f 414/295/116 408/282/70 412/300/88
+f 410/282/83 416/295/90 417/300/89
+f 422/302/92 428/306/97 429/303/93
+f 418/301/96 412/300/88 419/305/95
+f 419/305/95 413/304/94 423/301/91
+f 415/298/86 421/299/87 422/302/92
+f 420/302/99 414/295/116 418/301/96
+f 416/295/90 422/302/92 423/301/91
+f 428/306/97 434/312/102 435/307/98
+f 427/311/104 421/299/87 426/306/100
+f 424/303/101 418/301/96 425/313/106
+f 423/301/91 429/303/93 425/313/106
+f 421/299/87 427/311/104 428/306/97
+f 426/306/100 420/302/99 424/303/101
+f 441/322/112 435/308/98 440/310/103
+f 433/381/109 427/311/104 432/312/105
+f 430/307/108 424/303/101 431/314/107
+f 429/303/93 435/307/98 431/314/107
+f 427/311/104 433/381/109 434/312/102
+f 432/312/105 426/306/100 430/307/108
+f 439/382/113 433/315/109 438/317/110
+f 431/319/107 437/383/114 436/320/111
+f 437/326/114 431/321/107 441/322/112
+f 433/323/109 439/325/113 440/310/103
+f 438/310/110 432/309/105 436/322/111
+f 463/281/118 457/267/55 461/269/117
+f 454/271/59 459/267/73 460/268/60
+f 447/279/66 445/272/61 448/270/63
+f 460/268/60 466/269/78 462/275/65
+f 443/380/56 448/276/63 444/278/64
+f 449/283/71 447/279/66 450/271/67
+f 470/294/79 464/280/68 469/282/70
+f 457/267/55 450/271/67 443/268/56
+f 451/288/74 449/283/71 452/284/72
+f 452/286/72 458/327/77 459/287/73
+f 444/274/64 462/275/65 461/269/117
+f 452/284/72 454/271/59 453/283/75
+f 450/289/67 457/290/55 458/327/77
+f 456/270/58 446/273/62 445/272/61
+f 454/271/59 456/270/58 455/279/76
+f 464/280/68 458/291/77 463/281/118
+f 456/292/58 460/293/60 444/278/64
+f 447/276/66 449/289/71 455/292/76
+f 449/289/71 451/286/74 453/285/75
+f 455/292/76 449/289/71 453/285/75
+f 465/281/82 459/267/73 464/280/68
+f 459/267/73 465/281/82 466/269/78
+f 476/298/86 470/294/79 475/295/80
+f 467/297/84 461/269/117 468/296/81
+f 466/269/78 472/297/85 468/296/81
+f 464/280/68 470/294/79 471/282/83
+f 469/282/70 463/281/118 467/297/84
+f 465/281/82 471/282/83 472/297/85
+f 475/295/80 481/302/99 482/299/87
+f 468/296/81 474/304/94 473/300/88
+f 474/304/94 468/296/81 478/300/89
+f 470/294/79 476/298/86 477/295/90
+f 475/295/80 469/282/70 473/300/88
+f 471/282/83 477/295/90 478/300/89
+f 483/302/92 489/306/97 490/303/93
+f 479/301/96 473/300/88 480/305/95
+f 478/300/89 484/301/91 480/305/95
+f 476/298/86 482/299/87 483/302/92
+f 481/302/99 475/295/80 479/301/96
+f 477/295/90 483/302/92 484/301/91
+f 489/306/97 495/312/102 496/307/98
+f 488/311/104 482/299/87 487/306/100
+f 480/305/95 486/313/106 485/303/101
+f 484/301/91 490/303/93 486/313/106
+f 482/299/87 488/311/104 489/306/97
+f 487/306/100 481/302/99 485/303/101
+f 502/322/112 496/308/98 501/310/103
+f 494/381/109 488/311/104 493/312/105
+f 491/307/108 485/303/101 492/314/107
+f 490/303/93 496/307/98 492/314/107
+f 488/311/104 494/381/109 495/312/102
+f 493/312/105 487/306/100 491/307/108
+f 500/382/119 494/315/109 499/317/110
+f 492/319/107 498/383/114 497/320/111
+f 498/326/114 492/321/107 502/322/112
+f 494/323/109 500/325/119 501/310/103
+f 499/310/110 493/309/105 497/322/111
+f 504/384/3 80/385/120 76/386/121
+f 78/387/122 79/388/123 74/389/124
+f 80/385/120 77/390/125 73/391/126
+f 77/390/125 78/387/122 73/391/126
+f 77/390/125 80/385/120 84/392/127
+f 81/393/128 84/392/127 88/394/129
+f 80/385/120 504/384/3 506/395/3
+f 79/388/123 78/387/122 83/396/130
+f 78/387/122 77/390/125 81/393/128
+f 85/397/131 88/394/129 92/398/132
+f 82/399/133 81/393/128 85/397/131
+f 83/396/130 82/399/133 87/400/134
+f 84/392/127 506/395/3 507/401/135
+f 89/402/136 92/398/132 93/403/137
+f 87/400/134 86/404/138 91/405/139
+f 88/394/129 507/401/135 92/398/132
+f 86/404/138 85/397/131 90/406/140
+f 96/407/141 95/408/142 93/403/137
+f 90/406/140 89/402/136 94/409/143
+f 91/405/139 90/406/140 94/409/143
+f 92/398/132 508/410/3 96/407/141
+f 75/411/3 504/384/3 76/386/121
+f 79/388/123 505/412/6 74/389/124
+f 76/386/121 80/385/120 73/391/126
+f 78/387/122 74/389/124 73/391/126
+f 81/393/128 77/390/125 84/392/127
+f 85/397/131 81/393/128 88/394/129
+f 84/392/127 80/385/120 506/395/3
+f 78/387/122 82/399/133 83/396/130
+f 82/399/133 78/387/122 81/393/128
+f 89/402/136 85/397/131 92/398/132
+f 86/404/138 82/399/133 85/397/131
+f 82/399/133 86/404/138 87/400/134
+f 88/394/129 84/392/127 507/401/135
+f 92/398/132 96/407/141 93/403/137
+f 86/404/138 90/406/140 91/405/139
+f 507/401/135 508/410/3 92/398/132
+f 85/397/131 89/402/136 90/406/140
+f 95/408/142 94/409/143 93/403/137
+f 89/402/136 93/403/137 94/409/143
+f 509/413/144 91/405/139 94/409/143
+f 508/410/3 95/408/142 96/407/141
diff --git a/07-july/resources/textures/blendmap.png b/07-july/resources/textures/blendmap.png
new file mode 100644
index 0000000..4789845
--- /dev/null
+++ b/07-july/resources/textures/blendmap.png
Binary files differ
diff --git a/07-july/resources/textures/gato.png b/07-july/resources/textures/gato.png
new file mode 100644
index 0000000..fc5c762
--- /dev/null
+++ b/07-july/resources/textures/gato.png
Binary files differ
diff --git a/07-july/resources/textures/heightmap.png b/07-july/resources/textures/heightmap.png
new file mode 100644
index 0000000..12741e5
--- /dev/null
+++ b/07-july/resources/textures/heightmap.png
Binary files differ
diff --git a/07-july/resources/textures/soil1.png b/07-july/resources/textures/soil1.png
new file mode 100644
index 0000000..227e96c
--- /dev/null
+++ b/07-july/resources/textures/soil1.png
Binary files differ
diff --git a/07-july/resources/textures/soil2.png b/07-july/resources/textures/soil2.png
new file mode 100644
index 0000000..5fc40e2
--- /dev/null
+++ b/07-july/resources/textures/soil2.png
Binary files differ
diff --git a/07-july/resources/textures/soil3.png b/07-july/resources/textures/soil3.png
new file mode 100644
index 0000000..2c1c431
--- /dev/null
+++ b/07-july/resources/textures/soil3.png
Binary files differ
diff --git a/07-july/resources/textures/soil4.png b/07-july/resources/textures/soil4.png
new file mode 100644
index 0000000..8d3a4d3
--- /dev/null
+++ b/07-july/resources/textures/soil4.png
Binary files differ
diff --git a/07-july/resources/textures/spaceship.png b/07-july/resources/textures/spaceship.png
new file mode 100644
index 0000000..2263cdc
--- /dev/null
+++ b/07-july/resources/textures/spaceship.png
Binary files differ
diff --git a/07-july/resources/textures/stall.png b/07-july/resources/textures/stall.png
new file mode 100644
index 0000000..d4d6f6e
--- /dev/null
+++ b/07-july/resources/textures/stall.png
Binary files differ
diff --git a/07-july/src/camera.c b/07-july/src/camera.c
new file mode 100644
index 0000000..9afadf2
--- /dev/null
+++ b/07-july/src/camera.c
@@ -0,0 +1,85 @@
+#include "camera.h"
+
+#include "util/util_time.h"
+
+static const float movementSpeed = 40.0f;
+
+void Camera_Init(camera_t* camera)
+{
+ camera->position = vec3_create(5.0f, 15.0f, 0.0f);
+ camera->viewDirection = vec3_create(-1.0f, 0.0f, 0.0f);
+ camera->needsUpdate = true;
+ camera->up = vec3_create(0.0f, 1.0f, 0.0f);
+}
+
+void Camera_Move_Up(camera_t* camera)
+{
+ vec3_t temp = vec3_scalar_mul(&camera->up, movementSpeed * Time_GetFrameTime());
+ camera->position = vec3_add(&camera->position, &temp);
+}
+
+void Camera_Move_Down(camera_t* camera)
+{
+ vec3_t temp = vec3_scalar_mul(&camera->up, -movementSpeed * Time_GetFrameTime());
+ camera->position = vec3_add(&camera->position, &temp);
+}
+
+void Camera_Move_Left(camera_t* camera)
+{
+ vec3_t strafeDirection = vec3_cross_mul(&camera->viewDirection, &camera->up);
+ strafeDirection = vec3_scalar_mul(&strafeDirection, -movementSpeed * Time_GetFrameTime());
+ camera->position = vec3_add(&camera->position, &strafeDirection);
+}
+
+void Camera_Move_Right(camera_t* camera)
+{
+ vec3_t strafeDirection = vec3_cross_mul(&camera->viewDirection, &camera->up);
+ strafeDirection = vec3_scalar_mul(&strafeDirection, movementSpeed * Time_GetFrameTime());
+ camera->position = vec3_add(&camera->position, &strafeDirection);
+}
+
+void Camera_Move_Foward(camera_t* camera)
+{
+ vec3_t temp = vec3_scalar_mul(&camera->viewDirection, movementSpeed * Time_GetFrameTime());
+ camera->position = vec3_add(&camera->position, &temp);
+}
+
+void Camera_Move_Backward(camera_t* camera)
+{
+ vec3_t temp = vec3_scalar_mul(&camera->viewDirection, -movementSpeed * Time_GetFrameTime());
+ camera->position = vec3_add(&camera->position, &temp);
+}
+
+void Camera_MouseUpdate(camera_t* camera, const vec2_t* newMousePosition)
+{
+ vec2_t mouseDelta = vec2_sub(newMousePosition, &camera->mousePosition);
+
+ //El if evita que el mouse se teletrasporte al cambiar de posicion muy rapido
+ if(vec2_length(&mouseDelta) > 50.0f){
+ camera->mousePosition = *newMousePosition;
+ return;
+ }
+
+ vec3_t verticalRotation = vec3_cross_mul(&camera->viewDirection, &camera->up);
+
+ mat4_t temp = mat4_rotate(mouseDelta.x * -0.5f, &camera->up);
+
+ camera->viewDirection = mat4_mul_vec3(&temp, &camera->viewDirection);
+
+ temp = mat4_rotate(mouseDelta.y * -0.5f, &verticalRotation);
+ camera->viewDirection = mat4_mul_vec3(&temp, &camera->viewDirection);
+
+ camera->mousePosition = *newMousePosition;
+
+ camera->needsUpdate = true;
+}
+
+mat4_t Camera_GetModelToViewMatrix(camera_t* camera)
+{
+ if(camera->needsUpdate)
+ {
+ vec3_t temp = vec3_add(&camera->position, &camera->viewDirection);
+ camera->viewMatrix = mat4_lookAt(&camera->position, &temp, &camera->up);
+ }
+ return camera->viewMatrix;
+}
diff --git a/07-july/src/camera.h b/07-july/src/camera.h
new file mode 100644
index 0000000..4254045
--- /dev/null
+++ b/07-july/src/camera.h
@@ -0,0 +1,32 @@
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#include "math/matrix4x4.h"
+#include "math/vector3f.h"
+#include "math/vector2f.h"
+#include <stdbool.h>
+
+typedef struct
+{
+ vec3_t position;
+ vec3_t viewDirection;
+ vec3_t up;
+ mat4_t projectionMatrix;
+ mat4_t viewMatrix;
+ vec2_t mousePosition;
+ bool needsUpdate;
+} camera_t;
+
+extern void Camera_Init(camera_t* camera);
+extern void Camera_Move_Up(camera_t* camera);
+extern void Camera_Move_Down(camera_t* camera);
+extern void Camera_Move_Left(camera_t* camera);
+extern void Camera_Move_Right(camera_t* camera);
+extern void Camera_Move_Foward(camera_t* camera);
+extern void Camera_Move_Backward(camera_t* camera);
+extern void Camera_MouseUpdate(camera_t* camera, const vec2_t* newMousePosition);
+
+//Consigue la viewMatrix
+extern mat4_t Camera_GetModelToViewMatrix(camera_t* camera);
+
+#endif // CAMERA_H
diff --git a/07-july/src/game.h b/07-july/src/game.h
new file mode 100644
index 0000000..8ba77ed
--- /dev/null
+++ b/07-july/src/game.h
@@ -0,0 +1,42 @@
+#ifndef GAME_H
+#define GAME_H
+
+#include "camera.h"
+#include "graphics/window.h"
+#include "renderer/entity.h"
+#include "player.h"
+#include "terrain.h"
+#include "texture.h"
+#include "renderer/shape.h"
+#include "graphics/shaders.h"
+
+typedef enum
+{
+ MENU,
+ RUNNING,
+ EXIT
+}GameState_t;
+
+#define NUM_ENTITIES 1
+
+#define WINDOW_WIDTH 1024
+#define WINDOW_HEIGHT 768
+#define WINDOW_ASPECT_RATIO ( (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT )
+
+typedef struct
+{
+ GameState_t gameState;
+ Shader_Layout shaderProgram, terrainProgram;
+
+ entity_t ents[NUM_ENTITIES];
+ shape_t *entsShape;
+ texture_t *entsTexture;
+ terrain_t *terrain;
+
+ player_t player;
+
+ camera_t camera;
+ window_t *window;
+} game_t;
+
+#endif // GAME_H
diff --git a/07-july/src/graphics/shaders.c b/07-july/src/graphics/shaders.c
new file mode 100644
index 0000000..ef4ec0a
--- /dev/null
+++ b/07-july/src/graphics/shaders.c
@@ -0,0 +1,134 @@
+#include "shaders.h"
+#include "../util/util.h"
+
+#include <stdlib.h>
+
+static void CompileShader(const char* source, GLuint shaderID)
+{
+ glShaderSource(shaderID, 1, &source, 0);
+ glCompileShader(shaderID);
+ GLint error;
+ glGetShaderiv(shaderID, GL_COMPILE_STATUS, &error);
+ if(error != GL_TRUE)
+ {
+ GLint logLenth;
+ glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLenth);
+ GLchar buffer[logLenth];
+ glGetShaderInfoLog(shaderID, logLenth, &logLenth, buffer);
+ glDeleteShader(shaderID);
+ Util_FatalError(buffer);
+ }
+}
+
+
+GLuint Shader_CompileShaders(const char* vertexShader, const char* fragmentShader)
+{
+ char* vertexShaderSource = Util_LoadFile(vertexShader);
+ char* fragmentShaderSource = Util_LoadFile(fragmentShader);
+
+ GLuint vs = 0, fs = 0, program;
+ vs = glCreateShader(GL_VERTEX_SHADER);
+ fs = glCreateShader(GL_FRAGMENT_SHADER);
+
+ if(vs == 0 || fs == 0)
+ Util_FatalError("Shaders could not be created\n");
+
+ program = glCreateProgram();
+
+ CompileShader(vertexShaderSource, vs);
+ CompileShader(fragmentShaderSource, fs);
+
+ glAttachShader(program, vs);
+ glAttachShader(program, fs);
+
+ glLinkProgram(program);
+
+ GLint error;
+ glGetProgramiv(program, GL_LINK_STATUS, &error);
+
+ if(error != GL_TRUE)
+ {
+ GLint logLength;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);
+
+ GLchar buffer[logLength];
+ glGetProgramInfoLog(program, logLength, &logLength, buffer);
+
+ glDeleteProgram(program);
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+
+ Util_FatalError(buffer);
+ }
+
+ glDetachShader(program, vs);
+ glDetachShader(program, fs);
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+
+ free(vertexShaderSource);
+ free(fragmentShaderSource);
+
+ return program;
+}
+
+GLint Shader_GetUniformLocation( GLuint programID, const char* uniformName )
+{
+ GLint u = glGetUniformLocation(programID, uniformName);
+ if(u == GL_INVALID_INDEX)
+ Util_FatalError("Uniform variable could not be found!");
+ else
+ return u;
+
+ return 0;
+}
+
+GLint Shader_GetAttribLocation ( GLuint programID, const char* attributeName )
+{
+ GLint attrLocation = glGetAttribLocation(programID, attributeName);
+ if(attrLocation < 0)
+ Util_FatalError("Attribute could not be found\n");
+ return attrLocation;
+}
+
+void Shader_Destroy(GLuint programID)
+{
+ glUseProgram(0);
+ glDeleteProgram(programID);
+}
+
+void Shader_SetUniformMat4( GLuint programID, const char* name, const float *matrix )
+{
+ GLint location = Shader_GetUniformLocation(programID, name);
+ glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
+}
+
+void Shader_SetUniformFloat( GLuint programID, const char* name, const float val )
+{
+ GLint location = Shader_GetUniformLocation(programID, name);
+ glUniform1f(location, val);
+}
+
+void Shader_SetUniformVec2( GLuint programID, const char* name, const float vec[2] )
+{
+ GLint location = Shader_GetUniformLocation(programID, name);
+ glUniform2fv(location, 1, vec);
+}
+
+void Shader_SetUniformVec3( GLuint programID, const char* name, const float vec[3] )
+{
+ GLint location = Shader_GetUniformLocation(programID, name);
+ glUniform3fv(location, 1, vec);
+}
+
+void Shader_SetUniformVec4( GLuint programID, const char* name, const float vec[4] )
+{
+ GLint location = Shader_GetUniformLocation(programID, name);
+ glUniform4fv(location, 1, vec);
+}
+
+void Shader_SetUniformInt( GLuint programID, const char* name, const int val )
+{
+ GLint location = Shader_GetUniformLocation(programID, name);
+ glUniform1i(location, val);
+}
diff --git a/07-july/src/graphics/shaders.h b/07-july/src/graphics/shaders.h
new file mode 100644
index 0000000..9e0bbab
--- /dev/null
+++ b/07-july/src/graphics/shaders.h
@@ -0,0 +1,46 @@
+#ifndef SHADERS_H
+#define SHADERS_H
+
+#include <GL/glew.h>
+
+#include "../math/matrix4x4.h"
+
+typedef struct
+{
+ GLuint ID;
+
+ GLint position;
+ GLint color;
+ GLint uv;
+ GLint normal;
+
+ GLint totalTransform;
+ GLint modelToWorld;
+ GLint lightPosition;
+ GLint ambientLight;
+ GLint lightColor;
+ GLint lightAttenuation;
+ GLint World_eyePosition;
+ GLint Texture;
+
+ GLint Texture_Background;
+ GLint Texture_R;
+ GLint Texture_G;
+ GLint Texture_B;
+ GLint Texture_BlendMap;
+
+} Shader_Layout;
+
+extern GLuint Shader_CompileShaders(const char* vertexShader, const char* fragmentShader);
+extern GLint Shader_GetUniformLocation( GLuint programID, const char* uniformName );
+extern GLint Shader_GetAttribLocation ( GLuint programID, const char* attributeName );
+extern void Shader_Destroy(GLuint programID);
+
+extern void Shader_SetUniformMat4( GLuint programID, const char* name, const float *matrix );
+extern void Shader_SetUniformFloat( GLuint programID, const char* name, const float val );
+extern void Shader_SetUniformVec2( GLuint programID, const char* name, const float vec[2] );
+extern void Shader_SetUniformVec3( GLuint programID, const char* name, const float vec[3] );
+extern void Shader_SetUniformVec4( GLuint programID, const char* name, const float vec[4] );
+extern void Shader_SetUniformInt( GLuint programID, const char* name, const int val );
+
+#endif // SHADERS_H
diff --git a/07-july/src/graphics/video.c b/07-july/src/graphics/video.c
new file mode 100644
index 0000000..4b9b084
--- /dev/null
+++ b/07-july/src/graphics/video.c
@@ -0,0 +1,14 @@
+#include "video.h"
+
+#include <SDL2/SDL.h>
+#include <GL/glew.h>
+
+void Video_Init()
+{
+
+}
+
+void Video_Shutdown()
+{
+
+}
diff --git a/07-july/src/graphics/video.h b/07-july/src/graphics/video.h
new file mode 100644
index 0000000..db23a45
--- /dev/null
+++ b/07-july/src/graphics/video.h
@@ -0,0 +1,7 @@
+#ifndef VIDEO_H
+#define VIDEO_H
+
+extern void Video_Init(void);
+extern void Video_Shutdown(void);
+
+#endif // VIDEO_H_INCLUDED
diff --git a/07-july/src/graphics/window.c b/07-july/src/graphics/window.c
new file mode 100644
index 0000000..9afb27a
--- /dev/null
+++ b/07-july/src/graphics/window.c
@@ -0,0 +1,44 @@
+#include "window.h"
+#include "../util/util.h"
+#include <stdlib.h>
+
+window_t* Window_Create(const char* title, Uint32 width, Uint32 height)
+{
+ window_t* window = (window_t*) malloc(sizeof(window_t));
+ window->title = title;
+ window->Width = width;
+ window->Height = height;
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ window->window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+ width, height, SDL_WINDOW_OPENGL);
+ if(window->window == NULL)
+ Util_FatalError( SDL_GetError() );
+
+ window->context = SDL_GL_CreateContext(window->window);
+
+ if(window->context == NULL)
+ Util_FatalError( SDL_GetError() );
+
+ glViewport(0, 0, width, height);
+ return window;
+}
+
+void Window_Resize(window_t* window, Uint32 width, Uint32 height)
+{
+ window->Width = width;
+ window->Height = height;
+ SDL_SetWindowSize(window->window, width, height);
+ glViewport(0, 0, width, height);
+}
+
+void Window_Update(window_t* window)
+{
+ SDL_GL_SwapWindow(window->window);
+}
+
+void Window_Destroy(window_t* window)
+{
+ SDL_GL_DeleteContext(window->context);
+ SDL_DestroyWindow(window->window);
+ free(window);
+}
diff --git a/07-july/src/graphics/window.h b/07-july/src/graphics/window.h
new file mode 100644
index 0000000..1e71a83
--- /dev/null
+++ b/07-july/src/graphics/window.h
@@ -0,0 +1,20 @@
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <SDL2/SDL.h>
+#include <GL/glew.h>
+
+typedef struct
+{
+ SDL_Window* window;
+ SDL_GLContext context;
+ Uint32 Width, Height;
+ const char* title;
+} window_t;
+
+extern window_t* Window_Create(const char* title, Uint32 width, Uint32 height);
+extern void Window_Resize(window_t* window, Uint32 width, Uint32 height);
+extern void Window_Update(window_t* window);
+extern void Window_Destroy(window_t* window);
+
+#endif // WINDOW_H
diff --git a/07-july/src/gui/gui_renderer.c b/07-july/src/gui/gui_renderer.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/07-july/src/gui/gui_renderer.c
diff --git a/07-july/src/gui/gui_renderer.h b/07-july/src/gui/gui_renderer.h
new file mode 100644
index 0000000..2c1b57f
--- /dev/null
+++ b/07-july/src/gui/gui_renderer.h
@@ -0,0 +1,9 @@
+#ifndef GUI_RENDERER_H
+#define GUI_RENDERER_H
+
+extern void gui_renderer_init();
+extern void gui_renderer_submit(widget *widget);
+extern void gui_renderer_quit();
+
+
+#endif // GUI_RENDERER_H
diff --git a/07-july/src/gui/widget.c b/07-july/src/gui/widget.c
new file mode 100644
index 0000000..9ed00f7
--- /dev/null
+++ b/07-july/src/gui/widget.c
@@ -0,0 +1,17 @@
+#include "widget.h"
+#include <stdlib.h>
+
+widget_t *Widget_CreateImage(texture_t *texture, int x, int y, int w, int h)
+{
+ widget_t *widget = (widget_t *) malloc( sizeof(widget_t) );
+ *widget = (widget_t){ x, y, w, h, 0, texture };
+
+ glGenBuffers(1, &widget->vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, widget->vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 4, NULL, GL_DYNAMIC_DRAW);
+}
+
+void Widget_Destroy(widget_t *widget)
+{
+ free(widget);
+}
diff --git a/07-july/src/gui/widget.h b/07-july/src/gui/widget.h
new file mode 100644
index 0000000..91fc4c4
--- /dev/null
+++ b/07-july/src/gui/widget.h
@@ -0,0 +1,13 @@
+#ifndef WIDGET_H
+#define WIDGET_H
+
+#include "GL/glew.h"
+#include "../texture.h"
+
+typedef struct
+{
+ int x, y, w, h;
+ texture_t *texture;
+} widget_t;
+
+#endif // WIDGET_H
diff --git a/07-july/src/input.c b/07-july/src/input.c
new file mode 100644
index 0000000..8384ceb
--- /dev/null
+++ b/07-july/src/input.c
@@ -0,0 +1,21 @@
+#include "input.h"
+
+static bool key_buffer[MAX_KEY_BUFFER_SIZE] = { false };
+
+void Input_PressKey(unsigned int key)
+{
+ if(key > 256 || key < 0) return;
+ key_buffer[key] = true;
+}
+
+void Input_ReleaseKey(unsigned int key)
+{
+ if(key > 256 || key < 0) return;
+ key_buffer[key] = false;
+}
+
+bool Input_isKeyPressed(unsigned int key)
+{
+ if(key > 256 || key < 0) return false;
+ return key_buffer[key];
+}
diff --git a/07-july/src/input.h b/07-july/src/input.h
new file mode 100644
index 0000000..92876ca
--- /dev/null
+++ b/07-july/src/input.h
@@ -0,0 +1,11 @@
+#ifndef INPUT_H
+#define INPUT_H
+
+#include <stdbool.h>
+#define MAX_KEY_BUFFER_SIZE 256
+
+void Input_PressKey(unsigned int key);
+void Input_ReleaseKey(unsigned int key);
+bool Input_isKeyPressed(unsigned int key);
+
+#endif // INPUT_H
diff --git a/07-july/src/light.c b/07-july/src/light.c
new file mode 100644
index 0000000..decd182
--- /dev/null
+++ b/07-july/src/light.c
@@ -0,0 +1 @@
+#include "light.h"
diff --git a/07-july/src/light.h b/07-july/src/light.h
new file mode 100644
index 0000000..6b6da0a
--- /dev/null
+++ b/07-july/src/light.h
@@ -0,0 +1,13 @@
+#ifndef LIGHT_H
+#define LIGHT_H
+
+#include "vertex.h"
+
+typedef struct
+{
+ vec3_t position;
+ color_t color;
+ vec3_t attenuation;
+} light_t;
+
+#endif // LIGHT_H
diff --git a/07-july/src/main.c b/07-july/src/main.c
new file mode 100644
index 0000000..d119764
--- /dev/null
+++ b/07-july/src/main.c
@@ -0,0 +1,227 @@
+#include "game.h"
+#include "math/vector3f.h"
+#include "math/vector2f.h"
+#include "math/matrix4x4.h"
+#include "input.h"
+#include "util/util.h"
+#include "util/util_time.h"
+#include "light.h"
+#include "renderer/renderer.h"
+
+/*
+ TODO: Shadows
+ Texture Atlases
+
+ improve math package
+ repair gui on renderer.c
+*/
+
+void LoadResources(game_t* game);
+void Draw(game_t* game);
+void ProcessInput(game_t* game);
+void CleanUp(game_t* game);
+
+int main(int args, char* argv[])
+{
+ SDL_Init(SDL_INIT_EVERYTHING);
+
+ game_t game;
+ game.gameState = RUNNING;
+ game.window = Window_Create("Test", WINDOW_WIDTH, WINDOW_HEIGHT);
+
+ if(glewInit() != GLEW_OK)
+ Util_FatalError("Glew could no be started!");
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ SDL_GL_SetSwapInterval(0);
+ //glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+
+ game.shaderProgram.ID = Shader_CompileShaders("resources/shaders/shader.vert",
+ "resources/shaders/shader.frag");
+
+ game.terrainProgram.ID = Shader_CompileShaders("resources/shaders/terrainShader.vert",
+ "resources/shaders/terrainShader.frag");
+ glUseProgram(game.shaderProgram.ID);
+
+ Camera_Init(&game.camera);
+
+ LoadResources(&game);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ Time_Init();
+ Time_SetMaxFramesPerSecond(6000);
+ while(game.gameState != EXIT)
+ {
+ Time_Begin();
+ ProcessInput(&game);
+ Player_Update(&game.player, game.terrain);
+ Draw(&game);
+
+ float FPS = Time_End();
+
+ if( !( Time_GetCountedFrames() % (int)FPS ) ) {
+ fprintf(stderr, "FPS: %.4f\n", FPS);
+ }
+ }
+
+ Window_Destroy(game.window);
+ CleanUp(&game);
+ SDL_Quit();
+ return 0;
+}
+
+void CleanUp(game_t* game)
+{
+ Shape_Free(game->entsShape);
+ Texture_Destroy(game->entsTexture);
+ Terrain_Destroy(game->terrain);
+
+ Shader_Destroy(game->shaderProgram.ID);
+ Shader_Destroy(game->terrainProgram.ID);
+ Render_Quit();
+}
+
+void LoadResources(game_t* game)
+{
+ Render_Init();
+ Uint32 start = SDL_GetTicks();
+
+ game->entsShape = Shape_MakeCube();
+ game->entsTexture = Texture_Create("resources/textures/gato.png");
+
+ Player_Init(&game->player);
+ game->player.entity.texture = game->entsTexture;
+ game->player.entity.shape = game->entsShape;
+
+ {
+ vec3_t position = { 0.0f, 3.0f, 0.0f };
+ float rotation[3] = { 0.0f, 45.0f, 45.0f };
+ game->ents[0].position = position;
+ game->ents[0].rotX = rotation[0];
+ game->ents[0].rotY = rotation[1];
+ game->ents[0].rotZ = rotation[2];
+ game->ents[0].shape = game->entsShape;
+ game->ents[0].texture = game->entsTexture;
+ }
+
+ {
+ vec3_t position = { -400.0f, 0.0f, -400.0f };
+ texture_t *blendmap = Texture_Create("resources/textures/blendmap.png");
+ TerrainTexturePack pack =
+ {
+ {
+ Texture_Create("resources/textures/soil1.png"),
+ Texture_Create("resources/textures/soil2.png"),
+ Texture_Create("resources/textures/soil4.png"),
+ Texture_Create("resources/textures/soil3.png"),
+ }
+ };
+ game->terrain = Terrain_Create(800, 800, "resources/textures/heightmap.png", blendmap, &pack);
+ game->terrain->position = position;
+ }
+
+ /* Shader Layouts */
+
+ game->shaderProgram.Texture = Shader_GetUniformLocation(game->shaderProgram.ID, "Texture");
+ game->shaderProgram.modelToWorld = Shader_GetUniformLocation(game->shaderProgram.ID, "Matrix_modelToWorld");
+ game->shaderProgram.totalTransform = Shader_GetUniformLocation(game->shaderProgram.ID, "Matrix_totalTransform");
+ game->shaderProgram.lightPosition = Shader_GetUniformLocation(game->shaderProgram.ID, "lightPosition");
+ game->shaderProgram.lightColor = Shader_GetUniformLocation(game->shaderProgram.ID, "lightColor");
+ game->shaderProgram.lightAttenuation = Shader_GetUniformLocation(game->shaderProgram.ID, "attenuation");
+
+ game->terrainProgram.modelToWorld = Shader_GetUniformLocation(game->terrainProgram.ID, "Matrix_modelToWorld");
+ game->terrainProgram.totalTransform = Shader_GetUniformLocation(game->terrainProgram.ID, "Matrix_totalTransform");
+ game->terrainProgram.lightPosition = Shader_GetUniformLocation(game->terrainProgram.ID, "lightPosition");
+ game->terrainProgram.lightColor = Shader_GetUniformLocation(game->terrainProgram.ID, "lightColor");
+ game->terrainProgram.lightAttenuation = Shader_GetUniformLocation(game->terrainProgram.ID, "attenuation");
+
+ game->terrainProgram.Texture_Background = Shader_GetUniformLocation(game->terrainProgram.ID, "Texture_Background");
+ game->terrainProgram.Texture_BlendMap = Shader_GetUniformLocation(game->terrainProgram.ID, "Texture_BlendMap");
+ game->terrainProgram.Texture_R = Shader_GetUniformLocation(game->terrainProgram.ID, "Texture_R");
+ game->terrainProgram.Texture_G = Shader_GetUniformLocation(game->terrainProgram.ID, "Texture_G");
+ game->terrainProgram.Texture_B = Shader_GetUniformLocation(game->terrainProgram.ID, "Texture_B");
+
+ fprintf(stderr, "Loading time: %u (ms)\n", SDL_GetTicks() - start);
+}
+
+void Draw(game_t* game)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /*We upload all the light vectors*/
+ static light_t diffuseLight[4] =
+ {
+ { {0.0f, 20.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 0.01f, 0.002f} },
+ { {10.0f, 20.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 0.01f, 0.002f} },
+ { {20.0f, 20.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 1.0f}, {1.0f, 0.01f, 0.002f} },
+ { {30.0f, 20.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.01f, 0.002f} },
+ };
+
+ Shader_SetUniformVec3(game->shaderProgram.ID, "World_eyePosition", (float*)&game->camera.position);
+ Render_LoadLights(&game->shaderProgram, diffuseLight, 4);
+
+ mat4_t viewMatrix, projectionMatrix, projectedViewMatrix;
+
+ viewMatrix = Camera_GetModelToViewMatrix(&game->camera);
+ projectionMatrix = mat4_perspective(60.0f, WINDOW_ASPECT_RATIO, 0.1f, 300.0f);
+ projectedViewMatrix = mat4_mul(&projectionMatrix, &viewMatrix);
+
+ Render_DrawEntity(&game->shaderProgram, &projectedViewMatrix, &game->player.entity);
+ Render_DrawEntity(&game->shaderProgram, &projectedViewMatrix, &game->ents[0]);
+
+ glUseProgram(game->terrainProgram.ID);
+
+ Shader_SetUniformVec3(game->terrainProgram.ID, "World_eyePosition", (float*)&game->camera.position);
+ Render_LoadLights(&game->terrainProgram, diffuseLight, 4);
+
+ Render_DrawTerrain(&game->terrainProgram, &projectedViewMatrix, game->terrain);
+
+ glUseProgram(game->shaderProgram.ID);
+
+ Window_Update(game->window);
+}
+
+void ProcessInput(game_t* game)
+{
+ vec2_t mousePosition;
+ SDL_Event e;
+ while(SDL_PollEvent(&e))
+ {
+ switch(e.type)
+ {
+ case SDL_QUIT:
+ game->gameState = EXIT;
+ break;
+
+ case SDL_MOUSEMOTION:
+ mousePosition = vec2_create(e.motion.x, e.motion.y);
+ Camera_MouseUpdate(&game->camera, &mousePosition);
+ break;
+
+ case SDL_KEYDOWN:
+ Input_PressKey(e.key.keysym.scancode);
+ break;
+
+ case SDL_KEYUP:
+ Input_ReleaseKey(e.key.keysym.scancode);
+ break;
+ }
+
+ if(Input_isKeyPressed(SDL_SCANCODE_UP))
+ Camera_Move_Foward(&game->camera);
+
+ if(Input_isKeyPressed(SDL_SCANCODE_DOWN))
+ Camera_Move_Backward(&game->camera);
+
+ if(Input_isKeyPressed(SDL_SCANCODE_LEFT))
+ Camera_Move_Left(&game->camera);
+
+ if(Input_isKeyPressed(SDL_SCANCODE_RIGHT))
+ Camera_Move_Right(&game->camera);
+
+ if(Input_isKeyPressed(SDL_SCANCODE_ESCAPE))
+ game->gameState = EXIT;
+ }
+}
diff --git a/07-july/src/math/math_util.c b/07-july/src/math/math_util.c
new file mode 100644
index 0000000..f58e447
--- /dev/null
+++ b/07-july/src/math/math_util.c
@@ -0,0 +1,10 @@
+#include "math_util.h"
+
+float baryCentric(vec3_t *p1, vec3_t *p2, vec3_t *p3, vec2_t *pos)
+{
+ float det = (p2->z - p3->z) * (p1->x - p3->x) + (p3->x - p2->x) * (p1->z - p3->z);
+ float l1 = ((p2->z - p3->z) * (pos->x - p3->x) + (p3->x - p2->x) * (pos->y - p3->z)) / det;
+ float l2 = ((p3->z - p1->z) * (pos->x - p3->x) + (p1->x - p3->x) * (pos->y - p3->z)) / det;
+ float l3 = 1.0f - l1 - l2;
+ return l1 * p1->y + l2 * p2->y + l3 * p3->y;
+}
diff --git a/07-july/src/math/math_util.h b/07-july/src/math/math_util.h
new file mode 100644
index 0000000..28a5464
--- /dev/null
+++ b/07-july/src/math/math_util.h
@@ -0,0 +1,9 @@
+#ifndef MATH_UTIL_H
+#define MATH_UTIL_H
+
+#include "vector3f.h"
+#include "vector2f.h"
+
+extern float baryCentric(vec3_t *p1, vec3_t *p2, vec3_t *p3, vec2_t *pos);
+
+#endif // MATH_UTIL_H
diff --git a/07-july/src/math/matrix4x4.c b/07-july/src/math/matrix4x4.c
new file mode 100644
index 0000000..c46895a
--- /dev/null
+++ b/07-july/src/math/matrix4x4.c
@@ -0,0 +1,180 @@
+#include "matrix4x4.h"
+#include "../util/util.h"
+#include <SDL2/SDL.h>
+
+void mat4_identity(mat4_t *a)
+{
+ int i;
+ for(i = 0; i < 4*4; i++)
+ {
+ a->data[i] = 0.0f;
+ }
+ a->data[0 + 0 * 4] = 1.0f;
+ a->data[1 + 1 * 4] = 1.0f;
+ a->data[2 + 2 * 4] = 1.0f;
+ a->data[3 + 3 * 4] = 1.0f;
+}
+
+mat4_t mat4_mul(const mat4_t* a, const mat4_t* b)
+{
+ int i, j, k;
+ GLfloat sum = 0.0f;
+ mat4_t c;
+ mat4_identity(&c);
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 4; j++){
+ for(k = 0; k < 4; k++){
+ sum += a->data[i + k * 4] * b->data[k + j * 4];
+ }
+ c.data[i + j * 4] = sum;
+ sum = 0.0f;
+ }
+
+ return c;
+}
+
+mat4_t mat4_translate(const vec3_t *a)
+{
+ mat4_t b;
+ mat4_identity(&b);
+ b.data[0 + 3 * 4] = a->x;
+ b.data[1 + 3 * 4] = a->y;
+ b.data[2 + 3 * 4] = a->z;
+ return b;
+}
+
+mat4_t mat4_scale(GLfloat x, GLfloat y, GLfloat z)
+{
+ mat4_t b;
+ mat4_identity(&b);
+ b.data[0 + 0 * 4] = x;
+ b.data[1 + 1 * 4] = y;
+ b.data[2 + 2 * 4] = z;
+ return b;
+}
+
+mat4_t mat4_rotate(GLfloat degrees, const vec3_t* a)
+{
+ mat4_t b;
+ mat4_identity(&b);
+ GLfloat c = SDL_cosf(toRadians(degrees)), s = SDL_sinf(toRadians(degrees)), o = 1-c;
+ b.data[0 + 0 * 4] = a->x * a->x * o + c;
+ b.data[0 + 1 * 4] = a->x * a->y * o - a->z * s;
+ b.data[0 + 2 * 4] = a->x * a->z * o + a->y * s;
+
+ b.data[1 + 0 * 4] = a->x * a->y * o + a->z * s;
+ b.data[1 + 1 * 4] = a->y * a->y * o + c;
+ b.data[1 + 2 * 4] = a->y * a->z * o - a->x * s;
+
+ b.data[2 + 0 * 4] = a->x * a->z * o - a->y * s;
+ b.data[2 + 1 * 4] = a->y * a->z * o + a->x * s;
+ b.data[2 + 2 * 4] = a->z * a->z * o + c;
+ return b;
+}
+
+mat4_t mat4_rotate_x(GLfloat degrees)
+{
+ mat4_t a;
+ mat4_identity(&a);
+ GLfloat c = SDL_cosf(toRadians(degrees)), s = SDL_sinf(toRadians(degrees));
+ a.data[1 + 1 * 4] = c;
+ a.data[2 + 1 * 4] = s;
+ a.data[1 + 2 * 4] = -s;
+ a.data[2 + 2 * 4] = c;
+ return a;
+}
+
+mat4_t mat4_rotate_y(GLfloat degrees)
+{
+ mat4_t a;
+ mat4_identity(&a);
+ GLfloat c = SDL_cosf(toRadians(degrees)), s = SDL_sinf(toRadians(degrees));
+ a.data[0 + 0 * 4] = c;
+ a.data[2 + 0 * 4] = -s;
+ a.data[0 + 2 * 4] = s;
+ a.data[2 + 2 * 4] = c;
+ return a;
+}
+
+mat4_t mat4_rotate_z(GLfloat degrees)
+{
+ mat4_t a;
+ mat4_identity(&a);
+ GLfloat c = SDL_cosf(toRadians(degrees)), s = SDL_sinf(toRadians(degrees));
+ a.data[0 + 0 * 4] = c;
+ a.data[1 + 0 * 4] = s;
+ a.data[0 + 1 * 4] = -s;
+ a.data[1 + 1 * 4] = c;
+ return a;
+}
+
+mat4_t mat4_perspective(GLfloat fov, GLfloat aspect, GLfloat zNear, GLfloat zFar)
+{
+ mat4_t a;
+ GLubyte i, j;
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 4; j++)
+ a.data[i + j * 4] = 0.0f;
+ fov = toRadians(fov); //To radians
+
+ a.data[0 + 0 * 4] = ( (1.0f / SDL_tanf( fov/2.0f )) / aspect);
+ a.data[1 + 1 * 4] = (1.0f / SDL_tanf( fov/2.0f ));
+ a.data[2 + 2 * 4] = -( (zFar + zNear) / (zFar - zNear) );
+ a.data[2 + 3 * 4] = -( ( 2.0f * zFar * zNear) / (zFar - zNear) );
+ a.data[3 + 2 * 4] = -1.0f;
+
+ return a;
+}
+
+mat4_t
+mat4_orthographic(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top)
+{
+ mat4_t a;
+ mat4_identity(&a);
+ a.data[0 + 0 * 4] = 2.0f / (right - left);
+ a.data[1 + 1 * 4] = 2.0f / (top - bottom);
+ a.data[2 + 2 * 4] = -1.0f;
+
+ a.data[0 + 3 * 4] = (left + right) / (left - right);
+ a.data[1 + 3 * 4] = (bottom + top) / (bottom - top);
+
+ return a;
+}
+
+mat4_t mat4_lookAt(vec3_t* eye, vec3_t* center, vec3_t* up)
+{
+ vec3_t temp = vec3_sub(center, eye);
+
+ vec3_t f = vec3_normalize(&temp);
+ vec3_t u = vec3_normalize(up);
+ temp = vec3_cross_mul(&f, &u);
+ vec3_t s = vec3_normalize(&temp);
+ u = vec3_cross_mul(&s, &f);
+
+ mat4_t a;
+ mat4_identity(&a);
+
+ a.data[0 + 0 * 4] = s.x;
+ a.data[0 + 1 * 4] = s.y;
+ a.data[0 + 2 * 4] = s.z;
+ a.data[1 + 0 * 4] = u.x;
+ a.data[1 + 1 * 4] = u.y;
+ a.data[1 + 2 * 4] = u.z;
+ a.data[2 + 0 * 4] =-f.x;
+ a.data[2 + 1 * 4] =-f.y;
+ a.data[2 + 2 * 4] =-f.z;
+ a.data[0 + 3 * 4] =-vec3_dot_mul(&s, eye);
+ a.data[1 + 3 * 4] =-vec3_dot_mul(&u, eye);
+ a.data[2 + 3 * 4] = vec3_dot_mul(&f, eye);
+
+ return a;
+}
+
+vec3_t mat4_mul_vec3(const mat4_t* a, const vec3_t* b)
+{
+ vec3_t c;
+ c.x = a->data[0 + 0 * 4] * b->x + a->data[0 + 1 * 4] * b->y + a->data[0 + 2 * 4] * b->z + a->data[0 + 3 * 4];
+ c.y = a->data[1 + 0 * 4] * b->x + a->data[1 + 1 * 4] * b->y + a->data[1 + 2 * 4] * b->z + a->data[1 + 3 * 4];
+ c.z = a->data[2 + 0 * 4] * b->x + a->data[2 + 1 * 4] * b->y + a->data[2 + 2 * 4] * b->z + a->data[2 + 3 * 4];
+ return c;
+}
diff --git a/07-july/src/math/matrix4x4.h b/07-july/src/math/matrix4x4.h
new file mode 100644
index 0000000..6668fc5
--- /dev/null
+++ b/07-july/src/math/matrix4x4.h
@@ -0,0 +1,35 @@
+#ifndef MATRIX4X4_H
+#define MATRIX4X4_H
+
+#include <GL/glew.h>
+#include "vector3f.h"
+
+/* accesing data: row + column * width */
+typedef struct
+{
+ GLfloat data[16];
+} mat4_t;
+
+extern void mat4_identity(mat4_t* a);
+extern mat4_t mat4_mul(const mat4_t* a, const mat4_t* b);
+
+extern mat4_t mat4_translate(const vec3_t *a);
+extern mat4_t mat4_scale(GLfloat x, GLfloat y, GLfloat z);
+extern mat4_t mat4_rotate_x(GLfloat degrees);
+extern mat4_t mat4_rotate_y(GLfloat degrees);
+extern mat4_t mat4_rotate_z(GLfloat degrees);
+extern mat4_t mat4_rotate(GLfloat degrees, const vec3_t* a);
+
+extern mat4_t
+mat4_perspective(GLfloat fov, GLfloat aspect, GLfloat zNear, GLfloat zFar);
+
+extern mat4_t
+mat4_orthographic(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top);
+
+extern mat4_t
+mat4_lookAt(vec3_t* eye, vec3_t* center, vec3_t* up);
+
+extern vec3_t
+mat4_mul_vec3(const mat4_t* a, const vec3_t* b);
+
+#endif // MATRIX4X4_H
diff --git a/07-july/src/math/vector2f.c b/07-july/src/math/vector2f.c
new file mode 100644
index 0000000..5a3e29d
--- /dev/null
+++ b/07-july/src/math/vector2f.c
@@ -0,0 +1,60 @@
+#include "vector2f.h"
+#include <SDL2/SDL.h>
+
+vec2_t vec2_create(GLfloat x, GLfloat y)
+{
+ vec2_t a = {x, y};
+ return a;
+}
+
+vec2_t vec2_add(const vec2_t* a, const vec2_t* b)
+{
+ vec2_t c;
+ c.x = a->x + b->x;
+ c.y = a->y + b->y;
+ return c;
+}
+
+vec2_t vec2_sub(const vec2_t* a, const vec2_t* b)
+{
+ vec2_t c;
+ c.x = a->x - b->x;
+ c.y = a->y - b->y;
+ return c;
+}
+
+vec2_t vec2_scalar_mul(const vec2_t* a, GLfloat scalar)
+{
+ vec2_t c;
+ c.x = a->x * scalar;
+ c.y = a->y * scalar;
+ return c;
+}
+
+GLfloat vec2_dot_mul(const vec2_t* a, const vec2_t* b)
+{
+ return ( (a->x * b->x) + (a->y * b->y) );
+}
+
+
+vec2_t vec2_cross_mul(const vec2_t* a, const vec2_t* b)
+{
+ vec2_t c;
+ c.x = (a->x * b->y) - (a->y * b->x);
+ c.y = (a->y * b->x) - (a->x * b->y);
+ return c;
+}
+
+GLfloat vec2_length(vec2_t* a)
+{
+ return SDL_sqrtf(SDL_pow(a->x, 2.0f) + SDL_pow(a->y, 2.0f) );
+}
+
+vec2_t vec2_normalize(vec2_t* a)
+{
+ vec2_t b;
+ GLfloat length = vec2_length(a);
+ b.x = a->x / length;
+ b.y = a->y / length;
+ return b;
+}
diff --git a/07-july/src/math/vector2f.h b/07-july/src/math/vector2f.h
new file mode 100644
index 0000000..8c20b9a
--- /dev/null
+++ b/07-july/src/math/vector2f.h
@@ -0,0 +1,20 @@
+#ifndef VECTOR2F_H
+#define VECTOR2F_H
+
+#include <GL/glew.h>
+
+typedef struct
+{
+ GLfloat x, y;
+} vec2_t;
+
+extern vec2_t vec2_create(GLfloat x, GLfloat y);
+extern vec2_t vec2_add(const vec2_t* a, const vec2_t* b);
+extern vec2_t vec2_sub(const vec2_t* a, const vec2_t* b);
+extern vec2_t vec2_scalar_mul(const vec2_t* a, GLfloat scalar);
+extern GLfloat vec2_dot_mul(const vec2_t* a, const vec2_t* b);
+extern vec2_t vec2_cross_mul(const vec2_t* a, const vec2_t* b);
+extern GLfloat vec2_length(vec2_t* a);
+extern vec2_t vec2_normalize(vec2_t* a);
+
+#endif // VECTOR2F_H
diff --git a/07-july/src/math/vector3f.c b/07-july/src/math/vector3f.c
new file mode 100644
index 0000000..d68acf6
--- /dev/null
+++ b/07-july/src/math/vector3f.c
@@ -0,0 +1,65 @@
+#include "vector3f.h"
+#include <SDL2/SDL.h>
+
+vec3_t vec3_create(GLfloat x, GLfloat y, GLfloat z)
+{
+ vec3_t a = {x, y, z};
+ return a;
+}
+
+vec3_t vec3_add(const vec3_t* a, const vec3_t* b)
+{
+ vec3_t c;
+ c.x = a->x + b->x;
+ c.y = a->y + b->y;
+ c.z = a->z + b->z;
+ return c;
+}
+
+vec3_t vec3_sub(const vec3_t* a, const vec3_t* b)
+{
+ vec3_t c;
+ c.x = a->x - b->x;
+ c.y = a->y - b->y;
+ c.z = a->z - b->z;
+ return c;
+}
+
+vec3_t vec3_scalar_mul(const vec3_t* a, GLfloat scalar)
+{
+ vec3_t c;
+ c.x = a->x * scalar;
+ c.y = a->y * scalar;
+ c.z = a->z * scalar;
+ return c;
+}
+
+GLfloat vec3_dot_mul(const vec3_t* a, const vec3_t* b)
+{
+ return ( (a->x * b->x) + (a->y * b->y) + (a->z * b->z) );
+}
+
+
+vec3_t vec3_cross_mul(const vec3_t* a, const vec3_t* b)
+{
+ vec3_t c;
+ c.x = (a->y * b->z) - (a->z * b->y);
+ c.y = (a->z * b->x) - (a->x * b->z);
+ c.z = (a->x * b->y) - (a->y * b->x);
+ return c;
+}
+
+GLfloat vec3_length(vec3_t* a)
+{
+ return SDL_sqrtf(SDL_pow(a->x, 2.0f) + SDL_pow(a->y, 2.0f) + SDL_pow(a->z, 2.0f));
+}
+
+vec3_t vec3_normalize(vec3_t* a)
+{
+ vec3_t b;
+ GLfloat length = vec3_length(a);
+ b.x = a->x / length;
+ b.y = a->y / length;
+ b.z = a->z / length;
+ return b;
+}
diff --git a/07-july/src/math/vector3f.h b/07-july/src/math/vector3f.h
new file mode 100644
index 0000000..ab255d1
--- /dev/null
+++ b/07-july/src/math/vector3f.h
@@ -0,0 +1,20 @@
+#ifndef VECTOR3F_H
+#define VECTOR3F_H
+
+#include <GL/glew.h>
+
+typedef struct
+{
+ GLfloat x, y, z;
+} vec3_t;
+
+extern vec3_t vec3_create(GLfloat x, GLfloat y, GLfloat z);
+extern vec3_t vec3_add(const vec3_t* a, const vec3_t* b);
+extern vec3_t vec3_sub(const vec3_t* a, const vec3_t* b);
+extern vec3_t vec3_scalar_mul(const vec3_t* a, GLfloat scalar);
+extern GLfloat vec3_dot_mul(const vec3_t* a, const vec3_t* b);
+extern vec3_t vec3_cross_mul(const vec3_t* a, const vec3_t* b);
+extern GLfloat vec3_length(vec3_t* a);
+extern vec3_t vec3_normalize(vec3_t* a);
+
+#endif // VECTOR3F_H
diff --git a/07-july/src/math/vector4f.c b/07-july/src/math/vector4f.c
new file mode 100644
index 0000000..735e679
--- /dev/null
+++ b/07-july/src/math/vector4f.c
@@ -0,0 +1,70 @@
+#include "vector4f.h"
+#include <SDL2/SDL.h>
+
+vec4_t vec4_create(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ vec4_t a = {x, y, z, w};
+ return a;
+}
+
+vec4_t vec4_add(const vec4_t* a, const vec4_t* b)
+{
+ vec4_t c;
+ c.x = a->x + b->x;
+ c.y = a->y + b->y;
+ c.z = a->z + b->z;
+ c.w = a->w + b->w;
+ return c;
+}
+
+vec4_t vec4_sub(const vec4_t* a, const vec4_t* b)
+{
+ vec4_t c;
+ c.x = a->x - b->x;
+ c.y = a->y - b->y;
+ c.z = a->z - b->z;
+ c.w = a->w - b->w;
+ return c;
+}
+
+vec4_t vec4_scalar_mul(const vec4_t* a, GLfloat scalar)
+{
+ vec4_t c;
+ c.x = a->x * scalar;
+ c.y = a->y * scalar;
+ c.z = a->z * scalar;
+ c.w = a->w * scalar;
+ return c;
+}
+
+GLfloat vec4_dot_mul(const vec4_t* a, const vec4_t* b)
+{
+ return ( (a->x * b->x) + (a->y * b->y) + (a->z * b->z) + (a->w * b->w) );
+}
+
+
+vec4_t vec4_cross_mul(const vec4_t* a, const vec4_t* b)
+{
+ vec4_t c;
+ c.x = (a->y * b->z) - (a->z * b->y);
+ c.y = (a->z * b->x) - (a->x * b->z);
+ c.z = (a->x * b->y) - (a->y * b->x);
+ c.w = 1.0f;
+ return c;
+}
+
+GLfloat vec4_length(vec4_t* a)
+{
+ return SDL_sqrtf(SDL_pow(a->x, 2.0f) + SDL_pow(a->y, 2.0f) + SDL_pow(a->z, 2.0f) + SDL_pow(a->w, 2.0f) );
+}
+
+vec4_t vec4_normalize(vec4_t* a)
+{
+ vec4_t b;
+ GLfloat length = vec4_length(a);
+ b.x = a->x / length;
+ b.y = a->y / length;
+ b.z = a->z / length;
+ b.w = a->w / length;
+ return b;
+}
diff --git a/07-july/src/math/vector4f.h b/07-july/src/math/vector4f.h
new file mode 100644
index 0000000..4f83695
--- /dev/null
+++ b/07-july/src/math/vector4f.h
@@ -0,0 +1,20 @@
+#ifndef VECTOR4F_H
+#define VECTOR4F_H
+
+#include <GL/glew.h>
+
+typedef struct
+{
+ GLfloat x, y, z, w;
+} vec4_t;
+
+extern vec4_t vec4_create(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+extern vec4_t vec4_add(const vec4_t* a, const vec4_t* b);
+extern vec4_t vec4_sub(const vec4_t* a, const vec4_t* b);
+extern vec4_t vec4_scalar_mul(const vec4_t* a, GLfloat scalar);
+extern GLfloat vec4_dot_mul(const vec4_t* a, const vec4_t* b);
+extern vec4_t vec4_cross_mul(const vec4_t* a, const vec4_t* b);
+extern GLfloat vec4_length(vec4_t* a);
+extern vec4_t vec4_normalize(vec4_t* a);
+
+#endif // VECTOR4F_H
diff --git a/07-july/src/player.c b/07-july/src/player.c
new file mode 100644
index 0000000..02a417b
--- /dev/null
+++ b/07-july/src/player.c
@@ -0,0 +1,62 @@
+#include "player.h"
+#include "util/util_time.h"
+#include "input.h"
+#include "util/util.h"
+
+#define MAX_MOVEMENT_SPEED 10
+#define MAX_ROTATION_SPEED 100
+#define GRAVITY -15
+#define JUMP_POWER 7
+
+static void jump(player_t* player)
+{
+ player->verticalSpeed = JUMP_POWER;
+}
+
+static void check_input(player_t* player)
+{
+ if(Input_isKeyPressed(SDL_SCANCODE_W)) {
+ player->speed = MAX_MOVEMENT_SPEED;
+ } else if(Input_isKeyPressed(SDL_SCANCODE_S)) {
+ player->speed = -MAX_MOVEMENT_SPEED;
+ } else {
+ player->speed = 0.0f;
+ }
+
+ if(Input_isKeyPressed(SDL_SCANCODE_A)) {
+ player->turnSpeed = MAX_ROTATION_SPEED;
+ } else if(Input_isKeyPressed(SDL_SCANCODE_D)) {
+ player->turnSpeed = -MAX_ROTATION_SPEED;
+ } else {
+ player->turnSpeed = 0.0f;
+ }
+
+ if(Input_isKeyPressed(SDL_SCANCODE_SPACE)) {
+ jump(player);
+ }
+}
+
+void Player_Init(player_t* player)
+{
+ player->entity.position = vec3_create(0.0f, 6.0f, 0.0f);
+ player->entity.rotX = player->entity.rotY = player->entity.rotZ = 0;
+ player->speed = player->turnSpeed = player->verticalSpeed = 0;
+}
+
+void Player_Update(player_t *player, terrain_t *terrain)
+{
+ check_input(player);
+ player->entity.rotY += player->turnSpeed * Time_GetFrameTime();
+ player->entity.position.x += SDL_sinf(toRadians(player->entity.rotY)) * player->speed * Time_GetFrameTime();
+ player->entity.position.z += SDL_cosf(toRadians(player->entity.rotY)) * player->speed * Time_GetFrameTime();
+
+ player->verticalSpeed += GRAVITY * Time_GetFrameTime();
+
+ player->entity.position.y += player->verticalSpeed * Time_GetFrameTime();
+
+ GLfloat terrainHeight = Terrain_GetHeightOfTerrain(terrain, player->entity.position.x, player->entity.position.z);
+ if(player->entity.position.y - 1.0f < terrainHeight) {
+ player->entity.position.y = terrainHeight + 1.0f;
+ player->verticalSpeed = 0.0f;
+ }
+}
diff --git a/07-july/src/player.h b/07-july/src/player.h
new file mode 100644
index 0000000..654dc17
--- /dev/null
+++ b/07-july/src/player.h
@@ -0,0 +1,17 @@
+#ifndef PLAYER_H
+#define PLAYER_H
+
+#include "renderer/entity.h"
+#include "math/vector3f.h"
+#include "terrain.h"
+
+typedef struct
+{
+ entity_t entity;
+ float speed, turnSpeed, verticalSpeed;
+} player_t;
+
+extern void Player_Init(player_t* player);
+extern void Player_Update(player_t* player, terrain_t *terrain);
+
+#endif // PLAYER_H
diff --git a/07-july/src/renderer/entity.c b/07-july/src/renderer/entity.c
new file mode 100644
index 0000000..b96491d
--- /dev/null
+++ b/07-july/src/renderer/entity.c
@@ -0,0 +1,18 @@
+#include "entity.h"
+
+mat4_t Entity_GetModelTransform(entity_t* entity)
+{
+ mat4_t temp;
+ mat4_t rotation = mat4_rotate_x(entity->rotX);
+ temp = mat4_rotate_y(entity->rotY);
+ rotation = mat4_mul(&rotation, &temp);
+ temp = mat4_rotate_z(entity->rotZ);
+ rotation = mat4_mul(&rotation, &temp);
+
+ temp = mat4_translate(&entity->position);
+
+ mat4_t modelTransform = mat4_mul(&temp, &rotation);
+
+ return modelTransform;
+}
+
diff --git a/07-july/src/renderer/entity.h b/07-july/src/renderer/entity.h
new file mode 100644
index 0000000..8954c7f
--- /dev/null
+++ b/07-july/src/renderer/entity.h
@@ -0,0 +1,20 @@
+#ifndef ENTITY_H
+#define ENTITY_H
+
+#include "../math/vector3f.h"
+#include "../math/matrix4x4.h"
+
+#include "shape.h"
+#include "../texture.h"
+
+typedef struct
+{
+ shape_t *shape;
+ texture_t *texture;
+ vec3_t position;
+ float rotX, rotY, rotZ;
+} entity_t;
+
+extern mat4_t Entity_GetModelTransform(entity_t* entity);
+
+#endif // ENTITY_H
diff --git a/07-july/src/renderer/renderer.c b/07-july/src/renderer/renderer.c
new file mode 100644
index 0000000..5b8638c
--- /dev/null
+++ b/07-july/src/renderer/renderer.c
@@ -0,0 +1,98 @@
+#include "renderer.h"
+#include <string.h>
+
+static const int MAX_LIGHTS = 4;
+
+void Render_Init()
+{
+
+}
+
+void Render_LoadLights(Shader_Layout *layout, light_t *lights, int n)
+{
+ vec3_t light_positions[MAX_LIGHTS];
+ color_t light_colors[MAX_LIGHTS];
+ vec3_t attenuation[MAX_LIGHTS];
+
+ light_t defaultLight = { {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f} };
+
+ int i;
+ for(i = 0; i < MAX_LIGHTS; i++)
+ {
+ if(i < MAX_LIGHTS)
+ {
+ light_positions[i] = lights[i].position;
+ light_colors[i] = lights[i].color;
+ attenuation[i] = lights[i].attenuation;
+ }
+ else
+ {
+ light_positions[i] = defaultLight.position;
+ light_colors[i] = defaultLight.color;
+ attenuation[i] = defaultLight.attenuation;
+ }
+
+ }
+
+ glUniform3fv(layout->lightPosition, MAX_LIGHTS, (float*)light_positions);
+ glUniform4fv(layout->lightColor, MAX_LIGHTS, (float*)light_colors);
+ glUniform3fv(layout->lightAttenuation, MAX_LIGHTS, (float*)attenuation);
+
+}
+
+void Render_DrawEntity(Shader_Layout *layout, mat4_t *projectedViewMatrix, entity_t *entity)
+{
+ glBindVertexArray(entity->shape->vao);
+
+ /*We need the model to world matrix in our shader in order to rotate the normals*/
+ mat4_t modelTransform = Entity_GetModelTransform(entity);
+ glUniformMatrix4fv(layout->modelToWorld, 1, GL_FALSE, modelTransform.data);
+
+ mat4_t totalMatrix = mat4_mul(projectedViewMatrix, &modelTransform);
+ glUniformMatrix4fv(layout->totalTransform, 1, GL_FALSE, totalMatrix.data);
+
+ glActiveTexture(GL_TEXTURE0);
+ glUniform1i(layout->Texture, 0);
+ Texture_Bind(entity->texture);
+
+ glDrawElements(GL_TRIANGLES, entity->shape->num_indices, GL_UNSIGNED_SHORT, NULL);
+ glBindVertexArray(0);
+}
+
+void Render_DrawTerrain(Shader_Layout *layout, mat4_t *projectedViewMatrix, terrain_t *terrain)
+{
+ glBindVertexArray(terrain->shape->vao);
+
+ /* We need the model to world matrix in our shader in order to rotate the normals */
+ mat4_t modelTransform = mat4_translate(&terrain->position);
+ glUniformMatrix4fv(layout->modelToWorld, 1, GL_FALSE, modelTransform.data);
+
+ mat4_t totalMatrix = mat4_mul(projectedViewMatrix, &modelTransform);
+ glUniformMatrix4fv(layout->totalTransform, 1, GL_FALSE, totalMatrix.data);
+
+ glUniform1i(layout->Texture_Background, 0);
+ glUniform1i(layout->Texture_R, 1);
+ glUniform1i(layout->Texture_G, 2);
+ glUniform1i(layout->Texture_B, 3);
+ glUniform1i(layout->Texture_BlendMap, 4);
+
+ glActiveTexture(GL_TEXTURE0);
+ Texture_Bind(terrain->textures.texture[0]);
+ glActiveTexture(GL_TEXTURE1);
+ Texture_Bind(terrain->textures.texture[1]);
+ glActiveTexture(GL_TEXTURE2);
+ Texture_Bind(terrain->textures.texture[2]);
+ glActiveTexture(GL_TEXTURE3);
+ Texture_Bind(terrain->textures.texture[3]);
+ glActiveTexture(GL_TEXTURE4);
+ Texture_Bind(terrain->blendmap);
+
+ glDrawElements(GL_TRIANGLES, terrain->shape->num_indices, GL_UNSIGNED_SHORT, NULL);
+
+ glBindVertexArray(0);
+}
+
+void Render_Quit()
+{
+
+}
diff --git a/07-july/src/renderer/renderer.h b/07-july/src/renderer/renderer.h
new file mode 100644
index 0000000..7d06fdc
--- /dev/null
+++ b/07-july/src/renderer/renderer.h
@@ -0,0 +1,15 @@
+#ifndef RENDERER_H
+#define RENDERER_H
+
+#include "../graphics/shaders.h"
+#include "entity.h"
+#include "../terrain.h"
+#include "../light.h"
+
+extern void Render_Init();
+extern void Render_LoadLights(Shader_Layout *layout, light_t *lights, int n);
+extern void Render_DrawEntity(Shader_Layout *layout, mat4_t *projectedViewMatrix, entity_t *entity);
+extern void Render_DrawTerrain(Shader_Layout *layout, mat4_t *projectedViewMatrix, terrain_t *terrain);
+extern void Render_Quit();
+
+#endif // RENDERER_H
diff --git a/07-july/src/renderer/shape.c b/07-july/src/renderer/shape.c
new file mode 100644
index 0000000..d48b847
--- /dev/null
+++ b/07-july/src/renderer/shape.c
@@ -0,0 +1,302 @@
+#include "shape.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "../util/util.h"
+
+#define NUM_ARRAY_ELEMENTS(a) sizeof(a) / sizeof(*a)
+
+shape_t* Shape_CreateFromRawData(vertex_t* vertices, GLsizeiptr vertexBufferSize,
+ GLushort* indices, GLsizeiptr indexBufferSize)
+{
+ shape_t* shape = (shape_t*) malloc( sizeof(shape_t) );
+
+ shape->num_indices = ( indexBufferSize / sizeof(GLushort) );
+
+ glGenVertexArrays(1, &shape->vao);
+ glGenBuffers(1, &shape->vbo);
+ glGenBuffers(1, &shape->ebo);
+
+ glBindVertexArray(shape->vao);
+
+ glBindBuffer(GL_ARRAY_BUFFER, shape->vbo);
+ glBufferData(GL_ARRAY_BUFFER, vertexBufferSize, vertices, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, shape->ebo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBufferSize, indices, GL_STATIC_DRAW);
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+ glEnableVertexAttribArray(2);
+ glEnableVertexAttribArray(3);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (const void*)offsetof(vertex_t, position) );
+ glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (const void*)offsetof(vertex_t, color) );
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (const void*)offsetof(vertex_t, texCoord) );
+ glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (const void*)offsetof(vertex_t, normal) );
+
+ glBindVertexArray(0);
+
+ return shape;
+}
+
+shape_t* Shape_MakeCube()
+{
+ vertex_t data[] =
+ {
+ { {-1.0f, +1.0f, +1.0f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.0f, +1.0f, +0.0f} },
+ { {+1.0f, +1.0f, +1.0f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 1.0f}, {+0.0f, +1.0f, +0.0f} },
+ { {+1.0f, +1.0f, -1.0f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {1.0f, 1.0f}, {+0.0f, +1.0f, +0.0f} },
+ { {-1.0f, +1.0f, -1.0f}, {+1.0f, +1.0f, +1.0f, +1.0f}, {1.0f, 0.0f}, {+0.0f, +1.0f, +0.0f} },
+
+ { {-1.0f, +1.0f, -1.0f}, {+1.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.0f, +0.0f, -1.0f} },
+ { {+1.0f, +1.0f, -1.0f}, {+0.0f, +0.5f, +0.2f, +1.0f}, {0.0f, 1.0f}, {+0.0f, +0.0f, -1.0f} },
+ { {+1.0f, -1.0f, -1.0f}, {+0.8f, +0.6f, +0.4f, +1.0f}, {1.0f, 1.0f}, {+0.0f, +0.0f, -1.0f} },
+ { {-1.0f, -1.0f, -1.0f}, {+0.3f, +1.0f, +0.5f, +1.0f}, {1.0f, 0.0f}, {+0.0f, +0.0f, -1.0f} },
+
+ { {+1.0f, +1.0f, -1.0f}, {+0.2f, +0.5f, +0.2f, +1.0f}, {0.0f, 0.0f}, {+1.0f, +0.0f, +0.0f} },
+ { {+1.0f, +1.0f, +1.0f}, {+0.9f, +0.3f, +0.7f, +1.0f}, {0.0f, 1.0f}, {+1.0f, +0.0f, +0.0f} },
+ { {+1.0f, -1.0f, +1.0f}, {+0.3f, +0.7f, +0.5f, +1.0f}, {1.0f, 1.0f}, {+1.0f, +0.0f, +0.0f} },
+ { {+1.0f, -1.0f, -1.0f}, {+0.5f, +0.7f, +0.5f, +1.0f}, {1.0f, 0.0f}, {+1.0f, +0.0f, +0.0f} },
+
+ { {-1.0f, +1.0f, +1.0f}, {+0.7f, +0.8f, +0.2f, +1.0f}, {0.0f, 0.0f}, {-1.0f, +0.0f, +0.0f} },
+ { {-1.0f, +1.0f, -1.0f}, {+0.5f, +0.7f, +0.3f, +1.0f}, {0.0f, 1.0f}, {-1.0f, +0.0f, +0.0f} },
+ { {-1.0f, -1.0f, -1.0f}, {+0.4f, +0.7f, +0.7f, +1.0f}, {1.0f, 1.0f}, {-1.0f, +0.0f, +0.0f} },
+ { {-1.0f, -1.0f, +1.0f}, {+0.2f, +0.5f, +1.0f, +1.0f}, {1.0f, 0.0f}, {-1.0f, +0.0f, +0.0f} },
+
+ { {+1.0f, +1.0f, +1.0f}, {+0.6f, +1.0f, +0.7f, +1.0f}, {0.0f, 0.0f}, {+0.0f, +0.0f, +1.0f} },
+ { {-1.0f, +1.0f, +1.0f}, {+0.6f, +0.4f, +0.8f, +1.0f}, {0.0f, 1.0f}, {+0.0f, +0.0f, +1.0f} },
+ { {-1.0f, -1.0f, +1.0f}, {+0.2f, +0.8f, +0.7f, +1.0f}, {1.0f, 1.0f}, {+0.0f, +0.0f, +1.0f} },
+ { {+1.0f, -1.0f, +1.0f}, {+0.2f, +0.7f, +1.0f, +1.0f}, {1.0f, 0.0f}, {+0.0f, +0.0f, +1.0f} },
+
+ { {+1.0f, -1.0f, -1.0f}, {+0.8f, +0.3f, +0.7f, +1.0f}, {0.0f, 0.0f}, {+0.0f, -1.0f, +0.0f} },
+ { {-1.0f, -1.0f, -1.0f}, {+0.8f, +0.9f, +0.5f, +1.0f}, {0.0f, 1.0f}, {+0.0f, -1.0f, +0.0f} },
+ { {-1.0f, -1.0f, +1.0f}, {+0.5f, +0.8f, +0.5f, +1.0f}, {1.0f, 1.0f}, {+0.0f, -1.0f, +0.0f} },
+ { {+1.0f, -1.0f, +1.0f}, {+0.9f, +1.0f, +0.2f, +1.0f}, {1.0f, 0.0f}, {+0.0f, -1.0f, +0.0f} },
+ };
+
+ GLushort indices[] = {
+ 0, 1, 2, 0, 2, 3, // Top
+ 4, 5, 6, 4, 6, 7, // Front
+ 8, 9, 10, 8, 10, 11, // Right
+ 12, 13, 14, 12, 14, 15, // Left
+ 16, 17, 18, 16, 18, 19, // Back
+ 20, 22, 21, 20, 23, 22, // Bottom
+ };
+
+ GLsizeiptr vertexBufferSize = NUM_ARRAY_ELEMENTS(data) * sizeof(vertex_t);
+ GLsizeiptr indexBufferSize = NUM_ARRAY_ELEMENTS(indices) * sizeof(GLushort);
+
+ return Shape_CreateFromRawData(data, vertexBufferSize, indices, indexBufferSize);
+}
+
+shape_t* Shape_MakeArrow()
+{
+ vertex_t data[] =
+ {
+ // Top side of arrow head
+ { {+0.00f, +0.25f, -0.25f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +1.00f, +0.00f} },
+ { {+0.50f, +0.25f, -0.25f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +1.00f, +0.00f} },
+ { {+0.00f, +0.25f, -1.00f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +1.00f, +0.00f} },
+ { {-0.50f, +0.25f, -0.25f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +1.00f, +0.00f} },
+ // Bottom side of arrow head
+ { {+0.00f, -0.25f, -0.25f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, -1.00f, +0.00f} },
+ { {+0.50f, -0.25f, -0.25f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, -1.00f, +0.00f} },
+ { {+0.00f, -0.25f, -1.00f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, -1.00f, +0.00f} },
+ { {-0.50f, -0.25f, -0.25f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, -1.00f, +0.00f} },
+ // Right side of arrow tip
+ { {+0.50f, +0.25f, -0.25f}, {+0.6f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {0.83205032f, 0.00f, -0.55470026f} },
+ { {+0.00f, +0.25f, -1.00f}, {+0.6f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {0.83205032f, 0.00f, -0.55470026f} },
+ { {+0.00f, -0.25f, -1.00f}, {+0.6f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {0.83205032f, 0.00f, -0.55470026f} },
+ { {+0.50f, -0.25f, -0.25f}, {+0.6f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {0.83205032f, 0.00f, -0.55470026f} },
+ // Left side of arrow tip
+ { {+0.00f, +0.25f, -1.00f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {-0.55708605f, 0.00f, -0.37139067f} },
+ { {-0.50f, +0.25f, -0.25f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {-0.55708605f, 0.00f, -0.37139067f} },
+ { {+0.00f, -0.25f, -1.00f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {-0.55708605f, 0.00f, -0.37139067f} },
+ { {-0.50f, -0.25f, -0.25f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {-0.55708605f, 0.00f, -0.37139067f} },
+ // Back side of arrow tip
+ { {-0.50f, +0.25f, -0.25f}, {+0.5f, +0.5f, +0.5f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +0.00f, +1.00f} },
+ { {+0.50f, +0.25f, -0.25f}, {+0.5f, +0.5f, +0.5f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +0.00f, +1.00f} },
+ { {-0.50f, -0.25f, -0.25f}, {+0.5f, +0.5f, +0.5f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +0.00f, +1.00f} },
+ { {+0.50f, -0.25f, -0.25f}, {+0.5f, +0.5f, +0.5f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +0.00f, +1.00f} },
+ // Top side of back of arrow
+ { {+0.25f, +0.25f, -0.25f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +1.00f, +0.00f} },
+ { {+0.25f, +0.25f, +1.00f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +1.00f, +0.00f} },
+ { {-0.25f, +0.25f, +1.00f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +1.00f, +0.00f} },
+ { {-0.25f, +0.25f, -0.25f}, {+1.0f, +0.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +1.00f, +0.00f} },
+ // Bottom side of back of arrow
+ { {+0.25f, -0.25f, -0.25f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, -1.00f, +0.00f} },
+ { {+0.25f, -0.25f, +1.00f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, -1.00f, +0.00f} },
+ { {-0.25f, -0.25f, +1.00f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, -1.00f, +0.00f} },
+ { {-0.25f, -0.25f, -0.25f}, {+0.0f, +0.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.00f, -1.00f, +0.00f} },
+ // Right side of back of arrow
+ { {+0.25f, +0.25f, -0.25f}, {+0.6f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+1.00f, +0.00f, +0.00f} },
+ { {+0.25f, -0.25f, -0.25f}, {+0.6f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+1.00f, +0.00f, +0.00f} },
+ { {+0.25f, -0.25f, +1.00f}, {+0.6f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+1.00f, +0.00f, +0.00f} },
+ { {+0.25f, +0.25f, +1.00f}, {+0.6f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {+1.00f, +0.00f, +0.00f} },
+ // Left side of back of arrow
+ { {-0.25f, +0.25f, -0.25f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {-1.00f, +0.00f, +0.00f} },
+ { {-0.25f, -0.25f, -0.25f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {-1.00f, +0.00f, +0.00f} },
+ { {-0.25f, -0.25f, +1.00f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {-1.00f, +0.00f, +0.00f} },
+ { {-0.25f, +0.25f, +1.00f}, {+0.0f, +1.0f, +0.0f, +1.0f}, {0.0f, 0.0f}, {-1.00f, +0.00f, +0.00f} },
+ // Back side of back of arrow
+ { {-0.25f, +0.25f, +1.00f}, {+0.5f, +0.5f, +0.5f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +0.00f, +1.00f} },
+ { {+0.25f, +0.25f, +1.00f}, {+0.5f, +0.5f, +0.5f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +0.00f, +1.00f} },
+ { {-0.25f, -0.25f, +1.00f}, {+0.5f, +0.5f, +0.5f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +0.00f, +1.00f} },
+ { {+0.25f, -0.25f, +1.00f}, {+0.5f, +0.5f, +0.5f, +1.0f}, {0.0f, 0.0f}, {+0.00f, +0.00f, +1.00f} },
+ };
+
+ GLushort indices[] = {
+ 0, 1, 2, // Top
+ 0, 2, 3,
+ 4, 6, 5, // Bottom
+ 4, 7, 6,
+ 8, 10, 9, // Right side of arrow tip
+ 8, 11, 10,
+ 12, 15, 13, // Left side of arrow tip
+ 12, 14, 15,
+ 16, 19, 17, // Back side of arrow tip
+ 16, 18, 19,
+ 20, 22, 21, // Top side of back of arrow
+ 20, 23, 22,
+ 24, 25, 26, // Bottom side of back of arrow
+ 24, 26, 27,
+ 28, 30, 29, // Right side of back of arrow
+ 28, 31, 30,
+ 32, 33, 34, // Left side of back of arrow
+ 32, 34, 35,
+ 36, 39, 37, // Back side of back of arrow
+ 36, 38, 39,
+ };
+
+ GLsizeiptr vertexBufferSize = NUM_ARRAY_ELEMENTS(data) * sizeof(vertex_t);
+ GLsizeiptr indexBufferSize = NUM_ARRAY_ELEMENTS(indices) * sizeof(GLushort);
+
+ return Shape_CreateFromRawData(data, vertexBufferSize, indices, indexBufferSize);
+}
+
+shape_t* Shape_MakeQuad()
+{
+ vertex_t data[] =
+ {
+ { {+1.0f, +1.0f, +0.0f}, {+1.0f, +1.0f, +1.0f, +1.0f}, {1.0f, 1.0f}, {+0.0f, +0.0f, +1.0f} },
+ { {-1.0f, +1.0f, +0.0f}, {+1.0f, +1.0f, +1.0f, +1.0f}, {0.0f, 1.0f}, {+0.0f, +0.0f, +1.0f} },
+ { {+1.0f, -1.0f, +0.0f}, {+1.0f, +1.0f, +1.0f, +1.0f}, {1.0f, 0.0f}, {+0.0f, +0.0f, +1.0f} },
+ { {-1.0f, -1.0f, +0.0f}, {+1.0f, +1.0f, +1.0f, +1.0f}, {0.0f, 0.0f}, {+0.0f, +0.0f, +1.0f} },
+ };
+
+ GLushort indices[] =
+ {
+ 0, 1, 2, 1, 3, 2
+ };
+
+ GLsizeiptr vertexBufferSize = NUM_ARRAY_ELEMENTS(data) * sizeof(vertex_t);
+ GLsizeiptr indexBufferSize = NUM_ARRAY_ELEMENTS(indices) * sizeof(GLushort);
+
+ return Shape_CreateFromRawData(data, vertexBufferSize, indices, indexBufferSize);
+}
+
+#define BUFFER_SIZE 128
+
+shape_t* Shape_LoadOBJ(const char* path)
+{
+ vec3_t* vertices = NULL;
+ vec2_t* textures = NULL;
+ vec3_t* normals = NULL;
+
+ vertex_t* data = NULL;
+ GLushort* indices = NULL;
+
+ unsigned int vertices_count = 0, textures_count = 0, normals_count = 0, index_pointer = 0, faces_count = 0;
+ int count = 0;
+ int texture[3], normal[3], verts[3];
+
+ FILE* file = fopen(path, "r");
+ if(file == NULL)
+ Util_FatalError(".obj file could not be loaded!");
+
+ char buffer[BUFFER_SIZE];
+ while(!feof(file))
+ {
+ fgets(buffer, BUFFER_SIZE, file);
+ switch(buffer[0])
+ {
+ case 'v':
+ if(buffer[1] == 't') {
+ textures = (vec2_t*) realloc(textures, sizeof(vec2_t) * (++textures_count) );
+ count = sscanf(buffer, "vt %f %f\n", &textures[textures_count-1].x, &textures[textures_count-1].y);
+ if(count != 2)
+ Util_FatalError("Bad texture coordinates on .obj file");
+ } else if(buffer[1] == 'n') {
+ normals = (vec3_t*) realloc(normals, sizeof(vec3_t) * (++normals_count) );
+ count = sscanf(buffer, "vn %f %f %f\n", &normals[normals_count-1].x,
+ &normals[normals_count-1].y, &normals[normals_count-1].z);
+ if(count != 3)
+ Util_FatalError("Bad normals data on .obj file");
+ } else {
+ vertices = (vec3_t*) realloc(vertices, sizeof(vec3_t) * (++vertices_count) );
+ count = sscanf(buffer, "v %f %f %f\n", &vertices[vertices_count-1].x,
+ &vertices[vertices_count-1].y, &vertices[vertices_count-1].z);
+ if(count != 3)
+ Util_FatalError("Bad vertices data on .obj file");
+ }
+ break;
+ case 'f':
+ data = (vertex_t*) realloc( data, sizeof(vertex_t) * (++faces_count * 3) );
+ indices = (GLushort*) realloc( indices, sizeof(GLushort) * (++faces_count * 3) );
+
+ count = sscanf(buffer, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
+ &verts[0], &texture[0], &normal[0], &verts[1], &texture[1], &normal[1],
+ &verts[2], &texture[2], &normal[2]);
+ if(count != 9)
+ Util_FatalError("Bad face data on .obj file");
+
+ indices[index_pointer] = index_pointer;
+ data[index_pointer].position = vertices[verts[0]-1];
+ data[index_pointer].texCoord = textures[texture[0]-1];
+ data[index_pointer++].normal = normals[normal[0]-1];
+
+ indices[index_pointer] = index_pointer;
+ data[index_pointer].position = vertices[verts[1]-1];
+ data[index_pointer].texCoord = textures[texture[1]-1];
+ data[index_pointer++].normal = normals[normal[1]-1];
+
+ indices[index_pointer] = index_pointer;
+ data[index_pointer].position = vertices[verts[2]-1];
+ data[index_pointer].texCoord = textures[texture[2]-1];
+ data[index_pointer++].normal = normals[normal[2]-1];
+
+ break;
+ default:
+ break;
+ }
+ }
+
+ free(vertices);
+ free(normals);
+ free(textures);
+ fclose(file);
+
+ /*Remember, each face contains 3 vertex -> (faces_count * 3)*/
+
+ GLsizeiptr vertexBufferSize = faces_count * sizeof(vertex_t) * 3;
+ GLsizeiptr indexBufferSize = faces_count * sizeof(GLushort) * 3;
+
+ shape_t* shape = Shape_CreateFromRawData(data, vertexBufferSize, indices, indexBufferSize);
+
+ free(data);
+ free(indices);
+
+ return shape;
+}
+
+void Shape_Free(shape_t* shape)
+{
+ if(shape)
+ {
+ glDeleteBuffers(1, &shape->vbo);
+ glDeleteBuffers(1, &shape->ebo);
+ glDeleteVertexArrays(1, &shape->vao);
+ free(shape);
+ }
+}
diff --git a/07-july/src/renderer/shape.h b/07-july/src/renderer/shape.h
new file mode 100644
index 0000000..b019333
--- /dev/null
+++ b/07-july/src/renderer/shape.h
@@ -0,0 +1,25 @@
+#ifndef SHAPE_H
+#define SHAPE_H
+
+#include "../vertex.h"
+
+typedef struct
+{
+ GLuint num_indices;
+ GLuint vbo, ebo, vao;
+} shape_t;
+
+extern shape_t* Shape_MakeCube();
+extern shape_t* Shape_MakeArrow();
+extern shape_t* Shape_MakeQuad();
+
+extern shape_t* Shape_LoadOBJ(const char* path);
+
+extern shape_t* Shape_CreateFromRawData(vertex_t* vertices, GLsizeiptr vertexBufferSize,
+ GLushort* indices, GLsizeiptr indexBufferSize);
+
+extern void Shape_Free(shape_t* shape);
+
+
+
+#endif // SHAPE_H
diff --git a/07-july/src/terrain.c b/07-july/src/terrain.c
new file mode 100644
index 0000000..3bc66d2
--- /dev/null
+++ b/07-july/src/terrain.c
@@ -0,0 +1,163 @@
+#include "terrain.h"
+#include "math/math_util.h"
+#include "math/vector3f.h"
+#include "util/util.h"
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_image.h>
+#include <math.h>
+
+#define PLANE_SIZE 128
+#define PLANE_MAX_HEIGHT 10
+
+#define NUM_ARRAY_ELEMENTS(a) sizeof(a) / sizeof(*a)
+
+static float GetHeight(int x, int y, SDL_Surface* surface)
+{
+ if(x < 0 || x >= surface->w || y < 0 || y >= surface->h)
+ return 0.0f;
+
+ Uint32 pixel = ( (Uint32*)surface->pixels )[y * surface->w + x];
+ Uint8 r, g, b;
+ SDL_GetRGB(pixel, surface->format, &r, &g, &b);
+
+ float height = (float)r / 255.0f;
+
+ return height * 40.0f;
+}
+
+static vec3_t GenerateNomal(int x, int y, SDL_Surface* surface)
+{
+ float hLeft = GetHeight(x-1, y, surface);
+ float hRight = GetHeight(x+1, y, surface);
+ float hUp = GetHeight(x, y+1, surface);
+ float hDown = GetHeight(x, y-1, surface);
+
+ vec3_t normal = { hLeft - hRight, 2.0f, hDown - hUp};
+ return vec3_normalize(&normal);
+}
+
+GLfloat Terrain_GetHeightOfTerrain(terrain_t* terrain, GLfloat x, GLfloat z)
+{
+ GLfloat terrainX = x - terrain->position.x;
+ GLfloat terrainZ = z - terrain->position.z;
+
+ GLfloat gridSquareSize = (float)terrain->l / ( (float)PLANE_SIZE - 1 );
+
+ GLint gridX = (GLint) floor(terrainX / gridSquareSize);
+ GLint gridZ = (GLint) floor(terrainZ / gridSquareSize);
+
+ if(gridX >= PLANE_SIZE - 1 || gridX < 0 || gridZ >= PLANE_SIZE - 1 || gridZ < 0)
+ {
+ printf("called\n");
+ return 0;
+ }
+
+ GLfloat xCoord = fmod(terrainX, gridSquareSize) / gridSquareSize;
+ GLfloat zCoord = fmod(terrainZ, gridSquareSize) / gridSquareSize;
+ GLfloat answer;
+
+ /* Determine in which triangle of the square are we. "Bary Centric Interpolation"*/
+ if(xCoord <= (1 - zCoord)){
+ /* 0, heights[gridX][gridZ], 0) */
+ vec3_t p1 = { 0, terrain->height[ gridX * PLANE_SIZE + gridZ ], 0 };
+ /* 1, heights[gridX + 1][gridZ], 0) */
+ vec3_t p2 = { 1, terrain->height[ (gridX + 1) * PLANE_SIZE + gridZ ], 0};
+ /* 0, heights[gridX][gridZ + 1], 1) */
+ vec3_t p3 = { 0, terrain->height[ gridX * PLANE_SIZE + (gridZ + 1) ], 1};
+
+ vec2_t pos = {xCoord, zCoord};
+
+ answer = baryCentric(&p1, &p2, &p3, &pos);
+ } else {
+ /* (1, heights[gridX + 1][gridZ], 0) */
+ vec3_t p1 = { 1, terrain->height[ (gridX + 1) * PLANE_SIZE + gridZ ], 0 };
+ /* (1, heights[gridX + 1][gridZ + 1], 1) */
+ vec3_t p2 = { 1, terrain->height[ (gridX + 1) * PLANE_SIZE + (gridZ + 1) ], 1};
+ /* (0, heights[gridX][gridZ + 1], 1) */
+ vec3_t p3 = { 0, terrain->height[ gridX * PLANE_SIZE + (gridZ + 1) ], 1};
+ vec2_t pos = {xCoord, zCoord};
+
+ answer = baryCentric(&p1, &p2, &p3, &pos);
+ }
+
+ return answer;
+}
+
+terrain_t *Terrain_Create( int w, int l, const char* heightmap_path, texture_t *blendmap, TerrainTexturePack *textures )
+{
+ terrain_t *terrain = (terrain_t*) malloc( sizeof(terrain_t) );
+ terrain->height = (GLfloat*) malloc( sizeof(GLfloat) * PLANE_SIZE * PLANE_SIZE);
+
+ terrain->blendmap = blendmap;
+ terrain->w = w; terrain->l = l;
+ terrain->textures = *textures;
+
+ SDL_Surface* surface = IMG_Load(heightmap_path);
+ if(surface == NULL)
+ Util_FatalError("Heightmap file could not be loaded\n");
+
+ vertex_t data[PLANE_SIZE * PLANE_SIZE];
+ int x, y;
+ for(x = 0; x < PLANE_SIZE; x++)
+ {
+ for(y = 0; y < PLANE_SIZE; y++)
+ {
+ vertex_t* v = &data[y + x * PLANE_SIZE];
+ v->position = vec3_create( (float)x / (float)PLANE_SIZE, 0.0f, (float)y / (float)PLANE_SIZE);
+ /* Heightmap cordinates */
+ int image_x = v->position.x * surface->w, image_y = v->position.z * surface->h;
+
+ v->texCoord = vec2_create( v->position.x, v->position.z);
+ GLfloat height = GetHeight(image_x, image_y, surface);
+ terrain->height[y + x * PLANE_SIZE] = height;
+ v->position.y = height;
+ v->position.x *= w;
+ v->position.z *= l;
+
+ v->normal = GenerateNomal(image_x, image_y, surface);
+ color_t temp = {+1.0f, +0.0f, +0.0f, +1.0f};
+ v->color = temp;
+ }
+ }
+
+ int runner = 0;
+ GLushort indices[ (PLANE_SIZE-1) * (PLANE_SIZE-1) * 6 ];
+ for(x = 0; x < PLANE_SIZE-1; x++)
+ {
+ for(y = 0; y < PLANE_SIZE-1; y++)
+ {
+ indices[runner++] = PLANE_SIZE * x + y;
+ indices[runner++] = PLANE_SIZE * x + y + 1;
+ indices[runner++] = PLANE_SIZE * x + y + PLANE_SIZE;
+
+ indices[runner++] = PLANE_SIZE * x + y + 1;
+ indices[runner++] = PLANE_SIZE * x + y + PLANE_SIZE + 1;
+ indices[runner++] = PLANE_SIZE * x + y + PLANE_SIZE;
+ }
+ }
+
+ GLsizeiptr vertexBufferSize = NUM_ARRAY_ELEMENTS(data) * sizeof(vertex_t);
+ GLsizeiptr indexBufferSize = NUM_ARRAY_ELEMENTS(indices) * sizeof(GLushort);
+
+ SDL_FreeSurface(surface);
+
+ terrain->shape = Shape_CreateFromRawData(data, vertexBufferSize, indices, indexBufferSize);
+ return terrain;
+}
+
+void Terrain_Destroy( terrain_t* terrain )
+{
+ if(terrain->height)
+ free(terrain->height);
+
+ Shape_Free(terrain->shape);
+
+ int i;
+ for(i = 0; i < 4; i++)
+ Texture_Destroy(terrain->textures.texture[i]);
+
+ Texture_Destroy(terrain->blendmap);
+ free(terrain);
+}
+
diff --git a/07-july/src/terrain.h b/07-july/src/terrain.h
new file mode 100644
index 0000000..74e9f33
--- /dev/null
+++ b/07-july/src/terrain.h
@@ -0,0 +1,27 @@
+#ifndef TERRAIN_H
+#define TERRAIN_H
+
+#include "renderer/shape.h"
+#include "texture.h"
+
+typedef struct
+{
+ texture_t *texture[4];
+} TerrainTexturePack;
+
+typedef struct
+{
+ shape_t *shape;
+ texture_t *blendmap;
+ TerrainTexturePack textures;
+
+ GLfloat *height;
+ int w, l;
+ vec3_t position;
+} terrain_t;
+
+extern terrain_t *Terrain_Create( int w, int l, const char* heightmap_path, texture_t *blendmap, TerrainTexturePack *textures);
+extern GLfloat Terrain_GetHeightOfTerrain(terrain_t* terrain, GLfloat x, GLfloat z);
+extern void Terrain_Destroy( terrain_t *terrain );
+
+#endif // TERRAIN_H
diff --git a/07-july/src/texture.c b/07-july/src/texture.c
new file mode 100644
index 0000000..26fddde
--- /dev/null
+++ b/07-july/src/texture.c
@@ -0,0 +1,47 @@
+#include "texture.h"
+#include "util/util.h"
+
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_image.h>
+
+texture_t* Texture_Create( const char* path )
+{
+ texture_t* texture = (texture_t*) malloc( sizeof(texture_t) );
+ SDL_Surface* data = IMG_Load(path);
+ if(data == NULL)
+ Util_FatalError("Texture could not be found!\n");
+
+ glGenTextures(1, &texture->ID);
+ glBindTexture(GL_TEXTURE_2D, texture->ID);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data->w, data->h, GL_FALSE, GL_RGBA, GL_UNSIGNED_BYTE, data->pixels);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ 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_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+
+ SDL_FreeSurface(data);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ texture->width = data->w;
+ texture->height = data->h;
+
+ return texture;
+}
+
+void Texture_Bind(texture_t* texture)
+{
+ glBindTexture(GL_TEXTURE_2D, texture->ID);
+}
+
+void Texture_Unbind()
+{
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void Texture_Destroy(texture_t* texture)
+{
+ glDeleteTextures(1, &texture->ID);
+ free(texture);
+}
diff --git a/07-july/src/texture.h b/07-july/src/texture.h
new file mode 100644
index 0000000..98048b5
--- /dev/null
+++ b/07-july/src/texture.h
@@ -0,0 +1,18 @@
+#ifndef TEXTURE_H
+#define TEXTURE_H
+
+#include <GL/glew.h>
+
+typedef struct
+{
+ GLuint ID;
+ GLuint width, height;
+} texture_t;
+
+extern texture_t* Texture_Create( const char* path );
+extern void Texture_Destroy( texture_t* texture );
+
+extern void Texture_Bind(texture_t* texture);
+extern void Texture_Unbind();
+
+#endif // TEXTURE_H
diff --git a/07-july/src/util/util.c b/07-july/src/util/util.c
new file mode 100644
index 0000000..fcdd665
--- /dev/null
+++ b/07-july/src/util/util.c
@@ -0,0 +1,49 @@
+#include "util.h"
+
+#include <SDL2/SDL.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+void Util_FatalError( const char* error )
+{
+ fprintf(stderr, "Fatal Error:\n%s", error);
+ SDL_Quit();
+ exit(1);
+}
+
+char* Util_LoadFile( const char* path )
+{
+ FILE* file = fopen( path, "r" );
+
+ if(file == NULL)
+ {
+ const char* temp = " could not be found\n";
+ size_t length = strlen(temp);
+ length += strlen(path);
+ char buffer[length];
+ strcpy(buffer, path);
+ strcat(buffer, temp);
+ Util_FatalError(buffer);
+ }
+
+ fseek( file, 0, SEEK_END );
+ size_t sizeOfFile = ftell( file );
+ fseek( file, 0, SEEK_SET );
+ char* file_data = (char*) malloc( sizeof(char)*sizeOfFile + 1 );
+ fread( file_data, sizeof(char), sizeOfFile, file );
+ file_data[sizeOfFile] = '\0';
+ fclose(file);
+ return file_data;
+}
+
+float Util_RandomF(float min, float max)
+{
+ return ( min + (float)rand() ) / ( (float)RAND_MAX / (max-min) );
+}
+
+int Util_RandomI(int min, int max)
+{
+ return ( rand()%(max-min) ) + min;
+}
diff --git a/07-july/src/util/util.h b/07-july/src/util/util.h
new file mode 100644
index 0000000..5f82f30
--- /dev/null
+++ b/07-july/src/util/util.h
@@ -0,0 +1,19 @@
+#ifndef UTIL_H
+#define UTIL_H
+
+#define toRadians(degrees) (degrees * 3.1415926 / 180.0f)
+#define toDegrees(radians) (radians * 180.0f / 3.1415926)
+
+#ifdef DEBUG
+#include <stdio.h>
+#define myAssert(expr) expr ? 1==1 : fprintf(stderr, "The expresion was not true\n")
+#else
+#define myAssert(expr)
+#endif // DEBUG
+
+extern void Util_FatalError( const char* error );
+extern char* Util_LoadFile( const char* path );
+extern float Util_RandomF(float min, float max);
+extern int Util_RandomI(int min, int max);
+
+#endif // UTIL_H
diff --git a/07-july/src/util/util_time.c b/07-july/src/util/util_time.c
new file mode 100644
index 0000000..b601379
--- /dev/null
+++ b/07-july/src/util/util_time.c
@@ -0,0 +1,52 @@
+#include "util_time.h"
+
+static struct
+{
+ float max_ticks_per_frame; //< cuantos ticks (tiempo demora) un frame
+ Uint32 counted_frames; //< cuantos frames han pasado
+ Uint32 start_ticks; //< ticks al iniciar la iteracion del loop
+ Uint32 beg_ticks; //< ticks desde el inicio del juego
+ Uint32 time_per_frame;
+} TIME = {
+ 1000.0f / 60.0f,
+ 0, 0, 0, 0
+};
+
+void Time_Init()
+{
+ TIME.beg_ticks = SDL_GetTicks();
+}
+
+void Time_Begin()
+{
+ TIME.start_ticks = SDL_GetTicks();
+}
+
+float Time_End()
+{
+ TIME.counted_frames += 1;
+ float FPS = TIME.counted_frames / ( (float)(SDL_GetTicks() - TIME.beg_ticks) / 1000.f );
+
+ float frameTicks = (float)(SDL_GetTicks() - TIME.start_ticks);
+ TIME.time_per_frame = frameTicks;
+ if(frameTicks < TIME.max_ticks_per_frame){
+ SDL_Delay( (Uint32)(TIME.max_ticks_per_frame - frameTicks) );
+ }
+
+ return FPS;
+}
+
+float Time_GetFrameTime()
+{
+ return (float)TIME.time_per_frame / 1000.0f;
+}
+
+void Time_SetMaxFramesPerSecond(Uint32 frames)
+{
+ TIME.max_ticks_per_frame = 1000.0f / (float)frames;
+}
+
+Uint32 Time_GetCountedFrames()
+{
+ return TIME.counted_frames;
+}
diff --git a/07-july/src/util/util_time.h b/07-july/src/util/util_time.h
new file mode 100644
index 0000000..3c3e470
--- /dev/null
+++ b/07-july/src/util/util_time.h
@@ -0,0 +1,13 @@
+#ifndef UTIL_TIME_H
+#define UTIL_TIME_H
+
+#include <SDL2/SDL.h>
+
+extern void Time_Init( void );
+extern void Time_Begin( void );
+extern float Time_End( void );
+extern void Time_SetMaxFramesPerSecond(Uint32 frames);
+extern float Time_GetFrameTime( void );
+extern Uint32 Time_GetCountedFrames( void );
+
+#endif // UTIL_TIME_H
diff --git a/07-july/src/vertex.h b/07-july/src/vertex.h
new file mode 100644
index 0000000..90152c8
--- /dev/null
+++ b/07-july/src/vertex.h
@@ -0,0 +1,21 @@
+#ifndef VERTEX_H
+#define VERTEX_H
+
+#include <GL/glew.h>
+#include "math/vector2f.h"
+#include "math/vector3f.h"
+
+typedef struct
+{
+ GLfloat r, g, b, a;
+} color_t;
+
+typedef struct
+{
+ vec3_t position;
+ color_t color;
+ vec2_t texCoord;
+ vec3_t normal;
+} vertex_t;
+
+#endif // VERTEX_H