From 66b096d97848eb096a043781f1f305e7189f2a00 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 30 Mar 2016 20:09:16 +0200 Subject: Added support for render to texture (use RenderTexture2D) Now it's possible to render to texture, old postprocessing system will be removed on next raylib version. --- examples/resources/shaders/base.vs | 3 +++ examples/resources/shaders/bloom.fs | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/base.vs b/examples/resources/shaders/base.vs index b0f930b7..9b8cca69 100644 --- a/examples/resources/shaders/base.vs +++ b/examples/resources/shaders/base.vs @@ -3,8 +3,10 @@ in vec3 vertexPosition; in vec2 vertexTexCoord; in vec3 vertexNormal; +in vec4 vertexColor; out vec2 fragTexCoord; +out vec4 fragTintColor; uniform mat4 mvpMatrix; @@ -13,6 +15,7 @@ uniform mat4 mvpMatrix; void main() { fragTexCoord = vertexTexCoord; + fragTintColor = vertexColor; gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); } \ No newline at end of file diff --git a/examples/resources/shaders/bloom.fs b/examples/resources/shaders/bloom.fs index 2833ce33..0a73161a 100644 --- a/examples/resources/shaders/bloom.fs +++ b/examples/resources/shaders/bloom.fs @@ -1,11 +1,12 @@ #version 330 in vec2 fragTexCoord; +in vec4 fragTintColor; out vec4 fragColor; uniform sampler2D texture0; -uniform vec4 fragTintColor; +//uniform vec4 fragTintColor; // NOTE: Add here your custom variables -- cgit v1.2.3 From 1d545449bb19148b45d2d92f213e1001a8eb527c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 7 Apr 2016 12:32:32 +0200 Subject: Reviewed shaders and added comments --- examples/resources/shaders/base.vs | 21 ------- examples/resources/shaders/bloom.fs | 43 -------------- examples/resources/shaders/glsl100/base.vs | 26 +++++++++ examples/resources/shaders/glsl100/bloom.fs | 37 ++++++++++++ examples/resources/shaders/glsl100/grayscale.fs | 25 ++++++++ examples/resources/shaders/glsl100/swirl.fs | 45 +++++++++++++++ examples/resources/shaders/glsl330/base.vs | 26 +++++++++ examples/resources/shaders/glsl330/bloom.fs | 38 +++++++++++++ examples/resources/shaders/glsl330/grayscale.fs | 26 +++++++++ examples/resources/shaders/glsl330/phong.fs | 76 +++++++++++++++++++++++++ examples/resources/shaders/glsl330/phong.vs | 29 ++++++++++ examples/resources/shaders/glsl330/swirl.fs | 46 +++++++++++++++ examples/resources/shaders/grayscale.fs | 20 ------- examples/resources/shaders/phong.fs | 76 ------------------------- examples/resources/shaders/phong.vs | 29 ---------- examples/resources/shaders/shapes_base.vs | 18 ------ examples/resources/shaders/shapes_grayscale.fs | 15 ----- examples/resources/shaders/swirl.fs | 41 ------------- examples/shaders_custom_uniform.c | 6 +- examples/shaders_model_shader.c | 4 +- examples/shaders_postprocessing.c | 6 +- examples/shaders_shapes_textures.c | 7 +-- 22 files changed, 385 insertions(+), 275 deletions(-) delete mode 100644 examples/resources/shaders/base.vs delete mode 100644 examples/resources/shaders/bloom.fs create mode 100644 examples/resources/shaders/glsl100/base.vs create mode 100644 examples/resources/shaders/glsl100/bloom.fs create mode 100644 examples/resources/shaders/glsl100/grayscale.fs create mode 100644 examples/resources/shaders/glsl100/swirl.fs create mode 100644 examples/resources/shaders/glsl330/base.vs create mode 100644 examples/resources/shaders/glsl330/bloom.fs create mode 100644 examples/resources/shaders/glsl330/grayscale.fs create mode 100644 examples/resources/shaders/glsl330/phong.fs create mode 100644 examples/resources/shaders/glsl330/phong.vs create mode 100644 examples/resources/shaders/glsl330/swirl.fs delete mode 100644 examples/resources/shaders/grayscale.fs delete mode 100644 examples/resources/shaders/phong.fs delete mode 100644 examples/resources/shaders/phong.vs delete mode 100644 examples/resources/shaders/shapes_base.vs delete mode 100644 examples/resources/shaders/shapes_grayscale.fs delete mode 100644 examples/resources/shaders/swirl.fs (limited to 'examples/resources') diff --git a/examples/resources/shaders/base.vs b/examples/resources/shaders/base.vs deleted file mode 100644 index 9b8cca69..00000000 --- a/examples/resources/shaders/base.vs +++ /dev/null @@ -1,21 +0,0 @@ -#version 330 - -in vec3 vertexPosition; -in vec2 vertexTexCoord; -in vec3 vertexNormal; -in vec4 vertexColor; - -out vec2 fragTexCoord; -out vec4 fragTintColor; - -uniform mat4 mvpMatrix; - -// NOTE: Add here your custom variables - -void main() -{ - fragTexCoord = vertexTexCoord; - fragTintColor = vertexColor; - - gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); -} \ No newline at end of file diff --git a/examples/resources/shaders/bloom.fs b/examples/resources/shaders/bloom.fs deleted file mode 100644 index 0a73161a..00000000 --- a/examples/resources/shaders/bloom.fs +++ /dev/null @@ -1,43 +0,0 @@ -#version 330 - -in vec2 fragTexCoord; -in vec4 fragTintColor; - -out vec4 fragColor; - -uniform sampler2D texture0; -//uniform vec4 fragTintColor; - -// NOTE: Add here your custom variables - -void main() -{ - vec4 sum = vec4(0); - vec4 tc = vec4(0); - - for (int i = -4; i < 4; i++) - { - for (int j = -3; j < 3; j++) - { - sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25; - } - } - - if (texture2D(texture0, fragTexCoord).r < 0.3) - { - tc = sum*sum*0.012 + texture2D(texture0, fragTexCoord); - } - else - { - if (texture2D(texture0, fragTexCoord).r < 0.5) - { - tc = sum*sum*0.009 + texture2D(texture0, fragTexCoord); - } - else - { - tc = sum*sum*0.0075 + texture2D(texture0, fragTexCoord); - } - } - - fragColor = tc; -} \ No newline at end of file diff --git a/examples/resources/shaders/glsl100/base.vs b/examples/resources/shaders/glsl100/base.vs new file mode 100644 index 00000000..e9386939 --- /dev/null +++ b/examples/resources/shaders/glsl100/base.vs @@ -0,0 +1,26 @@ +#version 100 + +// Input vertex attributes +attribute vec3 vertexPosition; +attribute vec2 vertexTexCoord; +attribute vec3 vertexNormal; +attribute vec4 vertexColor; + +// Input uniform values +uniform mat4 mvpMatrix; + +// Output vertex attributes (to fragment shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl100/bloom.fs b/examples/resources/shaders/glsl100/bloom.fs new file mode 100644 index 00000000..5a08843d --- /dev/null +++ b/examples/resources/shaders/glsl100/bloom.fs @@ -0,0 +1,37 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 fragTintColor; + +// NOTE: Add here your custom variables + +void main() +{ + vec4 sum = vec4(0); + vec4 tc = vec4(0); + + for (int i = -4; i < 4; i++) + { + for (int j = -3; j < 3; j++) + { + sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25; + } + } + + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + + // Calculate final fragment color + if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; + else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; + else tc = sum*sum*0.0075 + texelColor; + + finalColor = tc; +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl100/grayscale.fs b/examples/resources/shaders/glsl100/grayscale.fs new file mode 100644 index 00000000..f92ec335 --- /dev/null +++ b/examples/resources/shaders/glsl100/grayscale.fs @@ -0,0 +1,25 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 fragTintColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor; + + // Convert texel color to grayscale using NTSC conversion weights + float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); + + // Calculate final fragment color + gl_FragColor = vec4(gray, gray, gray, texelColor.a); +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl100/swirl.fs b/examples/resources/shaders/glsl100/swirl.fs new file mode 100644 index 00000000..e77d4f87 --- /dev/null +++ b/examples/resources/shaders/glsl100/swirl.fs @@ -0,0 +1,45 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 fragTintColor; + +// NOTE: Add here your custom variables + +const float renderWidth = 800.0; // HARDCODED for example! +const float renderHeight = 480.0; // Use uniforms instead... + +float radius = 250.0; +float angle = 0.8; + +uniform vec2 center = vec2(200.0, 200.0); + +void main (void) +{ + vec2 texSize = vec2(renderWidth, renderHeight); + vec2 tc = fragTexCoord*texSize; + tc -= center; + + float dist = length(tc); + + if (dist < radius) + { + float percent = (radius - dist)/radius; + float theta = percent*percent*angle*8.0; + float s = sin(theta); + float c = cos(theta); + + tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); + } + + tc += center; + vec3 color = texture2D(texture0, tc/texSize).rgb; + + gl_FragColor = vec4(color, 1.0);; +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/base.vs b/examples/resources/shaders/glsl330/base.vs new file mode 100644 index 00000000..638cb8ae --- /dev/null +++ b/examples/resources/shaders/glsl330/base.vs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvpMatrix; + +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/bloom.fs b/examples/resources/shaders/glsl330/bloom.fs new file mode 100644 index 00000000..c8cb0d32 --- /dev/null +++ b/examples/resources/shaders/glsl330/bloom.fs @@ -0,0 +1,38 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 fragTintColor; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + vec4 sum = vec4(0); + vec4 tc = vec4(0); + + for (int i = -4; i < 4; i++) + { + for (int j = -3; j < 3; j++) + { + sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25; + } + } + + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + + // Calculate final fragment color + if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; + else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; + else tc = sum*sum*0.0075 + texelColor; + + finalColor = tc; +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/grayscale.fs b/examples/resources/shaders/glsl330/grayscale.fs new file mode 100644 index 00000000..d4a8824f --- /dev/null +++ b/examples/resources/shaders/glsl330/grayscale.fs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 fragTintColor; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor; + + // Convert texel color to grayscale using NTSC conversion weights + float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); + + // Calculate final fragment color + finalColor = vec4(gray, gray, gray, texelColor.a); +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/phong.fs b/examples/resources/shaders/glsl330/phong.fs new file mode 100644 index 00000000..2e7a95f6 --- /dev/null +++ b/examples/resources/shaders/glsl330/phong.fs @@ -0,0 +1,76 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec3 fragNormal; + +// Diffuse data +uniform sampler2D texture0; +uniform vec4 fragTintColor; + +// Light attributes +uniform vec3 light_ambientColor = vec3(0.6, 0.3, 0.0); +uniform vec3 light_diffuseColor = vec3(1.0, 0.5, 0.0); +uniform vec3 light_specularColor = vec3(0.0, 1.0, 0.0); +uniform float light_intensity = 1.0; +uniform float light_specIntensity = 1.0; + +// Material attributes +uniform vec3 mat_ambientColor = vec3(1.0, 1.0, 1.0); +uniform vec3 mat_specularColor = vec3(1.0, 1.0, 1.0); +uniform float mat_glossiness = 50.0; + +// World attributes +uniform vec3 lightPos; +uniform vec3 cameraPos; + +// Fragment shader output data +out vec4 fragColor; + +vec3 AmbientLighting() +{ + return (mat_ambientColor*light_ambientColor); +} + +vec3 DiffuseLighting(in vec3 N, in vec3 L) +{ + // Lambertian reflection calculation + float diffuse = clamp(dot(N, L), 0, 1); + + return (fragTintColor.xyz*light_diffuseColor*light_intensity*diffuse); +} + +vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V) +{ + float specular = 0.0; + + // Calculate specular reflection only if the surface is oriented to the light source + if (dot(N, L) > 0) + { + // Calculate half vector + vec3 H = normalize(L + V); + + // Calculate specular intensity + specular = pow(dot(N, H), 3 + mat_glossiness); + } + + return (mat_specularColor*light_specularColor*light_specIntensity*specular); +} + +void main() +{ + // Normalize input vectors + vec3 L = normalize(lightPos); + vec3 V = normalize(cameraPos); + vec3 N = normalize(fragNormal); + + vec3 ambient = AmbientLighting(); + vec3 diffuse = DiffuseLighting(N, L); + vec3 specular = SpecularLighting(N, L, V); + + // Get base color from texture + vec4 textureColor = texture(texture0, fragTexCoord); + vec3 finalColor = textureColor.rgb; + + fragColor = vec4(finalColor * (ambient + diffuse + specular), textureColor.a); +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/phong.vs b/examples/resources/shaders/glsl330/phong.vs new file mode 100644 index 00000000..d68d9b3f --- /dev/null +++ b/examples/resources/shaders/glsl330/phong.vs @@ -0,0 +1,29 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; + +// Input uniform values +uniform mat4 mvpMatrix; + +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec3 fragNormal; + +// NOTE: Add here your custom variables +uniform mat4 modelMatrix; + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + + // Calculate view vector normal from model + mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); + fragNormal = normalize(normalMatrix*vertexNormal); + + // Calculate final vertex position + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/swirl.fs b/examples/resources/shaders/glsl330/swirl.fs new file mode 100644 index 00000000..b1dc82f0 --- /dev/null +++ b/examples/resources/shaders/glsl330/swirl.fs @@ -0,0 +1,46 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 fragTintColor; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +const float renderWidth = 800.0; // HARDCODED for example! +const float renderHeight = 480.0; // Use uniforms instead... + +float radius = 250.0; +float angle = 0.8; + +uniform vec2 center = vec2(200.0, 200.0); + +void main (void) +{ + vec2 texSize = vec2(renderWidth, renderHeight); + vec2 tc = fragTexCoord*texSize; + tc -= center; + + float dist = length(tc); + + if (dist < radius) + { + float percent = (radius - dist)/radius; + float theta = percent*percent*angle*8.0; + float s = sin(theta); + float c = cos(theta); + + tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); + } + + tc += center; + vec3 color = texture2D(texture0, tc/texSize).rgb; + + finalColor = vec4(color, 1.0);; +} \ No newline at end of file diff --git a/examples/resources/shaders/grayscale.fs b/examples/resources/shaders/grayscale.fs deleted file mode 100644 index af50b8c1..00000000 --- a/examples/resources/shaders/grayscale.fs +++ /dev/null @@ -1,20 +0,0 @@ -#version 330 - -in vec2 fragTexCoord; - -out vec4 fragColor; - -uniform sampler2D texture0; -uniform vec4 fragTintColor; - -// NOTE: Add here your custom variables - -void main() -{ - vec4 base = texture2D(texture0, fragTexCoord)*fragTintColor; - - // Convert to grayscale using NTSC conversion weights - float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114)); - - fragColor = vec4(gray, gray, gray, fragTintColor.a); -} \ No newline at end of file diff --git a/examples/resources/shaders/phong.fs b/examples/resources/shaders/phong.fs deleted file mode 100644 index f79413d9..00000000 --- a/examples/resources/shaders/phong.fs +++ /dev/null @@ -1,76 +0,0 @@ -#version 330 - -// Vertex shader input data -in vec2 fragTexCoord; -in vec3 fragNormal; - -// Diffuse data -uniform sampler2D texture0; -uniform vec4 fragTintColor; - -// Light attributes -uniform vec3 light_ambientColor = vec3(0.6, 0.3, 0.0); -uniform vec3 light_diffuseColor = vec3(1.0, 0.5, 0.0); -uniform vec3 light_specularColor = vec3(0.0, 1.0, 0.0); -uniform float light_intensity = 1.0; -uniform float light_specIntensity = 1.0; - -// Material attributes -uniform vec3 mat_ambientColor = vec3(1.0, 1.0, 1.0); -uniform vec3 mat_specularColor = vec3(1.0, 1.0, 1.0); -uniform float mat_glossiness = 50.0; - -// World attributes -uniform vec3 lightPos; -uniform vec3 cameraPos; - -// Fragment shader output data -out vec4 fragColor; - -vec3 AmbientLighting() -{ - return (mat_ambientColor*light_ambientColor); -} - -vec3 DiffuseLighting(in vec3 N, in vec3 L) -{ - // Lambertian reflection calculation - float diffuse = clamp(dot(N, L), 0, 1); - - return (fragTintColor.xyz*light_diffuseColor*light_intensity*diffuse); -} - -vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V) -{ - float specular = 0.0; - - // Calculate specular reflection only if the surface is oriented to the light source - if (dot(N, L) > 0) - { - // Calculate half vector - vec3 H = normalize(L + V); - - // Calculate specular intensity - specular = pow(dot(N, H), 3 + mat_glossiness); - } - - return (mat_specularColor*light_specularColor*light_specIntensity*specular); -} - -void main() -{ - // Normalize input vectors - vec3 L = normalize(lightPos); - vec3 V = normalize(cameraPos); - vec3 N = normalize(fragNormal); - - vec3 ambient = AmbientLighting(); - vec3 diffuse = DiffuseLighting(N, L); - vec3 specular = SpecularLighting(N, L, V); - - // Get base color from texture - vec4 textureColor = texture(texture0, fragTexCoord); - vec3 finalColor = textureColor.rgb; - - fragColor = vec4(finalColor * (ambient + diffuse + specular), textureColor.a); -} \ No newline at end of file diff --git a/examples/resources/shaders/phong.vs b/examples/resources/shaders/phong.vs deleted file mode 100644 index 52cc2227..00000000 --- a/examples/resources/shaders/phong.vs +++ /dev/null @@ -1,29 +0,0 @@ -#version 330 - -// Vertex input data -in vec3 vertexPosition; -in vec2 vertexTexCoord; -in vec3 vertexNormal; - -// Projection and model data -uniform mat4 mvpMatrix; - -uniform mat4 modelMatrix; -//uniform mat4 viewMatrix; // Not used - -// Attributes to fragment shader -out vec2 fragTexCoord; -out vec3 fragNormal; - -void main() -{ - // Send texture coord to fragment shader - fragTexCoord = vertexTexCoord; - - // Calculate view vector normal from model - mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); - fragNormal = normalize(normalMatrix*vertexNormal); - - // Calculate final vertex position - gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); -} \ No newline at end of file diff --git a/examples/resources/shaders/shapes_base.vs b/examples/resources/shaders/shapes_base.vs deleted file mode 100644 index ad272dc1..00000000 --- a/examples/resources/shaders/shapes_base.vs +++ /dev/null @@ -1,18 +0,0 @@ -#version 330 - -attribute vec3 vertexPosition; -attribute vec2 vertexTexCoord; -attribute vec4 vertexColor; - -uniform mat4 mvpMatrix; - -varying vec2 fragTexCoord; -varying vec4 fragTintColor; - -void main() -{ - fragTexCoord = vertexTexCoord; - fragTintColor = vertexColor; - - gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); -} \ No newline at end of file diff --git a/examples/resources/shaders/shapes_grayscale.fs b/examples/resources/shaders/shapes_grayscale.fs deleted file mode 100644 index 0698e1bf..00000000 --- a/examples/resources/shaders/shapes_grayscale.fs +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 - -uniform sampler2D texture0; -varying vec2 fragTexCoord; -varying vec4 fragTintColor; - -void main() -{ - vec4 base = texture2D(texture0, fragTexCoord)*fragTintColor; - - // Convert to grayscale using NTSC conversion weights - float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114)); - - gl_FragColor = vec4(gray, gray, gray, base.a); -} \ No newline at end of file diff --git a/examples/resources/shaders/swirl.fs b/examples/resources/shaders/swirl.fs deleted file mode 100644 index f89ef406..00000000 --- a/examples/resources/shaders/swirl.fs +++ /dev/null @@ -1,41 +0,0 @@ -#version 330 - -in vec2 fragTexCoord; - -out vec4 fragColor; - -uniform sampler2D texture0; -uniform vec4 fragTintColor; - -// NOTE: Add here your custom variables - -const float renderWidth = 800.0; // HARDCODED for example! -const float renderHeight = 480.0; // Use uniforms instead... - -float radius = 250.0; -float angle = 0.8; - -uniform vec2 center = vec2(200.0, 200.0); - -void main (void) -{ - vec2 texSize = vec2(renderWidth, renderHeight); - vec2 tc = fragTexCoord*texSize; - tc -= center; - float dist = length(tc); - - if (dist < radius) - { - float percent = (radius - dist)/radius; - float theta = percent*percent*angle*8.0; - float s = sin(theta); - float c = cos(theta); - - tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); - } - - tc += center; - vec3 color = texture2D(texture0, tc/texSize).rgb; - - fragColor = vec4(color, 1.0);; -} \ No newline at end of file diff --git a/examples/shaders_custom_uniform.c b/examples/shaders_custom_uniform.c index af59dc3c..ceaa86df 100644 --- a/examples/shaders_custom_uniform.c +++ b/examples/shaders_custom_uniform.c @@ -36,10 +36,10 @@ int main() Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture SetModelTexture(&dwarf, texture); // Bind texture to model - Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position - Shader shader = LoadShader("resources/shaders/base.vs", - "resources/shaders/swirl.fs"); // Load postpro shader + Shader shader = LoadShader("resources/shaders/glsl330/base.vs", + "resources/shaders/glsl330/swirl.fs"); // Load postpro shader // Get variable (uniform) location on the shader to connect with the program // NOTE: If uniform variable could not be found in the shader, function returns -1 diff --git a/examples/shaders_model_shader.c b/examples/shaders_model_shader.c index a10ec235..b302f631 100644 --- a/examples/shaders_model_shader.c +++ b/examples/shaders_model_shader.c @@ -34,8 +34,8 @@ int main() Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model Texture2D texture = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model texture - Shader shader = LoadShader("resources/shaders/base.vs", - "resources/shaders/grayscale.fs"); // Load model shader + Shader shader = LoadShader("resources/shaders/glsl330/base.vs", + "resources/shaders/glsl330/grayscale.fs"); // Load model shader SetModelShader(&dwarf, shader); // Set shader effect to 3d model SetModelTexture(&dwarf, texture); // Bind texture to model diff --git a/examples/shaders_postprocessing.c b/examples/shaders_postprocessing.c index 0bcd5156..632a6371 100644 --- a/examples/shaders_postprocessing.c +++ b/examples/shaders_postprocessing.c @@ -38,8 +38,8 @@ int main() Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position - Shader shader = LoadShader("resources/shaders/base.vs", - "resources/shaders/bloom.fs"); // Load postpro shader + Shader shader = LoadShader("resources/shaders/glsl330/base.vs", + "resources/shaders/glsl330/bloom.fs"); // Load postpro shader // Create a RenderTexture2D to be used for render to texture RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight); @@ -76,7 +76,7 @@ int main() End3dMode(); - DrawText("HELLO TEXTURE!!!", 120, 200, 60, RED); + DrawText("HELLO POSTPROCESSING!", 70, 190, 50, RED); EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) diff --git a/examples/shaders_shapes_textures.c b/examples/shaders_shapes_textures.c index 37180cec..1b1142fa 100644 --- a/examples/shaders_shapes_textures.c +++ b/examples/shaders_shapes_textures.c @@ -32,10 +32,9 @@ int main() Texture2D sonic = LoadTexture("resources/texture_formats/sonic.png"); - // NOTE: This shader is a bit different than model/postprocessing shaders, - // it requires the color data for every vertice to use it in every shape or texture independently - Shader shader = LoadShader("resources/shaders/shapes_base.vs", - "resources/shaders/shapes_grayscale.fs"); + // NOTE: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version + Shader shader = LoadShader("resources/shaders/glsl330/base.vs", + "resources/shaders/glsl330/grayscale.fs"); // Shader usage is also different than models/postprocessing, shader is just activated when required -- cgit v1.2.3 From 4b51248372302bd9f1baf2452b389f57f0173d59 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 7 Apr 2016 12:43:45 +0200 Subject: Review shader and add comments --- examples/resources/shaders/glsl330/phong.fs | 84 +++++++++++++++-------------- examples/shaders_basic_lighting.c | 22 ++++---- 2 files changed, 56 insertions(+), 50 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl330/phong.fs b/examples/resources/shaders/glsl330/phong.fs index 2e7a95f6..80e3d673 100644 --- a/examples/resources/shaders/glsl330/phong.fs +++ b/examples/resources/shaders/glsl330/phong.fs @@ -4,73 +4,79 @@ in vec2 fragTexCoord; in vec3 fragNormal; -// Diffuse data +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; -// Light attributes -uniform vec3 light_ambientColor = vec3(0.6, 0.3, 0.0); -uniform vec3 light_diffuseColor = vec3(1.0, 0.5, 0.0); -uniform vec3 light_specularColor = vec3(0.0, 1.0, 0.0); -uniform float light_intensity = 1.0; -uniform float light_specIntensity = 1.0; +// Output fragment color +out vec4 finalColor; -// Material attributes -uniform vec3 mat_ambientColor = vec3(1.0, 1.0, 1.0); -uniform vec3 mat_specularColor = vec3(1.0, 1.0, 1.0); -uniform float mat_glossiness = 50.0; +// NOTE: Add here your custom variables -// World attributes -uniform vec3 lightPos; -uniform vec3 cameraPos; +// Light uniform values +uniform vec3 lightAmbientColor = vec3(0.6, 0.3, 0.0); +uniform vec3 lightDiffuseColor = vec3(1.0, 0.5, 0.0); +uniform vec3 lightSpecularColor = vec3(0.0, 1.0, 0.0); +uniform float lightIntensity = 1.0; +uniform float lightSpecIntensity = 1.0; -// Fragment shader output data -out vec4 fragColor; +// Material uniform values +uniform vec3 matAmbientColor = vec3(1.0, 1.0, 1.0); +uniform vec3 matSpecularColor = vec3(1.0, 1.0, 1.0); +uniform float matGlossiness = 50.0; +// World uniform values +uniform vec3 lightPosition; +uniform vec3 cameraPosition; + +// Calculate ambient lighting component vec3 AmbientLighting() { - return (mat_ambientColor*light_ambientColor); + return (matAmbientColor*lightAmbientColor); } +// Calculate diffuse lighting component vec3 DiffuseLighting(in vec3 N, in vec3 L) { - // Lambertian reflection calculation - float diffuse = clamp(dot(N, L), 0, 1); - - return (fragTintColor.xyz*light_diffuseColor*light_intensity*diffuse); + // Lambertian reflection calculation + float diffuse = clamp(dot(N, L), 0, 1); + + return (fragTintColor.xyz*lightDiffuseColor*lightIntensity*diffuse); } +// Calculate specular lighting component vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V) { - float specular = 0.0; + float specular = 0.0; - // Calculate specular reflection only if the surface is oriented to the light source - if (dot(N, L) > 0) - { - // Calculate half vector - vec3 H = normalize(L + V); - - // Calculate specular intensity - specular = pow(dot(N, H), 3 + mat_glossiness); - } + // Calculate specular reflection only if the surface is oriented to the light source + if (dot(N, L) > 0) + { + // Calculate half vector + vec3 H = normalize(L + V); + + // Calculate specular intensity + specular = pow(dot(N, H), 3 + matGlossiness); + } - return (mat_specularColor*light_specularColor*light_specIntensity*specular); + return (matSpecularColor*lightSpecularColor*lightSpecIntensity*specular); } void main() { // Normalize input vectors - vec3 L = normalize(lightPos); - vec3 V = normalize(cameraPos); + vec3 L = normalize(lightPosition); + vec3 V = normalize(cameraPosition); vec3 N = normalize(fragNormal); + // Calculate lighting components vec3 ambient = AmbientLighting(); vec3 diffuse = DiffuseLighting(N, L); vec3 specular = SpecularLighting(N, L, V); - // Get base color from texture - vec4 textureColor = texture(texture0, fragTexCoord); - vec3 finalColor = textureColor.rgb; - - fragColor = vec4(finalColor * (ambient + diffuse + specular), textureColor.a); + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + + // Calculate final fragment color + finalColor = vec4(texelColor.rgb*(ambient + diffuse + specular), texelColor.a); } \ No newline at end of file diff --git a/examples/shaders_basic_lighting.c b/examples/shaders_basic_lighting.c index 18aea8e1..d72eb417 100644 --- a/examples/shaders_basic_lighting.c +++ b/examples/shaders_basic_lighting.c @@ -41,23 +41,23 @@ int main() // Model initialization Vector3 position = { 0.0f, 0.0f, 0.0f }; Model model = LoadModel("resources/model/dwarf.obj"); - Shader shader = LoadShader("resources/shaders/phong.vs", "resources/shaders/phong.fs"); + Shader shader = LoadShader("resources/shaders/glsl330/phong.vs", "resources/shaders/glsl330/phong.fs"); SetModelShader(&model, shader); // Shader locations initialization - int lIntensityLoc = GetShaderLocation(shader, "light_intensity"); - int lAmbientLoc = GetShaderLocation(shader, "light_ambientColor"); - int lDiffuseLoc = GetShaderLocation(shader, "light_diffuseColor"); - int lSpecularLoc = GetShaderLocation(shader, "light_specularColor"); - int lSpecIntensityLoc = GetShaderLocation(shader, "light_specIntensity"); + int lIntensityLoc = GetShaderLocation(shader, "lightIntensity"); + int lAmbientLoc = GetShaderLocation(shader, "lightAmbientColor"); + int lDiffuseLoc = GetShaderLocation(shader, "lightDiffuseColor"); + int lSpecularLoc = GetShaderLocation(shader, "lightSpecularColor"); + int lSpecIntensityLoc = GetShaderLocation(shader, "lightSpecIntensity"); - int mAmbientLoc = GetShaderLocation(shader, "mat_ambientColor"); - int mSpecularLoc = GetShaderLocation(shader, "mat_specularColor"); - int mGlossLoc = GetShaderLocation(shader, "mat_glossiness"); + int mAmbientLoc = GetShaderLocation(shader, "matAmbientColor"); + int mSpecularLoc = GetShaderLocation(shader, "matSpecularColor"); + int mGlossLoc = GetShaderLocation(shader, "matGlossiness"); // Camera and light vectors shader locations - int cameraLoc = GetShaderLocation(shader, "cameraPos"); - int lightLoc = GetShaderLocation(shader, "lightPos"); + int cameraLoc = GetShaderLocation(shader, "cameraPosition"); + int lightLoc = GetShaderLocation(shader, "lightPosition"); // Model and View matrix locations (required for lighting) int modelLoc = GetShaderLocation(shader, "modelMatrix"); -- cgit v1.2.3 From cde2c1aa6db6577fa415d60280aa53a86b3cc97a Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 8 Apr 2016 00:21:21 +0200 Subject: Added depth drawing shader NOTE: It requires a depth texture as input, it should be configured on rlgl, by default RenderTexture (fbo) uses Depth Renderbuffer instead of Depth Texture. Check rlglLoadRenderTexture() --- examples/resources/shaders/glsl330/depth.fs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 examples/resources/shaders/glsl330/depth.fs (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl330/depth.fs b/examples/resources/shaders/glsl330/depth.fs new file mode 100644 index 00000000..06d399f9 --- /dev/null +++ b/examples/resources/shaders/glsl330/depth.fs @@ -0,0 +1,27 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; // Depth texture +uniform vec4 fragTintColor; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + float zNear = 0.01; // camera z near + float zFar = 10.0; // camera z far + float z = texture(texture0, fragTexCoord).x; + + // Linearize depth value + float depth = (2.0*zNear)/(zFar + zNear - z*(zFar - zNear)); + + // Calculate final fragment color + finalColor = vec4(depth, depth, depth, 1.0f); +} \ No newline at end of file -- cgit v1.2.3 From 0e29aa2951fe11e9d0fabec2182ed6309fce37bb Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 17 May 2016 00:39:56 +0200 Subject: Corrected function name texture2D() is deprecated on GLSL 330 --- examples/resources/shaders/glsl330/bloom.fs | 2 +- examples/resources/shaders/glsl330/swirl.fs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl330/bloom.fs b/examples/resources/shaders/glsl330/bloom.fs index c8cb0d32..47ddee30 100644 --- a/examples/resources/shaders/glsl330/bloom.fs +++ b/examples/resources/shaders/glsl330/bloom.fs @@ -22,7 +22,7 @@ void main() { for (int j = -3; j < 3; j++) { - sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25; + sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25; } } diff --git a/examples/resources/shaders/glsl330/swirl.fs b/examples/resources/shaders/glsl330/swirl.fs index b1dc82f0..da098754 100644 --- a/examples/resources/shaders/glsl330/swirl.fs +++ b/examples/resources/shaders/glsl330/swirl.fs @@ -40,7 +40,7 @@ void main (void) } tc += center; - vec3 color = texture2D(texture0, tc/texSize).rgb; + vec3 color = texture(texture0, tc/texSize).rgb; finalColor = vec4(color, 1.0);; } \ No newline at end of file -- cgit v1.2.3 From bc08271da3e68d2880f4ef712c13e88b99f1021d Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 18 May 2016 12:04:27 +0200 Subject: Updated shaders with comments --- examples/resources/shaders/glsl100/bloom.fs | 2 +- examples/resources/shaders/glsl100/swirl.fs | 2 +- examples/resources/shaders/glsl330/bloom.fs | 2 +- examples/resources/shaders/glsl330/phong.fs | 3 + examples/resources/shaders/glsl330/swirl.fs | 2 +- shaders/glsl100/base.vs | 14 +++-- shaders/glsl100/bloom.fs | 25 ++++----- shaders/glsl100/blur.fs | 5 ++ shaders/glsl100/cross_hatching.fs | 5 +- shaders/glsl100/cross_stitching.fs | 5 +- shaders/glsl100/dream_vision.fs | 3 + shaders/glsl100/fisheye.fs | 5 +- shaders/glsl100/grayscale.fs | 13 +++-- shaders/glsl100/pixel.fs | 3 + shaders/glsl100/posterization.fs | 3 + shaders/glsl100/predator.fs | 3 + shaders/glsl100/scanlines.fs | 5 +- shaders/glsl100/swirl.fs | 16 ++++-- shaders/glsl100/template.fs | 4 ++ shaders/glsl330/base.vs | 12 +++- shaders/glsl330/bloom.fs | 34 +++++------ shaders/glsl330/blur.fs | 19 ++++--- shaders/glsl330/cross_hatching.fs | 18 +++--- shaders/glsl330/cross_stitching.fs | 12 ++-- shaders/glsl330/depth.fs | 27 +++++++++ shaders/glsl330/grayscale.fs | 18 ++++-- shaders/glsl330/phong.fs | 87 ++++++++++++++++------------- shaders/glsl330/phong.vs | 14 +++-- shaders/glsl330/pixel.fs | 12 ++-- shaders/glsl330/posterization.fs | 23 +++++--- shaders/glsl330/predator.fs | 15 +++-- shaders/glsl330/scanlines.fs | 15 +++-- shaders/glsl330/swirl.fs | 17 ++++-- shaders/glsl330/template.fs | 11 +++- 34 files changed, 295 insertions(+), 159 deletions(-) create mode 100644 shaders/glsl330/depth.fs (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl100/bloom.fs b/examples/resources/shaders/glsl100/bloom.fs index 5a08843d..280d2fb6 100644 --- a/examples/resources/shaders/glsl100/bloom.fs +++ b/examples/resources/shaders/glsl100/bloom.fs @@ -33,5 +33,5 @@ void main() else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; else tc = sum*sum*0.0075 + texelColor; - finalColor = tc; + gl_FragColor = tc; } \ No newline at end of file diff --git a/examples/resources/shaders/glsl100/swirl.fs b/examples/resources/shaders/glsl100/swirl.fs index e77d4f87..0d6d24f2 100644 --- a/examples/resources/shaders/glsl100/swirl.fs +++ b/examples/resources/shaders/glsl100/swirl.fs @@ -20,7 +20,7 @@ float angle = 0.8; uniform vec2 center = vec2(200.0, 200.0); -void main (void) +void main() { vec2 texSize = vec2(renderWidth, renderHeight); vec2 tc = fragTexCoord*texSize; diff --git a/examples/resources/shaders/glsl330/bloom.fs b/examples/resources/shaders/glsl330/bloom.fs index 47ddee30..0307bc06 100644 --- a/examples/resources/shaders/glsl330/bloom.fs +++ b/examples/resources/shaders/glsl330/bloom.fs @@ -17,7 +17,7 @@ void main() { vec4 sum = vec4(0); vec4 tc = vec4(0); - + for (int i = -4; i < 4; i++) { for (int j = -3; j < 3; j++) diff --git a/examples/resources/shaders/glsl330/phong.fs b/examples/resources/shaders/glsl330/phong.fs index 80e3d673..c14b346a 100644 --- a/examples/resources/shaders/glsl330/phong.fs +++ b/examples/resources/shaders/glsl330/phong.fs @@ -29,6 +29,9 @@ uniform float matGlossiness = 50.0; uniform vec3 lightPosition; uniform vec3 cameraPosition; +// Fragment shader output data +out vec4 fragColor; + // Calculate ambient lighting component vec3 AmbientLighting() { diff --git a/examples/resources/shaders/glsl330/swirl.fs b/examples/resources/shaders/glsl330/swirl.fs index da098754..80c16cc9 100644 --- a/examples/resources/shaders/glsl330/swirl.fs +++ b/examples/resources/shaders/glsl330/swirl.fs @@ -21,7 +21,7 @@ float angle = 0.8; uniform vec2 center = vec2(200.0, 200.0); -void main (void) +void main() { vec2 texSize = vec2(renderWidth, renderHeight); vec2 tc = fragTexCoord*texSize; diff --git a/shaders/glsl100/base.vs b/shaders/glsl100/base.vs index 9f339382..e9386939 100644 --- a/shaders/glsl100/base.vs +++ b/shaders/glsl100/base.vs @@ -1,20 +1,26 @@ #version 100 +// Input vertex attributes attribute vec3 vertexPosition; attribute vec2 vertexTexCoord; attribute vec3 vertexNormal; +attribute vec4 vertexColor; -varying vec2 fragTexCoord; - +// Input uniform values uniform mat4 mvpMatrix; +// Output vertex attributes (to fragment shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + // NOTE: Add here your custom variables void main() { - vec3 normal = vertexNormal; - + // Send vertex attributes to fragment shader fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + // Calculate final vertex position gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); } \ No newline at end of file diff --git a/shaders/glsl100/bloom.fs b/shaders/glsl100/bloom.fs index 33754c7e..280d2fb6 100644 --- a/shaders/glsl100/bloom.fs +++ b/shaders/glsl100/bloom.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; @@ -22,21 +25,13 @@ void main() } } - if (texture2D(texture0, fragTexCoord).r < 0.3) - { - tc = sum*sum*0.012 + texture2D(texture0, fragTexCoord); - } - else - { - if (texture2D(texture0, fragTexCoord).r < 0.5) - { - tc = sum*sum*0.009 + texture2D(texture0, fragTexCoord); - } - else - { - tc = sum*sum*0.0075 + texture2D(texture0, fragTexCoord); - } - } + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + + // Calculate final fragment color + if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; + else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; + else tc = sum*sum*0.0075 + texelColor; gl_FragColor = tc; } \ No newline at end of file diff --git a/shaders/glsl100/blur.fs b/shaders/glsl100/blur.fs index a1069c6f..80d40834 100644 --- a/shaders/glsl100/blur.fs +++ b/shaders/glsl100/blur.fs @@ -2,7 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; @@ -16,6 +20,7 @@ float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 ); void main() { + // Texel color fetching from texture sampler vec3 tc = texture2D(texture0, fragTexCoord).rgb*weight[0]; for (int i = 1; i < 3; i++) diff --git a/shaders/glsl100/cross_hatching.fs b/shaders/glsl100/cross_hatching.fs index cf01b65e..1f7dab08 100644 --- a/shaders/glsl100/cross_hatching.fs +++ b/shaders/glsl100/cross_hatching.fs @@ -2,12 +2,15 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; -// NOTE: Add here your custom variables +// NOTE: Add here your custom variables float hatchOffsetY = 5.0f; float lumThreshold01 = 0.9f; diff --git a/shaders/glsl100/cross_stitching.fs b/shaders/glsl100/cross_stitching.fs index f1afef04..6fabc027 100644 --- a/shaders/glsl100/cross_stitching.fs +++ b/shaders/glsl100/cross_stitching.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; @@ -46,7 +49,7 @@ vec4 PostFX(sampler2D tex, vec2 uv) return c; } -void main(void) +void main() { vec3 tc = PostFX(texture0, fragTexCoord).rgb; diff --git a/shaders/glsl100/dream_vision.fs b/shaders/glsl100/dream_vision.fs index bb828970..d0cdc687 100644 --- a/shaders/glsl100/dream_vision.fs +++ b/shaders/glsl100/dream_vision.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; diff --git a/shaders/glsl100/fisheye.fs b/shaders/glsl100/fisheye.fs index e7a4485c..9dba297b 100644 --- a/shaders/glsl100/fisheye.fs +++ b/shaders/glsl100/fisheye.fs @@ -2,12 +2,15 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; -// NOTE: Add here your custom variables +// NOTE: Add here your custom variables const float PI = 3.1415926535; diff --git a/shaders/glsl100/grayscale.fs b/shaders/glsl100/grayscale.fs index e55545e2..f92ec335 100644 --- a/shaders/glsl100/grayscale.fs +++ b/shaders/glsl100/grayscale.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; @@ -11,10 +14,12 @@ uniform vec4 fragTintColor; void main() { - vec4 base = texture2D(texture0, fragTexCoord)*fragTintColor; + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor; - // Convert to grayscale using NTSC conversion weights - float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114)); + // Convert texel color to grayscale using NTSC conversion weights + float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); - gl_FragColor = vec4(gray, gray, gray, fragTintColor.a); + // Calculate final fragment color + gl_FragColor = vec4(gray, gray, gray, texelColor.a); } \ No newline at end of file diff --git a/shaders/glsl100/pixel.fs b/shaders/glsl100/pixel.fs index 552e8900..c532f219 100644 --- a/shaders/glsl100/pixel.fs +++ b/shaders/glsl100/pixel.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; diff --git a/shaders/glsl100/posterization.fs b/shaders/glsl100/posterization.fs index 4f4c4b93..801ca89c 100644 --- a/shaders/glsl100/posterization.fs +++ b/shaders/glsl100/posterization.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; diff --git a/shaders/glsl100/predator.fs b/shaders/glsl100/predator.fs index 2fbdc7af..1f0e2ce5 100644 --- a/shaders/glsl100/predator.fs +++ b/shaders/glsl100/predator.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; diff --git a/shaders/glsl100/scanlines.fs b/shaders/glsl100/scanlines.fs index 85de158d..d885e10b 100644 --- a/shaders/glsl100/scanlines.fs +++ b/shaders/glsl100/scanlines.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; @@ -14,7 +17,7 @@ float frequency = 720/3.0; uniform float time; -void main (void) +void main() { /* // Scanlines method 1 diff --git a/shaders/glsl100/swirl.fs b/shaders/glsl100/swirl.fs index b0d54b23..0d6d24f2 100644 --- a/shaders/glsl100/swirl.fs +++ b/shaders/glsl100/swirl.fs @@ -2,28 +2,32 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; // NOTE: Add here your custom variables -const float renderWidth = 1280; -const float renderHeight = 720; +const float renderWidth = 800.0; // HARDCODED for example! +const float renderHeight = 480.0; // Use uniforms instead... float radius = 250.0; float angle = 0.8; -uniform vec2 center = vec2(200, 200); +uniform vec2 center = vec2(200.0, 200.0); -void main (void) +void main() { vec2 texSize = vec2(renderWidth, renderHeight); vec2 tc = fragTexCoord*texSize; tc -= center; - float dist = length(tc); + float dist = length(tc); + if (dist < radius) { float percent = (radius - dist)/radius; @@ -33,7 +37,7 @@ void main (void) tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); } - + tc += center; vec3 color = texture2D(texture0, tc/texSize).rgb; diff --git a/shaders/glsl100/template.fs b/shaders/glsl100/template.fs index 1f4b8ccf..a3942890 100644 --- a/shaders/glsl100/template.fs +++ b/shaders/glsl100/template.fs @@ -2,8 +2,11 @@ precision mediump float; +// Input vertex attributes (from vertex shader) varying vec2 fragTexCoord; +varying vec4 fragColor; +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; @@ -11,6 +14,7 @@ uniform vec4 fragTintColor; void main() { + // Texel color fetching from texture sampler vec4 texelColor = texture2D(texture0, fragTexCoord); // NOTE: Implement here your fragment shader code diff --git a/shaders/glsl330/base.vs b/shaders/glsl330/base.vs index b0f930b7..638cb8ae 100644 --- a/shaders/glsl330/base.vs +++ b/shaders/glsl330/base.vs @@ -1,18 +1,26 @@ #version 330 +// Input vertex attributes in vec3 vertexPosition; in vec2 vertexTexCoord; in vec3 vertexNormal; +in vec4 vertexColor; -out vec2 fragTexCoord; - +// Input uniform values uniform mat4 mvpMatrix; +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec4 fragColor; + // NOTE: Add here your custom variables void main() { + // Send vertex attributes to fragment shader fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + // Calculate final vertex position gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); } \ No newline at end of file diff --git a/shaders/glsl330/bloom.fs b/shaders/glsl330/bloom.fs index 34b6295c..0307bc06 100644 --- a/shaders/glsl330/bloom.fs +++ b/shaders/glsl330/bloom.fs @@ -1,12 +1,16 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables void main() @@ -18,25 +22,17 @@ void main() { for (int j = -3; j < 3; j++) { - sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25; + sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25; } } - if (texture(texture0, fragTexCoord).r < 0.3) - { - tc = sum*sum*0.012 + texture(texture0, fragTexCoord); - } - else - { - if (texture(texture0, fragTexCoord).r < 0.5) - { - tc = sum*sum*0.009 + texture(texture0, fragTexCoord); - } - else - { - tc = sum*sum*0.0075 + texture(texture0, fragTexCoord); - } - } + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); - fragColor = tc; + // Calculate final fragment color + if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; + else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; + else tc = sum*sum*0.0075 + texelColor; + + finalColor = tc; } \ No newline at end of file diff --git a/shaders/glsl330/blur.fs b/shaders/glsl330/blur.fs index 44ea42b1..7c31f727 100644 --- a/shaders/glsl330/blur.fs +++ b/shaders/glsl330/blur.fs @@ -1,12 +1,16 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables const float renderWidth = 1280.0; @@ -17,13 +21,14 @@ float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703); void main() { - vec3 tc = texture(texture0, fragTexCoord).rgb*weight[0]; - + // Texel color fetching from texture sampler + vec3 texelColor = texture(texture0, fragTexCoord).rgb*weight[0]; + for (int i = 1; i < 3; i++) { - tc += texture(texture0, fragTexCoord + vec2(offset[i])/renderWidth, 0.0).rgb*weight[i]; - tc += texture(texture0, fragTexCoord - vec2(offset[i])/renderWidth, 0.0).rgb*weight[i]; + texelColor += texture(texture0, fragTexCoord + vec2(offset[i])/renderWidth, 0.0).rgb*weight[i]; + texelColor += texture(texture0, fragTexCoord - vec2(offset[i])/renderWidth, 0.0).rgb*weight[i]; } - fragColor = vec4(tc, 1.0); + finalColor = vec4(texelColor, 1.0); } \ No newline at end of file diff --git a/shaders/glsl330/cross_hatching.fs b/shaders/glsl330/cross_hatching.fs index 6f5df964..c12c48cd 100644 --- a/shaders/glsl330/cross_hatching.fs +++ b/shaders/glsl330/cross_hatching.fs @@ -1,13 +1,17 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; -// NOTE: Add here your custom variables +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables float hatchOffsetY = 5.0; float lumThreshold01 = 0.9; @@ -27,18 +31,18 @@ void main() if (lum < lumThreshold02) { - if (mod(gl_FragCoord .x - gl_FragCoord .y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); } if (lum < lumThreshold03) { - if (mod(gl_FragCoord .x + gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + if (mod(gl_FragCoord.x + gl_FragCoord.y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); } if (lum < lumThreshold04) { - if (mod(gl_FragCoord .x - gl_FragCoord .y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); + if (mod(gl_FragCoord.x - gl_FragCoord.y - hatchOffsetY, 10.0) == 0.0) tc = vec3(0.0, 0.0, 0.0); } - fragColor = vec4(tc, 1.0); + finalColor = vec4(tc, 1.0); } \ No newline at end of file diff --git a/shaders/glsl330/cross_stitching.fs b/shaders/glsl330/cross_stitching.fs index dcb26e79..7c87c6cd 100644 --- a/shaders/glsl330/cross_stitching.fs +++ b/shaders/glsl330/cross_stitching.fs @@ -1,12 +1,16 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables const float renderWidth = 1280.0; @@ -46,9 +50,9 @@ vec4 PostFX(sampler2D tex, vec2 uv) return c; } -void main(void) +void main() { vec3 tc = PostFX(texture0, fragTexCoord).rgb; - fragColor = vec4(tc, 1.0); + finalColor = vec4(tc, 1.0); } \ No newline at end of file diff --git a/shaders/glsl330/depth.fs b/shaders/glsl330/depth.fs new file mode 100644 index 00000000..06d399f9 --- /dev/null +++ b/shaders/glsl330/depth.fs @@ -0,0 +1,27 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; // Depth texture +uniform vec4 fragTintColor; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + float zNear = 0.01; // camera z near + float zFar = 10.0; // camera z far + float z = texture(texture0, fragTexCoord).x; + + // Linearize depth value + float depth = (2.0*zNear)/(zFar + zNear - z*(zFar - zNear)); + + // Calculate final fragment color + finalColor = vec4(depth, depth, depth, 1.0f); +} \ No newline at end of file diff --git a/shaders/glsl330/grayscale.fs b/shaders/glsl330/grayscale.fs index b3a695bf..d4a8824f 100644 --- a/shaders/glsl330/grayscale.fs +++ b/shaders/glsl330/grayscale.fs @@ -1,20 +1,26 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables void main() { - vec4 base = texture(texture0, fragTexCoord)*fragTintColor; + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor; - // Convert to grayscale using NTSC conversion weights - float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114)); + // Convert texel color to grayscale using NTSC conversion weights + float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); - fragColor = vec4(gray, gray, gray, fragTintColor.a); + // Calculate final fragment color + finalColor = vec4(gray, gray, gray, texelColor.a); } \ No newline at end of file diff --git a/shaders/glsl330/phong.fs b/shaders/glsl330/phong.fs index 75b7e6d7..c14b346a 100644 --- a/shaders/glsl330/phong.fs +++ b/shaders/glsl330/phong.fs @@ -1,76 +1,85 @@ #version 330 -// Vertex shader input data +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; in vec3 fragNormal; -// Diffuse data +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; -// Light attributes -uniform vec3 light_ambientColor = vec3(0.6, 0.3, 0); -uniform vec3 light_diffuseColor = vec3(1, 0.5, 0); -uniform vec3 light_specularColor = vec3(0, 1, 0); -uniform float light_intensity = 1; -uniform float light_specIntensity = 1; +// Output fragment color +out vec4 finalColor; -// Material attributes -uniform vec3 mat_ambientColor = vec3(1, 1, 1); -uniform vec3 mat_specularColor = vec3(1, 1, 1); -uniform float mat_glossiness = 50; +// NOTE: Add here your custom variables -// World attributes -uniform vec3 lightPos; -uniform vec3 cameraPos; +// Light uniform values +uniform vec3 lightAmbientColor = vec3(0.6, 0.3, 0.0); +uniform vec3 lightDiffuseColor = vec3(1.0, 0.5, 0.0); +uniform vec3 lightSpecularColor = vec3(0.0, 1.0, 0.0); +uniform float lightIntensity = 1.0; +uniform float lightSpecIntensity = 1.0; + +// Material uniform values +uniform vec3 matAmbientColor = vec3(1.0, 1.0, 1.0); +uniform vec3 matSpecularColor = vec3(1.0, 1.0, 1.0); +uniform float matGlossiness = 50.0; + +// World uniform values +uniform vec3 lightPosition; +uniform vec3 cameraPosition; // Fragment shader output data out vec4 fragColor; +// Calculate ambient lighting component vec3 AmbientLighting() { - return mat_ambientColor * light_ambientColor; + return (matAmbientColor*lightAmbientColor); } +// Calculate diffuse lighting component vec3 DiffuseLighting(in vec3 N, in vec3 L) { - // Lambertian reflection calculation - float diffuse = clamp(dot(N, L), 0, 1); - - return tintColor.xyz * light_diffuseColor * light_intensity * diffuse; + // Lambertian reflection calculation + float diffuse = clamp(dot(N, L), 0, 1); + + return (fragTintColor.xyz*lightDiffuseColor*lightIntensity*diffuse); } +// Calculate specular lighting component vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V) { - float specular = 0; - - // Calculate specular reflection only if the surface is oriented to the light source - if(dot(N, L) > 0) - { - // Calculate half vector - vec3 H = normalize(L + V); - - // Calculate specular intensity - specular = pow(dot(N, H), 3 + mat_glossiness); - } + float specular = 0.0; + + // Calculate specular reflection only if the surface is oriented to the light source + if (dot(N, L) > 0) + { + // Calculate half vector + vec3 H = normalize(L + V); + + // Calculate specular intensity + specular = pow(dot(N, H), 3 + matGlossiness); + } - return mat_specularColor * light_specularColor * light_specIntensity * specular; + return (matSpecularColor*lightSpecularColor*lightSpecIntensity*specular); } void main() { // Normalize input vectors - vec3 L = normalize(lightPos); - vec3 V = normalize(cameraPos); + vec3 L = normalize(lightPosition); + vec3 V = normalize(cameraPosition); vec3 N = normalize(fragNormal); + // Calculate lighting components vec3 ambient = AmbientLighting(); vec3 diffuse = DiffuseLighting(N, L); vec3 specular = SpecularLighting(N, L, V); - // Get base color from texture - vec4 textureColor = texture(texture0, fragTexCoord); - vec3 finalColor = textureColor.rgb; - - fragColor = vec4(finalColor * (ambient + diffuse + specular), textureColor.a); + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + + // Calculate final fragment color + finalColor = vec4(texelColor.rgb*(ambient + diffuse + specular), texelColor.a); } \ No newline at end of file diff --git a/shaders/glsl330/phong.vs b/shaders/glsl330/phong.vs index ee6d34bf..d68d9b3f 100644 --- a/shaders/glsl330/phong.vs +++ b/shaders/glsl330/phong.vs @@ -1,23 +1,25 @@ #version 330 -// Vertex input data +// Input vertex attributes in vec3 vertexPosition; in vec2 vertexTexCoord; in vec3 vertexNormal; -// Projection and model data +// Input uniform values uniform mat4 mvpMatrix; -uniform mat4 modelMatrix; -// Attributes to fragment shader +// Output vertex attributes (to fragment shader) out vec2 fragTexCoord; out vec3 fragNormal; +// NOTE: Add here your custom variables +uniform mat4 modelMatrix; + void main() { - // Send texture coord to fragment shader + // Send vertex attributes to fragment shader fragTexCoord = vertexTexCoord; - + // Calculate view vector normal from model mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); fragNormal = normalize(normalMatrix*vertexNormal); diff --git a/shaders/glsl330/pixel.fs b/shaders/glsl330/pixel.fs index aa5a22fe..9ed3ea7d 100644 --- a/shaders/glsl330/pixel.fs +++ b/shaders/glsl330/pixel.fs @@ -1,13 +1,17 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; -// NOTE: Add here your custom variables +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables const float renderWidth = 1280.0; const float renderHeight = 720.0; @@ -24,5 +28,5 @@ void main() vec3 tc = texture(texture0, coord).rgb; - fragColor = vec4(tc, 1.0); + finalColor = vec4(tc, 1.0); } \ No newline at end of file diff --git a/shaders/glsl330/posterization.fs b/shaders/glsl330/posterization.fs index 5215bd8b..f1d72a19 100644 --- a/shaders/glsl330/posterization.fs +++ b/shaders/glsl330/posterization.fs @@ -1,12 +1,16 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables float gamma = 0.6; @@ -14,13 +18,14 @@ float numColors = 8.0; void main() { - vec3 color = texture(texture0, fragTexCoord.xy).rgb; + // Texel color fetching from texture sampler + vec3 texelColor = texture(texture0, fragTexCoord.xy).rgb; - color = pow(color, vec3(gamma, gamma, gamma)); - color = color*numColors; - color = floor(color); - color = color/numColors; - color = pow(color, vec3(1.0/gamma)); + texelColor = pow(texelColor, vec3(gamma, gamma, gamma)); + texelColor = texelColor*numColors; + texelColor = floor(texelColor); + texelColor = texelColor/numColors; + texelColor = pow(texelColor, vec3(1.0/gamma)); - fragColor = vec4(color, 1.0); + finalColor = vec4(texelColor, 1.0); } \ No newline at end of file diff --git a/shaders/glsl330/predator.fs b/shaders/glsl330/predator.fs index 85c93d0c..9269dfd4 100644 --- a/shaders/glsl330/predator.fs +++ b/shaders/glsl330/predator.fs @@ -1,27 +1,32 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables void main() { - vec3 color = texture(texture0, fragTexCoord).rgb; + // Texel color fetching from texture sampler + vec3 texelColor = texture(texture0, fragTexCoord).rgb; vec3 colors[3]; colors[0] = vec3(0.0, 0.0, 1.0); colors[1] = vec3(1.0, 1.0, 0.0); colors[2] = vec3(1.0, 0.0, 0.0); - float lum = (color.r + color.g + color.b)/3.0; + float lum = (texelColor.r + texelColor.g + texelColor.b)/3.0; int ix = (lum < 0.5)? 0:1; vec3 tc = mix(colors[ix], colors[ix + 1], (lum - float(ix)*0.5)/0.5); - fragColor = vec4(tc, 1.0); + finalColor = vec4(tc, 1.0); } \ No newline at end of file diff --git a/shaders/glsl330/scanlines.fs b/shaders/glsl330/scanlines.fs index 0c89e610..177f000d 100644 --- a/shaders/glsl330/scanlines.fs +++ b/shaders/glsl330/scanlines.fs @@ -1,12 +1,16 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables float offset = 0.0; @@ -14,7 +18,7 @@ float frequency = 720.0/3.0; uniform float time; -void main (void) +void main() { /* // Scanlines method 1 @@ -35,7 +39,8 @@ void main (void) float globalPos = (fragTexCoord.y + offset) * frequency; float wavePos = cos((fract(globalPos) - 0.5)*3.14); - vec4 color = texture(texture0, fragTexCoord); + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); - fragColor = mix(vec4(0.0, 0.3, 0.0, 0.0), color, wavePos); + finalColor = mix(vec4(0.0, 0.3, 0.0, 0.0), texelColor, wavePos); } \ No newline at end of file diff --git a/shaders/glsl330/swirl.fs b/shaders/glsl330/swirl.fs index 19d7468b..80c16cc9 100644 --- a/shaders/glsl330/swirl.fs +++ b/shaders/glsl330/swirl.fs @@ -1,27 +1,32 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables -const float renderWidth = 1280.0; -const float renderHeight = 720.0; +const float renderWidth = 800.0; // HARDCODED for example! +const float renderHeight = 480.0; // Use uniforms instead... float radius = 250.0; float angle = 0.8; uniform vec2 center = vec2(200.0, 200.0); -void main (void) +void main() { vec2 texSize = vec2(renderWidth, renderHeight); vec2 tc = fragTexCoord*texSize; tc -= center; + float dist = length(tc); if (dist < radius) @@ -37,5 +42,5 @@ void main (void) tc += center; vec3 color = texture(texture0, tc/texSize).rgb; - fragColor = vec4(color, 1.0);; + finalColor = vec4(color, 1.0);; } \ No newline at end of file diff --git a/shaders/glsl330/template.fs b/shaders/glsl330/template.fs index ad7210a4..55b8d4a4 100644 --- a/shaders/glsl330/template.fs +++ b/shaders/glsl330/template.fs @@ -1,19 +1,24 @@ #version 330 +// Input vertex attributes (from vertex shader) in vec2 fragTexCoord; +in vec4 fragColor; -out vec4 fragColor; - +// Input uniform values uniform sampler2D texture0; uniform vec4 fragTintColor; +// Output fragment color +out vec4 finalColor; + // NOTE: Add here your custom variables void main() { + // Texel color fetching from texture sampler vec4 texelColor = texture(texture0, fragTexCoord); // NOTE: Implement here your fragment shader code - fragColor = texelColor*fragTintColor; + finalColor = texelColor*fragTintColor; } -- cgit v1.2.3 From 80eb4f3f50bb9773dd0e5d4b70c50e18df8996e5 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sat, 21 May 2016 18:11:25 +0200 Subject: Remove deprecated phong lighting shaders and example --- examples/resources/shaders/glsl330/phong.fs | 85 -------------- examples/resources/shaders/glsl330/phong.vs | 29 ----- examples/shaders_basic_lighting.c | 171 ---------------------------- 3 files changed, 285 deletions(-) delete mode 100644 examples/resources/shaders/glsl330/phong.fs delete mode 100644 examples/resources/shaders/glsl330/phong.vs delete mode 100644 examples/shaders_basic_lighting.c (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl330/phong.fs b/examples/resources/shaders/glsl330/phong.fs deleted file mode 100644 index c14b346a..00000000 --- a/examples/resources/shaders/glsl330/phong.fs +++ /dev/null @@ -1,85 +0,0 @@ -#version 330 - -// Input vertex attributes (from vertex shader) -in vec2 fragTexCoord; -in vec3 fragNormal; - -// Input uniform values -uniform sampler2D texture0; -uniform vec4 fragTintColor; - -// Output fragment color -out vec4 finalColor; - -// NOTE: Add here your custom variables - -// Light uniform values -uniform vec3 lightAmbientColor = vec3(0.6, 0.3, 0.0); -uniform vec3 lightDiffuseColor = vec3(1.0, 0.5, 0.0); -uniform vec3 lightSpecularColor = vec3(0.0, 1.0, 0.0); -uniform float lightIntensity = 1.0; -uniform float lightSpecIntensity = 1.0; - -// Material uniform values -uniform vec3 matAmbientColor = vec3(1.0, 1.0, 1.0); -uniform vec3 matSpecularColor = vec3(1.0, 1.0, 1.0); -uniform float matGlossiness = 50.0; - -// World uniform values -uniform vec3 lightPosition; -uniform vec3 cameraPosition; - -// Fragment shader output data -out vec4 fragColor; - -// Calculate ambient lighting component -vec3 AmbientLighting() -{ - return (matAmbientColor*lightAmbientColor); -} - -// Calculate diffuse lighting component -vec3 DiffuseLighting(in vec3 N, in vec3 L) -{ - // Lambertian reflection calculation - float diffuse = clamp(dot(N, L), 0, 1); - - return (fragTintColor.xyz*lightDiffuseColor*lightIntensity*diffuse); -} - -// Calculate specular lighting component -vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V) -{ - float specular = 0.0; - - // Calculate specular reflection only if the surface is oriented to the light source - if (dot(N, L) > 0) - { - // Calculate half vector - vec3 H = normalize(L + V); - - // Calculate specular intensity - specular = pow(dot(N, H), 3 + matGlossiness); - } - - return (matSpecularColor*lightSpecularColor*lightSpecIntensity*specular); -} - -void main() -{ - // Normalize input vectors - vec3 L = normalize(lightPosition); - vec3 V = normalize(cameraPosition); - vec3 N = normalize(fragNormal); - - // Calculate lighting components - vec3 ambient = AmbientLighting(); - vec3 diffuse = DiffuseLighting(N, L); - vec3 specular = SpecularLighting(N, L, V); - - // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord); - - // Calculate final fragment color - finalColor = vec4(texelColor.rgb*(ambient + diffuse + specular), texelColor.a); -} \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/phong.vs b/examples/resources/shaders/glsl330/phong.vs deleted file mode 100644 index d68d9b3f..00000000 --- a/examples/resources/shaders/glsl330/phong.vs +++ /dev/null @@ -1,29 +0,0 @@ -#version 330 - -// Input vertex attributes -in vec3 vertexPosition; -in vec2 vertexTexCoord; -in vec3 vertexNormal; - -// Input uniform values -uniform mat4 mvpMatrix; - -// Output vertex attributes (to fragment shader) -out vec2 fragTexCoord; -out vec3 fragNormal; - -// NOTE: Add here your custom variables -uniform mat4 modelMatrix; - -void main() -{ - // Send vertex attributes to fragment shader - fragTexCoord = vertexTexCoord; - - // Calculate view vector normal from model - mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); - fragNormal = normalize(normalMatrix*vertexNormal); - - // Calculate final vertex position - gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); -} \ No newline at end of file diff --git a/examples/shaders_basic_lighting.c b/examples/shaders_basic_lighting.c deleted file mode 100644 index d72eb417..00000000 --- a/examples/shaders_basic_lighting.c +++ /dev/null @@ -1,171 +0,0 @@ -/******************************************************************************************* -* -* raylib [shaders] example - Basic lighting: Blinn-Phong -* -* This example has been created using raylib 1.3 (www.raylib.com) -* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) -* -* Copyright (c) 2014 Ramon Santamaria (@raysan5) -* -********************************************************************************************/ - -#include "raylib.h" - -#define SHININESS_SPEED 1.0f -#define LIGHT_SPEED 0.25f - -// Light type -typedef struct Light { - Vector3 position; - Vector3 direction; - float intensity; - float specIntensity; - Color diffuse; - Color ambient; - Color specular; -} Light; - -int main() -{ - // Initialization - //-------------------------------------------------------------------------------------- - const int screenWidth = 800; - const int screenHeight = 450; - - SetConfigFlags(FLAG_MSAA_4X_HINT); - InitWindow(screenWidth, screenHeight, "raylib [shaders] example - basic lighting"); - - // Camera initialization - Camera camera = {{ 8.0f, 8.0f, 8.0f }, { 0.0f, 3.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; - - // Model initialization - Vector3 position = { 0.0f, 0.0f, 0.0f }; - Model model = LoadModel("resources/model/dwarf.obj"); - Shader shader = LoadShader("resources/shaders/glsl330/phong.vs", "resources/shaders/glsl330/phong.fs"); - SetModelShader(&model, shader); - - // Shader locations initialization - int lIntensityLoc = GetShaderLocation(shader, "lightIntensity"); - int lAmbientLoc = GetShaderLocation(shader, "lightAmbientColor"); - int lDiffuseLoc = GetShaderLocation(shader, "lightDiffuseColor"); - int lSpecularLoc = GetShaderLocation(shader, "lightSpecularColor"); - int lSpecIntensityLoc = GetShaderLocation(shader, "lightSpecIntensity"); - - int mAmbientLoc = GetShaderLocation(shader, "matAmbientColor"); - int mSpecularLoc = GetShaderLocation(shader, "matSpecularColor"); - int mGlossLoc = GetShaderLocation(shader, "matGlossiness"); - - // Camera and light vectors shader locations - int cameraLoc = GetShaderLocation(shader, "cameraPosition"); - int lightLoc = GetShaderLocation(shader, "lightPosition"); - - // Model and View matrix locations (required for lighting) - int modelLoc = GetShaderLocation(shader, "modelMatrix"); - //int viewLoc = GetShaderLocation(shader, "viewMatrix"); // Not used - - // Light and material definitions - Light light; - Material matBlinn; - - // Light initialization - light.position = (Vector3){ 4.0f, 2.0f, 0.0f }; - light.direction = (Vector3){ 5.0f, 1.0f, 1.0f }; - light.intensity = 1.0f; - light.diffuse = WHITE; - light.ambient = (Color){ 150, 75, 0, 255 }; - light.specular = WHITE; - light.specIntensity = 1.0f; - - // Material initialization - matBlinn.colDiffuse = WHITE; - matBlinn.colAmbient = (Color){ 50, 50, 50, 255 }; - matBlinn.colSpecular = WHITE; - matBlinn.glossiness = 50.0f; - - // Setup camera - SetCameraMode(CAMERA_FREE); // Set camera mode - SetCameraPosition(camera.position); // Set internal camera position to match our camera position - SetCameraTarget(camera.target); // Set internal camera target to match our camera target - - SetTargetFPS(60); - //-------------------------------------------------------------------------------------- - - // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key - { - // Update - //---------------------------------------------------------------------------------- - UpdateCamera(&camera); // Update camera position - - // NOTE: Model transform can be set in model.transform or directly with params at draw... WATCH OUT! - SetShaderValueMatrix(shader, modelLoc, model.transform); // Send model matrix to shader - //SetShaderValueMatrix(shader, viewLoc, GetCameraMatrix(camera)); // Not used - - // Glossiness input control - if(IsKeyDown(KEY_UP)) matBlinn.glossiness += SHININESS_SPEED; - else if(IsKeyDown(KEY_DOWN)) - { - matBlinn.glossiness -= SHININESS_SPEED; - if( matBlinn.glossiness < 0) matBlinn.glossiness = 0.0f; - } - - // Light X movement - if (IsKeyDown(KEY_D)) light.position.x += LIGHT_SPEED; - else if(IsKeyDown(KEY_A)) light.position.x -= LIGHT_SPEED; - - // Light Y movement - if (IsKeyDown(KEY_LEFT_SHIFT)) light.position.y += LIGHT_SPEED; - else if (IsKeyDown(KEY_LEFT_CONTROL)) light.position.y -= LIGHT_SPEED; - - // Light Z movement - if (IsKeyDown(KEY_S)) light.position.z += LIGHT_SPEED; - else if (IsKeyDown(KEY_W)) light.position.z -= LIGHT_SPEED; - - // Send light values to shader - SetShaderValue(shader, lIntensityLoc, &light.intensity, 1); - SetShaderValue(shader, lAmbientLoc, ColorToFloat(light.ambient), 3); - SetShaderValue(shader, lDiffuseLoc, ColorToFloat(light.diffuse), 3); - SetShaderValue(shader, lSpecularLoc, ColorToFloat(light.specular), 3); - SetShaderValue(shader, lSpecIntensityLoc, &light.specIntensity, 1); - - // Send material values to shader - SetShaderValue(shader, mAmbientLoc, ColorToFloat(matBlinn.colAmbient), 3); - SetShaderValue(shader, mSpecularLoc, ColorToFloat(matBlinn.colSpecular), 3); - SetShaderValue(shader, mGlossLoc, &matBlinn.glossiness, 1); - - // Send camera and light transform values to shader - SetShaderValue(shader, cameraLoc, VectorToFloat(camera.position), 3); - SetShaderValue(shader, lightLoc, VectorToFloat(light.position), 3); - //---------------------------------------------------------------------------------- - - // Draw - //---------------------------------------------------------------------------------- - BeginDrawing(); - - ClearBackground(RAYWHITE); - - Begin3dMode(camera); - - DrawModel(model, position, 4.0f, matBlinn.colDiffuse); - DrawSphere(light.position, 0.5f, GOLD); - - DrawGrid(20, 1.0f); - - End3dMode(); - - DrawFPS(10, 10); // Draw FPS - - EndDrawing(); - //---------------------------------------------------------------------------------- - } - - // De-Initialization - //-------------------------------------------------------------------------------------- - UnloadShader(shader); - UnloadModel(model); - - CloseWindow(); // Close window and OpenGL context - //-------------------------------------------------------------------------------------- - - return 0; -} -- cgit v1.2.3 From c320a21f2b0e96f7605624e84048ccab9700b516 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sat, 21 May 2016 18:16:39 +0200 Subject: Add standard lighting (2/3) - 3 light types added (point, directional, spot). - DrawLights() function added using line shapes. - Standard lighting example added. - Removed useless struct variables from material and light. - Fixed light attributes dynamic locations errors. - Standard vertex and fragment shaders temporally added until rewrite it as char pointers in rlgl. TODO: - Add normal and specular maps calculations in standard shader. - Add control structs to handle which attributes needs to be calculated (textures, specular...). - Adapt standard shader to version 110. - Rewrite standard shader as char pointers in rlgl. --- examples/resources/shaders/standard.fs | 136 +++++++++++++++++++++ examples/resources/shaders/standard.vs | 23 ++++ examples/shaders_standard_lighting.c | 118 ++++++++++++++++++ src/raylib.h | 15 ++- src/rlgl.c | 213 ++++++++++++++------------------- src/rlgl.h | 32 ++--- 6 files changed, 388 insertions(+), 149 deletions(-) create mode 100644 examples/resources/shaders/standard.fs create mode 100644 examples/resources/shaders/standard.vs create mode 100644 examples/shaders_standard_lighting.c (limited to 'examples/resources') diff --git a/examples/resources/shaders/standard.fs b/examples/resources/shaders/standard.fs new file mode 100644 index 00000000..30c841d2 --- /dev/null +++ b/examples/resources/shaders/standard.fs @@ -0,0 +1,136 @@ +#version 330 + +in vec3 fragPosition; +in vec2 fragTexCoord; +in vec4 fragColor; +in vec3 fragNormal; + +out vec4 finalColor; + +uniform sampler2D texture0; + +uniform vec4 colAmbient; +uniform vec4 colDiffuse; +uniform vec4 colSpecular; +uniform float glossiness; + +uniform mat4 modelMatrix; +uniform vec3 viewDir; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 direction; + vec4 diffuse; + float intensity; + float attenuation; + float coneAngle; +}; + +const int maxLights = 8; +uniform int lightsCount; +uniform Light lights[maxLights]; + +vec3 CalcPointLight(Light l, vec3 n, vec3 v) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 surfaceToLight = l.position - surfacePos; + + // Diffuse shading + float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1); + float diff = 1.0/dot(surfaceToLight/l.attenuation, surfaceToLight/l.attenuation)*brightness*l.intensity; + + // Specular shading + float spec = 0.0; + if(diff > 0.0) + { + vec3 h = normalize(-l.direction + v); + spec = pow(dot(n, h), 3 + glossiness); + } + + return (diff*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v) +{ + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Specular shading + float spec = 0.0; + if(diff > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness); + } + + // Combine results + return (diff*l.intensity*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcSpotLight(Light l, vec3 n, vec3 v) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 lightToSurface = normalize(surfacePos - l.position); + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Spot attenuation + float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); + attenuation = dot(lightToSurface, -lightDir); + float lightToSurfaceAngle = degrees(acos(attenuation)); + if(lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; + + // Combine diffuse and attenuation + float diffAttenuation = diff*attenuation; + + // Specular shading + float spec = 0.0; + if(diffAttenuation > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness); + } + + return falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb); +} + +void main() +{ + // Calculate fragment normal in screen space + mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); + vec3 normal = normalize(normalMatrix*fragNormal); + + // Normalize normal and view direction vectors + vec3 n = normalize(normal); + vec3 v = normalize(viewDir); + + // Calculate diffuse texture color fetching + vec4 texelColor = texture(texture0, fragTexCoord); + vec3 lighting = colAmbient.rgb; + + for(int i = 0; i < lightsCount; i++) + { + // Check if light is enabled + if(lights[i].enabled == 1) + { + // Calculate lighting based on light type + switch(lights[i].type) + { + case 0: lighting += CalcPointLight(lights[i], n, v); break; + case 1: lighting += CalcDirectionalLight(lights[i], n, v); break; + case 2: lighting += CalcSpotLight(lights[i], n, v); break; + default: break; + } + } + } + + // Calculate final fragment color + finalColor = vec4(texelColor.rgb*lighting, texelColor.a); +} diff --git a/examples/resources/shaders/standard.vs b/examples/resources/shaders/standard.vs new file mode 100644 index 00000000..fc0a5ff4 --- /dev/null +++ b/examples/resources/shaders/standard.vs @@ -0,0 +1,23 @@ +#version 330 + +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec2 vertexTexCoord; +in vec4 vertexColor; + +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec4 fragColor; +out vec3 fragNormal; + +uniform mat4 mvpMatrix; + +void main() +{ + fragPosition = vertexPosition; + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = vertexNormal; + + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/examples/shaders_standard_lighting.c b/examples/shaders_standard_lighting.c new file mode 100644 index 00000000..7a9cc086 --- /dev/null +++ b/examples/shaders_standard_lighting.c @@ -0,0 +1,118 @@ +/******************************************************************************************* +* +* raylib [shaders] example - Standard lighting (materials and lights) +* +* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, +* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version. +* +* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example +* on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders +* raylib comes with shaders ready for both versions, check raylib/shaders install folder +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2016 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "raymath.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + SetConfigFlags(FLAG_MSAA_4X_HINT); // Enable Multi Sampling Anti Aliasing 4x (if available) + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - model shader"); + + // Define the camera to look into our 3d world + Camera camera = {{ 4.0f, 4.0f, 4.0f }, { 0.0f, 1.5f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position + + Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model + Texture2D texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture + + Material material = LoadStandardMaterial(); + material.texDiffuse = texDiffuse; + material.colDiffuse = (Color){255, 255, 255, 255}; + material.colAmbient = (Color){0, 0, 10, 255}; + material.colSpecular = (Color){255, 255, 255, 255}; + material.glossiness = 50.0f; + dwarf.material = material; // Apply material to model + + Light spotLight = CreateLight(LIGHT_SPOT, (Vector3){3.0f, 5.0f, 2.0f}, (Color){255, 255, 255, 255}); + spotLight->target = (Vector3){0.0f, 0.0f, 0.0f}; + spotLight->intensity = 2.0f; + spotLight->diffuse = (Color){255, 100, 100, 255}; + spotLight->coneAngle = 60.0f; + + Light dirLight = CreateLight(LIGHT_DIRECTIONAL, (Vector3){0.0f, -3.0f, -3.0f}, (Color){255, 255, 255, 255}); + dirLight->target = (Vector3){1.0f, -2.0f, -2.0f}; + dirLight->intensity = 2.0f; + dirLight->diffuse = (Color){100, 255, 100, 255}; + + Light pointLight = CreateLight(LIGHT_POINT, (Vector3){0.0f, 4.0f, 5.0f}, (Color){255, 255, 255, 255}); + pointLight->intensity = 2.0f; + pointLight->diffuse = (Color){100, 100, 255, 255}; + pointLight->attenuation = 3.0f; + + // Setup orbital camera + SetCameraMode(CAMERA_ORBITAL); // Set a orbital camera mode + SetCameraPosition(camera.position); // Set internal camera position to match our camera position + SetCameraTarget(camera.target); // Set internal camera target to match our camera target + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + UpdateCamera(&camera); // Update internal camera and our camera + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + Begin3dMode(camera); + + DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture + + DrawLights(); // Draw all created lights in 3D world + + DrawGrid(10, 1.0f); // Draw a grid + + End3dMode(); + + DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadMaterial(material); // Unload material and assigned textures + UnloadModel(dwarf); // Unload model + + // Destroy all created lights + DestroyLight(pointLight); + DestroyLight(dirLight); + DestroyLight(spotLight); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/src/raylib.h b/src/raylib.h index 48534fd6..9cd02fd8 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -418,7 +418,7 @@ typedef struct Material { Color colAmbient; // Ambient color Color colSpecular; // Specular color - float glossiness; // Glossiness level + float glossiness; // Glossiness level (Ranges from 0 to 1000) float normalDepth; // Normal map depth } Material; @@ -430,22 +430,19 @@ typedef struct Model { } Model; // Light type -// TODO: Review contained data to support different light types and features typedef struct LightData { int id; int type; // LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT bool enabled; Vector3 position; - Vector3 direction; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction) - float attenuation; // Lost of light intensity with distance (use radius?) + Vector3 target; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) + float attenuation; // Lost of light intensity with distance (world distance) - Color diffuse; // Use Vector3 diffuse (including intensities)? + Color diffuse; // Use Vector3 diffuse float intensity; - Color specular; - - float coneAngle; // SpotLight + float coneAngle; // Spot light max angle } LightData, *Light; // Light types @@ -805,6 +802,7 @@ const char *SubText(const char *text, int position, int length); //------------------------------------------------------------------------------------ // Basic 3d Shapes Drawing Functions (Module: models) //------------------------------------------------------------------------------------ +void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires @@ -874,6 +872,7 @@ void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // S void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool +void DrawLights(void); // Draw all created lights in 3D world void DestroyLight(Light light); // Destroy a light and take it out of the list //---------------------------------------------------------------------------------- diff --git a/src/rlgl.c b/src/rlgl.c index e2195e4d..55677f3e 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1773,6 +1773,9 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // Send model transformations matrix to shader glUniformMatrix4fv(glGetUniformLocation(material.shader.id, "modelMatrix"), 1, false, MatrixToFloat(transform)); + // Send view transformation matrix to shader. View matrix 8, 9 and 10 are view direction vector axis values (target - position) + glUniform3f(glGetUniformLocation(material.shader.id, "viewDir"), matView.m8, matView.m9, matView.m10); + // Setup shader uniforms for lights SetShaderLights(material.shader); @@ -1782,8 +1785,8 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // Upload to shader material.colSpecular glUniform4f(glGetUniformLocation(material.shader.id, "colSpecular"), (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255); - // TODO: Upload to shader glossiness - //glUniform1f(???, material.glossiness); + // Upload to shader glossiness + glUniform1f(glGetUniformLocation(material.shader.id, "glossiness"), material.glossiness); } // Set shader textures (diffuse, normal, specular) @@ -2245,7 +2248,6 @@ void SetBlendMode(int mode) } // Create a new light, initialize it and add to pool -// TODO: Review creation parameters (only generic ones) Light CreateLight(int type, Vector3 position, Color diffuse) { // Allocate dynamic memory @@ -2257,10 +2259,9 @@ Light CreateLight(int type, Vector3 position, Color diffuse) light->enabled = true; light->position = position; - light->direction = (Vector3){ 0.0f, 0.0f, 0.0f }; + light->target = (Vector3){ 0.0f, 0.0f, 0.0f }; light->intensity = 1.0f; light->diffuse = diffuse; - light->specular = WHITE; // Add new light to the array lights[lightsCount] = light; @@ -2271,6 +2272,31 @@ Light CreateLight(int type, Vector3 position, Color diffuse) return light; } +// Draw all created lights in 3D world +void DrawLights(void) +{ + for (int i = 0; i < lightsCount; i++) + { + switch (lights[i]->type) + { + case LIGHT_POINT: DrawSphereWires(lights[i]->position, 0.3f*lights[i]->intensity, 4, 8, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); break; + case LIGHT_DIRECTIONAL: + { + Draw3DLine(lights[i]->position, lights[i]->target, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); + DrawSphereWires(lights[i]->position, 0.3f*lights[i]->intensity, 4, 8, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); + DrawCubeWires(lights[i]->target, 0.3f, 0.3f, 0.3f, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); + } + case LIGHT_SPOT: + { + Draw3DLine(lights[i]->position, lights[i]->target, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); + DrawCylinderWires(lights[i]->position, 0.0f, 0.3f*lights[i]->coneAngle/50, 0.6f, 5, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); + DrawCubeWires(lights[i]->target, 0.3f, 0.3f, 0.3f, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); + } break; + default: break; + } + } +} + // Destroy a light and take it out of the list void DestroyLight(Light light) { @@ -2488,15 +2514,15 @@ static Shader LoadDefaultShader(void) "varying vec4 fragColor; \n" #endif "uniform sampler2D texture0; \n" - "uniform vec4 fragTintColor; \n" + "uniform vec4 colDiffuse; \n" "void main() \n" "{ \n" #if defined(GRAPHICS_API_OPENGL_33) " vec4 texelColor = texture(texture0, fragTexCoord); \n" - " finalColor = texelColor*fragTintColor*fragColor; \n" + " finalColor = texelColor*colDiffuse*fragColor; \n" #elif defined(GRAPHICS_API_OPENGL_ES2) " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0 - " gl_FragColor = texelColor*fragTintColor*fragColor; \n" + " gl_FragColor = texelColor*colDiffuse*fragColor; \n" #endif "} \n"; @@ -2513,87 +2539,17 @@ static Shader LoadDefaultShader(void) // Load standard shader // NOTE: This shader supports: // - Up to 3 different maps: diffuse, normal, specular -// - Material properties: colDiffuse, colAmbient, colSpecular, glossiness, normalDepth +// - Material properties: colAmbient, colDiffuse, colSpecular, glossiness, normalDepth // - Up to 8 lights: Point, Directional or Spot static Shader LoadStandardShader(void) { - Shader shader; - - // Vertex shader directly defined, no external file required -#if defined(GRAPHICS_API_OPENGL_33) - char vShaderStr[] = "#version 330 \n" - "in vec3 vertexPosition; \n" - "in vec3 vertexNormal; \n" - "in vec2 vertexTexCoord; \n" - "in vec4 vertexColor; \n" - "out vec2 fragTexCoord; \n" - "out vec4 fragColor; \n" - "out vec3 fragNormal; \n" -#elif defined(GRAPHICS_API_OPENGL_ES2) - char vShaderStr[] = "#version 100 \n" - "attribute vec3 vertexPosition; \n" - "attribute vec3 vertexNormal; \n" - "attribute vec2 vertexTexCoord; \n" - "attribute vec4 vertexColor; \n" - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" - "varying vec3 fragNormal; \n" -#endif - "uniform mat4 mvpMatrix; \n" - "uniform mat4 modelMatrix; \n" - "void main() \n" - "{ \n" - " fragTexCoord = vertexTexCoord; \n" - " fragColor = vertexColor; \n" - " mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); \n" - " fragNormal = normalize(normalMatrix*vertexNormal); \n" - " gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n" - "} \n"; - - // TODO: add specular calculation, multi-lights structs and light type calculations (directional, point, spot) - // Fragment shader directly defined, no external file required -#if defined(GRAPHICS_API_OPENGL_33) - char fShaderStr[] = "#version 330 \n" - "in vec2 fragTexCoord; \n" - "in vec4 fragColor; \n" - "in vec3 fragNormal; \n" - "out vec4 finalColor; \n" -#elif defined(GRAPHICS_API_OPENGL_ES2) - char fShaderStr[] = "#version 100 \n" - "precision mediump float; \n" // precision required for OpenGL ES2 (WebGL) - "varying vec2 fragTexCoord; \n" - "varying vec4 fragColor; \n" - "varying vec3 fragNormal; \n" -#endif - "uniform sampler2D texture0; \n" - "uniform vec4 fragTintColor; \n" - "uniform vec4 colAmbient; \n" - "uniform vec4 colSpecular; \n" - "uniform vec3 lightDir; \n" - "vec3 LambertLighting(in vec3 n, in vec3 l) \n" - "{ \n" - " return clamp(dot(n, l), 0, 1)*fragTintColor.rgb; \n" - "} \n" - - "void main() \n" - "{ \n" - " vec3 n = normalize(fragNormal); \n" - " vec3 l = normalize(lightDir); \n" -#if defined(GRAPHICS_API_OPENGL_33) - " vec4 texelColor = texture(texture0, fragTexCoord); \n" - " finalColor = vec4(texelColor.rgb*(colAmbient.rgb + LambertLighting(n, l)) - colSpecular.rgb + colSpecular.rgb, texelColor.a*fragTintColor.a); \n" // Stupid specular color operation to avoid shader location errors -#elif defined(GRAPHICS_API_OPENGL_ES2) - " vec4 texelColor = texture2D(texture0, fragTexCoord); \n" // NOTE: texture2D() is deprecated on OpenGL 3.3 and ES 3.0 - " gl_FragColor = texelColor*fragTintColor*fragColor; \n" -#endif - "} \n"; - - shader.id = LoadShaderProgram(vShaderStr, fShaderStr); + // Load standard shader (TODO: rewrite as char pointers) + Shader shader = LoadShader("resources/shaders/standard.vs", "resources/shaders/standard.fs"); if (shader.id != 0) TraceLog(INFO, "[SHDR ID %i] Standard shader loaded successfully", shader.id); else TraceLog(WARNING, "[SHDR ID %i] Standard shader could not be loaded", shader.id); - if (shader.id != 0) LoadDefaultShaderLocations(&shader); // TODO: Review locations fetching + if (shader.id != 0) LoadDefaultShaderLocations(&shader); return shader; } @@ -2622,7 +2578,7 @@ static void LoadDefaultShaderLocations(Shader *shader) shader->mvpLoc = glGetUniformLocation(shader->id, "mvpMatrix"); // Get handles to GLSL uniform locations (fragment shader) - shader->tintColorLoc = glGetUniformLocation(shader->id, "fragTintColor"); + shader->tintColorLoc = glGetUniformLocation(shader->id, "colDiffuse"); shader->mapDiffuseLoc = glGetUniformLocation(shader->id, "texture0"); shader->mapNormalLoc = glGetUniformLocation(shader->id, "texture1"); shader->mapSpecularLoc = glGetUniformLocation(shader->id, "texture2"); @@ -3098,62 +3054,75 @@ static void UnloadDefaultBuffers(void) // Sets shader uniform values for lights array // NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0f -// TODO: Review memcpy() and parameters pass static void SetShaderLights(Shader shader) { - // Note: currently working with one light (index 0) - // TODO: add multi-lights feature (http://www.learnopengl.com/#!Lighting/Multiple-lights) - - /* - // NOTE: Standard Shader must include the following data: - - // Shader Light struct - struct Light { - vec3 position; - vec3 direction; - - vec3 diffuse; - float intensity; - } - - const int maxLights = 8; - uniform int lightsCount; // Number of lights - uniform Light lights[maxLights]; - */ + int locPoint = glGetUniformLocation(shader.id, "lightsCount"); + glUniform1i(locPoint, lightsCount); - /*int locPoint; char locName[32] = "lights[x].position\0"; - - glUseProgram(shader.id); - - locPoint = glGetUniformLocation(shader.id, "lightsCount"); - glUniform1i(locPoint, lightsCount); for (int i = 0; i < lightsCount; i++) { locName[7] = '0' + i; - memcpy(&locName[10], "position\0", strlen("position\0")); - locPoint = glGetUniformLocation(shader.id, locName); - glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); + memcpy(&locName[10], "enabled\0", strlen("enabled\0") + 1); + locPoint = GetShaderLocation(shader, locName); + glUniform1i(locPoint, lights[i]->enabled); - memcpy(&locName[10], "direction\0", strlen("direction\0")); - locPoint = glGetUniformLocation(shader.id, locName); - glUniform3f(locPoint, lights[i]->direction.x, lights[i]->direction.y, lights[i]->direction.z); - - memcpy(&locName[10], "diffuse\0", strlen("diffuse\0")); + memcpy(&locName[10], "type\0", strlen("type\0") + 1); + locPoint = GetShaderLocation(shader, locName); + glUniform1i(locPoint, lights[i]->type); + + memcpy(&locName[10], "diffuse\0", strlen("diffuse\0") + 2); locPoint = glGetUniformLocation(shader.id, locName); - glUniform4f(locPoint, (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255 ); + glUniform4f(locPoint, (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255); memcpy(&locName[10], "intensity\0", strlen("intensity\0")); locPoint = glGetUniformLocation(shader.id, locName); glUniform1f(locPoint, lights[i]->intensity); + switch(lights[i]->type) + { + case LIGHT_POINT: + { + memcpy(&locName[10], "position\0", strlen("position\0") + 1); + locPoint = GetShaderLocation(shader, locName); + glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); + + memcpy(&locName[10], "attenuation\0", strlen("attenuation\0")); + locPoint = GetShaderLocation(shader, locName); + glUniform1f(locPoint, lights[i]->attenuation); + } break; + case LIGHT_DIRECTIONAL: + { + memcpy(&locName[10], "direction\0", strlen("direction\0") + 2); + locPoint = GetShaderLocation(shader, locName); + Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z }; + VectorNormalize(&direction); + glUniform3f(locPoint, direction.x, direction.y, direction.z); + } break; + case LIGHT_SPOT: + { + memcpy(&locName[10], "position\0", strlen("position\0") + 1); + locPoint = GetShaderLocation(shader, locName); + glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z); + + memcpy(&locName[10], "direction\0", strlen("direction\0") + 2); + locPoint = GetShaderLocation(shader, locName); + + Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z }; + VectorNormalize(&direction); + glUniform3f(locPoint, direction.x, direction.y, direction.z); + + memcpy(&locName[10], "coneAngle\0", strlen("coneAngle\0")); + locPoint = GetShaderLocation(shader, locName); + glUniform1f(locPoint, lights[i]->coneAngle); + } break; + default: break; + } + // TODO: Pass to the shader any other required data from LightData struct - }*/ - - int locPoint = GetShaderLocation(shader, "lightDir"); - glUniform3f(locPoint, lights[0]->position.x, lights[0]->position.y, lights[0]->position.z); + } } // Read text data from file diff --git a/src/rlgl.h b/src/rlgl.h index 39941b33..0765a8a7 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -196,40 +196,34 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; // Material type typedef struct Material { - Shader shader; + Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular) - Texture2D texDiffuse; // Diffuse texture - Texture2D texNormal; // Normal texture - Texture2D texSpecular; // Specular texture + Texture2D texDiffuse; // Diffuse texture + Texture2D texNormal; // Normal texture + Texture2D texSpecular; // Specular texture - Color colDiffuse; - Color colAmbient; - Color colSpecular; + Color colDiffuse; // Diffuse color + Color colAmbient; // Ambient color + Color colSpecular; // Specular color - float glossiness; - float normalDepth; + float glossiness; // Glossiness level (Ranges from 0 to 1000) + float normalDepth; // Normal map depth } Material; // Light type - // TODO: Review contained data to support different light types and features typedef struct LightData { int id; int type; // LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT bool enabled; Vector3 position; - Vector3 direction; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction) - float attenuation; // Lost of light intensity with distance (use radius?) + Vector3 target; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) + float attenuation; // Lost of light intensity with distance (world distance) - Color diffuse; // Use Vector3 diffuse (including intensities)? + Color diffuse; // Use Vector3 diffuse float intensity; - Color specular; - //float specFactor; // Specular intensity ? - - //Color ambient; // Required? - - float coneAngle; // SpotLight + float coneAngle; // Spot light max angle } LightData, *Light; // Color blending modes (pre-defined) -- cgit v1.2.3 From dcd6942ed1ab703625f5c7072cbcfd823c681db7 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sat, 21 May 2016 18:22:15 +0200 Subject: Fix small bug and spacing --- examples/resources/shaders/standard.fs | 14 +++++------ src/models.c | 46 +++++++++++++++++----------------- src/rlgl.c | 10 ++++---- 3 files changed, 35 insertions(+), 35 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/standard.fs b/examples/resources/shaders/standard.fs index 30c841d2..3c3bef4b 100644 --- a/examples/resources/shaders/standard.fs +++ b/examples/resources/shaders/standard.fs @@ -43,7 +43,7 @@ vec3 CalcPointLight(Light l, vec3 n, vec3 v) // Specular shading float spec = 0.0; - if(diff > 0.0) + if (diff > 0.0) { vec3 h = normalize(-l.direction + v); spec = pow(dot(n, h), 3 + glossiness); @@ -61,7 +61,7 @@ vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v) // Specular shading float spec = 0.0; - if(diff > 0.0) + if (diff > 0.0) { vec3 h = normalize(lightDir + v); spec = pow(dot(n, h), 3 + glossiness); @@ -84,7 +84,7 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v) float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); attenuation = dot(lightToSurface, -lightDir); float lightToSurfaceAngle = degrees(acos(attenuation)); - if(lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; // Combine diffuse and attenuation @@ -92,7 +92,7 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v) // Specular shading float spec = 0.0; - if(diffAttenuation > 0.0) + if (diffAttenuation > 0.0) { vec3 h = normalize(lightDir + v); spec = pow(dot(n, h), 3 + glossiness); @@ -115,13 +115,13 @@ void main() vec4 texelColor = texture(texture0, fragTexCoord); vec3 lighting = colAmbient.rgb; - for(int i = 0; i < lightsCount; i++) + for (int i = 0; i < lightsCount; i++) { // Check if light is enabled - if(lights[i].enabled == 1) + if (lights[i].enabled == 1) { // Calculate lighting based on light type - switch(lights[i].type) + switch (lights[i].type) { case 0: lighting += CalcPointLight(lights[i], n, v); break; case 1: lighting += CalcDirectionalLight(lights[i], n, v); break; diff --git a/src/models.c b/src/models.c index aef79626..07dee720 100644 --- a/src/models.c +++ b/src/models.c @@ -302,9 +302,9 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color rlBegin(RL_TRIANGLES); rlColor4ub(color.r, color.g, color.b, color.a); - for(int i = 0; i < (rings + 2); i++) + for (int i = 0; i < (rings + 2); i++) { - for(int j = 0; j < slices; j++) + for (int j = 0; j < slices; j++) { rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*i)), @@ -341,9 +341,9 @@ void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Col rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); - for(int i = 0; i < (rings + 2); i++) + for (int i = 0; i < (rings + 2); i++) { - for(int j = 0; j < slices; j++) + for (int j = 0; j < slices; j++) { rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)), sin(DEG2RAD*(270+(180/(rings + 1))*i)), @@ -386,7 +386,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h if (radiusTop > 0) { // Draw Body ------------------------------------------------------------------------------------- - for(int i = 0; i < 360; i += 360/sides) + for (int i = 0; i < 360; i += 360/sides) { rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); //Bottom Left rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); //Bottom Right @@ -398,7 +398,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h } // Draw Cap -------------------------------------------------------------------------------------- - for(int i = 0; i < 360; i += 360/sides) + for (int i = 0; i < 360; i += 360/sides) { rlVertex3f(0, height, 0); rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop); @@ -408,7 +408,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h else { // Draw Cone ------------------------------------------------------------------------------------- - for(int i = 0; i < 360; i += 360/sides) + for (int i = 0; i < 360; i += 360/sides) { rlVertex3f(0, height, 0); rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); @@ -417,7 +417,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h } // Draw Base ----------------------------------------------------------------------------------------- - for(int i = 0; i < 360; i += 360/sides) + for (int i = 0; i < 360; i += 360/sides) { rlVertex3f(0, 0, 0); rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); @@ -431,7 +431,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h // NOTE: It could be also used for pyramid and cone void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int sides, Color color) { - if(sides < 3) sides = 3; + if (sides < 3) sides = 3; rlPushMatrix(); rlTranslatef(position.x, position.y, position.z); @@ -439,7 +439,7 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl rlBegin(RL_LINES); rlColor4ub(color.r, color.g, color.b, color.a); - for(int i = 0; i < 360; i += 360/sides) + for (int i = 0; i < 360; i += 360/sides) { rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); @@ -500,7 +500,7 @@ void DrawGrid(int slices, float spacing) int halfSlices = slices / 2; rlBegin(RL_LINES); - for(int i = -halfSlices; i <= halfSlices; i++) + for (int i = -halfSlices; i <= halfSlices; i++) { if (i == 0) { @@ -798,9 +798,9 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size) Vector3 scaleFactor = { size.x/mapX, size.y/255.0f, size.z/mapZ }; - for(int z = 0; z < mapZ-1; z++) + for (int z = 0; z < mapZ-1; z++) { - for(int x = 0; x < mapX-1; x++) + for (int x = 0; x < mapX-1; x++) { // Fill vertices array with data //---------------------------------------------------------- @@ -1417,7 +1417,7 @@ bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius float vector = VectorDotProduct(raySpherePos, ray.direction); float d = sphereRadius*sphereRadius - (distance*distance - vector*vector); - if(d >= 0.0f) collision = true; + if (d >= 0.0f) collision = true; return collision; } @@ -1432,14 +1432,14 @@ bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadi float vector = VectorDotProduct(raySpherePos, ray.direction); float d = sphereRadius*sphereRadius - (distance*distance - vector*vector); - if(d >= 0.0f) collision = true; + if (d >= 0.0f) collision = true; // Calculate collision point Vector3 offset = ray.direction; float collisionDistance = 0; // Check if ray origin is inside the sphere to calculate the correct collision point - if(distance < sphereRadius) collisionDistance = vector + sqrt(d); + if (distance < sphereRadius) collisionDistance = vector + sqrt(d); else collisionDistance = vector - sqrt(d); VectorScale(&offset, collisionDistance); @@ -1777,11 +1777,11 @@ static Mesh LoadOBJ(const char *fileName) // First reading pass: Get numVertex, numNormals, numTexCoords, numTriangles // NOTE: vertex, texcoords and normals could be optimized (to be used indexed on faces definition) // NOTE: faces MUST be defined as TRIANGLES (3 vertex per face) - while(!feof(objFile)) + while (!feof(objFile)) { fscanf(objFile, "%c", &dataType); - switch(dataType) + switch (dataType) { case '#': // Comments case 'o': // Object name (One OBJ file can contain multible named meshes) @@ -1842,11 +1842,11 @@ static Mesh LoadOBJ(const char *fileName) // Second reading pass: Get vertex data to fill intermediate arrays // NOTE: This second pass is required in case of multiple meshes defined in same OBJ // TODO: Consider that different meshes can have different vertex data available (position, texcoords, normals) - while(!feof(objFile)) + while (!feof(objFile)) { fscanf(objFile, "%c", &dataType); - switch(dataType) + switch (dataType) { case '#': case 'o': case 'g': case 's': case 'm': case 'u': case 'f': fgets(comments, 200, objFile); break; case 'v': @@ -1903,11 +1903,11 @@ static Mesh LoadOBJ(const char *fileName) if (numNormals == 0) TraceLog(INFO, "[%s] No normals data on OBJ, normals will be generated from faces data", fileName); // Third reading pass: Get faces (triangles) data and fill VertexArray - while(!feof(objFile)) + while (!feof(objFile)) { fscanf(objFile, "%c", &dataType); - switch(dataType) + switch (dataType) { case '#': case 'o': case 'g': case 's': case 'm': case 'u': case 'v': fgets(comments, 200, objFile); break; case 'f': @@ -2023,7 +2023,7 @@ static Material LoadMTL(const char *fileName) return material; } - while(!feof(mtlFile)) + while (!feof(mtlFile)) { fgets(buffer, MAX_BUFFER_SIZE, mtlFile); diff --git a/src/rlgl.c b/src/rlgl.c index 55677f3e..85c0cae2 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1397,7 +1397,7 @@ RenderTexture2D rlglLoadRenderTexture(int width, int height) { TraceLog(WARNING, "Framebuffer object could not be created..."); - switch(status) + switch (status) { case GL_FRAMEBUFFER_UNSUPPORTED: TraceLog(WARNING, "Framebuffer is unsupported"); break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TraceLog(WARNING, "Framebuffer incomplete attachment"); break; @@ -1768,7 +1768,7 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // Check if using standard shader to get location points // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations) - if(material.shader.id == standardShader.id) + if (material.shader.id == standardShader.id) { // Send model transformations matrix to shader glUniformMatrix4fv(glGetUniformLocation(material.shader.id, "modelMatrix"), 1, false, MatrixToFloat(transform)); @@ -2285,7 +2285,7 @@ void DrawLights(void) Draw3DLine(lights[i]->position, lights[i]->target, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); DrawSphereWires(lights[i]->position, 0.3f*lights[i]->intensity, 4, 8, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); DrawCubeWires(lights[i]->target, 0.3f, 0.3f, 0.3f, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); - } + } break; case LIGHT_SPOT: { Draw3DLine(lights[i]->position, lights[i]->target, (lights[i]->enabled ? lights[i]->diffuse : BLACK)); @@ -3081,7 +3081,7 @@ static void SetShaderLights(Shader shader) locPoint = glGetUniformLocation(shader.id, locName); glUniform1f(locPoint, lights[i]->intensity); - switch(lights[i]->type) + switch (lights[i]->type) { case LIGHT_POINT: { @@ -3295,7 +3295,7 @@ static void TraceLog(int msgType, const char *text, ...) va_list args; va_start(args, text); - switch(msgType) + switch (msgType) { case INFO: fprintf(stdout, "INFO: "); break; case ERROR: fprintf(stdout, "ERROR: "); break; -- cgit v1.2.3 From ae2d0d4cd8739c49b1a4e230e6f1ca4a8bdab319 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sun, 29 May 2016 22:41:23 +0200 Subject: Delete old example mesh resource file --- examples/resources/model/shapes.obj | 6433 ----------------------------------- 1 file changed, 6433 deletions(-) delete mode 100644 examples/resources/model/shapes.obj (limited to 'examples/resources') diff --git a/examples/resources/model/shapes.obj b/examples/resources/model/shapes.obj deleted file mode 100644 index 80205310..00000000 --- a/examples/resources/model/shapes.obj +++ /dev/null @@ -1,6433 +0,0 @@ -# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware -# File Created: 17.12.2015 16:35:37 - -# -# object Box001 -# - -v -29.206673 -11.629548 3.941377 -v -6.725425 -11.629548 -1.993001 -v -35.141048 -11.629548 -18.539871 -v -12.659802 -11.629548 -24.474247 -v -29.206673 11.621758 3.941377 -v -6.725425 11.621758 -1.993001 -v -35.141048 11.621758 -18.539871 -v -12.659802 11.621758 -24.474247 -v 9.611540 16.536621 -13.505542 -v 9.611540 16.218872 -16.731674 -v 8.982153 16.218872 -16.669687 -v 8.376951 16.218872 -16.486101 -v 7.819195 16.218872 -16.187973 -v 7.330318 16.218872 -15.786763 -v 6.929106 16.218872 -15.297886 -v 6.630980 16.218872 -14.740129 -v 6.447395 16.218872 -14.134929 -v 6.385406 16.218872 -13.505540 -v 6.447397 16.218872 -12.876153 -v 6.630980 16.218872 -12.270952 -v 6.929110 16.218872 -11.713196 -v 7.330320 16.218872 -11.224319 -v 7.819201 16.218872 -10.823108 -v 8.376955 16.218872 -10.524981 -v 8.982157 16.218872 -10.341396 -v 9.611546 16.218872 -10.279408 -v 10.240931 16.218872 -10.341396 -v 10.846130 16.218872 -10.524984 -v 11.403891 16.218872 -10.823111 -v 11.892763 16.218872 -11.224323 -v 12.293978 16.218872 -11.713202 -v 12.592104 16.218872 -12.270958 -v 12.775690 16.218872 -12.876159 -v 12.837675 16.218872 -13.505547 -v 12.775686 16.218872 -14.134933 -v 12.592100 16.218872 -14.740135 -v 12.293974 16.218872 -15.297892 -v 11.892759 16.218872 -15.786766 -v 11.403879 16.218872 -16.187979 -v 10.846123 16.218872 -16.486103 -v 10.240921 16.218872 -16.669687 -v 9.611540 15.277844 -19.833832 -v 8.376951 15.277844 -19.712234 -v 7.189810 15.277844 -19.352119 -v 6.095730 15.277844 -18.767323 -v 5.136763 15.277844 -17.980320 -v 4.349756 15.277844 -17.021351 -v 3.764961 15.277844 -15.927273 -v 3.404844 15.277844 -14.740128 -v 3.283251 15.277844 -13.505539 -v 3.404846 15.277844 -12.270950 -v 3.764965 15.277844 -11.083807 -v 4.349760 15.277844 -9.989729 -v 5.136766 15.277844 -9.030762 -v 6.095734 15.277844 -8.243757 -v 7.189814 15.277844 -7.658960 -v 8.376957 15.277844 -7.298847 -v 9.611546 15.277844 -7.177250 -v 10.846136 15.277844 -7.298848 -v 12.033278 15.277844 -7.658965 -v 13.127356 15.277844 -8.243764 -v 14.086321 15.277844 -9.030769 -v 14.873327 15.277844 -9.989739 -v 15.458120 15.277844 -11.083817 -v 15.818235 15.277844 -12.270962 -v 15.939829 15.277844 -13.505550 -v 15.818232 15.277844 -14.740141 -v 15.458117 15.277844 -15.927283 -v 14.873316 15.277844 -17.021362 -v 14.086309 15.277844 -17.980328 -v 13.127340 15.277844 -18.767330 -v 12.033262 15.277844 -19.352125 -v 10.846117 15.277844 -19.712238 -v 9.611540 13.749696 -22.692797 -v 7.819195 13.749696 -22.516266 -v 6.095732 13.749696 -21.993458 -v 4.507378 13.749696 -21.144464 -v 3.115171 13.749696 -20.001911 -v 1.972616 13.749696 -18.609707 -v 1.123623 13.749696 -17.021351 -v 0.600817 13.749696 -15.297884 -v 0.424284 13.749696 -13.505539 -v 0.600817 13.749696 -11.713193 -v 1.123625 13.749696 -9.989727 -v 1.972622 13.749696 -8.401373 -v 3.115173 13.749696 -7.009167 -v 4.507380 13.749696 -5.866615 -v 6.095739 13.749696 -5.017623 -v 7.819202 13.749696 -4.494817 -v 9.611549 13.749696 -4.318287 -v 11.403894 13.749696 -4.494820 -v 13.127363 13.749696 -5.017629 -v 14.715715 13.749696 -5.866625 -v 16.107920 13.749696 -7.009181 -v 17.250471 13.749696 -8.401387 -v 18.099459 13.749696 -9.989742 -v 18.622267 13.749696 -11.713211 -v 18.798796 13.749696 -13.505556 -v 18.622259 13.749696 -15.297901 -v 18.099455 13.749696 -17.021366 -v 17.250452 13.749696 -18.609722 -v 16.107897 13.749696 -20.001925 -v 14.715693 13.749696 -21.144474 -v 13.127333 13.749696 -21.993465 -v 11.403864 13.749696 -22.516270 -v 9.611540 11.693156 -25.198696 -v 7.330318 11.693156 -24.974016 -v 5.136763 11.693156 -24.308609 -v 3.115171 11.693156 -23.228046 -v 1.343229 11.693156 -21.773851 -v -0.110964 11.693156 -20.001911 -v -1.191528 11.693156 -17.980316 -v -1.856936 11.693156 -15.786760 -v -2.081615 11.693156 -13.505538 -v -1.856934 11.693156 -11.224315 -v -1.191525 11.693156 -9.030760 -v -0.110960 11.693156 -7.009166 -v 1.343235 11.693156 -5.237227 -v 3.115177 11.693156 -3.783033 -v 5.136772 11.693156 -2.702470 -v 7.330328 11.693156 -2.037066 -v 9.611549 11.693156 -1.812386 -v 11.892775 11.693156 -2.037068 -v 14.086332 11.693156 -2.702479 -v 16.107920 11.693156 -3.783048 -v 17.879862 11.693156 -5.237242 -v 19.334051 11.693156 -7.009185 -v 20.414614 11.693156 -9.030780 -v 21.080019 11.693156 -11.224338 -v 21.304697 11.693156 -13.505560 -v 21.080015 11.693156 -15.786782 -v 20.414602 11.693156 -17.980339 -v 19.334028 11.693156 -20.001928 -v 17.879831 11.693156 -21.773867 -v 16.107893 11.693156 -23.228058 -v 14.086294 11.693156 -24.308619 -v 11.892736 11.693156 -24.974022 -v 9.611540 9.187253 -27.255239 -v 6.929108 9.187253 -26.991041 -v 4.349760 9.187253 -26.208607 -v 1.972618 9.187253 -24.938000 -v -0.110964 9.187253 -23.228046 -v -1.820917 9.187253 -21.144463 -v -3.091526 9.187253 -18.767321 -v -3.873960 9.187253 -16.187971 -v -4.138157 9.187253 -13.505537 -v -3.873959 9.187253 -10.823103 -v -3.091520 9.187253 -8.243754 -v -1.820911 9.187253 -5.866612 -v -0.110958 9.187253 -3.783032 -v 1.972626 9.187253 -2.073080 -v 4.349768 9.187253 -0.802473 -v 6.929121 9.187253 -0.020039 -v 9.611553 9.187253 0.244156 -v 12.293989 9.187253 -0.020043 -v 14.873335 9.187253 -0.802485 -v 17.250479 9.187253 -2.073095 -v 19.334059 9.187253 -3.783049 -v 21.044004 9.187253 -5.866634 -v 22.314611 9.187253 -8.243777 -v 23.097048 9.187253 -10.823130 -v 23.361238 9.187253 -13.505564 -v 23.097036 9.187253 -16.187996 -v 22.314596 9.187253 -18.767345 -v 21.043982 9.187253 -21.144485 -v 19.334024 9.187253 -23.228065 -v 17.250437 9.187253 -24.938011 -v 14.873293 9.187253 -26.208616 -v 12.293943 9.187253 -26.991047 -v 9.611538 6.328290 -28.783384 -v 6.630981 6.328290 -28.489828 -v 3.764963 6.328290 -27.620428 -v 1.123625 6.328290 -26.208605 -v -1.191526 6.328290 -24.308609 -v -3.091524 6.328290 -21.993456 -v -4.503347 6.328290 -19.352118 -v -5.372744 6.328290 -16.486097 -v -5.666305 6.328290 -13.505537 -v -5.372743 6.328290 -10.524976 -v -4.503345 6.328290 -7.658957 -v -3.091518 6.328290 -5.017619 -v -1.191521 6.328290 -2.702466 -v 1.123632 6.328290 -0.802471 -v 3.764975 6.328290 0.609350 -v 6.630993 6.328290 1.478745 -v 9.611555 6.328290 1.772303 -v 12.592115 6.328290 1.478741 -v 15.458136 6.328290 0.609339 -v 18.099470 6.328290 -0.802490 -v 20.414621 6.328290 -2.702490 -v 22.314619 6.328290 -5.017643 -v 23.726439 6.328290 -7.658983 -v 24.595831 6.328290 -10.525005 -v 24.889383 6.328290 -13.505566 -v 24.595819 6.328290 -16.486126 -v 23.726416 6.328290 -19.352144 -v 22.314589 6.328290 -21.993481 -v 20.414587 6.328290 -24.308628 -v 18.099432 6.328290 -26.208620 -v 15.458090 6.328290 -27.620440 -v 12.592066 6.328290 -28.489836 -v 9.611540 3.226134 -29.724413 -v 6.447395 3.226134 -29.412773 -v 3.404846 3.226134 -28.489826 -v 0.600817 3.226134 -26.991041 -v -1.856936 3.226134 -24.974018 -v -3.873960 3.226134 -22.516266 -v -5.372746 3.226134 -19.712233 -v -6.295692 3.226134 -16.669682 -v -6.607332 3.226134 -13.505536 -v -6.295691 3.226134 -10.341390 -v -5.372740 3.226134 -7.298840 -v -3.873955 3.226134 -4.494810 -v -1.856928 3.226134 -2.037058 -v 0.600828 3.226134 -0.020035 -v 3.404858 3.226134 1.478746 -v 6.447409 3.226134 2.401691 -v 9.611555 3.226134 2.713330 -v 12.775702 3.226134 2.401687 -v 15.818251 3.226134 1.478735 -v 18.622282 3.226134 -0.020055 -v 21.080030 3.226134 -2.037082 -v 23.097055 3.226134 -4.494838 -v 24.595835 3.226134 -7.298870 -v 25.518774 3.226134 -10.341419 -v 25.830408 3.226134 -13.505567 -v 25.518766 3.226134 -16.669714 -v 24.595812 3.226134 -19.712261 -v 23.097025 3.226134 -22.516289 -v 21.079992 3.226134 -24.974037 -v 18.622236 3.226134 -26.991058 -v 15.818205 3.226134 -28.489840 -v 12.775652 3.226134 -29.412781 -v 9.611538 0.000001 -30.042162 -v 6.385406 0.000001 -29.724417 -v 3.283249 0.000001 -28.783388 -v 0.424286 0.000001 -27.255239 -v -2.081615 0.000001 -25.198698 -v -4.138157 0.000001 -22.692795 -v -5.666304 0.000001 -19.833830 -v -6.607334 0.000001 -16.731672 -v -6.925080 0.000001 -13.505536 -v -6.607332 0.000001 -10.279400 -v -5.666301 0.000001 -7.177244 -v -4.138151 0.000001 -4.318279 -v -2.081610 0.000001 -1.812377 -v 0.424297 0.000001 0.244163 -v 3.283260 0.000001 1.772307 -v 6.385422 0.000001 2.713336 -v 9.611557 0.000001 3.031079 -v 12.837690 0.000001 2.713330 -v 15.939848 0.000001 1.772296 -v 18.798811 0.000001 0.244145 -v 21.304712 0.000001 -1.812400 -v 23.361250 0.000001 -4.318306 -v 24.889395 0.000001 -7.177274 -v 25.830423 0.000001 -10.279431 -v 26.148161 0.000001 -13.505568 -v 25.830408 0.000001 -16.731703 -v 24.889376 0.000001 -19.833858 -v 23.361219 0.000001 -22.692820 -v 21.304674 0.000001 -25.198719 -v 18.798765 0.000001 -27.255259 -v 15.939802 0.000001 -28.783400 -v 12.837637 0.000001 -29.724421 -v 9.611540 -3.226133 -29.724415 -v 6.447395 -3.226133 -29.412775 -v 3.404846 -3.226133 -28.489828 -v 0.600817 -3.226133 -26.991045 -v -1.856936 -3.226133 -24.974018 -v -3.873960 -3.226133 -22.516266 -v -5.372747 -3.226133 -19.712233 -v -6.295694 -3.226133 -16.669683 -v -6.607334 -3.226133 -13.505536 -v -6.295692 -3.226133 -10.341390 -v -5.372742 -3.226133 -7.298840 -v -3.873957 -3.226133 -4.494810 -v -1.856928 -3.226133 -2.037058 -v 0.600826 -3.226133 -0.020033 -v 3.404856 -3.226133 1.478751 -v 6.447409 -3.226133 2.401693 -v 9.611555 -3.226133 2.713333 -v 12.775705 -3.226133 2.401688 -v 15.818251 -3.226133 1.478737 -v 18.622282 -3.226133 -0.020053 -v 21.080030 -3.226133 -2.037082 -v 23.097052 -3.226133 -4.494835 -v 24.595835 -3.226133 -7.298868 -v 25.518778 -3.226133 -10.341420 -v 25.830412 -3.226133 -13.505567 -v 25.518766 -3.226133 -16.669714 -v 24.595812 -3.226133 -19.712261 -v 23.097025 -3.226133 -22.516291 -v 21.079996 -3.226133 -24.974041 -v 18.622236 -3.226133 -26.991062 -v 15.818201 -3.226133 -28.489841 -v 12.775652 -3.226133 -29.412783 -v 9.611538 -6.328289 -28.783388 -v 6.630981 -6.328289 -28.489828 -v 3.764963 -6.328289 -27.620430 -v 1.123625 -6.328289 -26.208607 -v -1.191526 -6.328289 -24.308609 -v -3.091524 -6.328289 -21.993456 -v -4.503351 -6.328289 -19.352118 -v -5.372746 -6.328289 -16.486097 -v -5.666306 -6.328289 -13.505537 -v -5.372745 -6.328289 -10.524975 -v -4.503345 -6.328289 -7.658956 -v -3.091518 -6.328289 -5.017619 -v -1.191521 -6.328289 -2.702466 -v 1.123632 -6.328289 -0.802471 -v 3.764973 -6.328289 0.609352 -v 6.630993 -6.328289 1.478746 -v 9.611555 -6.328289 1.772305 -v 12.592115 -6.328289 1.478741 -v 15.458136 -6.328289 0.609339 -v 18.099474 -6.328289 -0.802486 -v 20.414621 -6.328289 -2.702488 -v 22.314619 -6.328289 -5.017643 -v 23.726439 -6.328289 -7.658984 -v 24.595831 -6.328289 -10.525005 -v 24.889387 -6.328289 -13.505566 -v 24.595819 -6.328289 -16.486126 -v 23.726416 -6.328289 -19.352144 -v 22.314589 -6.328289 -21.993481 -v 20.414591 -6.328289 -24.308630 -v 18.099432 -6.328289 -26.208622 -v 15.458090 -6.328289 -27.620440 -v 12.592066 -6.328289 -28.489836 -v 9.611540 -9.187254 -27.255239 -v 6.929108 -9.187254 -26.991041 -v 4.349760 -9.187254 -26.208607 -v 1.972618 -9.187254 -24.938000 -v -0.110964 -9.187254 -23.228046 -v -1.820917 -9.187254 -21.144463 -v -3.091526 -9.187254 -18.767321 -v -3.873960 -9.187254 -16.187971 -v -4.138157 -9.187254 -13.505537 -v -3.873959 -9.187254 -10.823103 -v -3.091520 -9.187254 -8.243754 -v -1.820911 -9.187254 -5.866612 -v -0.110958 -9.187254 -3.783032 -v 1.972626 -9.187254 -2.073080 -v 4.349768 -9.187254 -0.802473 -v 6.929121 -9.187254 -0.020039 -v 9.611553 -9.187254 0.244156 -v 12.293989 -9.187254 -0.020043 -v 14.873335 -9.187254 -0.802485 -v 17.250479 -9.187254 -2.073095 -v 19.334059 -9.187254 -3.783049 -v 21.044004 -9.187254 -5.866634 -v 22.314611 -9.187254 -8.243777 -v 23.097048 -9.187254 -10.823130 -v 23.361238 -9.187254 -13.505564 -v 23.097036 -9.187254 -16.187996 -v 22.314596 -9.187254 -18.767345 -v 21.043982 -9.187254 -21.144485 -v 19.334024 -9.187254 -23.228065 -v 17.250437 -9.187254 -24.938011 -v 14.873293 -9.187254 -26.208616 -v 12.293943 -9.187254 -26.991047 -v 9.611540 -11.693157 -25.198696 -v 7.330318 -11.693157 -24.974016 -v 5.136763 -11.693157 -24.308609 -v 3.115171 -11.693157 -23.228046 -v 1.343229 -11.693157 -21.773851 -v -0.110964 -11.693157 -20.001911 -v -1.191528 -11.693157 -17.980316 -v -1.856936 -11.693157 -15.786760 -v -2.081615 -11.693157 -13.505538 -v -1.856934 -11.693157 -11.224315 -v -1.191525 -11.693157 -9.030760 -v -0.110960 -11.693157 -7.009166 -v 1.343235 -11.693157 -5.237227 -v 3.115177 -11.693157 -3.783033 -v 5.136772 -11.693157 -2.702470 -v 7.330328 -11.693157 -2.037066 -v 9.611549 -11.693157 -1.812386 -v 11.892775 -11.693157 -2.037068 -v 14.086332 -11.693157 -2.702479 -v 16.107920 -11.693157 -3.783048 -v 17.879862 -11.693157 -5.237242 -v 19.334051 -11.693157 -7.009185 -v 20.414614 -11.693157 -9.030780 -v 21.080019 -11.693157 -11.224338 -v 21.304697 -11.693157 -13.505560 -v 21.080015 -11.693157 -15.786782 -v 20.414602 -11.693157 -17.980339 -v 19.334028 -11.693157 -20.001928 -v 17.879831 -11.693157 -21.773867 -v 16.107893 -11.693157 -23.228058 -v 14.086294 -11.693157 -24.308619 -v 11.892736 -11.693157 -24.974022 -v 9.611540 -13.749699 -22.692795 -v 7.819195 -13.749699 -22.516264 -v 6.095732 -13.749699 -21.993458 -v 4.507378 -13.749699 -21.144464 -v 3.115171 -13.749699 -20.001911 -v 1.972616 -13.749699 -18.609705 -v 1.123623 -13.749699 -17.021349 -v 0.600817 -13.749699 -15.297884 -v 0.424286 -13.749699 -13.505538 -v 0.600817 -13.749699 -11.713193 -v 1.123625 -13.749699 -9.989727 -v 1.972622 -13.749699 -8.401373 -v 3.115175 -13.749699 -7.009168 -v 4.507381 -13.749699 -5.866616 -v 6.095739 -13.749699 -5.017623 -v 7.819206 -13.749699 -4.494817 -v 9.611549 -13.749699 -4.318288 -v 11.403894 -13.749699 -4.494821 -v 13.127359 -13.749699 -5.017631 -v 14.715715 -13.749699 -5.866625 -v 16.107920 -13.749699 -7.009181 -v 17.250467 -13.749699 -8.401387 -v 18.099459 -13.749699 -9.989744 -v 18.622267 -13.749699 -11.713211 -v 18.798796 -13.749699 -13.505556 -v 18.622259 -13.749699 -15.297901 -v 18.099451 -13.749699 -17.021366 -v 17.250452 -13.749699 -18.609718 -v 16.107897 -13.749699 -20.001923 -v 14.715693 -13.749699 -21.144474 -v 13.127333 -13.749699 -21.993464 -v 11.403864 -13.749699 -22.516270 -v 9.611540 -15.277846 -19.833830 -v 8.376951 -15.277846 -19.712233 -v 7.189810 -15.277846 -19.352118 -v 6.095734 -15.277846 -18.767323 -v 5.136765 -15.277846 -17.980316 -v 4.349762 -15.277846 -17.021349 -v 3.764965 -15.277846 -15.927272 -v 3.404848 -15.277846 -14.740128 -v 3.283253 -15.277846 -13.505540 -v 3.404848 -15.277846 -12.270950 -v 3.764967 -15.277846 -11.083808 -v 4.349762 -15.277846 -9.989730 -v 5.136768 -15.277846 -9.030764 -v 6.095736 -15.277846 -8.243760 -v 7.189816 -15.277846 -7.658964 -v 8.376957 -15.277846 -7.298849 -v 9.611546 -15.277846 -7.177253 -v 10.846136 -15.277846 -7.298851 -v 12.033278 -15.277846 -7.658967 -v 13.127356 -15.277846 -8.243767 -v 14.086321 -15.277846 -9.030771 -v 14.873323 -15.277846 -9.989740 -v 15.458120 -15.277846 -11.083818 -v 15.818235 -15.277846 -12.270964 -v 15.939829 -15.277846 -13.505552 -v 15.818228 -15.277846 -14.740139 -v 15.458113 -15.277846 -15.927282 -v 14.873312 -15.277846 -17.021358 -v 14.086306 -15.277846 -17.980324 -v 13.127340 -15.277846 -18.767326 -v 12.033258 -15.277846 -19.352121 -v 10.846113 -15.277846 -19.712234 -v 9.611542 -16.218876 -16.731672 -v 8.982155 -16.218876 -16.669683 -v 8.376953 -16.218876 -16.486097 -v 7.819199 -16.218876 -16.187971 -v 7.330320 -16.218876 -15.786760 -v 6.929110 -16.218876 -15.297883 -v 6.630983 -16.218876 -14.740128 -v 6.447399 -16.218876 -14.134928 -v 6.385410 -16.218876 -13.505540 -v 6.447399 -16.218876 -12.876153 -v 6.630985 -16.218876 -12.270953 -v 6.929111 -16.218876 -11.713198 -v 7.330322 -16.218876 -11.224320 -v 7.819199 -16.218876 -10.823111 -v 8.376955 -16.218876 -10.524984 -v 8.982157 -16.218876 -10.341399 -v 9.611544 -16.218876 -10.279411 -v 10.240929 -16.218876 -10.341400 -v 10.846130 -16.218876 -10.524986 -v 11.403883 -16.218876 -10.823112 -v 11.892759 -16.218876 -11.224325 -v 12.293974 -16.218876 -11.713202 -v 12.592100 -16.218876 -12.270960 -v 12.775686 -16.218876 -12.876160 -v 12.837671 -16.218876 -13.505547 -v 12.775682 -16.218876 -14.134933 -v 12.592093 -16.218876 -14.740133 -v 12.293966 -16.218876 -15.297888 -v 11.892756 -16.218876 -15.786764 -v 11.403879 -16.218876 -16.187975 -v 10.846121 -16.218876 -16.486099 -v 10.240923 -16.218876 -16.669685 -v 9.611540 -16.536621 -13.505542 -v 7.404444 -11.629548 14.999386 -v 6.914089 -11.629548 11.274763 -v 5.476439 -11.629548 7.803965 -v 3.189468 -11.629548 4.823524 -v 0.209024 -11.629548 2.536550 -v -3.261770 -11.629548 1.098902 -v -6.986394 -11.629548 0.608545 -v -10.711016 -11.629548 1.098901 -v -14.181813 -11.629548 2.536551 -v -17.162252 -11.629548 4.823524 -v -19.449226 -11.629548 7.803963 -v -20.886879 -11.629548 11.274757 -v -21.377235 -11.629548 14.999380 -v -20.886881 -11.629548 18.724003 -v -19.449232 -11.629548 22.194799 -v -17.162262 -11.629548 25.175241 -v -14.181819 -11.629548 27.462217 -v -10.711023 -11.629548 28.899866 -v -6.986402 -11.629548 29.390230 -v -3.261778 -11.629548 28.899870 -v 0.209021 -11.629548 27.462225 -v 3.189459 -11.629548 25.175253 -v 5.476435 -11.629548 22.194815 -v 6.914087 -11.629548 18.724018 -v 4.526278 -6.021804 14.999386 -v 4.133991 -6.021804 12.019686 -v 2.983871 -6.021804 9.243050 -v 1.154293 -6.021804 6.858698 -v -1.230059 -6.021804 5.029119 -v -4.006697 -6.021804 3.878999 -v -6.986394 -6.021804 3.486713 -v -9.966091 -6.021804 3.878998 -v -12.742728 -6.021804 5.029119 -v -15.127081 -6.021804 6.858694 -v -16.956659 -6.021804 9.243046 -v -18.106781 -6.021804 12.019682 -v -18.499065 -6.021804 14.999382 -v -18.106783 -6.021804 17.979080 -v -16.956663 -6.021804 20.755716 -v -15.127088 -6.021804 23.140070 -v -12.742735 -6.021804 24.969648 -v -9.966098 -6.021804 26.119772 -v -6.986401 -6.021804 26.512056 -v -4.006702 -6.021804 26.119776 -v -1.230064 -6.021804 24.969656 -v 1.154287 -6.021804 23.140078 -v 2.983870 -6.021804 20.755726 -v 4.133989 -6.021804 17.979094 -v 1.648109 -0.414061 14.999384 -v 1.353897 -0.414061 12.764610 -v 0.491306 -0.414061 10.682133 -v -0.880878 -0.414061 8.893867 -v -2.669142 -0.414061 7.521685 -v -4.751619 -0.414061 6.659094 -v -6.986394 -0.414061 6.364882 -v -9.221169 -0.414061 6.659092 -v -11.303646 -0.414061 7.521683 -v -13.091910 -0.414061 8.893866 -v -14.464094 -0.414061 10.682131 -v -15.326685 -0.414061 12.764608 -v -15.620899 -0.414061 14.999384 -v -15.326687 -0.414061 17.234158 -v -14.464097 -0.414061 19.316635 -v -13.091915 -0.414061 21.104900 -v -11.303650 -0.414061 22.477083 -v -9.221172 -0.414061 23.339674 -v -6.986399 -0.414061 23.633890 -v -4.751623 -0.414061 23.339678 -v -2.669146 -0.414061 22.477091 -v -0.880880 -0.414061 21.104906 -v 0.491302 -0.414061 19.316643 -v 1.353895 -0.414061 17.234167 -v -1.230061 5.193685 14.999384 -v -1.426203 5.193685 13.509537 -v -2.001261 5.193685 12.121216 -v -2.916052 5.193685 10.929041 -v -4.108227 5.193685 10.014252 -v -5.496546 5.193685 9.439192 -v -6.986395 5.193685 9.243050 -v -8.476243 5.193685 9.439192 -v -9.864561 5.193685 10.014252 -v -11.056738 5.193685 10.929039 -v -11.971527 5.193685 12.121216 -v -12.546587 5.193685 13.509535 -v -12.742730 5.193685 14.999382 -v -12.546589 5.193685 16.489231 -v -11.971529 5.193685 17.877550 -v -11.056741 5.193685 19.069729 -v -9.864565 5.193685 19.984518 -v -8.476246 5.193685 20.559580 -v -6.986398 5.193685 20.755722 -v -5.496548 5.193685 20.559580 -v -4.108229 5.193685 19.984522 -v -2.916054 5.193685 19.069735 -v -2.001265 5.193685 17.877556 -v -1.426203 5.193685 16.489239 -v -4.108227 10.801427 14.999386 -v -4.206299 10.801427 14.254461 -v -4.493828 10.801427 13.560303 -v -4.951223 10.801427 12.964212 -v -5.547310 10.801427 12.506819 -v -6.241470 10.801427 12.219290 -v -6.986395 10.801427 12.121216 -v -7.731319 10.801427 12.219288 -v -8.425478 10.801427 12.506819 -v -9.021566 10.801427 12.964212 -v -9.478960 10.801427 13.560303 -v -9.766491 10.801427 14.254459 -v -9.864563 10.801427 14.999384 -v -9.766492 10.801427 15.744308 -v -9.478962 10.801427 16.438467 -v -9.021568 10.801427 17.034555 -v -8.425480 10.801427 17.491951 -v -7.731320 10.801427 17.779482 -v -6.986397 10.801427 17.877552 -v -6.241472 10.801427 17.779484 -v -5.547312 10.801427 17.491953 -v -4.951224 10.801427 17.034559 -v -4.493830 10.801427 16.438471 -v -4.206299 10.801427 15.744314 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -v -6.986395 16.409168 14.999386 -# 634 vertices - -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.000000 1.000000 -0.000000 -vn 0.255228 0.000000 0.966881 -vn 0.255228 0.000000 0.966881 -vn 0.255228 0.000000 0.966881 -vn 0.255228 0.000000 0.966881 -vn 0.255228 0.000000 0.966881 -vn 0.255228 0.000000 0.966881 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn -0.255228 0.000000 -0.966881 -vn -0.255228 0.000000 -0.966881 -vn -0.255228 0.000000 -0.966881 -vn -0.255228 0.000000 -0.966881 -vn -0.255228 0.000000 -0.966881 -vn -0.255228 0.000000 -0.966881 -vn -0.966881 0.000000 0.255228 -vn -0.966881 0.000000 0.255228 -vn -0.966881 0.000000 0.255228 -vn -0.966881 0.000000 0.255228 -vn -0.966881 0.000000 0.255228 -vn -0.966881 0.000000 0.255228 -vn -0.000000 1.000000 0.000000 -vn -0.000000 0.979598 -0.200969 -vn -0.039207 0.979598 -0.197107 -vn -0.000000 1.000000 0.000000 -vn -0.039207 0.979598 -0.197107 -vn -0.076907 0.979598 -0.185671 -vn -0.000000 1.000000 0.000000 -vn -0.076907 0.979598 -0.185671 -vn -0.111652 0.979598 -0.167099 -vn -0.000000 1.000000 0.000000 -vn -0.111652 0.979598 -0.167099 -vn -0.142106 0.979598 -0.142106 -vn -0.000000 1.000000 0.000000 -vn -0.142106 0.979598 -0.142106 -vn -0.167099 0.979598 -0.111652 -vn -0.000000 1.000000 0.000000 -vn -0.167099 0.979598 -0.111652 -vn -0.185671 0.979598 -0.076907 -vn -0.000000 1.000000 0.000000 -vn -0.185671 0.979598 -0.076907 -vn -0.197107 0.979598 -0.039207 -vn -0.000000 1.000000 0.000000 -vn -0.197107 0.979598 -0.039207 -vn -0.200969 0.979598 0.000000 -vn -0.000000 1.000000 0.000000 -vn -0.200969 0.979598 0.000000 -vn -0.197107 0.979598 0.039207 -vn -0.000000 1.000000 0.000000 -vn -0.197107 0.979598 0.039207 -vn -0.185671 0.979598 0.076907 -vn -0.000000 1.000000 0.000000 -vn -0.185671 0.979598 0.076907 -vn -0.167099 0.979598 0.111652 -vn -0.000000 1.000000 0.000000 -vn -0.167099 0.979598 0.111652 -vn -0.142106 0.979598 0.142107 -vn -0.000000 1.000000 0.000000 -vn -0.142106 0.979598 0.142107 -vn -0.111652 0.979598 0.167099 -vn -0.000000 1.000000 0.000000 -vn -0.111652 0.979598 0.167099 -vn -0.076907 0.979598 0.185671 -vn -0.000000 1.000000 0.000000 -vn -0.076907 0.979598 0.185671 -vn -0.039207 0.979598 0.197107 -vn -0.000000 1.000000 0.000000 -vn -0.039207 0.979598 0.197107 -vn 0.000000 0.979598 0.200969 -vn -0.000000 1.000000 0.000000 -vn 0.000000 0.979598 0.200969 -vn 0.039207 0.979598 0.197107 -vn -0.000000 1.000000 0.000000 -vn 0.039207 0.979598 0.197107 -vn 0.076908 0.979598 0.185671 -vn -0.000000 1.000000 0.000000 -vn 0.076908 0.979598 0.185671 -vn 0.111652 0.979598 0.167099 -vn -0.000000 1.000000 0.000000 -vn 0.111652 0.979598 0.167099 -vn 0.142107 0.979598 0.142106 -vn -0.000000 1.000000 0.000000 -vn 0.142107 0.979598 0.142106 -vn 0.167100 0.979598 0.111652 -vn -0.000000 1.000000 0.000000 -vn 0.167100 0.979598 0.111652 -vn 0.185671 0.979598 0.076907 -vn -0.000000 1.000000 0.000000 -vn 0.185671 0.979598 0.076907 -vn 0.197107 0.979598 0.039206 -vn -0.000000 1.000000 0.000000 -vn 0.197107 0.979598 0.039206 -vn 0.200969 0.979598 -0.000001 -vn -0.000000 1.000000 0.000000 -vn 0.200969 0.979598 -0.000001 -vn 0.197107 0.979598 -0.039207 -vn -0.000000 1.000000 0.000000 -vn 0.197107 0.979598 -0.039207 -vn 0.185671 0.979598 -0.076908 -vn -0.000000 1.000000 0.000000 -vn 0.185671 0.979598 -0.076908 -vn 0.167099 0.979598 -0.111653 -vn -0.000000 1.000000 0.000000 -vn 0.167099 0.979598 -0.111653 -vn 0.142106 0.979598 -0.142107 -vn -0.000000 1.000000 0.000000 -vn 0.142106 0.979598 -0.142107 -vn 0.111652 0.979598 -0.167100 -vn -0.000000 1.000000 0.000000 -vn 0.111652 0.979598 -0.167100 -vn 0.076907 0.979598 -0.185671 -vn -0.000000 1.000000 0.000000 -vn 0.076907 0.979598 -0.185671 -vn 0.039207 0.979598 -0.197107 -vn -0.000000 1.000000 0.000000 -vn 0.039207 0.979598 -0.197107 -vn -0.000000 0.979598 -0.200969 -vn -0.075673 0.921707 -0.380434 -vn -0.039207 0.979598 -0.197107 -vn -0.000000 0.979598 -0.200969 -vn -0.000000 0.979598 -0.200969 -vn -0.000000 0.921707 -0.387887 -vn -0.075673 0.921707 -0.380434 -vn -0.148438 0.921707 -0.358361 -vn -0.076907 0.979598 -0.185671 -vn -0.039207 0.979598 -0.197107 -vn -0.039207 0.979598 -0.197107 -vn -0.075673 0.921707 -0.380434 -vn -0.148438 0.921707 -0.358361 -vn -0.215499 0.921707 -0.322516 -vn -0.111652 0.979598 -0.167099 -vn -0.076907 0.979598 -0.185671 -vn -0.076907 0.979598 -0.185671 -vn -0.148438 0.921707 -0.358361 -vn -0.215499 0.921707 -0.322516 -vn -0.274278 0.921707 -0.274278 -vn -0.142106 0.979598 -0.142106 -vn -0.111652 0.979598 -0.167099 -vn -0.111652 0.979598 -0.167099 -vn -0.215499 0.921707 -0.322516 -vn -0.274278 0.921707 -0.274278 -vn -0.322516 0.921707 -0.215499 -vn -0.167099 0.979598 -0.111652 -vn -0.142106 0.979598 -0.142106 -vn -0.142106 0.979598 -0.142106 -vn -0.274278 0.921707 -0.274278 -vn -0.322516 0.921707 -0.215499 -vn -0.358361 0.921707 -0.148438 -vn -0.185671 0.979598 -0.076907 -vn -0.167099 0.979598 -0.111652 -vn -0.167099 0.979598 -0.111652 -vn -0.322516 0.921707 -0.215499 -vn -0.358361 0.921707 -0.148438 -vn -0.380434 0.921707 -0.075673 -vn -0.197107 0.979598 -0.039207 -vn -0.185671 0.979598 -0.076907 -vn -0.185671 0.979598 -0.076907 -vn -0.358361 0.921707 -0.148438 -vn -0.380434 0.921707 -0.075673 -vn -0.387887 0.921707 0.000000 -vn -0.200969 0.979598 0.000000 -vn -0.197107 0.979598 -0.039207 -vn -0.197107 0.979598 -0.039207 -vn -0.380434 0.921707 -0.075673 -vn -0.387887 0.921707 0.000000 -vn -0.380434 0.921707 0.075673 -vn -0.197107 0.979598 0.039207 -vn -0.200969 0.979598 0.000000 -vn -0.200969 0.979598 0.000000 -vn -0.387887 0.921707 0.000000 -vn -0.380434 0.921707 0.075673 -vn -0.358361 0.921707 0.148438 -vn -0.185671 0.979598 0.076907 -vn -0.197107 0.979598 0.039207 -vn -0.197107 0.979598 0.039207 -vn -0.380434 0.921707 0.075673 -vn -0.358361 0.921707 0.148438 -vn -0.322516 0.921707 0.215498 -vn -0.167099 0.979598 0.111652 -vn -0.185671 0.979598 0.076907 -vn -0.185671 0.979598 0.076907 -vn -0.358361 0.921707 0.148438 -vn -0.322516 0.921707 0.215498 -vn -0.274277 0.921707 0.274278 -vn -0.142106 0.979598 0.142107 -vn -0.167099 0.979598 0.111652 -vn -0.167099 0.979598 0.111652 -vn -0.322516 0.921707 0.215498 -vn -0.274277 0.921707 0.274278 -vn -0.215498 0.921707 0.322516 -vn -0.111652 0.979598 0.167099 -vn -0.142106 0.979598 0.142107 -vn -0.142106 0.979598 0.142107 -vn -0.274277 0.921707 0.274278 -vn -0.215498 0.921707 0.322516 -vn -0.148438 0.921707 0.358361 -vn -0.076907 0.979598 0.185671 -vn -0.111652 0.979598 0.167099 -vn -0.111652 0.979598 0.167099 -vn -0.215498 0.921707 0.322516 -vn -0.148438 0.921707 0.358361 -vn -0.075673 0.921707 0.380434 -vn -0.039207 0.979598 0.197107 -vn -0.076907 0.979598 0.185671 -vn -0.076907 0.979598 0.185671 -vn -0.148438 0.921707 0.358361 -vn -0.075673 0.921707 0.380434 -vn 0.000000 0.921707 0.387887 -vn 0.000000 0.979598 0.200969 -vn -0.039207 0.979598 0.197107 -vn -0.039207 0.979598 0.197107 -vn -0.075673 0.921707 0.380434 -vn 0.000000 0.921707 0.387887 -vn 0.075673 0.921707 0.380434 -vn 0.039207 0.979598 0.197107 -vn 0.000000 0.979598 0.200969 -vn 0.000000 0.979598 0.200969 -vn 0.000000 0.921707 0.387887 -vn 0.075673 0.921707 0.380434 -vn 0.148438 0.921707 0.358361 -vn 0.076908 0.979598 0.185671 -vn 0.039207 0.979598 0.197107 -vn 0.039207 0.979598 0.197107 -vn 0.075673 0.921707 0.380434 -vn 0.148438 0.921707 0.358361 -vn 0.215499 0.921707 0.322516 -vn 0.111652 0.979598 0.167099 -vn 0.076908 0.979598 0.185671 -vn 0.076908 0.979598 0.185671 -vn 0.148438 0.921707 0.358361 -vn 0.215499 0.921707 0.322516 -vn 0.274278 0.921707 0.274277 -vn 0.142107 0.979598 0.142106 -vn 0.111652 0.979598 0.167099 -vn 0.111652 0.979598 0.167099 -vn 0.215499 0.921707 0.322516 -vn 0.274278 0.921707 0.274277 -vn 0.322517 0.921707 0.215498 -vn 0.167100 0.979598 0.111652 -vn 0.142107 0.979598 0.142106 -vn 0.142107 0.979598 0.142106 -vn 0.274278 0.921707 0.274277 -vn 0.322517 0.921707 0.215498 -vn 0.358361 0.921707 0.148437 -vn 0.185671 0.979598 0.076907 -vn 0.167100 0.979598 0.111652 -vn 0.167100 0.979598 0.111652 -vn 0.322517 0.921707 0.215498 -vn 0.358361 0.921707 0.148437 -vn 0.380434 0.921707 0.075673 -vn 0.197107 0.979598 0.039206 -vn 0.185671 0.979598 0.076907 -vn 0.185671 0.979598 0.076907 -vn 0.358361 0.921707 0.148437 -vn 0.380434 0.921707 0.075673 -vn 0.387887 0.921707 -0.000001 -vn 0.200969 0.979598 -0.000001 -vn 0.197107 0.979598 0.039206 -vn 0.197107 0.979598 0.039206 -vn 0.380434 0.921707 0.075673 -vn 0.387887 0.921707 -0.000001 -vn 0.380434 0.921707 -0.075674 -vn 0.197107 0.979598 -0.039207 -vn 0.200969 0.979598 -0.000001 -vn 0.200969 0.979598 -0.000001 -vn 0.387887 0.921707 -0.000001 -vn 0.380434 0.921707 -0.075674 -vn 0.358361 0.921707 -0.148438 -vn 0.185671 0.979598 -0.076908 -vn 0.197107 0.979598 -0.039207 -vn 0.197107 0.979598 -0.039207 -vn 0.380434 0.921707 -0.075674 -vn 0.358361 0.921707 -0.148438 -vn 0.322516 0.921707 -0.215499 -vn 0.167099 0.979598 -0.111653 -vn 0.185671 0.979598 -0.076908 -vn 0.185671 0.979598 -0.076908 -vn 0.358361 0.921707 -0.148438 -vn 0.322516 0.921707 -0.215499 -vn 0.274277 0.921707 -0.274278 -vn 0.142106 0.979598 -0.142107 -vn 0.167099 0.979598 -0.111653 -vn 0.167099 0.979598 -0.111653 -vn 0.322516 0.921707 -0.215499 -vn 0.274277 0.921707 -0.274278 -vn 0.215498 0.921707 -0.322517 -vn 0.111652 0.979598 -0.167100 -vn 0.142106 0.979598 -0.142107 -vn 0.142106 0.979598 -0.142107 -vn 0.274277 0.921707 -0.274278 -vn 0.215498 0.921707 -0.322517 -vn 0.148437 0.921707 -0.358361 -vn 0.076907 0.979598 -0.185671 -vn 0.111652 0.979598 -0.167100 -vn 0.111652 0.979598 -0.167100 -vn 0.215498 0.921707 -0.322517 -vn 0.148437 0.921707 -0.358361 -vn 0.075672 0.921707 -0.380434 -vn 0.039207 0.979598 -0.197107 -vn 0.076907 0.979598 -0.185671 -vn 0.076907 0.979598 -0.185671 -vn 0.148437 0.921707 -0.358361 -vn 0.075672 0.921707 -0.380434 -vn -0.000000 0.921707 -0.387887 -vn -0.000000 0.979598 -0.200969 -vn 0.039207 0.979598 -0.197107 -vn 0.039207 0.979598 -0.197107 -vn 0.075672 0.921707 -0.380434 -vn -0.000000 0.921707 -0.387887 -vn -0.109207 0.828645 -0.549019 -vn -0.075673 0.921707 -0.380434 -vn -0.000000 0.921707 -0.387887 -vn -0.000000 0.921707 -0.387887 -vn -0.000000 0.828645 -0.559775 -vn -0.109207 0.828645 -0.549019 -vn -0.214217 0.828645 -0.517165 -vn -0.148438 0.921707 -0.358361 -vn -0.075673 0.921707 -0.380434 -vn -0.075673 0.921707 -0.380434 -vn -0.109207 0.828645 -0.549019 -vn -0.214217 0.828645 -0.517165 -vn -0.310994 0.828645 -0.465436 -vn -0.215499 0.921707 -0.322516 -vn -0.148438 0.921707 -0.358361 -vn -0.148438 0.921707 -0.358361 -vn -0.214217 0.828645 -0.517165 -vn -0.310994 0.828645 -0.465436 -vn -0.395821 0.828645 -0.395821 -vn -0.274278 0.921707 -0.274278 -vn -0.215499 0.921707 -0.322516 -vn -0.215499 0.921707 -0.322516 -vn -0.310994 0.828645 -0.465436 -vn -0.395821 0.828645 -0.395821 -vn -0.465436 0.828645 -0.310995 -vn -0.322516 0.921707 -0.215499 -vn -0.274278 0.921707 -0.274278 -vn -0.274278 0.921707 -0.274278 -vn -0.395821 0.828645 -0.395821 -vn -0.465436 0.828645 -0.310995 -vn -0.517165 0.828645 -0.214216 -vn -0.358361 0.921707 -0.148438 -vn -0.322516 0.921707 -0.215499 -vn -0.322516 0.921707 -0.215499 -vn -0.465436 0.828645 -0.310995 -vn -0.517165 0.828645 -0.214216 -vn -0.549019 0.828645 -0.109207 -vn -0.380434 0.921707 -0.075673 -vn -0.358361 0.921707 -0.148438 -vn -0.358361 0.921707 -0.148438 -vn -0.517165 0.828645 -0.214216 -vn -0.549019 0.828645 -0.109207 -vn -0.559775 0.828645 -0.000000 -vn -0.387887 0.921707 0.000000 -vn -0.380434 0.921707 -0.075673 -vn -0.380434 0.921707 -0.075673 -vn -0.549019 0.828645 -0.109207 -vn -0.559775 0.828645 -0.000000 -vn -0.549019 0.828645 0.109207 -vn -0.380434 0.921707 0.075673 -vn -0.387887 0.921707 0.000000 -vn -0.387887 0.921707 0.000000 -vn -0.559775 0.828645 -0.000000 -vn -0.549019 0.828645 0.109207 -vn -0.517165 0.828645 0.214217 -vn -0.358361 0.921707 0.148438 -vn -0.380434 0.921707 0.075673 -vn -0.380434 0.921707 0.075673 -vn -0.549019 0.828645 0.109207 -vn -0.517165 0.828645 0.214217 -vn -0.465436 0.828645 0.310995 -vn -0.322516 0.921707 0.215498 -vn -0.358361 0.921707 0.148438 -vn -0.358361 0.921707 0.148438 -vn -0.517165 0.828645 0.214217 -vn -0.465436 0.828645 0.310995 -vn -0.395821 0.828645 0.395821 -vn -0.274277 0.921707 0.274278 -vn -0.322516 0.921707 0.215498 -vn -0.322516 0.921707 0.215498 -vn -0.465436 0.828645 0.310995 -vn -0.395821 0.828645 0.395821 -vn -0.310994 0.828645 0.465436 -vn -0.215498 0.921707 0.322516 -vn -0.274277 0.921707 0.274278 -vn -0.274277 0.921707 0.274278 -vn -0.395821 0.828645 0.395821 -vn -0.310994 0.828645 0.465436 -vn -0.214216 0.828645 0.517165 -vn -0.148438 0.921707 0.358361 -vn -0.215498 0.921707 0.322516 -vn -0.215498 0.921707 0.322516 -vn -0.310994 0.828645 0.465436 -vn -0.214216 0.828645 0.517165 -vn -0.109206 0.828645 0.549019 -vn -0.075673 0.921707 0.380434 -vn -0.148438 0.921707 0.358361 -vn -0.148438 0.921707 0.358361 -vn -0.214216 0.828645 0.517165 -vn -0.109206 0.828645 0.549019 -vn 0.000001 0.828645 0.559775 -vn 0.000000 0.921707 0.387887 -vn -0.075673 0.921707 0.380434 -vn -0.075673 0.921707 0.380434 -vn -0.109206 0.828645 0.549019 -vn 0.000001 0.828645 0.559775 -vn 0.109207 0.828645 0.549019 -vn 0.075673 0.921707 0.380434 -vn 0.000000 0.921707 0.387887 -vn 0.000000 0.921707 0.387887 -vn 0.000001 0.828645 0.559775 -vn 0.109207 0.828645 0.549019 -vn 0.214217 0.828645 0.517165 -vn 0.148438 0.921707 0.358361 -vn 0.075673 0.921707 0.380434 -vn 0.075673 0.921707 0.380434 -vn 0.109207 0.828645 0.549019 -vn 0.214217 0.828645 0.517165 -vn 0.310995 0.828645 0.465436 -vn 0.215499 0.921707 0.322516 -vn 0.148438 0.921707 0.358361 -vn 0.148438 0.921707 0.358361 -vn 0.214217 0.828645 0.517165 -vn 0.310995 0.828645 0.465436 -vn 0.395821 0.828645 0.395820 -vn 0.274278 0.921707 0.274277 -vn 0.215499 0.921707 0.322516 -vn 0.215499 0.921707 0.322516 -vn 0.310995 0.828645 0.465436 -vn 0.395821 0.828645 0.395820 -vn 0.465436 0.828645 0.310994 -vn 0.322517 0.921707 0.215498 -vn 0.274278 0.921707 0.274277 -vn 0.274278 0.921707 0.274277 -vn 0.395821 0.828645 0.395820 -vn 0.465436 0.828645 0.310994 -vn 0.517165 0.828645 0.214216 -vn 0.358361 0.921707 0.148437 -vn 0.322517 0.921707 0.215498 -vn 0.322517 0.921707 0.215498 -vn 0.465436 0.828645 0.310994 -vn 0.517165 0.828645 0.214216 -vn 0.549019 0.828645 0.109206 -vn 0.380434 0.921707 0.075673 -vn 0.358361 0.921707 0.148437 -vn 0.358361 0.921707 0.148437 -vn 0.517165 0.828645 0.214216 -vn 0.549019 0.828645 0.109206 -vn 0.559775 0.828645 -0.000001 -vn 0.387887 0.921707 -0.000001 -vn 0.380434 0.921707 0.075673 -vn 0.380434 0.921707 0.075673 -vn 0.549019 0.828645 0.109206 -vn 0.559775 0.828645 -0.000001 -vn 0.549019 0.828645 -0.109208 -vn 0.380434 0.921707 -0.075674 -vn 0.387887 0.921707 -0.000001 -vn 0.387887 0.921707 -0.000001 -vn 0.559775 0.828645 -0.000001 -vn 0.549019 0.828645 -0.109208 -vn 0.517165 0.828645 -0.214217 -vn 0.358361 0.921707 -0.148438 -vn 0.380434 0.921707 -0.075674 -vn 0.380434 0.921707 -0.075674 -vn 0.549019 0.828645 -0.109208 -vn 0.517165 0.828645 -0.214217 -vn 0.465435 0.828645 -0.310995 -vn 0.322516 0.921707 -0.215499 -vn 0.358361 0.921707 -0.148438 -vn 0.358361 0.921707 -0.148438 -vn 0.517165 0.828645 -0.214217 -vn 0.465435 0.828645 -0.310995 -vn 0.395820 0.828645 -0.395822 -vn 0.274277 0.921707 -0.274278 -vn 0.322516 0.921707 -0.215499 -vn 0.322516 0.921707 -0.215499 -vn 0.465435 0.828645 -0.310995 -vn 0.395820 0.828645 -0.395822 -vn 0.310993 0.828645 -0.465437 -vn 0.215498 0.921707 -0.322517 -vn 0.274277 0.921707 -0.274278 -vn 0.274277 0.921707 -0.274278 -vn 0.395820 0.828645 -0.395822 -vn 0.310993 0.828645 -0.465437 -vn 0.214216 0.828645 -0.517165 -vn 0.148437 0.921707 -0.358361 -vn 0.215498 0.921707 -0.322517 -vn 0.215498 0.921707 -0.322517 -vn 0.310993 0.828645 -0.465437 -vn 0.214216 0.828645 -0.517165 -vn 0.109206 0.828645 -0.549019 -vn 0.075672 0.921707 -0.380434 -vn 0.148437 0.921707 -0.358361 -vn 0.148437 0.921707 -0.358361 -vn 0.214216 0.828645 -0.517165 -vn 0.109206 0.828645 -0.549019 -vn -0.000000 0.828645 -0.559775 -vn -0.000000 0.921707 -0.387887 -vn 0.075672 0.921707 -0.380434 -vn 0.075672 0.921707 -0.380434 -vn 0.109206 0.828645 -0.549019 -vn -0.000000 0.828645 -0.559775 -vn -0.138542 0.704059 -0.696496 -vn -0.109207 0.828645 -0.549019 -vn -0.000000 0.828645 -0.559775 -vn -0.000000 0.828645 -0.559775 -vn -0.000000 0.704059 -0.710141 -vn -0.138542 0.704059 -0.696496 -vn -0.271759 0.704059 -0.656085 -vn -0.214217 0.828645 -0.517165 -vn -0.109207 0.828645 -0.549019 -vn -0.109207 0.828645 -0.549019 -vn -0.138542 0.704059 -0.696496 -vn -0.271759 0.704059 -0.656085 -vn -0.394533 0.704059 -0.590461 -vn -0.310994 0.828645 -0.465436 -vn -0.214217 0.828645 -0.517165 -vn -0.214217 0.828645 -0.517165 -vn -0.271759 0.704059 -0.656085 -vn -0.394533 0.704059 -0.590461 -vn -0.502146 0.704059 -0.502146 -vn -0.395821 0.828645 -0.395821 -vn -0.310994 0.828645 -0.465436 -vn -0.310994 0.828645 -0.465436 -vn -0.394533 0.704059 -0.590461 -vn -0.502146 0.704059 -0.502146 -vn -0.590461 0.704059 -0.394533 -vn -0.465436 0.828645 -0.310995 -vn -0.395821 0.828645 -0.395821 -vn -0.395821 0.828645 -0.395821 -vn -0.502146 0.704059 -0.502146 -vn -0.590461 0.704059 -0.394533 -vn -0.656085 0.704059 -0.271759 -vn -0.517165 0.828645 -0.214216 -vn -0.465436 0.828645 -0.310995 -vn -0.465436 0.828645 -0.310995 -vn -0.590461 0.704059 -0.394533 -vn -0.656085 0.704059 -0.271759 -vn -0.696496 0.704059 -0.138541 -vn -0.549019 0.828645 -0.109207 -vn -0.517165 0.828645 -0.214216 -vn -0.517165 0.828645 -0.214216 -vn -0.656085 0.704059 -0.271759 -vn -0.696496 0.704059 -0.138541 -vn -0.710141 0.704059 0.000000 -vn -0.559775 0.828645 -0.000000 -vn -0.549019 0.828645 -0.109207 -vn -0.549019 0.828645 -0.109207 -vn -0.696496 0.704059 -0.138541 -vn -0.710141 0.704059 0.000000 -vn -0.696496 0.704059 0.138542 -vn -0.549019 0.828645 0.109207 -vn -0.559775 0.828645 -0.000000 -vn -0.559775 0.828645 -0.000000 -vn -0.710141 0.704059 0.000000 -vn -0.696496 0.704059 0.138542 -vn -0.656085 0.704059 0.271760 -vn -0.517165 0.828645 0.214217 -vn -0.549019 0.828645 0.109207 -vn -0.549019 0.828645 0.109207 -vn -0.696496 0.704059 0.138542 -vn -0.656085 0.704059 0.271760 -vn -0.590461 0.704059 0.394534 -vn -0.465436 0.828645 0.310995 -vn -0.517165 0.828645 0.214217 -vn -0.517165 0.828645 0.214217 -vn -0.656085 0.704059 0.271760 -vn -0.590461 0.704059 0.394534 -vn -0.502145 0.704059 0.502146 -vn -0.395821 0.828645 0.395821 -vn -0.465436 0.828645 0.310995 -vn -0.465436 0.828645 0.310995 -vn -0.590461 0.704059 0.394534 -vn -0.502145 0.704059 0.502146 -vn -0.394533 0.704059 0.590461 -vn -0.310994 0.828645 0.465436 -vn -0.395821 0.828645 0.395821 -vn -0.395821 0.828645 0.395821 -vn -0.502145 0.704059 0.502146 -vn -0.394533 0.704059 0.590461 -vn -0.271759 0.704059 0.656085 -vn -0.214216 0.828645 0.517165 -vn -0.310994 0.828645 0.465436 -vn -0.310994 0.828645 0.465436 -vn -0.394533 0.704059 0.590461 -vn -0.271759 0.704059 0.656085 -vn -0.138541 0.704059 0.696496 -vn -0.109206 0.828645 0.549019 -vn -0.214216 0.828645 0.517165 -vn -0.214216 0.828645 0.517165 -vn -0.271759 0.704059 0.656085 -vn -0.138541 0.704059 0.696496 -vn 0.000001 0.704059 0.710142 -vn 0.000001 0.828645 0.559775 -vn -0.109206 0.828645 0.549019 -vn -0.109206 0.828645 0.549019 -vn -0.138541 0.704059 0.696496 -vn 0.000001 0.704059 0.710142 -vn 0.138542 0.704059 0.696496 -vn 0.109207 0.828645 0.549019 -vn 0.000001 0.828645 0.559775 -vn 0.000001 0.828645 0.559775 -vn 0.000001 0.704059 0.710142 -vn 0.138542 0.704059 0.696496 -vn 0.271760 0.704059 0.656085 -vn 0.214217 0.828645 0.517165 -vn 0.109207 0.828645 0.549019 -vn 0.109207 0.828645 0.549019 -vn 0.138542 0.704059 0.696496 -vn 0.271760 0.704059 0.656085 -vn 0.394534 0.704059 0.590460 -vn 0.310995 0.828645 0.465436 -vn 0.214217 0.828645 0.517165 -vn 0.214217 0.828645 0.517165 -vn 0.271760 0.704059 0.656085 -vn 0.394534 0.704059 0.590460 -vn 0.502146 0.704059 0.502145 -vn 0.395821 0.828645 0.395820 -vn 0.310995 0.828645 0.465436 -vn 0.310995 0.828645 0.465436 -vn 0.394534 0.704059 0.590460 -vn 0.502146 0.704059 0.502145 -vn 0.590461 0.704059 0.394533 -vn 0.465436 0.828645 0.310994 -vn 0.395821 0.828645 0.395820 -vn 0.395821 0.828645 0.395820 -vn 0.502146 0.704059 0.502145 -vn 0.590461 0.704059 0.394533 -vn 0.656086 0.704059 0.271758 -vn 0.517165 0.828645 0.214216 -vn 0.465436 0.828645 0.310994 -vn 0.465436 0.828645 0.310994 -vn 0.590461 0.704059 0.394533 -vn 0.656086 0.704059 0.271758 -vn 0.696496 0.704059 0.138541 -vn 0.549019 0.828645 0.109206 -vn 0.517165 0.828645 0.214216 -vn 0.517165 0.828645 0.214216 -vn 0.656086 0.704059 0.271758 -vn 0.696496 0.704059 0.138541 -vn 0.710141 0.704059 -0.000001 -vn 0.559775 0.828645 -0.000001 -vn 0.549019 0.828645 0.109206 -vn 0.549019 0.828645 0.109206 -vn 0.696496 0.704059 0.138541 -vn 0.710141 0.704059 -0.000001 -vn 0.696496 0.704059 -0.138543 -vn 0.549019 0.828645 -0.109208 -vn 0.559775 0.828645 -0.000001 -vn 0.559775 0.828645 -0.000001 -vn 0.710141 0.704059 -0.000001 -vn 0.696496 0.704059 -0.138543 -vn 0.656085 0.704059 -0.271761 -vn 0.517165 0.828645 -0.214217 -vn 0.549019 0.828645 -0.109208 -vn 0.549019 0.828645 -0.109208 -vn 0.696496 0.704059 -0.138543 -vn 0.656085 0.704059 -0.271761 -vn 0.590460 0.704059 -0.394535 -vn 0.465435 0.828645 -0.310995 -vn 0.517165 0.828645 -0.214217 -vn 0.517165 0.828645 -0.214217 -vn 0.656085 0.704059 -0.271761 -vn 0.590460 0.704059 -0.394535 -vn 0.502145 0.704059 -0.502147 -vn 0.395820 0.828645 -0.395822 -vn 0.465435 0.828645 -0.310995 -vn 0.465435 0.828645 -0.310995 -vn 0.590460 0.704059 -0.394535 -vn 0.502145 0.704059 -0.502147 -vn 0.394532 0.704059 -0.590462 -vn 0.310993 0.828645 -0.465437 -vn 0.395820 0.828645 -0.395822 -vn 0.395820 0.828645 -0.395822 -vn 0.502145 0.704059 -0.502147 -vn 0.394532 0.704059 -0.590462 -vn 0.271758 0.704059 -0.656086 -vn 0.214216 0.828645 -0.517165 -vn 0.310993 0.828645 -0.465437 -vn 0.310993 0.828645 -0.465437 -vn 0.394532 0.704059 -0.590462 -vn 0.271758 0.704059 -0.656086 -vn 0.138540 0.704059 -0.696496 -vn 0.109206 0.828645 -0.549019 -vn 0.214216 0.828645 -0.517165 -vn 0.214216 0.828645 -0.517165 -vn 0.271758 0.704059 -0.656086 -vn 0.138540 0.704059 -0.696496 -vn -0.000000 0.704059 -0.710141 -vn -0.000000 0.828645 -0.559775 -vn 0.109206 0.828645 -0.549019 -vn 0.109206 0.828645 -0.549019 -vn 0.138540 0.704059 -0.696496 -vn -0.000000 0.704059 -0.710141 -vn -0.162576 0.552761 -0.817327 -vn -0.138542 0.704059 -0.696496 -vn -0.000000 0.704059 -0.710141 -vn -0.000000 0.704059 -0.710141 -vn -0.000000 0.552761 -0.833340 -vn -0.162576 0.552761 -0.817327 -vn -0.318905 0.552761 -0.769906 -vn -0.271759 0.704059 -0.656085 -vn -0.138542 0.704059 -0.696496 -vn -0.138542 0.704059 -0.696496 -vn -0.162576 0.552761 -0.817327 -vn -0.318905 0.552761 -0.769906 -vn -0.462979 0.552761 -0.692897 -vn -0.394533 0.704059 -0.590461 -vn -0.271759 0.704059 -0.656085 -vn -0.271759 0.704059 -0.656085 -vn -0.318905 0.552761 -0.769906 -vn -0.462979 0.552761 -0.692897 -vn -0.589260 0.552761 -0.589260 -vn -0.502146 0.704059 -0.502146 -vn -0.394533 0.704059 -0.590461 -vn -0.394533 0.704059 -0.590461 -vn -0.462979 0.552761 -0.692897 -vn -0.589260 0.552761 -0.589260 -vn -0.692897 0.552761 -0.462979 -vn -0.590461 0.704059 -0.394533 -vn -0.502146 0.704059 -0.502146 -vn -0.502146 0.704059 -0.502146 -vn -0.589260 0.552761 -0.589260 -vn -0.692897 0.552761 -0.462979 -vn -0.769906 0.552761 -0.318905 -vn -0.656085 0.704059 -0.271759 -vn -0.590461 0.704059 -0.394533 -vn -0.590461 0.704059 -0.394533 -vn -0.692897 0.552761 -0.462979 -vn -0.769906 0.552761 -0.318905 -vn -0.817327 0.552761 -0.162576 -vn -0.696496 0.704059 -0.138541 -vn -0.656085 0.704059 -0.271759 -vn -0.656085 0.704059 -0.271759 -vn -0.769906 0.552761 -0.318905 -vn -0.817327 0.552761 -0.162576 -vn -0.833340 0.552761 0.000000 -vn -0.710141 0.704059 0.000000 -vn -0.696496 0.704059 -0.138541 -vn -0.696496 0.704059 -0.138541 -vn -0.817327 0.552761 -0.162576 -vn -0.833340 0.552761 0.000000 -vn -0.817327 0.552761 0.162577 -vn -0.696496 0.704059 0.138542 -vn -0.710141 0.704059 0.000000 -vn -0.710141 0.704059 0.000000 -vn -0.833340 0.552761 0.000000 -vn -0.817327 0.552761 0.162577 -vn -0.769905 0.552761 0.318906 -vn -0.656085 0.704059 0.271760 -vn -0.696496 0.704059 0.138542 -vn -0.696496 0.704059 0.138542 -vn -0.817327 0.552761 0.162577 -vn -0.769905 0.552761 0.318906 -vn -0.692896 0.552761 0.462979 -vn -0.590461 0.704059 0.394534 -vn -0.656085 0.704059 0.271760 -vn -0.656085 0.704059 0.271760 -vn -0.769905 0.552761 0.318906 -vn -0.692896 0.552761 0.462979 -vn -0.589260 0.552761 0.589260 -vn -0.502145 0.704059 0.502146 -vn -0.590461 0.704059 0.394534 -vn -0.590461 0.704059 0.394534 -vn -0.692896 0.552761 0.462979 -vn -0.589260 0.552761 0.589260 -vn -0.462978 0.552761 0.692897 -vn -0.394533 0.704059 0.590461 -vn -0.502145 0.704059 0.502146 -vn -0.502145 0.704059 0.502146 -vn -0.589260 0.552761 0.589260 -vn -0.462978 0.552761 0.692897 -vn -0.318905 0.552761 0.769906 -vn -0.271759 0.704059 0.656085 -vn -0.394533 0.704059 0.590461 -vn -0.394533 0.704059 0.590461 -vn -0.462978 0.552761 0.692897 -vn -0.318905 0.552761 0.769906 -vn -0.162576 0.552761 0.817328 -vn -0.138541 0.704059 0.696496 -vn -0.271759 0.704059 0.656085 -vn -0.271759 0.704059 0.656085 -vn -0.318905 0.552761 0.769906 -vn -0.162576 0.552761 0.817328 -vn 0.000001 0.552761 0.833340 -vn 0.000001 0.704059 0.710142 -vn -0.138541 0.704059 0.696496 -vn -0.138541 0.704059 0.696496 -vn -0.162576 0.552761 0.817328 -vn 0.000001 0.552761 0.833340 -vn 0.162577 0.552761 0.817327 -vn 0.138542 0.704059 0.696496 -vn 0.000001 0.704059 0.710142 -vn 0.000001 0.704059 0.710142 -vn 0.000001 0.552761 0.833340 -vn 0.162577 0.552761 0.817327 -vn 0.318906 0.552761 0.769905 -vn 0.271760 0.704059 0.656085 -vn 0.138542 0.704059 0.696496 -vn 0.138542 0.704059 0.696496 -vn 0.162577 0.552761 0.817327 -vn 0.318906 0.552761 0.769905 -vn 0.462980 0.552761 0.692896 -vn 0.394534 0.704059 0.590460 -vn 0.271760 0.704059 0.656085 -vn 0.271760 0.704059 0.656085 -vn 0.318906 0.552761 0.769905 -vn 0.462980 0.552761 0.692896 -vn 0.589261 0.552761 0.589259 -vn 0.502146 0.704059 0.502145 -vn 0.394534 0.704059 0.590460 -vn 0.394534 0.704059 0.590460 -vn 0.462980 0.552761 0.692896 -vn 0.589261 0.552761 0.589259 -vn 0.692897 0.552761 0.462978 -vn 0.590461 0.704059 0.394533 -vn 0.502146 0.704059 0.502145 -vn 0.502146 0.704059 0.502145 -vn 0.589261 0.552761 0.589259 -vn 0.692897 0.552761 0.462978 -vn 0.769906 0.552761 0.318904 -vn 0.656086 0.704059 0.271758 -vn 0.590461 0.704059 0.394533 -vn 0.590461 0.704059 0.394533 -vn 0.692897 0.552761 0.462978 -vn 0.769906 0.552761 0.318904 -vn 0.817328 0.552761 0.162575 -vn 0.696496 0.704059 0.138541 -vn 0.656086 0.704059 0.271758 -vn 0.656086 0.704059 0.271758 -vn 0.769906 0.552761 0.318904 -vn 0.817328 0.552761 0.162575 -vn 0.833340 0.552761 -0.000001 -vn 0.710141 0.704059 -0.000001 -vn 0.696496 0.704059 0.138541 -vn 0.696496 0.704059 0.138541 -vn 0.817328 0.552761 0.162575 -vn 0.833340 0.552761 -0.000001 -vn 0.817327 0.552761 -0.162578 -vn 0.696496 0.704059 -0.138543 -vn 0.710141 0.704059 -0.000001 -vn 0.710141 0.704059 -0.000001 -vn 0.833340 0.552761 -0.000001 -vn 0.817327 0.552761 -0.162578 -vn 0.769905 0.552761 -0.318907 -vn 0.656085 0.704059 -0.271761 -vn 0.696496 0.704059 -0.138543 -vn 0.696496 0.704059 -0.138543 -vn 0.817327 0.552761 -0.162578 -vn 0.769905 0.552761 -0.318907 -vn 0.692896 0.552761 -0.462980 -vn 0.590460 0.704059 -0.394535 -vn 0.656085 0.704059 -0.271761 -vn 0.656085 0.704059 -0.271761 -vn 0.769905 0.552761 -0.318907 -vn 0.692896 0.552761 -0.462980 -vn 0.589259 0.552761 -0.589261 -vn 0.502145 0.704059 -0.502147 -vn 0.590460 0.704059 -0.394535 -vn 0.590460 0.704059 -0.394535 -vn 0.692896 0.552761 -0.462980 -vn 0.589259 0.552761 -0.589261 -vn 0.462977 0.552761 -0.692898 -vn 0.394532 0.704059 -0.590462 -vn 0.502145 0.704059 -0.502147 -vn 0.502145 0.704059 -0.502147 -vn 0.589259 0.552761 -0.589261 -vn 0.462977 0.552761 -0.692898 -vn 0.318904 0.552761 -0.769906 -vn 0.271758 0.704059 -0.656086 -vn 0.394532 0.704059 -0.590462 -vn 0.394532 0.704059 -0.590462 -vn 0.462977 0.552761 -0.692898 -vn 0.318904 0.552761 -0.769906 -vn 0.162575 0.552761 -0.817328 -vn 0.138540 0.704059 -0.696496 -vn 0.271758 0.704059 -0.656086 -vn 0.271758 0.704059 -0.656086 -vn 0.318904 0.552761 -0.769906 -vn 0.162575 0.552761 -0.817328 -vn -0.000000 0.552761 -0.833340 -vn -0.000000 0.704059 -0.710141 -vn 0.138540 0.704059 -0.696496 -vn 0.138540 0.704059 -0.696496 -vn 0.162575 0.552761 -0.817328 -vn -0.000000 0.552761 -0.833340 -vn -0.180413 0.380537 -0.906996 -vn -0.162576 0.552761 -0.817327 -vn -0.000000 0.552761 -0.833340 -vn -0.000000 0.552761 -0.833340 -vn -0.000001 0.380537 -0.924766 -vn -0.180413 0.380537 -0.906996 -vn -0.353893 0.380537 -0.854372 -vn -0.318905 0.552761 -0.769906 -vn -0.162576 0.552761 -0.817327 -vn -0.162576 0.552761 -0.817327 -vn -0.180413 0.380537 -0.906996 -vn -0.353893 0.380537 -0.854372 -vn -0.513772 0.380537 -0.768915 -vn -0.462979 0.552761 -0.692897 -vn -0.318905 0.552761 -0.769906 -vn -0.318905 0.552761 -0.769906 -vn -0.353893 0.380537 -0.854372 -vn -0.513772 0.380537 -0.768915 -vn -0.653908 0.380537 -0.653908 -vn -0.589260 0.552761 -0.589260 -vn -0.462979 0.552761 -0.692897 -vn -0.462979 0.552761 -0.692897 -vn -0.513772 0.380537 -0.768915 -vn -0.653908 0.380537 -0.653908 -vn -0.768915 0.380537 -0.513772 -vn -0.692897 0.552761 -0.462979 -vn -0.589260 0.552761 -0.589260 -vn -0.589260 0.552761 -0.589260 -vn -0.653908 0.380537 -0.653908 -vn -0.768915 0.380537 -0.513772 -vn -0.854372 0.380537 -0.353892 -vn -0.769906 0.552761 -0.318905 -vn -0.692897 0.552761 -0.462979 -vn -0.692897 0.552761 -0.462979 -vn -0.768915 0.380537 -0.513772 -vn -0.854372 0.380537 -0.353892 -vn -0.906997 0.380537 -0.180412 -vn -0.817327 0.552761 -0.162576 -vn -0.769906 0.552761 -0.318905 -vn -0.769906 0.552761 -0.318905 -vn -0.854372 0.380537 -0.353892 -vn -0.906997 0.380537 -0.180412 -vn -0.924766 0.380537 0.000000 -vn -0.833340 0.552761 0.000000 -vn -0.817327 0.552761 -0.162576 -vn -0.817327 0.552761 -0.162576 -vn -0.906997 0.380537 -0.180412 -vn -0.924766 0.380537 0.000000 -vn -0.906996 0.380537 0.180413 -vn -0.817327 0.552761 0.162577 -vn -0.833340 0.552761 0.000000 -vn -0.833340 0.552761 0.000000 -vn -0.924766 0.380537 0.000000 -vn -0.906996 0.380537 0.180413 -vn -0.854372 0.380537 0.353893 -vn -0.769905 0.552761 0.318906 -vn -0.817327 0.552761 0.162577 -vn -0.817327 0.552761 0.162577 -vn -0.906996 0.380537 0.180413 -vn -0.854372 0.380537 0.353893 -vn -0.768914 0.380537 0.513773 -vn -0.692896 0.552761 0.462979 -vn -0.769905 0.552761 0.318906 -vn -0.769905 0.552761 0.318906 -vn -0.854372 0.380537 0.353893 -vn -0.768914 0.380537 0.513773 -vn -0.653907 0.380537 0.653908 -vn -0.589260 0.552761 0.589260 -vn -0.692896 0.552761 0.462979 -vn -0.692896 0.552761 0.462979 -vn -0.768914 0.380537 0.513773 -vn -0.653907 0.380537 0.653908 -vn -0.513772 0.380537 0.768915 -vn -0.462978 0.552761 0.692897 -vn -0.589260 0.552761 0.589260 -vn -0.589260 0.552761 0.589260 -vn -0.653907 0.380537 0.653908 -vn -0.513772 0.380537 0.768915 -vn -0.353892 0.380537 0.854372 -vn -0.318905 0.552761 0.769906 -vn -0.462978 0.552761 0.692897 -vn -0.462978 0.552761 0.692897 -vn -0.513772 0.380537 0.768915 -vn -0.353892 0.380537 0.854372 -vn -0.180412 0.380537 0.906997 -vn -0.162576 0.552761 0.817328 -vn -0.318905 0.552761 0.769906 -vn -0.318905 0.552761 0.769906 -vn -0.353892 0.380537 0.854372 -vn -0.180412 0.380537 0.906997 -vn 0.000001 0.380537 0.924766 -vn 0.000001 0.552761 0.833340 -vn -0.162576 0.552761 0.817328 -vn -0.162576 0.552761 0.817328 -vn -0.180412 0.380537 0.906997 -vn 0.000001 0.380537 0.924766 -vn 0.180414 0.380537 0.906996 -vn 0.162577 0.552761 0.817327 -vn 0.000001 0.552761 0.833340 -vn 0.000001 0.552761 0.833340 -vn 0.000001 0.380537 0.924766 -vn 0.180414 0.380537 0.906996 -vn 0.353894 0.380537 0.854372 -vn 0.318906 0.552761 0.769905 -vn 0.162577 0.552761 0.817327 -vn 0.162577 0.552761 0.817327 -vn 0.180414 0.380537 0.906996 -vn 0.353894 0.380537 0.854372 -vn 0.513773 0.380537 0.768914 -vn 0.462980 0.552761 0.692896 -vn 0.318906 0.552761 0.769905 -vn 0.318906 0.552761 0.769905 -vn 0.353894 0.380537 0.854372 -vn 0.513773 0.380537 0.768914 -vn 0.653909 0.380537 0.653907 -vn 0.589261 0.552761 0.589259 -vn 0.462980 0.552761 0.692896 -vn 0.462980 0.552761 0.692896 -vn 0.513773 0.380537 0.768914 -vn 0.653909 0.380537 0.653907 -vn 0.768915 0.380537 0.513771 -vn 0.692897 0.552761 0.462978 -vn 0.589261 0.552761 0.589259 -vn 0.589261 0.552761 0.589259 -vn 0.653909 0.380537 0.653907 -vn 0.768915 0.380537 0.513771 -vn 0.854373 0.380537 0.353891 -vn 0.769906 0.552761 0.318904 -vn 0.692897 0.552761 0.462978 -vn 0.692897 0.552761 0.462978 -vn 0.768915 0.380537 0.513771 -vn 0.854373 0.380537 0.353891 -vn 0.906997 0.380537 0.180411 -vn 0.817328 0.552761 0.162575 -vn 0.769906 0.552761 0.318904 -vn 0.769906 0.552761 0.318904 -vn 0.854373 0.380537 0.353891 -vn 0.906997 0.380537 0.180411 -vn 0.924766 0.380537 -0.000001 -vn 0.833340 0.552761 -0.000001 -vn 0.817328 0.552761 0.162575 -vn 0.817328 0.552761 0.162575 -vn 0.906997 0.380537 0.180411 -vn 0.924766 0.380537 -0.000001 -vn 0.906996 0.380537 -0.180414 -vn 0.817327 0.552761 -0.162578 -vn 0.833340 0.552761 -0.000001 -vn 0.833340 0.552761 -0.000001 -vn 0.924766 0.380537 -0.000001 -vn 0.906996 0.380537 -0.180414 -vn 0.854371 0.380537 -0.353894 -vn 0.769905 0.552761 -0.318907 -vn 0.817327 0.552761 -0.162578 -vn 0.817327 0.552761 -0.162578 -vn 0.906996 0.380537 -0.180414 -vn 0.854371 0.380537 -0.353894 -vn 0.768913 0.380537 -0.513774 -vn 0.692896 0.552761 -0.462980 -vn 0.769905 0.552761 -0.318907 -vn 0.769905 0.552761 -0.318907 -vn 0.854371 0.380537 -0.353894 -vn 0.768913 0.380537 -0.513774 -vn 0.653907 0.380537 -0.653909 -vn 0.589259 0.552761 -0.589261 -vn 0.692896 0.552761 -0.462980 -vn 0.692896 0.552761 -0.462980 -vn 0.768913 0.380537 -0.513774 -vn 0.653907 0.380537 -0.653909 -vn 0.513771 0.380537 -0.768915 -vn 0.462977 0.552761 -0.692898 -vn 0.589259 0.552761 -0.589261 -vn 0.589259 0.552761 -0.589261 -vn 0.653907 0.380537 -0.653909 -vn 0.513771 0.380537 -0.768915 -vn 0.353891 0.380537 -0.854373 -vn 0.318904 0.552761 -0.769906 -vn 0.462977 0.552761 -0.692898 -vn 0.462977 0.552761 -0.692898 -vn 0.513771 0.380537 -0.768915 -vn 0.353891 0.380537 -0.854373 -vn 0.180411 0.380537 -0.906997 -vn 0.162575 0.552761 -0.817328 -vn 0.318904 0.552761 -0.769906 -vn 0.318904 0.552761 -0.769906 -vn 0.353891 0.380537 -0.854373 -vn 0.180411 0.380537 -0.906997 -vn -0.000001 0.380537 -0.924766 -vn -0.000000 0.552761 -0.833340 -vn 0.162575 0.552761 -0.817328 -vn 0.162575 0.552761 -0.817328 -vn 0.180411 0.380537 -0.906997 -vn -0.000001 0.380537 -0.924766 -vn -0.191387 0.193930 -0.962165 -vn -0.180413 0.380537 -0.906996 -vn -0.000001 0.380537 -0.924766 -vn -0.000001 0.380537 -0.924766 -vn -0.000001 0.193930 -0.981015 -vn -0.191387 0.193930 -0.962165 -vn -0.375418 0.193930 -0.906340 -vn -0.353893 0.380537 -0.854372 -vn -0.180413 0.380537 -0.906996 -vn -0.180413 0.380537 -0.906996 -vn -0.191387 0.193930 -0.962165 -vn -0.375418 0.193930 -0.906340 -vn -0.545023 0.193930 -0.815684 -vn -0.513772 0.380537 -0.768915 -vn -0.353893 0.380537 -0.854372 -vn -0.353893 0.380537 -0.854372 -vn -0.375418 0.193930 -0.906340 -vn -0.545023 0.193930 -0.815684 -vn -0.693682 0.193930 -0.693683 -vn -0.653908 0.380537 -0.653908 -vn -0.513772 0.380537 -0.768915 -vn -0.513772 0.380537 -0.768915 -vn -0.545023 0.193930 -0.815684 -vn -0.693682 0.193930 -0.693683 -vn -0.815684 0.193930 -0.545023 -vn -0.768915 0.380537 -0.513772 -vn -0.653908 0.380537 -0.653908 -vn -0.653908 0.380537 -0.653908 -vn -0.693682 0.193930 -0.693683 -vn -0.815684 0.193930 -0.545023 -vn -0.906340 0.193930 -0.375418 -vn -0.854372 0.380537 -0.353892 -vn -0.768915 0.380537 -0.513772 -vn -0.768915 0.380537 -0.513772 -vn -0.815684 0.193930 -0.545023 -vn -0.906340 0.193930 -0.375418 -vn -0.962165 0.193930 -0.191386 -vn -0.906997 0.380537 -0.180412 -vn -0.854372 0.380537 -0.353892 -vn -0.854372 0.380537 -0.353892 -vn -0.906340 0.193930 -0.375418 -vn -0.962165 0.193930 -0.191386 -vn -0.981015 0.193930 0.000000 -vn -0.924766 0.380537 0.000000 -vn -0.906997 0.380537 -0.180412 -vn -0.906997 0.380537 -0.180412 -vn -0.962165 0.193930 -0.191386 -vn -0.981015 0.193930 0.000000 -vn -0.962165 0.193930 0.191387 -vn -0.906996 0.380537 0.180413 -vn -0.924766 0.380537 0.000000 -vn -0.924766 0.380537 0.000000 -vn -0.981015 0.193930 0.000000 -vn -0.962165 0.193930 0.191387 -vn -0.906340 0.193930 0.375419 -vn -0.854372 0.380537 0.353893 -vn -0.906996 0.380537 0.180413 -vn -0.906996 0.380537 0.180413 -vn -0.962165 0.193930 0.191387 -vn -0.906340 0.193930 0.375419 -vn -0.815684 0.193930 0.545023 -vn -0.768914 0.380537 0.513773 -vn -0.854372 0.380537 0.353893 -vn -0.854372 0.380537 0.353893 -vn -0.906340 0.193930 0.375419 -vn -0.815684 0.193930 0.545023 -vn -0.693682 0.193930 0.693683 -vn -0.653907 0.380537 0.653908 -vn -0.768914 0.380537 0.513773 -vn -0.768914 0.380537 0.513773 -vn -0.815684 0.193930 0.545023 -vn -0.693682 0.193930 0.693683 -vn -0.545022 0.193930 0.815685 -vn -0.513772 0.380537 0.768915 -vn -0.653907 0.380537 0.653908 -vn -0.653907 0.380537 0.653908 -vn -0.693682 0.193930 0.693683 -vn -0.545022 0.193930 0.815685 -vn -0.375417 0.193930 0.906340 -vn -0.353892 0.380537 0.854372 -vn -0.513772 0.380537 0.768915 -vn -0.513772 0.380537 0.768915 -vn -0.545022 0.193930 0.815685 -vn -0.375417 0.193930 0.906340 -vn -0.191386 0.193930 0.962166 -vn -0.180412 0.380537 0.906997 -vn -0.353892 0.380537 0.854372 -vn -0.353892 0.380537 0.854372 -vn -0.375417 0.193930 0.906340 -vn -0.191386 0.193930 0.962166 -vn 0.000001 0.193930 0.981015 -vn 0.000001 0.380537 0.924766 -vn -0.180412 0.380537 0.906997 -vn -0.180412 0.380537 0.906997 -vn -0.191386 0.193930 0.962166 -vn 0.000001 0.193930 0.981015 -vn 0.191388 0.193930 0.962165 -vn 0.180414 0.380537 0.906996 -vn 0.000001 0.380537 0.924766 -vn 0.000001 0.380537 0.924766 -vn 0.000001 0.193930 0.981015 -vn 0.191388 0.193930 0.962165 -vn 0.375419 0.193930 0.906339 -vn 0.353894 0.380537 0.854372 -vn 0.180414 0.380537 0.906996 -vn 0.180414 0.380537 0.906996 -vn 0.191388 0.193930 0.962165 -vn 0.375419 0.193930 0.906339 -vn 0.545024 0.193930 0.815684 -vn 0.513773 0.380537 0.768914 -vn 0.353894 0.380537 0.854372 -vn 0.353894 0.380537 0.854372 -vn 0.375419 0.193930 0.906339 -vn 0.545024 0.193930 0.815684 -vn 0.693683 0.193930 0.693682 -vn 0.653909 0.380537 0.653907 -vn 0.513773 0.380537 0.768914 -vn 0.513773 0.380537 0.768914 -vn 0.545024 0.193930 0.815684 -vn 0.693683 0.193930 0.693682 -vn 0.815685 0.193930 0.545022 -vn 0.768915 0.380537 0.513771 -vn 0.653909 0.380537 0.653907 -vn 0.653909 0.380537 0.653907 -vn 0.693683 0.193930 0.693682 -vn 0.815685 0.193930 0.545022 -vn 0.906341 0.193930 0.375417 -vn 0.854373 0.380537 0.353891 -vn 0.768915 0.380537 0.513771 -vn 0.768915 0.380537 0.513771 -vn 0.815685 0.193930 0.545022 -vn 0.906341 0.193930 0.375417 -vn 0.962166 0.193931 0.191385 -vn 0.906997 0.380537 0.180411 -vn 0.854373 0.380537 0.353891 -vn 0.854373 0.380537 0.353891 -vn 0.906341 0.193930 0.375417 -vn 0.962166 0.193931 0.191385 -vn 0.981015 0.193930 -0.000001 -vn 0.924766 0.380537 -0.000001 -vn 0.906997 0.380537 0.180411 -vn 0.906997 0.380537 0.180411 -vn 0.962166 0.193931 0.191385 -vn 0.981015 0.193930 -0.000001 -vn 0.962165 0.193930 -0.191388 -vn 0.906996 0.380537 -0.180414 -vn 0.924766 0.380537 -0.000001 -vn 0.924766 0.380537 -0.000001 -vn 0.981015 0.193930 -0.000001 -vn 0.962165 0.193930 -0.191388 -vn 0.906339 0.193930 -0.375420 -vn 0.854371 0.380537 -0.353894 -vn 0.906996 0.380537 -0.180414 -vn 0.906996 0.380537 -0.180414 -vn 0.962165 0.193930 -0.191388 -vn 0.906339 0.193930 -0.375420 -vn 0.815683 0.193930 -0.545025 -vn 0.768913 0.380537 -0.513774 -vn 0.854371 0.380537 -0.353894 -vn 0.854371 0.380537 -0.353894 -vn 0.906339 0.193930 -0.375420 -vn 0.815683 0.193930 -0.545025 -vn 0.693681 0.193930 -0.693684 -vn 0.653907 0.380537 -0.653909 -vn 0.768913 0.380537 -0.513774 -vn 0.768913 0.380537 -0.513774 -vn 0.815683 0.193930 -0.545025 -vn 0.693681 0.193930 -0.693684 -vn 0.545021 0.193931 -0.815685 -vn 0.513771 0.380537 -0.768915 -vn 0.653907 0.380537 -0.653909 -vn 0.653907 0.380537 -0.653909 -vn 0.693681 0.193930 -0.693684 -vn 0.545021 0.193931 -0.815685 -vn 0.375416 0.193930 -0.906341 -vn 0.353891 0.380537 -0.854373 -vn 0.513771 0.380537 -0.768915 -vn 0.513771 0.380537 -0.768915 -vn 0.545021 0.193931 -0.815685 -vn 0.375416 0.193930 -0.906341 -vn 0.191385 0.193930 -0.962166 -vn 0.180411 0.380537 -0.906997 -vn 0.353891 0.380537 -0.854373 -vn 0.353891 0.380537 -0.854373 -vn 0.375416 0.193930 -0.906341 -vn 0.191385 0.193930 -0.962166 -vn -0.000001 0.193930 -0.981015 -vn -0.000001 0.380537 -0.924766 -vn 0.180411 0.380537 -0.906997 -vn 0.180411 0.380537 -0.906997 -vn 0.191385 0.193930 -0.962166 -vn -0.000001 0.193930 -0.981015 -vn -0.195090 0.000000 -0.980785 -vn -0.191387 0.193930 -0.962165 -vn -0.000001 0.193930 -0.981015 -vn -0.000001 0.193930 -0.981015 -vn -0.000000 0.000000 -1.000000 -vn -0.195090 0.000000 -0.980785 -vn -0.382683 0.000000 -0.923880 -vn -0.375418 0.193930 -0.906340 -vn -0.191387 0.193930 -0.962165 -vn -0.191387 0.193930 -0.962165 -vn -0.195090 0.000000 -0.980785 -vn -0.382683 0.000000 -0.923880 -vn -0.555570 0.000000 -0.831469 -vn -0.545023 0.193930 -0.815684 -vn -0.375418 0.193930 -0.906340 -vn -0.375418 0.193930 -0.906340 -vn -0.382683 0.000000 -0.923880 -vn -0.555570 0.000000 -0.831469 -vn -0.707107 0.000000 -0.707107 -vn -0.693682 0.193930 -0.693683 -vn -0.545023 0.193930 -0.815684 -vn -0.545023 0.193930 -0.815684 -vn -0.555570 0.000000 -0.831469 -vn -0.707107 0.000000 -0.707107 -vn -0.831470 0.000000 -0.555570 -vn -0.815684 0.193930 -0.545023 -vn -0.693682 0.193930 -0.693683 -vn -0.693682 0.193930 -0.693683 -vn -0.707107 0.000000 -0.707107 -vn -0.831470 0.000000 -0.555570 -vn -0.923880 0.000000 -0.382683 -vn -0.906340 0.193930 -0.375418 -vn -0.815684 0.193930 -0.545023 -vn -0.815684 0.193930 -0.545023 -vn -0.831470 0.000000 -0.555570 -vn -0.923880 0.000000 -0.382683 -vn -0.980785 0.000000 -0.195090 -vn -0.962165 0.193930 -0.191386 -vn -0.906340 0.193930 -0.375418 -vn -0.906340 0.193930 -0.375418 -vn -0.923880 0.000000 -0.382683 -vn -0.980785 0.000000 -0.195090 -vn -1.000000 0.000000 0.000000 -vn -0.981015 0.193930 0.000000 -vn -0.962165 0.193930 -0.191386 -vn -0.962165 0.193930 -0.191386 -vn -0.980785 0.000000 -0.195090 -vn -1.000000 0.000000 0.000000 -vn -0.980785 0.000000 0.195091 -vn -0.962165 0.193930 0.191387 -vn -0.981015 0.193930 0.000000 -vn -0.981015 0.193930 0.000000 -vn -1.000000 0.000000 0.000000 -vn -0.980785 0.000000 0.195091 -vn -0.923879 0.000000 0.382684 -vn -0.906340 0.193930 0.375419 -vn -0.962165 0.193930 0.191387 -vn -0.962165 0.193930 0.191387 -vn -0.980785 0.000000 0.195091 -vn -0.923879 0.000000 0.382684 -vn -0.831469 0.000000 0.555570 -vn -0.815684 0.193930 0.545023 -vn -0.906340 0.193930 0.375419 -vn -0.906340 0.193930 0.375419 -vn -0.923879 0.000000 0.382684 -vn -0.831469 0.000000 0.555570 -vn -0.707106 0.000000 0.707107 -vn -0.693682 0.193930 0.693683 -vn -0.815684 0.193930 0.545023 -vn -0.815684 0.193930 0.545023 -vn -0.831469 0.000000 0.555570 -vn -0.707106 0.000000 0.707107 -vn -0.555570 0.000000 0.831470 -vn -0.545022 0.193930 0.815685 -vn -0.693682 0.193930 0.693683 -vn -0.693682 0.193930 0.693683 -vn -0.707106 0.000000 0.707107 -vn -0.555570 0.000000 0.831470 -vn -0.382683 0.000000 0.923880 -vn -0.375417 0.193930 0.906340 -vn -0.545022 0.193930 0.815685 -vn -0.545022 0.193930 0.815685 -vn -0.555570 0.000000 0.831470 -vn -0.382683 0.000000 0.923880 -vn -0.195090 0.000000 0.980785 -vn -0.191386 0.193930 0.962166 -vn -0.375417 0.193930 0.906340 -vn -0.375417 0.193930 0.906340 -vn -0.382683 0.000000 0.923880 -vn -0.195090 0.000000 0.980785 -vn 0.000001 0.000000 1.000000 -vn 0.000001 0.193930 0.981015 -vn -0.191386 0.193930 0.962166 -vn -0.191386 0.193930 0.962166 -vn -0.195090 0.000000 0.980785 -vn 0.000001 0.000000 1.000000 -vn 0.195092 0.000000 0.980785 -vn 0.191388 0.193930 0.962165 -vn 0.000001 0.193930 0.981015 -vn 0.000001 0.193930 0.981015 -vn 0.000001 0.000000 1.000000 -vn 0.195092 0.000000 0.980785 -vn 0.382685 0.000000 0.923879 -vn 0.375419 0.193930 0.906339 -vn 0.191388 0.193930 0.962165 -vn 0.191388 0.193930 0.962165 -vn 0.195092 0.000000 0.980785 -vn 0.382685 0.000000 0.923879 -vn 0.555571 0.000000 0.831469 -vn 0.545024 0.193930 0.815684 -vn 0.375419 0.193930 0.906339 -vn 0.375419 0.193930 0.906339 -vn 0.382685 0.000000 0.923879 -vn 0.555571 0.000000 0.831469 -vn 0.707108 0.000000 0.707106 -vn 0.693683 0.193930 0.693682 -vn 0.545024 0.193930 0.815684 -vn 0.545024 0.193930 0.815684 -vn 0.555571 0.000000 0.831469 -vn 0.707108 0.000000 0.707106 -vn 0.831470 -0.000000 0.555569 -vn 0.815685 0.193930 0.545022 -vn 0.693683 0.193930 0.693682 -vn 0.693683 0.193930 0.693682 -vn 0.707108 0.000000 0.707106 -vn 0.831470 -0.000000 0.555569 -vn 0.923880 0.000000 0.382682 -vn 0.906341 0.193930 0.375417 -vn 0.815685 0.193930 0.545022 -vn 0.815685 0.193930 0.545022 -vn 0.831470 -0.000000 0.555569 -vn 0.923880 0.000000 0.382682 -vn 0.980786 0.000000 0.195089 -vn 0.962166 0.193931 0.191385 -vn 0.906341 0.193930 0.375417 -vn 0.906341 0.193930 0.375417 -vn 0.923880 0.000000 0.382682 -vn 0.980786 0.000000 0.195089 -vn 1.000000 0.000001 -0.000002 -vn 0.981015 0.193930 -0.000001 -vn 0.962166 0.193931 0.191385 -vn 0.962166 0.193931 0.191385 -vn 0.980786 0.000000 0.195089 -vn 1.000000 0.000001 -0.000002 -vn 0.980785 0.000000 -0.195092 -vn 0.962165 0.193930 -0.191388 -vn 0.981015 0.193930 -0.000001 -vn 0.981015 0.193930 -0.000001 -vn 1.000000 0.000001 -0.000002 -vn 0.980785 0.000000 -0.195092 -vn 0.923879 -0.000000 -0.382685 -vn 0.906339 0.193930 -0.375420 -vn 0.962165 0.193930 -0.191388 -vn 0.962165 0.193930 -0.191388 -vn 0.980785 0.000000 -0.195092 -vn 0.923879 -0.000000 -0.382685 -vn 0.831469 0.000000 -0.555572 -vn 0.815683 0.193930 -0.545025 -vn 0.906339 0.193930 -0.375420 -vn 0.906339 0.193930 -0.375420 -vn 0.923879 -0.000000 -0.382685 -vn 0.831469 0.000000 -0.555572 -vn 0.707106 0.000000 -0.707108 -vn 0.693681 0.193930 -0.693684 -vn 0.815683 0.193930 -0.545025 -vn 0.815683 0.193930 -0.545025 -vn 0.831469 0.000000 -0.555572 -vn 0.707106 0.000000 -0.707108 -vn 0.555569 0.000000 -0.831471 -vn 0.545021 0.193931 -0.815685 -vn 0.693681 0.193930 -0.693684 -vn 0.693681 0.193930 -0.693684 -vn 0.707106 0.000000 -0.707108 -vn 0.555569 0.000000 -0.831471 -vn 0.382681 0.000000 -0.923880 -vn 0.375416 0.193930 -0.906341 -vn 0.545021 0.193931 -0.815685 -vn 0.545021 0.193931 -0.815685 -vn 0.555569 0.000000 -0.831471 -vn 0.382681 0.000000 -0.923880 -vn 0.195089 0.000000 -0.980786 -vn 0.191385 0.193930 -0.962166 -vn 0.375416 0.193930 -0.906341 -vn 0.375416 0.193930 -0.906341 -vn 0.382681 0.000000 -0.923880 -vn 0.195089 0.000000 -0.980786 -vn -0.000000 0.000000 -1.000000 -vn -0.000001 0.193930 -0.981015 -vn 0.191385 0.193930 -0.962166 -vn 0.191385 0.193930 -0.962166 -vn 0.195089 0.000000 -0.980786 -vn -0.000000 0.000000 -1.000000 -vn -0.191387 -0.193930 -0.962165 -vn -0.195090 0.000000 -0.980785 -vn -0.000000 0.000000 -1.000000 -vn -0.000000 0.000000 -1.000000 -vn -0.000001 -0.193930 -0.981015 -vn -0.191387 -0.193930 -0.962165 -vn -0.375418 -0.193930 -0.906340 -vn -0.382683 0.000000 -0.923880 -vn -0.195090 0.000000 -0.980785 -vn -0.195090 0.000000 -0.980785 -vn -0.191387 -0.193930 -0.962165 -vn -0.375418 -0.193930 -0.906340 -vn -0.545023 -0.193930 -0.815684 -vn -0.555570 0.000000 -0.831469 -vn -0.382683 0.000000 -0.923880 -vn -0.382683 0.000000 -0.923880 -vn -0.375418 -0.193930 -0.906340 -vn -0.545023 -0.193930 -0.815684 -vn -0.693683 -0.193930 -0.693683 -vn -0.707107 0.000000 -0.707107 -vn -0.555570 0.000000 -0.831469 -vn -0.555570 0.000000 -0.831469 -vn -0.545023 -0.193930 -0.815684 -vn -0.693683 -0.193930 -0.693683 -vn -0.815684 -0.193930 -0.545023 -vn -0.831470 0.000000 -0.555570 -vn -0.707107 0.000000 -0.707107 -vn -0.707107 0.000000 -0.707107 -vn -0.693683 -0.193930 -0.693683 -vn -0.815684 -0.193930 -0.545023 -vn -0.906340 -0.193930 -0.375418 -vn -0.923880 0.000000 -0.382683 -vn -0.831470 0.000000 -0.555570 -vn -0.831470 0.000000 -0.555570 -vn -0.815684 -0.193930 -0.545023 -vn -0.906340 -0.193930 -0.375418 -vn -0.962165 -0.193930 -0.191386 -vn -0.980785 0.000000 -0.195090 -vn -0.923880 0.000000 -0.382683 -vn -0.923880 0.000000 -0.382683 -vn -0.906340 -0.193930 -0.375418 -vn -0.962165 -0.193930 -0.191386 -vn -0.981015 -0.193930 0.000000 -vn -1.000000 0.000000 0.000000 -vn -0.980785 0.000000 -0.195090 -vn -0.980785 0.000000 -0.195090 -vn -0.962165 -0.193930 -0.191386 -vn -0.981015 -0.193930 0.000000 -vn -0.962165 -0.193930 0.191387 -vn -0.980785 0.000000 0.195091 -vn -1.000000 0.000000 0.000000 -vn -1.000000 0.000000 0.000000 -vn -0.981015 -0.193930 0.000000 -vn -0.962165 -0.193930 0.191387 -vn -0.906340 -0.193930 0.375419 -vn -0.923879 0.000000 0.382684 -vn -0.980785 0.000000 0.195091 -vn -0.980785 0.000000 0.195091 -vn -0.962165 -0.193930 0.191387 -vn -0.906340 -0.193930 0.375419 -vn -0.815684 -0.193930 0.545023 -vn -0.831469 0.000000 0.555570 -vn -0.923879 0.000000 0.382684 -vn -0.923879 0.000000 0.382684 -vn -0.906340 -0.193930 0.375419 -vn -0.815684 -0.193930 0.545023 -vn -0.693682 -0.193930 0.693683 -vn -0.707106 0.000000 0.707107 -vn -0.831469 0.000000 0.555570 -vn -0.831469 0.000000 0.555570 -vn -0.815684 -0.193930 0.545023 -vn -0.693682 -0.193930 0.693683 -vn -0.545023 -0.193930 0.815685 -vn -0.555570 0.000000 0.831470 -vn -0.707106 0.000000 0.707107 -vn -0.707106 0.000000 0.707107 -vn -0.693682 -0.193930 0.693683 -vn -0.545023 -0.193930 0.815685 -vn -0.375417 -0.193930 0.906340 -vn -0.382683 0.000000 0.923880 -vn -0.555570 0.000000 0.831470 -vn -0.555570 0.000000 0.831470 -vn -0.545023 -0.193930 0.815685 -vn -0.375417 -0.193930 0.906340 -vn -0.191386 -0.193930 0.962166 -vn -0.195090 0.000000 0.980785 -vn -0.382683 0.000000 0.923880 -vn -0.382683 0.000000 0.923880 -vn -0.375417 -0.193930 0.906340 -vn -0.191386 -0.193930 0.962166 -vn 0.000001 -0.193930 0.981015 -vn 0.000001 0.000000 1.000000 -vn -0.195090 0.000000 0.980785 -vn -0.195090 0.000000 0.980785 -vn -0.191386 -0.193930 0.962166 -vn 0.000001 -0.193930 0.981015 -vn 0.191388 -0.193930 0.962165 -vn 0.195092 0.000000 0.980785 -vn 0.000001 0.000000 1.000000 -vn 0.000001 0.000000 1.000000 -vn 0.000001 -0.193930 0.981015 -vn 0.191388 -0.193930 0.962165 -vn 0.375419 -0.193930 0.906340 -vn 0.382685 0.000000 0.923879 -vn 0.195092 0.000000 0.980785 -vn 0.195092 0.000000 0.980785 -vn 0.191388 -0.193930 0.962165 -vn 0.375419 -0.193930 0.906340 -vn 0.545024 -0.193930 0.815684 -vn 0.555571 0.000000 0.831469 -vn 0.382685 0.000000 0.923879 -vn 0.382685 0.000000 0.923879 -vn 0.375419 -0.193930 0.906340 -vn 0.545024 -0.193930 0.815684 -vn 0.693684 -0.193930 0.693682 -vn 0.707108 0.000000 0.707106 -vn 0.555571 0.000000 0.831469 -vn 0.555571 0.000000 0.831469 -vn 0.545024 -0.193930 0.815684 -vn 0.693684 -0.193930 0.693682 -vn 0.815685 -0.193930 0.545022 -vn 0.831470 -0.000000 0.555569 -vn 0.707108 0.000000 0.707106 -vn 0.707108 0.000000 0.707106 -vn 0.693684 -0.193930 0.693682 -vn 0.815685 -0.193930 0.545022 -vn 0.906340 -0.193930 0.375417 -vn 0.923880 0.000000 0.382682 -vn 0.831470 -0.000000 0.555569 -vn 0.831470 -0.000000 0.555569 -vn 0.815685 -0.193930 0.545022 -vn 0.906340 -0.193930 0.375417 -vn 0.962166 -0.193930 0.191385 -vn 0.980786 0.000000 0.195089 -vn 0.923880 0.000000 0.382682 -vn 0.923880 0.000000 0.382682 -vn 0.906340 -0.193930 0.375417 -vn 0.962166 -0.193930 0.191385 -vn 0.981015 -0.193930 -0.000002 -vn 1.000000 0.000001 -0.000002 -vn 0.980786 0.000000 0.195089 -vn 0.980786 0.000000 0.195089 -vn 0.962166 -0.193930 0.191385 -vn 0.981015 -0.193930 -0.000002 -vn 0.962165 -0.193930 -0.191388 -vn 0.980785 0.000000 -0.195092 -vn 1.000000 0.000001 -0.000002 -vn 1.000000 0.000001 -0.000002 -vn 0.981015 -0.193930 -0.000002 -vn 0.962165 -0.193930 -0.191388 -vn 0.906339 -0.193930 -0.375420 -vn 0.923879 -0.000000 -0.382685 -vn 0.980785 0.000000 -0.195092 -vn 0.980785 0.000000 -0.195092 -vn 0.962165 -0.193930 -0.191388 -vn 0.906339 -0.193930 -0.375420 -vn 0.815684 -0.193930 -0.545024 -vn 0.831469 0.000000 -0.555572 -vn 0.923879 -0.000000 -0.382685 -vn 0.923879 -0.000000 -0.382685 -vn 0.906339 -0.193930 -0.375420 -vn 0.815684 -0.193930 -0.545024 -vn 0.693681 -0.193930 -0.693684 -vn 0.707106 0.000000 -0.707108 -vn 0.831469 0.000000 -0.555572 -vn 0.831469 0.000000 -0.555572 -vn 0.815684 -0.193930 -0.545024 -vn 0.693681 -0.193930 -0.693684 -vn 0.545021 -0.193930 -0.815686 -vn 0.555569 0.000000 -0.831471 -vn 0.707106 0.000000 -0.707108 -vn 0.707106 0.000000 -0.707108 -vn 0.693681 -0.193930 -0.693684 -vn 0.545021 -0.193930 -0.815686 -vn 0.375416 -0.193930 -0.906341 -vn 0.382681 0.000000 -0.923880 -vn 0.555569 0.000000 -0.831471 -vn 0.555569 0.000000 -0.831471 -vn 0.545021 -0.193930 -0.815686 -vn 0.375416 -0.193930 -0.906341 -vn 0.191385 -0.193930 -0.962166 -vn 0.195089 0.000000 -0.980786 -vn 0.382681 0.000000 -0.923880 -vn 0.382681 0.000000 -0.923880 -vn 0.375416 -0.193930 -0.906341 -vn 0.191385 -0.193930 -0.962166 -vn -0.000001 -0.193930 -0.981015 -vn -0.000000 0.000000 -1.000000 -vn 0.195089 0.000000 -0.980786 -vn 0.195089 0.000000 -0.980786 -vn 0.191385 -0.193930 -0.962166 -vn -0.000001 -0.193930 -0.981015 -vn -0.180413 -0.380537 -0.906996 -vn -0.191387 -0.193930 -0.962165 -vn -0.000001 -0.193930 -0.981015 -vn -0.000001 -0.193930 -0.981015 -vn -0.000001 -0.380537 -0.924766 -vn -0.180413 -0.380537 -0.906996 -vn -0.353893 -0.380537 -0.854372 -vn -0.375418 -0.193930 -0.906340 -vn -0.191387 -0.193930 -0.962165 -vn -0.191387 -0.193930 -0.962165 -vn -0.180413 -0.380537 -0.906996 -vn -0.353893 -0.380537 -0.854372 -vn -0.513772 -0.380537 -0.768914 -vn -0.545023 -0.193930 -0.815684 -vn -0.375418 -0.193930 -0.906340 -vn -0.375418 -0.193930 -0.906340 -vn -0.353893 -0.380537 -0.854372 -vn -0.513772 -0.380537 -0.768914 -vn -0.653908 -0.380537 -0.653908 -vn -0.693683 -0.193930 -0.693683 -vn -0.545023 -0.193930 -0.815684 -vn -0.545023 -0.193930 -0.815684 -vn -0.513772 -0.380537 -0.768914 -vn -0.653908 -0.380537 -0.653908 -vn -0.768914 -0.380537 -0.513772 -vn -0.815684 -0.193930 -0.545023 -vn -0.693683 -0.193930 -0.693683 -vn -0.693683 -0.193930 -0.693683 -vn -0.653908 -0.380537 -0.653908 -vn -0.768914 -0.380537 -0.513772 -vn -0.854372 -0.380537 -0.353892 -vn -0.906340 -0.193930 -0.375418 -vn -0.815684 -0.193930 -0.545023 -vn -0.815684 -0.193930 -0.545023 -vn -0.768914 -0.380537 -0.513772 -vn -0.854372 -0.380537 -0.353892 -vn -0.906996 -0.380537 -0.180413 -vn -0.962165 -0.193930 -0.191386 -vn -0.906340 -0.193930 -0.375418 -vn -0.906340 -0.193930 -0.375418 -vn -0.854372 -0.380537 -0.353892 -vn -0.906996 -0.380537 -0.180413 -vn -0.924766 -0.380537 0.000000 -vn -0.981015 -0.193930 0.000000 -vn -0.962165 -0.193930 -0.191386 -vn -0.962165 -0.193930 -0.191386 -vn -0.906996 -0.380537 -0.180413 -vn -0.924766 -0.380537 0.000000 -vn -0.906996 -0.380537 0.180413 -vn -0.962165 -0.193930 0.191387 -vn -0.981015 -0.193930 0.000000 -vn -0.981015 -0.193930 0.000000 -vn -0.924766 -0.380537 0.000000 -vn -0.906996 -0.380537 0.180413 -vn -0.854372 -0.380537 0.353893 -vn -0.906340 -0.193930 0.375419 -vn -0.962165 -0.193930 0.191387 -vn -0.962165 -0.193930 0.191387 -vn -0.906996 -0.380537 0.180413 -vn -0.854372 -0.380537 0.353893 -vn -0.768914 -0.380537 0.513773 -vn -0.815684 -0.193930 0.545023 -vn -0.906340 -0.193930 0.375419 -vn -0.906340 -0.193930 0.375419 -vn -0.854372 -0.380537 0.353893 -vn -0.768914 -0.380537 0.513773 -vn -0.653908 -0.380537 0.653908 -vn -0.693682 -0.193930 0.693683 -vn -0.815684 -0.193930 0.545023 -vn -0.815684 -0.193930 0.545023 -vn -0.768914 -0.380537 0.513773 -vn -0.653908 -0.380537 0.653908 -vn -0.513772 -0.380537 0.768915 -vn -0.545023 -0.193930 0.815685 -vn -0.693682 -0.193930 0.693683 -vn -0.693682 -0.193930 0.693683 -vn -0.653908 -0.380537 0.653908 -vn -0.513772 -0.380537 0.768915 -vn -0.353892 -0.380537 0.854372 -vn -0.375417 -0.193930 0.906340 -vn -0.545023 -0.193930 0.815685 -vn -0.545023 -0.193930 0.815685 -vn -0.513772 -0.380537 0.768915 -vn -0.353892 -0.380537 0.854372 -vn -0.180412 -0.380537 0.906997 -vn -0.191386 -0.193930 0.962166 -vn -0.375417 -0.193930 0.906340 -vn -0.375417 -0.193930 0.906340 -vn -0.353892 -0.380537 0.854372 -vn -0.180412 -0.380537 0.906997 -vn 0.000001 -0.380537 0.924766 -vn 0.000001 -0.193930 0.981015 -vn -0.191386 -0.193930 0.962166 -vn -0.191386 -0.193930 0.962166 -vn -0.180412 -0.380537 0.906997 -vn 0.000001 -0.380537 0.924766 -vn 0.180414 -0.380537 0.906996 -vn 0.191388 -0.193930 0.962165 -vn 0.000001 -0.193930 0.981015 -vn 0.000001 -0.193930 0.981015 -vn 0.000001 -0.380537 0.924766 -vn 0.180414 -0.380537 0.906996 -vn 0.353893 -0.380537 0.854372 -vn 0.375419 -0.193930 0.906340 -vn 0.191388 -0.193930 0.962165 -vn 0.191388 -0.193930 0.962165 -vn 0.180414 -0.380537 0.906996 -vn 0.353893 -0.380537 0.854372 -vn 0.513773 -0.380537 0.768914 -vn 0.545024 -0.193930 0.815684 -vn 0.375419 -0.193930 0.906340 -vn 0.375419 -0.193930 0.906340 -vn 0.353893 -0.380537 0.854372 -vn 0.513773 -0.380537 0.768914 -vn 0.653909 -0.380537 0.653907 -vn 0.693684 -0.193930 0.693682 -vn 0.545024 -0.193930 0.815684 -vn 0.545024 -0.193930 0.815684 -vn 0.513773 -0.380537 0.768914 -vn 0.653909 -0.380537 0.653907 -vn 0.768915 -0.380537 0.513771 -vn 0.815685 -0.193930 0.545022 -vn 0.693684 -0.193930 0.693682 -vn 0.693684 -0.193930 0.693682 -vn 0.653909 -0.380537 0.653907 -vn 0.768915 -0.380537 0.513771 -vn 0.854373 -0.380537 0.353891 -vn 0.906340 -0.193930 0.375417 -vn 0.815685 -0.193930 0.545022 -vn 0.815685 -0.193930 0.545022 -vn 0.768915 -0.380537 0.513771 -vn 0.854373 -0.380537 0.353891 -vn 0.906997 -0.380537 0.180411 -vn 0.962166 -0.193930 0.191385 -vn 0.906340 -0.193930 0.375417 -vn 0.906340 -0.193930 0.375417 -vn 0.854373 -0.380537 0.353891 -vn 0.906997 -0.380537 0.180411 -vn 0.924766 -0.380537 -0.000002 -vn 0.981015 -0.193930 -0.000002 -vn 0.962166 -0.193930 0.191385 -vn 0.962166 -0.193930 0.191385 -vn 0.906997 -0.380537 0.180411 -vn 0.924766 -0.380537 -0.000002 -vn 0.906996 -0.380537 -0.180414 -vn 0.962165 -0.193930 -0.191388 -vn 0.981015 -0.193930 -0.000002 -vn 0.981015 -0.193930 -0.000002 -vn 0.924766 -0.380537 -0.000002 -vn 0.906996 -0.380537 -0.180414 -vn 0.854371 -0.380537 -0.353894 -vn 0.906339 -0.193930 -0.375420 -vn 0.962165 -0.193930 -0.191388 -vn 0.962165 -0.193930 -0.191388 -vn 0.906996 -0.380537 -0.180414 -vn 0.854371 -0.380537 -0.353894 -vn 0.768914 -0.380537 -0.513774 -vn 0.815684 -0.193930 -0.545024 -vn 0.906339 -0.193930 -0.375420 -vn 0.906339 -0.193930 -0.375420 -vn 0.854371 -0.380537 -0.353894 -vn 0.768914 -0.380537 -0.513774 -vn 0.653907 -0.380537 -0.653909 -vn 0.693681 -0.193930 -0.693684 -vn 0.815684 -0.193930 -0.545024 -vn 0.815684 -0.193930 -0.545024 -vn 0.768914 -0.380537 -0.513774 -vn 0.653907 -0.380537 -0.653909 -vn 0.513770 -0.380537 -0.768916 -vn 0.545021 -0.193930 -0.815686 -vn 0.693681 -0.193930 -0.693684 -vn 0.693681 -0.193930 -0.693684 -vn 0.653907 -0.380537 -0.653909 -vn 0.513770 -0.380537 -0.768916 -vn 0.353891 -0.380537 -0.854373 -vn 0.375416 -0.193930 -0.906341 -vn 0.545021 -0.193930 -0.815686 -vn 0.545021 -0.193930 -0.815686 -vn 0.513770 -0.380537 -0.768916 -vn 0.353891 -0.380537 -0.854373 -vn 0.180412 -0.380537 -0.906997 -vn 0.191385 -0.193930 -0.962166 -vn 0.375416 -0.193930 -0.906341 -vn 0.375416 -0.193930 -0.906341 -vn 0.353891 -0.380537 -0.854373 -vn 0.180412 -0.380537 -0.906997 -vn -0.000001 -0.380537 -0.924766 -vn -0.000001 -0.193930 -0.981015 -vn 0.191385 -0.193930 -0.962166 -vn 0.191385 -0.193930 -0.962166 -vn 0.180412 -0.380537 -0.906997 -vn -0.000001 -0.380537 -0.924766 -vn -0.162576 -0.552761 -0.817327 -vn -0.180413 -0.380537 -0.906996 -vn -0.000001 -0.380537 -0.924766 -vn -0.000001 -0.380537 -0.924766 -vn -0.000001 -0.552761 -0.833340 -vn -0.162576 -0.552761 -0.817327 -vn -0.318905 -0.552761 -0.769906 -vn -0.353893 -0.380537 -0.854372 -vn -0.180413 -0.380537 -0.906996 -vn -0.180413 -0.380537 -0.906996 -vn -0.162576 -0.552761 -0.817327 -vn -0.318905 -0.552761 -0.769906 -vn -0.462979 -0.552761 -0.692897 -vn -0.513772 -0.380537 -0.768914 -vn -0.353893 -0.380537 -0.854372 -vn -0.353893 -0.380537 -0.854372 -vn -0.318905 -0.552761 -0.769906 -vn -0.462979 -0.552761 -0.692897 -vn -0.589260 -0.552761 -0.589260 -vn -0.653908 -0.380537 -0.653908 -vn -0.513772 -0.380537 -0.768914 -vn -0.513772 -0.380537 -0.768914 -vn -0.462979 -0.552761 -0.692897 -vn -0.589260 -0.552761 -0.589260 -vn -0.692897 -0.552761 -0.462979 -vn -0.768914 -0.380537 -0.513772 -vn -0.653908 -0.380537 -0.653908 -vn -0.653908 -0.380537 -0.653908 -vn -0.589260 -0.552761 -0.589260 -vn -0.692897 -0.552761 -0.462979 -vn -0.769906 -0.552761 -0.318905 -vn -0.854372 -0.380537 -0.353892 -vn -0.768914 -0.380537 -0.513772 -vn -0.768914 -0.380537 -0.513772 -vn -0.692897 -0.552761 -0.462979 -vn -0.769906 -0.552761 -0.318905 -vn -0.817327 -0.552761 -0.162576 -vn -0.906996 -0.380537 -0.180413 -vn -0.854372 -0.380537 -0.353892 -vn -0.854372 -0.380537 -0.353892 -vn -0.769906 -0.552761 -0.318905 -vn -0.817327 -0.552761 -0.162576 -vn -0.833340 -0.552761 0.000000 -vn -0.924766 -0.380537 0.000000 -vn -0.906996 -0.380537 -0.180413 -vn -0.906996 -0.380537 -0.180413 -vn -0.817327 -0.552761 -0.162576 -vn -0.833340 -0.552761 0.000000 -vn -0.817327 -0.552761 0.162577 -vn -0.906996 -0.380537 0.180413 -vn -0.924766 -0.380537 0.000000 -vn -0.924766 -0.380537 0.000000 -vn -0.833340 -0.552761 0.000000 -vn -0.817327 -0.552761 0.162577 -vn -0.769905 -0.552761 0.318906 -vn -0.854372 -0.380537 0.353893 -vn -0.906996 -0.380537 0.180413 -vn -0.906996 -0.380537 0.180413 -vn -0.817327 -0.552761 0.162577 -vn -0.769905 -0.552761 0.318906 -vn -0.692896 -0.552761 0.462979 -vn -0.768914 -0.380537 0.513773 -vn -0.854372 -0.380537 0.353893 -vn -0.854372 -0.380537 0.353893 -vn -0.769905 -0.552761 0.318906 -vn -0.692896 -0.552761 0.462979 -vn -0.589260 -0.552761 0.589260 -vn -0.653908 -0.380537 0.653908 -vn -0.768914 -0.380537 0.513773 -vn -0.768914 -0.380537 0.513773 -vn -0.692896 -0.552761 0.462979 -vn -0.589260 -0.552761 0.589260 -vn -0.462978 -0.552761 0.692897 -vn -0.513772 -0.380537 0.768915 -vn -0.653908 -0.380537 0.653908 -vn -0.653908 -0.380537 0.653908 -vn -0.589260 -0.552761 0.589260 -vn -0.462978 -0.552761 0.692897 -vn -0.318905 -0.552761 0.769906 -vn -0.353892 -0.380537 0.854372 -vn -0.513772 -0.380537 0.768915 -vn -0.513772 -0.380537 0.768915 -vn -0.462978 -0.552761 0.692897 -vn -0.318905 -0.552761 0.769906 -vn -0.162576 -0.552761 0.817327 -vn -0.180412 -0.380537 0.906997 -vn -0.353892 -0.380537 0.854372 -vn -0.353892 -0.380537 0.854372 -vn -0.318905 -0.552761 0.769906 -vn -0.162576 -0.552761 0.817327 -vn 0.000001 -0.552761 0.833340 -vn 0.000001 -0.380537 0.924766 -vn -0.180412 -0.380537 0.906997 -vn -0.180412 -0.380537 0.906997 -vn -0.162576 -0.552761 0.817327 -vn 0.000001 -0.552761 0.833340 -vn 0.162577 -0.552761 0.817327 -vn 0.180414 -0.380537 0.906996 -vn 0.000001 -0.380537 0.924766 -vn 0.000001 -0.380537 0.924766 -vn 0.000001 -0.552761 0.833340 -vn 0.162577 -0.552761 0.817327 -vn 0.318906 -0.552761 0.769905 -vn 0.353893 -0.380537 0.854372 -vn 0.180414 -0.380537 0.906996 -vn 0.180414 -0.380537 0.906996 -vn 0.162577 -0.552761 0.817327 -vn 0.318906 -0.552761 0.769905 -vn 0.462979 -0.552761 0.692896 -vn 0.513773 -0.380537 0.768914 -vn 0.353893 -0.380537 0.854372 -vn 0.353893 -0.380537 0.854372 -vn 0.318906 -0.552761 0.769905 -vn 0.462979 -0.552761 0.692896 -vn 0.589261 -0.552761 0.589259 -vn 0.653909 -0.380537 0.653907 -vn 0.513773 -0.380537 0.768914 -vn 0.513773 -0.380537 0.768914 -vn 0.462979 -0.552761 0.692896 -vn 0.589261 -0.552761 0.589259 -vn 0.692897 -0.552761 0.462978 -vn 0.768915 -0.380537 0.513771 -vn 0.653909 -0.380537 0.653907 -vn 0.653909 -0.380537 0.653907 -vn 0.589261 -0.552761 0.589259 -vn 0.692897 -0.552761 0.462978 -vn 0.769906 -0.552761 0.318904 -vn 0.854373 -0.380537 0.353891 -vn 0.768915 -0.380537 0.513771 -vn 0.768915 -0.380537 0.513771 -vn 0.692897 -0.552761 0.462978 -vn 0.769906 -0.552761 0.318904 -vn 0.817327 -0.552761 0.162576 -vn 0.906997 -0.380537 0.180411 -vn 0.854373 -0.380537 0.353891 -vn 0.854373 -0.380537 0.353891 -vn 0.769906 -0.552761 0.318904 -vn 0.817327 -0.552761 0.162576 -vn 0.833340 -0.552761 -0.000001 -vn 0.924766 -0.380537 -0.000002 -vn 0.906997 -0.380537 0.180411 -vn 0.906997 -0.380537 0.180411 -vn 0.817327 -0.552761 0.162576 -vn 0.833340 -0.552761 -0.000001 -vn 0.817327 -0.552761 -0.162578 -vn 0.906996 -0.380537 -0.180414 -vn 0.924766 -0.380537 -0.000002 -vn 0.924766 -0.380537 -0.000002 -vn 0.833340 -0.552761 -0.000001 -vn 0.817327 -0.552761 -0.162578 -vn 0.769905 -0.552761 -0.318907 -vn 0.854371 -0.380537 -0.353894 -vn 0.906996 -0.380537 -0.180414 -vn 0.906996 -0.380537 -0.180414 -vn 0.817327 -0.552761 -0.162578 -vn 0.769905 -0.552761 -0.318907 -vn 0.692896 -0.552761 -0.462980 -vn 0.768914 -0.380537 -0.513774 -vn 0.854371 -0.380537 -0.353894 -vn 0.854371 -0.380537 -0.353894 -vn 0.769905 -0.552761 -0.318907 -vn 0.692896 -0.552761 -0.462980 -vn 0.589259 -0.552761 -0.589261 -vn 0.653907 -0.380537 -0.653909 -vn 0.768914 -0.380537 -0.513774 -vn 0.768914 -0.380537 -0.513774 -vn 0.692896 -0.552761 -0.462980 -vn 0.589259 -0.552761 -0.589261 -vn 0.462977 -0.552761 -0.692898 -vn 0.513770 -0.380537 -0.768916 -vn 0.653907 -0.380537 -0.653909 -vn 0.653907 -0.380537 -0.653909 -vn 0.589259 -0.552761 -0.589261 -vn 0.462977 -0.552761 -0.692898 -vn 0.318904 -0.552761 -0.769906 -vn 0.353891 -0.380537 -0.854373 -vn 0.513770 -0.380537 -0.768916 -vn 0.513770 -0.380537 -0.768916 -vn 0.462977 -0.552761 -0.692898 -vn 0.318904 -0.552761 -0.769906 -vn 0.162575 -0.552761 -0.817328 -vn 0.180412 -0.380537 -0.906997 -vn 0.353891 -0.380537 -0.854373 -vn 0.353891 -0.380537 -0.854373 -vn 0.318904 -0.552761 -0.769906 -vn 0.162575 -0.552761 -0.817328 -vn -0.000001 -0.552761 -0.833340 -vn -0.000001 -0.380537 -0.924766 -vn 0.180412 -0.380537 -0.906997 -vn 0.180412 -0.380537 -0.906997 -vn 0.162575 -0.552761 -0.817328 -vn -0.000001 -0.552761 -0.833340 -vn -0.138542 -0.704059 -0.696496 -vn -0.162576 -0.552761 -0.817327 -vn -0.000001 -0.552761 -0.833340 -vn -0.000001 -0.552761 -0.833340 -vn -0.000000 -0.704059 -0.710141 -vn -0.138542 -0.704059 -0.696496 -vn -0.271759 -0.704059 -0.656085 -vn -0.318905 -0.552761 -0.769906 -vn -0.162576 -0.552761 -0.817327 -vn -0.162576 -0.552761 -0.817327 -vn -0.138542 -0.704059 -0.696496 -vn -0.271759 -0.704059 -0.656085 -vn -0.394533 -0.704059 -0.590461 -vn -0.462979 -0.552761 -0.692897 -vn -0.318905 -0.552761 -0.769906 -vn -0.318905 -0.552761 -0.769906 -vn -0.271759 -0.704059 -0.656085 -vn -0.394533 -0.704059 -0.590461 -vn -0.502146 -0.704059 -0.502146 -vn -0.589260 -0.552761 -0.589260 -vn -0.462979 -0.552761 -0.692897 -vn -0.462979 -0.552761 -0.692897 -vn -0.394533 -0.704059 -0.590461 -vn -0.502146 -0.704059 -0.502146 -vn -0.590461 -0.704059 -0.394533 -vn -0.692897 -0.552761 -0.462979 -vn -0.589260 -0.552761 -0.589260 -vn -0.589260 -0.552761 -0.589260 -vn -0.502146 -0.704059 -0.502146 -vn -0.590461 -0.704059 -0.394533 -vn -0.656085 -0.704059 -0.271759 -vn -0.769906 -0.552761 -0.318905 -vn -0.692897 -0.552761 -0.462979 -vn -0.692897 -0.552761 -0.462979 -vn -0.590461 -0.704059 -0.394533 -vn -0.656085 -0.704059 -0.271759 -vn -0.696496 -0.704059 -0.138541 -vn -0.817327 -0.552761 -0.162576 -vn -0.769906 -0.552761 -0.318905 -vn -0.769906 -0.552761 -0.318905 -vn -0.656085 -0.704059 -0.271759 -vn -0.696496 -0.704059 -0.138541 -vn -0.710141 -0.704059 0.000000 -vn -0.833340 -0.552761 0.000000 -vn -0.817327 -0.552761 -0.162576 -vn -0.817327 -0.552761 -0.162576 -vn -0.696496 -0.704059 -0.138541 -vn -0.710141 -0.704059 0.000000 -vn -0.696496 -0.704059 0.138542 -vn -0.817327 -0.552761 0.162577 -vn -0.833340 -0.552761 0.000000 -vn -0.833340 -0.552761 0.000000 -vn -0.710141 -0.704059 0.000000 -vn -0.696496 -0.704059 0.138542 -vn -0.656085 -0.704059 0.271760 -vn -0.769905 -0.552761 0.318906 -vn -0.817327 -0.552761 0.162577 -vn -0.817327 -0.552761 0.162577 -vn -0.696496 -0.704059 0.138542 -vn -0.656085 -0.704059 0.271760 -vn -0.590461 -0.704059 0.394534 -vn -0.692896 -0.552761 0.462979 -vn -0.769905 -0.552761 0.318906 -vn -0.769905 -0.552761 0.318906 -vn -0.656085 -0.704059 0.271760 -vn -0.590461 -0.704059 0.394534 -vn -0.502146 -0.704059 0.502146 -vn -0.589260 -0.552761 0.589260 -vn -0.692896 -0.552761 0.462979 -vn -0.692896 -0.552761 0.462979 -vn -0.590461 -0.704059 0.394534 -vn -0.502146 -0.704059 0.502146 -vn -0.394533 -0.704059 0.590461 -vn -0.462978 -0.552761 0.692897 -vn -0.589260 -0.552761 0.589260 -vn -0.589260 -0.552761 0.589260 -vn -0.502146 -0.704059 0.502146 -vn -0.394533 -0.704059 0.590461 -vn -0.271759 -0.704059 0.656085 -vn -0.318905 -0.552761 0.769906 -vn -0.462978 -0.552761 0.692897 -vn -0.462978 -0.552761 0.692897 -vn -0.394533 -0.704059 0.590461 -vn -0.271759 -0.704059 0.656085 -vn -0.138541 -0.704059 0.696496 -vn -0.162576 -0.552761 0.817327 -vn -0.318905 -0.552761 0.769906 -vn -0.318905 -0.552761 0.769906 -vn -0.271759 -0.704059 0.656085 -vn -0.138541 -0.704059 0.696496 -vn 0.000001 -0.704059 0.710142 -vn 0.000001 -0.552761 0.833340 -vn -0.162576 -0.552761 0.817327 -vn -0.162576 -0.552761 0.817327 -vn -0.138541 -0.704059 0.696496 -vn 0.000001 -0.704059 0.710142 -vn 0.138542 -0.704059 0.696496 -vn 0.162577 -0.552761 0.817327 -vn 0.000001 -0.552761 0.833340 -vn 0.000001 -0.552761 0.833340 -vn 0.000001 -0.704059 0.710142 -vn 0.138542 -0.704059 0.696496 -vn 0.271760 -0.704059 0.656085 -vn 0.318906 -0.552761 0.769905 -vn 0.162577 -0.552761 0.817327 -vn 0.162577 -0.552761 0.817327 -vn 0.138542 -0.704059 0.696496 -vn 0.271760 -0.704059 0.656085 -vn 0.394534 -0.704059 0.590461 -vn 0.462979 -0.552761 0.692896 -vn 0.318906 -0.552761 0.769905 -vn 0.318906 -0.552761 0.769905 -vn 0.271760 -0.704059 0.656085 -vn 0.394534 -0.704059 0.590461 -vn 0.502146 -0.704059 0.502145 -vn 0.589261 -0.552761 0.589259 -vn 0.462979 -0.552761 0.692896 -vn 0.462979 -0.552761 0.692896 -vn 0.394534 -0.704059 0.590461 -vn 0.502146 -0.704059 0.502145 -vn 0.590462 -0.704059 0.394533 -vn 0.692897 -0.552761 0.462978 -vn 0.589261 -0.552761 0.589259 -vn 0.589261 -0.552761 0.589259 -vn 0.502146 -0.704059 0.502145 -vn 0.590462 -0.704059 0.394533 -vn 0.656086 -0.704059 0.271758 -vn 0.769906 -0.552761 0.318904 -vn 0.692897 -0.552761 0.462978 -vn 0.692897 -0.552761 0.462978 -vn 0.590462 -0.704059 0.394533 -vn 0.656086 -0.704059 0.271758 -vn 0.696496 -0.704059 0.138541 -vn 0.817327 -0.552761 0.162576 -vn 0.769906 -0.552761 0.318904 -vn 0.769906 -0.552761 0.318904 -vn 0.656086 -0.704059 0.271758 -vn 0.696496 -0.704059 0.138541 -vn 0.710141 -0.704059 -0.000001 -vn 0.833340 -0.552761 -0.000001 -vn 0.817327 -0.552761 0.162576 -vn 0.817327 -0.552761 0.162576 -vn 0.696496 -0.704059 0.138541 -vn 0.710141 -0.704059 -0.000001 -vn 0.696496 -0.704059 -0.138543 -vn 0.817327 -0.552761 -0.162578 -vn 0.833340 -0.552761 -0.000001 -vn 0.833340 -0.552761 -0.000001 -vn 0.710141 -0.704059 -0.000001 -vn 0.696496 -0.704059 -0.138543 -vn 0.656085 -0.704059 -0.271761 -vn 0.769905 -0.552761 -0.318907 -vn 0.817327 -0.552761 -0.162578 -vn 0.817327 -0.552761 -0.162578 -vn 0.696496 -0.704059 -0.138543 -vn 0.656085 -0.704059 -0.271761 -vn 0.590460 -0.704059 -0.394535 -vn 0.692896 -0.552761 -0.462980 -vn 0.769905 -0.552761 -0.318907 -vn 0.769905 -0.552761 -0.318907 -vn 0.656085 -0.704059 -0.271761 -vn 0.590460 -0.704059 -0.394535 -vn 0.502145 -0.704059 -0.502147 -vn 0.589259 -0.552761 -0.589261 -vn 0.692896 -0.552761 -0.462980 -vn 0.692896 -0.552761 -0.462980 -vn 0.590460 -0.704059 -0.394535 -vn 0.502145 -0.704059 -0.502147 -vn 0.394532 -0.704059 -0.590462 -vn 0.462977 -0.552761 -0.692898 -vn 0.589259 -0.552761 -0.589261 -vn 0.589259 -0.552761 -0.589261 -vn 0.502145 -0.704059 -0.502147 -vn 0.394532 -0.704059 -0.590462 -vn 0.271758 -0.704059 -0.656086 -vn 0.318904 -0.552761 -0.769906 -vn 0.462977 -0.552761 -0.692898 -vn 0.462977 -0.552761 -0.692898 -vn 0.394532 -0.704059 -0.590462 -vn 0.271758 -0.704059 -0.656086 -vn 0.138541 -0.704059 -0.696497 -vn 0.162575 -0.552761 -0.817328 -vn 0.318904 -0.552761 -0.769906 -vn 0.318904 -0.552761 -0.769906 -vn 0.271758 -0.704059 -0.656086 -vn 0.138541 -0.704059 -0.696497 -vn -0.000000 -0.704059 -0.710141 -vn -0.000001 -0.552761 -0.833340 -vn 0.162575 -0.552761 -0.817328 -vn 0.162575 -0.552761 -0.817328 -vn 0.138541 -0.704059 -0.696497 -vn -0.000000 -0.704059 -0.710141 -vn -0.109207 -0.828645 -0.549019 -vn -0.138542 -0.704059 -0.696496 -vn -0.000000 -0.704059 -0.710141 -vn -0.000000 -0.704059 -0.710141 -vn -0.000000 -0.828645 -0.559775 -vn -0.109207 -0.828645 -0.549019 -vn -0.214217 -0.828645 -0.517165 -vn -0.271759 -0.704059 -0.656085 -vn -0.138542 -0.704059 -0.696496 -vn -0.138542 -0.704059 -0.696496 -vn -0.109207 -0.828645 -0.549019 -vn -0.214217 -0.828645 -0.517165 -vn -0.310994 -0.828645 -0.465436 -vn -0.394533 -0.704059 -0.590461 -vn -0.271759 -0.704059 -0.656085 -vn -0.271759 -0.704059 -0.656085 -vn -0.214217 -0.828645 -0.517165 -vn -0.310994 -0.828645 -0.465436 -vn -0.395821 -0.828645 -0.395821 -vn -0.502146 -0.704059 -0.502146 -vn -0.394533 -0.704059 -0.590461 -vn -0.394533 -0.704059 -0.590461 -vn -0.310994 -0.828645 -0.465436 -vn -0.395821 -0.828645 -0.395821 -vn -0.465436 -0.828645 -0.310994 -vn -0.590461 -0.704059 -0.394533 -vn -0.502146 -0.704059 -0.502146 -vn -0.502146 -0.704059 -0.502146 -vn -0.395821 -0.828645 -0.395821 -vn -0.465436 -0.828645 -0.310994 -vn -0.517165 -0.828645 -0.214216 -vn -0.656085 -0.704059 -0.271759 -vn -0.590461 -0.704059 -0.394533 -vn -0.590461 -0.704059 -0.394533 -vn -0.465436 -0.828645 -0.310994 -vn -0.517165 -0.828645 -0.214216 -vn -0.549019 -0.828645 -0.109206 -vn -0.696496 -0.704059 -0.138541 -vn -0.656085 -0.704059 -0.271759 -vn -0.656085 -0.704059 -0.271759 -vn -0.517165 -0.828645 -0.214216 -vn -0.549019 -0.828645 -0.109206 -vn -0.559775 -0.828645 0.000000 -vn -0.710141 -0.704059 0.000000 -vn -0.696496 -0.704059 -0.138541 -vn -0.696496 -0.704059 -0.138541 -vn -0.549019 -0.828645 -0.109206 -vn -0.559775 -0.828645 0.000000 -vn -0.549019 -0.828645 0.109207 -vn -0.696496 -0.704059 0.138542 -vn -0.710141 -0.704059 0.000000 -vn -0.710141 -0.704059 0.000000 -vn -0.559775 -0.828645 0.000000 -vn -0.549019 -0.828645 0.109207 -vn -0.517165 -0.828645 0.214217 -vn -0.656085 -0.704059 0.271760 -vn -0.696496 -0.704059 0.138542 -vn -0.696496 -0.704059 0.138542 -vn -0.549019 -0.828645 0.109207 -vn -0.517165 -0.828645 0.214217 -vn -0.465436 -0.828645 0.310995 -vn -0.590461 -0.704059 0.394534 -vn -0.656085 -0.704059 0.271760 -vn -0.656085 -0.704059 0.271760 -vn -0.517165 -0.828645 0.214217 -vn -0.465436 -0.828645 0.310995 -vn -0.395820 -0.828645 0.395821 -vn -0.502146 -0.704059 0.502146 -vn -0.590461 -0.704059 0.394534 -vn -0.590461 -0.704059 0.394534 -vn -0.465436 -0.828645 0.310995 -vn -0.395820 -0.828645 0.395821 -vn -0.310994 -0.828645 0.465436 -vn -0.394533 -0.704059 0.590461 -vn -0.502146 -0.704059 0.502146 -vn -0.502146 -0.704059 0.502146 -vn -0.395820 -0.828645 0.395821 -vn -0.310994 -0.828645 0.465436 -vn -0.214216 -0.828645 0.517165 -vn -0.271759 -0.704059 0.656085 -vn -0.394533 -0.704059 0.590461 -vn -0.394533 -0.704059 0.590461 -vn -0.310994 -0.828645 0.465436 -vn -0.214216 -0.828645 0.517165 -vn -0.109206 -0.828645 0.549019 -vn -0.138541 -0.704059 0.696496 -vn -0.271759 -0.704059 0.656085 -vn -0.271759 -0.704059 0.656085 -vn -0.214216 -0.828645 0.517165 -vn -0.109206 -0.828645 0.549019 -vn 0.000001 -0.828645 0.559775 -vn 0.000001 -0.704059 0.710142 -vn -0.138541 -0.704059 0.696496 -vn -0.138541 -0.704059 0.696496 -vn -0.109206 -0.828645 0.549019 -vn 0.000001 -0.828645 0.559775 -vn 0.109207 -0.828645 0.549019 -vn 0.138542 -0.704059 0.696496 -vn 0.000001 -0.704059 0.710142 -vn 0.000001 -0.704059 0.710142 -vn 0.000001 -0.828645 0.559775 -vn 0.109207 -0.828645 0.549019 -vn 0.214217 -0.828645 0.517164 -vn 0.271760 -0.704059 0.656085 -vn 0.138542 -0.704059 0.696496 -vn 0.138542 -0.704059 0.696496 -vn 0.109207 -0.828645 0.549019 -vn 0.214217 -0.828645 0.517164 -vn 0.310995 -0.828645 0.465436 -vn 0.394534 -0.704059 0.590461 -vn 0.271760 -0.704059 0.656085 -vn 0.271760 -0.704059 0.656085 -vn 0.214217 -0.828645 0.517164 -vn 0.310995 -0.828645 0.465436 -vn 0.395821 -0.828645 0.395820 -vn 0.502146 -0.704059 0.502145 -vn 0.394534 -0.704059 0.590461 -vn 0.394534 -0.704059 0.590461 -vn 0.310995 -0.828645 0.465436 -vn 0.395821 -0.828645 0.395820 -vn 0.465436 -0.828645 0.310994 -vn 0.590462 -0.704059 0.394533 -vn 0.502146 -0.704059 0.502145 -vn 0.502146 -0.704059 0.502145 -vn 0.395821 -0.828645 0.395820 -vn 0.465436 -0.828645 0.310994 -vn 0.517165 -0.828645 0.214216 -vn 0.656086 -0.704059 0.271758 -vn 0.590462 -0.704059 0.394533 -vn 0.590462 -0.704059 0.394533 -vn 0.465436 -0.828645 0.310994 -vn 0.517165 -0.828645 0.214216 -vn 0.549019 -0.828645 0.109206 -vn 0.696496 -0.704059 0.138541 -vn 0.656086 -0.704059 0.271758 -vn 0.656086 -0.704059 0.271758 -vn 0.517165 -0.828645 0.214216 -vn 0.549019 -0.828645 0.109206 -vn 0.559775 -0.828645 -0.000001 -vn 0.710141 -0.704059 -0.000001 -vn 0.696496 -0.704059 0.138541 -vn 0.696496 -0.704059 0.138541 -vn 0.549019 -0.828645 0.109206 -vn 0.559775 -0.828645 -0.000001 -vn 0.549019 -0.828645 -0.109208 -vn 0.696496 -0.704059 -0.138543 -vn 0.710141 -0.704059 -0.000001 -vn 0.710141 -0.704059 -0.000001 -vn 0.559775 -0.828645 -0.000001 -vn 0.549019 -0.828645 -0.109208 -vn 0.517164 -0.828645 -0.214218 -vn 0.656085 -0.704059 -0.271761 -vn 0.696496 -0.704059 -0.138543 -vn 0.696496 -0.704059 -0.138543 -vn 0.549019 -0.828645 -0.109208 -vn 0.517164 -0.828645 -0.214218 -vn 0.465435 -0.828645 -0.310995 -vn 0.590460 -0.704059 -0.394535 -vn 0.656085 -0.704059 -0.271761 -vn 0.656085 -0.704059 -0.271761 -vn 0.517164 -0.828645 -0.214218 -vn 0.465435 -0.828645 -0.310995 -vn 0.395820 -0.828645 -0.395821 -vn 0.502145 -0.704059 -0.502147 -vn 0.590460 -0.704059 -0.394535 -vn 0.590460 -0.704059 -0.394535 -vn 0.465435 -0.828645 -0.310995 -vn 0.395820 -0.828645 -0.395821 -vn 0.310994 -0.828645 -0.465436 -vn 0.394532 -0.704059 -0.590462 -vn 0.502145 -0.704059 -0.502147 -vn 0.502145 -0.704059 -0.502147 -vn 0.395820 -0.828645 -0.395821 -vn 0.310994 -0.828645 -0.465436 -vn 0.214215 -0.828645 -0.517165 -vn 0.271758 -0.704059 -0.656086 -vn 0.394532 -0.704059 -0.590462 -vn 0.394532 -0.704059 -0.590462 -vn 0.310994 -0.828645 -0.465436 -vn 0.214215 -0.828645 -0.517165 -vn 0.109206 -0.828645 -0.549019 -vn 0.138541 -0.704059 -0.696497 -vn 0.271758 -0.704059 -0.656086 -vn 0.271758 -0.704059 -0.656086 -vn 0.214215 -0.828645 -0.517165 -vn 0.109206 -0.828645 -0.549019 -vn -0.000000 -0.828645 -0.559775 -vn -0.000000 -0.704059 -0.710141 -vn 0.138541 -0.704059 -0.696497 -vn 0.138541 -0.704059 -0.696497 -vn 0.109206 -0.828645 -0.549019 -vn -0.000000 -0.828645 -0.559775 -vn -0.075673 -0.921707 -0.380434 -vn -0.109207 -0.828645 -0.549019 -vn -0.000000 -0.828645 -0.559775 -vn -0.000000 -0.828645 -0.559775 -vn -0.000000 -0.921707 -0.387887 -vn -0.075673 -0.921707 -0.380434 -vn -0.148438 -0.921707 -0.358361 -vn -0.214217 -0.828645 -0.517165 -vn -0.109207 -0.828645 -0.549019 -vn -0.109207 -0.828645 -0.549019 -vn -0.075673 -0.921707 -0.380434 -vn -0.148438 -0.921707 -0.358361 -vn -0.215498 -0.921707 -0.322516 -vn -0.310994 -0.828645 -0.465436 -vn -0.214217 -0.828645 -0.517165 -vn -0.214217 -0.828645 -0.517165 -vn -0.148438 -0.921707 -0.358361 -vn -0.215498 -0.921707 -0.322516 -vn -0.274278 -0.921707 -0.274277 -vn -0.395821 -0.828645 -0.395821 -vn -0.310994 -0.828645 -0.465436 -vn -0.310994 -0.828645 -0.465436 -vn -0.215498 -0.921707 -0.322516 -vn -0.274278 -0.921707 -0.274277 -vn -0.322516 -0.921707 -0.215498 -vn -0.465436 -0.828645 -0.310994 -vn -0.395821 -0.828645 -0.395821 -vn -0.395821 -0.828645 -0.395821 -vn -0.274278 -0.921707 -0.274277 -vn -0.322516 -0.921707 -0.215498 -vn -0.358361 -0.921707 -0.148438 -vn -0.517165 -0.828645 -0.214216 -vn -0.465436 -0.828645 -0.310994 -vn -0.465436 -0.828645 -0.310994 -vn -0.322516 -0.921707 -0.215498 -vn -0.358361 -0.921707 -0.148438 -vn -0.380434 -0.921707 -0.075673 -vn -0.549019 -0.828645 -0.109206 -vn -0.517165 -0.828645 -0.214216 -vn -0.517165 -0.828645 -0.214216 -vn -0.358361 -0.921707 -0.148438 -vn -0.380434 -0.921707 -0.075673 -vn -0.387887 -0.921707 0.000000 -vn -0.559775 -0.828645 0.000000 -vn -0.549019 -0.828645 -0.109206 -vn -0.549019 -0.828645 -0.109206 -vn -0.380434 -0.921707 -0.075673 -vn -0.387887 -0.921707 0.000000 -vn -0.380434 -0.921707 0.075673 -vn -0.549019 -0.828645 0.109207 -vn -0.559775 -0.828645 0.000000 -vn -0.559775 -0.828645 0.000000 -vn -0.387887 -0.921707 0.000000 -vn -0.380434 -0.921707 0.075673 -vn -0.358361 -0.921707 0.148438 -vn -0.517165 -0.828645 0.214217 -vn -0.549019 -0.828645 0.109207 -vn -0.549019 -0.828645 0.109207 -vn -0.380434 -0.921707 0.075673 -vn -0.358361 -0.921707 0.148438 -vn -0.322516 -0.921707 0.215499 -vn -0.465436 -0.828645 0.310995 -vn -0.517165 -0.828645 0.214217 -vn -0.517165 -0.828645 0.214217 -vn -0.358361 -0.921707 0.148438 -vn -0.322516 -0.921707 0.215499 -vn -0.274277 -0.921707 0.274278 -vn -0.395820 -0.828645 0.395821 -vn -0.465436 -0.828645 0.310995 -vn -0.465436 -0.828645 0.310995 -vn -0.322516 -0.921707 0.215499 -vn -0.274277 -0.921707 0.274278 -vn -0.215498 -0.921707 0.322516 -vn -0.310994 -0.828645 0.465436 -vn -0.395820 -0.828645 0.395821 -vn -0.395820 -0.828645 0.395821 -vn -0.274277 -0.921707 0.274278 -vn -0.215498 -0.921707 0.322516 -vn -0.148438 -0.921707 0.358361 -vn -0.214216 -0.828645 0.517165 -vn -0.310994 -0.828645 0.465436 -vn -0.310994 -0.828645 0.465436 -vn -0.215498 -0.921707 0.322516 -vn -0.148438 -0.921707 0.358361 -vn -0.075673 -0.921707 0.380434 -vn -0.109206 -0.828645 0.549019 -vn -0.214216 -0.828645 0.517165 -vn -0.214216 -0.828645 0.517165 -vn -0.148438 -0.921707 0.358361 -vn -0.075673 -0.921707 0.380434 -vn 0.000000 -0.921707 0.387887 -vn 0.000001 -0.828645 0.559775 -vn -0.109206 -0.828645 0.549019 -vn -0.109206 -0.828645 0.549019 -vn -0.075673 -0.921707 0.380434 -vn 0.000000 -0.921707 0.387887 -vn 0.075673 -0.921707 0.380434 -vn 0.109207 -0.828645 0.549019 -vn 0.000001 -0.828645 0.559775 -vn 0.000001 -0.828645 0.559775 -vn 0.000000 -0.921707 0.387887 -vn 0.075673 -0.921707 0.380434 -vn 0.148438 -0.921707 0.358361 -vn 0.214217 -0.828645 0.517164 -vn 0.109207 -0.828645 0.549019 -vn 0.109207 -0.828645 0.549019 -vn 0.075673 -0.921707 0.380434 -vn 0.148438 -0.921707 0.358361 -vn 0.215499 -0.921707 0.322516 -vn 0.310995 -0.828645 0.465436 -vn 0.214217 -0.828645 0.517164 -vn 0.214217 -0.828645 0.517164 -vn 0.148438 -0.921707 0.358361 -vn 0.215499 -0.921707 0.322516 -vn 0.274278 -0.921707 0.274277 -vn 0.395821 -0.828645 0.395820 -vn 0.310995 -0.828645 0.465436 -vn 0.310995 -0.828645 0.465436 -vn 0.215499 -0.921707 0.322516 -vn 0.274278 -0.921707 0.274277 -vn 0.322516 -0.921707 0.215498 -vn 0.465436 -0.828645 0.310994 -vn 0.395821 -0.828645 0.395820 -vn 0.395821 -0.828645 0.395820 -vn 0.274278 -0.921707 0.274277 -vn 0.322516 -0.921707 0.215498 -vn 0.358361 -0.921707 0.148437 -vn 0.517165 -0.828645 0.214216 -vn 0.465436 -0.828645 0.310994 -vn 0.465436 -0.828645 0.310994 -vn 0.322516 -0.921707 0.215498 -vn 0.358361 -0.921707 0.148437 -vn 0.380434 -0.921707 0.075672 -vn 0.549019 -0.828645 0.109206 -vn 0.517165 -0.828645 0.214216 -vn 0.517165 -0.828645 0.214216 -vn 0.358361 -0.921707 0.148437 -vn 0.380434 -0.921707 0.075672 -vn 0.387887 -0.921707 -0.000001 -vn 0.559775 -0.828645 -0.000001 -vn 0.549019 -0.828645 0.109206 -vn 0.549019 -0.828645 0.109206 -vn 0.380434 -0.921707 0.075672 -vn 0.387887 -0.921707 -0.000001 -vn 0.380433 -0.921707 -0.075674 -vn 0.549019 -0.828645 -0.109208 -vn 0.559775 -0.828645 -0.000001 -vn 0.559775 -0.828645 -0.000001 -vn 0.387887 -0.921707 -0.000001 -vn 0.380433 -0.921707 -0.075674 -vn 0.358360 -0.921707 -0.148438 -vn 0.517164 -0.828645 -0.214218 -vn 0.549019 -0.828645 -0.109208 -vn 0.549019 -0.828645 -0.109208 -vn 0.380433 -0.921707 -0.075674 -vn 0.358360 -0.921707 -0.148438 -vn 0.322516 -0.921707 -0.215499 -vn 0.465435 -0.828645 -0.310995 -vn 0.517164 -0.828645 -0.214218 -vn 0.517164 -0.828645 -0.214218 -vn 0.358360 -0.921707 -0.148438 -vn 0.322516 -0.921707 -0.215499 -vn 0.274277 -0.921707 -0.274278 -vn 0.395820 -0.828645 -0.395821 -vn 0.465435 -0.828645 -0.310995 -vn 0.465435 -0.828645 -0.310995 -vn 0.322516 -0.921707 -0.215499 -vn 0.274277 -0.921707 -0.274278 -vn 0.215498 -0.921707 -0.322516 -vn 0.310994 -0.828645 -0.465436 -vn 0.395820 -0.828645 -0.395821 -vn 0.395820 -0.828645 -0.395821 -vn 0.274277 -0.921707 -0.274278 -vn 0.215498 -0.921707 -0.322516 -vn 0.148437 -0.921707 -0.358361 -vn 0.214215 -0.828645 -0.517165 -vn 0.310994 -0.828645 -0.465436 -vn 0.310994 -0.828645 -0.465436 -vn 0.215498 -0.921707 -0.322516 -vn 0.148437 -0.921707 -0.358361 -vn 0.075672 -0.921707 -0.380434 -vn 0.109206 -0.828645 -0.549019 -vn 0.214215 -0.828645 -0.517165 -vn 0.214215 -0.828645 -0.517165 -vn 0.148437 -0.921707 -0.358361 -vn 0.075672 -0.921707 -0.380434 -vn -0.000000 -0.921707 -0.387887 -vn -0.000000 -0.828645 -0.559775 -vn 0.109206 -0.828645 -0.549019 -vn 0.109206 -0.828645 -0.549019 -vn 0.075672 -0.921707 -0.380434 -vn -0.000000 -0.921707 -0.387887 -vn -0.039207 -0.979598 -0.197107 -vn -0.075673 -0.921707 -0.380434 -vn -0.000000 -0.921707 -0.387887 -vn -0.000000 -0.921707 -0.387887 -vn -0.000000 -0.979598 -0.200969 -vn -0.039207 -0.979598 -0.197107 -vn -0.076907 -0.979598 -0.185671 -vn -0.148438 -0.921707 -0.358361 -vn -0.075673 -0.921707 -0.380434 -vn -0.075673 -0.921707 -0.380434 -vn -0.039207 -0.979598 -0.197107 -vn -0.076907 -0.979598 -0.185671 -vn -0.111652 -0.979598 -0.167099 -vn -0.215498 -0.921707 -0.322516 -vn -0.148438 -0.921707 -0.358361 -vn -0.148438 -0.921707 -0.358361 -vn -0.076907 -0.979598 -0.185671 -vn -0.111652 -0.979598 -0.167099 -vn -0.142106 -0.979598 -0.142106 -vn -0.274278 -0.921707 -0.274277 -vn -0.215498 -0.921707 -0.322516 -vn -0.215498 -0.921707 -0.322516 -vn -0.111652 -0.979598 -0.167099 -vn -0.142106 -0.979598 -0.142106 -vn -0.167099 -0.979598 -0.111652 -vn -0.322516 -0.921707 -0.215498 -vn -0.274278 -0.921707 -0.274277 -vn -0.274278 -0.921707 -0.274277 -vn -0.142106 -0.979598 -0.142106 -vn -0.167099 -0.979598 -0.111652 -vn -0.185671 -0.979598 -0.076907 -vn -0.358361 -0.921707 -0.148438 -vn -0.322516 -0.921707 -0.215498 -vn -0.322516 -0.921707 -0.215498 -vn -0.167099 -0.979598 -0.111652 -vn -0.185671 -0.979598 -0.076907 -vn -0.197107 -0.979598 -0.039207 -vn -0.380434 -0.921707 -0.075673 -vn -0.358361 -0.921707 -0.148438 -vn -0.358361 -0.921707 -0.148438 -vn -0.185671 -0.979598 -0.076907 -vn -0.197107 -0.979598 -0.039207 -vn -0.200969 -0.979598 -0.000000 -vn -0.387887 -0.921707 0.000000 -vn -0.380434 -0.921707 -0.075673 -vn -0.380434 -0.921707 -0.075673 -vn -0.197107 -0.979598 -0.039207 -vn -0.200969 -0.979598 -0.000000 -vn -0.197107 -0.979598 0.039207 -vn -0.380434 -0.921707 0.075673 -vn -0.387887 -0.921707 0.000000 -vn -0.387887 -0.921707 0.000000 -vn -0.200969 -0.979598 -0.000000 -vn -0.197107 -0.979598 0.039207 -vn -0.185671 -0.979598 0.076907 -vn -0.358361 -0.921707 0.148438 -vn -0.380434 -0.921707 0.075673 -vn -0.380434 -0.921707 0.075673 -vn -0.197107 -0.979598 0.039207 -vn -0.185671 -0.979598 0.076907 -vn -0.167099 -0.979598 0.111652 -vn -0.322516 -0.921707 0.215499 -vn -0.358361 -0.921707 0.148438 -vn -0.358361 -0.921707 0.148438 -vn -0.185671 -0.979598 0.076907 -vn -0.167099 -0.979598 0.111652 -vn -0.142106 -0.979598 0.142106 -vn -0.274277 -0.921707 0.274278 -vn -0.322516 -0.921707 0.215499 -vn -0.322516 -0.921707 0.215499 -vn -0.167099 -0.979598 0.111652 -vn -0.142106 -0.979598 0.142106 -vn -0.111652 -0.979598 0.167100 -vn -0.215498 -0.921707 0.322516 -vn -0.274277 -0.921707 0.274278 -vn -0.274277 -0.921707 0.274278 -vn -0.142106 -0.979598 0.142106 -vn -0.111652 -0.979598 0.167100 -vn -0.076907 -0.979598 0.185671 -vn -0.148438 -0.921707 0.358361 -vn -0.215498 -0.921707 0.322516 -vn -0.215498 -0.921707 0.322516 -vn -0.111652 -0.979598 0.167100 -vn -0.076907 -0.979598 0.185671 -vn -0.039207 -0.979598 0.197107 -vn -0.075673 -0.921707 0.380434 -vn -0.148438 -0.921707 0.358361 -vn -0.148438 -0.921707 0.358361 -vn -0.076907 -0.979598 0.185671 -vn -0.039207 -0.979598 0.197107 -vn 0.000000 -0.979598 0.200969 -vn 0.000000 -0.921707 0.387887 -vn -0.075673 -0.921707 0.380434 -vn -0.075673 -0.921707 0.380434 -vn -0.039207 -0.979598 0.197107 -vn 0.000000 -0.979598 0.200969 -vn 0.039207 -0.979598 0.197107 -vn 0.075673 -0.921707 0.380434 -vn 0.000000 -0.921707 0.387887 -vn 0.000000 -0.921707 0.387887 -vn 0.000000 -0.979598 0.200969 -vn 0.039207 -0.979598 0.197107 -vn 0.076908 -0.979598 0.185671 -vn 0.148438 -0.921707 0.358361 -vn 0.075673 -0.921707 0.380434 -vn 0.075673 -0.921707 0.380434 -vn 0.039207 -0.979598 0.197107 -vn 0.076908 -0.979598 0.185671 -vn 0.111653 -0.979598 0.167099 -vn 0.215499 -0.921707 0.322516 -vn 0.148438 -0.921707 0.358361 -vn 0.148438 -0.921707 0.358361 -vn 0.076908 -0.979598 0.185671 -vn 0.111653 -0.979598 0.167099 -vn 0.142106 -0.979598 0.142106 -vn 0.274278 -0.921707 0.274277 -vn 0.215499 -0.921707 0.322516 -vn 0.215499 -0.921707 0.322516 -vn 0.111653 -0.979598 0.167099 -vn 0.142106 -0.979598 0.142106 -vn 0.167099 -0.979598 0.111652 -vn 0.322516 -0.921707 0.215498 -vn 0.274278 -0.921707 0.274277 -vn 0.274278 -0.921707 0.274277 -vn 0.142106 -0.979598 0.142106 -vn 0.167099 -0.979598 0.111652 -vn 0.185671 -0.979598 0.076907 -vn 0.358361 -0.921707 0.148437 -vn 0.322516 -0.921707 0.215498 -vn 0.322516 -0.921707 0.215498 -vn 0.167099 -0.979598 0.111652 -vn 0.185671 -0.979598 0.076907 -vn 0.197107 -0.979598 0.039207 -vn 0.380434 -0.921707 0.075672 -vn 0.358361 -0.921707 0.148437 -vn 0.358361 -0.921707 0.148437 -vn 0.185671 -0.979598 0.076907 -vn 0.197107 -0.979598 0.039207 -vn 0.200969 -0.979598 -0.000000 -vn 0.387887 -0.921707 -0.000001 -vn 0.380434 -0.921707 0.075672 -vn 0.380434 -0.921707 0.075672 -vn 0.197107 -0.979598 0.039207 -vn 0.200969 -0.979598 -0.000000 -vn 0.197107 -0.979598 -0.039207 -vn 0.380433 -0.921707 -0.075674 -vn 0.387887 -0.921707 -0.000001 -vn 0.387887 -0.921707 -0.000001 -vn 0.200969 -0.979598 -0.000000 -vn 0.197107 -0.979598 -0.039207 -vn 0.185671 -0.979598 -0.076908 -vn 0.358360 -0.921707 -0.148438 -vn 0.380433 -0.921707 -0.075674 -vn 0.380433 -0.921707 -0.075674 -vn 0.197107 -0.979598 -0.039207 -vn 0.185671 -0.979598 -0.076908 -vn 0.167099 -0.979598 -0.111652 -vn 0.322516 -0.921707 -0.215499 -vn 0.358360 -0.921707 -0.148438 -vn 0.358360 -0.921707 -0.148438 -vn 0.185671 -0.979598 -0.076908 -vn 0.167099 -0.979598 -0.111652 -vn 0.142106 -0.979598 -0.142106 -vn 0.274277 -0.921707 -0.274278 -vn 0.322516 -0.921707 -0.215499 -vn 0.322516 -0.921707 -0.215499 -vn 0.167099 -0.979598 -0.111652 -vn 0.142106 -0.979598 -0.142106 -vn 0.111652 -0.979598 -0.167100 -vn 0.215498 -0.921707 -0.322516 -vn 0.274277 -0.921707 -0.274278 -vn 0.274277 -0.921707 -0.274278 -vn 0.142106 -0.979598 -0.142106 -vn 0.111652 -0.979598 -0.167100 -vn 0.076907 -0.979598 -0.185671 -vn 0.148437 -0.921707 -0.358361 -vn 0.215498 -0.921707 -0.322516 -vn 0.215498 -0.921707 -0.322516 -vn 0.111652 -0.979598 -0.167100 -vn 0.076907 -0.979598 -0.185671 -vn 0.039207 -0.979598 -0.197107 -vn 0.075672 -0.921707 -0.380434 -vn 0.148437 -0.921707 -0.358361 -vn 0.148437 -0.921707 -0.358361 -vn 0.076907 -0.979598 -0.185671 -vn 0.039207 -0.979598 -0.197107 -vn -0.000000 -0.979598 -0.200969 -vn -0.000000 -0.921707 -0.387887 -vn 0.075672 -0.921707 -0.380434 -vn 0.075672 -0.921707 -0.380434 -vn 0.039207 -0.979598 -0.197107 -vn -0.000000 -0.979598 -0.200969 -vn -0.000000 -1.000000 -0.000000 -vn -0.039207 -0.979598 -0.197107 -vn -0.000000 -0.979598 -0.200969 -vn -0.000000 -1.000000 -0.000000 -vn -0.076907 -0.979598 -0.185671 -vn -0.039207 -0.979598 -0.197107 -vn -0.000000 -1.000000 -0.000000 -vn -0.111652 -0.979598 -0.167099 -vn -0.076907 -0.979598 -0.185671 -vn -0.000000 -1.000000 -0.000000 -vn -0.142106 -0.979598 -0.142106 -vn -0.111652 -0.979598 -0.167099 -vn -0.000000 -1.000000 -0.000000 -vn -0.167099 -0.979598 -0.111652 -vn -0.142106 -0.979598 -0.142106 -vn -0.000000 -1.000000 -0.000000 -vn -0.185671 -0.979598 -0.076907 -vn -0.167099 -0.979598 -0.111652 -vn -0.000000 -1.000000 -0.000000 -vn -0.197107 -0.979598 -0.039207 -vn -0.185671 -0.979598 -0.076907 -vn -0.000000 -1.000000 -0.000000 -vn -0.200969 -0.979598 -0.000000 -vn -0.197107 -0.979598 -0.039207 -vn -0.000000 -1.000000 -0.000000 -vn -0.197107 -0.979598 0.039207 -vn -0.200969 -0.979598 -0.000000 -vn -0.000000 -1.000000 -0.000000 -vn -0.185671 -0.979598 0.076907 -vn -0.197107 -0.979598 0.039207 -vn -0.000000 -1.000000 -0.000000 -vn -0.167099 -0.979598 0.111652 -vn -0.185671 -0.979598 0.076907 -vn -0.000000 -1.000000 -0.000000 -vn -0.142106 -0.979598 0.142106 -vn -0.167099 -0.979598 0.111652 -vn -0.000000 -1.000000 -0.000000 -vn -0.111652 -0.979598 0.167100 -vn -0.142106 -0.979598 0.142106 -vn -0.000000 -1.000000 -0.000000 -vn -0.076907 -0.979598 0.185671 -vn -0.111652 -0.979598 0.167100 -vn -0.000000 -1.000000 -0.000000 -vn -0.039207 -0.979598 0.197107 -vn -0.076907 -0.979598 0.185671 -vn -0.000000 -1.000000 -0.000000 -vn 0.000000 -0.979598 0.200969 -vn -0.039207 -0.979598 0.197107 -vn -0.000000 -1.000000 -0.000000 -vn 0.039207 -0.979598 0.197107 -vn 0.000000 -0.979598 0.200969 -vn -0.000000 -1.000000 -0.000000 -vn 0.076908 -0.979598 0.185671 -vn 0.039207 -0.979598 0.197107 -vn -0.000000 -1.000000 -0.000000 -vn 0.111653 -0.979598 0.167099 -vn 0.076908 -0.979598 0.185671 -vn -0.000000 -1.000000 -0.000000 -vn 0.142106 -0.979598 0.142106 -vn 0.111653 -0.979598 0.167099 -vn -0.000000 -1.000000 -0.000000 -vn 0.167099 -0.979598 0.111652 -vn 0.142106 -0.979598 0.142106 -vn -0.000000 -1.000000 -0.000000 -vn 0.185671 -0.979598 0.076907 -vn 0.167099 -0.979598 0.111652 -vn -0.000000 -1.000000 -0.000000 -vn 0.197107 -0.979598 0.039207 -vn 0.185671 -0.979598 0.076907 -vn -0.000000 -1.000000 -0.000000 -vn 0.200969 -0.979598 -0.000000 -vn 0.197107 -0.979598 0.039207 -vn -0.000000 -1.000000 -0.000000 -vn 0.197107 -0.979598 -0.039207 -vn 0.200969 -0.979598 -0.000000 -vn -0.000000 -1.000000 -0.000000 -vn 0.185671 -0.979598 -0.076908 -vn 0.197107 -0.979598 -0.039207 -vn -0.000000 -1.000000 -0.000000 -vn 0.167099 -0.979598 -0.111652 -vn 0.185671 -0.979598 -0.076908 -vn -0.000000 -1.000000 -0.000000 -vn 0.142106 -0.979598 -0.142106 -vn 0.167099 -0.979598 -0.111652 -vn -0.000000 -1.000000 -0.000000 -vn 0.111652 -0.979598 -0.167100 -vn 0.142106 -0.979598 -0.142106 -vn -0.000000 -1.000000 -0.000000 -vn 0.076907 -0.979598 -0.185671 -vn 0.111652 -0.979598 -0.167100 -vn -0.000000 -1.000000 -0.000000 -vn 0.039207 -0.979598 -0.197107 -vn 0.076907 -0.979598 -0.185671 -vn -0.000000 -1.000000 -0.000000 -vn -0.000000 -0.979598 -0.200969 -vn 0.039207 -0.979598 -0.197107 -vn 0.889663 0.456618 -0.000000 -vn 0.859348 0.456618 -0.230262 -vn 0.859348 0.456618 -0.230262 -vn 0.859348 0.456618 -0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 -0.000000 -vn 0.859348 0.456618 -0.230262 -vn 0.770470 0.456619 -0.444831 -vn 0.770470 0.456618 -0.444831 -vn 0.770470 0.456618 -0.444831 -vn 0.859348 0.456618 -0.230262 -vn 0.859348 0.456618 -0.230262 -vn 0.770470 0.456619 -0.444831 -vn 0.629086 0.456619 -0.629086 -vn 0.629087 0.456618 -0.629086 -vn 0.629087 0.456618 -0.629086 -vn 0.770470 0.456618 -0.444831 -vn 0.770470 0.456619 -0.444831 -vn 0.629086 0.456619 -0.629086 -vn 0.444831 0.456619 -0.770471 -vn 0.444831 0.456618 -0.770471 -vn 0.444831 0.456618 -0.770471 -vn 0.629087 0.456618 -0.629086 -vn 0.629086 0.456619 -0.629086 -vn 0.444831 0.456619 -0.770471 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.444831 0.456618 -0.770471 -vn 0.444831 0.456619 -0.770471 -vn 0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn -0.230261 0.456618 -0.859348 -vn -0.230262 0.456618 -0.859348 -vn -0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn -0.230261 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770470 -vn -0.444831 0.456618 -0.770471 -vn -0.444831 0.456618 -0.770471 -vn -0.230262 0.456618 -0.859348 -vn -0.230261 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770470 -vn -0.629086 0.456618 -0.629086 -vn -0.629086 0.456618 -0.629087 -vn -0.629086 0.456618 -0.629087 -vn -0.444831 0.456618 -0.770471 -vn -0.444831 0.456618 -0.770470 -vn -0.629086 0.456618 -0.629086 -vn -0.770470 0.456618 -0.444832 -vn -0.770470 0.456618 -0.444832 -vn -0.770470 0.456618 -0.444832 -vn -0.629086 0.456618 -0.629087 -vn -0.629086 0.456618 -0.629086 -vn -0.770470 0.456618 -0.444832 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.770470 0.456618 -0.444832 -vn -0.770470 0.456618 -0.444832 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.444832 0.456618 0.770470 -vn -0.444832 0.456618 0.770470 -vn -0.444832 0.456618 0.770470 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.444832 0.456618 0.770470 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.444832 0.456618 0.770470 -vn -0.444832 0.456618 0.770470 -vn -0.230262 0.456618 0.859348 -vn -0.000001 0.456619 0.889663 -vn -0.000000 0.456618 0.889663 -vn -0.000000 0.456618 0.889663 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.000001 0.456619 0.889663 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn -0.000000 0.456618 0.889663 -vn -0.000001 0.456619 0.889663 -vn 0.230261 0.456618 0.859348 -vn 0.444831 0.456619 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn 0.444831 0.456619 0.770471 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456619 0.770471 -vn 0.629086 0.456618 0.629087 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444832 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.770470 0.456618 0.444832 -vn 0.859348 0.456619 0.230262 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456618 0.230262 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444832 -vn 0.859348 0.456619 0.230262 -vn 0.889663 0.456618 -0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456619 0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 -0.230262 -vn 0.859348 0.456618 -0.230261 -vn 0.859348 0.456618 -0.230261 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 -0.230262 -vn 0.770470 0.456618 -0.444831 -vn 0.770470 0.456618 -0.444832 -vn 0.770470 0.456618 -0.444832 -vn 0.859348 0.456618 -0.230261 -vn 0.859348 0.456618 -0.230262 -vn 0.770470 0.456618 -0.444831 -vn 0.629087 0.456618 -0.629086 -vn 0.629086 0.456618 -0.629087 -vn 0.629086 0.456618 -0.629087 -vn 0.770470 0.456618 -0.444832 -vn 0.770470 0.456618 -0.444831 -vn 0.629087 0.456618 -0.629086 -vn 0.444831 0.456618 -0.770471 -vn 0.444831 0.456618 -0.770471 -vn 0.444831 0.456618 -0.770471 -vn 0.629086 0.456618 -0.629087 -vn 0.629087 0.456618 -0.629086 -vn 0.444831 0.456618 -0.770471 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.444831 0.456618 -0.770471 -vn 0.444831 0.456618 -0.770471 -vn 0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn -0.230262 0.456618 -0.859348 -vn -0.230261 0.456618 -0.859348 -vn -0.230261 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn -0.230262 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770471 -vn -0.444831 0.456618 -0.770471 -vn -0.444831 0.456618 -0.770471 -vn -0.230261 0.456618 -0.859348 -vn -0.230262 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770471 -vn -0.629086 0.456618 -0.629087 -vn -0.629086 0.456618 -0.629087 -vn -0.629086 0.456618 -0.629087 -vn -0.444831 0.456618 -0.770471 -vn -0.444831 0.456618 -0.770471 -vn -0.629086 0.456618 -0.629087 -vn -0.770470 0.456618 -0.444832 -vn -0.770470 0.456618 -0.444832 -vn -0.770470 0.456618 -0.444832 -vn -0.629086 0.456618 -0.629087 -vn -0.629086 0.456618 -0.629087 -vn -0.770470 0.456618 -0.444832 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.770470 0.456618 -0.444832 -vn -0.770470 0.456618 -0.444832 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.444832 0.456618 0.770470 -vn -0.444831 0.456618 0.770471 -vn -0.444831 0.456618 0.770471 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.444832 0.456618 0.770470 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.444831 0.456618 0.770471 -vn -0.444832 0.456618 0.770470 -vn -0.230262 0.456618 0.859348 -vn -0.000000 0.456618 0.889663 -vn -0.000001 0.456618 0.889663 -vn -0.000001 0.456618 0.889663 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.000000 0.456618 0.889663 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn -0.000001 0.456618 0.889663 -vn -0.000000 0.456618 0.889663 -vn 0.230261 0.456618 0.859348 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn 0.444831 0.456618 0.770471 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.629086 0.456618 0.629087 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444832 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.770470 0.456618 0.444832 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456618 0.230262 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444832 -vn 0.859348 0.456618 0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456618 0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 -0.230261 -vn 0.859348 0.456618 -0.230261 -vn 0.859348 0.456618 -0.230261 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 -0.230261 -vn 0.770470 0.456618 -0.444832 -vn 0.770470 0.456619 -0.444831 -vn 0.770470 0.456619 -0.444831 -vn 0.859348 0.456618 -0.230261 -vn 0.859348 0.456618 -0.230261 -vn 0.770470 0.456618 -0.444832 -vn 0.629086 0.456618 -0.629087 -vn 0.629086 0.456618 -0.629087 -vn 0.629086 0.456618 -0.629087 -vn 0.770470 0.456619 -0.444831 -vn 0.770470 0.456618 -0.444832 -vn 0.629086 0.456618 -0.629087 -vn 0.444831 0.456618 -0.770471 -vn 0.444831 0.456618 -0.770470 -vn 0.444831 0.456618 -0.770470 -vn 0.629086 0.456618 -0.629087 -vn 0.629086 0.456618 -0.629087 -vn 0.444831 0.456618 -0.770471 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.444831 0.456618 -0.770470 -vn 0.444831 0.456618 -0.770471 -vn 0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn 0.230262 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn -0.230261 0.456618 -0.859348 -vn -0.230261 0.456618 -0.859348 -vn -0.230261 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn -0.230261 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770471 -vn -0.444831 0.456618 -0.770470 -vn -0.444831 0.456618 -0.770470 -vn -0.230261 0.456618 -0.859348 -vn -0.230261 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770471 -vn -0.629086 0.456618 -0.629087 -vn -0.629086 0.456618 -0.629087 -vn -0.629086 0.456618 -0.629087 -vn -0.444831 0.456618 -0.770470 -vn -0.444831 0.456618 -0.770471 -vn -0.629086 0.456618 -0.629087 -vn -0.770470 0.456618 -0.444832 -vn -0.770470 0.456618 -0.444831 -vn -0.770470 0.456618 -0.444831 -vn -0.629086 0.456618 -0.629087 -vn -0.629086 0.456618 -0.629087 -vn -0.770470 0.456618 -0.444832 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.770470 0.456618 -0.444831 -vn -0.770470 0.456618 -0.444832 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.444831 0.456618 0.770471 -vn -0.444832 0.456618 0.770470 -vn -0.444832 0.456618 0.770470 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.444831 0.456618 0.770471 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.444832 0.456618 0.770470 -vn -0.444831 0.456618 0.770471 -vn -0.230262 0.456618 0.859348 -vn -0.000001 0.456618 0.889663 -vn -0.000001 0.456618 0.889663 -vn -0.000001 0.456618 0.889663 -vn -0.230262 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.000001 0.456618 0.889663 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn -0.000001 0.456618 0.889663 -vn -0.000001 0.456618 0.889663 -vn 0.230261 0.456618 0.859348 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456618 0.859348 -vn 0.444831 0.456618 0.770471 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.629086 0.456618 0.629087 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444831 -vn 0.770470 0.456618 0.444831 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629087 -vn 0.770470 0.456618 0.444832 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456618 0.230262 -vn 0.770470 0.456618 0.444831 -vn 0.770470 0.456618 0.444832 -vn 0.859348 0.456618 0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456618 0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 -0.230261 -vn 0.859348 0.456618 -0.230262 -vn 0.859348 0.456618 -0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 -0.230261 -vn 0.770470 0.456619 -0.444831 -vn 0.770470 0.456618 -0.444831 -vn 0.770470 0.456618 -0.444831 -vn 0.859348 0.456618 -0.230262 -vn 0.859348 0.456618 -0.230261 -vn 0.770470 0.456619 -0.444831 -vn 0.629086 0.456618 -0.629087 -vn 0.629086 0.456618 -0.629087 -vn 0.629086 0.456618 -0.629087 -vn 0.770470 0.456618 -0.444831 -vn 0.770470 0.456619 -0.444831 -vn 0.629086 0.456618 -0.629087 -vn 0.444831 0.456618 -0.770470 -vn 0.444831 0.456618 -0.770470 -vn 0.444831 0.456618 -0.770470 -vn 0.629086 0.456618 -0.629087 -vn 0.629086 0.456618 -0.629087 -vn 0.444831 0.456618 -0.770470 -vn 0.230262 0.456618 -0.859348 -vn 0.230263 0.456618 -0.859348 -vn 0.230263 0.456618 -0.859348 -vn 0.444831 0.456618 -0.770470 -vn 0.444831 0.456618 -0.770470 -vn 0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn 0.230263 0.456618 -0.859348 -vn 0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn -0.230261 0.456618 -0.859348 -vn -0.230262 0.456618 -0.859348 -vn -0.230262 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.000000 0.456618 -0.889663 -vn -0.230261 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770470 -vn -0.444831 0.456618 -0.770471 -vn -0.444831 0.456618 -0.770471 -vn -0.230262 0.456618 -0.859348 -vn -0.230261 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770470 -vn -0.629086 0.456618 -0.629087 -vn -0.629087 0.456619 -0.629086 -vn -0.629087 0.456619 -0.629086 -vn -0.444831 0.456618 -0.770471 -vn -0.444831 0.456618 -0.770470 -vn -0.629086 0.456618 -0.629087 -vn -0.770470 0.456618 -0.444831 -vn -0.770471 0.456618 -0.444831 -vn -0.770471 0.456618 -0.444831 -vn -0.629087 0.456619 -0.629086 -vn -0.629086 0.456618 -0.629087 -vn -0.770470 0.456618 -0.444831 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.770471 0.456618 -0.444831 -vn -0.770470 0.456618 -0.444831 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 -0.230262 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.889663 0.456618 -0.000000 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.859348 0.456618 0.230261 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.770471 0.456618 0.444831 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.444832 0.456618 0.770470 -vn -0.444832 0.456618 0.770470 -vn -0.444832 0.456618 0.770470 -vn -0.629087 0.456618 0.629086 -vn -0.629087 0.456618 0.629086 -vn -0.444832 0.456618 0.770470 -vn -0.230262 0.456618 0.859348 -vn -0.230261 0.456618 0.859348 -vn -0.230261 0.456618 0.859348 -vn -0.444832 0.456618 0.770470 -vn -0.444832 0.456618 0.770470 -vn -0.230262 0.456618 0.859348 -vn -0.000001 0.456618 0.889663 -vn -0.000001 0.456618 0.889663 -vn -0.000001 0.456618 0.889663 -vn -0.230261 0.456618 0.859348 -vn -0.230262 0.456618 0.859348 -vn -0.000001 0.456618 0.889663 -vn 0.230261 0.456618 0.859348 -vn 0.230261 0.456619 0.859348 -vn 0.230261 0.456619 0.859348 -vn -0.000001 0.456618 0.889663 -vn -0.000001 0.456618 0.889663 -vn 0.230261 0.456618 0.859348 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.230261 0.456619 0.859348 -vn 0.230261 0.456618 0.859348 -vn 0.444831 0.456618 0.770471 -vn 0.629086 0.456618 0.629087 -vn 0.629086 0.456618 0.629086 -vn 0.629086 0.456618 0.629086 -vn 0.444831 0.456618 0.770471 -vn 0.444831 0.456618 0.770471 -vn 0.629086 0.456618 0.629087 -vn 0.770470 0.456618 0.444831 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444832 -vn 0.629086 0.456618 0.629086 -vn 0.629086 0.456618 0.629087 -vn 0.770470 0.456618 0.444831 -vn 0.859348 0.456618 0.230262 -vn 0.859348 0.456618 0.230263 -vn 0.859348 0.456618 0.230263 -vn 0.770470 0.456618 0.444832 -vn 0.770470 0.456618 0.444831 -vn 0.859348 0.456618 0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 0.230263 -vn 0.859348 0.456618 0.230262 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 -0.230262 -vn 0.883622 0.453518 -0.116331 -vn 0.883622 0.453518 -0.116331 -vn 0.883622 0.453518 0.116332 -vn 0.889663 0.456618 0.000000 -vn 0.859348 0.456618 -0.230262 -vn 0.770470 0.456618 -0.444831 -vn 0.823405 0.453518 -0.341066 -vn 0.823405 0.453518 -0.341066 -vn 0.883622 0.453518 -0.116331 -vn 0.859348 0.456618 -0.230262 -vn 0.770470 0.456618 -0.444831 -vn 0.629086 0.456618 -0.629087 -vn 0.707074 0.453518 -0.542557 -vn 0.707074 0.453518 -0.542557 -vn 0.823405 0.453518 -0.341066 -vn 0.770470 0.456618 -0.444831 -vn 0.629086 0.456618 -0.629087 -vn 0.444831 0.456618 -0.770470 -vn 0.542556 0.453518 -0.707074 -vn 0.542556 0.453518 -0.707074 -vn 0.707074 0.453518 -0.542557 -vn 0.629086 0.456618 -0.629087 -vn 0.444831 0.456618 -0.770470 -vn 0.230263 0.456618 -0.859348 -vn 0.341066 0.453518 -0.823405 -vn 0.341066 0.453518 -0.823405 -vn 0.542556 0.453518 -0.707074 -vn 0.444831 0.456618 -0.770470 -vn 0.230263 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn 0.116332 0.453518 -0.883622 -vn 0.116332 0.453518 -0.883622 -vn 0.341066 0.453518 -0.823405 -vn 0.230263 0.456618 -0.859348 -vn 0.000000 0.456618 -0.889663 -vn -0.230262 0.456618 -0.859348 -vn -0.116332 0.453518 -0.883622 -vn -0.116332 0.453518 -0.883622 -vn 0.116332 0.453518 -0.883622 -vn 0.000000 0.456618 -0.889663 -vn -0.230262 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770471 -vn -0.341066 0.453518 -0.823405 -vn -0.341066 0.453518 -0.823405 -vn -0.116332 0.453518 -0.883622 -vn -0.230262 0.456618 -0.859348 -vn -0.444831 0.456618 -0.770471 -vn -0.629087 0.456619 -0.629086 -vn -0.542555 0.453518 -0.707075 -vn -0.542555 0.453518 -0.707075 -vn -0.341066 0.453518 -0.823405 -vn -0.444831 0.456618 -0.770471 -vn -0.629087 0.456619 -0.629086 -vn -0.770471 0.456618 -0.444831 -vn -0.707075 0.453518 -0.542555 -vn -0.707075 0.453518 -0.542555 -vn -0.542555 0.453518 -0.707075 -vn -0.629087 0.456619 -0.629086 -vn -0.770471 0.456618 -0.444831 -vn -0.859348 0.456618 -0.230262 -vn -0.823405 0.453518 -0.341066 -vn -0.823405 0.453518 -0.341066 -vn -0.707075 0.453518 -0.542555 -vn -0.770471 0.456618 -0.444831 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.883622 0.453518 -0.116332 -vn -0.883622 0.453518 -0.116332 -vn -0.823405 0.453518 -0.341066 -vn -0.859348 0.456618 -0.230262 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.883622 0.453518 0.116331 -vn -0.883622 0.453518 0.116331 -vn -0.883622 0.453518 -0.116332 -vn -0.889663 0.456618 -0.000000 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.823405 0.453518 0.341065 -vn -0.823405 0.453518 0.341065 -vn -0.883622 0.453518 0.116331 -vn -0.859348 0.456618 0.230261 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.707074 0.453518 0.542557 -vn -0.707074 0.453518 0.542557 -vn -0.823405 0.453518 0.341065 -vn -0.770471 0.456618 0.444831 -vn -0.629087 0.456618 0.629086 -vn -0.444832 0.456618 0.770470 -vn -0.542558 0.453518 0.707073 -vn -0.542558 0.453518 0.707073 -vn -0.707074 0.453518 0.542557 -vn -0.629087 0.456618 0.629086 -vn -0.444832 0.456618 0.770470 -vn -0.230261 0.456618 0.859348 -vn -0.341066 0.453518 0.823405 -vn -0.341066 0.453518 0.823405 -vn -0.542558 0.453518 0.707073 -vn -0.444832 0.456618 0.770470 -vn -0.230261 0.456618 0.859348 -vn -0.000001 0.456618 0.889663 -vn -0.116330 0.453518 0.883622 -vn -0.116330 0.453518 0.883622 -vn -0.341066 0.453518 0.823405 -vn -0.230261 0.456618 0.859348 -vn -0.000001 0.456618 0.889663 -vn 0.230261 0.456619 0.859348 -vn 0.116328 0.453518 0.883623 -vn 0.116328 0.453518 0.883623 -vn -0.116330 0.453518 0.883622 -vn -0.000001 0.456618 0.889663 -vn 0.230261 0.456619 0.859348 -vn 0.444831 0.456618 0.770471 -vn 0.341066 0.453518 0.823405 -vn 0.341066 0.453518 0.823405 -vn 0.116328 0.453518 0.883623 -vn 0.230261 0.456619 0.859348 -vn 0.444831 0.456618 0.770471 -vn 0.629086 0.456618 0.629086 -vn 0.542556 0.453518 0.707075 -vn 0.542556 0.453518 0.707075 -vn 0.341066 0.453518 0.823405 -vn 0.444831 0.456618 0.770471 -vn 0.629086 0.456618 0.629086 -vn 0.770470 0.456618 0.444832 -vn 0.707075 0.453518 0.542556 -vn 0.707075 0.453518 0.542556 -vn 0.542556 0.453518 0.707075 -vn 0.629086 0.456618 0.629086 -vn 0.770470 0.456618 0.444832 -vn 0.859348 0.456618 0.230263 -vn 0.823404 0.453518 0.341068 -vn 0.823404 0.453518 0.341068 -vn 0.707075 0.453518 0.542556 -vn 0.770470 0.456618 0.444832 -vn 0.859348 0.456618 0.230263 -vn 0.889663 0.456618 0.000000 -vn 0.883622 0.453518 0.116332 -vn 0.883622 0.453518 0.116332 -vn 0.823404 0.453518 0.341068 -vn 0.859348 0.456618 0.230263 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.000000 -1.000000 -0.000000 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -vn 0.966881 0.000000 -0.255228 -# 3768 vertex normals - -vt 1.000000 0.000000 0.000000 -vt 0.000000 0.000000 0.000000 -vt 1.000000 1.000000 0.000000 -vt 0.000000 1.000000 0.000000 -vt 0.000000 0.000000 0.000000 -vt 1.000000 0.000000 0.000000 -vt 0.000000 1.000000 0.000000 -vt 1.000000 1.000000 0.000000 -vt 0.000000 0.000000 0.000000 -vt 1.000000 0.000000 0.000000 -vt 0.000000 1.000000 0.000000 -vt 1.000000 1.000000 0.000000 -vt 0.000000 0.000000 0.000000 -vt 1.000000 0.000000 0.000000 -vt 0.000000 1.000000 0.000000 -vt 1.000000 1.000000 0.000000 -vt 0.000000 0.000000 0.000000 -vt 1.000000 0.000000 0.000000 -vt 0.000000 1.000000 0.000000 -vt 1.000000 1.000000 0.000000 -vt 0.000000 0.000000 0.000000 -vt 1.000000 0.000000 0.000000 -vt 0.000000 1.000000 0.000000 -vt 1.000000 1.000000 0.000000 -vt 0.000000 1.000000 0.000000 -vt 0.031250 1.000000 0.000000 -vt 0.062500 1.000000 0.000000 -vt 0.093750 1.000000 0.000000 -vt 0.125000 1.000000 0.000000 -vt 0.156250 1.000000 0.000000 -vt 0.187500 1.000000 0.000000 -vt 0.218750 1.000000 0.000000 -vt 0.250000 1.000000 0.000000 -vt 0.281250 1.000000 0.000000 -vt 0.312500 1.000000 0.000000 -vt 0.343750 1.000000 0.000000 -vt 0.375000 1.000000 0.000000 -vt 0.406250 1.000000 0.000000 -vt 0.437500 1.000000 0.000000 -vt 0.468750 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.531250 1.000000 0.000000 -vt 0.562500 1.000000 0.000000 -vt 0.593750 1.000000 0.000000 -vt 0.625000 1.000000 0.000000 -vt 0.656250 1.000000 0.000000 -vt 0.687500 1.000000 0.000000 -vt 0.718750 1.000000 0.000000 -vt 0.750000 1.000000 0.000000 -vt 0.781250 1.000000 0.000000 -vt 0.812500 1.000000 0.000000 -vt 0.843750 1.000000 0.000000 -vt 0.875000 1.000000 0.000000 -vt 0.906250 1.000000 0.000000 -vt 0.937500 1.000000 0.000000 -vt 0.968750 1.000000 0.000000 -vt 0.000000 0.937500 0.000000 -vt 0.031250 0.937500 0.000000 -vt 0.062500 0.937500 0.000000 -vt 0.093750 0.937500 0.000000 -vt 0.125000 0.937500 0.000000 -vt 0.156250 0.937500 0.000000 -vt 0.187500 0.937500 0.000000 -vt 0.218750 0.937500 0.000000 -vt 0.250000 0.937500 0.000000 -vt 0.281250 0.937500 0.000000 -vt 0.312500 0.937500 0.000000 -vt 0.343750 0.937500 0.000000 -vt 0.375000 0.937500 0.000000 -vt 0.406250 0.937500 0.000000 -vt 0.437500 0.937500 0.000000 -vt 0.468750 0.937500 0.000000 -vt 0.500000 0.937500 0.000000 -vt 0.531250 0.937500 0.000000 -vt 0.562500 0.937500 0.000000 -vt 0.593750 0.937500 0.000000 -vt 0.625000 0.937500 0.000000 -vt 0.656250 0.937500 0.000000 -vt 0.687500 0.937500 0.000000 -vt 0.718750 0.937500 0.000000 -vt 0.750000 0.937500 0.000000 -vt 0.781250 0.937500 0.000000 -vt 0.812500 0.937500 0.000000 -vt 0.843750 0.937500 0.000000 -vt 0.875000 0.937500 0.000000 -vt 0.906250 0.937500 0.000000 -vt 0.937500 0.937500 0.000000 -vt 0.968750 0.937500 0.000000 -vt 1.000000 0.937500 0.000000 -vt 0.000000 0.875000 0.000000 -vt 0.031250 0.875000 0.000000 -vt 0.062500 0.875000 0.000000 -vt 0.093750 0.875000 0.000000 -vt 0.125000 0.875000 0.000000 -vt 0.156250 0.875000 0.000000 -vt 0.187500 0.875000 0.000000 -vt 0.218750 0.875000 0.000000 -vt 0.250000 0.875000 0.000000 -vt 0.281250 0.875000 0.000000 -vt 0.312500 0.875000 0.000000 -vt 0.343750 0.875000 0.000000 -vt 0.375000 0.875000 0.000000 -vt 0.406250 0.875000 0.000000 -vt 0.437500 0.875000 0.000000 -vt 0.468750 0.875000 0.000000 -vt 0.500000 0.875000 0.000000 -vt 0.531250 0.875000 0.000000 -vt 0.562500 0.875000 0.000000 -vt 0.593750 0.875000 0.000000 -vt 0.625000 0.875000 0.000000 -vt 0.656250 0.875000 0.000000 -vt 0.687500 0.875000 0.000000 -vt 0.718750 0.875000 0.000000 -vt 0.750000 0.875000 0.000000 -vt 0.781250 0.875000 0.000000 -vt 0.812500 0.875000 0.000000 -vt 0.843750 0.875000 0.000000 -vt 0.875000 0.875000 0.000000 -vt 0.906250 0.875000 0.000000 -vt 0.937500 0.875000 0.000000 -vt 0.968750 0.875000 0.000000 -vt 1.000000 0.875000 0.000000 -vt 0.000000 0.812500 0.000000 -vt 0.031250 0.812500 0.000000 -vt 0.062500 0.812500 0.000000 -vt 0.093750 0.812500 0.000000 -vt 0.125000 0.812500 0.000000 -vt 0.156250 0.812500 0.000000 -vt 0.187500 0.812500 0.000000 -vt 0.218750 0.812500 0.000000 -vt 0.250000 0.812500 0.000000 -vt 0.281250 0.812500 0.000000 -vt 0.312500 0.812500 0.000000 -vt 0.343750 0.812500 0.000000 -vt 0.375000 0.812500 0.000000 -vt 0.406250 0.812500 0.000000 -vt 0.437500 0.812500 0.000000 -vt 0.468750 0.812500 0.000000 -vt 0.500000 0.812500 0.000000 -vt 0.531250 0.812500 0.000000 -vt 0.562500 0.812500 0.000000 -vt 0.593750 0.812500 0.000000 -vt 0.625000 0.812500 0.000000 -vt 0.656250 0.812500 0.000000 -vt 0.687500 0.812500 0.000000 -vt 0.718750 0.812500 0.000000 -vt 0.750000 0.812500 0.000000 -vt 0.781250 0.812500 0.000000 -vt 0.812500 0.812500 0.000000 -vt 0.843750 0.812500 0.000000 -vt 0.875000 0.812500 0.000000 -vt 0.906250 0.812500 0.000000 -vt 0.937500 0.812500 0.000000 -vt 0.968750 0.812500 0.000000 -vt 1.000000 0.812500 0.000000 -vt 0.000000 0.750000 0.000000 -vt 0.031250 0.750000 0.000000 -vt 0.062500 0.750000 0.000000 -vt 0.093750 0.750000 0.000000 -vt 0.125000 0.750000 0.000000 -vt 0.156250 0.750000 0.000000 -vt 0.187500 0.750000 0.000000 -vt 0.218750 0.750000 0.000000 -vt 0.250000 0.750000 0.000000 -vt 0.281250 0.750000 0.000000 -vt 0.312500 0.750000 0.000000 -vt 0.343750 0.750000 0.000000 -vt 0.375000 0.750000 0.000000 -vt 0.406250 0.750000 0.000000 -vt 0.437500 0.750000 0.000000 -vt 0.468750 0.750000 0.000000 -vt 0.500000 0.750000 0.000000 -vt 0.531250 0.750000 0.000000 -vt 0.562500 0.750000 0.000000 -vt 0.593750 0.750000 0.000000 -vt 0.625000 0.750000 0.000000 -vt 0.656250 0.750000 0.000000 -vt 0.687500 0.750000 0.000000 -vt 0.718750 0.750000 0.000000 -vt 0.750000 0.750000 0.000000 -vt 0.781250 0.750000 0.000000 -vt 0.812500 0.750000 0.000000 -vt 0.843750 0.750000 0.000000 -vt 0.875000 0.750000 0.000000 -vt 0.906250 0.750000 0.000000 -vt 0.937500 0.750000 0.000000 -vt 0.968750 0.750000 0.000000 -vt 1.000000 0.750000 0.000000 -vt 0.000000 0.687500 0.000000 -vt 0.031250 0.687500 0.000000 -vt 0.062500 0.687500 0.000000 -vt 0.093750 0.687500 0.000000 -vt 0.125000 0.687500 0.000000 -vt 0.156250 0.687500 0.000000 -vt 0.187500 0.687500 0.000000 -vt 0.218750 0.687500 0.000000 -vt 0.250000 0.687500 0.000000 -vt 0.281250 0.687500 0.000000 -vt 0.312500 0.687500 0.000000 -vt 0.343750 0.687500 0.000000 -vt 0.375000 0.687500 0.000000 -vt 0.406250 0.687500 0.000000 -vt 0.437500 0.687500 0.000000 -vt 0.468750 0.687500 0.000000 -vt 0.500000 0.687500 0.000000 -vt 0.531250 0.687500 0.000000 -vt 0.562500 0.687500 0.000000 -vt 0.593750 0.687500 0.000000 -vt 0.625000 0.687500 0.000000 -vt 0.656250 0.687500 0.000000 -vt 0.687500 0.687500 0.000000 -vt 0.718750 0.687500 0.000000 -vt 0.750000 0.687500 0.000000 -vt 0.781250 0.687500 0.000000 -vt 0.812500 0.687500 0.000000 -vt 0.843750 0.687500 0.000000 -vt 0.875000 0.687500 0.000000 -vt 0.906250 0.687500 0.000000 -vt 0.937500 0.687500 0.000000 -vt 0.968750 0.687500 0.000000 -vt 1.000000 0.687500 0.000000 -vt 0.000000 0.625000 0.000000 -vt 0.031250 0.625000 0.000000 -vt 0.062500 0.625000 0.000000 -vt 0.093750 0.625000 0.000000 -vt 0.125000 0.625000 0.000000 -vt 0.156250 0.625000 0.000000 -vt 0.187500 0.625000 0.000000 -vt 0.218750 0.625000 0.000000 -vt 0.250000 0.625000 0.000000 -vt 0.281250 0.625000 0.000000 -vt 0.312500 0.625000 0.000000 -vt 0.343750 0.625000 0.000000 -vt 0.375000 0.625000 0.000000 -vt 0.406250 0.625000 0.000000 -vt 0.437500 0.625000 0.000000 -vt 0.468750 0.625000 0.000000 -vt 0.500000 0.625000 0.000000 -vt 0.531250 0.625000 0.000000 -vt 0.562500 0.625000 0.000000 -vt 0.593750 0.625000 0.000000 -vt 0.625000 0.625000 0.000000 -vt 0.656250 0.625000 0.000000 -vt 0.687500 0.625000 0.000000 -vt 0.718750 0.625000 0.000000 -vt 0.750000 0.625000 0.000000 -vt 0.781250 0.625000 0.000000 -vt 0.812500 0.625000 0.000000 -vt 0.843750 0.625000 0.000000 -vt 0.875000 0.625000 0.000000 -vt 0.906250 0.625000 0.000000 -vt 0.937500 0.625000 0.000000 -vt 0.968750 0.625000 0.000000 -vt 1.000000 0.625000 0.000000 -vt 0.000000 0.562500 0.000000 -vt 0.031250 0.562500 0.000000 -vt 0.062500 0.562500 0.000000 -vt 0.093750 0.562500 0.000000 -vt 0.125000 0.562500 0.000000 -vt 0.156250 0.562500 0.000000 -vt 0.187500 0.562500 0.000000 -vt 0.218750 0.562500 0.000000 -vt 0.250000 0.562500 0.000000 -vt 0.281250 0.562500 0.000000 -vt 0.312500 0.562500 0.000000 -vt 0.343750 0.562500 0.000000 -vt 0.375000 0.562500 0.000000 -vt 0.406250 0.562500 0.000000 -vt 0.437500 0.562500 0.000000 -vt 0.468750 0.562500 0.000000 -vt 0.500000 0.562500 0.000000 -vt 0.531250 0.562500 0.000000 -vt 0.562500 0.562500 0.000000 -vt 0.593750 0.562500 0.000000 -vt 0.625000 0.562500 0.000000 -vt 0.656250 0.562500 0.000000 -vt 0.687500 0.562500 0.000000 -vt 0.718750 0.562500 0.000000 -vt 0.750000 0.562500 0.000000 -vt 0.781250 0.562500 0.000000 -vt 0.812500 0.562500 0.000000 -vt 0.843750 0.562500 0.000000 -vt 0.875000 0.562500 0.000000 -vt 0.906250 0.562500 0.000000 -vt 0.937500 0.562500 0.000000 -vt 0.968750 0.562500 0.000000 -vt 1.000000 0.562500 0.000000 -vt 0.000000 0.500000 0.000000 -vt 0.031250 0.500000 0.000000 -vt 0.062500 0.500000 0.000000 -vt 0.093750 0.500000 0.000000 -vt 0.125000 0.500000 0.000000 -vt 0.156250 0.500000 0.000000 -vt 0.187500 0.500000 0.000000 -vt 0.218750 0.500000 0.000000 -vt 0.250000 0.500000 0.000000 -vt 0.281250 0.500000 0.000000 -vt 0.312500 0.500000 0.000000 -vt 0.343750 0.500000 0.000000 -vt 0.375000 0.500000 0.000000 -vt 0.406250 0.500000 0.000000 -vt 0.437500 0.500000 0.000000 -vt 0.468750 0.500000 0.000000 -vt 0.500000 0.500000 0.000000 -vt 0.531250 0.500000 0.000000 -vt 0.562500 0.500000 0.000000 -vt 0.593750 0.500000 0.000000 -vt 0.625000 0.500000 0.000000 -vt 0.656250 0.500000 0.000000 -vt 0.687500 0.500000 0.000000 -vt 0.718750 0.500000 0.000000 -vt 0.750000 0.500000 0.000000 -vt 0.781250 0.500000 0.000000 -vt 0.812500 0.500000 0.000000 -vt 0.843750 0.500000 0.000000 -vt 0.875000 0.500000 0.000000 -vt 0.906250 0.500000 0.000000 -vt 0.937500 0.500000 0.000000 -vt 0.968750 0.500000 0.000000 -vt 1.000000 0.500000 0.000000 -vt 0.000000 0.437500 0.000000 -vt 0.031250 0.437500 0.000000 -vt 0.062500 0.437500 0.000000 -vt 0.093750 0.437500 0.000000 -vt 0.125000 0.437500 0.000000 -vt 0.156250 0.437500 0.000000 -vt 0.187500 0.437500 0.000000 -vt 0.218750 0.437500 0.000000 -vt 0.250000 0.437500 0.000000 -vt 0.281250 0.437500 0.000000 -vt 0.312500 0.437500 0.000000 -vt 0.343750 0.437500 0.000000 -vt 0.375000 0.437500 0.000000 -vt 0.406250 0.437500 0.000000 -vt 0.437500 0.437500 0.000000 -vt 0.468750 0.437500 0.000000 -vt 0.500000 0.437500 0.000000 -vt 0.531250 0.437500 0.000000 -vt 0.562500 0.437500 0.000000 -vt 0.593750 0.437500 0.000000 -vt 0.625000 0.437500 0.000000 -vt 0.656250 0.437500 0.000000 -vt 0.687500 0.437500 0.000000 -vt 0.718750 0.437500 0.000000 -vt 0.750000 0.437500 0.000000 -vt 0.781250 0.437500 0.000000 -vt 0.812500 0.437500 0.000000 -vt 0.843750 0.437500 0.000000 -vt 0.875000 0.437500 0.000000 -vt 0.906250 0.437500 0.000000 -vt 0.937500 0.437500 0.000000 -vt 0.968750 0.437500 0.000000 -vt 1.000000 0.437500 0.000000 -vt 0.000000 0.375000 0.000000 -vt 0.031250 0.375000 0.000000 -vt 0.062500 0.375000 0.000000 -vt 0.093750 0.375000 0.000000 -vt 0.125000 0.375000 0.000000 -vt 0.156250 0.375000 0.000000 -vt 0.187500 0.375000 0.000000 -vt 0.218750 0.375000 0.000000 -vt 0.250000 0.375000 0.000000 -vt 0.281250 0.375000 0.000000 -vt 0.312500 0.375000 0.000000 -vt 0.343750 0.375000 0.000000 -vt 0.375000 0.375000 0.000000 -vt 0.406250 0.375000 0.000000 -vt 0.437500 0.375000 0.000000 -vt 0.468750 0.375000 0.000000 -vt 0.500000 0.375000 0.000000 -vt 0.531250 0.375000 0.000000 -vt 0.562500 0.375000 0.000000 -vt 0.593750 0.375000 0.000000 -vt 0.625000 0.375000 0.000000 -vt 0.656250 0.375000 0.000000 -vt 0.687500 0.375000 0.000000 -vt 0.718750 0.375000 0.000000 -vt 0.750000 0.375000 0.000000 -vt 0.781250 0.375000 0.000000 -vt 0.812500 0.375000 0.000000 -vt 0.843750 0.375000 0.000000 -vt 0.875000 0.375000 0.000000 -vt 0.906250 0.375000 0.000000 -vt 0.937500 0.375000 0.000000 -vt 0.968750 0.375000 0.000000 -vt 1.000000 0.375000 0.000000 -vt 0.000000 0.312500 0.000000 -vt 0.031250 0.312500 0.000000 -vt 0.062500 0.312500 0.000000 -vt 0.093750 0.312500 0.000000 -vt 0.125000 0.312500 0.000000 -vt 0.156250 0.312500 0.000000 -vt 0.187500 0.312500 0.000000 -vt 0.218750 0.312500 0.000000 -vt 0.250000 0.312500 0.000000 -vt 0.281250 0.312500 0.000000 -vt 0.312500 0.312500 0.000000 -vt 0.343750 0.312500 0.000000 -vt 0.375000 0.312500 0.000000 -vt 0.406250 0.312500 0.000000 -vt 0.437500 0.312500 0.000000 -vt 0.468750 0.312500 0.000000 -vt 0.500000 0.312500 0.000000 -vt 0.531250 0.312500 0.000000 -vt 0.562500 0.312500 0.000000 -vt 0.593750 0.312500 0.000000 -vt 0.625000 0.312500 0.000000 -vt 0.656250 0.312500 0.000000 -vt 0.687500 0.312500 0.000000 -vt 0.718750 0.312500 0.000000 -vt 0.750000 0.312500 0.000000 -vt 0.781250 0.312500 0.000000 -vt 0.812500 0.312500 0.000000 -vt 0.843750 0.312500 0.000000 -vt 0.875000 0.312500 0.000000 -vt 0.906250 0.312500 0.000000 -vt 0.937500 0.312500 0.000000 -vt 0.968750 0.312500 0.000000 -vt 1.000000 0.312500 0.000000 -vt 0.000000 0.250000 0.000000 -vt 0.031250 0.250000 0.000000 -vt 0.062500 0.250000 0.000000 -vt 0.093750 0.250000 0.000000 -vt 0.125000 0.250000 0.000000 -vt 0.156250 0.250000 0.000000 -vt 0.187500 0.250000 0.000000 -vt 0.218750 0.250000 0.000000 -vt 0.250000 0.250000 0.000000 -vt 0.281250 0.250000 0.000000 -vt 0.312500 0.250000 0.000000 -vt 0.343750 0.250000 0.000000 -vt 0.375000 0.250000 0.000000 -vt 0.406250 0.250000 0.000000 -vt 0.437500 0.250000 0.000000 -vt 0.468750 0.250000 0.000000 -vt 0.500000 0.250000 0.000000 -vt 0.531250 0.250000 0.000000 -vt 0.562500 0.250000 0.000000 -vt 0.593750 0.250000 0.000000 -vt 0.625000 0.250000 0.000000 -vt 0.656250 0.250000 0.000000 -vt 0.687500 0.250000 0.000000 -vt 0.718750 0.250000 0.000000 -vt 0.750000 0.250000 0.000000 -vt 0.781250 0.250000 0.000000 -vt 0.812500 0.250000 0.000000 -vt 0.843750 0.250000 0.000000 -vt 0.875000 0.250000 0.000000 -vt 0.906250 0.250000 0.000000 -vt 0.937500 0.250000 0.000000 -vt 0.968750 0.250000 0.000000 -vt 1.000000 0.250000 0.000000 -vt 0.000000 0.187500 0.000000 -vt 0.031250 0.187500 0.000000 -vt 0.062500 0.187500 0.000000 -vt 0.093750 0.187500 0.000000 -vt 0.125000 0.187500 0.000000 -vt 0.156250 0.187500 0.000000 -vt 0.187500 0.187500 0.000000 -vt 0.218750 0.187500 0.000000 -vt 0.250000 0.187500 0.000000 -vt 0.281250 0.187500 0.000000 -vt 0.312500 0.187500 0.000000 -vt 0.343750 0.187500 0.000000 -vt 0.375000 0.187500 0.000000 -vt 0.406250 0.187500 0.000000 -vt 0.437500 0.187500 0.000000 -vt 0.468750 0.187500 0.000000 -vt 0.500000 0.187500 0.000000 -vt 0.531250 0.187500 0.000000 -vt 0.562500 0.187500 0.000000 -vt 0.593750 0.187500 0.000000 -vt 0.625000 0.187500 0.000000 -vt 0.656250 0.187500 0.000000 -vt 0.687500 0.187500 0.000000 -vt 0.718750 0.187500 0.000000 -vt 0.750000 0.187500 0.000000 -vt 0.781250 0.187500 0.000000 -vt 0.812500 0.187500 0.000000 -vt 0.843750 0.187500 0.000000 -vt 0.875000 0.187500 0.000000 -vt 0.906250 0.187500 0.000000 -vt 0.937500 0.187500 0.000000 -vt 0.968750 0.187500 0.000000 -vt 1.000000 0.187500 0.000000 -vt 0.000000 0.125000 0.000000 -vt 0.031250 0.125000 0.000000 -vt 0.062500 0.125000 0.000000 -vt 0.093750 0.125000 0.000000 -vt 0.125000 0.125000 0.000000 -vt 0.156250 0.125000 0.000000 -vt 0.187500 0.125000 0.000000 -vt 0.218750 0.125000 0.000000 -vt 0.250000 0.125000 0.000000 -vt 0.281250 0.125000 0.000000 -vt 0.312500 0.125000 0.000000 -vt 0.343750 0.125000 0.000000 -vt 0.375000 0.125000 0.000000 -vt 0.406250 0.125000 0.000000 -vt 0.437500 0.125000 0.000000 -vt 0.468750 0.125000 0.000000 -vt 0.500000 0.125000 0.000000 -vt 0.531250 0.125000 0.000000 -vt 0.562500 0.125000 0.000000 -vt 0.593750 0.125000 0.000000 -vt 0.625000 0.125000 0.000000 -vt 0.656250 0.125000 0.000000 -vt 0.687500 0.125000 0.000000 -vt 0.718750 0.125000 0.000000 -vt 0.750000 0.125000 0.000000 -vt 0.781250 0.125000 0.000000 -vt 0.812500 0.125000 0.000000 -vt 0.843750 0.125000 0.000000 -vt 0.875000 0.125000 0.000000 -vt 0.906250 0.125000 0.000000 -vt 0.937500 0.125000 0.000000 -vt 0.968750 0.125000 0.000000 -vt 1.000000 0.125000 0.000000 -vt 0.000000 0.062500 0.000000 -vt 0.031250 0.062500 0.000000 -vt 0.062500 0.062500 0.000000 -vt 0.093750 0.062500 0.000000 -vt 0.125000 0.062500 0.000000 -vt 0.156250 0.062500 0.000000 -vt 0.187500 0.062500 0.000000 -vt 0.218750 0.062500 0.000000 -vt 0.250000 0.062500 0.000000 -vt 0.281250 0.062500 0.000000 -vt 0.312500 0.062500 0.000000 -vt 0.343750 0.062500 0.000000 -vt 0.375000 0.062500 0.000000 -vt 0.406250 0.062500 0.000000 -vt 0.437500 0.062500 0.000000 -vt 0.468750 0.062500 0.000000 -vt 0.500000 0.062500 0.000000 -vt 0.531250 0.062500 0.000000 -vt 0.562500 0.062500 0.000000 -vt 0.593750 0.062500 0.000000 -vt 0.625000 0.062500 0.000000 -vt 0.656250 0.062500 0.000000 -vt 0.687500 0.062500 0.000000 -vt 0.718750 0.062500 0.000000 -vt 0.750000 0.062500 0.000000 -vt 0.781250 0.062500 0.000000 -vt 0.812500 0.062500 0.000000 -vt 0.843750 0.062500 0.000000 -vt 0.875000 0.062500 0.000000 -vt 0.906250 0.062500 0.000000 -vt 0.937500 0.062500 0.000000 -vt 0.968750 0.062500 0.000000 -vt 1.000000 0.062500 0.000000 -vt 0.000000 -0.000000 0.000000 -vt 0.031250 -0.000000 0.000000 -vt 0.062500 -0.000000 0.000000 -vt 0.093750 -0.000000 0.000000 -vt 0.125000 -0.000000 0.000000 -vt 0.156250 -0.000000 0.000000 -vt 0.187500 -0.000000 0.000000 -vt 0.218750 -0.000000 0.000000 -vt 0.250000 -0.000000 0.000000 -vt 0.281250 -0.000000 0.000000 -vt 0.312500 -0.000000 0.000000 -vt 0.343750 -0.000000 0.000000 -vt 0.375000 -0.000000 0.000000 -vt 0.406250 -0.000000 0.000000 -vt 0.437500 -0.000000 0.000000 -vt 0.468750 -0.000000 0.000000 -vt 0.500000 -0.000000 0.000000 -vt 0.531250 -0.000000 0.000000 -vt 0.562500 -0.000000 0.000000 -vt 0.593750 -0.000000 0.000000 -vt 0.625000 -0.000000 0.000000 -vt 0.656250 -0.000000 0.000000 -vt 0.687500 -0.000000 0.000000 -vt 0.718750 -0.000000 0.000000 -vt 0.750000 -0.000000 0.000000 -vt 0.781250 -0.000000 0.000000 -vt 0.812500 -0.000000 0.000000 -vt 0.843750 -0.000000 0.000000 -vt 0.875000 -0.000000 0.000000 -vt 0.906250 -0.000000 0.000000 -vt 0.937500 -0.000000 0.000000 -vt 0.968750 -0.000000 0.000000 -vt 0.750000 0.000000 1.000000 -vt 0.791667 0.000000 1.000000 -vt 0.833333 0.000000 1.000000 -vt 0.875000 0.000000 1.000000 -vt 0.916667 0.000000 1.000000 -vt 0.958333 0.000000 1.000000 -vt 1.000000 0.000000 1.000000 -vt 0.041667 0.000000 1.000000 -vt 0.083333 0.000000 1.000000 -vt 0.125000 0.000000 1.000000 -vt 0.166667 0.000000 1.000000 -vt 0.208333 0.000000 1.000000 -vt 0.250000 0.000000 1.000000 -vt 0.291667 0.000000 1.000000 -vt 0.333333 0.000000 1.000000 -vt 0.375000 0.000000 1.000000 -vt 0.416667 0.000000 1.000000 -vt 0.458333 0.000000 1.000000 -vt 0.500000 0.000000 1.000000 -vt 0.541667 0.000000 1.000000 -vt 0.583333 0.000000 1.000000 -vt 0.625000 0.000000 1.000000 -vt 0.666667 0.000000 1.000000 -vt 0.708333 0.000000 1.000000 -vt 0.750000 0.200000 0.800000 -vt 0.791667 0.200000 0.800000 -vt 0.833333 0.200000 0.800000 -vt 0.875000 0.200000 0.800000 -vt 0.916667 0.200000 0.800000 -vt 0.958333 0.200000 0.800000 -vt 1.000000 0.200000 0.800000 -vt 0.041667 0.200000 0.800000 -vt 0.083333 0.200000 0.800000 -vt 0.125000 0.200000 0.800000 -vt 0.166667 0.200000 0.800000 -vt 0.208333 0.200000 0.800000 -vt 0.250000 0.200000 0.800000 -vt 0.291667 0.200000 0.800000 -vt 0.333333 0.200000 0.800000 -vt 0.375000 0.200000 0.800000 -vt 0.416667 0.200000 0.800000 -vt 0.458333 0.200000 0.800000 -vt 0.500000 0.200000 0.800000 -vt 0.541667 0.200000 0.800000 -vt 0.583333 0.200000 0.800000 -vt 0.625000 0.200000 0.800000 -vt 0.666667 0.200000 0.800000 -vt 0.708333 0.200000 0.800000 -vt 0.750000 0.400000 0.600000 -vt 0.791667 0.400000 0.600000 -vt 0.833333 0.400000 0.600000 -vt 0.875000 0.400000 0.600000 -vt 0.916667 0.400000 0.600000 -vt 0.958333 0.400000 0.600000 -vt 1.000000 0.400000 0.600000 -vt 0.041667 0.400000 0.600000 -vt 0.083333 0.400000 0.600000 -vt 0.125000 0.400000 0.600000 -vt 0.166667 0.400000 0.600000 -vt 0.208333 0.400000 0.600000 -vt 0.250000 0.400000 0.600000 -vt 0.291667 0.400000 0.600000 -vt 0.333333 0.400000 0.600000 -vt 0.375000 0.400000 0.600000 -vt 0.416667 0.400000 0.600000 -vt 0.458333 0.400000 0.600000 -vt 0.500000 0.400000 0.600000 -vt 0.541667 0.400000 0.600000 -vt 0.583333 0.400000 0.600000 -vt 0.625000 0.400000 0.600000 -vt 0.666667 0.400000 0.600000 -vt 0.708333 0.400000 0.600000 -vt 0.750000 0.600000 0.400000 -vt 0.791667 0.600000 0.400000 -vt 0.833333 0.600000 0.400000 -vt 0.875000 0.600000 0.400000 -vt 0.916667 0.600000 0.400000 -vt 0.958333 0.600000 0.400000 -vt 1.000000 0.600000 0.400000 -vt 0.041667 0.600000 0.400000 -vt 0.083333 0.600000 0.400000 -vt 0.125000 0.600000 0.400000 -vt 0.166667 0.600000 0.400000 -vt 0.208333 0.600000 0.400000 -vt 0.250000 0.600000 0.400000 -vt 0.291667 0.600000 0.400000 -vt 0.333333 0.600000 0.400000 -vt 0.375000 0.600000 0.400000 -vt 0.416667 0.600000 0.400000 -vt 0.458333 0.600000 0.400000 -vt 0.500000 0.600000 0.400000 -vt 0.541667 0.600000 0.400000 -vt 0.583333 0.600000 0.400000 -vt 0.625000 0.600000 0.400000 -vt 0.666667 0.600000 0.400000 -vt 0.708333 0.600000 0.400000 -vt 0.750000 0.800000 0.200000 -vt 0.791667 0.800000 0.200000 -vt 0.833333 0.800000 0.200000 -vt 0.875000 0.800000 0.200000 -vt 0.916667 0.800000 0.200000 -vt 0.958333 0.800000 0.200000 -vt 1.000000 0.800000 0.200000 -vt 0.041667 0.800000 0.200000 -vt 0.083333 0.800000 0.200000 -vt 0.125000 0.800000 0.200000 -vt 0.166667 0.800000 0.200000 -vt 0.208333 0.800000 0.200000 -vt 0.250000 0.800000 0.200000 -vt 0.291667 0.800000 0.200000 -vt 0.333333 0.800000 0.200000 -vt 0.375000 0.800000 0.200000 -vt 0.416667 0.800000 0.200000 -vt 0.458333 0.800000 0.200000 -vt 0.500000 0.800000 0.200000 -vt 0.541667 0.800000 0.200000 -vt 0.583333 0.800000 0.200000 -vt 0.625000 0.800000 0.200000 -vt 0.666667 0.800000 0.200000 -vt 0.708333 0.800000 0.200000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 0.500000 1.000000 0.000000 -vt 1.041667 0.000000 1.000000 -vt 1.041667 0.200000 0.800000 -vt 1.041667 0.400000 0.600000 -vt 1.041667 0.600000 0.400000 -vt 1.041667 0.800000 0.200000 -vt 1.500000 1.000000 0.000000 -vt 1.500000 1.000000 0.000000 -vt 2.000000 0.800000 0.200000 -vt 0.629410 0.982963 -0.250000 -vt 0.750000 0.933013 -0.250000 -vt 0.853554 0.853553 -0.250000 -vt 0.933013 0.750000 -0.250000 -vt 0.982963 0.629409 -0.250000 -vt 1.000000 0.500000 -0.250000 -vt 0.982963 0.370590 -0.250000 -vt 0.933013 0.250000 -0.250000 -vt 0.853553 0.146446 -0.250000 -vt 0.750000 0.066987 -0.250000 -vt 0.629409 0.017037 -0.250000 -vt 0.500000 0.000000 -0.250000 -vt 0.370590 0.017037 -0.250000 -vt 0.250000 0.066987 -0.250000 -vt 0.146447 0.146447 -0.250000 -vt 0.066987 0.250000 -0.250000 -vt 0.017037 0.370591 -0.250000 -vt 0.000000 0.500000 -0.250000 -vt 0.017037 0.629410 -0.250000 -vt 0.066987 0.750000 -0.250000 -vt 0.146447 0.853553 -0.250000 -vt 0.250000 0.933013 -0.250000 -vt 0.370590 0.982963 -0.250000 -vt 0.500000 1.000000 -0.250000 -# 759 texture coords - -g Box001 -f 1/1/1 3/3/2 4/4/3 -f 4/4/4 2/2/5 1/1/6 -f 5/5/7 6/6/8 8/8/9 -f 8/8/10 7/7/11 5/5/12 -f 1/9/13 2/10/14 6/12/15 -f 6/12/16 5/11/17 1/9/18 -f 2/13/19 4/14/20 8/16/21 -f 8/16/22 6/15/23 2/13/24 -f 4/17/25 3/18/26 7/20/27 -f 7/20/28 8/19/29 4/17/30 -f 3/21/31 1/22/32 5/24/33 -f 5/24/34 7/23/35 3/21/36 -f 9/25/37 10/57/38 11/58/39 -f 9/26/40 11/58/41 12/59/42 -f 9/27/43 12/59/44 13/60/45 -f 9/28/46 13/60/47 14/61/48 -f 9/29/49 14/61/50 15/62/51 -f 9/30/52 15/62/53 16/63/54 -f 9/31/55 16/63/56 17/64/57 -f 9/32/58 17/64/59 18/65/60 -f 9/33/61 18/65/62 19/66/63 -f 9/34/64 19/66/65 20/67/66 -f 9/35/67 20/67/68 21/68/69 -f 9/36/70 21/68/71 22/69/72 -f 9/37/73 22/69/74 23/70/75 -f 9/38/76 23/70/77 24/71/78 -f 9/39/79 24/71/80 25/72/81 -f 9/40/82 25/72/83 26/73/84 -f 9/41/85 26/73/86 27/74/87 -f 9/42/88 27/74/89 28/75/90 -f 9/43/91 28/75/92 29/76/93 -f 9/44/94 29/76/95 30/77/96 -f 9/45/97 30/77/98 31/78/99 -f 9/46/100 31/78/101 32/79/102 -f 9/47/103 32/79/104 33/80/105 -f 9/48/106 33/80/107 34/81/108 -f 9/49/109 34/81/110 35/82/111 -f 9/50/112 35/82/113 36/83/114 -f 9/51/115 36/83/116 37/84/117 -f 9/52/118 37/84/119 38/85/120 -f 9/53/121 38/85/122 39/86/123 -f 9/54/124 39/86/125 40/87/126 -f 9/55/127 40/87/128 41/88/129 -f 9/56/130 41/88/131 10/89/132 -f 43/91/133 11/58/134 10/57/135 -f 10/57/136 42/90/137 43/91/138 -f 44/92/139 12/59/140 11/58/141 -f 11/58/142 43/91/143 44/92/144 -f 45/93/145 13/60/146 12/59/147 -f 12/59/148 44/92/149 45/93/150 -f 46/94/151 14/61/152 13/60/153 -f 13/60/154 45/93/155 46/94/156 -f 47/95/157 15/62/158 14/61/159 -f 14/61/160 46/94/161 47/95/162 -f 48/96/163 16/63/164 15/62/165 -f 15/62/166 47/95/167 48/96/168 -f 49/97/169 17/64/170 16/63/171 -f 16/63/172 48/96/173 49/97/174 -f 50/98/175 18/65/176 17/64/177 -f 17/64/178 49/97/179 50/98/180 -f 51/99/181 19/66/182 18/65/183 -f 18/65/184 50/98/185 51/99/186 -f 52/100/187 20/67/188 19/66/189 -f 19/66/190 51/99/191 52/100/192 -f 53/101/193 21/68/194 20/67/195 -f 20/67/196 52/100/197 53/101/198 -f 54/102/199 22/69/200 21/68/201 -f 21/68/202 53/101/203 54/102/204 -f 55/103/205 23/70/206 22/69/207 -f 22/69/208 54/102/209 55/103/210 -f 56/104/211 24/71/212 23/70/213 -f 23/70/214 55/103/215 56/104/216 -f 57/105/217 25/72/218 24/71/219 -f 24/71/220 56/104/221 57/105/222 -f 58/106/223 26/73/224 25/72/225 -f 25/72/226 57/105/227 58/106/228 -f 59/107/229 27/74/230 26/73/231 -f 26/73/232 58/106/233 59/107/234 -f 60/108/235 28/75/236 27/74/237 -f 27/74/238 59/107/239 60/108/240 -f 61/109/241 29/76/242 28/75/243 -f 28/75/244 60/108/245 61/109/246 -f 62/110/247 30/77/248 29/76/249 -f 29/76/250 61/109/251 62/110/252 -f 63/111/253 31/78/254 30/77/255 -f 30/77/256 62/110/257 63/111/258 -f 64/112/259 32/79/260 31/78/261 -f 31/78/262 63/111/263 64/112/264 -f 65/113/265 33/80/266 32/79/267 -f 32/79/268 64/112/269 65/113/270 -f 66/114/271 34/81/272 33/80/273 -f 33/80/274 65/113/275 66/114/276 -f 67/115/277 35/82/278 34/81/279 -f 34/81/280 66/114/281 67/115/282 -f 68/116/283 36/83/284 35/82/285 -f 35/82/286 67/115/287 68/116/288 -f 69/117/289 37/84/290 36/83/291 -f 36/83/292 68/116/293 69/117/294 -f 70/118/295 38/85/296 37/84/297 -f 37/84/298 69/117/299 70/118/300 -f 71/119/301 39/86/302 38/85/303 -f 38/85/304 70/118/305 71/119/306 -f 72/120/307 40/87/308 39/86/309 -f 39/86/310 71/119/311 72/120/312 -f 73/121/313 41/88/314 40/87/315 -f 40/87/316 72/120/317 73/121/318 -f 42/122/319 10/89/320 41/88/321 -f 41/88/322 73/121/323 42/122/324 -f 75/124/325 43/91/326 42/90/327 -f 42/90/328 74/123/329 75/124/330 -f 76/125/331 44/92/332 43/91/333 -f 43/91/334 75/124/335 76/125/336 -f 77/126/337 45/93/338 44/92/339 -f 44/92/340 76/125/341 77/126/342 -f 78/127/343 46/94/344 45/93/345 -f 45/93/346 77/126/347 78/127/348 -f 79/128/349 47/95/350 46/94/351 -f 46/94/352 78/127/353 79/128/354 -f 80/129/355 48/96/356 47/95/357 -f 47/95/358 79/128/359 80/129/360 -f 81/130/361 49/97/362 48/96/363 -f 48/96/364 80/129/365 81/130/366 -f 82/131/367 50/98/368 49/97/369 -f 49/97/370 81/130/371 82/131/372 -f 83/132/373 51/99/374 50/98/375 -f 50/98/376 82/131/377 83/132/378 -f 84/133/379 52/100/380 51/99/381 -f 51/99/382 83/132/383 84/133/384 -f 85/134/385 53/101/386 52/100/387 -f 52/100/388 84/133/389 85/134/390 -f 86/135/391 54/102/392 53/101/393 -f 53/101/394 85/134/395 86/135/396 -f 87/136/397 55/103/398 54/102/399 -f 54/102/400 86/135/401 87/136/402 -f 88/137/403 56/104/404 55/103/405 -f 55/103/406 87/136/407 88/137/408 -f 89/138/409 57/105/410 56/104/411 -f 56/104/412 88/137/413 89/138/414 -f 90/139/415 58/106/416 57/105/417 -f 57/105/418 89/138/419 90/139/420 -f 91/140/421 59/107/422 58/106/423 -f 58/106/424 90/139/425 91/140/426 -f 92/141/427 60/108/428 59/107/429 -f 59/107/430 91/140/431 92/141/432 -f 93/142/433 61/109/434 60/108/435 -f 60/108/436 92/141/437 93/142/438 -f 94/143/439 62/110/440 61/109/441 -f 61/109/442 93/142/443 94/143/444 -f 95/144/445 63/111/446 62/110/447 -f 62/110/448 94/143/449 95/144/450 -f 96/145/451 64/112/452 63/111/453 -f 63/111/454 95/144/455 96/145/456 -f 97/146/457 65/113/458 64/112/459 -f 64/112/460 96/145/461 97/146/462 -f 98/147/463 66/114/464 65/113/465 -f 65/113/466 97/146/467 98/147/468 -f 99/148/469 67/115/470 66/114/471 -f 66/114/472 98/147/473 99/148/474 -f 100/149/475 68/116/476 67/115/477 -f 67/115/478 99/148/479 100/149/480 -f 101/150/481 69/117/482 68/116/483 -f 68/116/484 100/149/485 101/150/486 -f 102/151/487 70/118/488 69/117/489 -f 69/117/490 101/150/491 102/151/492 -f 103/152/493 71/119/494 70/118/495 -f 70/118/496 102/151/497 103/152/498 -f 104/153/499 72/120/500 71/119/501 -f 71/119/502 103/152/503 104/153/504 -f 105/154/505 73/121/506 72/120/507 -f 72/120/508 104/153/509 105/154/510 -f 74/155/511 42/122/512 73/121/513 -f 73/121/514 105/154/515 74/155/516 -f 107/157/517 75/124/518 74/123/519 -f 74/123/520 106/156/521 107/157/522 -f 108/158/523 76/125/524 75/124/525 -f 75/124/526 107/157/527 108/158/528 -f 109/159/529 77/126/530 76/125/531 -f 76/125/532 108/158/533 109/159/534 -f 110/160/535 78/127/536 77/126/537 -f 77/126/538 109/159/539 110/160/540 -f 111/161/541 79/128/542 78/127/543 -f 78/127/544 110/160/545 111/161/546 -f 112/162/547 80/129/548 79/128/549 -f 79/128/550 111/161/551 112/162/552 -f 113/163/553 81/130/554 80/129/555 -f 80/129/556 112/162/557 113/163/558 -f 114/164/559 82/131/560 81/130/561 -f 81/130/562 113/163/563 114/164/564 -f 115/165/565 83/132/566 82/131/567 -f 82/131/568 114/164/569 115/165/570 -f 116/166/571 84/133/572 83/132/573 -f 83/132/574 115/165/575 116/166/576 -f 117/167/577 85/134/578 84/133/579 -f 84/133/580 116/166/581 117/167/582 -f 118/168/583 86/135/584 85/134/585 -f 85/134/586 117/167/587 118/168/588 -f 119/169/589 87/136/590 86/135/591 -f 86/135/592 118/168/593 119/169/594 -f 120/170/595 88/137/596 87/136/597 -f 87/136/598 119/169/599 120/170/600 -f 121/171/601 89/138/602 88/137/603 -f 88/137/604 120/170/605 121/171/606 -f 122/172/607 90/139/608 89/138/609 -f 89/138/610 121/171/611 122/172/612 -f 123/173/613 91/140/614 90/139/615 -f 90/139/616 122/172/617 123/173/618 -f 124/174/619 92/141/620 91/140/621 -f 91/140/622 123/173/623 124/174/624 -f 125/175/625 93/142/626 92/141/627 -f 92/141/628 124/174/629 125/175/630 -f 126/176/631 94/143/632 93/142/633 -f 93/142/634 125/175/635 126/176/636 -f 127/177/637 95/144/638 94/143/639 -f 94/143/640 126/176/641 127/177/642 -f 128/178/643 96/145/644 95/144/645 -f 95/144/646 127/177/647 128/178/648 -f 129/179/649 97/146/650 96/145/651 -f 96/145/652 128/178/653 129/179/654 -f 130/180/655 98/147/656 97/146/657 -f 97/146/658 129/179/659 130/180/660 -f 131/181/661 99/148/662 98/147/663 -f 98/147/664 130/180/665 131/181/666 -f 132/182/667 100/149/668 99/148/669 -f 99/148/670 131/181/671 132/182/672 -f 133/183/673 101/150/674 100/149/675 -f 100/149/676 132/182/677 133/183/678 -f 134/184/679 102/151/680 101/150/681 -f 101/150/682 133/183/683 134/184/684 -f 135/185/685 103/152/686 102/151/687 -f 102/151/688 134/184/689 135/185/690 -f 136/186/691 104/153/692 103/152/693 -f 103/152/694 135/185/695 136/186/696 -f 137/187/697 105/154/698 104/153/699 -f 104/153/700 136/186/701 137/187/702 -f 106/188/703 74/155/704 105/154/705 -f 105/154/706 137/187/707 106/188/708 -f 139/190/709 107/157/710 106/156/711 -f 106/156/712 138/189/713 139/190/714 -f 140/191/715 108/158/716 107/157/717 -f 107/157/718 139/190/719 140/191/720 -f 141/192/721 109/159/722 108/158/723 -f 108/158/724 140/191/725 141/192/726 -f 142/193/727 110/160/728 109/159/729 -f 109/159/730 141/192/731 142/193/732 -f 143/194/733 111/161/734 110/160/735 -f 110/160/736 142/193/737 143/194/738 -f 144/195/739 112/162/740 111/161/741 -f 111/161/742 143/194/743 144/195/744 -f 145/196/745 113/163/746 112/162/747 -f 112/162/748 144/195/749 145/196/750 -f 146/197/751 114/164/752 113/163/753 -f 113/163/754 145/196/755 146/197/756 -f 147/198/757 115/165/758 114/164/759 -f 114/164/760 146/197/761 147/198/762 -f 148/199/763 116/166/764 115/165/765 -f 115/165/766 147/198/767 148/199/768 -f 149/200/769 117/167/770 116/166/771 -f 116/166/772 148/199/773 149/200/774 -f 150/201/775 118/168/776 117/167/777 -f 117/167/778 149/200/779 150/201/780 -f 151/202/781 119/169/782 118/168/783 -f 118/168/784 150/201/785 151/202/786 -f 152/203/787 120/170/788 119/169/789 -f 119/169/790 151/202/791 152/203/792 -f 153/204/793 121/171/794 120/170/795 -f 120/170/796 152/203/797 153/204/798 -f 154/205/799 122/172/800 121/171/801 -f 121/171/802 153/204/803 154/205/804 -f 155/206/805 123/173/806 122/172/807 -f 122/172/808 154/205/809 155/206/810 -f 156/207/811 124/174/812 123/173/813 -f 123/173/814 155/206/815 156/207/816 -f 157/208/817 125/175/818 124/174/819 -f 124/174/820 156/207/821 157/208/822 -f 158/209/823 126/176/824 125/175/825 -f 125/175/826 157/208/827 158/209/828 -f 159/210/829 127/177/830 126/176/831 -f 126/176/832 158/209/833 159/210/834 -f 160/211/835 128/178/836 127/177/837 -f 127/177/838 159/210/839 160/211/840 -f 161/212/841 129/179/842 128/178/843 -f 128/178/844 160/211/845 161/212/846 -f 162/213/847 130/180/848 129/179/849 -f 129/179/850 161/212/851 162/213/852 -f 163/214/853 131/181/854 130/180/855 -f 130/180/856 162/213/857 163/214/858 -f 164/215/859 132/182/860 131/181/861 -f 131/181/862 163/214/863 164/215/864 -f 165/216/865 133/183/866 132/182/867 -f 132/182/868 164/215/869 165/216/870 -f 166/217/871 134/184/872 133/183/873 -f 133/183/874 165/216/875 166/217/876 -f 167/218/877 135/185/878 134/184/879 -f 134/184/880 166/217/881 167/218/882 -f 168/219/883 136/186/884 135/185/885 -f 135/185/886 167/218/887 168/219/888 -f 169/220/889 137/187/890 136/186/891 -f 136/186/892 168/219/893 169/220/894 -f 138/221/895 106/188/896 137/187/897 -f 137/187/898 169/220/899 138/221/900 -f 171/223/901 139/190/902 138/189/903 -f 138/189/904 170/222/905 171/223/906 -f 172/224/907 140/191/908 139/190/909 -f 139/190/910 171/223/911 172/224/912 -f 173/225/913 141/192/914 140/191/915 -f 140/191/916 172/224/917 173/225/918 -f 174/226/919 142/193/920 141/192/921 -f 141/192/922 173/225/923 174/226/924 -f 175/227/925 143/194/926 142/193/927 -f 142/193/928 174/226/929 175/227/930 -f 176/228/931 144/195/932 143/194/933 -f 143/194/934 175/227/935 176/228/936 -f 177/229/937 145/196/938 144/195/939 -f 144/195/940 176/228/941 177/229/942 -f 178/230/943 146/197/944 145/196/945 -f 145/196/946 177/229/947 178/230/948 -f 179/231/949 147/198/950 146/197/951 -f 146/197/952 178/230/953 179/231/954 -f 180/232/955 148/199/956 147/198/957 -f 147/198/958 179/231/959 180/232/960 -f 181/233/961 149/200/962 148/199/963 -f 148/199/964 180/232/965 181/233/966 -f 182/234/967 150/201/968 149/200/969 -f 149/200/970 181/233/971 182/234/972 -f 183/235/973 151/202/974 150/201/975 -f 150/201/976 182/234/977 183/235/978 -f 184/236/979 152/203/980 151/202/981 -f 151/202/982 183/235/983 184/236/984 -f 185/237/985 153/204/986 152/203/987 -f 152/203/988 184/236/989 185/237/990 -f 186/238/991 154/205/992 153/204/993 -f 153/204/994 185/237/995 186/238/996 -f 187/239/997 155/206/998 154/205/999 -f 154/205/1000 186/238/1001 187/239/1002 -f 188/240/1003 156/207/1004 155/206/1005 -f 155/206/1006 187/239/1007 188/240/1008 -f 189/241/1009 157/208/1010 156/207/1011 -f 156/207/1012 188/240/1013 189/241/1014 -f 190/242/1015 158/209/1016 157/208/1017 -f 157/208/1018 189/241/1019 190/242/1020 -f 191/243/1021 159/210/1022 158/209/1023 -f 158/209/1024 190/242/1025 191/243/1026 -f 192/244/1027 160/211/1028 159/210/1029 -f 159/210/1030 191/243/1031 192/244/1032 -f 193/245/1033 161/212/1034 160/211/1035 -f 160/211/1036 192/244/1037 193/245/1038 -f 194/246/1039 162/213/1040 161/212/1041 -f 161/212/1042 193/245/1043 194/246/1044 -f 195/247/1045 163/214/1046 162/213/1047 -f 162/213/1048 194/246/1049 195/247/1050 -f 196/248/1051 164/215/1052 163/214/1053 -f 163/214/1054 195/247/1055 196/248/1056 -f 197/249/1057 165/216/1058 164/215/1059 -f 164/215/1060 196/248/1061 197/249/1062 -f 198/250/1063 166/217/1064 165/216/1065 -f 165/216/1066 197/249/1067 198/250/1068 -f 199/251/1069 167/218/1070 166/217/1071 -f 166/217/1072 198/250/1073 199/251/1074 -f 200/252/1075 168/219/1076 167/218/1077 -f 167/218/1078 199/251/1079 200/252/1080 -f 201/253/1081 169/220/1082 168/219/1083 -f 168/219/1084 200/252/1085 201/253/1086 -f 170/254/1087 138/221/1088 169/220/1089 -f 169/220/1090 201/253/1091 170/254/1092 -f 203/256/1093 171/223/1094 170/222/1095 -f 170/222/1096 202/255/1097 203/256/1098 -f 204/257/1099 172/224/1100 171/223/1101 -f 171/223/1102 203/256/1103 204/257/1104 -f 205/258/1105 173/225/1106 172/224/1107 -f 172/224/1108 204/257/1109 205/258/1110 -f 206/259/1111 174/226/1112 173/225/1113 -f 173/225/1114 205/258/1115 206/259/1116 -f 207/260/1117 175/227/1118 174/226/1119 -f 174/226/1120 206/259/1121 207/260/1122 -f 208/261/1123 176/228/1124 175/227/1125 -f 175/227/1126 207/260/1127 208/261/1128 -f 209/262/1129 177/229/1130 176/228/1131 -f 176/228/1132 208/261/1133 209/262/1134 -f 210/263/1135 178/230/1136 177/229/1137 -f 177/229/1138 209/262/1139 210/263/1140 -f 211/264/1141 179/231/1142 178/230/1143 -f 178/230/1144 210/263/1145 211/264/1146 -f 212/265/1147 180/232/1148 179/231/1149 -f 179/231/1150 211/264/1151 212/265/1152 -f 213/266/1153 181/233/1154 180/232/1155 -f 180/232/1156 212/265/1157 213/266/1158 -f 214/267/1159 182/234/1160 181/233/1161 -f 181/233/1162 213/266/1163 214/267/1164 -f 215/268/1165 183/235/1166 182/234/1167 -f 182/234/1168 214/267/1169 215/268/1170 -f 216/269/1171 184/236/1172 183/235/1173 -f 183/235/1174 215/268/1175 216/269/1176 -f 217/270/1177 185/237/1178 184/236/1179 -f 184/236/1180 216/269/1181 217/270/1182 -f 218/271/1183 186/238/1184 185/237/1185 -f 185/237/1186 217/270/1187 218/271/1188 -f 219/272/1189 187/239/1190 186/238/1191 -f 186/238/1192 218/271/1193 219/272/1194 -f 220/273/1195 188/240/1196 187/239/1197 -f 187/239/1198 219/272/1199 220/273/1200 -f 221/274/1201 189/241/1202 188/240/1203 -f 188/240/1204 220/273/1205 221/274/1206 -f 222/275/1207 190/242/1208 189/241/1209 -f 189/241/1210 221/274/1211 222/275/1212 -f 223/276/1213 191/243/1214 190/242/1215 -f 190/242/1216 222/275/1217 223/276/1218 -f 224/277/1219 192/244/1220 191/243/1221 -f 191/243/1222 223/276/1223 224/277/1224 -f 225/278/1225 193/245/1226 192/244/1227 -f 192/244/1228 224/277/1229 225/278/1230 -f 226/279/1231 194/246/1232 193/245/1233 -f 193/245/1234 225/278/1235 226/279/1236 -f 227/280/1237 195/247/1238 194/246/1239 -f 194/246/1240 226/279/1241 227/280/1242 -f 228/281/1243 196/248/1244 195/247/1245 -f 195/247/1246 227/280/1247 228/281/1248 -f 229/282/1249 197/249/1250 196/248/1251 -f 196/248/1252 228/281/1253 229/282/1254 -f 230/283/1255 198/250/1256 197/249/1257 -f 197/249/1258 229/282/1259 230/283/1260 -f 231/284/1261 199/251/1262 198/250/1263 -f 198/250/1264 230/283/1265 231/284/1266 -f 232/285/1267 200/252/1268 199/251/1269 -f 199/251/1270 231/284/1271 232/285/1272 -f 233/286/1273 201/253/1274 200/252/1275 -f 200/252/1276 232/285/1277 233/286/1278 -f 202/287/1279 170/254/1280 201/253/1281 -f 201/253/1282 233/286/1283 202/287/1284 -f 235/289/1285 203/256/1286 202/255/1287 -f 202/255/1288 234/288/1289 235/289/1290 -f 236/290/1291 204/257/1292 203/256/1293 -f 203/256/1294 235/289/1295 236/290/1296 -f 237/291/1297 205/258/1298 204/257/1299 -f 204/257/1300 236/290/1301 237/291/1302 -f 238/292/1303 206/259/1304 205/258/1305 -f 205/258/1306 237/291/1307 238/292/1308 -f 239/293/1309 207/260/1310 206/259/1311 -f 206/259/1312 238/292/1313 239/293/1314 -f 240/294/1315 208/261/1316 207/260/1317 -f 207/260/1318 239/293/1319 240/294/1320 -f 241/295/1321 209/262/1322 208/261/1323 -f 208/261/1324 240/294/1325 241/295/1326 -f 242/296/1327 210/263/1328 209/262/1329 -f 209/262/1330 241/295/1331 242/296/1332 -f 243/297/1333 211/264/1334 210/263/1335 -f 210/263/1336 242/296/1337 243/297/1338 -f 244/298/1339 212/265/1340 211/264/1341 -f 211/264/1342 243/297/1343 244/298/1344 -f 245/299/1345 213/266/1346 212/265/1347 -f 212/265/1348 244/298/1349 245/299/1350 -f 246/300/1351 214/267/1352 213/266/1353 -f 213/266/1354 245/299/1355 246/300/1356 -f 247/301/1357 215/268/1358 214/267/1359 -f 214/267/1360 246/300/1361 247/301/1362 -f 248/302/1363 216/269/1364 215/268/1365 -f 215/268/1366 247/301/1367 248/302/1368 -f 249/303/1369 217/270/1370 216/269/1371 -f 216/269/1372 248/302/1373 249/303/1374 -f 250/304/1375 218/271/1376 217/270/1377 -f 217/270/1378 249/303/1379 250/304/1380 -f 251/305/1381 219/272/1382 218/271/1383 -f 218/271/1384 250/304/1385 251/305/1386 -f 252/306/1387 220/273/1388 219/272/1389 -f 219/272/1390 251/305/1391 252/306/1392 -f 253/307/1393 221/274/1394 220/273/1395 -f 220/273/1396 252/306/1397 253/307/1398 -f 254/308/1399 222/275/1400 221/274/1401 -f 221/274/1402 253/307/1403 254/308/1404 -f 255/309/1405 223/276/1406 222/275/1407 -f 222/275/1408 254/308/1409 255/309/1410 -f 256/310/1411 224/277/1412 223/276/1413 -f 223/276/1414 255/309/1415 256/310/1416 -f 257/311/1417 225/278/1418 224/277/1419 -f 224/277/1420 256/310/1421 257/311/1422 -f 258/312/1423 226/279/1424 225/278/1425 -f 225/278/1426 257/311/1427 258/312/1428 -f 259/313/1429 227/280/1430 226/279/1431 -f 226/279/1432 258/312/1433 259/313/1434 -f 260/314/1435 228/281/1436 227/280/1437 -f 227/280/1438 259/313/1439 260/314/1440 -f 261/315/1441 229/282/1442 228/281/1443 -f 228/281/1444 260/314/1445 261/315/1446 -f 262/316/1447 230/283/1448 229/282/1449 -f 229/282/1450 261/315/1451 262/316/1452 -f 263/317/1453 231/284/1454 230/283/1455 -f 230/283/1456 262/316/1457 263/317/1458 -f 264/318/1459 232/285/1460 231/284/1461 -f 231/284/1462 263/317/1463 264/318/1464 -f 265/319/1465 233/286/1466 232/285/1467 -f 232/285/1468 264/318/1469 265/319/1470 -f 234/320/1471 202/287/1472 233/286/1473 -f 233/286/1474 265/319/1475 234/320/1476 -f 267/322/1477 235/289/1478 234/288/1479 -f 234/288/1480 266/321/1481 267/322/1482 -f 268/323/1483 236/290/1484 235/289/1485 -f 235/289/1486 267/322/1487 268/323/1488 -f 269/324/1489 237/291/1490 236/290/1491 -f 236/290/1492 268/323/1493 269/324/1494 -f 270/325/1495 238/292/1496 237/291/1497 -f 237/291/1498 269/324/1499 270/325/1500 -f 271/326/1501 239/293/1502 238/292/1503 -f 238/292/1504 270/325/1505 271/326/1506 -f 272/327/1507 240/294/1508 239/293/1509 -f 239/293/1510 271/326/1511 272/327/1512 -f 273/328/1513 241/295/1514 240/294/1515 -f 240/294/1516 272/327/1517 273/328/1518 -f 274/329/1519 242/296/1520 241/295/1521 -f 241/295/1522 273/328/1523 274/329/1524 -f 275/330/1525 243/297/1526 242/296/1527 -f 242/296/1528 274/329/1529 275/330/1530 -f 276/331/1531 244/298/1532 243/297/1533 -f 243/297/1534 275/330/1535 276/331/1536 -f 277/332/1537 245/299/1538 244/298/1539 -f 244/298/1540 276/331/1541 277/332/1542 -f 278/333/1543 246/300/1544 245/299/1545 -f 245/299/1546 277/332/1547 278/333/1548 -f 279/334/1549 247/301/1550 246/300/1551 -f 246/300/1552 278/333/1553 279/334/1554 -f 280/335/1555 248/302/1556 247/301/1557 -f 247/301/1558 279/334/1559 280/335/1560 -f 281/336/1561 249/303/1562 248/302/1563 -f 248/302/1564 280/335/1565 281/336/1566 -f 282/337/1567 250/304/1568 249/303/1569 -f 249/303/1570 281/336/1571 282/337/1572 -f 283/338/1573 251/305/1574 250/304/1575 -f 250/304/1576 282/337/1577 283/338/1578 -f 284/339/1579 252/306/1580 251/305/1581 -f 251/305/1582 283/338/1583 284/339/1584 -f 285/340/1585 253/307/1586 252/306/1587 -f 252/306/1588 284/339/1589 285/340/1590 -f 286/341/1591 254/308/1592 253/307/1593 -f 253/307/1594 285/340/1595 286/341/1596 -f 287/342/1597 255/309/1598 254/308/1599 -f 254/308/1600 286/341/1601 287/342/1602 -f 288/343/1603 256/310/1604 255/309/1605 -f 255/309/1606 287/342/1607 288/343/1608 -f 289/344/1609 257/311/1610 256/310/1611 -f 256/310/1612 288/343/1613 289/344/1614 -f 290/345/1615 258/312/1616 257/311/1617 -f 257/311/1618 289/344/1619 290/345/1620 -f 291/346/1621 259/313/1622 258/312/1623 -f 258/312/1624 290/345/1625 291/346/1626 -f 292/347/1627 260/314/1628 259/313/1629 -f 259/313/1630 291/346/1631 292/347/1632 -f 293/348/1633 261/315/1634 260/314/1635 -f 260/314/1636 292/347/1637 293/348/1638 -f 294/349/1639 262/316/1640 261/315/1641 -f 261/315/1642 293/348/1643 294/349/1644 -f 295/350/1645 263/317/1646 262/316/1647 -f 262/316/1648 294/349/1649 295/350/1650 -f 296/351/1651 264/318/1652 263/317/1653 -f 263/317/1654 295/350/1655 296/351/1656 -f 297/352/1657 265/319/1658 264/318/1659 -f 264/318/1660 296/351/1661 297/352/1662 -f 266/353/1663 234/320/1664 265/319/1665 -f 265/319/1666 297/352/1667 266/353/1668 -f 299/355/1669 267/322/1670 266/321/1671 -f 266/321/1672 298/354/1673 299/355/1674 -f 300/356/1675 268/323/1676 267/322/1677 -f 267/322/1678 299/355/1679 300/356/1680 -f 301/357/1681 269/324/1682 268/323/1683 -f 268/323/1684 300/356/1685 301/357/1686 -f 302/358/1687 270/325/1688 269/324/1689 -f 269/324/1690 301/357/1691 302/358/1692 -f 303/359/1693 271/326/1694 270/325/1695 -f 270/325/1696 302/358/1697 303/359/1698 -f 304/360/1699 272/327/1700 271/326/1701 -f 271/326/1702 303/359/1703 304/360/1704 -f 305/361/1705 273/328/1706 272/327/1707 -f 272/327/1708 304/360/1709 305/361/1710 -f 306/362/1711 274/329/1712 273/328/1713 -f 273/328/1714 305/361/1715 306/362/1716 -f 307/363/1717 275/330/1718 274/329/1719 -f 274/329/1720 306/362/1721 307/363/1722 -f 308/364/1723 276/331/1724 275/330/1725 -f 275/330/1726 307/363/1727 308/364/1728 -f 309/365/1729 277/332/1730 276/331/1731 -f 276/331/1732 308/364/1733 309/365/1734 -f 310/366/1735 278/333/1736 277/332/1737 -f 277/332/1738 309/365/1739 310/366/1740 -f 311/367/1741 279/334/1742 278/333/1743 -f 278/333/1744 310/366/1745 311/367/1746 -f 312/368/1747 280/335/1748 279/334/1749 -f 279/334/1750 311/367/1751 312/368/1752 -f 313/369/1753 281/336/1754 280/335/1755 -f 280/335/1756 312/368/1757 313/369/1758 -f 314/370/1759 282/337/1760 281/336/1761 -f 281/336/1762 313/369/1763 314/370/1764 -f 315/371/1765 283/338/1766 282/337/1767 -f 282/337/1768 314/370/1769 315/371/1770 -f 316/372/1771 284/339/1772 283/338/1773 -f 283/338/1774 315/371/1775 316/372/1776 -f 317/373/1777 285/340/1778 284/339/1779 -f 284/339/1780 316/372/1781 317/373/1782 -f 318/374/1783 286/341/1784 285/340/1785 -f 285/340/1786 317/373/1787 318/374/1788 -f 319/375/1789 287/342/1790 286/341/1791 -f 286/341/1792 318/374/1793 319/375/1794 -f 320/376/1795 288/343/1796 287/342/1797 -f 287/342/1798 319/375/1799 320/376/1800 -f 321/377/1801 289/344/1802 288/343/1803 -f 288/343/1804 320/376/1805 321/377/1806 -f 322/378/1807 290/345/1808 289/344/1809 -f 289/344/1810 321/377/1811 322/378/1812 -f 323/379/1813 291/346/1814 290/345/1815 -f 290/345/1816 322/378/1817 323/379/1818 -f 324/380/1819 292/347/1820 291/346/1821 -f 291/346/1822 323/379/1823 324/380/1824 -f 325/381/1825 293/348/1826 292/347/1827 -f 292/347/1828 324/380/1829 325/381/1830 -f 326/382/1831 294/349/1832 293/348/1833 -f 293/348/1834 325/381/1835 326/382/1836 -f 327/383/1837 295/350/1838 294/349/1839 -f 294/349/1840 326/382/1841 327/383/1842 -f 328/384/1843 296/351/1844 295/350/1845 -f 295/350/1846 327/383/1847 328/384/1848 -f 329/385/1849 297/352/1850 296/351/1851 -f 296/351/1852 328/384/1853 329/385/1854 -f 298/386/1855 266/353/1856 297/352/1857 -f 297/352/1858 329/385/1859 298/386/1860 -f 331/388/1861 299/355/1862 298/354/1863 -f 298/354/1864 330/387/1865 331/388/1866 -f 332/389/1867 300/356/1868 299/355/1869 -f 299/355/1870 331/388/1871 332/389/1872 -f 333/390/1873 301/357/1874 300/356/1875 -f 300/356/1876 332/389/1877 333/390/1878 -f 334/391/1879 302/358/1880 301/357/1881 -f 301/357/1882 333/390/1883 334/391/1884 -f 335/392/1885 303/359/1886 302/358/1887 -f 302/358/1888 334/391/1889 335/392/1890 -f 336/393/1891 304/360/1892 303/359/1893 -f 303/359/1894 335/392/1895 336/393/1896 -f 337/394/1897 305/361/1898 304/360/1899 -f 304/360/1900 336/393/1901 337/394/1902 -f 338/395/1903 306/362/1904 305/361/1905 -f 305/361/1906 337/394/1907 338/395/1908 -f 339/396/1909 307/363/1910 306/362/1911 -f 306/362/1912 338/395/1913 339/396/1914 -f 340/397/1915 308/364/1916 307/363/1917 -f 307/363/1918 339/396/1919 340/397/1920 -f 341/398/1921 309/365/1922 308/364/1923 -f 308/364/1924 340/397/1925 341/398/1926 -f 342/399/1927 310/366/1928 309/365/1929 -f 309/365/1930 341/398/1931 342/399/1932 -f 343/400/1933 311/367/1934 310/366/1935 -f 310/366/1936 342/399/1937 343/400/1938 -f 344/401/1939 312/368/1940 311/367/1941 -f 311/367/1942 343/400/1943 344/401/1944 -f 345/402/1945 313/369/1946 312/368/1947 -f 312/368/1948 344/401/1949 345/402/1950 -f 346/403/1951 314/370/1952 313/369/1953 -f 313/369/1954 345/402/1955 346/403/1956 -f 347/404/1957 315/371/1958 314/370/1959 -f 314/370/1960 346/403/1961 347/404/1962 -f 348/405/1963 316/372/1964 315/371/1965 -f 315/371/1966 347/404/1967 348/405/1968 -f 349/406/1969 317/373/1970 316/372/1971 -f 316/372/1972 348/405/1973 349/406/1974 -f 350/407/1975 318/374/1976 317/373/1977 -f 317/373/1978 349/406/1979 350/407/1980 -f 351/408/1981 319/375/1982 318/374/1983 -f 318/374/1984 350/407/1985 351/408/1986 -f 352/409/1987 320/376/1988 319/375/1989 -f 319/375/1990 351/408/1991 352/409/1992 -f 353/410/1993 321/377/1994 320/376/1995 -f 320/376/1996 352/409/1997 353/410/1998 -f 354/411/1999 322/378/2000 321/377/2001 -f 321/377/2002 353/410/2003 354/411/2004 -f 355/412/2005 323/379/2006 322/378/2007 -f 322/378/2008 354/411/2009 355/412/2010 -f 356/413/2011 324/380/2012 323/379/2013 -f 323/379/2014 355/412/2015 356/413/2016 -f 357/414/2017 325/381/2018 324/380/2019 -f 324/380/2020 356/413/2021 357/414/2022 -f 358/415/2023 326/382/2024 325/381/2025 -f 325/381/2026 357/414/2027 358/415/2028 -f 359/416/2029 327/383/2030 326/382/2031 -f 326/382/2032 358/415/2033 359/416/2034 -f 360/417/2035 328/384/2036 327/383/2037 -f 327/383/2038 359/416/2039 360/417/2040 -f 361/418/2041 329/385/2042 328/384/2043 -f 328/384/2044 360/417/2045 361/418/2046 -f 330/419/2047 298/386/2048 329/385/2049 -f 329/385/2050 361/418/2051 330/419/2052 -f 363/421/2053 331/388/2054 330/387/2055 -f 330/387/2056 362/420/2057 363/421/2058 -f 364/422/2059 332/389/2060 331/388/2061 -f 331/388/2062 363/421/2063 364/422/2064 -f 365/423/2065 333/390/2066 332/389/2067 -f 332/389/2068 364/422/2069 365/423/2070 -f 366/424/2071 334/391/2072 333/390/2073 -f 333/390/2074 365/423/2075 366/424/2076 -f 367/425/2077 335/392/2078 334/391/2079 -f 334/391/2080 366/424/2081 367/425/2082 -f 368/426/2083 336/393/2084 335/392/2085 -f 335/392/2086 367/425/2087 368/426/2088 -f 369/427/2089 337/394/2090 336/393/2091 -f 336/393/2092 368/426/2093 369/427/2094 -f 370/428/2095 338/395/2096 337/394/2097 -f 337/394/2098 369/427/2099 370/428/2100 -f 371/429/2101 339/396/2102 338/395/2103 -f 338/395/2104 370/428/2105 371/429/2106 -f 372/430/2107 340/397/2108 339/396/2109 -f 339/396/2110 371/429/2111 372/430/2112 -f 373/431/2113 341/398/2114 340/397/2115 -f 340/397/2116 372/430/2117 373/431/2118 -f 374/432/2119 342/399/2120 341/398/2121 -f 341/398/2122 373/431/2123 374/432/2124 -f 375/433/2125 343/400/2126 342/399/2127 -f 342/399/2128 374/432/2129 375/433/2130 -f 376/434/2131 344/401/2132 343/400/2133 -f 343/400/2134 375/433/2135 376/434/2136 -f 377/435/2137 345/402/2138 344/401/2139 -f 344/401/2140 376/434/2141 377/435/2142 -f 378/436/2143 346/403/2144 345/402/2145 -f 345/402/2146 377/435/2147 378/436/2148 -f 379/437/2149 347/404/2150 346/403/2151 -f 346/403/2152 378/436/2153 379/437/2154 -f 380/438/2155 348/405/2156 347/404/2157 -f 347/404/2158 379/437/2159 380/438/2160 -f 381/439/2161 349/406/2162 348/405/2163 -f 348/405/2164 380/438/2165 381/439/2166 -f 382/440/2167 350/407/2168 349/406/2169 -f 349/406/2170 381/439/2171 382/440/2172 -f 383/441/2173 351/408/2174 350/407/2175 -f 350/407/2176 382/440/2177 383/441/2178 -f 384/442/2179 352/409/2180 351/408/2181 -f 351/408/2182 383/441/2183 384/442/2184 -f 385/443/2185 353/410/2186 352/409/2187 -f 352/409/2188 384/442/2189 385/443/2190 -f 386/444/2191 354/411/2192 353/410/2193 -f 353/410/2194 385/443/2195 386/444/2196 -f 387/445/2197 355/412/2198 354/411/2199 -f 354/411/2200 386/444/2201 387/445/2202 -f 388/446/2203 356/413/2204 355/412/2205 -f 355/412/2206 387/445/2207 388/446/2208 -f 389/447/2209 357/414/2210 356/413/2211 -f 356/413/2212 388/446/2213 389/447/2214 -f 390/448/2215 358/415/2216 357/414/2217 -f 357/414/2218 389/447/2219 390/448/2220 -f 391/449/2221 359/416/2222 358/415/2223 -f 358/415/2224 390/448/2225 391/449/2226 -f 392/450/2227 360/417/2228 359/416/2229 -f 359/416/2230 391/449/2231 392/450/2232 -f 393/451/2233 361/418/2234 360/417/2235 -f 360/417/2236 392/450/2237 393/451/2238 -f 362/452/2239 330/419/2240 361/418/2241 -f 361/418/2242 393/451/2243 362/452/2244 -f 395/454/2245 363/421/2246 362/420/2247 -f 362/420/2248 394/453/2249 395/454/2250 -f 396/455/2251 364/422/2252 363/421/2253 -f 363/421/2254 395/454/2255 396/455/2256 -f 397/456/2257 365/423/2258 364/422/2259 -f 364/422/2260 396/455/2261 397/456/2262 -f 398/457/2263 366/424/2264 365/423/2265 -f 365/423/2266 397/456/2267 398/457/2268 -f 399/458/2269 367/425/2270 366/424/2271 -f 366/424/2272 398/457/2273 399/458/2274 -f 400/459/2275 368/426/2276 367/425/2277 -f 367/425/2278 399/458/2279 400/459/2280 -f 401/460/2281 369/427/2282 368/426/2283 -f 368/426/2284 400/459/2285 401/460/2286 -f 402/461/2287 370/428/2288 369/427/2289 -f 369/427/2290 401/460/2291 402/461/2292 -f 403/462/2293 371/429/2294 370/428/2295 -f 370/428/2296 402/461/2297 403/462/2298 -f 404/463/2299 372/430/2300 371/429/2301 -f 371/429/2302 403/462/2303 404/463/2304 -f 405/464/2305 373/431/2306 372/430/2307 -f 372/430/2308 404/463/2309 405/464/2310 -f 406/465/2311 374/432/2312 373/431/2313 -f 373/431/2314 405/464/2315 406/465/2316 -f 407/466/2317 375/433/2318 374/432/2319 -f 374/432/2320 406/465/2321 407/466/2322 -f 408/467/2323 376/434/2324 375/433/2325 -f 375/433/2326 407/466/2327 408/467/2328 -f 409/468/2329 377/435/2330 376/434/2331 -f 376/434/2332 408/467/2333 409/468/2334 -f 410/469/2335 378/436/2336 377/435/2337 -f 377/435/2338 409/468/2339 410/469/2340 -f 411/470/2341 379/437/2342 378/436/2343 -f 378/436/2344 410/469/2345 411/470/2346 -f 412/471/2347 380/438/2348 379/437/2349 -f 379/437/2350 411/470/2351 412/471/2352 -f 413/472/2353 381/439/2354 380/438/2355 -f 380/438/2356 412/471/2357 413/472/2358 -f 414/473/2359 382/440/2360 381/439/2361 -f 381/439/2362 413/472/2363 414/473/2364 -f 415/474/2365 383/441/2366 382/440/2367 -f 382/440/2368 414/473/2369 415/474/2370 -f 416/475/2371 384/442/2372 383/441/2373 -f 383/441/2374 415/474/2375 416/475/2376 -f 417/476/2377 385/443/2378 384/442/2379 -f 384/442/2380 416/475/2381 417/476/2382 -f 418/477/2383 386/444/2384 385/443/2385 -f 385/443/2386 417/476/2387 418/477/2388 -f 419/478/2389 387/445/2390 386/444/2391 -f 386/444/2392 418/477/2393 419/478/2394 -f 420/479/2395 388/446/2396 387/445/2397 -f 387/445/2398 419/478/2399 420/479/2400 -f 421/480/2401 389/447/2402 388/446/2403 -f 388/446/2404 420/479/2405 421/480/2406 -f 422/481/2407 390/448/2408 389/447/2409 -f 389/447/2410 421/480/2411 422/481/2412 -f 423/482/2413 391/449/2414 390/448/2415 -f 390/448/2416 422/481/2417 423/482/2418 -f 424/483/2419 392/450/2420 391/449/2421 -f 391/449/2422 423/482/2423 424/483/2424 -f 425/484/2425 393/451/2426 392/450/2427 -f 392/450/2428 424/483/2429 425/484/2430 -f 394/485/2431 362/452/2432 393/451/2433 -f 393/451/2434 425/484/2435 394/485/2436 -f 427/487/2437 395/454/2438 394/453/2439 -f 394/453/2440 426/486/2441 427/487/2442 -f 428/488/2443 396/455/2444 395/454/2445 -f 395/454/2446 427/487/2447 428/488/2448 -f 429/489/2449 397/456/2450 396/455/2451 -f 396/455/2452 428/488/2453 429/489/2454 -f 430/490/2455 398/457/2456 397/456/2457 -f 397/456/2458 429/489/2459 430/490/2460 -f 431/491/2461 399/458/2462 398/457/2463 -f 398/457/2464 430/490/2465 431/491/2466 -f 432/492/2467 400/459/2468 399/458/2469 -f 399/458/2470 431/491/2471 432/492/2472 -f 433/493/2473 401/460/2474 400/459/2475 -f 400/459/2476 432/492/2477 433/493/2478 -f 434/494/2479 402/461/2480 401/460/2481 -f 401/460/2482 433/493/2483 434/494/2484 -f 435/495/2485 403/462/2486 402/461/2487 -f 402/461/2488 434/494/2489 435/495/2490 -f 436/496/2491 404/463/2492 403/462/2493 -f 403/462/2494 435/495/2495 436/496/2496 -f 437/497/2497 405/464/2498 404/463/2499 -f 404/463/2500 436/496/2501 437/497/2502 -f 438/498/2503 406/465/2504 405/464/2505 -f 405/464/2506 437/497/2507 438/498/2508 -f 439/499/2509 407/466/2510 406/465/2511 -f 406/465/2512 438/498/2513 439/499/2514 -f 440/500/2515 408/467/2516 407/466/2517 -f 407/466/2518 439/499/2519 440/500/2520 -f 441/501/2521 409/468/2522 408/467/2523 -f 408/467/2524 440/500/2525 441/501/2526 -f 442/502/2527 410/469/2528 409/468/2529 -f 409/468/2530 441/501/2531 442/502/2532 -f 443/503/2533 411/470/2534 410/469/2535 -f 410/469/2536 442/502/2537 443/503/2538 -f 444/504/2539 412/471/2540 411/470/2541 -f 411/470/2542 443/503/2543 444/504/2544 -f 445/505/2545 413/472/2546 412/471/2547 -f 412/471/2548 444/504/2549 445/505/2550 -f 446/506/2551 414/473/2552 413/472/2553 -f 413/472/2554 445/505/2555 446/506/2556 -f 447/507/2557 415/474/2558 414/473/2559 -f 414/473/2560 446/506/2561 447/507/2562 -f 448/508/2563 416/475/2564 415/474/2565 -f 415/474/2566 447/507/2567 448/508/2568 -f 449/509/2569 417/476/2570 416/475/2571 -f 416/475/2572 448/508/2573 449/509/2574 -f 450/510/2575 418/477/2576 417/476/2577 -f 417/476/2578 449/509/2579 450/510/2580 -f 451/511/2581 419/478/2582 418/477/2583 -f 418/477/2584 450/510/2585 451/511/2586 -f 452/512/2587 420/479/2588 419/478/2589 -f 419/478/2590 451/511/2591 452/512/2592 -f 453/513/2593 421/480/2594 420/479/2595 -f 420/479/2596 452/512/2597 453/513/2598 -f 454/514/2599 422/481/2600 421/480/2601 -f 421/480/2602 453/513/2603 454/514/2604 -f 455/515/2605 423/482/2606 422/481/2607 -f 422/481/2608 454/514/2609 455/515/2610 -f 456/516/2611 424/483/2612 423/482/2613 -f 423/482/2614 455/515/2615 456/516/2616 -f 457/517/2617 425/484/2618 424/483/2619 -f 424/483/2620 456/516/2621 457/517/2622 -f 426/518/2623 394/485/2624 425/484/2625 -f 425/484/2626 457/517/2627 426/518/2628 -f 459/520/2629 427/487/2630 426/486/2631 -f 426/486/2632 458/519/2633 459/520/2634 -f 460/521/2635 428/488/2636 427/487/2637 -f 427/487/2638 459/520/2639 460/521/2640 -f 461/522/2641 429/489/2642 428/488/2643 -f 428/488/2644 460/521/2645 461/522/2646 -f 462/523/2647 430/490/2648 429/489/2649 -f 429/489/2650 461/522/2651 462/523/2652 -f 463/524/2653 431/491/2654 430/490/2655 -f 430/490/2656 462/523/2657 463/524/2658 -f 464/525/2659 432/492/2660 431/491/2661 -f 431/491/2662 463/524/2663 464/525/2664 -f 465/526/2665 433/493/2666 432/492/2667 -f 432/492/2668 464/525/2669 465/526/2670 -f 466/527/2671 434/494/2672 433/493/2673 -f 433/493/2674 465/526/2675 466/527/2676 -f 467/528/2677 435/495/2678 434/494/2679 -f 434/494/2680 466/527/2681 467/528/2682 -f 468/529/2683 436/496/2684 435/495/2685 -f 435/495/2686 467/528/2687 468/529/2688 -f 469/530/2689 437/497/2690 436/496/2691 -f 436/496/2692 468/529/2693 469/530/2694 -f 470/531/2695 438/498/2696 437/497/2697 -f 437/497/2698 469/530/2699 470/531/2700 -f 471/532/2701 439/499/2702 438/498/2703 -f 438/498/2704 470/531/2705 471/532/2706 -f 472/533/2707 440/500/2708 439/499/2709 -f 439/499/2710 471/532/2711 472/533/2712 -f 473/534/2713 441/501/2714 440/500/2715 -f 440/500/2716 472/533/2717 473/534/2718 -f 474/535/2719 442/502/2720 441/501/2721 -f 441/501/2722 473/534/2723 474/535/2724 -f 475/536/2725 443/503/2726 442/502/2727 -f 442/502/2728 474/535/2729 475/536/2730 -f 476/537/2731 444/504/2732 443/503/2733 -f 443/503/2734 475/536/2735 476/537/2736 -f 477/538/2737 445/505/2738 444/504/2739 -f 444/504/2740 476/537/2741 477/538/2742 -f 478/539/2743 446/506/2744 445/505/2745 -f 445/505/2746 477/538/2747 478/539/2748 -f 479/540/2749 447/507/2750 446/506/2751 -f 446/506/2752 478/539/2753 479/540/2754 -f 480/541/2755 448/508/2756 447/507/2757 -f 447/507/2758 479/540/2759 480/541/2760 -f 481/542/2761 449/509/2762 448/508/2763 -f 448/508/2764 480/541/2765 481/542/2766 -f 482/543/2767 450/510/2768 449/509/2769 -f 449/509/2770 481/542/2771 482/543/2772 -f 483/544/2773 451/511/2774 450/510/2775 -f 450/510/2776 482/543/2777 483/544/2778 -f 484/545/2779 452/512/2780 451/511/2781 -f 451/511/2782 483/544/2783 484/545/2784 -f 485/546/2785 453/513/2786 452/512/2787 -f 452/512/2788 484/545/2789 485/546/2790 -f 486/547/2791 454/514/2792 453/513/2793 -f 453/513/2794 485/546/2795 486/547/2796 -f 487/548/2797 455/515/2798 454/514/2799 -f 454/514/2800 486/547/2801 487/548/2802 -f 488/549/2803 456/516/2804 455/515/2805 -f 455/515/2806 487/548/2807 488/549/2808 -f 489/550/2809 457/517/2810 456/516/2811 -f 456/516/2812 488/549/2813 489/550/2814 -f 458/551/2815 426/518/2816 457/517/2817 -f 457/517/2818 489/550/2819 458/551/2820 -f 490/552/2821 459/520/2822 458/519/2823 -f 490/553/2824 460/521/2825 459/520/2826 -f 490/554/2827 461/522/2828 460/521/2829 -f 490/555/2830 462/523/2831 461/522/2832 -f 490/556/2833 463/524/2834 462/523/2835 -f 490/557/2836 464/525/2837 463/524/2838 -f 490/558/2839 465/526/2840 464/525/2841 -f 490/559/2842 466/527/2843 465/526/2844 -f 490/560/2845 467/528/2846 466/527/2847 -f 490/561/2848 468/529/2849 467/528/2850 -f 490/562/2851 469/530/2852 468/529/2853 -f 490/563/2854 470/531/2855 469/530/2856 -f 490/564/2857 471/532/2858 470/531/2859 -f 490/565/2860 472/533/2861 471/532/2862 -f 490/566/2863 473/534/2864 472/533/2865 -f 490/567/2866 474/535/2867 473/534/2868 -f 490/568/2869 475/536/2870 474/535/2871 -f 490/569/2872 476/537/2873 475/536/2874 -f 490/570/2875 477/538/2876 476/537/2877 -f 490/571/2878 478/539/2879 477/538/2880 -f 490/572/2881 479/540/2882 478/539/2883 -f 490/573/2884 480/541/2885 479/540/2886 -f 490/574/2887 481/542/2888 480/541/2889 -f 490/575/2890 482/543/2891 481/542/2892 -f 490/576/2893 483/544/2894 482/543/2895 -f 490/577/2896 484/545/2897 483/544/2898 -f 490/578/2899 485/546/2900 484/545/2901 -f 490/579/2902 486/547/2903 485/546/2904 -f 490/580/2905 487/548/2906 486/547/2907 -f 490/581/2908 488/549/2909 487/548/2910 -f 490/582/2911 489/550/2912 488/549/2913 -f 490/583/2914 458/551/2915 489/550/2916 -f 491/584/2917 492/585/2918 516/609/2919 -f 516/609/2920 515/608/2921 491/584/2922 -f 492/585/2923 493/586/2924 517/610/2925 -f 517/610/2926 516/609/2927 492/585/2928 -f 493/586/2929 494/587/2930 518/611/2931 -f 518/611/2932 517/610/2933 493/586/2934 -f 494/587/2935 495/588/2936 519/612/2937 -f 519/612/2938 518/611/2939 494/587/2940 -f 495/588/2941 496/589/2942 520/613/2943 -f 520/613/2944 519/612/2945 495/588/2946 -f 496/589/2947 497/590/2948 521/614/2949 -f 521/614/2950 520/613/2951 496/589/2952 -f 497/590/2953 498/728/2954 522/729/2955 -f 522/729/2956 521/614/2957 497/590/2958 -f 498/591/2959 499/592/2960 523/616/2961 -f 523/616/2962 522/615/2963 498/591/2964 -f 499/592/2965 500/593/2966 524/617/2967 -f 524/617/2968 523/616/2969 499/592/2970 -f 500/593/2971 501/594/2972 525/618/2973 -f 525/618/2974 524/617/2975 500/593/2976 -f 501/594/2977 502/595/2978 526/619/2979 -f 526/619/2980 525/618/2981 501/594/2982 -f 502/595/2983 503/596/2984 527/620/2985 -f 527/620/2986 526/619/2987 502/595/2988 -f 503/596/2989 504/597/2990 528/621/2991 -f 528/621/2992 527/620/2993 503/596/2994 -f 504/597/2995 505/598/2996 529/622/2997 -f 529/622/2998 528/621/2999 504/597/3000 -f 505/598/3001 506/599/3002 530/623/3003 -f 530/623/3004 529/622/3005 505/598/3006 -f 506/599/3007 507/600/3008 531/624/3009 -f 531/624/3010 530/623/3011 506/599/3012 -f 507/600/3013 508/601/3014 532/625/3015 -f 532/625/3016 531/624/3017 507/600/3018 -f 508/601/3019 509/602/3020 533/626/3021 -f 533/626/3022 532/625/3023 508/601/3024 -f 509/602/3025 510/603/3026 534/627/3027 -f 534/627/3028 533/626/3029 509/602/3030 -f 510/603/3031 511/604/3032 535/628/3033 -f 535/628/3034 534/627/3035 510/603/3036 -f 511/604/3037 512/605/3038 536/629/3039 -f 536/629/3040 535/628/3041 511/604/3042 -f 512/605/3043 513/606/3044 537/630/3045 -f 537/630/3046 536/629/3047 512/605/3048 -f 513/606/3049 514/607/3050 538/631/3051 -f 538/631/3052 537/630/3053 513/606/3054 -f 514/607/3055 491/584/3056 515/608/3057 -f 515/608/3058 538/631/3059 514/607/3060 -f 515/608/3061 516/609/3062 540/633/3063 -f 540/633/3064 539/632/3065 515/608/3066 -f 516/609/3067 517/610/3068 541/634/3069 -f 541/634/3070 540/633/3071 516/609/3072 -f 517/610/3073 518/611/3074 542/635/3075 -f 542/635/3076 541/634/3077 517/610/3078 -f 518/611/3079 519/612/3080 543/636/3081 -f 543/636/3082 542/635/3083 518/611/3084 -f 519/612/3085 520/613/3086 544/637/3087 -f 544/637/3088 543/636/3089 519/612/3090 -f 520/613/3091 521/614/3092 545/638/3093 -f 545/638/3094 544/637/3095 520/613/3096 -f 521/614/3097 522/729/3098 546/730/3099 -f 546/730/3100 545/638/3101 521/614/3102 -f 522/615/3103 523/616/3104 547/640/3105 -f 547/640/3106 546/639/3107 522/615/3108 -f 523/616/3109 524/617/3110 548/641/3111 -f 548/641/3112 547/640/3113 523/616/3114 -f 524/617/3115 525/618/3116 549/642/3117 -f 549/642/3118 548/641/3119 524/617/3120 -f 525/618/3121 526/619/3122 550/643/3123 -f 550/643/3124 549/642/3125 525/618/3126 -f 526/619/3127 527/620/3128 551/644/3129 -f 551/644/3130 550/643/3131 526/619/3132 -f 527/620/3133 528/621/3134 552/645/3135 -f 552/645/3136 551/644/3137 527/620/3138 -f 528/621/3139 529/622/3140 553/646/3141 -f 553/646/3142 552/645/3143 528/621/3144 -f 529/622/3145 530/623/3146 554/647/3147 -f 554/647/3148 553/646/3149 529/622/3150 -f 530/623/3151 531/624/3152 555/648/3153 -f 555/648/3154 554/647/3155 530/623/3156 -f 531/624/3157 532/625/3158 556/649/3159 -f 556/649/3160 555/648/3161 531/624/3162 -f 532/625/3163 533/626/3164 557/650/3165 -f 557/650/3166 556/649/3167 532/625/3168 -f 533/626/3169 534/627/3170 558/651/3171 -f 558/651/3172 557/650/3173 533/626/3174 -f 534/627/3175 535/628/3176 559/652/3177 -f 559/652/3178 558/651/3179 534/627/3180 -f 535/628/3181 536/629/3182 560/653/3183 -f 560/653/3184 559/652/3185 535/628/3186 -f 536/629/3187 537/630/3188 561/654/3189 -f 561/654/3190 560/653/3191 536/629/3192 -f 537/630/3193 538/631/3194 562/655/3195 -f 562/655/3196 561/654/3197 537/630/3198 -f 538/631/3199 515/608/3200 539/632/3201 -f 539/632/3202 562/655/3203 538/631/3204 -f 539/632/3205 540/633/3206 564/657/3207 -f 564/657/3208 563/656/3209 539/632/3210 -f 540/633/3211 541/634/3212 565/658/3213 -f 565/658/3214 564/657/3215 540/633/3216 -f 541/634/3217 542/635/3218 566/659/3219 -f 566/659/3220 565/658/3221 541/634/3222 -f 542/635/3223 543/636/3224 567/660/3225 -f 567/660/3226 566/659/3227 542/635/3228 -f 543/636/3229 544/637/3230 568/661/3231 -f 568/661/3232 567/660/3233 543/636/3234 -f 544/637/3235 545/638/3236 569/662/3237 -f 569/662/3238 568/661/3239 544/637/3240 -f 545/638/3241 546/730/3242 570/731/3243 -f 570/731/3244 569/662/3245 545/638/3246 -f 546/639/3247 547/640/3248 571/664/3249 -f 571/664/3250 570/663/3251 546/639/3252 -f 547/640/3253 548/641/3254 572/665/3255 -f 572/665/3256 571/664/3257 547/640/3258 -f 548/641/3259 549/642/3260 573/666/3261 -f 573/666/3262 572/665/3263 548/641/3264 -f 549/642/3265 550/643/3266 574/667/3267 -f 574/667/3268 573/666/3269 549/642/3270 -f 550/643/3271 551/644/3272 575/668/3273 -f 575/668/3274 574/667/3275 550/643/3276 -f 551/644/3277 552/645/3278 576/669/3279 -f 576/669/3280 575/668/3281 551/644/3282 -f 552/645/3283 553/646/3284 577/670/3285 -f 577/670/3286 576/669/3287 552/645/3288 -f 553/646/3289 554/647/3290 578/671/3291 -f 578/671/3292 577/670/3293 553/646/3294 -f 554/647/3295 555/648/3296 579/672/3297 -f 579/672/3298 578/671/3299 554/647/3300 -f 555/648/3301 556/649/3302 580/673/3303 -f 580/673/3304 579/672/3305 555/648/3306 -f 556/649/3307 557/650/3308 581/674/3309 -f 581/674/3310 580/673/3311 556/649/3312 -f 557/650/3313 558/651/3314 582/675/3315 -f 582/675/3316 581/674/3317 557/650/3318 -f 558/651/3319 559/652/3320 583/676/3321 -f 583/676/3322 582/675/3323 558/651/3324 -f 559/652/3325 560/653/3326 584/677/3327 -f 584/677/3328 583/676/3329 559/652/3330 -f 560/653/3331 561/654/3332 585/678/3333 -f 585/678/3334 584/677/3335 560/653/3336 -f 561/654/3337 562/655/3338 586/679/3339 -f 586/679/3340 585/678/3341 561/654/3342 -f 562/655/3343 539/632/3344 563/656/3345 -f 563/656/3346 586/679/3347 562/655/3348 -f 563/656/3349 564/657/3350 588/681/3351 -f 588/681/3352 587/680/3353 563/656/3354 -f 564/657/3355 565/658/3356 589/682/3357 -f 589/682/3358 588/681/3359 564/657/3360 -f 565/658/3361 566/659/3362 590/683/3363 -f 590/683/3364 589/682/3365 565/658/3366 -f 566/659/3367 567/660/3368 591/684/3369 -f 591/684/3370 590/683/3371 566/659/3372 -f 567/660/3373 568/661/3374 592/685/3375 -f 592/685/3376 591/684/3377 567/660/3378 -f 568/661/3379 569/662/3380 593/686/3381 -f 593/686/3382 592/685/3383 568/661/3384 -f 569/662/3385 570/731/3386 594/732/3387 -f 594/732/3388 593/686/3389 569/662/3390 -f 570/663/3391 571/664/3392 595/688/3393 -f 595/688/3394 594/687/3395 570/663/3396 -f 571/664/3397 572/665/3398 596/689/3399 -f 596/689/3400 595/688/3401 571/664/3402 -f 572/665/3403 573/666/3404 597/690/3405 -f 597/690/3406 596/689/3407 572/665/3408 -f 573/666/3409 574/667/3410 598/691/3411 -f 598/691/3412 597/690/3413 573/666/3414 -f 574/667/3415 575/668/3416 599/692/3417 -f 599/692/3418 598/691/3419 574/667/3420 -f 575/668/3421 576/669/3422 600/693/3423 -f 600/693/3424 599/692/3425 575/668/3426 -f 576/669/3427 577/670/3428 601/694/3429 -f 601/694/3430 600/693/3431 576/669/3432 -f 577/670/3433 578/671/3434 602/695/3435 -f 602/695/3436 601/694/3437 577/670/3438 -f 578/671/3439 579/672/3440 603/696/3441 -f 603/696/3442 602/695/3443 578/671/3444 -f 579/672/3445 580/673/3446 604/697/3447 -f 604/697/3448 603/696/3449 579/672/3450 -f 580/673/3451 581/674/3452 605/698/3453 -f 605/698/3454 604/697/3455 580/673/3456 -f 581/674/3457 582/675/3458 606/699/3459 -f 606/699/3460 605/698/3461 581/674/3462 -f 582/675/3463 583/676/3464 607/700/3465 -f 607/700/3466 606/699/3467 582/675/3468 -f 583/676/3469 584/677/3470 608/701/3471 -f 608/701/3472 607/700/3473 583/676/3474 -f 584/677/3475 585/678/3476 609/702/3477 -f 609/702/3478 608/701/3479 584/677/3480 -f 585/678/3481 586/679/3482 610/703/3483 -f 610/703/3484 609/702/3485 585/678/3486 -f 586/679/3487 563/656/3488 587/680/3489 -f 587/680/3490 610/703/3491 586/679/3492 -f 587/680/3493 588/681/3494 612/705/3495 -f 612/705/3496 611/704/3497 587/680/3498 -f 588/681/3499 589/682/3500 613/706/3501 -f 613/706/3502 612/705/3503 588/681/3504 -f 589/682/3505 590/683/3506 614/707/3507 -f 614/707/3508 613/706/3509 589/682/3510 -f 590/683/3511 591/684/3512 615/708/3513 -f 615/708/3514 614/707/3515 590/683/3516 -f 591/684/3517 592/685/3518 616/709/3519 -f 616/709/3520 615/708/3521 591/684/3522 -f 592/685/3523 593/686/3524 617/710/3525 -f 617/710/3526 616/709/3527 592/685/3528 -f 593/735/3529 594/732/3530 618/733/3531 -f 618/733/3532 617/734/3533 593/735/3534 -f 594/687/3535 595/688/3536 619/712/3537 -f 619/712/3538 618/711/3539 594/687/3540 -f 595/688/3541 596/689/3542 620/713/3543 -f 620/713/3544 619/712/3545 595/688/3546 -f 596/689/3547 597/690/3548 621/714/3549 -f 621/714/3550 620/713/3551 596/689/3552 -f 597/690/3553 598/691/3554 622/715/3555 -f 622/715/3556 621/714/3557 597/690/3558 -f 598/691/3559 599/692/3560 623/716/3561 -f 623/716/3562 622/715/3563 598/691/3564 -f 599/692/3565 600/693/3566 624/717/3567 -f 624/717/3568 623/716/3569 599/692/3570 -f 600/693/3571 601/694/3572 625/718/3573 -f 625/718/3574 624/717/3575 600/693/3576 -f 601/694/3577 602/695/3578 626/719/3579 -f 626/719/3580 625/718/3581 601/694/3582 -f 602/695/3583 603/696/3584 627/720/3585 -f 627/720/3586 626/719/3587 602/695/3588 -f 603/696/3589 604/697/3590 628/721/3591 -f 628/721/3592 627/720/3593 603/696/3594 -f 604/697/3595 605/698/3596 629/722/3597 -f 629/722/3598 628/721/3599 604/697/3600 -f 605/698/3601 606/699/3602 630/723/3603 -f 630/723/3604 629/722/3605 605/698/3606 -f 606/699/3607 607/700/3608 631/724/3609 -f 631/724/3610 630/723/3611 606/699/3612 -f 607/700/3613 608/701/3614 632/725/3615 -f 632/725/3616 631/724/3617 607/700/3618 -f 608/701/3619 609/702/3620 633/726/3621 -f 633/726/3622 632/725/3623 608/701/3624 -f 609/702/3625 610/703/3626 634/727/3627 -f 634/727/3628 633/726/3629 609/702/3630 -f 610/703/3631 587/680/3632 611/704/3633 -f 611/704/3634 634/727/3635 610/703/3636 -f 513/737/3637 512/738/3638 511/739/3639 -f 511/739/3640 510/740/3641 509/741/3642 -f 509/741/3643 508/742/3644 507/743/3645 -f 511/739/3646 509/741/3647 507/743/3648 -f 507/743/3649 506/744/3650 505/745/3651 -f 505/745/3652 504/746/3653 503/747/3654 -f 507/743/3655 505/745/3656 503/747/3657 -f 503/747/3658 502/748/3659 501/749/3660 -f 501/749/3661 500/750/3662 499/751/3663 -f 503/747/3664 501/749/3665 499/751/3666 -f 507/743/3667 503/747/3668 499/751/3669 -f 499/751/3670 498/752/3671 497/753/3672 -f 497/753/3673 496/754/3674 495/755/3675 -f 499/751/3676 497/753/3677 495/755/3678 -f 495/755/3679 494/756/3680 493/757/3681 -f 493/757/3682 492/758/3683 491/759/3684 -f 495/755/3685 493/757/3686 491/759/3687 -f 499/751/3688 495/755/3689 491/759/3690 -f 507/743/3691 499/751/3692 491/759/3693 -f 511/739/3694 507/743/3695 491/759/3696 -f 513/737/3697 511/739/3698 491/759/3699 -f 514/736/3700 513/737/3701 491/759/3702 -f 612/705/3703 613/706/3704 614/707/3705 -f 614/707/3706 615/708/3707 616/709/3708 -f 616/709/3709 617/710/3710 618/711/3711 -f 614/707/3712 616/709/3713 618/711/3714 -f 618/711/3715 619/712/3716 620/713/3717 -f 620/713/3718 621/714/3719 622/715/3720 -f 618/711/3721 620/713/3722 622/715/3723 -f 622/715/3724 623/716/3725 624/717/3726 -f 624/717/3727 625/718/3728 626/719/3729 -f 622/715/3730 624/717/3731 626/719/3732 -f 618/711/3733 622/715/3734 626/719/3735 -f 626/719/3736 627/720/3737 628/721/3738 -f 628/721/3739 629/722/3740 630/723/3741 -f 626/719/3742 628/721/3743 630/723/3744 -f 630/723/3745 631/724/3746 632/725/3747 -f 632/725/3748 633/726/3749 634/727/3750 -f 630/723/3751 632/725/3752 634/727/3753 -f 626/719/3754 630/723/3755 634/727/3756 -f 618/711/3757 626/719/3758 634/727/3759 -f 614/707/3760 618/711/3761 634/727/3762 -f 612/705/3763 614/707/3764 634/727/3765 -f 611/704/3766 612/705/3767 634/727/3768 -# 1256 faces - -- cgit v1.2.3 From 5c32cf20959e5457665c8da904e4528ccb255e53 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Mon, 30 May 2016 19:19:15 +0200 Subject: Add 'dwarf' model normal and specular maps to resources folder --- examples/resources/model/dwarf_normal.png | Bin 0 -> 4053623 bytes examples/resources/model/dwarf_specular.png | Bin 0 -> 2938756 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 examples/resources/model/dwarf_normal.png create mode 100644 examples/resources/model/dwarf_specular.png (limited to 'examples/resources') diff --git a/examples/resources/model/dwarf_normal.png b/examples/resources/model/dwarf_normal.png new file mode 100644 index 00000000..ae2babfd Binary files /dev/null and b/examples/resources/model/dwarf_normal.png differ diff --git a/examples/resources/model/dwarf_specular.png b/examples/resources/model/dwarf_specular.png new file mode 100644 index 00000000..5f51039f Binary files /dev/null and b/examples/resources/model/dwarf_specular.png differ -- cgit v1.2.3 From 11cf455fe0d2c956043aa70f7d8256c4a339b430 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Mon, 30 May 2016 19:59:21 +0200 Subject: Standard Lighting (3/3) - Added normal and specular maps to standard shader. - Added full tint attribute to standard shader and material data type. - Changed point light attenuation to radius. --- examples/resources/shaders/standard.fs | 44 ++++++++++++++++++++++++---------- examples/shaders_standard_lighting.c | 8 +++---- 2 files changed, 34 insertions(+), 18 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/standard.fs b/examples/resources/shaders/standard.fs index 3c3bef4b..bb9e6865 100644 --- a/examples/resources/shaders/standard.fs +++ b/examples/resources/shaders/standard.fs @@ -8,12 +8,18 @@ in vec3 fragNormal; out vec4 finalColor; uniform sampler2D texture0; +uniform sampler2D texture1; +uniform sampler2D texture2; +uniform vec4 colTint; uniform vec4 colAmbient; uniform vec4 colDiffuse; uniform vec4 colSpecular; uniform float glossiness; +uniform int useNormal; +uniform int useSpecular; + uniform mat4 modelMatrix; uniform vec3 viewDir; @@ -24,7 +30,7 @@ struct Light { vec3 direction; vec4 diffuse; float intensity; - float attenuation; + float radius; float coneAngle; }; @@ -32,27 +38,27 @@ const int maxLights = 8; uniform int lightsCount; uniform Light lights[maxLights]; -vec3 CalcPointLight(Light l, vec3 n, vec3 v) +vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) { vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); vec3 surfaceToLight = l.position - surfacePos; // Diffuse shading float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1); - float diff = 1.0/dot(surfaceToLight/l.attenuation, surfaceToLight/l.attenuation)*brightness*l.intensity; + float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; // Specular shading float spec = 0.0; if (diff > 0.0) { vec3 h = normalize(-l.direction + v); - spec = pow(dot(n, h), 3 + glossiness); + spec = pow(dot(n, h), 3 + glossiness)*s; } return (diff*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb); } -vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v) +vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) { vec3 lightDir = normalize(-l.direction); @@ -64,14 +70,14 @@ vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v) if (diff > 0.0) { vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3 + glossiness); + spec = pow(dot(n, h), 3 + glossiness)*s; } // Combine results return (diff*l.intensity*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb); } -vec3 CalcSpotLight(Light l, vec3 n, vec3 v) +vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) { vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); vec3 lightToSurface = normalize(surfacePos - l.position); @@ -95,7 +101,7 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v) if (diffAttenuation > 0.0) { vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3 + glossiness); + spec = pow(dot(n, h), 3 + glossiness)*s; } return falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb); @@ -104,9 +110,10 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v) void main() { // Calculate fragment normal in screen space + // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); vec3 normal = normalize(normalMatrix*fragNormal); - + // Normalize normal and view direction vectors vec3 n = normalize(normal); vec3 v = normalize(viewDir); @@ -115,6 +122,17 @@ void main() vec4 texelColor = texture(texture0, fragTexCoord); vec3 lighting = colAmbient.rgb; + // Calculate normal texture color fetching or set to maximum normal value by default + if(useNormal == 1) + { + n *= texture(texture1, fragTexCoord).rgb; + n = normalize(n); + } + + // Calculate specular texture color fetching or set to maximum specular value by default + float spec = 1.0; + if(useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); + for (int i = 0; i < lightsCount; i++) { // Check if light is enabled @@ -123,14 +141,14 @@ void main() // Calculate lighting based on light type switch (lights[i].type) { - case 0: lighting += CalcPointLight(lights[i], n, v); break; - case 1: lighting += CalcDirectionalLight(lights[i], n, v); break; - case 2: lighting += CalcSpotLight(lights[i], n, v); break; + case 0: lighting += CalcPointLight(lights[i], n, v, spec); break; + case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break; + case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break; default: break; } } } // Calculate final fragment color - finalColor = vec4(texelColor.rgb*lighting, texelColor.a); + finalColor = vec4(texelColor.rgb*lighting*colTint.rgb, texelColor.a*colTint.a); } diff --git a/examples/shaders_standard_lighting.c b/examples/shaders_standard_lighting.c index 6f45ca61..6b5cd9f5 100644 --- a/examples/shaders_standard_lighting.c +++ b/examples/shaders_standard_lighting.c @@ -69,8 +69,6 @@ int main() SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode SetCameraPosition(camera.position); // Set internal camera position to match our camera position SetCameraTarget(camera.target); // Set internal camera target to match our camera target - - float framesCounter = 0; // Define frames counter to update model rotation SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -81,8 +79,6 @@ int main() // Update //---------------------------------------------------------------------------------- UpdateCamera(&camera); // Update internal camera and our camera - - framesCounter += 0.5f; //---------------------------------------------------------------------------------- // Draw @@ -93,7 +89,7 @@ int main() Begin3dMode(camera); - DrawModelEx(dwarf, position, (Vector3){ 0.0f, 1.0f, 0.0f }, framesCounter, (Vector3){ 2.0f, 2.0f, 2.0f}, RED); // Draw 3d model with texture + DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture DrawLights(); // Draw all created lights in 3D world @@ -102,6 +98,8 @@ int main() End3dMode(); DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY); + + DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- -- cgit v1.2.3 From 302ec438dd8a5483e4fcf81d4bd80ac7d09e6a61 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 31 May 2016 18:15:53 +0200 Subject: Removed colTint, tint color is colDiffuse Tint color could be applied to colDiffuse... but what's the best way? Replace it? Multiply by? A point to think about... --- examples/resources/shaders/glsl330/grayscale.fs | 4 ++-- examples/resources/shaders/standard.fs | 7 +++---- examples/shaders_standard_lighting.c | 4 ++-- src/models.c | 5 ++--- src/raylib.h | 1 - src/rlgl.c | 3 --- src/rlgl.h | 21 ++++++++++----------- 7 files changed, 19 insertions(+), 26 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl330/grayscale.fs b/examples/resources/shaders/glsl330/grayscale.fs index d4a8824f..5b3e11be 100644 --- a/examples/resources/shaders/glsl330/grayscale.fs +++ b/examples/resources/shaders/glsl330/grayscale.fs @@ -6,7 +6,7 @@ in vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // Output fragment color out vec4 finalColor; @@ -16,7 +16,7 @@ out vec4 finalColor; void main() { // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor; + vec4 texelColor = texture(texture0, fragTexCoord)*colDiffuse*fragColor; // Convert texel color to grayscale using NTSC conversion weights float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); diff --git a/examples/resources/shaders/standard.fs b/examples/resources/shaders/standard.fs index bb9e6865..e5916031 100644 --- a/examples/resources/shaders/standard.fs +++ b/examples/resources/shaders/standard.fs @@ -11,7 +11,6 @@ uniform sampler2D texture0; uniform sampler2D texture1; uniform sampler2D texture2; -uniform vec4 colTint; uniform vec4 colAmbient; uniform vec4 colDiffuse; uniform vec4 colSpecular; @@ -55,7 +54,7 @@ vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) spec = pow(dot(n, h), 3 + glossiness)*s; } - return (diff*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb); + return (diff*l.diffuse.rgb + spec*colSpecular.rgb); } vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) @@ -74,7 +73,7 @@ vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) } // Combine results - return (diff*l.intensity*l.diffuse.rgb*colDiffuse.rgb + spec*colSpecular.rgb); + return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); } vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) @@ -150,5 +149,5 @@ void main() } // Calculate final fragment color - finalColor = vec4(texelColor.rgb*lighting*colTint.rgb, texelColor.a*colTint.a); + finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); } diff --git a/examples/shaders_standard_lighting.c b/examples/shaders_standard_lighting.c index 10416f7f..ccbe74ca 100644 --- a/examples/shaders_standard_lighting.c +++ b/examples/shaders_standard_lighting.c @@ -40,9 +40,9 @@ int main() material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture material.texNormal = LoadTexture("resources/model/dwarf_normal.png"); // Load model normal texture material.texSpecular = LoadTexture("resources/model/dwarf_specular.png"); // Load model specular texture - material.colDiffuse = (Color){255, 255, 255, 255}; + material.colDiffuse = WHITE; material.colAmbient = (Color){0, 0, 10, 255}; - material.colSpecular = (Color){255, 255, 255, 255}; + material.colSpecular = WHITE; material.glossiness = 50.0f; dwarf.material = material; // Apply material to model diff --git a/src/models.c b/src/models.c index 8c5ed914..962a6470 100644 --- a/src/models.c +++ b/src/models.c @@ -779,8 +779,7 @@ Material LoadDefaultMaterial(void) material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel) //material.texNormal; // NOTE: By default, not set //material.texSpecular; // NOTE: By default, not set - - material.colTint = WHITE; // Tint color + material.colDiffuse = WHITE; // Diffuse color material.colAmbient = WHITE; // Ambient color material.colSpecular = WHITE; // Specular color @@ -1298,7 +1297,7 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota //Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation); - model.material.colTint = tint; + model.material.colDiffuse = tint; // TODO: Multiply tint color by diffuse color? rlglDrawMesh(model.mesh, model.material, model.transform); } diff --git a/src/raylib.h b/src/raylib.h index 5bef3698..271c0e42 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -414,7 +414,6 @@ typedef struct Material { Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc) Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc) - Color colTint; // Tint color Color colDiffuse; // Diffuse color Color colAmbient; // Ambient color Color colSpecular; // Specular color diff --git a/src/rlgl.c b/src/rlgl.c index 5c4c9c01..6a2adeb2 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -1800,9 +1800,6 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) // Setup shader uniforms for lights SetShaderLights(material.shader); - // Upload to shader material.colSpecular - glUniform4f(glGetUniformLocation(material.shader.id, "colTint"), (float)material.colTint.r/255, (float)material.colTint.g/255, (float)material.colTint.b/255, (float)material.colTint.a/255); - // Upload to shader material.colAmbient glUniform4f(glGetUniformLocation(material.shader.id, "colAmbient"), (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255); diff --git a/src/rlgl.h b/src/rlgl.h index ccf2b36a..336f6019 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -201,8 +201,7 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; Texture2D texDiffuse; // Diffuse texture Texture2D texNormal; // Normal texture Texture2D texSpecular; // Specular texture - - Color colTint; // Tint color + Color colDiffuse; // Diffuse color Color colAmbient; // Ambient color Color colSpecular; // Specular color @@ -212,18 +211,18 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; // Light type typedef struct LightData { - int id; - int type; // LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT - bool enabled; + unsigned int id; // Light id + int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT + bool enabled; // Light enabled - Vector3 position; - Vector3 target; // Used on LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) - float radius; // Lost of light intensity with distance (world distance) + Vector3 position; // Light position + Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) + float radius; // Light attenuation radius light intensity reduced with distance (world distance) - Color diffuse; // Use Vector3 diffuse - float intensity; + Color diffuse; // Light diffuse color + float intensity; // Light intensity level - float coneAngle; // Spot light max angle + float coneAngle; // Light cone max angle: LIGHT_SPOT } LightData, *Light; // Color blending modes (pre-defined) -- cgit v1.2.3 From d17a0cee1aa53978387e68be58d901bffd1ac0a9 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 31 May 2016 19:12:37 +0200 Subject: Review text formatting (spacing, tabs...) --- examples/resources/shaders/standard.fs | 8 ++- src/core.c | 18 +++--- src/raylib.h | 96 +++++++++++++++--------------- src/raymath.h | 2 +- src/rlgl.c | 2 +- src/rlgl.h | 103 +++++++++++++++++---------------- src/shapes.c | 2 +- 7 files changed, 117 insertions(+), 114 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/standard.fs b/examples/resources/shaders/standard.fs index e5916031..e5a6d1bc 100644 --- a/examples/resources/shaders/standard.fs +++ b/examples/resources/shaders/standard.fs @@ -88,8 +88,10 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) // Spot attenuation float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); attenuation = dot(lightToSurface, -lightDir); + float lightToSurfaceAngle = degrees(acos(attenuation)); if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; // Combine diffuse and attenuation @@ -103,7 +105,7 @@ vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) spec = pow(dot(n, h), 3 + glossiness)*s; } - return falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb); + return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); } void main() @@ -122,7 +124,7 @@ void main() vec3 lighting = colAmbient.rgb; // Calculate normal texture color fetching or set to maximum normal value by default - if(useNormal == 1) + if (useNormal == 1) { n *= texture(texture1, fragTexCoord).rgb; n = normalize(n); @@ -130,7 +132,7 @@ void main() // Calculate specular texture color fetching or set to maximum specular value by default float spec = 1.0; - if(useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); + if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); for (int i = 0; i < lightsCount; i++) { diff --git a/src/core.c b/src/core.c index 70dfa7a5..7bd44c81 100644 --- a/src/core.c +++ b/src/core.c @@ -2078,10 +2078,10 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int gestureEvent.position[0] = GetMousePosition(); // Normalize gestureEvent.position[0] for screenWidth and screenHeight - gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].x /= (float)GetScreenWidth(); gestureEvent.position[0].y /= (float)GetScreenHeight(); - - // Gesture data is sent to gestures system for processing + + // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); #endif } @@ -2223,10 +2223,10 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // Load default font for convenience // NOTE: External function (defined in module: text) LoadDefaultFont(); - + // TODO: GPU assets reload in case of lost focus (lost context) // NOTE: This problem has been solved just unbinding and rebinding context from display - /* + /* if (assetsReloadRequired) { for (int i = 0; i < assetsCount; i++) @@ -2759,9 +2759,9 @@ static void *GamepadThread(void *arg) }; // Read gamepad event - struct js_event gamepadEvent; + struct js_event gamepadEvent; - while (1) + while (1) { for (int i = 0; i < MAX_GAMEPADS; i++) { @@ -2792,8 +2792,8 @@ static void *GamepadThread(void *arg) } } } - } - + } + return NULL; } #endif diff --git a/src/raylib.h b/src/raylib.h index 271c0e42..1ef0a98e 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -349,7 +349,7 @@ typedef struct Camera { Vector3 position; // Camera position Vector3 target; // Camera target it looks-at Vector3 up; // Camera up vector (rotation over its axis) - float fovy; // Field-Of-View apperture in Y (degrees) + float fovy; // Camera field-of-view apperture in Y (degrees) } Camera; // Camera2D type, defines a 2d camera @@ -362,86 +362,84 @@ typedef struct Camera2D { // Bounding box type typedef struct BoundingBox { - Vector3 min; - Vector3 max; + Vector3 min; // minimum vertex box-corner + Vector3 max; // maximum vertex box-corner } BoundingBox; // Vertex data definning a mesh typedef struct Mesh { - int vertexCount; // number of vertices stored in arrays - int triangleCount; // number of triangles stored (indexed or not) - float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0) - float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) - float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5) - float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2) - float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4) - unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3) - unsigned short *indices; // vertex indices (in case vertex data comes indexed) - - BoundingBox bounds; // mesh limits defined by min and max points - - unsigned int vaoId; // OpenGL Vertex Array Object id - unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data) + int vertexCount; // number of vertices stored in arrays + int triangleCount; // number of triangles stored (indexed or not) + float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0) + float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5) + float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2) + float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4) + unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + unsigned short *indices;// vertex indices (in case vertex data comes indexed) + + unsigned int vaoId; // OpenGL Vertex Array Object id + unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data) } Mesh; // Shader type (generic shader) typedef struct Shader { - unsigned int id; // Shader program id + unsigned int id; // Shader program id // Vertex attributes locations (default locations) - int vertexLoc; // Vertex attribute location point (default-location = 0) - int texcoordLoc; // Texcoord attribute location point (default-location = 1) - int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5) - int normalLoc; // Normal attribute location point (default-location = 2) - int tangentLoc; // Tangent attribute location point (default-location = 4) - int colorLoc; // Color attibute location point (default-location = 3) + int vertexLoc; // Vertex attribute location point (default-location = 0) + int texcoordLoc; // Texcoord attribute location point (default-location = 1) + int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5) + int normalLoc; // Normal attribute location point (default-location = 2) + int tangentLoc; // Tangent attribute location point (default-location = 4) + int colorLoc; // Color attibute location point (default-location = 3) // Uniform locations - int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) - int tintColorLoc; // Diffuse color uniform location point (fragment shader) + int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) + int tintColorLoc; // Diffuse color uniform location point (fragment shader) // Texture map locations (generic for any kind of map) - int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0) - int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1) - int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2) + int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0) + int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1) + int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2) } Shader; // Material type typedef struct Material { - Shader shader; // Standard shader (supports 3 map textures) + Shader shader; // Standard shader (supports 3 map textures) - Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc) - Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc) - Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc) + Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc) + Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc) + Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc) - Color colDiffuse; // Diffuse color - Color colAmbient; // Ambient color - Color colSpecular; // Specular color + Color colDiffuse; // Diffuse color + Color colAmbient; // Ambient color + Color colSpecular; // Specular color - float glossiness; // Glossiness level (Ranges from 0 to 1000) + float glossiness; // Glossiness level (Ranges from 0 to 1000) } Material; // Model type typedef struct Model { - Mesh mesh; // Vertex data buffers (RAM and VRAM) - Matrix transform; // Local transform matrix - Material material; // Shader and textures data + Mesh mesh; // Vertex data buffers (RAM and VRAM) + Matrix transform; // Local transform matrix + Material material; // Shader and textures data } Model; // Light type typedef struct LightData { - unsigned int id; // Light id - int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT - bool enabled; // Light enabled + unsigned int id; // Light unique id + int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT + bool enabled; // Light enabled - Vector3 position; // Light position - Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) - float radius; // Light attenuation radius light intensity reduced with distance (world distance) + Vector3 position; // Light position + Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) + float radius; // Light attenuation radius light intensity reduced with distance (world distance) - Color diffuse; // Light diffuse color - float intensity; // Light intensity level + Color diffuse; // Light diffuse color + float intensity; // Light intensity level - float coneAngle; // Light cone max angle: LIGHT_SPOT + float coneAngle; // Light cone max angle: LIGHT_SPOT } LightData, *Light; // Light types diff --git a/src/raymath.h b/src/raymath.h index 59d66e56..2e055e9f 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -73,7 +73,7 @@ //---------------------------------------------------------------------------------- #if defined(RAYMATH_STANDALONE) - // Vector2 type + // Vector2 type typedef struct Vector2 { float x; float y; diff --git a/src/rlgl.c b/src/rlgl.c index 6a2adeb2..89361f46 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2369,7 +2369,7 @@ static void LoadCompressedTexture(unsigned char *data, int width, int height, in static unsigned int LoadShaderProgram(char *vShaderStr, char *fShaderStr) { unsigned int program = 0; - + #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) GLuint vertexShader; GLuint fragmentShader; diff --git a/src/rlgl.h b/src/rlgl.h index 336f6019..e8e754b4 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -130,51 +130,43 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; COMPRESSED_ASTC_4x4_RGBA, // 8 bpp COMPRESSED_ASTC_8x8_RGBA // 2 bpp } TextureFormat; - - // Bounding box type - typedef struct BoundingBox { - Vector3 min; - Vector3 max; - } BoundingBox; // Vertex data definning a mesh typedef struct Mesh { - int vertexCount; // number of vertices stored in arrays - float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0) - float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) - float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5) - float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2) - float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4) - unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3) - unsigned short *indices; // vertex indices (in case vertex data comes indexed) - int triangleCount; // number of triangles stored (indexed or not) - - BoundingBox bounds; // mesh limits defined by min and max points - - unsigned int vaoId; // OpenGL Vertex Array Object id - unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data) + int vertexCount; // number of vertices stored in arrays + int triangleCount; // number of triangles stored (indexed or not) + float *vertices; // vertex position (XYZ - 3 components per vertex) (shader-location = 0) + float *texcoords; // vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + float *texcoords2; // vertex second texture coordinates (useful for lightmaps) (shader-location = 5) + float *normals; // vertex normals (XYZ - 3 components per vertex) (shader-location = 2) + float *tangents; // vertex tangents (XYZ - 3 components per vertex) (shader-location = 4) + unsigned char *colors; // vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + unsigned short *indices;// vertex indices (in case vertex data comes indexed) + + unsigned int vaoId; // OpenGL Vertex Array Object id + unsigned int vboId[7]; // OpenGL Vertex Buffer Objects id (7 types of vertex data) } Mesh; // Shader type (generic shader) typedef struct Shader { - unsigned int id; // Shader program id + unsigned int id; // Shader program id // Vertex attributes locations (default locations) - int vertexLoc; // Vertex attribute location point (default-location = 0) - int texcoordLoc; // Texcoord attribute location point (default-location = 1) - int normalLoc; // Normal attribute location point (default-location = 2) - int colorLoc; // Color attibute location point (default-location = 3) - int tangentLoc; // Tangent attribute location point (default-location = 4) - int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5) + int vertexLoc; // Vertex attribute location point (default-location = 0) + int texcoordLoc; // Texcoord attribute location point (default-location = 1) + int normalLoc; // Normal attribute location point (default-location = 2) + int colorLoc; // Color attibute location point (default-location = 3) + int tangentLoc; // Tangent attribute location point (default-location = 4) + int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5) // Uniform locations - int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) - int tintColorLoc; // Color uniform location point (fragment shader) + int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader) + int tintColorLoc; // Color uniform location point (fragment shader) // Texture map locations (generic for any kind of map) - int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0) - int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1) - int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2) + int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0) + int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1) + int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2) } Shader; // Texture2D type @@ -196,35 +188,46 @@ typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion; // Material type typedef struct Material { - Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular) + Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular) - Texture2D texDiffuse; // Diffuse texture - Texture2D texNormal; // Normal texture - Texture2D texSpecular; // Specular texture + Texture2D texDiffuse; // Diffuse texture + Texture2D texNormal; // Normal texture + Texture2D texSpecular; // Specular texture - Color colDiffuse; // Diffuse color - Color colAmbient; // Ambient color - Color colSpecular; // Specular color + Color colDiffuse; // Diffuse color + Color colAmbient; // Ambient color + Color colSpecular; // Specular color - float glossiness; // Glossiness level (Ranges from 0 to 1000) + float glossiness; // Glossiness level (Ranges from 0 to 1000) } Material; + // Camera type, defines a camera position/orientation in 3d space + typedef struct Camera { + Vector3 position; // Camera position + Vector3 target; // Camera target it looks-at + Vector3 up; // Camera up vector (rotation over its axis) + float fovy; // Camera field-of-view apperture in Y (degrees) + } Camera; + // Light type typedef struct LightData { - unsigned int id; // Light id - int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT - bool enabled; // Light enabled + unsigned int id; // Light unique id + int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT + bool enabled; // Light enabled - Vector3 position; // Light position - Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) - float radius; // Light attenuation radius light intensity reduced with distance (world distance) + Vector3 position; // Light position + Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target) + float radius; // Light attenuation radius light intensity reduced with distance (world distance) - Color diffuse; // Light diffuse color - float intensity; // Light intensity level + Color diffuse; // Light diffuse color + float intensity; // Light intensity level - float coneAngle; // Light cone max angle: LIGHT_SPOT + float coneAngle; // Light cone max angle: LIGHT_SPOT } LightData, *Light; - + + // Light types + typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType; + // Color blending modes (pre-defined) typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode; #endif diff --git a/src/shapes.c b/src/shapes.c index 5b66e5ef..7129ac17 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -489,7 +489,7 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2) retRec.height = rec2.height - dyy; } } - + if (rec1.width > rec2.width) { if (retRec.width >= rec2.width) retRec.width = rec2.width; -- cgit v1.2.3 From 77f599885dade4930fb01baca22db6e2ae0c9f20 Mon Sep 17 00:00:00 2001 From: victorfisac Date: Fri, 10 Jun 2016 00:59:48 +0200 Subject: Fixed GLSL 100 shaders texture() doesn't exist in glsl 100, it must use texture2D(). --- examples/resources/shaders/glsl100/bloom.fs | 2 +- examples/resources/shaders/glsl100/grayscale.fs | 2 +- shaders/glsl100/bloom.fs | 2 +- shaders/glsl100/grayscale.fs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl100/bloom.fs b/examples/resources/shaders/glsl100/bloom.fs index 280d2fb6..128736f2 100644 --- a/examples/resources/shaders/glsl100/bloom.fs +++ b/examples/resources/shaders/glsl100/bloom.fs @@ -26,7 +26,7 @@ void main() } // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord); + vec4 texelColor = texture2D(texture0, fragTexCoord); // Calculate final fragment color if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; diff --git a/examples/resources/shaders/glsl100/grayscale.fs b/examples/resources/shaders/glsl100/grayscale.fs index f92ec335..cf857488 100644 --- a/examples/resources/shaders/glsl100/grayscale.fs +++ b/examples/resources/shaders/glsl100/grayscale.fs @@ -15,7 +15,7 @@ uniform vec4 fragTintColor; void main() { // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord)*fragTintColor*fragColor; + vec4 texelColor = texture2D(texture0, fragTexCoord)*fragTintColor*fragColor; // Convert texel color to grayscale using NTSC conversion weights float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); diff --git a/shaders/glsl100/bloom.fs b/shaders/glsl100/bloom.fs index 280d2fb6..128736f2 100644 --- a/shaders/glsl100/bloom.fs +++ b/shaders/glsl100/bloom.fs @@ -26,7 +26,7 @@ void main() } // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord); + vec4 texelColor = texture2D(texture0, fragTexCoord); // Calculate final fragment color if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; diff --git a/shaders/glsl100/grayscale.fs b/shaders/glsl100/grayscale.fs index c76dd8af..15174ea5 100644 --- a/shaders/glsl100/grayscale.fs +++ b/shaders/glsl100/grayscale.fs @@ -15,7 +15,7 @@ uniform vec4 colDiffuse; void main() { // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord)*colDiffuse*fragColor; + vec4 texelColor = texture2D(texture0, fragTexCoord)*colDiffuse*fragColor; // Convert texel color to grayscale using NTSC conversion weights float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); -- cgit v1.2.3 From e913de58c73ff82fbcd8f23b8cb1fd1a88664164 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 21 Jun 2016 13:45:35 +0200 Subject: Added distortion shader for testing --- examples/resources/shaders/base.vs | 26 ++++++++++++++ examples/resources/shaders/distortion.fs | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 examples/resources/shaders/base.vs create mode 100644 examples/resources/shaders/distortion.fs (limited to 'examples/resources') diff --git a/examples/resources/shaders/base.vs b/examples/resources/shaders/base.vs new file mode 100644 index 00000000..638cb8ae --- /dev/null +++ b/examples/resources/shaders/base.vs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvpMatrix; + +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/examples/resources/shaders/distortion.fs b/examples/resources/shaders/distortion.fs new file mode 100644 index 00000000..cd5951fe --- /dev/null +++ b/examples/resources/shaders/distortion.fs @@ -0,0 +1,59 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +const vec2 ScaleIn = vec2(4, 2.2222); +const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); + +/* +// Another set of default values +ChromaAbCorrection = {1.0, 0.0, 1.0, 0} +DistortionK = {1.0, 0.22, 0.24, 0} +Scale = {0.25, 0.5*AspectRatio, 0, 0} +ScaleIn = {4.0, 2/AspectRatio, 0, 0} +Left Screen Center = {0.25, 0.5, 0, 0} +Left Lens Center = {0.287994117, 0.5, 0, 0} +Right Screen Center = {0.75, 0.5, 0, 0} +Right Lens Center = {0.712005913, 0.5, 0, 0} +*/ + +// Scales input texture coordinates for distortion. +vec2 HmdWarp(vec2 in01, vec2 LensCenter) +{ + vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + + return LensCenter + Scale*rvector; +} + +void main() +{ + // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 + + // The following two variables need to be set per eye + vec2 LensCenter = gl_FragCoord.x < 540 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = gl_FragCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + + vec2 tc = HmdWarp(fragTexCoord, LensCenter); + + if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); + finalColor = texture2D(texture0, tc); + } +} -- cgit v1.2.3 From 4ff85c2ac257eb5494626dae30e79c5f48430609 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 26 Jun 2016 10:22:17 +0200 Subject: Added notes about chromatic aberration --- examples/resources/shaders/distortion.fs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'examples/resources') diff --git a/examples/resources/shaders/distortion.fs b/examples/resources/shaders/distortion.fs index cd5951fe..79bc5fa1 100644 --- a/examples/resources/shaders/distortion.fs +++ b/examples/resources/shaders/distortion.fs @@ -56,4 +56,14 @@ void main() //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); finalColor = texture2D(texture0, tc); } + + /* + // Chromatic aberration is caused when a lens can't focus every color to the same focal point. + // A simple way to fake this effect, and render it as a quick full-screen post-process, + // is to apply an offset to each color channel in a fragment shader. + vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); + vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); + vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); + finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); + */ } -- cgit v1.2.3 From c4922c9e8854f9c936b28c3f8b00162b407ae503 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 18:32:56 +0200 Subject: Reorganize shaders to respective folders --- examples/resources/shaders/base.vs | 26 ---- examples/resources/shaders/distortion.fs | 69 ---------- examples/resources/shaders/glsl100/distortion.fs | 68 ++++++++++ examples/resources/shaders/glsl330/distortion.fs | 69 ++++++++++ examples/resources/shaders/standard.fs | 155 ----------------------- examples/resources/shaders/standard.vs | 23 ---- shaders/glsl100/standard.fs | 155 +++++++++++++++++++++++ shaders/glsl100/standard.vs | 23 ++++ shaders/glsl330/standard.fs | 155 +++++++++++++++++++++++ shaders/glsl330/standard.vs | 23 ++++ src/rlgl.c | 2 +- 11 files changed, 494 insertions(+), 274 deletions(-) delete mode 100644 examples/resources/shaders/base.vs delete mode 100644 examples/resources/shaders/distortion.fs create mode 100644 examples/resources/shaders/glsl100/distortion.fs create mode 100644 examples/resources/shaders/glsl330/distortion.fs delete mode 100644 examples/resources/shaders/standard.fs delete mode 100644 examples/resources/shaders/standard.vs create mode 100644 shaders/glsl100/standard.fs create mode 100644 shaders/glsl100/standard.vs create mode 100644 shaders/glsl330/standard.fs create mode 100644 shaders/glsl330/standard.vs (limited to 'examples/resources') diff --git a/examples/resources/shaders/base.vs b/examples/resources/shaders/base.vs deleted file mode 100644 index 638cb8ae..00000000 --- a/examples/resources/shaders/base.vs +++ /dev/null @@ -1,26 +0,0 @@ -#version 330 - -// Input vertex attributes -in vec3 vertexPosition; -in vec2 vertexTexCoord; -in vec3 vertexNormal; -in vec4 vertexColor; - -// Input uniform values -uniform mat4 mvpMatrix; - -// Output vertex attributes (to fragment shader) -out vec2 fragTexCoord; -out vec4 fragColor; - -// NOTE: Add here your custom variables - -void main() -{ - // Send vertex attributes to fragment shader - fragTexCoord = vertexTexCoord; - fragColor = vertexColor; - - // Calculate final vertex position - gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); -} \ No newline at end of file diff --git a/examples/resources/shaders/distortion.fs b/examples/resources/shaders/distortion.fs deleted file mode 100644 index 79bc5fa1..00000000 --- a/examples/resources/shaders/distortion.fs +++ /dev/null @@ -1,69 +0,0 @@ -#version 330 - -// Input vertex attributes (from vertex shader) -in vec2 fragTexCoord; - -// Input uniform values -uniform sampler2D texture0; - -// Output fragment color -out vec4 finalColor; - -// NOTE: Add here your custom variables -const vec2 LeftLensCenter = vec2(0.2863248, 0.5); -const vec2 RightLensCenter = vec2(0.7136753, 0.5); -const vec2 LeftScreenCenter = vec2(0.25, 0.5); -const vec2 RightScreenCenter = vec2(0.75, 0.5); -const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -const vec2 ScaleIn = vec2(4, 2.2222); -const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); - -/* -// Another set of default values -ChromaAbCorrection = {1.0, 0.0, 1.0, 0} -DistortionK = {1.0, 0.22, 0.24, 0} -Scale = {0.25, 0.5*AspectRatio, 0, 0} -ScaleIn = {4.0, 2/AspectRatio, 0, 0} -Left Screen Center = {0.25, 0.5, 0, 0} -Left Lens Center = {0.287994117, 0.5, 0, 0} -Right Screen Center = {0.75, 0.5, 0, 0} -Right Lens Center = {0.712005913, 0.5, 0, 0} -*/ - -// Scales input texture coordinates for distortion. -vec2 HmdWarp(vec2 in01, vec2 LensCenter) -{ - vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] - float rSq = theta.x*theta.x + theta.y*theta.y; - vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); - - return LensCenter + Scale*rvector; -} - -void main() -{ - // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 - - // The following two variables need to be set per eye - vec2 LensCenter = gl_FragCoord.x < 540 ? LeftLensCenter : RightLensCenter; - vec2 ScreenCenter = gl_FragCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; - - vec2 tc = HmdWarp(fragTexCoord, LensCenter); - - if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); - else - { - //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); - finalColor = texture2D(texture0, tc); - } - - /* - // Chromatic aberration is caused when a lens can't focus every color to the same focal point. - // A simple way to fake this effect, and render it as a quick full-screen post-process, - // is to apply an offset to each color channel in a fragment shader. - vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); - vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); - vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); - finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); - */ -} diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs new file mode 100644 index 00000000..3a1a45d3 --- /dev/null +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -0,0 +1,68 @@ +#version 100 + +precision mediump float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// NOTE: Add here your custom variables +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +const vec2 ScaleIn = vec2(4, 2.2222); +const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); + +/* +// Another set of default values +ChromaAbCorrection = {1.0, 0.0, 1.0, 0} +DistortionK = {1.0, 0.22, 0.24, 0} +Scale = {0.25, 0.5*AspectRatio, 0, 0} +ScaleIn = {4.0, 2/AspectRatio, 0, 0} +Left Screen Center = {0.25, 0.5, 0, 0} +Left Lens Center = {0.287994117, 0.5, 0, 0} +Right Screen Center = {0.75, 0.5, 0, 0} +Right Lens Center = {0.712005913, 0.5, 0, 0} +*/ + +// Scales input texture coordinates for distortion. +vec2 HmdWarp(vec2 in01, vec2 LensCenter) +{ + vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + + return LensCenter + Scale*rvector; +} + +void main() +{ + // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 + + // The following two variables need to be set per eye + vec2 LensCenter = fragTexCoord.x < 540 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + + vec2 tc = HmdWarp(fragTexCoord, LensCenter); + + if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); + gl_FragColor = texture2D(texture0, tc); + } + + /* + // Chromatic aberration is caused when a lens can't focus every color to the same focal point. + // A simple way to fake this effect, and render it as a quick full-screen post-process, + // is to apply an offset to each color channel in a fragment shader. + vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); + vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); + vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); + finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); + */ +} diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs new file mode 100644 index 00000000..e43f8451 --- /dev/null +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -0,0 +1,69 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; + +// Input uniform values +uniform sampler2D texture0; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftScreenCenter = vec2(0.25, 0.5); +const vec2 RightScreenCenter = vec2(0.75, 0.5); +const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +const vec2 ScaleIn = vec2(4, 2.2222); +const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); + +/* +// Another set of default values +ChromaAbCorrection = {1.0, 0.0, 1.0, 0} +DistortionK = {1.0, 0.22, 0.24, 0} +Scale = {0.25, 0.5*AspectRatio, 0, 0} +ScaleIn = {4.0, 2/AspectRatio, 0, 0} +Left Screen Center = {0.25, 0.5, 0, 0} +Left Lens Center = {0.287994117, 0.5, 0, 0} +Right Screen Center = {0.75, 0.5, 0, 0} +Right Lens Center = {0.712005913, 0.5, 0, 0} +*/ + +// Scales input texture coordinates for distortion. +vec2 HmdWarp(vec2 in01, vec2 LensCenter) +{ + vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + + return LensCenter + Scale*rvector; +} + +void main() +{ + // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 + + // The following two variables need to be set per eye + vec2 LensCenter = fragTexCoord.x < 540 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + + vec2 tc = HmdWarp(fragTexCoord, LensCenter); + + if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); + finalColor = texture2D(texture0, tc); + } + + /* + // Chromatic aberration is caused when a lens can't focus every color to the same focal point. + // A simple way to fake this effect, and render it as a quick full-screen post-process, + // is to apply an offset to each color channel in a fragment shader. + vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); + vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); + vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); + finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); + */ +} diff --git a/examples/resources/shaders/standard.fs b/examples/resources/shaders/standard.fs deleted file mode 100644 index e5a6d1bc..00000000 --- a/examples/resources/shaders/standard.fs +++ /dev/null @@ -1,155 +0,0 @@ -#version 330 - -in vec3 fragPosition; -in vec2 fragTexCoord; -in vec4 fragColor; -in vec3 fragNormal; - -out vec4 finalColor; - -uniform sampler2D texture0; -uniform sampler2D texture1; -uniform sampler2D texture2; - -uniform vec4 colAmbient; -uniform vec4 colDiffuse; -uniform vec4 colSpecular; -uniform float glossiness; - -uniform int useNormal; -uniform int useSpecular; - -uniform mat4 modelMatrix; -uniform vec3 viewDir; - -struct Light { - int enabled; - int type; - vec3 position; - vec3 direction; - vec4 diffuse; - float intensity; - float radius; - float coneAngle; -}; - -const int maxLights = 8; -uniform int lightsCount; -uniform Light lights[maxLights]; - -vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) -{ - vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); - vec3 surfaceToLight = l.position - surfacePos; - - // Diffuse shading - float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1); - float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; - - // Specular shading - float spec = 0.0; - if (diff > 0.0) - { - vec3 h = normalize(-l.direction + v); - spec = pow(dot(n, h), 3 + glossiness)*s; - } - - return (diff*l.diffuse.rgb + spec*colSpecular.rgb); -} - -vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) -{ - vec3 lightDir = normalize(-l.direction); - - // Diffuse shading - float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; - - // Specular shading - float spec = 0.0; - if (diff > 0.0) - { - vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3 + glossiness)*s; - } - - // Combine results - return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); -} - -vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) -{ - vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); - vec3 lightToSurface = normalize(surfacePos - l.position); - vec3 lightDir = normalize(-l.direction); - - // Diffuse shading - float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; - - // Spot attenuation - float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); - attenuation = dot(lightToSurface, -lightDir); - - float lightToSurfaceAngle = degrees(acos(attenuation)); - if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; - - float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; - - // Combine diffuse and attenuation - float diffAttenuation = diff*attenuation; - - // Specular shading - float spec = 0.0; - if (diffAttenuation > 0.0) - { - vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3 + glossiness)*s; - } - - return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); -} - -void main() -{ - // Calculate fragment normal in screen space - // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) - mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); - vec3 normal = normalize(normalMatrix*fragNormal); - - // Normalize normal and view direction vectors - vec3 n = normalize(normal); - vec3 v = normalize(viewDir); - - // Calculate diffuse texture color fetching - vec4 texelColor = texture(texture0, fragTexCoord); - vec3 lighting = colAmbient.rgb; - - // Calculate normal texture color fetching or set to maximum normal value by default - if (useNormal == 1) - { - n *= texture(texture1, fragTexCoord).rgb; - n = normalize(n); - } - - // Calculate specular texture color fetching or set to maximum specular value by default - float spec = 1.0; - if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); - - for (int i = 0; i < lightsCount; i++) - { - // Check if light is enabled - if (lights[i].enabled == 1) - { - // Calculate lighting based on light type - switch (lights[i].type) - { - case 0: lighting += CalcPointLight(lights[i], n, v, spec); break; - case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break; - case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break; - default: break; - } - } - } - - // Calculate final fragment color - finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); -} diff --git a/examples/resources/shaders/standard.vs b/examples/resources/shaders/standard.vs deleted file mode 100644 index fc0a5ff4..00000000 --- a/examples/resources/shaders/standard.vs +++ /dev/null @@ -1,23 +0,0 @@ -#version 330 - -in vec3 vertexPosition; -in vec3 vertexNormal; -in vec2 vertexTexCoord; -in vec4 vertexColor; - -out vec3 fragPosition; -out vec2 fragTexCoord; -out vec4 fragColor; -out vec3 fragNormal; - -uniform mat4 mvpMatrix; - -void main() -{ - fragPosition = vertexPosition; - fragTexCoord = vertexTexCoord; - fragColor = vertexColor; - fragNormal = vertexNormal; - - gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); -} \ No newline at end of file diff --git a/shaders/glsl100/standard.fs b/shaders/glsl100/standard.fs new file mode 100644 index 00000000..d5daa445 --- /dev/null +++ b/shaders/glsl100/standard.fs @@ -0,0 +1,155 @@ +#version 100 + +precision mediump float; + +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform sampler2D texture2; + +uniform vec4 colAmbient; +uniform vec4 colDiffuse; +uniform vec4 colSpecular; +uniform float glossiness; + +uniform int useNormal; +uniform int useSpecular; + +uniform mat4 modelMatrix; +uniform vec3 viewDir; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 direction; + vec4 diffuse; + float intensity; + float radius; + float coneAngle; +}; + +const int maxLights = 8; +uniform int lightsCount; +uniform Light lights[maxLights]; + +vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 surfaceToLight = l.position - surfacePos; + + // Diffuse shading + float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1); + float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(-l.direction + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + return (diff*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + // Combine results + return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 lightToSurface = normalize(surfacePos - l.position); + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Spot attenuation + float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); + attenuation = dot(lightToSurface, -lightDir); + + float lightToSurfaceAngle = degrees(acos(attenuation)); + if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + + float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; + + // Combine diffuse and attenuation + float diffAttenuation = diff*attenuation; + + // Specular shading + float spec = 0.0; + if (diffAttenuation > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); +} + +void main() +{ + // Calculate fragment normal in screen space + // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) + mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); + vec3 normal = normalize(normalMatrix*fragNormal); + + // Normalize normal and view direction vectors + vec3 n = normalize(normal); + vec3 v = normalize(viewDir); + + // Calculate diffuse texture color fetching + vec4 texelColor = texture2D(texture0, fragTexCoord); + vec3 lighting = colAmbient.rgb; + + // Calculate normal texture color fetching or set to maximum normal value by default + if (useNormal == 1) + { + n *= texture2D(texture1, fragTexCoord).rgb; + n = normalize(n); + } + + // Calculate specular texture color fetching or set to maximum specular value by default + float spec = 1.0; + if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r); + + for (int i = 0; i < lightsCount; i++) + { + // Check if light is enabled + if (lights[i].enabled == 1) + { + // Calculate lighting based on light type + switch (lights[i].type) + { + case 0: lighting += CalcPointLight(lights[i], n, v, spec); break; + case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break; + case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break; + default: break; + } + } + } + + // Calculate final fragment color + gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); +} diff --git a/shaders/glsl100/standard.vs b/shaders/glsl100/standard.vs new file mode 100644 index 00000000..49c5a3eb --- /dev/null +++ b/shaders/glsl100/standard.vs @@ -0,0 +1,23 @@ +#version 100 + +attribute vec3 vertexPosition; +attribute vec3 vertexNormal; +attribute vec2 vertexTexCoord; +attribute vec4 vertexColor; + +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +uniform mat4 mvpMatrix; + +void main() +{ + fragPosition = vertexPosition; + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = vertexNormal; + + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/shaders/glsl330/standard.fs b/shaders/glsl330/standard.fs new file mode 100644 index 00000000..e5a6d1bc --- /dev/null +++ b/shaders/glsl330/standard.fs @@ -0,0 +1,155 @@ +#version 330 + +in vec3 fragPosition; +in vec2 fragTexCoord; +in vec4 fragColor; +in vec3 fragNormal; + +out vec4 finalColor; + +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform sampler2D texture2; + +uniform vec4 colAmbient; +uniform vec4 colDiffuse; +uniform vec4 colSpecular; +uniform float glossiness; + +uniform int useNormal; +uniform int useSpecular; + +uniform mat4 modelMatrix; +uniform vec3 viewDir; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 direction; + vec4 diffuse; + float intensity; + float radius; + float coneAngle; +}; + +const int maxLights = 8; +uniform int lightsCount; +uniform Light lights[maxLights]; + +vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 surfaceToLight = l.position - surfacePos; + + // Diffuse shading + float brightness = clamp(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n)), 0, 1); + float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(-l.direction + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + return (diff*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcDirectionalLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + // Combine results + return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 CalcSpotLight(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 lightToSurface = normalize(surfacePos - l.position); + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(dot(n, lightDir), 0.0, 1.0)*l.intensity; + + // Spot attenuation + float attenuation = clamp(dot(n, lightToSurface), 0.0, 1.0); + attenuation = dot(lightToSurface, -lightDir); + + float lightToSurfaceAngle = degrees(acos(attenuation)); + if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + + float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; + + // Combine diffuse and attenuation + float diffAttenuation = diff*attenuation; + + // Specular shading + float spec = 0.0; + if (diffAttenuation > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3 + glossiness)*s; + } + + return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); +} + +void main() +{ + // Calculate fragment normal in screen space + // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) + mat3 normalMatrix = transpose(inverse(mat3(modelMatrix))); + vec3 normal = normalize(normalMatrix*fragNormal); + + // Normalize normal and view direction vectors + vec3 n = normalize(normal); + vec3 v = normalize(viewDir); + + // Calculate diffuse texture color fetching + vec4 texelColor = texture(texture0, fragTexCoord); + vec3 lighting = colAmbient.rgb; + + // Calculate normal texture color fetching or set to maximum normal value by default + if (useNormal == 1) + { + n *= texture(texture1, fragTexCoord).rgb; + n = normalize(n); + } + + // Calculate specular texture color fetching or set to maximum specular value by default + float spec = 1.0; + if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); + + for (int i = 0; i < lightsCount; i++) + { + // Check if light is enabled + if (lights[i].enabled == 1) + { + // Calculate lighting based on light type + switch (lights[i].type) + { + case 0: lighting += CalcPointLight(lights[i], n, v, spec); break; + case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break; + case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break; + default: break; + } + } + } + + // Calculate final fragment color + finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); +} diff --git a/shaders/glsl330/standard.vs b/shaders/glsl330/standard.vs new file mode 100644 index 00000000..fc0a5ff4 --- /dev/null +++ b/shaders/glsl330/standard.vs @@ -0,0 +1,23 @@ +#version 330 + +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec2 vertexTexCoord; +in vec4 vertexColor; + +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec4 fragColor; +out vec3 fragNormal; + +uniform mat4 mvpMatrix; + +void main() +{ + fragPosition = vertexPosition; + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = vertexNormal; + + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/src/rlgl.c b/src/rlgl.c index 69c80faf..fa57e9ac 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2538,7 +2538,7 @@ void InitOculusDevice(void) // Load oculus-distortion shader (oculus parameters setup internally) // TODO: Embed coulus distortion shader (in this function like default shader?) - distortion = LoadShader("resources/shaders/base.vs", "resources/shaders/distortion.fs"); + distortion = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); oculusSimulator = true; vrEnabled = true; -- cgit v1.2.3 From 5a4eb34c39e404fdd5804299111477a10dd3895d Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 18:59:03 +0200 Subject: Corrected issue on distortion shader --- examples/core_oculus_rift.c | 4 +++- examples/resources/shaders/glsl100/distortion.fs | 10 +++------- examples/resources/shaders/glsl330/distortion.fs | 22 ++++++++++------------ 3 files changed, 16 insertions(+), 20 deletions(-) (limited to 'examples/resources') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 4fe35607..95b89106 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -63,11 +63,13 @@ int main() DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); DrawGrid(10, 1.0f); - + DrawDefaultBuffers(); // Process internal dynamic buffers } End3dMode(); + + DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index 3a1a45d3..19e6656a 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -44,17 +44,13 @@ void main() // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 // The following two variables need to be set per eye - vec2 LensCenter = fragTexCoord.x < 540 ? LeftLensCenter : RightLensCenter; - vec2 ScreenCenter = fragTexCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; vec2 tc = HmdWarp(fragTexCoord, LensCenter); if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - else - { - //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); - gl_FragColor = texture2D(texture0, tc); - } + else gl_FragColor = texture2D(texture0, tc); /* // Chromatic aberration is caused when a lens can't focus every color to the same focal point. diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index e43f8451..c8777c18 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -17,6 +17,7 @@ const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); const vec2 ScaleIn = vec2(4, 2.2222); const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); +const vec4 ChromaAbCorrection = vec4(0.99599999, -0.0040000002, 1.0140001, 0.0); /* // Another set of default values @@ -45,25 +46,22 @@ void main() // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 // The following two variables need to be set per eye - vec2 LensCenter = fragTexCoord.x < 540 ? LeftLensCenter : RightLensCenter; - vec2 ScreenCenter = fragTexCoord.x < 540 ? LeftScreenCenter : RightScreenCenter; + vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; + vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; vec2 tc = HmdWarp(fragTexCoord, LensCenter); - if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); - else - { - //tc.x = gl_FragCoord.x < 640 ? (2.0 * tc.x) : (2.0 * (tc.x - 0.5)); - finalColor = texture2D(texture0, tc); - } + if (any(bvec2(clamp(tc, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else finalColor = texture2D(texture0, tc); - /* // Chromatic aberration is caused when a lens can't focus every color to the same focal point. // A simple way to fake this effect, and render it as a quick full-screen post-process, // is to apply an offset to each color channel in a fragment shader. - vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); - vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); - vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); + /* + vec4 rValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.x); + vec4 gValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.y); + vec4 bValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.z); + finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); */ } -- cgit v1.2.3 From 6fbf6a1c234ab7db9b975109c3c2138f83684442 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 19:18:53 +0200 Subject: Redesigned distortion shader, added chromatic aberration --- examples/resources/shaders/glsl100/distortion.fs | 51 ++++++++++++----------- examples/resources/shaders/glsl330/distortion.fs | 53 ++++++++++++------------ 2 files changed, 53 insertions(+), 51 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index 19e6656a..d7b687bf 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -29,36 +29,37 @@ Right Screen Center = {0.75, 0.5, 0, 0} Right Lens Center = {0.712005913, 0.5, 0, 0} */ -// Scales input texture coordinates for distortion. -vec2 HmdWarp(vec2 in01, vec2 LensCenter) -{ - vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] - float rSq = theta.x*theta.x + theta.y*theta.y; - vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); - - return LensCenter + Scale*rvector; -} - void main() { - // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 - // The following two variables need to be set per eye vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; + + // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter) + vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + //vec2 tc = LensCenter + Scale*theta1; + + // Detect whether blue texture coordinates are out of range since these will scaled out the furthest + vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq); + vec2 tcBlue = LensCenter + Scale*thetaBlue; - vec2 tc = HmdWarp(fragTexCoord, LensCenter); + if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + // Do blue texture lookup + float blue = texture2D(texture0, tcBlue).b; - if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); - else gl_FragColor = texture2D(texture0, tc); - - /* - // Chromatic aberration is caused when a lens can't focus every color to the same focal point. - // A simple way to fake this effect, and render it as a quick full-screen post-process, - // is to apply an offset to each color channel in a fragment shader. - vec4 rValue = texture2D(texture0, fragTexCoord - rOffset); - vec4 gValue = texture2D(texture0, fragTexCoord - gOffset); - vec4 bValue = texture2D(texture0, fragTexCoord - bOffset); - finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); - */ + // Do green lookup (no scaling) + vec2 tcGreen = LensCenter + Scale*theta1; + float green = texture2D(texture0, tcGreen).g; + + // Do red scale and lookup + vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq); + vec2 tcRed = LensCenter + Scale*thetaRed; + float red = texture2D(texture0, tcRed).r; + + gl_FragColor = vec4(red, green, blue, 1.0); + } } diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index c8777c18..4cd9937f 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -17,7 +17,7 @@ const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); const vec2 ScaleIn = vec2(4, 2.2222); const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); -const vec4 ChromaAbCorrection = vec4(0.99599999, -0.0040000002, 1.0140001, 0.0); +const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); /* // Another set of default values @@ -31,37 +31,38 @@ Right Screen Center = {0.75, 0.5, 0, 0} Right Lens Center = {0.712005913, 0.5, 0, 0} */ -// Scales input texture coordinates for distortion. -vec2 HmdWarp(vec2 in01, vec2 LensCenter) -{ - vec2 theta = (in01 - LensCenter)*ScaleIn; // Scales to [-1, 1] - float rSq = theta.x*theta.x + theta.y*theta.y; - vec2 rvector = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); - - return LensCenter + Scale*rvector; -} - void main() { - // SOURCE: http://www.mtbs3d.com/phpbb/viewtopic.php?f=140&t=17081 - // The following two variables need to be set per eye vec2 LensCenter = fragTexCoord.x < 0.5 ? LeftLensCenter : RightLensCenter; vec2 ScreenCenter = fragTexCoord.x < 0.5 ? LeftScreenCenter : RightScreenCenter; + + // Scales input texture coordinates for distortion: vec2 HmdWarp(vec2 fragTexCoord, vec2 LensCenter) + vec2 theta = (fragTexCoord - LensCenter)*ScaleIn; // Scales to [-1, 1] + float rSq = theta.x*theta.x + theta.y*theta.y; + vec2 theta1 = theta*(HmdWarpParam.x + HmdWarpParam.y*rSq + HmdWarpParam.z*rSq*rSq + HmdWarpParam.w*rSq*rSq*rSq); + //vec2 tc = LensCenter + Scale*theta1; + + // Detect whether blue texture coordinates are out of range since these will scaled out the furthest + vec2 thetaBlue = theta1*(ChromaAbParam.z + ChromaAbParam.w*rSq); + vec2 tcBlue = LensCenter + Scale*thetaBlue; - vec2 tc = HmdWarp(fragTexCoord, LensCenter); + if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tcBlue))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); + else + { + // Do blue texture lookup + float blue = texture(texture0, tcBlue).b; - if (any(bvec2(clamp(tc, ScreenCenter - vec2(0.25, 0.5), ScreenCenter + vec2(0.25, 0.5)) - tc))) finalColor = vec4(0.0, 0.0, 0.0, 1.0); - else finalColor = texture2D(texture0, tc); - - // Chromatic aberration is caused when a lens can't focus every color to the same focal point. - // A simple way to fake this effect, and render it as a quick full-screen post-process, - // is to apply an offset to each color channel in a fragment shader. - /* - vec4 rValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.x); - vec4 gValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.y); - vec4 bValue = texture2D(texture0, fragTexCoord - ChromaAbCorrection.z); + // Do green lookup (no scaling) + vec2 tcGreen = LensCenter + Scale*theta1; + float green = texture(texture0, tcGreen).g; + + // Do red scale and lookup + vec2 thetaRed = theta1*(ChromaAbParam.x + ChromaAbParam.y*rSq); + vec2 tcRed = LensCenter + Scale*thetaRed; + float red = texture(texture0, tcRed).r; - finalColor = vec4(rValue.r, gValue.g, bValue.b, 1.0); - */ + finalColor = vec4(red, green, blue, 1.0); + } } + -- cgit v1.2.3 From be61d2f8c1d3ce4579b4e74557fb4773624bf00c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 27 Jun 2016 20:09:10 +0200 Subject: Added missing parameter --- examples/resources/shaders/glsl100/distortion.fs | 1 + 1 file changed, 1 insertion(+) (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index d7b687bf..a0a6cc18 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -16,6 +16,7 @@ const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); const vec2 ScaleIn = vec2(4, 2.2222); const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); +const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); /* // Another set of default values -- cgit v1.2.3 From ee72654b557202a673f042484c83d3020ae618b8 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 4 Jul 2016 01:29:23 +0200 Subject: Redesigned stereo rendering mechanism Now it's easier for the user! Just init Oculus device and get stereo rendering! --- examples/core_oculus_rift.c | 11 +- examples/resources/shaders/glsl330/distortion.fs | 9 +- src/core.c | 18 +- src/raylib.h | 2 - src/rlgl.c | 443 ++++++++++++----------- src/rlgl.h | 4 - 6 files changed, 251 insertions(+), 236 deletions(-) (limited to 'examples/resources') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index c073d3d6..131a21c2 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -50,22 +50,15 @@ int main() // Draw //---------------------------------------------------------------------------------- BeginDrawing(); - + ClearBackground(RAYWHITE); - + Begin3dMode(camera); - for (int eye = 0; eye < 2; eye++) - { - SetOculusView(eye); - DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON); DrawGrid(10, 1.0f); - - DrawDefaultBuffers(); // Process internal dynamic buffers - } End3dMode(); diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index 4cd9937f..62856341 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -10,12 +10,13 @@ uniform sampler2D texture0; out vec4 finalColor; // NOTE: Add here your custom variables -const vec2 LeftLensCenter = vec2(0.2863248, 0.5); -const vec2 RightLensCenter = vec2(0.7136753, 0.5); +const vec2 LeftLensCenter = vec2(0.288, 0.5); +const vec2 RightLensCenter = vec2(0.712, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); -const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -const vec2 ScaleIn = vec2(4, 2.2222); +uniform vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); +uniform vec2 ScaleIn = vec2(4, 2.2222); + const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); diff --git a/src/core.c b/src/core.c index 47ce5cea..a8557831 100644 --- a/src/core.c +++ b/src/core.c @@ -520,6 +520,8 @@ void BeginDrawing(void) currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called updateTime = currentTime - previousTime; previousTime = currentTime; + + if (IsOculusReady()) BeginOculusDrawing(); rlClearScreenBuffers(); // Clear current framebuffers rlLoadIdentity(); // Reset current matrix (MODELVIEW) @@ -533,6 +535,8 @@ void BeginDrawing(void) void EndDrawing(void) { rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2) + + if (IsOculusReady()) EndOculusDrawing(); SwapBuffers(); // Copy back buffer to front buffer PollInputEvents(); // Poll user events @@ -608,15 +612,11 @@ void Begin3dMode(Camera camera) rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera) rlEnableDepthTest(); // Enable DEPTH_TEST for 3D - - if (IsOculusReady()) BeginOculusDrawing(); } // Ends 3D mode and returns to default 2D orthographic mode void End3dMode(void) -{ - if (IsOculusReady()) EndOculusDrawing(); - +{ rlglDraw(); // Process internal buffers (update + draw) rlMatrixMode(RL_PROJECTION); // Switch to projection matrix @@ -1021,14 +1021,6 @@ Matrix GetCameraMatrix(Camera camera) return MatrixLookAt(camera.position, camera.target, camera.up); } -// Update and draw default buffers vertex data -// NOTE: This data has been stored dynamically during frame on each Draw*() call -void DrawDefaultBuffers(void) -{ - rlglUpdateDefaultBuffers(); // Upload frame vertex data to GPU - rlglDrawDefaultBuffers(); // Draw vertex data into framebuffer -} - //---------------------------------------------------------------------------------- // Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions //---------------------------------------------------------------------------------- diff --git a/src/raylib.h b/src/raylib.h index 6bacfc67..89fc457f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -572,7 +572,6 @@ void EndTextureMode(void); // Ends drawing to r Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) -void DrawDefaultBuffers(void); // Update and draw default buffers vertex data (stored dynamically in frame) void SetTargetFPS(int fps); // Set target FPS (maximum) float GetFPS(void); // Returns current FPS @@ -853,7 +852,6 @@ void DestroyLight(Light light); // Destroy a void InitOculusDevice(void); // Init Oculus Rift device void CloseOculusDevice(void); // Close Oculus Rift device void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data void BeginOculusDrawing(void); // Begin Oculus drawing configuration void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready diff --git a/src/rlgl.c b/src/rlgl.c index d3ffdd8b..57e6b894 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -276,9 +276,10 @@ static unsigned int frameIndex = 0; // Oculus frames counter, used to discar static bool oculusReady = false; // Oculus device ready flag static bool oculusSimulator = false; // Oculus device simulator static bool vrEnabled = false; // VR experience enabled (Oculus device or simulator) +static bool vrControl = true; // VR controlled by user code, instead of internally static RenderTexture2D stereoFbo; -static Shader distortion; +static Shader distortionShader; // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support @@ -315,10 +316,13 @@ static void UnloadDefaultShader(void); // Unload default shader static void UnloadStandardShader(void); // Unload standard shader static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads) -void rlglUpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data -void rlglDrawDefaultBuffers(void); // Draw default internal buffers vertex data +static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data +static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers vertex data static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU +// Set internal projection and modelview matrix depending on eyes tracking data +static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView); + static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array static char *ReadTextFile(const char *fileName); @@ -1205,15 +1209,14 @@ void rlglClose(void) void rlglDraw(void) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) -/* - for (int i = 0; i < modelsCount; i++) - { - rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform); - } -*/ - // NOTE: Default buffers always drawn at the end - rlglUpdateDefaultBuffers(); - rlglDrawDefaultBuffers(); + // NOTE: In a future version, models could be stored in a stack... + //for (int i = 0; i < modelsCount; i++) rlglDrawMesh(models[i]->mesh, models[i]->material, models[i]->transform); + + // NOTE: Default buffers upload and draw + UpdateDefaultBuffers(); + + if (vrEnabled && vrControl) DrawDefaultBuffers(2); + else DrawDefaultBuffers(1); #endif } @@ -1865,26 +1868,23 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) #endif #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) + int eyesCount = 1; + if (vrEnabled) eyesCount = 2; + glUseProgram(material.shader.id); + // Upload to shader material.colDiffuse + float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 }; + glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse); + // At this point the modelview matrix just contains the view matrix (camera) // That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix() Matrix matView = modelview; // View matrix (camera) Matrix matProjection = projection; // Projection matrix (perspective) - + // Calculate model-view matrix combining matModel and matView Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates - // Calculate model-view-projection matrix (MVP) - Matrix matMVP = MatrixMultiply(matModelView, matProjection); // Transform to screen-space coordinates - - // Send combined model-view-projection matrix to shader - glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); - - // Upload to shader material.colDiffuse - float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 }; - glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse); - // Check if using standard shader to get location points // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations) if (material.shader.id == standardShader.id) @@ -1989,9 +1989,20 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); } - // Draw call! - if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw - else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); + for (int eye = 0; eye < eyesCount; eye++) + { + if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); + + // Calculate model-view-projection matrix (MVP) + Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates + + // Send combined model-view-projection matrix to shader + glUniformMatrix4fv(material.shader.mvpLoc, 1, false, MatrixToFloat(matMVP)); + + // Draw call! + if (mesh.indices != NULL) glDrawElements(GL_TRIANGLES, mesh.triangleCount*3, GL_UNSIGNED_SHORT, 0); // Indexed vertices draw + else glDrawArrays(GL_TRIANGLES, 0, mesh.vertexCount); + } if (material.texNormal.id != 0) { @@ -2016,6 +2027,10 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform) } glUseProgram(0); // Unbind shader program + + // Restore projection/modelview matrices + projection = matProjection; + modelview = matView; #endif } @@ -2538,7 +2553,7 @@ void InitOculusDevice(void) // Load oculus-distortion shader (oculus parameters setup internally) // TODO: Embed coulus distortion shader (in this function like default shader?) - distortion = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); + distortionShader = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); oculusSimulator = true; vrEnabled = true; @@ -2564,7 +2579,7 @@ void CloseOculusDevice(void) rlDeleteRenderTextures(stereoFbo); // Unload oculus-distortion shader - UnloadShader(distortion); + UnloadShader(distortionShader); } oculusReady = false; @@ -2615,13 +2630,13 @@ void UpdateOculusTracking(void) } // Set internal projection and modelview matrix depending on eyes tracking data -void SetOculusView(int eye) -{ - Matrix eyeProjection; - Matrix eyeModelView; - +static void SetOculusView(int eye, Matrix matProjection, Matrix matModelView) +{ if (vrEnabled) { + Matrix eyeProjection = matProjection; + Matrix eyeModelView = matModelView; + #if defined(RLGL_OCULUS_SUPPORT) if (oculusReady) { @@ -2639,10 +2654,8 @@ void SetOculusView(int eye) -layer.eyeLayer.RenderPose[eye].Position.z); Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement - eyeModelView = MatrixMultiply(modelview, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement - // TODO: Find a better way to get camera view matrix (instead of using internal modelview) - eyeProjection = layer.eyeProjections[eye]; } else @@ -2651,28 +2664,43 @@ void SetOculusView(int eye) // Setup viewport and projection/modelview matrices using tracking data rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); - float hmdIPD = 0.064f; - float hmdHScreenSize = 0.14976f; - float hmdVScreenSize = 0.0936f; - //float hmdVScreenCenter = 0.04675f; - float hmdEyeToScreenDistance = 0.041f; - float hmdLensSeparationDistance = 0.064f; + static float IPD = 0.064f; // InterpupillaryDistance + float HScreenSize = 0.14976f; + float VScreenSize = 0.0936f; // HScreenSize/(1280.0f/800.0f) + float VScreenCenter = 0.04675f; + float EyeToScreenDistance = 0.041f; + float LensSeparationDistance = 0.064f; //0.0635f (DK1) - //NOTE: fovy value hardcoded to 60 degrees (Oculus Rift CV1 vertical FOV is 100 degrees) - //float halfScreenDistance = hmdVScreenSize/2.0f; - //float yfov = 2.0f*atan(halfScreenDistance/hmdEyeToScreenDistance); - - float viewCenter = (float)hmdHScreenSize*0.25f; - float eyeProjectionShift = viewCenter - hmdLensSeparationDistance*0.5f; - float projectionCenterOffset = 4.0f*eyeProjectionShift/(float)hmdHScreenSize; - + // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) + float halfScreenDistance = VScreenSize/2.0f; + float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG; + + float viewCenter = (float)HScreenSize*0.25f; + float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f; + float projectionCenterOffset = 4.0f*eyeProjectionShift/(float)HScreenSize; +/* + static float scale[2] = { 0.25, 0.45 }; + + if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01; + else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01; + else if (IsKeyDown(KEY_UP)) scale[1] += 0.01; + else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01; + SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2); + + if (IsKeyDown(KEY_N)) IPD += 0.02; + else if (IsKeyDown(KEY_M)) IPD -= 0.02; +*/ // The matrixes for offsetting the projection and view for each eye, to achieve stereo effect Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f }; - Vector3 viewOffset = { -hmdIPD/2.0f, 0.0f, 0.0f }; + + // Camera movement might seem more natural if we model the head. + // Our axis of rotation is the base of our head, so we might want to add + // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions. + Vector3 viewOffset = { -IPD/2.0f, 0.075f, 0.045f }; // Negate the left eye versions - if (eye == 1) + if (eye == 0) { projectionOffset.x *= -1.0f; viewOffset.x *= -1.0f; @@ -2680,29 +2708,18 @@ void SetOculusView(int eye) // Adjust the view and projection matrixes // View matrix is translated based on the eye offset - Matrix projCenter = MatrixPerspective(60.0, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); + Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z); Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z); eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection - eyeModelView = MatrixMultiply(modelview, viewTranslation); // modelview + eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview MatrixTranspose(&eyeProjection); - - /* - // NOTE: fovy value hardcoded to 60 degrees (Oculus Rift CV1 vertical FOV is 100 degrees) - eyeProjection = MatrixPerspective(60.0, (double)(screenWidth/2)/(double)screenHeight, 0.01, 1000.0); - MatrixTranspose(&eyeProjection); - - // TODO: Compute eyes IPD and apply to current modelview matrix (camera) - Matrix eyeView = MatrixIdentity(); - - eyeModelView = MatrixMultiply(modelview, eyeView); - */ } - SetMatrixModelview(eyeModelView); + SetMatrixModelview(eyeModelView); // ERROR! We are modifying modelview for next eye!!! SetMatrixProjection(eyeProjection); } } @@ -2738,6 +2755,8 @@ void BeginOculusDrawing(void) //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) rlClearScreenBuffers(); // Clear current framebuffer(s) + + vrControl = true; } // End Oculus drawing process (and desktop mirror) @@ -2777,40 +2796,44 @@ void EndOculusDrawing(void) rlLoadIdentity(); // Reset internal modelview matrix // Draw RenderTexture (stereoFbo) using distortion shader - BeginShaderMode(distortion); + currentShader = distortionShader; - rlEnableTexture(stereoFbo.texture.id); + rlEnableTexture(stereoFbo.texture.id); - rlPushMatrix(); - rlBegin(RL_QUADS); - rlColor4ub(255, 255, 255, 255); - rlNormal3f(0.0f, 0.0f, 1.0f); + rlPushMatrix(); + rlBegin(RL_QUADS); + rlColor4ub(255, 255, 255, 255); + rlNormal3f(0.0f, 0.0f, 1.0f); - // Bottom-left corner for texture and quad - rlTexCoord2f(0.0f, 1.0f); - rlVertex2f(0.0f, 0.0f); + // Bottom-left corner for texture and quad + rlTexCoord2f(0.0f, 1.0f); + rlVertex2f(0.0f, 0.0f); - // Bottom-right corner for texture and quad - rlTexCoord2f(0.0f, 0.0f); - rlVertex2f(0.0f, stereoFbo.texture.height); + // Bottom-right corner for texture and quad + rlTexCoord2f(0.0f, 0.0f); + rlVertex2f(0.0f, stereoFbo.texture.height); - // Top-right corner for texture and quad - rlTexCoord2f(1.0f, 0.0f); - rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height); + // Top-right corner for texture and quad + rlTexCoord2f(1.0f, 0.0f); + rlVertex2f(stereoFbo.texture.width, stereoFbo.texture.height); - // Top-left corner for texture and quad - rlTexCoord2f(1.0f, 1.0f); - rlVertex2f(stereoFbo.texture.width, 0.0f); - rlEnd(); - rlPopMatrix(); + // Top-left corner for texture and quad + rlTexCoord2f(1.0f, 1.0f); + rlVertex2f(stereoFbo.texture.width, 0.0f); + rlEnd(); + rlPopMatrix(); - rlDisableTexture(); - - //rlglDraw(); - EndShaderMode(); + rlDisableTexture(); + + UpdateDefaultBuffers(); + DrawDefaultBuffers(1); + + currentShader = defaultShader; } rlDisableDepthTest(); + + vrControl = false; } //---------------------------------------------------------------------------------- @@ -3303,7 +3326,7 @@ static void LoadDefaultBuffers(void) // Update default internal buffers (VAOs/VBOs) with vertex array data // NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) // TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (change flag required) -void rlglUpdateDefaultBuffers(void) +static void UpdateDefaultBuffers(void) { // Update lines vertex buffers if (lines.vCounter > 0) @@ -3373,146 +3396,154 @@ void rlglUpdateDefaultBuffers(void) // Draw default internal buffers vertex data // NOTE: We draw in this order: lines, triangles, quads -void rlglDrawDefaultBuffers(void) +static void DrawDefaultBuffers(int eyesCount) { - // Set current shader and upload current MVP matrix - if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) - { - glUseProgram(currentShader.id); - - // Create modelview-projection matrix - Matrix matMVP = MatrixMultiply(modelview, projection); - - glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); - glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f); - glUniform1i(currentShader.mapTexture0Loc, 0); - - // NOTE: Additional map textures not considered for default buffers drawing - } - - // Draw lines buffers - if (lines.vCounter > 0) + Matrix matProjection = projection; + Matrix matModelView = modelview; + + for (int eye = 0; eye < eyesCount; eye++) { - glBindTexture(GL_TEXTURE_2D, whiteTexture); + if (eyesCount == 2) SetOculusView(eye, matProjection, matModelView); - if (vaoSupported) + // Set current shader and upload current MVP matrix + if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0)) { - glBindVertexArray(lines.vaoId); + glUseProgram(currentShader.id); + + // Create modelview-projection matrix + Matrix matMVP = MatrixMultiply(modelview, projection); + + glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP)); + glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f); + glUniform1i(currentShader.mapTexture0Loc, 0); + + // NOTE: Additional map textures not considered for default buffers drawing } - else + + // Draw lines buffers + if (lines.vCounter > 0) { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); - } + glBindTexture(GL_TEXTURE_2D, whiteTexture); - glDrawArrays(GL_LINES, 0, lines.vCounter); - - if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - } + if (vaoSupported) + { + glBindVertexArray(lines.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, lines.vboId[1]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + } - // Draw triangles buffers - if (triangles.vCounter > 0) - { - glBindTexture(GL_TEXTURE_2D, whiteTexture); + glDrawArrays(GL_LINES, 0, lines.vCounter); - if (vaoSupported) - { - glBindVertexArray(triangles.vaoId); - } - else - { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); + if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); } - glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter); + // Draw triangles buffers + if (triangles.vCounter > 0) + { + glBindTexture(GL_TEXTURE_2D, whiteTexture); - if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); - } + if (vaoSupported) + { + glBindVertexArray(triangles.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, triangles.vboId[1]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + } - // Draw quads buffers - if (quads.vCounter > 0) - { - int quadsCount = 0; - int numIndicesToProcess = 0; - int indicesOffset = 0; + glDrawArrays(GL_TRIANGLES, 0, triangles.vCounter); - if (vaoSupported) - { - glBindVertexArray(quads.vaoId); + if (!vaoSupported) glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindTexture(GL_TEXTURE_2D, 0); } - else + + // Draw quads buffers + if (quads.vCounter > 0) { - // Bind vertex attrib: position (shader-location = 0) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); - glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.vertexLoc); - - // Bind vertex attrib: texcoord (shader-location = 1) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]); - glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); - glEnableVertexAttribArray(currentShader.texcoordLoc); - - // Bind vertex attrib: color (shader-location = 3) - glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); - glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); - glEnableVertexAttribArray(currentShader.colorLoc); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); - } + int quadsCount = 0; + int numIndicesToProcess = 0; + int indicesOffset = 0; - //TraceLog(DEBUG, "Draws required per frame: %i", drawsCounter); + if (vaoSupported) + { + glBindVertexArray(quads.vaoId); + } + else + { + // Bind vertex attrib: position (shader-location = 0) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[0]); + glVertexAttribPointer(currentShader.vertexLoc, 3, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.vertexLoc); + + // Bind vertex attrib: texcoord (shader-location = 1) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[1]); + glVertexAttribPointer(currentShader.texcoordLoc, 2, GL_FLOAT, 0, 0, 0); + glEnableVertexAttribArray(currentShader.texcoordLoc); + + // Bind vertex attrib: color (shader-location = 3) + glBindBuffer(GL_ARRAY_BUFFER, quads.vboId[2]); + glVertexAttribPointer(currentShader.colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0); + glEnableVertexAttribArray(currentShader.colorLoc); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]); + } - for (int i = 0; i < drawsCounter; i++) - { - quadsCount = draws[i].vertexCount/4; - numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad + //TraceLog(DEBUG, "Draws required per frame: %i", drawsCounter); - //TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount); + for (int i = 0; i < drawsCounter; i++) + { + quadsCount = draws[i].vertexCount/4; + numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad - glBindTexture(GL_TEXTURE_2D, draws[i].textureId); + //TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount); - // NOTE: The final parameter tells the GPU the offset in bytes from the start of the index buffer to the location of the first index to process -#if defined(GRAPHICS_API_OPENGL_33) - glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*indicesOffset)); -#elif defined(GRAPHICS_API_OPENGL_ES2) - glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*indicesOffset)); -#endif - //GLenum err; - //if ((err = glGetError()) != GL_NO_ERROR) TraceLog(INFO, "OpenGL error: %i", (int)err); //GL_INVALID_ENUM! + glBindTexture(GL_TEXTURE_2D, draws[i].textureId); - indicesOffset += draws[i].vertexCount/4*6; - } + // NOTE: The final parameter tells the GPU the offset in bytes from the start of the index buffer to the location of the first index to process + #if defined(GRAPHICS_API_OPENGL_33) + glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_INT, (GLvoid *)(sizeof(GLuint)*indicesOffset)); + #elif defined(GRAPHICS_API_OPENGL_ES2) + glDrawElements(GL_TRIANGLES, numIndicesToProcess, GL_UNSIGNED_SHORT, (GLvoid *)(sizeof(GLushort)*indicesOffset)); + #endif + //GLenum err; + //if ((err = glGetError()) != GL_NO_ERROR) TraceLog(INFO, "OpenGL error: %i", (int)err); //GL_INVALID_ENUM! - if (!vaoSupported) - { - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } + indicesOffset += draws[i].vertexCount/4*6; + } - glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures - } + if (!vaoSupported) + { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } - if (vaoSupported) glBindVertexArray(0); // Unbind VAO + glBindTexture(GL_TEXTURE_2D, 0); // Unbind textures + } - glUseProgram(0); // Unbind shader program + if (vaoSupported) glBindVertexArray(0); // Unbind VAO + glUseProgram(0); // Unbind shader program + } + // Reset draws counter drawsCounter = 1; draws[0].textureId = whiteTexture; @@ -3529,6 +3560,10 @@ void rlglDrawDefaultBuffers(void) // Reset depth for next draw currentDepth = -1.0f; + + // Restore projection/modelview matrices + projection = matProjection; + modelview = matModelView; } // Unload default internal buffers vertex data from CPU and GPU diff --git a/src/rlgl.h b/src/rlgl.h index 675bb74f..f52af6f9 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -303,9 +303,6 @@ void rlglClose(void); // De-init rlgl void rlglDraw(void); // Draw VAO/VBO void rlglLoadExtensions(void *loader); // Load OpenGL extensions -void rlglUpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data -void rlglDrawDefaultBuffers(void); // Draw default internal buffers vertex data - unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments) void rlglUpdateTexture(unsigned int id, int width, int height, int format, void *data); // Update GPU texture with new data @@ -358,7 +355,6 @@ void TraceLog(int msgType, const char *text, ...); void InitOculusDevice(void); // Init Oculus Rift device void CloseOculusDevice(void); // Close Oculus Rift device void UpdateOculusTracking(void); // Update Oculus Rift tracking (position and orientation) -void SetOculusView(int eye); // Set internal projection and modelview matrix depending on eyes tracking data void BeginOculusDrawing(void); // Begin Oculus drawing configuration void EndOculusDrawing(void); // End Oculus drawing process (and desktop mirror) bool IsOculusReady(void); // Detect if oculus device (or simulator) is ready -- cgit v1.2.3 From 884e13ac2faea7ea91af1fa5a4c1cfaf44dfb4af Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 8 Jul 2016 20:32:06 +0200 Subject: Updated VR support -IN PROGRESS- - Embedded VR distortion shader - Ready to support multiple VR devices - Fallback to VR Simulator if device not ready - Support mono rendering over stereo rendering --- examples/resources/shaders/glsl100/distortion.fs | 20 +- examples/resources/shaders/glsl330/distortion.fs | 21 +- src/rlgl.c | 505 +++++++++++++---------- src/shader_distortion.h | 91 ++++ 4 files changed, 376 insertions(+), 261 deletions(-) create mode 100644 src/shader_distortion.h (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index a0a6cc18..f19c88ae 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -8,28 +8,16 @@ varying vec2 fragTexCoord; // Input uniform values uniform sampler2D texture0; -// NOTE: Add here your custom variables +// NOTE: Default parameters for Oculus Rift device const vec2 LeftLensCenter = vec2(0.2863248, 0.5); const vec2 RightLensCenter = vec2(0.7136753, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); -const vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -const vec2 ScaleIn = vec2(4, 2.2222); -const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); +const vec2 Scale = vec2(0.25, 0.45); +const vec2 ScaleIn = vec2(4.0, 2.2222); +const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); -/* -// Another set of default values -ChromaAbCorrection = {1.0, 0.0, 1.0, 0} -DistortionK = {1.0, 0.22, 0.24, 0} -Scale = {0.25, 0.5*AspectRatio, 0, 0} -ScaleIn = {4.0, 2/AspectRatio, 0, 0} -Left Screen Center = {0.25, 0.5, 0, 0} -Left Lens Center = {0.287994117, 0.5, 0, 0} -Right Screen Center = {0.75, 0.5, 0, 0} -Right Lens Center = {0.712005913, 0.5, 0, 0} -*/ - void main() { // The following two variables need to be set per eye diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index 62856341..635b86ac 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -9,29 +9,16 @@ uniform sampler2D texture0; // Output fragment color out vec4 finalColor; -// NOTE: Add here your custom variables +// NOTE: Default parameters for Oculus Rift device const vec2 LeftLensCenter = vec2(0.288, 0.5); const vec2 RightLensCenter = vec2(0.712, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); -uniform vec2 Scale = vec2(0.25, 0.45); //vec2(0.1469278, 0.2350845); -uniform vec2 ScaleIn = vec2(4, 2.2222); - -const vec4 HmdWarpParam = vec4(1, 0.22, 0.24, 0); +const vec2 Scale = vec2(0.25, 0.45); +const vec2 ScaleIn = vec2(4.0, 2.2222); +const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); -/* -// Another set of default values -ChromaAbCorrection = {1.0, 0.0, 1.0, 0} -DistortionK = {1.0, 0.22, 0.24, 0} -Scale = {0.25, 0.5*AspectRatio, 0, 0} -ScaleIn = {4.0, 2/AspectRatio, 0, 0} -Left Screen Center = {0.25, 0.5, 0, 0} -Left Lens Center = {0.287994117, 0.5, 0, 0} -Right Screen Center = {0.75, 0.5, 0, 0} -Right Lens Center = {0.712005913, 0.5, 0, 0} -*/ - void main() { // The following two variables need to be set per eye diff --git a/src/rlgl.c b/src/rlgl.c index 25a6745c..7cb6a751 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -74,7 +74,11 @@ #endif #if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_STANDARD_SHADER) - #include "standard_shader.h" // Standard shader to embed + #include "shader_standard.h" // Standard shader to be embedded +#endif + +#if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_DISTORTION_SHADER) + #include "shader_distortion.h" // Distortion shader to be embedded #endif //#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code @@ -288,13 +292,14 @@ static OculusMirror mirror; // Oculus mirror texture and fbo static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain #endif -static bool oculusReady = false; // Oculus device ready flag -static bool oculusSimulator = false; // Oculus device simulator -static bool vrEnabled = false; // VR experience enabled (Oculus device or simulator) -static bool vrControl = true; // VR controlled by user code, instead of internally +static bool vrDeviceReady = false; // VR device ready flag +static bool vrSimulator = false; // VR simulator enabled flag +static bool vrEnabled = false; // VR experience enabled (device or simulator) +static bool vrRendering = true; // VR stereo rendering enabled/disabled flag + // NOTE: This flag is useful to render data over stereo image (i.e. FPS) -static RenderTexture2D stereoFbo; -static Shader distortionShader; +static RenderTexture2D stereoFbo; // Stereo rendering framebuffer +static Shader distortionShader; // Stereo rendering distortion shader (simulator) // Compressed textures support flags static bool texCompDXTSupported = false; // DDS texture compression support @@ -335,12 +340,12 @@ static void UpdateDefaultBuffers(void); // Update default internal buffers ( static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers vertex data static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU +// Configure stereo rendering (including distortion shader) with HMD device parameters +static void SetupVrDevice(VrDeviceInfo info); + // Set internal projection and modelview matrix depending on eyes tracking data static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); -// Configure stereo rendering (including distortion shader) with HMD device parameters -static void SetupVrDevice(VrDeviceInfo hmd); - static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array static char *ReadTextFile(const char *fileName); @@ -1233,7 +1238,7 @@ void rlglDraw(void) // NOTE: Default buffers upload and draw UpdateDefaultBuffers(); - if (vrEnabled && vrControl) DrawDefaultBuffers(2); + if (vrEnabled && vrRendering) DrawDefaultBuffers(2); else DrawDefaultBuffers(1); #endif } @@ -2532,66 +2537,65 @@ void DestroyLight(Light light) // NOTE: If device is not available, it fallbacks to default device (simulator) void InitVrDevice(int hmdDevice) { -#if defined(RLGL_OCULUS_SUPPORT) - // Initialize Oculus device - ovrResult result = ovr_Initialize(NULL); - if (OVR_FAILURE(result)) + switch (hmdDevice) { - TraceLog(WARNING, "OVR: Could not initialize Oculus device"); - oculusReady = false; - } - else - { - result = ovr_Create(&session, &luid); - if (OVR_FAILURE(result)) + case HMD_DEFAULT_DEVICE: TraceLog(INFO, "Initializing default VR Device (Oculus Rift CV1)"); + case HMD_OCULUS_RIFT_DK2: + case HMD_OCULUS_RIFT_CV1: { - TraceLog(WARNING, "OVR: Could not create Oculus session"); - ovr_Shutdown(); - oculusReady = false; - } - else - { - hmdDesc = ovr_GetHmdDesc(session); - - TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); - TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); - TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); - TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); - //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); - TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); - - // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... - // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) - - // Initialize Oculus Buffers - layer = InitOculusLayer(session); - buffer = LoadOculusBuffer(session, layer.width, layer.height); - mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... - layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); - - // Recenter OVR tracking origin - ovr_RecenterTrackingOrigin(session); - - oculusReady = true; - vrEnabled = true; - } - } +#if defined(RLGL_OCULUS_SUPPORT) + vrDeviceReady = InitOculusDevice(); #else - oculusReady = false; + TraceLog(WARNING, "Oculus Rift not supported by default, recompile raylib with Oculus support"); #endif + } break; + case HMD_VALVE_HTC_VIVE: + case HMD_SAMSUNG_GEAR_VR: + case HMD_GOOGLE_CARDBOARD: + case HMD_SONY_PLAYSTATION_VR: + case HMD_RAZER_OSVR: + case HMD_FOVE_VR: TraceLog(WARNING, "VR Device not supported"); + default: break; + } - if (!oculusReady) + if (!vrDeviceReady) { - TraceLog(WARNING, "HMD Device not found: Initializing VR simulator"); + TraceLog(WARNING, "VR Device not found: Initializing VR Simulator"); // Initialize framebuffer and textures for stereo rendering stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight); - // Load oculus-distortion shader (oculus parameters setup internally) - // TODO: Embed coulus distortion shader (in this function like default shader?) - distortionShader = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/distortion.fs"); + // Load distortion shader (initialized by default with Oculus Rift CV1 parameters) + distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr); + if (distortionShader.id != 0) LoadDefaultShaderLocations(&distortionShader); + + VrDeviceInfo info = { 0 }; - oculusSimulator = true; + if ((hmdDevice == HMD_DEFAULT_DEVICE) || + (hmdDevice == HMD_OCULUS_RIFT_DK2) || + (hmdDevice == HMD_OCULUS_RIFT_CV1)) + { + info.hResolution = 1280; // HMD horizontal resolution in pixels + info.vResolution = 800; // HMD vertical resolution in pixels + info.hScreenSize = 0.14976f;; // HMD horizontal size in meters + info.vScreenSize = 0.09356f; // HMD vertical size in meters + info.vScreenCenter = 0.04675f; // HMD screen center in meters + info.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters + info.lensSeparationDistance = 0.0635f; // HMD lens separation distance in meters + info.interpupillaryDistance = 0.064f; // HMD IPD (distance between pupils) in meters + info.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0 + info.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1 + info.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2 + info.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3 + info.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0 + info.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1 + info.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2 + info.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3 + } + + SetupVrDevice(info); + + vrSimulator = true; vrEnabled = true; } } @@ -2600,14 +2604,7 @@ void InitVrDevice(int hmdDevice) void CloseVrDevice(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) - { - UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer - UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers - - ovr_Destroy(session); // Free Oculus session data - ovr_Shutdown(); // Close Oculus device connection - } + if (vrDeviceReady) CloseOculusDevice(); else #endif { @@ -2618,13 +2615,13 @@ void CloseVrDevice(void) UnloadShader(distortionShader); } - oculusReady = false; + vrDeviceReady = false; } // Detect if VR device is available bool IsVrDeviceReady(void) { - return (oculusReady || oculusSimulator) && vrEnabled; + return (vrDeviceReady || vrSimulator) && vrEnabled; } // Enable/Disable VR experience (device or simulator) @@ -2637,27 +2634,7 @@ void ToggleVrMode(void) void UpdateVrTracking(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) - { - frameIndex++; - - ovrPosef eyePoses[2]; - ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); - - layer.eyeLayer.RenderPose[0] = eyePoses[0]; - layer.eyeLayer.RenderPose[1] = eyePoses[1]; - - // Get session status information - ovrSessionStatus sessionStatus; - ovr_GetSessionStatus(session, &sessionStatus); - - if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); - if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); - //if (sessionStatus.HmdPresent) // HMD is present. - //if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR. - //if (sessionStatus.HmdMounted) // HMD is on the user's head. - //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD. - } + if (vrDeviceReady) UpdateOculusTracking(); else #endif { @@ -2665,116 +2642,13 @@ void UpdateVrTracking(void) } } -// Set internal projection and modelview matrix depending on eyes tracking data -static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) -{ - if (vrEnabled) - { - Matrix eyeProjection = matProjection; - Matrix eyeModelView = matModelView; - -#if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) - { - rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, - layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); - - Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, - layer.eyeLayer.RenderPose[eye].Orientation.y, - layer.eyeLayer.RenderPose[eye].Orientation.z, - layer.eyeLayer.RenderPose[eye].Orientation.w }; - QuaternionInvert(&eyeRenderPose); - Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); - Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, - -layer.eyeLayer.RenderPose[eye].Position.y, - -layer.eyeLayer.RenderPose[eye].Position.z); - - Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement - eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement - - eyeProjection = layer.eyeProjections[eye]; - } - else -#endif - { - // Setup viewport and projection/modelview matrices using tracking data - rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); - - static float IPD = 0.064f; // InterpupillaryDistance - float HScreenSize = 0.14976f; - float VScreenSize = 0.09356f; // HScreenSize/(1280.0f/800.0f) (DK2) - float VScreenCenter = 0.04675f; // VScreenSize/2 - float EyeToScreenDistance = 0.041f; - float LensSeparationDistance = 0.0635f; //0.0635f (DK2) - - // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) - float halfScreenDistance = VScreenSize/2.0f; - float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG; - - float viewCenter = (float)HScreenSize*0.25f; - float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f; - float projectionCenterOffset = eyeProjectionShift/(float)HScreenSize; //4.0f*eyeProjectionShift/(float)HScreenSize; -/* - static float scale[2] = { 0.25, 0.45 }; - - if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01; - else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01; - else if (IsKeyDown(KEY_UP)) scale[1] += 0.01; - else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01; - - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2); - - if (IsKeyDown(KEY_N)) IPD += 0.02; - else if (IsKeyDown(KEY_M)) IPD -= 0.02; -*/ - // The matrixes for offsetting the projection and view for each eye, to achieve stereo effect - Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f }; - - // Camera movement might seem more natural if we model the head. - // Our axis of rotation is the base of our head, so we might want to add - // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions. - Vector3 viewOffset = { -IPD/2.0f, 0.075f, 0.045f }; - - // Negate the left eye versions - if (eye == 0) - { - projectionOffset.x *= -1.0f; - viewOffset.x *= -1.0f; - } - - // Adjust the view and projection matrixes - // View matrix is translated based on the eye offset - Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); - - Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z); - Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z); - - eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection - eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview - - MatrixTranspose(&eyeProjection); - } - - SetMatrixModelview(eyeModelView); - SetMatrixProjection(eyeProjection); - } -} - // Begin Oculus drawing configuration void BeginVrDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) + if (vrDeviceReady) { - GLuint currentTexId; - int currentIndex; - - ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); - ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0); - //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded + BeginOculusDrawing(); } else #endif @@ -2792,26 +2666,16 @@ void BeginVrDrawing(void) //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye) rlClearScreenBuffers(); // Clear current framebuffer(s) - vrControl = true; + vrRendering = true; } // End Oculus drawing process (and desktop mirror) void EndVrDrawing(void) { #if defined(RLGL_OCULUS_SUPPORT) - if (oculusReady) + if (vrDeviceReady) { - // Unbind current framebuffer (Oculus buffer) - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - - ovr_CommitTextureSwapChain(session, buffer.textureChain); - - ovrLayerHeader *layers = &layer.eyeLayer.Header; - ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); - - // Blit mirror texture to back buffer - BlitOculusMirror(session, mirror); + EndOculusDrawing(); } else #endif @@ -2869,7 +2733,7 @@ void EndVrDrawing(void) rlDisableDepthTest(); - vrControl = false; + vrRendering = false; } //---------------------------------------------------------------------------------- @@ -3890,25 +3754,34 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) // Configure stereo rendering (including distortion shader) with HMD device parameters static void SetupVrDevice(VrDeviceInfo hmd) { + // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) + //float fovy = 2.0f*atan((VScreenSize*0.5f)/EyeToScreenDistance)*RAD2DEG; + + //float eyeProjectionShift = ; + //float projectionOffset = (HScreenSize*0.25f - LensSeparationDistance*0.5f)/(float)HScreenSize; + // Compute aspect ratio and FOV - float aspect = ((float)hmd.hResolution/2.0f)/(float)hmd.vResolution; + //float aspect = ((float)hmd.hResolution/2.0f)/(float)hmd.vResolution; + float aspect = (float)screenWidth*0.5f/(float)screenHeight; // Fov-y is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)*RAD2DEG // ...but with lens distortion it is increased (see Oculus SDK Documentation) float radius = -1.0 - (4*(hmd.hScreenSize/4 - hmd.lensSeparationDistance/2)/hmd.hScreenSize); float distScale = (hmd.distortionK[0] + hmd.distortionK[1]*pow(radius, 2) + hmd.distortionK[2]*pow(radius, 4) + hmd.distortionK[3]*pow(radius, 6)); - float fovy = 2*atan2(hmd.vScreenSize*distScale, 2*hmd.eyeToScreenDistance)*RAD2DEG; + //float fovy = 2.0f*atan2(hmd.vScreenSize*distScale, 2*hmd.eyeToScreenDistance)*RAD2DEG; + float fovy = 2.0f*atan((hmd.vScreenSize*0.5f)/hmd.eyeToScreenDistance)*RAD2DEG; // Compute camera projection matrices - Matrix proj = MatrixPerspective(fovy, aspect, 0.1, 10000); - float projOffset = 4*(hmd.hScreenSize/4 - hmd.interpupillaryDistance/2)/hmd.hScreenSize; + Matrix proj = MatrixPerspective(fovy, aspect, 0.01, 1000.0); + //float projOffset = 4.0f*(hmd.hScreenSize/4 - hmd.interpupillaryDistance/2)/hmd.hScreenSize; + float projOffset = (hmd.hScreenSize*0.25f - hmd.lensSeparationDistance*0.5f)/hmd.hScreenSize; - //Matrix projLeft = MatrixMultiply(MatrixTranslation(projOffset, 0.0, 0.0), proj); - //matrix projRight = MatrixMultiply(MatrixTranslation(-projOffset, 0.0, 0.0)), proj); + //Matrix projLeft = MatrixMultiply(MatrixTranslate(projOffset, 0.0, 0.0), proj); + //matrix projRight = MatrixMultiply(MatrixTranslate(-projOffset, 0.0, 0.0)), proj); // Compute camera transformation matrices - //Matrix viewTransformLeft = MatrixTranslation(-hmd.interpupillaryDistance/2, 0.0, 0.0 ); - //Matrix viewTransformRight = MatrixTranslation(hmd.interpupillaryDistance/2, 0.0, 0.0 ); + //Matrix viewTransformLeft = MatrixTranslate(-hmd.interpupillaryDistance/2, 0.0, 0.0 ); + //Matrix viewTransformRight = MatrixTranslate(hmd.interpupillaryDistance/2, 0.0, 0.0 ); // Compute eyes Viewports // Rectangle viewportLeft = { 0, 0, hmd.hResolution/2, hmd.vResolution }; @@ -3916,50 +3789,226 @@ static void SetupVrDevice(VrDeviceInfo hmd) // Distortion shader parameters float lensShift = 4*(hmd.hScreenSize/4 - hmd.lensSeparationDistance/2)/hmd.hScreenSize; - float leftLensCenter[2] = { lensShift, 0.0f }; - float rightLensCenter[2] = { -lensShift, 0.0f }; + float leftLensCenter[2] = { lensShift, 0.0f }; // REVIEW!!! + float rightLensCenter[2] = { -lensShift, 0.0f }; // REVIEW!!! float leftScreenCenter[2] = { 0.25f, 0.5f }; float rightScreenCenter[2] = { 0.75f, 0.5f }; - float scaleIn[2] = { 1.0f, 1.0f/aspect }; - float scale[2] = { 1.0f/distScale, 1.0f*aspect/distScale }; + float scaleIn[2] = { 1.0f, 1.0f/aspect }; // REVIEW!!! + float scale[2] = { 1.0f/distScale, 1.0f*aspect/distScale }; // REVIEW!!! // Distortion shader parameters update - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "leftLensCenter"), leftLensCenter, 2); - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "rightLensCenter"), rightLensCenter, 2); + //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "leftLensCenter"), leftLensCenter, 2); + //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "rightLensCenter"), rightLensCenter, 2); SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "leftScreenCenter"), leftScreenCenter, 2); SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "rightScreenCenter"), rightScreenCenter, 2); - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scale"), scale, 2); - SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scaleIn"), scaleIn, 2); + //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scale"), scale, 2); + //SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "scaleIn"), scaleIn, 2); SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "hmdWarpParam"), hmd.distortionK, 4); SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, 4); } +// Set internal projection and modelview matrix depending on eyes tracking data +static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView) +{ + if (vrEnabled) + { + Matrix eyeProjection = matProjection; + Matrix eyeModelView = matModelView; + #if defined(RLGL_OCULUS_SUPPORT) -static void InitOculusDevice(void) + if (vrDeviceReady) + { + rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y, + layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h); + + Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x, + layer.eyeLayer.RenderPose[eye].Orientation.y, + layer.eyeLayer.RenderPose[eye].Orientation.z, + layer.eyeLayer.RenderPose[eye].Orientation.w }; + QuaternionInvert(&eyeRenderPose); + Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose); + Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x, + -layer.eyeLayer.RenderPose[eye].Position.y, + -layer.eyeLayer.RenderPose[eye].Position.z); + + Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement + eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement + + eyeProjection = layer.eyeProjections[eye]; + } + else +#endif + { + // Setup viewport and projection/modelview matrices using tracking data + rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight); + + float HScreenSize = 0.14976f; + float VScreenSize = 0.09356f; // HScreenSize/(1280.0f/800.0f) (DK2) + float VScreenCenter = 0.04675f; // VScreenSize/2 + float EyeToScreenDistance = 0.041f; + float LensSeparationDistance = 0.0635f; // DK2 + float InterpupillaryDistance = 0.064f; // IPD + + // NOTE: fovy value obtained from device parameters (Oculus Rift CV1) + float halfScreenDistance = VScreenSize/2.0f; + float fovy = 2.0f*atan(halfScreenDistance/EyeToScreenDistance)*RAD2DEG; + + float viewCenter = (float)HScreenSize*0.25f; + float eyeProjectionShift = viewCenter - LensSeparationDistance*0.5f; + float projectionCenterOffset = eyeProjectionShift/(float)HScreenSize; //4.0f*eyeProjectionShift/(float)HScreenSize; +/* + static float scale[2] = { 0.25, 0.45 }; + + if (IsKeyDown(KEY_RIGHT)) scale[0] += 0.01; + else if (IsKeyDown(KEY_LEFT)) scale[0] -= 0.01; + else if (IsKeyDown(KEY_UP)) scale[1] += 0.01; + else if (IsKeyDown(KEY_DOWN)) scale[1] -= 0.01; + + SetShaderValue(distortionShader, GetShaderLocation(distortionShader, "Scale"), scale, 2); + + if (IsKeyDown(KEY_N)) IPD += 0.02; + else if (IsKeyDown(KEY_M)) IPD -= 0.02; +*/ + // The matrixes for offsetting the projection and view for each eye, to achieve stereo effect + Vector3 projectionOffset = { -projectionCenterOffset, 0.0f, 0.0f }; + + // Camera movement might seem more natural if we model the head. + // Our axis of rotation is the base of our head, so we might want to add + // some y (base of head to eye level) and -z (center of head to eye protrusion) to the camera positions. + Vector3 viewOffset = { -InterpupillaryDistance/2.0f, 0.075f, 0.045f }; + + // Negate the left eye versions + if (eye == 0) + { + projectionOffset.x *= -1.0f; + viewOffset.x *= -1.0f; + } + + // Adjust the view and projection matrixes + // View matrix is translated based on the eye offset + Matrix projCenter = MatrixPerspective(fovy, (double)((float)screenWidth*0.5f)/(double)screenHeight, 0.01, 1000.0); + + Matrix projTranslation = MatrixTranslate(projectionOffset.x, projectionOffset.y, projectionOffset.z); + Matrix viewTranslation = MatrixTranslate(viewOffset.x, viewOffset.y, viewOffset.z); + + eyeProjection = MatrixMultiply(projCenter, projTranslation); // projection + eyeModelView = MatrixMultiply(matModelView, viewTranslation); // modelview + + MatrixTranspose(&eyeProjection); + } + + SetMatrixModelview(eyeModelView); + SetMatrixProjection(eyeProjection); + } +} + +#if defined(RLGL_OCULUS_SUPPORT) +// Initialize Oculus device +static bool InitOculusDevice(void) { + bool oculusReady = false; + + ovrResult result = ovr_Initialize(NULL); + + if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device"); + else + { + result = ovr_Create(&session, &luid); + if (OVR_FAILURE(result)) + { + TraceLog(WARNING, "OVR: Could not create Oculus session"); + ovr_Shutdown(); + } + else + { + hmdDesc = ovr_GetHmdDesc(session); + + TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName); + TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer); + TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId); + TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type); + //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber); + TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h); + + // NOTE: Oculus mirror is set to defined screenWidth and screenHeight... + // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2) + + // Initialize Oculus Buffers + layer = InitOculusLayer(session); + buffer = LoadOculusBuffer(session, layer.width, layer.height); + mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded... + layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain); + + // Recenter OVR tracking origin + ovr_RecenterTrackingOrigin(session); + + oculusReady = true; + vrEnabled = true; + } + } + return oculusReady; } static void CloseOculusDevice(void) { - + UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer + UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers + + ovr_Destroy(session); // Free Oculus session data + ovr_Shutdown(); // Close Oculus device connection } static void UpdateOculusTracking(void) { + frameIndex++; + + ovrPosef eyePoses[2]; + ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime); + + layer.eyeLayer.RenderPose[0] = eyePoses[0]; + layer.eyeLayer.RenderPose[1] = eyePoses[1]; + // Get session status information + ovrSessionStatus sessionStatus; + ovr_GetSessionStatus(session, &sessionStatus); + + if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit..."); + if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session); + //if (sessionStatus.HmdPresent) // HMD is present. + //if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR. + //if (sessionStatus.HmdMounted) // HMD is on the user's head. + //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD. } static void BeginOculusDrawing(void) { + GLuint currentTexId; + int currentIndex; + ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, ¤tIndex); + ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, ¤tTexId); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0); + //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded } static void EndOculusDrawing(void) { + // Unbind current framebuffer (Oculus buffer) + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + ovr_CommitTextureSwapChain(session, buffer.textureChain); + + ovrLayerHeader *layers = &layer.eyeLayer.Header; + ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1); + + // Blit mirror texture to back buffer + BlitOculusMirror(session, mirror); } // Load Oculus required buffers: texture-swap-chain, fbo, texture-depth diff --git a/src/shader_distortion.h b/src/shader_distortion.h new file mode 100644 index 00000000..e4ce5d6c --- /dev/null +++ b/src/shader_distortion.h @@ -0,0 +1,91 @@ + +// Vertex shader definition to embed, no external file required +static const char vDistortionShaderStr[] = +#if defined(GRAPHICS_API_OPENGL_21) +"#version 120 \n" +#elif defined(GRAPHICS_API_OPENGL_ES2) +"#version 100 \n" +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +"attribute vec3 vertexPosition; \n" +"attribute vec2 vertexTexCoord; \n" +"attribute vec4 vertexColor; \n" +"varying vec2 fragTexCoord; \n" +"varying vec4 fragColor; \n" +#elif defined(GRAPHICS_API_OPENGL_33) +"#version 330 \n" +"in vec3 vertexPosition; \n" +"in vec2 vertexTexCoord; \n" +"in vec4 vertexColor; \n" +"out vec2 fragTexCoord; \n" +"out vec4 fragColor; \n" +#endif +"uniform mat4 mvpMatrix; \n" +"void main() \n" +"{ \n" +" fragTexCoord = vertexTexCoord; \n" +" fragColor = vertexColor; \n" +" gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); \n" +"} \n"; + +// Fragment shader definition to embed, no external file required +static const char fDistortionShaderStr[] = +#if defined(GRAPHICS_API_OPENGL_21) +"#version 120 \n" +#elif defined(GRAPHICS_API_OPENGL_ES2) +"#version 100 \n" +"precision mediump float; \n" // precision required for OpenGL ES2 (WebGL) +#endif +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +"varying vec2 fragTexCoord; \n" +"varying vec4 fragColor; \n" +#elif defined(GRAPHICS_API_OPENGL_33) +"#version 330 \n" +"in vec2 fragTexCoord; \n" +"in vec4 fragColor; \n" +"out vec4 finalColor; \n" +#endif +"uniform sampler2D texture0; \n" +"uniform vec2 leftLensCenter = vec2(0.288, 0.5); \n" +"uniform vec2 rightLensCenter = vec2(0.712, 0.5); \n" +"uniform vec2 leftScreenCenter = vec2(0.25, 0.5); \n" +"uniform vec2 rightScreenCenter = vec2(0.75, 0.5); \n" +"uniform vec2 scale = vec2(0.25, 0.45); \n" +"uniform vec2 scaleIn = vec2(4, 2.2222); \n" +"uniform vec4 hmdWarpParam = vec4(1, 0.22, 0.24, 0); \n" +"uniform vec4 chromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); \n" +"void main() \n" +"{ \n" +" vec2 lensCenter = fragTexCoord.x < 0.5 ? leftLensCenter : rightLensCenter; \n" +" vec2 screenCenter = fragTexCoord.x < 0.5 ? leftScreenCenter : rightScreenCenter; \n" +" vec2 theta = (fragTexCoord - lensCenter)*scaleIn; \n" +" float rSq = theta.x*theta.x + theta.y*theta.y; \n" +" vec2 theta1 = theta*(hmdWarpParam.x + hmdWarpParam.y*rSq + hmdWarpParam.z*rSq*rSq + hmdWarpParam.w*rSq*rSq*rSq); \n" +" vec2 thetaBlue = theta1*(chromaAbParam.z + chromaAbParam.w*rSq); \n" +" vec2 tcBlue = lensCenter + scale*thetaBlue; \n" +" if (any(bvec2(clamp(tcBlue, screenCenter - vec2(0.25, 0.5), screenCenter + vec2(0.25, 0.5)) - tcBlue))) \n" +" { \n" +" finalColor = vec4(0.0, 0.0, 0.0, 1.0); \n" +" } \n" +" else \n" +" { \n" +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +" float blue = texture2D(texture0, tcBlue).b; \n" +" vec2 tcGreen = lensCenter + scale*theta1; \n" +" float green = texture2D(texture0, tcGreen).g; \n" +#elif defined(GRAPHICS_API_OPENGL_33) +" float blue = texture(texture0, tcBlue).b; \n" +" vec2 tcGreen = lensCenter + scale*theta1; \n" +" float green = texture(texture0, tcGreen).g; \n" +#endif +" vec2 thetaRed = theta1*(chromaAbParam.x + chromaAbParam.y*rSq); \n" +" vec2 tcRed = lensCenter + scale*thetaRed; \n" +#if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) +" float red = texture2D(texture0, tcRed).r; \n" +" gl_FragColor = vec4(red, green, blue, 1.0); \n" +#elif defined(GRAPHICS_API_OPENGL_33) +" float red = texture(texture0, tcRed).r; \n" +" finalColor = vec4(red, green, blue, 1.0); \n" +#endif +" } \n" +"} \n"; -- cgit v1.2.3 From d587cc0e36a45798bad7ff1c01d7ba84723d011e Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 10 Jul 2016 20:07:54 +0200 Subject: Setup values for Oculus Rift DK2 Oculus Rift CV1 default values seem not to be available... --- examples/core_oculus_rift.c | 4 ++-- examples/resources/shaders/glsl100/distortion.fs | 4 ++-- examples/resources/shaders/glsl330/distortion.fs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'examples/resources') diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index fa70c487..b8a60f7a 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -18,8 +18,8 @@ int main() { // Initialization //-------------------------------------------------------------------------------------- - int screenWidth = 1080; - int screenHeight = 600; + int screenWidth = 1280; + int screenHeight = 800; InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift"); diff --git a/examples/resources/shaders/glsl100/distortion.fs b/examples/resources/shaders/glsl100/distortion.fs index f19c88ae..50116ce0 100644 --- a/examples/resources/shaders/glsl100/distortion.fs +++ b/examples/resources/shaders/glsl100/distortion.fs @@ -8,13 +8,13 @@ varying vec2 fragTexCoord; // Input uniform values uniform sampler2D texture0; -// NOTE: Default parameters for Oculus Rift device +// NOTE: Default parameters for Oculus Rift DK2 device const vec2 LeftLensCenter = vec2(0.2863248, 0.5); const vec2 RightLensCenter = vec2(0.7136753, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); -const vec2 ScaleIn = vec2(4.0, 2.2222); +const vec2 ScaleIn = vec2(4.0, 2.5); const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); diff --git a/examples/resources/shaders/glsl330/distortion.fs b/examples/resources/shaders/glsl330/distortion.fs index 635b86ac..cb4be8fc 100644 --- a/examples/resources/shaders/glsl330/distortion.fs +++ b/examples/resources/shaders/glsl330/distortion.fs @@ -9,13 +9,13 @@ uniform sampler2D texture0; // Output fragment color out vec4 finalColor; -// NOTE: Default parameters for Oculus Rift device -const vec2 LeftLensCenter = vec2(0.288, 0.5); -const vec2 RightLensCenter = vec2(0.712, 0.5); +// NOTE: Default parameters for Oculus Rift DK2 device +const vec2 LeftLensCenter = vec2(0.2863248, 0.5); +const vec2 RightLensCenter = vec2(0.7136753, 0.5); const vec2 LeftScreenCenter = vec2(0.25, 0.5); const vec2 RightScreenCenter = vec2(0.75, 0.5); const vec2 Scale = vec2(0.25, 0.45); -const vec2 ScaleIn = vec2(4.0, 2.2222); +const vec2 ScaleIn = vec2(4.0, 2.5); const vec4 HmdWarpParam = vec4(1.0, 0.22, 0.24, 0.0); const vec4 ChromaAbParam = vec4(0.996, -0.004, 1.014, 0.0); -- cgit v1.2.3 From 3876f19d6a385001a4238ec27bcf3d7643dd190f Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 12 Jul 2016 01:54:47 +0200 Subject: Corrected some issues on OpenGL ES --- examples/Makefile | 5 +++-- examples/models_obj_loading.c | 2 +- examples/resources/shaders/glsl100/grayscale.fs | 4 ++-- examples/resources/shaders/glsl100/swirl.fs | 8 ++++---- examples/resources/shaders/glsl330/swirl.fs | 6 +++--- 5 files changed, 13 insertions(+), 12 deletions(-) (limited to 'examples/resources') diff --git a/examples/Makefile b/examples/Makefile index 711f03a7..d20e229b 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -120,8 +120,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) # libraries for Debian GNU/Linux desktop compiling # requires the following packages: # libglfw3-dev libopenal-dev libegl1-mesa-dev - LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -pthread -ldl -lX11 \ - -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor + LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -pthread -ldl + # on XWindow could require also below libraries, just uncomment + #LIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor else ifeq ($(PLATFORM_OS),OSX) # libraries for OS X 10.9 desktop compiling diff --git a/examples/models_obj_loading.c b/examples/models_obj_loading.c index a6969f70..50d42d2e 100644 --- a/examples/models_obj_loading.c +++ b/examples/models_obj_loading.c @@ -49,7 +49,7 @@ int main() DrawModel(dwarf, position, 2.0f, WHITE); // Draw 3d model with texture - DrawGrid(10, 1.0f); // Draw a grid + DrawGrid(10, 1.0f); // Draw a grid DrawGizmo(position); // Draw gizmo diff --git a/examples/resources/shaders/glsl100/grayscale.fs b/examples/resources/shaders/glsl100/grayscale.fs index cf857488..15174ea5 100644 --- a/examples/resources/shaders/glsl100/grayscale.fs +++ b/examples/resources/shaders/glsl100/grayscale.fs @@ -8,14 +8,14 @@ varying vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // NOTE: Add here your custom variables void main() { // Texel color fetching from texture sampler - vec4 texelColor = texture2D(texture0, fragTexCoord)*fragTintColor*fragColor; + vec4 texelColor = texture2D(texture0, fragTexCoord)*colDiffuse*fragColor; // Convert texel color to grayscale using NTSC conversion weights float gray = dot(texelColor.rgb, vec3(0.299, 0.587, 0.114)); diff --git a/examples/resources/shaders/glsl100/swirl.fs b/examples/resources/shaders/glsl100/swirl.fs index 0d6d24f2..ca7668b2 100644 --- a/examples/resources/shaders/glsl100/swirl.fs +++ b/examples/resources/shaders/glsl100/swirl.fs @@ -8,7 +8,7 @@ varying vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // NOTE: Add here your custom variables @@ -18,7 +18,7 @@ const float renderHeight = 480.0; // Use uniforms instead... float radius = 250.0; float angle = 0.8; -uniform vec2 center = vec2(200.0, 200.0); +uniform vec2 center; void main() { @@ -39,7 +39,7 @@ void main() } tc += center; - vec3 color = texture2D(texture0, tc/texSize).rgb; + vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; - gl_FragColor = vec4(color, 1.0);; + gl_FragColor = vec4(color.rgb, 1.0);; } \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/swirl.fs b/examples/resources/shaders/glsl330/swirl.fs index 80c16cc9..5d238ac9 100644 --- a/examples/resources/shaders/glsl330/swirl.fs +++ b/examples/resources/shaders/glsl330/swirl.fs @@ -6,7 +6,7 @@ in vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // Output fragment color out vec4 finalColor; @@ -40,7 +40,7 @@ void main() } tc += center; - vec3 color = texture(texture0, tc/texSize).rgb; + vec4 color = texture2D(texture0, tc/texSize)*colDiffuse*fragColor;; - finalColor = vec4(color, 1.0);; + finalColor = vec4(color.rgb, 1.0);; } \ No newline at end of file -- cgit v1.2.3 From 8328353204212f754c7ef004a18de7161d91bb89 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 17 Jul 2016 17:27:49 +0200 Subject: New example: XM module playing --- examples/audio_module_playing.c | 138 +++++++++++++++++++++++++++++++++++ examples/audio_module_playing.png | Bin 0 -> 215508 bytes examples/resources/audio/2t2m_spa.xm | Bin 0 -> 2287400 bytes 3 files changed, 138 insertions(+) create mode 100644 examples/audio_module_playing.c create mode 100644 examples/audio_module_playing.png create mode 100644 examples/resources/audio/2t2m_spa.xm (limited to 'examples/resources') diff --git a/examples/audio_module_playing.c b/examples/audio_module_playing.c new file mode 100644 index 00000000..6189b866 --- /dev/null +++ b/examples/audio_module_playing.c @@ -0,0 +1,138 @@ +/******************************************************************************************* +* +* raylib [audio] example - Module playing (streaming) +* +* NOTE: This example requires OpenAL Soft library installed +* +* This example has been created using raylib 1.5 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2016 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define MAX_CIRCLES 64 + +typedef struct { + Vector2 position; + float radius; + float alpha; + float speed; + Color color; +} CircleWave; + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)"); + + InitAudioDevice(); // Initialize audio device + + Color colors[14] = { ORANGE, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, + YELLOW, GREEN, SKYBLUE, PURPLE, BEIGE }; + + // Creates ome circles for visual effect + CircleWave circles[MAX_CIRCLES]; + + for (int i = MAX_CIRCLES - 1; i >= 0; i--) + { + circles[i].alpha = 0.0f; + circles[i].radius = GetRandomValue(10, 40); + circles[i].position.x = GetRandomValue(circles[i].radius, screenWidth - circles[i].radius); + circles[i].position.y = GetRandomValue(circles[i].radius, screenHeight - circles[i].radius); + circles[i].speed = (float)GetRandomValue(1, 100)/20000.0f; + circles[i].color = colors[GetRandomValue(0, 13)]; + } + + // Load postprocessing bloom shader + Shader shader = LoadShader("resources/shaders/glsl330/base.vs", + "resources/shaders/glsl330/bloom.fs"); + + // Create a RenderTexture2D to be used for render to texture + RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight); + + PlayMusicStream(0, "resources/audio/2t2m_spa.xm"); // Play module stream + + float timePlayed = 0.0f; + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + for (int i = MAX_CIRCLES - 1; i >= 0; i--) + { + circles[i].alpha += circles[i].speed; + circles[i].radius += circles[i].speed*10.0f; + + if (circles[i].alpha > 1.0f) circles[i].speed *= -1; + + if (circles[i].alpha <= 0.0f) + { + circles[i].alpha = 0.0f; + circles[i].radius = GetRandomValue(10, 40); + circles[i].position.x = GetRandomValue(circles[i].radius, screenWidth - circles[i].radius); + circles[i].position.y = GetRandomValue(circles[i].radius, screenHeight - circles[i].radius); + circles[i].color = colors[GetRandomValue(0, 13)]; + circles[i].speed = (float)GetRandomValue(1, 100)/20000.0f; + } + } + + // Get timePlayed scaled to bar dimensions + timePlayed = (GetMusicTimePlayed(0)/GetMusicTimeLength(0)*(screenWidth - 40))*2; + + UpdateMusicStream(0); // Update music buffer with new stream data + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(BLACK); + + BeginTextureMode(target); // Enable drawing to texture + + for (int i = MAX_CIRCLES - 1; i >= 0; i--) + { + DrawCircleV(circles[i].position, circles[i].radius, Fade(circles[i].color, circles[i].alpha)); + } + + EndTextureMode(); // End drawing to texture (now we have a texture available for next passes) + + BeginShaderMode(shader); + + // NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom) + DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE); + + EndShaderMode(); + + // Draw time bar + DrawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, LIGHTGRAY); + DrawRectangle(20, screenHeight - 20 - 12, (int)timePlayed, 12, MAROON); + DrawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, WHITE); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(shader); // Unload shader + UnloadRenderTexture(target); // Unload render texture + + CloseAudioDevice(); // Close audio device (music streaming is automatically stopped) + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/audio_module_playing.png b/examples/audio_module_playing.png new file mode 100644 index 00000000..7c2e469f Binary files /dev/null and b/examples/audio_module_playing.png differ diff --git a/examples/resources/audio/2t2m_spa.xm b/examples/resources/audio/2t2m_spa.xm new file mode 100644 index 00000000..fa416ef2 Binary files /dev/null and b/examples/resources/audio/2t2m_spa.xm differ -- cgit v1.2.3 From 9e8232d7503e686f49e55eb388c0e8670e247277 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 25 Jul 2016 19:44:21 +0200 Subject: Redesigned bloom shader to work on RPI --- examples/resources/shaders/glsl100/bloom.fs | 30 +++++++++++++++-------------- examples/resources/shaders/glsl330/bloom.fs | 30 +++++++++++++++-------------- shaders/glsl100/bloom.fs | 28 ++++++++++++++------------- shaders/glsl330/bloom.fs | 28 ++++++++++++++------------- 4 files changed, 62 insertions(+), 54 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl100/bloom.fs b/examples/resources/shaders/glsl100/bloom.fs index 128736f2..a8e1d20f 100644 --- a/examples/resources/shaders/glsl100/bloom.fs +++ b/examples/resources/shaders/glsl100/bloom.fs @@ -8,30 +8,32 @@ varying vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // NOTE: Add here your custom variables +const vec2 size = vec2(800, 450); // render size +const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance +const float quality = 2.5; // lower = smaller glow, better quality + void main() { vec4 sum = vec4(0); - vec4 tc = vec4(0); + vec2 sizeFactor = vec2(1)/size*quality; + + // Texel color fetching from texture sampler + vec4 source = texture2D(texture0, fragTexCoord); - for (int i = -4; i < 4; i++) + const int range = 2; // should be = (samples - 1)/2; + + for (int x = -range; x <= range; x++) { - for (int j = -3; j < 3; j++) + for (int y = -range; y <= range; y++) { - sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25; + sum += texture2D(texture0, fragTexCoord + vec2(x, y)*sizeFactor); } } - - // Texel color fetching from texture sampler - vec4 texelColor = texture2D(texture0, fragTexCoord); - + // Calculate final fragment color - if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; - else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; - else tc = sum*sum*0.0075 + texelColor; - - gl_FragColor = tc; + gl_FragColor = ((sum/(samples*samples)) + source)*colDiffuse; } \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/bloom.fs b/examples/resources/shaders/glsl330/bloom.fs index 0307bc06..333d5b05 100644 --- a/examples/resources/shaders/glsl330/bloom.fs +++ b/examples/resources/shaders/glsl330/bloom.fs @@ -6,33 +6,35 @@ in vec4 fragColor; // Input uniform values uniform sampler2D texture0; -uniform vec4 fragTintColor; +uniform vec4 colDiffuse; // Output fragment color out vec4 finalColor; // NOTE: Add here your custom variables +const vec2 size = vec2(800, 450); // render size +const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance +const float quality = 2.5; // lower = smaller glow, better quality + void main() { vec4 sum = vec4(0); - vec4 tc = vec4(0); + vec2 sizeFactor = vec2(1)/size*quality; + + // Texel color fetching from texture sampler + vec4 source = texture(texture0, fragTexCoord); + + const int range = 2; // should be = (samples - 1)/2; - for (int i = -4; i < 4; i++) + for (int x = -range; x <= range; x++) { - for (int j = -3; j < 3; j++) + for (int y = -range; y <= range; y++) { - sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25; + sum += texture(texture0, fragTexCoord + vec2(x, y)*sizeFactor); } } - - // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord); - - // Calculate final fragment color - if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; - else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; - else tc = sum*sum*0.0075 + texelColor; - finalColor = tc; + // Calculate final fragment color + finalColor = ((sum/(samples*samples)) + source)*colDiffuse; } \ No newline at end of file diff --git a/shaders/glsl100/bloom.fs b/shaders/glsl100/bloom.fs index 82278fc3..a8e1d20f 100644 --- a/shaders/glsl100/bloom.fs +++ b/shaders/glsl100/bloom.fs @@ -12,26 +12,28 @@ uniform vec4 colDiffuse; // NOTE: Add here your custom variables +const vec2 size = vec2(800, 450); // render size +const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance +const float quality = 2.5; // lower = smaller glow, better quality + void main() { vec4 sum = vec4(0); - vec4 tc = vec4(0); + vec2 sizeFactor = vec2(1)/size*quality; + + // Texel color fetching from texture sampler + vec4 source = texture2D(texture0, fragTexCoord); - for (int i = -4; i < 4; i++) + const int range = 2; // should be = (samples - 1)/2; + + for (int x = -range; x <= range; x++) { - for (int j = -3; j < 3; j++) + for (int y = -range; y <= range; y++) { - sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25; + sum += texture2D(texture0, fragTexCoord + vec2(x, y)*sizeFactor); } } - - // Texel color fetching from texture sampler - vec4 texelColor = texture2D(texture0, fragTexCoord); - + // Calculate final fragment color - if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; - else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; - else tc = sum*sum*0.0075 + texelColor; - - gl_FragColor = tc; + gl_FragColor = ((sum/(samples*samples)) + source)*colDiffuse; } \ No newline at end of file diff --git a/shaders/glsl330/bloom.fs b/shaders/glsl330/bloom.fs index 102e6605..333d5b05 100644 --- a/shaders/glsl330/bloom.fs +++ b/shaders/glsl330/bloom.fs @@ -13,26 +13,28 @@ out vec4 finalColor; // NOTE: Add here your custom variables +const vec2 size = vec2(800, 450); // render size +const float samples = 5.0; // pixels per axis; higher = bigger glow, worse performance +const float quality = 2.5; // lower = smaller glow, better quality + void main() { vec4 sum = vec4(0); - vec4 tc = vec4(0); + vec2 sizeFactor = vec2(1)/size*quality; + + // Texel color fetching from texture sampler + vec4 source = texture(texture0, fragTexCoord); + + const int range = 2; // should be = (samples - 1)/2; - for (int i = -4; i < 4; i++) + for (int x = -range; x <= range; x++) { - for (int j = -3; j < 3; j++) + for (int y = -range; y <= range; y++) { - sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25; + sum += texture(texture0, fragTexCoord + vec2(x, y)*sizeFactor); } } - - // Texel color fetching from texture sampler - vec4 texelColor = texture(texture0, fragTexCoord); - - // Calculate final fragment color - if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor; - else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor; - else tc = sum*sum*0.0075 + texelColor; - finalColor = tc; + // Calculate final fragment color + finalColor = ((sum/(samples*samples)) + source)*colDiffuse; } \ No newline at end of file -- cgit v1.2.3 From 68d647c1af1b9f0479f680dbd7c4f93586cd51a2 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Tue, 2 Aug 2016 17:32:24 +0200 Subject: Complete review and update Simplified module for Music and AudioStream Added support for raw audio streaming (with example) --- examples/audio_module_playing.c | 2 +- examples/audio_music_stream.c | 3 - examples/audio_raw_stream.c | 106 ++++++++++++++++ examples/audio_sound_loading.c | 1 - examples/resources/audio/2t2m_spa.xm | Bin 2287400 -> 0 bytes examples/resources/audio/chiptun1.mod | Bin 0 -> 2142 bytes examples/resources/audio/mini1111.xm | Bin 0 -> 25676 bytes src/audio.c | 230 ++++++++++++++++++---------------- src/audio.h | 27 +++- src/raylib.h | 29 ++++- 10 files changed, 277 insertions(+), 121 deletions(-) create mode 100644 examples/audio_raw_stream.c delete mode 100644 examples/resources/audio/2t2m_spa.xm create mode 100644 examples/resources/audio/chiptun1.mod create mode 100644 examples/resources/audio/mini1111.xm (limited to 'examples/resources') diff --git a/examples/audio_module_playing.c b/examples/audio_module_playing.c index 07165c76..fe9ea15c 100644 --- a/examples/audio_module_playing.c +++ b/examples/audio_module_playing.c @@ -57,7 +57,7 @@ int main() // Create a RenderTexture2D to be used for render to texture RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight); - Music xm = LoadMusicStream("resources/audio/2t2m_spa.xm"); + Music xm = LoadMusicStream("resources/audio/mini1111.xm"); PlayMusicStream(xm); diff --git a/examples/audio_music_stream.c b/examples/audio_music_stream.c index 1d86bd1a..c552d030 100644 --- a/examples/audio_music_stream.c +++ b/examples/audio_music_stream.c @@ -59,9 +59,6 @@ int main() SetMusicVolume(volume); } */ - if (IsWindowMinimized()) PauseMusicStream(music); - else ResumeMusicStream(music); - timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*100*4; // We scale by 4 to fit 400 pixels UpdateMusicStream(music); // Update music buffer with new stream data diff --git a/examples/audio_raw_stream.c b/examples/audio_raw_stream.c new file mode 100644 index 00000000..37a5b4ff --- /dev/null +++ b/examples/audio_raw_stream.c @@ -0,0 +1,106 @@ +/******************************************************************************************* +* +* raylib [audio] example - Raw audio streaming +* +* NOTE: This example requires OpenAL Soft library installed +* +* This example has been created using raylib 1.6 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include // Required for: malloc(), free() +#include // Required for: sinf() + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + SetConfigFlags(FLAG_MSAA_4X_HINT); + InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw audio streaming"); + + InitAudioDevice(); // Initialize audio device + + AudioStream stream = InitAudioStream(44100, 32, 1); // Init raw audio stream + + // Fill audio stream with some samples (sine wave) + float *data = (float *)malloc(sizeof(float)*44100); + + for (int i = 0; i < 44100; i++) + { + data[i] = sinf(2*PI*(float)i*DEG2RAD); + } + + PlayAudioStream(stream); + + int totalSamples = 44100; + int samplesLeft = totalSamples; + + Vector2 position = { 0, 0 }; + + SetTargetFPS(30); // Set our game to run at 30 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + + // Refill audio stream if required + if (IsAudioBufferProcessed(stream)) + { + int numSamples = 0; + if (samplesLeft >= 4096) numSamples = 4096; + else numSamples = samplesLeft; + + UpdateAudioStream(stream, data + (totalSamples - samplesLeft), numSamples); + + samplesLeft -= numSamples; + + // Reset samples feeding (loop audio) + if (samplesLeft <= 0) samplesLeft = totalSamples; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("SINE WAVE SHOULD BE PLAYING!", 240, 140, 20, LIGHTGRAY); + + // NOTE: Draw a part of the sine wave (only screen width) + for (int i = 0; i < GetScreenWidth(); i++) + { + position.x = i; + position.y = 250 + 50*data[i]; + + DrawPixelV(position, RED); + } + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + free(data); // Unload sine wave data + + CloseAudioStream(stream); // Close raw audio stream and delete buffers from RAM + + CloseAudioDevice(); // Close audio device (music streaming is automatically stopped) + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/audio_sound_loading.c b/examples/audio_sound_loading.c index 8819aad1..f081e8ed 100644 --- a/examples/audio_sound_loading.c +++ b/examples/audio_sound_loading.c @@ -36,7 +36,6 @@ int main() // Update //---------------------------------------------------------------------------------- if (IsKeyPressed(KEY_SPACE)) PlaySound(fxWav); // Play WAV sound - if (IsKeyPressed(KEY_ENTER)) PlaySound(fxOgg); // Play OGG sound //---------------------------------------------------------------------------------- diff --git a/examples/resources/audio/2t2m_spa.xm b/examples/resources/audio/2t2m_spa.xm deleted file mode 100644 index fa416ef2..00000000 Binary files a/examples/resources/audio/2t2m_spa.xm and /dev/null differ diff --git a/examples/resources/audio/chiptun1.mod b/examples/resources/audio/chiptun1.mod new file mode 100644 index 00000000..00d16885 Binary files /dev/null and b/examples/resources/audio/chiptun1.mod differ diff --git a/examples/resources/audio/mini1111.xm b/examples/resources/audio/mini1111.xm new file mode 100644 index 00000000..a185c1a2 Binary files /dev/null and b/examples/resources/audio/mini1111.xm differ diff --git a/src/audio.c b/src/audio.c index d1c425d5..befed61c 100644 --- a/src/audio.c +++ b/src/audio.c @@ -100,17 +100,6 @@ typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_MODULE_XM, MUSIC_MODULE_MOD } MusicContextType; -// Used to create custom audio streams that are not bound to a specific file. -typedef struct AudioStream { - unsigned int sampleRate; // Frequency (samples per second): default is 48000 - unsigned int sampleSize; // BitDepth (bits per sample): 8, 16, 32 (24 not supported) - unsigned int channels; // Number of channels - - ALenum format; // OpenAL format specifier - ALuint source; // OpenAL source - ALuint buffers[MAX_STREAM_BUFFERS]; // OpenAL buffers (double buffering) -} AudioStream; - // Music type (file streaming from memory) typedef struct Music { MusicContextType ctxType; // Type of music context (OGG, XM, MOD) @@ -118,7 +107,7 @@ typedef struct Music { jar_xm_context_t *ctxXm; // XM chiptune context jar_mod_context_t ctxMod; // MOD chiptune context - AudioStream stream; // Audio stream + AudioStream stream; // Audio stream (double buffering) bool loop; // Repeat music after finish (loop) unsigned int totalSamples; // Total number of samples @@ -141,12 +130,6 @@ static Wave LoadWAV(const char *fileName); // Load WAV file static Wave LoadOGG(char *fileName); // Load OGG file static void UnloadWave(Wave wave); // Unload wave data -static bool BufferMusicStream(Music music, int numBuffersToProcess); // Fill music buffers with data - -static AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); -static void BufferAudioStream(AudioStream stream, void *data, int numSamples); -static void CloseAudioStream(AudioStream stream); - #if defined(AUDIO_STANDALONE) const char *GetExtension(const char *fileName); // Get the extension for a filename void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message (INFO, ERROR, WARNING) @@ -595,33 +578,89 @@ void StopMusicStream(Music music) // Update (re-fill) music buffers if data already processed void UpdateMusicStream(Music music) { - ALenum state; - bool active = true; ALint processed = 0; // Determine if music stream is ready to be written alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); - + + int numBuffersToProcess = processed; + if (processed > 0) { - active = BufferMusicStream(music, processed); + bool active = true; + short pcm[AUDIO_BUFFER_SIZE]; + float pcmf[AUDIO_BUFFER_SIZE]; + + int numSamples = 0; // Total size of data steamed in L+R samples for xm floats, + // individual L or R for ogg shorts + + for (int i = 0; i < numBuffersToProcess; i++) + { + switch (music->ctxType) + { + case MUSIC_AUDIO_OGG: + { + if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE; + else numSamples = music->samplesLeft; + + // NOTE: Returns the number of samples to process (should be the same as numSamples -> it is) + int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, pcm, numSamples); + + // TODO: Review stereo channels Ogg, not enough samples served! + UpdateAudioStream(music->stream, pcm, numSamples*music->stream.channels); + music->samplesLeft -= (numSamples*music->stream.channels); + + } break; + case MUSIC_MODULE_XM: + { + if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2; + else numSamples = music->samplesLeft; + + // NOTE: Output buffer is 2*numsamples elements (left and right value for each sample) + jar_xm_generate_samples(music->ctxXm, pcmf, numSamples); + UpdateAudioStream(music->stream, pcmf, numSamples*2); // Using 32bit PCM data + music->samplesLeft -= numSamples; + + //TraceLog(INFO, "Samples left: %i", music->samplesLeft); + + } break; + case MUSIC_MODULE_MOD: + { + if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2; + else numSamples = music->samplesLeft; + + // NOTE: Output buffer size is nbsample*channels (default: 48000Hz, 16bit, Stereo) + jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); + UpdateAudioStream(music->stream, pcm, numSamples*2); + music->samplesLeft -= numSamples; + + } break; + default: break; + } + if (music->samplesLeft <= 0) + { + active = false; + break; + } + } + + // Reset audio stream for looping if (!active && music->loop) { // Restart music context (if required) + //if (music->ctxType == MUSIC_MODULE_XM) if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_seek_start(&music->ctxMod); else if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_seek_start(music->ctxOgg); + // Reset samples left to total samples music->samplesLeft = music->totalSamples; - - // Determine if music stream is ready to be written - alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); - - active = BufferMusicStream(music, processed); } - if (alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Error buffering data..."); + // This error is registered when UpdateAudioStream() fails + if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data..."); + ALenum state; alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state); if (state != AL_PLAYING && active) alSourcePlay(music->stream.source); @@ -668,36 +707,14 @@ float GetMusicTimePlayed(Music music) { float secondsPlayed = 0.0f; - if (music->ctxType == MUSIC_MODULE_XM) - { - uint64_t samplesPlayed; - jar_xm_get_position(music->ctxXm, NULL, NULL, NULL, &samplesPlayed); - - // TODO: Not sure if this is the correct value - secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); - } - else if (music->ctxType == MUSIC_MODULE_MOD) - { - long samplesPlayed = jar_mod_current_samples(&music->ctxMod); - - secondsPlayed = (float)samplesPlayed/music->stream.sampleRate; - } - else if (music->ctxType == MUSIC_AUDIO_OGG) - { - unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; - - secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); - } + unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; + secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); return secondsPlayed; } -//---------------------------------------------------------------------------------- -// Module specific Functions Definition -//---------------------------------------------------------------------------------- - // Init audio stream (to stream audio pcm data) -static AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels) +AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels) { AudioStream stream = { 0 }; @@ -735,7 +752,7 @@ static AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleS alSource3f(stream.source, AL_POSITION, 0, 0, 0); alSource3f(stream.source, AL_VELOCITY, 0, 0, 0); - // Create Buffers + // Create Buffers (double buffering) alGenBuffers(MAX_STREAM_BUFFERS, stream.buffers); // Initialize buffer with zeros by default @@ -766,7 +783,7 @@ static AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleS } // Close audio stream and free memory -static void CloseAudioStream(AudioStream stream) +void CloseAudioStream(AudioStream stream) { // Stop playing channel alSourceStop(stream.source); @@ -790,75 +807,66 @@ static void CloseAudioStream(AudioStream stream) TraceLog(INFO, "[AUD ID %i] Unloaded audio stream data", stream.source); } -// Push more audio data into audio stream, only one buffer per call -static void BufferAudioStream(AudioStream stream, void *data, int numSamples) -{ +// Update audio stream buffers with data +// NOTE: Only one buffer per call +void UpdateAudioStream(AudioStream stream, void *data, int numSamples) +{ ALuint buffer = 0; alSourceUnqueueBuffers(stream.source, 1, &buffer); - //TraceLog(DEBUG, "Buffer to refill: %i", buffer); + // Check if any buffer was available for unqueue + if (alGetError() != AL_INVALID_VALUE) + { + if (stream.sampleSize == 8) alBufferData(buffer, stream.format, (unsigned char *)data, numSamples*sizeof(unsigned char), stream.sampleRate); + else if (stream.sampleSize == 16) alBufferData(buffer, stream.format, (short *)data, numSamples*sizeof(short), stream.sampleRate); + else if (stream.sampleSize == 32) alBufferData(buffer, stream.format, (float *)data, numSamples*sizeof(float), stream.sampleRate); + + alSourceQueueBuffers(stream.source, 1, &buffer); + } +} + +// Check if any audio stream buffers requires refill +bool IsAudioBufferProcessed(AudioStream stream) +{ + ALint processed = 0; - if (stream.sampleSize == 8) alBufferData(buffer, stream.format, (unsigned char *)data, numSamples*sizeof(unsigned char), stream.sampleRate); - else if (stream.sampleSize == 16) alBufferData(buffer, stream.format, (short *)data, numSamples*sizeof(short), stream.sampleRate); - else if (stream.sampleSize == 32) alBufferData(buffer, stream.format, (float *)data, numSamples*sizeof(float), stream.sampleRate); + // Determine if music stream is ready to be written + alGetSourcei(stream.source, AL_BUFFERS_PROCESSED, &processed); - alSourceQueueBuffers(stream.source, 1, &buffer); + return (processed > 0); } -// Fill music buffers with new data from music stream -static bool BufferMusicStream(Music music, int numBuffersToProcess) +// Play audio stream +void PlayAudioStream(AudioStream stream) { - short pcm[AUDIO_BUFFER_SIZE]; - float pcmf[AUDIO_BUFFER_SIZE]; + alSourcePlay(stream.source); +} - int size = 0; // Total size of data steamed in L+R samples for xm floats, individual L or R for ogg shorts - bool active = true; // We can get more data from stream (not finished) - - for (int i = 0; i < numBuffersToProcess; i++) - { - if (music->samplesLeft >= AUDIO_BUFFER_SIZE) size = AUDIO_BUFFER_SIZE; - else size = music->samplesLeft; +// Play audio stream +void PauseAudioStream(AudioStream stream) +{ + alSourcePause(stream.source); +} - switch (music->ctxType) - { - case MUSIC_AUDIO_OGG: - { - // NOTE: Returns the number of samples to process (should be the same as size) - int numSamples = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, pcm, size); - - BufferAudioStream(music->stream, pcm, numSamples*music->stream.channels); - music->samplesLeft -= (numSamples*music->stream.channels); - - } break; - case MUSIC_MODULE_XM: - { - // NOTE: Output buffer is 2*numsamples elements (left and right value for each sample) - jar_xm_generate_samples(music->ctxXm, pcmf, size/2); - BufferAudioStream(music->stream, pcmf, size); // Using 32bit PCM data - music->samplesLeft -= (size/2); - - } break; - case MUSIC_MODULE_MOD: - { - // NOTE: Output buffer size is nbsample*channels (default: 48000Hz, 16bit, Stereo) - jar_mod_fillbuffer(&music->ctxMod, pcm, size/2, 0); - BufferAudioStream(music->stream, pcm, size); - music->samplesLeft -= (size/2); - - } break; - default: break; - } +// Resume audio stream playing +void ResumeAudioStream(AudioStream stream) +{ + ALenum state; + alGetSourcei(stream.source, AL_SOURCE_STATE, &state); - if (music->samplesLeft <= 0) - { - active = false; - break; - } - } - - return active; + if (state == AL_PAUSED) alSourcePlay(stream.source); } +// Stop audio stream +void StopAudioStream(AudioStream stream) +{ + alSourceStop(stream.source); +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + // Load WAV file into Wave structure static Wave LoadWAV(const char *fileName) { diff --git a/src/audio.h b/src/audio.h index c9171339..dbd88939 100644 --- a/src/audio.h +++ b/src/audio.h @@ -76,9 +76,21 @@ typedef struct Wave { } Wave; // Music type (file streaming from memory) -// NOTE: Anything longer than ~10 seconds should be streamed into a mix channel... +// NOTE: Anything longer than ~10 seconds should be streamed typedef struct Music *Music; +// Audio stream type +// NOTE: Useful to create custom audio streams not bound to a specific file +typedef struct AudioStream { + unsigned int sampleRate; // Frequency (samples per second) + unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + unsigned int channels; // Number of channels (1-mono, 2-stereo) + + int format; // OpenAL audio format specifier + unsigned int source; // OpenAL audio source id + unsigned int buffers[2]; // OpenAL audio buffers (double buffering) +} AudioStream; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -93,7 +105,7 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- void InitAudioDevice(void); // Initialize audio device and context void CloseAudioDevice(void); // Close the audio device and context (and music stream) -bool IsAudioDeviceReady(void); // Check if device has been initialized successfully +bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully Sound LoadSound(char *fileName); // Load sound to memory Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data @@ -120,6 +132,17 @@ void SetMusicPitch(Music music, float pitch); // Set pitch for float GetMusicTimeLength(Music music); // Get music time length (in seconds) float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) +AudioStream InitAudioStream(unsigned int sampleRate, + unsigned int sampleSize, + unsigned int channels); // Init audio stream (to stream audio pcm data) +void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +void CloseAudioStream(AudioStream stream); // Close audio stream and free memory +bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill +void PlayAudioStream(AudioStream stream); // Play audio stream +void PauseAudioStream(AudioStream stream); // Pause audio stream +void ResumeAudioStream(AudioStream stream); // Resume audio stream +void StopAudioStream(AudioStream stream); // Stop audio stream + #ifdef __cplusplus } #endif diff --git a/src/raylib.h b/src/raylib.h index 4b9f6ca0..3ee7a793 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -499,8 +499,8 @@ typedef struct Ray { // Sound source type typedef struct Sound { - unsigned int source; // Sound audio source id - unsigned int buffer; // Sound audio buffer id + unsigned int source; // OpenAL audio source id + unsigned int buffer; // OpenAL audio buffer id } Sound; // Wave type, defines audio wave data @@ -516,6 +516,18 @@ typedef struct Wave { // NOTE: Anything longer than ~10 seconds should be streamed typedef struct Music *Music; +// Audio stream type +// NOTE: Useful to create custom audio streams not bound to a specific file +typedef struct AudioStream { + unsigned int sampleRate; // Frequency (samples per second) + unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + unsigned int channels; // Number of channels (1-mono, 2-stereo) + + int format; // OpenAL audio format specifier + unsigned int source; // OpenAL audio source id + unsigned int buffers[2]; // OpenAL audio buffers (double buffering) +} AudioStream; + // Texture formats // NOTE: Support depends on OpenGL version and platform typedef enum { @@ -923,7 +935,7 @@ void ToggleVrMode(void); // Enable/Disable VR experience (dev //------------------------------------------------------------------------------------ void InitAudioDevice(void); // Initialize audio device and context void CloseAudioDevice(void); // Close the audio device and context (and music stream) -bool IsAudioDeviceReady(void); // True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet +bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully Sound LoadSound(char *fileName); // Load sound to memory Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data @@ -950,6 +962,17 @@ void SetMusicPitch(Music music, float pitch); // Set pitch for float GetMusicTimeLength(Music music); // Get music time length (in seconds) float GetMusicTimePlayed(Music music); // Get current music time played (in seconds) +AudioStream InitAudioStream(unsigned int sampleRate, + unsigned int sampleSize, + unsigned int channels); // Init audio stream (to stream audio pcm data) +void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +void CloseAudioStream(AudioStream stream); // Close audio stream and free memory +bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill +void PlayAudioStream(AudioStream stream); // Play audio stream +void PauseAudioStream(AudioStream stream); // Pause audio stream +void ResumeAudioStream(AudioStream stream); // Resume audio stream +void StopAudioStream(AudioStream stream); // Stop audio stream + #ifdef __cplusplus } #endif -- cgit v1.2.3 From 478d3cbb79caa27351cf9e9a5ff9925ca658a89c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 21 Sep 2016 12:28:49 +0200 Subject: Added standard shader for testing --- examples/resources/shaders/glsl100/standard.fs | 161 +++++++++++++++++++++++++ examples/resources/shaders/glsl100/standard.vs | 23 ++++ examples/resources/shaders/glsl330/standard.fs | 150 +++++++++++++++++++++++ examples/resources/shaders/glsl330/standard.vs | 23 ++++ 4 files changed, 357 insertions(+) create mode 100644 examples/resources/shaders/glsl100/standard.fs create mode 100644 examples/resources/shaders/glsl100/standard.vs create mode 100644 examples/resources/shaders/glsl330/standard.fs create mode 100644 examples/resources/shaders/glsl330/standard.vs (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl100/standard.fs b/examples/resources/shaders/glsl100/standard.fs new file mode 100644 index 00000000..6ce2a186 --- /dev/null +++ b/examples/resources/shaders/glsl100/standard.fs @@ -0,0 +1,161 @@ +#version 100 + +precision mediump float; + +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform sampler2D texture2; + +uniform vec4 colAmbient; +uniform vec4 colDiffuse; +uniform vec4 colSpecular; +uniform float glossiness; + +uniform int useNormal; +uniform int useSpecular; + +uniform mat4 modelMatrix; +uniform vec3 viewDir; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 direction; + vec4 diffuse; + float intensity; + float radius; + float coneAngle; +}; + +const int maxLights = 8; +uniform Light lights[maxLights]; + +vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s) +{ +/* + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1.0)); + vec3 surfaceToLight = l.position - surfacePos; + + // Diffuse shading + float brightness = clamp(float(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n))), 0.0, 1.0); + float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(-l.direction + v); + spec = pow(dot(n, h), 3.0 + glossiness)*s; + } + + return (diff*l.diffuse.rgb + spec*colSpecular.rgb); +*/ + return vec3(0.5); +} + +vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s) +{ +/* + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3.0 + glossiness)*s; + } + + // Combine results + return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); +*/ + return vec3(0.5); +} + +vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s) +{ +/* + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 lightToSurface = normalize(surfacePos - l.position); + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity; + + // Spot attenuation + float attenuation = clamp(float(dot(n, lightToSurface)), 0.0, 1.0); + attenuation = dot(lightToSurface, -lightDir); + + float lightToSurfaceAngle = degrees(acos(attenuation)); + if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + + float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; + + // Combine diffuse and attenuation + float diffAttenuation = diff*attenuation; + + // Specular shading + float spec = 0.0; + if (diffAttenuation > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3.0 + glossiness)*s; + } + + return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); +*/ + return vec3(0.5); +} + +void main() +{ + // Calculate fragment normal in screen space + // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) + mat3 normalMatrix = mat3(modelMatrix); + vec3 normal = normalize(normalMatrix*fragNormal); + + // Normalize normal and view direction vectors + vec3 n = normalize(normal); + vec3 v = normalize(viewDir); + + // Calculate diffuse texture color fetching + vec4 texelColor = texture2D(texture0, fragTexCoord); + vec3 lighting = colAmbient.rgb; + + // Calculate normal texture color fetching or set to maximum normal value by default + if (useNormal == 1) + { + n *= texture2D(texture1, fragTexCoord).rgb; + n = normalize(n); + } + + // Calculate specular texture color fetching or set to maximum specular value by default + float spec = 1.0; + if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r); + + for (int i = 0; i < maxLights; i++) + { + // Check if light is enabled + if (lights[i].enabled == 1) + { + // Calculate lighting based on light type + if(lights[i].type == 0) lighting += ComputeLightPoint(lights[i], n, v, spec); + else if(lights[i].type == 1) lighting += ComputeLightDirectional(lights[i], n, v, spec); + else if(lights[i].type == 2) lighting += ComputeLightSpot(lights[i], n, v, spec); + + // NOTE: It seems that too many ComputeLight*() operations inside for loop breaks the shader on RPI + } + } + + // Calculate final fragment color + gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); +} diff --git a/examples/resources/shaders/glsl100/standard.vs b/examples/resources/shaders/glsl100/standard.vs new file mode 100644 index 00000000..49c5a3eb --- /dev/null +++ b/examples/resources/shaders/glsl100/standard.vs @@ -0,0 +1,23 @@ +#version 100 + +attribute vec3 vertexPosition; +attribute vec3 vertexNormal; +attribute vec2 vertexTexCoord; +attribute vec4 vertexColor; + +varying vec3 fragPosition; +varying vec2 fragTexCoord; +varying vec4 fragColor; +varying vec3 fragNormal; + +uniform mat4 mvpMatrix; + +void main() +{ + fragPosition = vertexPosition; + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = vertexNormal; + + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file diff --git a/examples/resources/shaders/glsl330/standard.fs b/examples/resources/shaders/glsl330/standard.fs new file mode 100644 index 00000000..14497839 --- /dev/null +++ b/examples/resources/shaders/glsl330/standard.fs @@ -0,0 +1,150 @@ +#version 330 + +in vec3 fragPosition; +in vec2 fragTexCoord; +in vec4 fragColor; +in vec3 fragNormal; + +out vec4 finalColor; + +uniform sampler2D texture0; +uniform sampler2D texture1; +uniform sampler2D texture2; + +uniform vec4 colAmbient; +uniform vec4 colDiffuse; +uniform vec4 colSpecular; +uniform float glossiness; + +uniform int useNormal; +uniform int useSpecular; + +uniform mat4 modelMatrix; +uniform vec3 viewDir; + +struct Light { + int enabled; + int type; + vec3 position; + vec3 direction; + vec4 diffuse; + float intensity; + float radius; + float coneAngle; +}; + +const int maxLights = 8; +uniform Light lights[maxLights]; + +vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 surfaceToLight = l.position - surfacePos; + + // Diffuse shading + float brightness = clamp(float(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n))), 0.0, 1.0); + float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(-l.direction + v); + spec = pow(dot(n, h), 3.0 + glossiness)*s; + } + + return (diff*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s) +{ + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity; + + // Specular shading + float spec = 0.0; + if (diff > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3.0 + glossiness)*s; + } + + // Combine results + return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); +} + +vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s) +{ + vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); + vec3 lightToSurface = normalize(surfacePos - l.position); + vec3 lightDir = normalize(-l.direction); + + // Diffuse shading + float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity; + + // Spot attenuation + float attenuation = clamp(float(dot(n, lightToSurface)), 0.0, 1.0); + attenuation = dot(lightToSurface, -lightDir); + + float lightToSurfaceAngle = degrees(acos(attenuation)); + if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0; + + float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle; + + // Combine diffuse and attenuation + float diffAttenuation = diff*attenuation; + + // Specular shading + float spec = 0.0; + if (diffAttenuation > 0.0) + { + vec3 h = normalize(lightDir + v); + spec = pow(dot(n, h), 3.0 + glossiness)*s; + } + + return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); +} + +void main() +{ + // Calculate fragment normal in screen space + // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale) + mat3 normalMatrix = mat3(modelMatrix); + vec3 normal = normalize(normalMatrix*fragNormal); + + // Normalize normal and view direction vectors + vec3 n = normalize(normal); + vec3 v = normalize(viewDir); + + // Calculate diffuse texture color fetching + vec4 texelColor = texture(texture0, fragTexCoord); + vec3 lighting = colAmbient.rgb; + + // Calculate normal texture color fetching or set to maximum normal value by default + if (useNormal == 1) + { + n *= texture(texture1, fragTexCoord).rgb; + n = normalize(n); + } + + // Calculate specular texture color fetching or set to maximum specular value by default + float spec = 1.0; + if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); + + for (int i = 0; i < maxLights; i++) + { + // Check if light is enabled + if (lights[i].enabled == 1) + { + // Calculate lighting based on light type + if (lights[i].type == 0) lighting += ComputeLightPoint(lights[i], n, v, spec); + else if (lights[i].type == 1) lighting += ComputeLightDirectional(lights[i], n, v, spec); + else if (lights[i].type == 2) lighting += ComputeLightSpot(lights[i], n, v, spec); + } + } + + // Calculate final fragment color + finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a); +} diff --git a/examples/resources/shaders/glsl330/standard.vs b/examples/resources/shaders/glsl330/standard.vs new file mode 100644 index 00000000..fc0a5ff4 --- /dev/null +++ b/examples/resources/shaders/glsl330/standard.vs @@ -0,0 +1,23 @@ +#version 330 + +in vec3 vertexPosition; +in vec3 vertexNormal; +in vec2 vertexTexCoord; +in vec4 vertexColor; + +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec4 fragColor; +out vec3 fragNormal; + +uniform mat4 mvpMatrix; + +void main() +{ + fragPosition = vertexPosition; + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = vertexNormal; + + gl_Position = mvpMatrix*vec4(vertexPosition, 1.0); +} \ No newline at end of file -- cgit v1.2.3 From 97e3277d58060df96cd002b1377a51ca4adcbb9e Mon Sep 17 00:00:00 2001 From: Ray Date: Tue, 11 Oct 2016 00:39:07 +0200 Subject: Updated standard shader Corrects weird artifacts on web --- examples/resources/shaders/glsl100/standard.fs | 17 ++++------------- examples/resources/shaders/glsl330/standard.fs | 8 ++++---- src/shader_standard.h | 10 +++++----- 3 files changed, 13 insertions(+), 22 deletions(-) (limited to 'examples/resources') diff --git a/examples/resources/shaders/glsl100/standard.fs b/examples/resources/shaders/glsl100/standard.fs index 6ce2a186..fe604e2a 100644 --- a/examples/resources/shaders/glsl100/standard.fs +++ b/examples/resources/shaders/glsl100/standard.fs @@ -38,7 +38,6 @@ uniform Light lights[maxLights]; vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s) { -/* vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1.0)); vec3 surfaceToLight = l.position - surfacePos; @@ -51,17 +50,14 @@ vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s) if (diff > 0.0) { vec3 h = normalize(-l.direction + v); - spec = pow(dot(n, h), 3.0 + glossiness)*s; + spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s; } return (diff*l.diffuse.rgb + spec*colSpecular.rgb); -*/ - return vec3(0.5); } vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s) { -/* vec3 lightDir = normalize(-l.direction); // Diffuse shading @@ -72,18 +68,15 @@ vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s) if (diff > 0.0) { vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3.0 + glossiness)*s; + spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s; } // Combine results return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb); -*/ - return vec3(0.5); } vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s) { -/* vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1)); vec3 lightToSurface = normalize(surfacePos - l.position); vec3 lightDir = normalize(-l.direction); @@ -108,12 +101,10 @@ vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s) if (diffAttenuation > 0.0) { vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3.0 + glossiness)*s; + spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s; } return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); -*/ - return vec3(0.5); } void main() @@ -140,7 +131,7 @@ void main() // Calculate specular texture color fetching or set to maximum specular value by default float spec = 1.0; - if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r); + if (useSpecular == 1) spec = texture2D(texture2, fragTexCoord).r; for (int i = 0; i < maxLights; i++) { diff --git a/examples/resources/shaders/glsl330/standard.fs b/examples/resources/shaders/glsl330/standard.fs index 14497839..0d461484 100644 --- a/examples/resources/shaders/glsl330/standard.fs +++ b/examples/resources/shaders/glsl330/standard.fs @@ -50,7 +50,7 @@ vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s) if (diff > 0.0) { vec3 h = normalize(-l.direction + v); - spec = pow(dot(n, h), 3.0 + glossiness)*s; + spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s; } return (diff*l.diffuse.rgb + spec*colSpecular.rgb); @@ -68,7 +68,7 @@ vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s) if (diff > 0.0) { vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3.0 + glossiness)*s; + spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s; } // Combine results @@ -101,7 +101,7 @@ vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s) if (diffAttenuation > 0.0) { vec3 h = normalize(lightDir + v); - spec = pow(dot(n, h), 3.0 + glossiness)*s; + spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s; } return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb)); @@ -131,7 +131,7 @@ void main() // Calculate specular texture color fetching or set to maximum specular value by default float spec = 1.0; - if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r); + if (useSpecular == 1) spec = texture(texture2, fragTexCoord).r; for (int i = 0; i < maxLights; i++) { diff --git a/src/shader_standard.h b/src/shader_standard.h index deae7fe1..995c62ea 100644 --- a/src/shader_standard.h +++ b/src/shader_standard.h @@ -90,7 +90,7 @@ static const char fStandardShaderStr[] = " if (diff > 0.0)\n" " {\n" " vec3 h = normalize(-l.direction + v);\n" -" spec = pow(dot(n, h), 3.0 + glossiness)*s;\n" +" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n" " }\n" " return (diff*l.diffuse.rgb + spec*colSpecular.rgb);\n" "}\n" @@ -103,7 +103,7 @@ static const char fStandardShaderStr[] = " if (diff > 0.0)\n" " {\n" " vec3 h = normalize(lightDir + v);\n" -" spec = pow(dot(n, h), 3.0 + glossiness)*s;\n" +" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n" " }\n" " return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);\n" "}\n" @@ -124,7 +124,7 @@ static const char fStandardShaderStr[] = " if (diffAttenuation > 0.0)\n" " {\n" " vec3 h = normalize(lightDir + v);\n" -" spec = pow(dot(n, h), 3.0 + glossiness)*s;\n" +" spec = pow(abs(dot(n, h)), 3.0 + glossiness)*s;\n" " }\n" " return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));\n" "}\n" @@ -152,9 +152,9 @@ static const char fStandardShaderStr[] = " }\n" " float spec = 1.0;\n" #if defined(GRAPHICS_API_OPENGL_ES2) || defined(GRAPHICS_API_OPENGL_21) -" if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r);\n" +" if (useSpecular == 1) spec = texture2D(texture2, fragTexCoord).r;\n" #elif defined(GRAPHICS_API_OPENGL_33) -" if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);\n" +" if (useSpecular == 1) spec = texture(texture2, fragTexCoord).r;\n" #endif " for (int i = 0; i < maxLights; i++)\n" " {\n" -- cgit v1.2.3 From 3be81b01d7463a63d59dd575b7f5d7c267e3c086 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 2 Nov 2016 13:39:58 +0100 Subject: Brand new gamepad example --- examples/core_input_gamepad.c | 165 ++++++++++++++++++++++++++++++++++++------ examples/resources/ps3.png | Bin 0 -> 19345 bytes examples/resources/xbox.png | Bin 0 -> 16177 bytes 3 files changed, 142 insertions(+), 23 deletions(-) create mode 100644 examples/resources/ps3.png create mode 100644 examples/resources/xbox.png (limited to 'examples/resources') diff --git a/examples/core_input_gamepad.c b/examples/core_input_gamepad.c index 6c356829..77d11f38 100644 --- a/examples/core_input_gamepad.c +++ b/examples/core_input_gamepad.c @@ -3,17 +3,29 @@ * raylib [core] example - Gamepad input * * NOTE: This example requires a Gamepad connected to the system -* raylib is configured to work with Xbox 360 gamepad, check raylib.h for buttons configuration +* raylib is configured to work with the following gamepads: +* Xbox 360 Controller (Xbox 360, Xbox One) +* PLAYSTATION(R)3 Controller +* Check raylib.h for buttons configuration * -* This example has been created using raylib 1.0 (www.raylib.com) +* This example has been created using raylib 1.6 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * -* Copyright (c) 2014 Ramon Santamaria (@raysan5) +* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5) * ********************************************************************************************/ #include "raylib.h" +// NOTE: Gamepad name ID depends on drivers and OS +#if defined(PLATFORM_RPI) + #define XBOX360_NAME_ID "Microsoft X-Box 360 pad" + #define PS3_NAME_ID "PLAYSTATION(R)3 Controller" +#else + #define XBOX360_NAME_ID "Xbox 360 Controller" + #define PS3_NAME_ID "PLAYSTATION(R)3 Controller" +#endif + int main() { // Initialization @@ -21,12 +33,14 @@ int main() int screenWidth = 800; int screenHeight = 450; + SetConfigFlags(FLAG_MSAA_4X_HINT); // Set MSAA 4X hint before windows creation + InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad input"); + + Texture2D texPs3Pad = LoadTexture("resources/ps3.png"); + Texture2D texXboxPad = LoadTexture("resources/xbox.png"); - Vector2 ballPosition = { (float)screenWidth/2, (float)screenHeight/2 }; - Vector2 gamepadMovement = { 0.0f, 0.0f }; - - SetTargetFPS(60); // Set target frames-per-second + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -34,20 +48,7 @@ int main() { // Update //---------------------------------------------------------------------------------- - if (IsGamepadAvailable(GAMEPAD_PLAYER1)) - { - gamepadMovement.x = GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LEFT_X); - gamepadMovement.y = GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LEFT_Y); - - ballPosition.x += gamepadMovement.x; - ballPosition.y -= gamepadMovement.y; - - if (IsGamepadButtonPressed(GAMEPAD_PLAYER1, GAMEPAD_BUTTON_A)) - { - ballPosition.x = (float)screenWidth/2; - ballPosition.y = (float)screenHeight/2; - } - } + // ... //---------------------------------------------------------------------------------- // Draw @@ -55,10 +56,125 @@ int main() BeginDrawing(); ClearBackground(RAYWHITE); + + if (IsGamepadAvailable(GAMEPAD_PLAYER1)) + { + DrawText(FormatText("GP1: %s", GetGamepadName(GAMEPAD_PLAYER1)), 10, 10, 10, BLACK); + + if (IsGamepadName(GAMEPAD_PLAYER1, XBOX360_NAME_ID)) + { + DrawTexture(texXboxPad, 0, 0, DARKGRAY); + + // Draw buttons: xbox home + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_HOME)) DrawCircle(396, 222, 13, RED); - DrawText("move the ball with gamepad", 10, 10, 20, DARKGRAY); + // Draw buttons: basic + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_START)) DrawCircle(436, 150, 9, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_SELECT)) DrawCircle(352, 150, 9, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_X)) DrawCircle(501, 151, 15, BLUE); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_A)) DrawCircle(536, 187, 15, LIME); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_B)) DrawCircle(572, 151, 15, MAROON); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_Y)) DrawCircle(536, 115, 15, GOLD); + + // Draw buttons: d-pad + DrawRectangle(317, 202, 19, 71, BLACK); + DrawRectangle(293, 228, 69, 19, BLACK); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_UP)) DrawRectangle(317, 202, 19, 26, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_DOWN)) DrawRectangle(317, 202 + 45, 19, 26, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_LEFT)) DrawRectangle(292, 228, 25, 19, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_RIGHT)) DrawRectangle(292 + 44, 228, 26, 19, RED); + + // Draw buttons: left-right back + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_LB)) DrawCircle(259, 61, 20, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_XBOX_BUTTON_RB)) DrawCircle(536, 61, 20, RED); - DrawCircleV(ballPosition, 50, MAROON); + // Draw axis: left joystick + DrawCircle(259, 152, 39, BLACK); + DrawCircle(259, 152, 34, LIGHTGRAY); + DrawCircle(259 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LEFT_X)*20), + 152 - (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LEFT_Y)*20), 25, BLACK); + + // Draw axis: right joystick + DrawCircle(461, 237, 38, BLACK); + DrawCircle(461, 237, 33, LIGHTGRAY); + DrawCircle(461 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_RIGHT_X)*20), + 237 - (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_RIGHT_Y)*20), 25, BLACK); + + // Draw axis: left-right triggers + DrawRectangle(170, 30, 15, 70, GRAY); + DrawRectangle(604, 30, 15, 70, GRAY); + DrawRectangle(170, 30, 15, (((1.0f + GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LT))/2.0f)*70), RED); + DrawRectangle(604, 30, 15, (((1.0f + GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_RT))/2.0f)*70), RED); + + //DrawText(FormatText("Xbox axis LT: %02.02f", GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_LT)), 10, 40, 10, BLACK); + //DrawText(FormatText("Xbox axis RT: %02.02f", GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_XBOX_AXIS_RT)), 10, 60, 10, BLACK); + } + else if (IsGamepadName(GAMEPAD_PLAYER1, PS3_NAME_ID)) + { + DrawTexture(texPs3Pad, 0, 0, DARKGRAY); + + // Draw buttons: ps + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_PS)) DrawCircle(396, 222, 13, RED); + + // Draw buttons: basic + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_SELECT)) DrawRectangle(328, 170, 32, 13, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_START)) DrawTriangle((Vector2){ 436, 168 }, (Vector2){ 436, 185 }, (Vector2){ 464, 177 }, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_TRIANGLE)) DrawCircle(557, 144, 13, LIME); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_CIRCLE)) DrawCircle(586, 173, 13, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_CROSS)) DrawCircle(557, 203, 13, VIOLET); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_SQUARE)) DrawCircle(527, 173, 13, PINK); + + // Draw buttons: d-pad + DrawRectangle(225, 132, 24, 84, BLACK); + DrawRectangle(195, 161, 84, 25, BLACK); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_UP)) DrawRectangle(225, 132, 24, 29, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_DOWN)) DrawRectangle(225, 132 + 54, 24, 30, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_LEFT)) DrawRectangle(195, 161, 30, 25, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_RIGHT)) DrawRectangle(195 + 54, 161, 30, 25, RED); + + // Draw buttons: left-right back buttons + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_L1)) DrawCircle(239, 82, 20, RED); + if (IsGamepadButtonDown(GAMEPAD_PLAYER1, GAMEPAD_PS3_BUTTON_R1)) DrawCircle(557, 82, 20, RED); + + // Draw axis: left joystick + DrawCircle(319, 255, 35, BLACK); + DrawCircle(319, 255, 31, LIGHTGRAY); + DrawCircle(319 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_X)*20), + 255 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_Y)*20), 25, BLACK); + + // Draw axis: right joystick + DrawCircle(475, 255, 35, BLACK); + DrawCircle(475, 255, 31, LIGHTGRAY); + DrawCircle(475 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_RIGHT_X)*20), + 255 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_RIGHT_Y)*20), 25, BLACK); + + // Draw axis: left-right triggers + DrawRectangle(169, 48, 15, 70, GRAY); + DrawRectangle(611, 48, 15, 70, GRAY); + DrawRectangle(169, 48, 15, (((1.0f - GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_L2))/2.0f)*70), RED); + DrawRectangle(611, 48, 15, (((1.0f - GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_R2))/2.0f)*70), RED); + } + else + { + // TODO: Draw generic gamepad + } + + DrawText(FormatText("DETECTED AXIS [%i]:", GetGamepadAxisCount(GAMEPAD_PLAYER1)), 10, 50, 10, MAROON); + + for (int i = 0; i < GetGamepadAxisCount(GAMEPAD_PLAYER1); i++) + { + DrawText(FormatText("AXIS %i: %.02f", i, GetGamepadAxisMovement(GAMEPAD_PLAYER1, i)), 20, 70 + 20*i, 10, DARKGRAY); + } + + if (GetGamepadButtonPressed() != -1) DrawText(FormatText("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 10, 430, 10, RED); + else DrawText("DETECTED BUTTON: NONE", 10, 430, 10, GRAY); + } + else + { + DrawText("GP1: NOT DETECTED", 10, 10, 10, GRAY); + + DrawTexture(texXboxPad, 0, 0, LIGHTGRAY); + } EndDrawing(); //---------------------------------------------------------------------------------- @@ -66,6 +182,9 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- + UnloadTexture(texPs3Pad); + UnloadTexture(texXboxPad); + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/resources/ps3.png b/examples/resources/ps3.png new file mode 100644 index 00000000..98befacc Binary files /dev/null and b/examples/resources/ps3.png differ diff --git a/examples/resources/xbox.png b/examples/resources/xbox.png new file mode 100644 index 00000000..029c9109 Binary files /dev/null and b/examples/resources/xbox.png differ -- cgit v1.2.3 From 0603e59cae0da924d7fe811b078972e04cdfe1e9 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Fri, 18 Nov 2016 14:05:49 +0100 Subject: Review examples and added new ones --- examples/Makefile | 24 ++++++- examples/audio_raw_stream.png | Bin 0 -> 16736 bytes examples/audio_standalone.c | 12 ++-- examples/core_drop_files.c | 2 +- examples/core_input_gamepad.png | Bin 10840 -> 38066 bytes examples/core_oculus_rift.c | 6 +- examples/resources/fonts/KAISG.ttf | Bin 0 -> 79912 bytes examples/text_ttf_loading.c | 125 +++++++++++++++++++++++++++++++++++++ examples/text_ttf_loading.png | Bin 0 -> 55588 bytes 9 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 examples/audio_raw_stream.png create mode 100644 examples/resources/fonts/KAISG.ttf create mode 100644 examples/text_ttf_loading.c create mode 100644 examples/text_ttf_loading.png (limited to 'examples/resources') diff --git a/examples/Makefile b/examples/Makefile index 378f5edf..da29e915 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -2,6 +2,8 @@ # # raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten) # +# NOTE: By default examples are compiled using raylib static library and OpenAL Soft shared library +# # Copyright (c) 2013-2016 Ramon Santamaria (@raysan5) # # This software is provided "as-is", without any express or implied warranty. In no event @@ -26,6 +28,9 @@ # WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop() PLATFORM ?= PLATFORM_DESKTOP +# define NO to use OpenAL Soft as static library (shared by default) +SHARED_OPENAL ?= YES + # determine PLATFORM_OS in case PLATFORM_DESKTOP selected ifeq ($(PLATFORM),PLATFORM_DESKTOP) # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows @@ -62,12 +67,13 @@ endif # define compiler flags: # -O2 defines optimization level +# -s strip unnecessary data from build # -Wall turns on most, but not all, compiler warnings # -std=c99 use standard C from 1999 revision ifeq ($(PLATFORM),PLATFORM_RPI) - CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline + CFLAGS = -O2 -s -Wall -std=gnu99 -fgnu89-inline else - CFLAGS = -O2 -Wall -std=c99 + CFLAGS = -O2 -s -Wall -std=c99 endif ifeq ($(PLATFORM),PLATFORM_WEB) CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 -s ASSERTIONS=1 --preload-file resources @@ -151,7 +157,14 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP) else # libraries for Windows desktop compiling # NOTE: GLFW3 and OpenAL Soft libraries should be installed - LIBS = -lraylib -lglfw3 -lopengl32 -lopenal32 -lgdi32 + LIBS = -lraylib -lglfw3 -lopengl32 -lgdi32 + # if static OpenAL Soft required, define the corresponding libs + ifeq ($(SHARED_OPENAL),NO) + LIBS += -lopenal32 -lwinmm + CFLAGS += -Wl,-allow-multiple-definition + else + LIBS += -lopenal32dll + endif endif endif endif @@ -215,6 +228,7 @@ EXAMPLES = \ text_format_text \ text_font_select \ text_writing_anim \ + text_ttf_loading \ models_geometric_shapes \ models_box_collisions \ models_billboard \ @@ -400,6 +414,10 @@ text_font_select: text_font_select.c text_writing_anim: text_writing_anim.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) +# compile [text] example - text ttf loading +text_ttf_loading: text_ttf_loading.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + # compile [models] example - basic geometric 3d shapes models_geometric_shapes: models_geometric_shapes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) diff --git a/examples/audio_raw_stream.png b/examples/audio_raw_stream.png new file mode 100644 index 00000000..344f4a71 Binary files /dev/null and b/examples/audio_raw_stream.png differ diff --git a/examples/audio_standalone.c b/examples/audio_standalone.c index c716faed..7688b881 100644 --- a/examples/audio_standalone.c +++ b/examples/audio_standalone.c @@ -32,6 +32,8 @@ int main() { + // Initialization + //-------------------------------------------------------------------------------------- unsigned char key; InitAudioDevice(); @@ -43,7 +45,9 @@ int main() PlayMusicStream(music); printf("\nPress s or d to play sounds...\n"); - + //-------------------------------------------------------------------------------------- + + // Main loop while (key != KEY_ESCAPE) { if (kbhit()) key = getch(); @@ -63,15 +67,15 @@ int main() UpdateMusicStream(music); } + // De-Initialization + //-------------------------------------------------------------------------------------- UnloadSound(fxWav); // Unload sound data UnloadSound(fxOgg); // Unload sound data UnloadMusicStream(music); // Unload music stream data CloseAudioDevice(); - - printf("\n\nPress ENTER to close..."); - getchar(); + //-------------------------------------------------------------------------------------- return 0; } \ No newline at end of file diff --git a/examples/core_drop_files.c b/examples/core_drop_files.c index 5eea35f3..5c1501b8 100644 --- a/examples/core_drop_files.c +++ b/examples/core_drop_files.c @@ -23,7 +23,7 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - drop files"); int count = 0; - char **droppedFiles; + char **droppedFiles = { 0 }; SetTargetFPS(60); //-------------------------------------------------------------------------------------- diff --git a/examples/core_input_gamepad.png b/examples/core_input_gamepad.png index f7e55658..5996eece 100644 Binary files a/examples/core_input_gamepad.png and b/examples/core_input_gamepad.png differ diff --git a/examples/core_oculus_rift.c b/examples/core_oculus_rift.c index 7276e3de..eb628cd7 100644 --- a/examples/core_oculus_rift.c +++ b/examples/core_oculus_rift.c @@ -47,10 +47,10 @@ int main() { // Update //---------------------------------------------------------------------------------- - if (IsVrSimulator()) UpdateCamera(&camera); // Update camera (simulator mode) - else UpdateVrTracking(&camera); // Update camera with device tracking data + if (IsVrSimulator()) UpdateCamera(&camera); // Update camera (simulator mode) + else if (IsVrDeviceReady()) UpdateVrTracking(&camera); // Update camera with device tracking data - if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); // Toggle VR mode + if (IsKeyPressed(KEY_SPACE)) ToggleVrMode(); // Toggle VR mode //---------------------------------------------------------------------------------- // Draw diff --git a/examples/resources/fonts/KAISG.ttf b/examples/resources/fonts/KAISG.ttf new file mode 100644 index 00000000..04478b25 Binary files /dev/null and b/examples/resources/fonts/KAISG.ttf differ diff --git a/examples/text_ttf_loading.c b/examples/text_ttf_loading.c new file mode 100644 index 00000000..1135619e --- /dev/null +++ b/examples/text_ttf_loading.c @@ -0,0 +1,125 @@ +/******************************************************************************************* +* +* raylib [text] example - TTF loading and usage +* +* This example has been created using raylib 1.3.0 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +********************************************************************************************/ + +#include "raylib.h" +#include + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [text] example - ttf loading"); + + const char msg1[50] = "TTF SpriteFont"; + + // NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required) + + // TTF SpriteFont loading with custom generation parameters + SpriteFont font = LoadSpriteFontTTF("resources/fonts/KAISG.ttf", 96, 0, 0); + + float fontSize = font.size; + Vector2 fontPosition = { 40, screenHeight/2 + 50 }; + Vector2 textSize; + + int currentFontFilter = 0; // FILTER_POINT + + int count = 0; + char **droppedFiles; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + fontSize += GetMouseWheelMove()*4.0f; + + // Choose font texture filter method + if (IsKeyPressed(KEY_ONE)) + { + SetTextureFilter(font.texture, FILTER_POINT); + currentFontFilter = 0; + } + else if (IsKeyPressed(KEY_TWO)) + { + SetTextureFilter(font.texture, FILTER_BILINEAR); + currentFontFilter = 1; + } + else if (IsKeyPressed(KEY_THREE)) + { + // NOTE: Trilinear filter not supported in font because there are not mipmap levels + SetTextureFilter(font.texture, FILTER_TRILINEAR); + //currentFontFilter = 2; + } + + textSize = MeasureTextEx(font, msg1, fontSize, 0); + + if (IsKeyDown(KEY_LEFT)) fontPosition.x -= 10; + else if (IsKeyDown(KEY_RIGHT)) fontPosition.x += 10; + + // Load a dropped TTF file dynamically (at current fontSize) + if (IsFileDropped()) + { + droppedFiles = GetDroppedFiles(&count); + + if (count == 1) // Only support one ttf file dropped + { + UnloadSpriteFont(font); + font = LoadSpriteFontTTF(droppedFiles[0], fontSize, 0, 0); + ClearDroppedFiles(); + } + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("Use mouse wheel to change font size", 20, 20, 10, GRAY); + DrawText("Use KEY_RIGHT and KEY_LEFT to move text", 20, 40, 10, GRAY); + DrawText("Use 1, 2, 3 to change texture filter", 20, 60, 10, GRAY); + DrawText("Drop a new TTF font for dynamic loading", 20, 80, 10, DARKGRAY); + + DrawTextEx(font, msg1, fontPosition, fontSize, 0, BLACK); + + // TODO: It seems texSize measurement is not accurate due to chars offsets... + //DrawRectangleLines(fontPosition.x, fontPosition.y, textSize.x, textSize.y, RED); + + DrawRectangle(0, screenHeight - 80, screenWidth, 80, LIGHTGRAY); + DrawText(FormatText("Font size: %02.02f", fontSize), 20, screenHeight - 50, 10, DARKGRAY); + DrawText(FormatText("Text size: [%02.02f, %02.02f]", textSize.x, textSize.y), 20, screenHeight - 30, 10, DARKGRAY); + DrawText("CURRENT TEXTURE FILTER:", 250, 400, 20, GRAY); + + if (currentFontFilter == 0) DrawText("POINT", 570, 400, 20, BLACK); + else if (currentFontFilter == 1) DrawText("BILINEAR", 570, 400, 20, BLACK); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadSpriteFont(font); // SpriteFont unloading + + ClearDroppedFiles(); // Clear internal buffers + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/text_ttf_loading.png b/examples/text_ttf_loading.png new file mode 100644 index 00000000..29ea263a Binary files /dev/null and b/examples/text_ttf_loading.png differ -- cgit v1.2.3 From bdbb1eb90133c882ee84421b1b024b286a76d5ce Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 21 Nov 2016 19:49:54 +0100 Subject: Added new text sample: text_bmfont_unordered BMFont loading has been improved to support unordered chars and extended characters (up to 255) --- examples/Makefile | 5 + examples/resources/fonts/pixantiqua.fnt | 188 ++++++++++++++++++++++++++++++ examples/resources/fonts/pixantiqua_0.png | Bin 0 -> 4531 bytes examples/text_bmfont_unordered.c | 65 +++++++++++ examples/text_bmfont_unordered.png | Bin 0 -> 18713 bytes examples/text_ttf_loading.c | 1 - 6 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 examples/resources/fonts/pixantiqua.fnt create mode 100644 examples/resources/fonts/pixantiqua_0.png create mode 100644 examples/text_bmfont_unordered.c create mode 100644 examples/text_bmfont_unordered.png (limited to 'examples/resources') diff --git a/examples/Makefile b/examples/Makefile index da29e915..2cb75ff9 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -229,6 +229,7 @@ EXAMPLES = \ text_font_select \ text_writing_anim \ text_ttf_loading \ + text_bmfont_unordered \ models_geometric_shapes \ models_box_collisions \ models_billboard \ @@ -418,6 +419,10 @@ text_writing_anim: text_writing_anim.c text_ttf_loading: text_ttf_loading.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) +# compile [text] example - text bmfont unordered +text_bmfont_unordered: text_bmfont_unordered.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + # compile [models] example - basic geometric 3d shapes models_geometric_shapes: models_geometric_shapes.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) diff --git a/examples/resources/fonts/pixantiqua.fnt b/examples/resources/fonts/pixantiqua.fnt new file mode 100644 index 00000000..971b9b0b --- /dev/null +++ b/examples/resources/fonts/pixantiqua.fnt @@ -0,0 +1,188 @@ +info face="PixAntiqua" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=2,2,2,2 spacing=2,2 outline=0 +common lineHeight=32 base=27 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4 +page id=0 file="pixantiqua_0.png" +chars count=184 +char id=32 x=9 y=304 width=7 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=33 x=391 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=34 x=240 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=35 x=468 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=36 x=152 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=37 x=176 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=38 x=303 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=39 x=495 y=266 width=8 height=36 xoffset=-3 yoffset=-2 xadvance=5 page=0 chnl=15 +char id=40 x=256 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=199 x=432 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=200 x=126 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=201 x=147 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=202 x=288 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=203 x=189 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=204 x=468 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=205 x=486 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=206 x=0 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=207 x=72 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=208 x=329 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=209 x=277 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=210 x=182 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=211 x=26 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=41 x=272 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=42 x=288 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=43 x=414 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=44 x=378 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=45 x=414 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=46 x=443 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=47 x=392 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=48 x=485 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=49 x=450 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=50 x=21 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=51 x=42 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=59 x=456 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=60 x=168 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=61 x=309 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=62 x=336 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=63 x=315 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=64 x=364 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=65 x=390 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=66 x=120 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=67 x=144 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=68 x=168 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=69 x=294 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=52 x=488 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=53 x=63 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=54 x=24 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=55 x=48 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=56 x=72 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=57 x=96 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=58 x=404 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=70 x=252 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=71 x=192 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=72 x=78 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=78 x=78 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=79 x=355 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=80 x=264 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=81 x=381 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=82 x=288 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=83 x=312 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=91 x=144 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=92 x=108 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=93 x=304 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=94 x=34 y=0 width=32 height=36 xoffset=-3 yoffset=-2 xadvance=29 page=0 chnl=15 +char id=95 x=231 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=96 x=442 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=97 x=408 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=98 x=432 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=99 x=210 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=84 x=336 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=85 x=360 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=86 x=0 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=87 x=68 y=0 width=30 height=36 xoffset=-3 yoffset=-2 xadvance=27 page=0 chnl=15 +char id=88 x=26 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=89 x=384 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=90 x=84 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=100 x=456 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=101 x=480 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=102 x=54 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=103 x=0 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=104 x=24 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=105 x=469 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=106 x=18 y=266 width=16 height=36 xoffset=-8 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=107 x=48 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=108 x=417 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=109 x=161 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=110 x=72 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=111 x=96 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=117 x=192 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=118 x=216 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=119 x=248 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=120 x=240 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=121 x=264 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=122 x=288 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=123 x=432 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=124 x=365 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=125 x=378 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=126 x=393 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=127 x=132 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=160 x=0 y=304 width=7 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=161 x=352 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=162 x=351 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=163 x=336 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=165 x=360 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=167 x=384 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=169 x=433 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=170 x=224 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=171 x=105 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=172 x=0 y=0 width=32 height=36 xoffset=-3 yoffset=-2 xadvance=29 page=0 chnl=15 +char id=173 x=494 y=38 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=174 x=52 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=175 x=52 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=176 x=126 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=177 x=435 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=178 x=320 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=179 x=336 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=181 x=459 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=112 x=120 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=113 x=144 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=114 x=396 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=115 x=168 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=116 x=36 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=182 x=408 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=183 x=498 y=190 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=185 x=192 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=186 x=208 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=187 x=477 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=191 x=456 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=192 x=407 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=193 x=234 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=194 x=416 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=195 x=156 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=196 x=130 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=197 x=104 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=198 x=190 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=212 x=0 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=213 x=338 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=214 x=312 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=215 x=357 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=216 x=286 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=217 x=456 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=218 x=480 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=219 x=0 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=220 x=24 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=221 x=48 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=222 x=260 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=223 x=72 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=224 x=96 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=225 x=120 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=226 x=144 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=227 x=168 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=228 x=192 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=229 x=216 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=230 x=219 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15 +char id=231 x=372 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=73 x=90 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15 +char id=74 x=216 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=75 x=240 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=76 x=273 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=77 x=100 y=0 width=30 height=36 xoffset=-3 yoffset=-2 xadvance=27 page=0 chnl=15 +char id=232 x=312 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=233 x=240 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=234 x=264 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=235 x=104 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=236 x=430 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=237 x=482 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=238 x=160 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15 +char id=239 x=176 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15 +char id=240 x=128 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=241 x=200 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=242 x=224 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=243 x=248 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=244 x=272 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=245 x=296 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=246 x=320 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=247 x=330 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=248 x=208 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15 +char id=249 x=344 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=250 x=368 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=251 x=416 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=252 x=440 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=253 x=464 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 +char id=254 x=0 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15 +char id=255 x=0 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15 diff --git a/examples/resources/fonts/pixantiqua_0.png b/examples/resources/fonts/pixantiqua_0.png new file mode 100644 index 00000000..2aa2870f Binary files /dev/null and b/examples/resources/fonts/pixantiqua_0.png differ diff --git a/examples/text_bmfont_unordered.c b/examples/text_bmfont_unordered.c new file mode 100644 index 00000000..b29c5f8b --- /dev/null +++ b/examples/text_bmfont_unordered.c @@ -0,0 +1,65 @@ +/******************************************************************************************* +* +* raylib [text] example - BMFont unordered chars loading and drawing +* +* This example has been created using raylib 1.4 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2016 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [text] example - bmfont unordered loading and drawing"); + + // NOTE: Using chars outside the [32..127] limits! + // NOTE: If a character is not found in the font, it just renders a space + const char msg[256] = "ASCII extended characters:\n¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆ\nÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæ\nçèéêëìíîïðñòóôõö÷øùúûüýþÿ"; + + // NOTE: Loaded font has an unordered list of characters (chars in the range 32..255) + SpriteFont font = LoadSpriteFont("resources/fonts/pixantiqua.fnt"); // BMFont (AngelCode) + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // TODO: Update variables here... + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + DrawText("Font name: PixAntiqua", 40, 50, 20, GRAY); + DrawText(FormatText("Font base size: %i", font.size), 40, 80, 20, GRAY); + DrawText(FormatText("Font chars number: %i", font.numChars), 40, 110, 20, GRAY); + + DrawTextEx(font, msg, (Vector2){ 40, 180 }, font.size, 0, MAROON); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadSpriteFont(font); // AngelCode SpriteFont unloading + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/text_bmfont_unordered.png b/examples/text_bmfont_unordered.png new file mode 100644 index 00000000..c6767567 Binary files /dev/null and b/examples/text_bmfont_unordered.png differ diff --git a/examples/text_ttf_loading.c b/examples/text_ttf_loading.c index 1135619e..b614023f 100644 --- a/examples/text_ttf_loading.c +++ b/examples/text_ttf_loading.c @@ -10,7 +10,6 @@ ********************************************************************************************/ #include "raylib.h" -#include int main() { -- cgit v1.2.3 From 5da815234c850dd1f1517e89854bbbed4eeb02e8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 26 Dec 2016 10:52:57 +0100 Subject: Improved FLAC audio support --- examples/resources/audio/tanatana.flac | Bin 0 -> 100733 bytes src/audio.c | 25 +-- src/external/dr_flac.h | 323 +++++++++++++++++++++++++-------- 3 files changed, 255 insertions(+), 93 deletions(-) create mode 100644 examples/resources/audio/tanatana.flac (limited to 'examples/resources') diff --git a/examples/resources/audio/tanatana.flac b/examples/resources/audio/tanatana.flac new file mode 100644 index 00000000..dfe735cd Binary files /dev/null and b/examples/resources/audio/tanatana.flac differ diff --git a/src/audio.c b/src/audio.c index 04ff90da..3a4ca3df 100644 --- a/src/audio.c +++ b/src/audio.c @@ -593,6 +593,7 @@ Music LoadMusicStream(const char *fileName) music->ctxType = MUSIC_AUDIO_OGG; music->loop = true; // We loop by default + TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] OGG sample rate: %i", fileName, info.sample_rate); TraceLog(DEBUG, "[%s] OGG channels: %i", fileName, info.channels); TraceLog(DEBUG, "[%s] OGG memory required: %i", fileName, info.temp_memory_required); @@ -606,11 +607,12 @@ Music LoadMusicStream(const char *fileName) else { music->stream = InitAudioStream(music->ctxFlac->sampleRate, music->ctxFlac->bitsPerSample, music->ctxFlac->channels); - music->totalSamples = (unsigned int)music->ctxFlac->totalSampleCount; + music->totalSamples = (unsigned int)music->ctxFlac->totalSampleCount/music->ctxFlac->channels; music->samplesLeft = music->totalSamples; music->ctxType = MUSIC_AUDIO_FLAC; music->loop = true; // We loop by default + TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples); TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate); TraceLog(DEBUG, "[%s] FLAC bits per sample: %i", fileName, music->ctxFlac->bitsPerSample); TraceLog(DEBUG, "[%s] FLAC channels: %i", fileName, music->ctxFlac->channels); @@ -745,9 +747,7 @@ void UpdateMusicStream(Music music) case MUSIC_AUDIO_FLAC: { // NOTE: Returns the number of samples to process - unsigned int numSamplesFlac = (unsigned int)drflac_read_s32(music->ctxFlac, numSamples/2, (int *)pcm); - - // TODO: Samples should be provided as 16 bit instead of 32 bit! + unsigned int numSamplesFlac = (unsigned int)drflac_read_s16(music->ctxFlac, numSamples*music->stream.channels, (short *)pcm); } break; case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, numSamples); break; @@ -1145,21 +1145,14 @@ static Wave LoadFLAC(const char *fileName) // Decode an entire FLAC file in one go uint64_t totalSampleCount; - wave.data = drflac_open_and_decode_file_s32(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount); - - wave.sampleCount = (int)totalSampleCount; - wave.sampleSize = 32; // 32 bit per sample (float) + wave.data = drflac_open_and_decode_file_s16(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount); - // NOTE: By default, dr_flac returns 32bit float samples, needs to be converted to 16bit - WaveFormat(&wave, wave.sampleRate, 16, wave.channels); + wave.sampleCount = (int)totalSampleCount/wave.channels; + wave.sampleSize = 16; // NOTE: Only support up to 2 channels (mono, stereo) - if (wave.channels > 2) - { - WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2); - TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported, converted to 2 channels", fileName, wave.channels); - } - + if (wave.channels > 2) TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported", fileName, wave.channels); + if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName); else TraceLog(INFO, "[%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo"); diff --git a/src/external/dr_flac.h b/src/external/dr_flac.h index d7b66f20..d2bebea5 100644 --- a/src/external/dr_flac.h +++ b/src/external/dr_flac.h @@ -1,5 +1,5 @@ // FLAC audio decoder. Public domain. See "unlicense" statement at the end of this file. -// dr_flac - v0.4 - 2016-09-29 +// dr_flac - v0.4c - 2016-12-26 // // David Reid - mackron@gmail.com @@ -105,18 +105,32 @@ #include #include -#ifndef DR_BOOL_DEFINED -#define DR_BOOL_DEFINED -#ifdef _WIN32 -typedef char drBool8; -typedef int drBool32; +#ifndef DR_SIZED_TYPES_DEFINED +#define DR_SIZED_TYPES_DEFINED +#if defined(_MSC_VER) && _MSC_VER < 1600 +typedef signed char dr_int8; +typedef unsigned char dr_uint8; +typedef signed short dr_int16; +typedef unsigned short dr_uint16; +typedef signed int dr_int32; +typedef unsigned int dr_uint32; +typedef signed __int64 dr_int64; +typedef unsigned __int64 dr_uint64; #else #include -typedef int8_t drBool8; -typedef int32_t drBool32; +typedef int8_t dr_int8; +typedef uint8_t dr_uint8; +typedef int16_t dr_int16; +typedef uint16_t dr_uint16; +typedef int32_t dr_int32; +typedef uint32_t dr_uint32; +typedef int64_t dr_int64; +typedef uint64_t dr_uint64; #endif -#define DR_TRUE 1 -#define DR_FALSE 0 +typedef dr_int8 dr_bool8; +typedef dr_int32 dr_bool32; +#define DR_TRUE 1 +#define DR_FALSE 0 #endif // As data is read from the client it is placed into an internal buffer for fast access. This controls the @@ -262,7 +276,7 @@ typedef struct { char catalog[128]; uint64_t leadInSampleCount; - drBool32 isCD; + dr_bool32 isCD; uint8_t trackCount; const uint8_t* pTrackData; } cuesheet; @@ -305,7 +319,7 @@ typedef size_t (* drflac_read_proc)(void* pUserData, void* pBufferOut, size_t by // // The offset will never be negative. Whether or not it is relative to the beginning or current position is determined // by the "origin" parameter which will be either drflac_seek_origin_start or drflac_seek_origin_current. -typedef drBool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin); +typedef dr_bool32 (* drflac_seek_proc)(void* pUserData, int offset, drflac_seek_origin origin); // Callback for when a metadata block is read. // @@ -546,6 +560,10 @@ void drflac_close(drflac* pFlac); // seeked. uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* pBufferOut); +// Same as drflac_read_s32(), except outputs samples as 16-bit integer PCM rather than 32-bit. Note +// that this is lossey. +uint64_t drflac_read_s16(drflac* pFlac, uint64_t samplesToRead, int16_t* pBufferOut); + // Seeks to the sample at the given index. // // pFlac [in] The decoder. @@ -558,7 +576,7 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* pBuffer // // When seeking, you will likely want to ensure it's rounded to a multiple of the channel count. You can do this with // something like drflac_seek_to_sample(pFlac, (mySampleIndex + (mySampleIndex % pFlac->channels))) -drBool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex); +dr_bool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex); @@ -607,14 +625,17 @@ drflac* drflac_open_memory_with_metadata(const void* data, size_t dataSize, drfl // // Do not call this function on a broadcast type of stream (like internet radio streams and whatnot). int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +int16_t* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); #ifndef DR_FLAC_NO_STDIO // Same as drflac_open_and_decode_s32() except opens the decoder from a file. int32_t* drflac_open_and_decode_file_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +int16_t* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); #endif // Same as drflac_open_and_decode_s32() except opens the decoder from a block of memory. int32_t* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); +int16_t* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount); // Frees data returned by drflac_open_and_decode_*(). void drflac_free(void* pSampleDataReturnedByOpenAndDecode); @@ -684,7 +705,7 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui //// Endian Management //// -static DRFLAC_INLINE drBool32 drflac__is_little_endian() +static DRFLAC_INLINE dr_bool32 drflac__is_little_endian() { int n = 1; return (*(char*)&n) == 1; @@ -817,7 +838,7 @@ static DRFLAC_INLINE uint32_t drflac__le2host_32(uint32_t n) #define DRFLAC_CACHE_L2_LINE_COUNT(bs) (DRFLAC_CACHE_L2_SIZE_BYTES(bs) / sizeof((bs)->cacheL2[0])) #define DRFLAC_CACHE_L2_LINES_REMAINING(bs) (DRFLAC_CACHE_L2_LINE_COUNT(bs) - (bs)->nextL2Line) -static DRFLAC_INLINE drBool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs) +static DRFLAC_INLINE dr_bool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs) { // Fast path. Try loading straight from L2. if (bs->nextL2Line < DRFLAC_CACHE_L2_LINE_COUNT(bs)) { @@ -871,7 +892,7 @@ static DRFLAC_INLINE drBool32 drflac__reload_l1_cache_from_l2(drflac_bs* bs) } } -static drBool32 drflac__reload_cache(drflac_bs* bs) +static dr_bool32 drflac__reload_cache(drflac_bs* bs) { // Fast path. Try just moving the next value in the L2 cache to the L1 cache. if (drflac__reload_l1_cache_from_l2(bs)) { @@ -907,7 +928,7 @@ static void drflac__reset_cache(drflac_bs* bs) bs->unalignedCache = 0; } -static drBool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek) +static dr_bool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek) { if (bitsToSeek <= DRFLAC_CACHE_L1_BITS_REMAINING(bs)) { bs->consumedBits += bitsToSeek; @@ -958,7 +979,7 @@ static drBool32 drflac__seek_bits(drflac_bs* bs, size_t bitsToSeek) } } -static drBool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, uint32_t* pResultOut) +static dr_bool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, uint32_t* pResultOut) { assert(bs != NULL); assert(pResultOut != NULL); @@ -999,7 +1020,7 @@ static drBool32 drflac__read_uint32(drflac_bs* bs, unsigned int bitCount, uint32 } } -static drBool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, int32_t* pResult) +static dr_bool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, int32_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1018,7 +1039,7 @@ static drBool32 drflac__read_int32(drflac_bs* bs, unsigned int bitCount, int32_t return DR_TRUE; } -static drBool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, uint64_t* pResultOut) +static dr_bool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, uint64_t* pResultOut) { assert(bitCount <= 64); assert(bitCount > 32); @@ -1039,7 +1060,7 @@ static drBool32 drflac__read_uint64(drflac_bs* bs, unsigned int bitCount, uint64 // Function below is unused, but leaving it here in case I need to quickly add it again. #if 0 -static drBool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, int64_t* pResultOut) +static dr_bool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, int64_t* pResultOut) { assert(bitCount <= 64); @@ -1056,7 +1077,7 @@ static drBool32 drflac__read_int64(drflac_bs* bs, unsigned int bitCount, int64_t } #endif -static drBool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, uint16_t* pResult) +static dr_bool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, uint16_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1072,7 +1093,7 @@ static drBool32 drflac__read_uint16(drflac_bs* bs, unsigned int bitCount, uint16 return DR_TRUE; } -static drBool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, int16_t* pResult) +static dr_bool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, int16_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1088,7 +1109,7 @@ static drBool32 drflac__read_int16(drflac_bs* bs, unsigned int bitCount, int16_t return DR_TRUE; } -static drBool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, uint8_t* pResult) +static dr_bool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, uint8_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1104,7 +1125,7 @@ static drBool32 drflac__read_uint8(drflac_bs* bs, unsigned int bitCount, uint8_t return DR_TRUE; } -static drBool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, int8_t* pResult) +static dr_bool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, int8_t* pResult) { assert(bs != NULL); assert(pResult != NULL); @@ -1121,7 +1142,7 @@ static drBool32 drflac__read_int8(drflac_bs* bs, unsigned int bitCount, int8_t* } -static inline drBool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut) +static inline dr_bool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned int* pOffsetOut) { unsigned int zeroCounter = 0; while (bs->cache == 0) { @@ -1169,7 +1190,7 @@ static inline drBool32 drflac__seek_past_next_set_bit(drflac_bs* bs, unsigned in -static drBool32 drflac__seek_to_byte(drflac_bs* bs, uint64_t offsetFromStart) +static dr_bool32 drflac__seek_to_byte(drflac_bs* bs, uint64_t offsetFromStart) { assert(bs != NULL); assert(offsetFromStart > 0); @@ -1214,7 +1235,7 @@ static drBool32 drflac__seek_to_byte(drflac_bs* bs, uint64_t offsetFromStart) } -static drBool32 drflac__read_utf8_coded_number(drflac_bs* bs, uint64_t* pNumberOut) +static dr_bool32 drflac__read_utf8_coded_number(drflac_bs* bs, uint64_t* pNumberOut) { assert(bs != NULL); assert(pNumberOut != NULL); @@ -1267,7 +1288,7 @@ static drBool32 drflac__read_utf8_coded_number(drflac_bs* bs, uint64_t* pNumberO -static DRFLAC_INLINE drBool32 drflac__read_and_seek_rice(drflac_bs* bs, uint8_t m) +static DRFLAC_INLINE dr_bool32 drflac__read_and_seek_rice(drflac_bs* bs, uint8_t m) { unsigned int unused; if (!drflac__seek_past_next_set_bit(bs, &unused)) { @@ -1520,7 +1541,7 @@ static DRFLAC_INLINE int32_t drflac__calculate_prediction_64(uint32_t order, int // iteration. The prediction is done at the end, and there's an annoying branch I'd like to avoid so the main function is defined // as a #define - sue me! #define DRFLAC__DECODE_SAMPLES_WITH_RESIDULE__RICE__PROC(funcName, predictionFunc) \ -static drBool32 funcName (drflac_bs* bs, uint32_t count, uint8_t riceParam, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) \ +static dr_bool32 funcName (drflac_bs* bs, uint32_t count, uint8_t riceParam, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) \ { \ assert(bs != NULL); \ assert(count > 0); \ @@ -1630,7 +1651,7 @@ DRFLAC__DECODE_SAMPLES_WITH_RESIDULE__RICE__PROC(drflac__decode_samples_with_res // Reads and seeks past a string of residual values as Rice codes. The decoder should be sitting on the first bit of the Rice codes. -static drBool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, uint32_t count, uint8_t riceParam) +static dr_bool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, uint32_t count, uint8_t riceParam) { assert(bs != NULL); assert(count > 0); @@ -1644,7 +1665,7 @@ static drBool32 drflac__read_and_seek_residual__rice(drflac_bs* bs, uint32_t cou return DR_TRUE; } -static drBool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, uint32_t bitsPerSample, uint32_t count, uint8_t unencodedBitsPerSample, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) +static dr_bool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, uint32_t bitsPerSample, uint32_t count, uint8_t unencodedBitsPerSample, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pSamplesOut) { assert(bs != NULL); assert(count > 0); @@ -1671,7 +1692,7 @@ static drBool32 drflac__decode_samples_with_residual__unencoded(drflac_bs* bs, u // Reads and decodes the residual for the sub-frame the decoder is currently sitting on. This function should be called // when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be ignored. The // and parameters are used to determine how many residual values need to be decoded. -static drBool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bitsPerSample, uint32_t blockSize, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bitsPerSample, uint32_t blockSize, uint32_t order, int32_t shift, const int16_t* coefficients, int32_t* pDecodedSamples) { assert(bs != NULL); assert(blockSize != 0); @@ -1755,7 +1776,7 @@ static drBool32 drflac__decode_samples_with_residual(drflac_bs* bs, uint32_t bit // Reads and seeks past the residual for the sub-frame the decoder is currently sitting on. This function should be called // when the decoder is sitting at the very start of the RESIDUAL block. The first residuals will be set to 0. The // and parameters are used to determine how many residual values need to be decoded. -static drBool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSize, uint32_t order) +static dr_bool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSize, uint32_t order) { assert(bs != NULL); assert(blockSize != 0); @@ -1823,7 +1844,7 @@ static drBool32 drflac__read_and_seek_residual(drflac_bs* bs, uint32_t blockSize } -static drBool32 drflac__decode_samples__constant(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples__constant(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples) { // Only a single sample needs to be decoded here. int32_t sample; @@ -1840,7 +1861,7 @@ static drBool32 drflac__decode_samples__constant(drflac_bs* bs, uint32_t blockSi return DR_TRUE; } -static drBool32 drflac__decode_samples__verbatim(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples__verbatim(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, int32_t* pDecodedSamples) { for (uint32_t i = 0; i < blockSize; ++i) { int32_t sample; @@ -1854,7 +1875,7 @@ static drBool32 drflac__decode_samples__verbatim(drflac_bs* bs, uint32_t blockSi return DR_TRUE; } -static drBool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples) { short lpcCoefficientsTable[5][4] = { {0, 0, 0, 0}, @@ -1882,7 +1903,7 @@ static drBool32 drflac__decode_samples__fixed(drflac_bs* bs, uint32_t blockSize, return DR_TRUE; } -static drBool32 drflac__decode_samples__lpc(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples) +static dr_bool32 drflac__decode_samples__lpc(drflac_bs* bs, uint32_t blockSize, uint32_t bitsPerSample, uint8_t lpcOrder, int32_t* pDecodedSamples) { // Warm up samples. for (uint8_t i = 0; i < lpcOrder; ++i) { @@ -1925,7 +1946,7 @@ static drBool32 drflac__decode_samples__lpc(drflac_bs* bs, uint32_t blockSize, u } -static drBool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfoBitsPerSample, drflac_frame_header* header) +static dr_bool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfoBitsPerSample, drflac_frame_header* header) { assert(bs != NULL); assert(header != NULL); @@ -1983,7 +2004,7 @@ static drBool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfo } - drBool32 isVariableBlockSize = blockingStrategy == 1; + dr_bool32 isVariableBlockSize = blockingStrategy == 1; if (isVariableBlockSize) { uint64_t sampleNumber; if (!drflac__read_utf8_coded_number(bs, &sampleNumber)) { @@ -2055,7 +2076,7 @@ static drBool32 drflac__read_next_frame_header(drflac_bs* bs, uint8_t streaminfo return DR_TRUE; } -static drBool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe) +static dr_bool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSubframe) { uint8_t header; if (!drflac__read_uint8(bs, 8, &header)) { @@ -2105,7 +2126,7 @@ static drBool32 drflac__read_subframe_header(drflac_bs* bs, drflac_subframe* pSu return DR_TRUE; } -static drBool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, int32_t* pDecodedSamplesOut) +static dr_bool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex, int32_t* pDecodedSamplesOut) { assert(bs != NULL); assert(frame != NULL); @@ -2155,7 +2176,7 @@ static drBool32 drflac__decode_subframe(drflac_bs* bs, drflac_frame* frame, int return DR_TRUE; } -static drBool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex) +static dr_bool32 drflac__seek_subframe(drflac_bs* bs, drflac_frame* frame, int subframeIndex) { assert(bs != NULL); assert(frame != NULL); @@ -2249,7 +2270,7 @@ static DRFLAC_INLINE uint8_t drflac__get_channel_count_from_channel_assignment(i return lookup[channelAssignment]; } -static drBool32 drflac__decode_frame(drflac* pFlac) +static dr_bool32 drflac__decode_frame(drflac* pFlac) { // This function should be called while the stream is sitting on the first byte after the frame header. memset(pFlac->currentFrame.subframes, 0, sizeof(pFlac->currentFrame.subframes)); @@ -2273,7 +2294,7 @@ static drBool32 drflac__decode_frame(drflac* pFlac) return DR_TRUE; } -static drBool32 drflac__seek_frame(drflac* pFlac) +static dr_bool32 drflac__seek_frame(drflac* pFlac) { int channelCount = drflac__get_channel_count_from_channel_assignment(pFlac->currentFrame.header.channelAssignment); for (int i = 0; i < channelCount; ++i) @@ -2287,7 +2308,7 @@ static drBool32 drflac__seek_frame(drflac* pFlac) return drflac__seek_bits(&pFlac->bs, (DRFLAC_CACHE_L1_BITS_REMAINING(&pFlac->bs) & 7) + 16); } -static drBool32 drflac__read_and_decode_next_frame(drflac* pFlac) +static dr_bool32 drflac__read_and_decode_next_frame(drflac* pFlac) { assert(pFlac != NULL); @@ -2324,24 +2345,24 @@ static void drflac__get_current_frame_sample_range(drflac* pFlac, uint64_t* pFir } } -static drBool32 drflac__seek_to_first_frame(drflac* pFlac) +static dr_bool32 drflac__seek_to_first_frame(drflac* pFlac) { assert(pFlac != NULL); - drBool32 result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos); + dr_bool32 result = drflac__seek_to_byte(&pFlac->bs, pFlac->firstFramePos); memset(&pFlac->currentFrame, 0, sizeof(pFlac->currentFrame)); return result; } -static DRFLAC_INLINE drBool32 drflac__seek_to_next_frame(drflac* pFlac) +static DRFLAC_INLINE dr_bool32 drflac__seek_to_next_frame(drflac* pFlac) { // This function should only ever be called while the decoder is sitting on the first byte past the FRAME_HEADER section. assert(pFlac != NULL); return drflac__seek_frame(pFlac); } -static drBool32 drflac__seek_to_frame_containing_sample(drflac* pFlac, uint64_t sampleIndex) +static dr_bool32 drflac__seek_to_frame_containing_sample(drflac* pFlac, uint64_t sampleIndex) { assert(pFlac != NULL); @@ -2372,7 +2393,7 @@ static drBool32 drflac__seek_to_frame_containing_sample(drflac* pFlac, uint64_t return DR_TRUE; } -static drBool32 drflac__seek_to_sample__brute_force(drflac* pFlac, uint64_t sampleIndex) +static dr_bool32 drflac__seek_to_sample__brute_force(drflac* pFlac, uint64_t sampleIndex) { if (!drflac__seek_to_frame_containing_sample(pFlac, sampleIndex)) { return DR_FALSE; @@ -2398,7 +2419,7 @@ static drBool32 drflac__seek_to_sample__brute_force(drflac* pFlac, uint64_t samp } -static drBool32 drflac__seek_to_sample__seek_table(drflac* pFlac, uint64_t sampleIndex) +static dr_bool32 drflac__seek_to_sample__seek_table(drflac* pFlac, uint64_t sampleIndex) { assert(pFlac != NULL); @@ -2508,7 +2529,7 @@ typedef struct uint64_t totalSampleCount; uint16_t maxBlockSize; uint64_t runningFilePos; - drBool32 hasMetadataBlocks; + dr_bool32 hasMetadataBlocks; #ifndef DR_FLAC_NO_OGG uint32_t oggSerial; @@ -2525,7 +2546,7 @@ static DRFLAC_INLINE void drflac__decode_block_header(uint32_t blockHeader, uint *blockSize = (blockHeader & 0xFFFFFF); } -static DRFLAC_INLINE drBool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, uint8_t* isLastBlock, uint8_t* blockType, uint32_t* blockSize) +static DRFLAC_INLINE dr_bool32 drflac__read_and_decode_block_header(drflac_read_proc onRead, void* pUserData, uint8_t* isLastBlock, uint8_t* blockType, uint32_t* blockSize) { uint32_t blockHeader; if (onRead(pUserData, &blockHeader, 4) != 4) { @@ -2536,7 +2557,7 @@ static DRFLAC_INLINE drBool32 drflac__read_and_decode_block_header(drflac_read_p return DR_TRUE; } -drBool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo) +dr_bool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drflac_streaminfo* pStreamInfo) { // min/max block size. uint32_t blockSizes; @@ -2579,7 +2600,7 @@ drBool32 drflac__read_streaminfo(drflac_read_proc onRead, void* pUserData, drfla return DR_TRUE; } -drBool32 drflac__read_and_decode_metadata(drflac* pFlac) +dr_bool32 drflac__read_and_decode_metadata(drflac* pFlac) { assert(pFlac != NULL); @@ -2823,7 +2844,7 @@ drBool32 drflac__read_and_decode_metadata(drflac* pFlac) return DR_TRUE; } -drBool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) +dr_bool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) { (void)onSeek; @@ -2869,7 +2890,7 @@ drBool32 drflac__init_private__native(drflac_init_info* pInit, drflac_read_proc } #ifndef DR_FLAC_NO_OGG -static DRFLAC_INLINE drBool32 drflac_ogg__is_capture_pattern(uint8_t pattern[4]) +static DRFLAC_INLINE dr_bool32 drflac_ogg__is_capture_pattern(uint8_t pattern[4]) { return pattern[0] == 'O' && pattern[1] == 'g' && pattern[2] == 'g' && pattern[3] == 'S'; } @@ -2889,7 +2910,7 @@ static DRFLAC_INLINE uint32_t drflac_ogg__get_page_body_size(drflac_ogg_page_hea return pageBodySize; } -drBool32 drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize) +dr_bool32 drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize) { if (onRead(pUserData, &pHeader->structureVersion, 1) != 1 || pHeader->structureVersion != 0) { return DR_FALSE; // Unknown structure version. Possibly corrupt stream. @@ -2920,7 +2941,7 @@ drBool32 drflac_ogg__read_page_header_after_capture_pattern(drflac_read_proc onR return DR_TRUE; } -drBool32 drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize) +dr_bool32 drflac_ogg__read_page_header(drflac_read_proc onRead, void* pUserData, drflac_ogg_page_header* pHeader, uint32_t* pHeaderSize) { uint8_t id[4]; if (onRead(pUserData, id, 4) != 4) { @@ -2961,7 +2982,7 @@ static size_t drflac_oggbs__read_physical(drflac_oggbs* oggbs, void* bufferOut, return bytesActuallyRead; } -static drBool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, uint64_t offset, drflac_seek_origin origin) +static dr_bool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, uint64_t offset, drflac_seek_origin origin) { if (origin == drflac_seek_origin_start) { @@ -3000,7 +3021,7 @@ static drBool32 drflac_oggbs__seek_physical(drflac_oggbs* oggbs, uint64_t offset } } -static drBool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs) +static dr_bool32 drflac_oggbs__goto_next_page(drflac_oggbs* oggbs) { drflac_ogg_page_header header; for (;;) @@ -3049,12 +3070,12 @@ static uint8_t drflac_oggbs__get_current_segment_index(drflac_oggbs* oggbs, uint return iSeg; } -static drBool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs) +static dr_bool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs) { // The current packet ends when we get to the segment with a lacing value of < 255 which is not at the end of a page. for (;;) // <-- Loop over pages. { - drBool32 atEndOfPage = DR_FALSE; + dr_bool32 atEndOfPage = DR_FALSE; uint8_t bytesRemainingInSeg; uint8_t iFirstSeg = drflac_oggbs__get_current_segment_index(oggbs, &bytesRemainingInSeg); @@ -3099,7 +3120,7 @@ static drBool32 drflac_oggbs__seek_to_next_packet(drflac_oggbs* oggbs) } } -static drBool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs) +static dr_bool32 drflac_oggbs__seek_to_next_frame(drflac_oggbs* oggbs) { // The bitstream should be sitting on the first byte just after the header of the frame. @@ -3148,7 +3169,7 @@ static size_t drflac__on_read_ogg(void* pUserData, void* bufferOut, size_t bytes return bytesRead; } -static drBool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin) +static dr_bool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_origin origin) { drflac_oggbs* oggbs = (drflac_oggbs*)pUserData; assert(oggbs != NULL); @@ -3204,7 +3225,7 @@ static drBool32 drflac__on_seek_ogg(void* pUserData, int offset, drflac_seek_ori return DR_TRUE; } -drBool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample) +dr_bool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample) { drflac_oggbs* oggbs = (drflac_oggbs*)(((int32_t*)pFlac->pExtraData) + pFlac->maxBlockSize*pFlac->channels); @@ -3327,7 +3348,7 @@ drBool32 drflac_ogg__seek_to_sample(drflac* pFlac, uint64_t sample) } -drBool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) +dr_bool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) { // Pre: The bit stream should be sitting just past the 4-byte OggS capture pattern. @@ -3491,7 +3512,7 @@ drBool32 drflac__init_private__ogg(drflac_init_info* pInit, drflac_read_proc onR } #endif -drBool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) +dr_bool32 drflac__init_private(drflac_init_info* pInit, drflac_read_proc onRead, drflac_seek_proc onSeek, drflac_meta_proc onMeta, void* pUserData, void* pUserDataMD) { if (pInit == NULL || onRead == NULL || onSeek == NULL) { return DR_FALSE; @@ -3610,7 +3631,7 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt return fread(bufferOut, 1, bytesToRead, (FILE*)pUserData); } -static drBool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) +static dr_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) { assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start)); @@ -3651,7 +3672,7 @@ static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t byt return (size_t)bytesRead; } -static drBool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) +static dr_bool32 drflac__on_seek_stdio(void* pUserData, int offset, drflac_seek_origin origin) { assert(offset > 0 || (offset == 0 && origin == drflac_seek_origin_start)); @@ -3727,7 +3748,7 @@ static size_t drflac__on_read_memory(void* pUserData, void* bufferOut, size_t by return bytesToRead; } -static drBool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin) +static dr_bool32 drflac__on_seek_memory(void* pUserData, int offset, drflac_seek_origin origin) { drflac__memory_stream* memoryStream = (drflac__memory_stream*)pUserData; assert(memoryStream != NULL); @@ -4107,7 +4128,32 @@ uint64_t drflac_read_s32(drflac* pFlac, uint64_t samplesToRead, int32_t* bufferO return samplesRead; } -drBool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex) +uint64_t drflac_read_s16(drflac* pFlac, uint64_t samplesToRead, int16_t* pBufferOut) +{ + // This reads samples in 2 passes and can probably be optimized. + uint64_t samplesRead = 0; + + while (samplesToRead > 0) { + int32_t samples32[4096]; + uint64_t samplesJustRead = drflac_read_s32(pFlac, samplesToRead > 4096 ? 4096 : samplesToRead, samples32); + if (samplesJustRead == 0) { + break; // Reached the end. + } + + // s32 -> s16 + for (uint64_t i = 0; i < samplesJustRead; ++i) { + pBufferOut[i] = (int16_t)(samples32[i] >> 16); + } + + samplesRead += samplesJustRead; + samplesToRead -= samplesJustRead; + pBufferOut += samplesJustRead; + } + + return samplesRead; +} + +dr_bool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex) { if (pFlac == NULL) { return DR_FALSE; @@ -4147,7 +4193,7 @@ drBool32 drflac_seek_to_sample(drflac* pFlac, uint64_t sampleIndex) //// High Level APIs //// -int32_t* drflac__full_decode_and_close(drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, uint64_t* totalSampleCountOut) +int32_t* drflac__full_decode_and_close_s32(drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, uint64_t* totalSampleCountOut) { assert(pFlac != NULL); @@ -4218,6 +4264,77 @@ on_error: return NULL; } +int16_t* drflac__full_decode_and_close_s16(drflac* pFlac, unsigned int* channelsOut, unsigned int* sampleRateOut, uint64_t* totalSampleCountOut) +{ + assert(pFlac != NULL); + + int16_t* pSampleData = NULL; + uint64_t totalSampleCount = pFlac->totalSampleCount; + + if (totalSampleCount == 0) + { + int16_t buffer[4096]; + + size_t sampleDataBufferSize = sizeof(buffer); + pSampleData = (int16_t*)malloc(sampleDataBufferSize); + if (pSampleData == NULL) { + goto on_error; + } + + uint64_t samplesRead; + while ((samplesRead = (uint64_t)drflac_read_s16(pFlac, sizeof(buffer)/sizeof(buffer[0]), buffer)) > 0) + { + if (((totalSampleCount + samplesRead) * sizeof(int16_t)) > sampleDataBufferSize) { + sampleDataBufferSize *= 2; + int16_t* pNewSampleData = (int16_t*)realloc(pSampleData, sampleDataBufferSize); + if (pNewSampleData == NULL) { + free(pSampleData); + goto on_error; + } + + pSampleData = pNewSampleData; + } + + memcpy(pSampleData + totalSampleCount, buffer, (size_t)(samplesRead*sizeof(int16_t))); + totalSampleCount += samplesRead; + } + + // At this point everything should be decoded, but we just want to fill the unused part buffer with silence - need to + // protect those ears from random noise! + memset(pSampleData + totalSampleCount, 0, (size_t)(sampleDataBufferSize - totalSampleCount*sizeof(int16_t))); + } + else + { + uint64_t dataSize = totalSampleCount * sizeof(int16_t); + if (dataSize > SIZE_MAX) { + goto on_error; // The decoded data is too big. + } + + pSampleData = (int16_t*)malloc((size_t)dataSize); // <-- Safe cast as per the check above. + if (pSampleData == NULL) { + goto on_error; + } + + uint64_t samplesDecoded = drflac_read_s16(pFlac, pFlac->totalSampleCount, pSampleData); + if (samplesDecoded != pFlac->totalSampleCount) { + free(pSampleData); + goto on_error; // Something went wrong when decoding the FLAC stream. + } + } + + + if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; + if (channelsOut) *channelsOut = pFlac->channels; + if (totalSampleCountOut) *totalSampleCountOut = totalSampleCount; + + drflac_close(pFlac); + return pSampleData; + +on_error: + drflac_close(pFlac); + return NULL; +} + int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) { // Safety. @@ -4230,7 +4347,22 @@ int32_t* drflac_open_and_decode_s32(drflac_read_proc onRead, drflac_seek_proc on return NULL; } - return drflac__full_decode_and_close(pFlac, channels, sampleRate, totalSampleCount); + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +int16_t* drflac_open_and_decode_s16(drflac_read_proc onRead, drflac_seek_proc onSeek, void* pUserData, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +{ + // Safety. + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + drflac* pFlac = drflac_open(onRead, onSeek, pUserData); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); } #ifndef DR_FLAC_NO_STDIO @@ -4245,7 +4377,21 @@ int32_t* drflac_open_and_decode_file_s32(const char* filename, unsigned int* cha return NULL; } - return drflac__full_decode_and_close(pFlac, channels, sampleRate, totalSampleCount); + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +int16_t* drflac_open_and_decode_file_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +{ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + drflac* pFlac = drflac_open_file(filename); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); } #endif @@ -4260,7 +4406,21 @@ int32_t* drflac_open_and_decode_memory_s32(const void* data, size_t dataSize, un return NULL; } - return drflac__full_decode_and_close(pFlac, channels, sampleRate, totalSampleCount); + return drflac__full_decode_and_close_s32(pFlac, channels, sampleRate, totalSampleCount); +} + +int16_t* drflac_open_and_decode_memory_s16(const void* data, size_t dataSize, unsigned int* channels, unsigned int* sampleRate, uint64_t* totalSampleCount) +{ + if (sampleRate) *sampleRate = 0; + if (channels) *channels = 0; + if (totalSampleCount) *totalSampleCount = 0; + + drflac* pFlac = drflac_open_memory(data, dataSize); + if (pFlac == NULL) { + return NULL; + } + + return drflac__full_decode_and_close_s16(pFlac, channels, sampleRate, totalSampleCount); } void drflac_free(void* pSampleDataReturnedByOpenAndDecode) @@ -4305,6 +4465,15 @@ const char* drflac_next_vorbis_comment(drflac_vorbis_comment_iterator* pIter, ui // REVISION HISTORY // +// v0.4c - 2016-12-26 +// - Add support for signed 16-bit integer PCM decoding. +// +// v0.4b - 2016-10-23 +// - A minor change to dr_bool8 and dr_bool32 types. +// +// v0.4a - 2016-10-11 +// - Rename drBool32 to dr_bool32 for styling consistency. +// // v0.4 - 2016-09-29 // - API/ABI CHANGE: Use fixed size 32-bit booleans instead of the built-in bool type. // - API CHANGE: Rename drflac_open_and_decode*() to drflac_open_and_decode*_s32() -- cgit v1.2.3 From d5d391faaf69027b8fecb26f30754c3bff83c311 Mon Sep 17 00:00:00 2001 From: Joel Davis Date: Mon, 2 Jan 2017 21:56:25 -0800 Subject: Added RaycastMesh function and example test case --- examples/core_3d_raypick.c | 159 +++++++--- examples/resources/model/lowpoly-tower.obj | 456 +++++++++++++++++++++++++++++ examples/resources/model/lowpoly-tower.png | Bin 0 -> 24939 bytes src/models.c | 38 +++ src/raylib.h | 3 + src/raymath.h | 26 ++ src/shapes.c | 73 ++++- 7 files changed, 708 insertions(+), 47 deletions(-) create mode 100644 examples/resources/model/lowpoly-tower.obj create mode 100644 examples/resources/model/lowpoly-tower.png (limited to 'examples/resources') diff --git a/examples/core_3d_raypick.c b/examples/core_3d_raypick.c index c1c32771..cf56b277 100644 --- a/examples/core_3d_raypick.c +++ b/examples/core_3d_raypick.c @@ -1,15 +1,21 @@ /******************************************************************************************* * -* raylib [core] example - Ray-Picking in 3d mode, also ground plane +* raylib [core] example - Ray-Picking in 3d mode, ground plane, triangle, mesh * * This example has been created using raylib 1.3 (www.raylib.com) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * * Copyright (c) 2015 Ramon Santamaria (@raysan5) +* Example contributed by Joel Davis (@joeld42) * ********************************************************************************************/ #include "raylib.h" +#include "raymath.h" + +#include +#include + int main() { @@ -22,24 +28,36 @@ int main() // Define the camera to look into our 3d world Camera camera; - camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position - camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point - camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) + camera.position = (Vector3){ 10.0f, 8.0f, 10.0f }; // Camera position + camera.target = (Vector3){ 0.0f, 2.3f, 0.0f }; // Camera looking at point + camera.up = (Vector3){ 0.0f, 1.6f, 0.0f }; // Camera up vector (rotation towards target) camera.fovy = 45.0f; // Camera field-of-view Y Vector3 cubePosition = { 0.0f, 1.0f, 0.0f }; Vector3 cubeSize = { 2.0f, 2.0f, 2.0f }; - Vector3 groundCursorPos = { 0 }; Ray ray; // Picking line ray - bool collision = false; - + Model tower = LoadModel("resources/model/lowpoly-tower.obj"); // Load OBJ model + Texture2D texture = LoadTexture("resources/model/lowpoly-tower.png"); // Load model texture + tower.material.texDiffuse = texture; // Set model diffuse texture + Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position + BoundingBox towerBBox = CalculateBoundingBox( tower.mesh ); + bool hitMeshBBox; + bool hitTriangle; + + // Test triangle + Vector3 ta = (Vector3){ -25.0, 0.5, 0.0 }; + Vector3 tb = (Vector3){ -4.0, 2.5, 1.0 }; + Vector3 tc = (Vector3){ -8.0, 6.5, 0.0 }; + + Vector3 bary = {0}; + SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { @@ -47,22 +65,52 @@ int main() //---------------------------------------------------------------------------------- UpdateCamera(&camera); // Update camera - // if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) - // { - // // NOTE: This function is NOT WORKING properly! - // ray = GetMouseRay(GetMousePosition(), camera); - - // // Check collision between ray and box - // collision = CheckCollisionRayBox(ray, - // (BoundingBox){(Vector3){ cubePosition.x - cubeSize.x/2, cubePosition.y - cubeSize.y/2, cubePosition.z - cubeSize.z/2 }, - // (Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }}); - // } + // Display information about closest hit + RayHitInfo nearestHit; + char *hitObjectName = "None"; + nearestHit.distance = FLT_MAX; + nearestHit.hit = false; + Color cursorColor = WHITE; + + // Get ray and test against ground, triangle, and mesh ray = GetMouseRay(GetMousePosition(), camera); - RayHitInfo hitinfo = RaycastGroundPlane( ray, 0.0 ); + + RayHitInfo groundHitInfo = RaycastGroundPlane( ray, 0.0 ); + if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance)) { + nearestHit = groundHitInfo; + cursorColor = GREEN; + hitObjectName = "Ground"; + } + + RayHitInfo triHitInfo = RaycastTriangle( ray, ta, tb, tc ); + if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance)) { + nearestHit = triHitInfo; + cursorColor = PURPLE; + hitObjectName = "Triangle"; + + bary = Barycentric( nearestHit.hitPosition, ta, tb, tc ); + hitTriangle = true; + } else { + hitTriangle = false; + } + + RayHitInfo meshHitInfo; + + // check the bounding box first, before trying the full ray/mesh test + if (CheckCollisionRayBox( ray, towerBBox )) { + hitMeshBBox = true; + meshHitInfo = RaycastMesh( ray, &tower.mesh ); + if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance)) { + nearestHit = meshHitInfo; + cursorColor = ORANGE; + hitObjectName = "Mesh"; + } + } else { + hitMeshBBox = false; + } //---------------------------------------------------------------------------------- - // Draw //---------------------------------------------------------------------------------- BeginDrawing(); @@ -71,37 +119,66 @@ int main() Begin3dMode(camera); - if (collision) - { - DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED); - DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON); - - DrawCubeWires(cubePosition, cubeSize.x + 0.2f, cubeSize.y + 0.2f, cubeSize.z + 0.2f, GREEN); - } - else - { - DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, GRAY); - DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, DARKGRAY); + // Draw the tower + DrawModel( tower, towerPos, 1.0, WHITE ); + + // Draw the test triangle + DrawLine3D( ta, tb, PURPLE ); + DrawLine3D( tb, tc, PURPLE ); + DrawLine3D( tc, ta, PURPLE ); + + // Draw the mesh bbox if we hit it + if (hitMeshBBox) { + DrawBoundingBox( towerBBox, LIME ); } - if (hitinfo.hit) { + // If we hit something, draw the cursor at the hit point + if (nearestHit.hit) { + DrawCube( nearestHit.hitPosition, 0.5, 0.5, 0.5, cursorColor ); + DrawCubeWires( nearestHit.hitPosition, 0.5, 0.5, 0.5, YELLOW ); - groundCursorPos = hitinfo.hitPosition; - groundCursorPos.y += 0.25; // Offset so the cube rests on the ground - printf("Hit: groundpos %3.2f %3.2f %3.2f\n", - groundCursorPos.x, groundCursorPos.y, groundCursorPos.z ); - DrawCubeWires( groundCursorPos, 0.5, 0.5, 0.5, RED ); + Vector3 normalEnd; + normalEnd.x = nearestHit.hitPosition.x + nearestHit.hitNormal.x; + normalEnd.y = nearestHit.hitPosition.y + nearestHit.hitNormal.y; + normalEnd.z = nearestHit.hitPosition.z + nearestHit.hitNormal.z; + DrawLine3D( nearestHit.hitPosition, normalEnd, YELLOW ); } - + DrawRay(ray, MAROON); DrawGrid(10, 1.0f); End3dMode(); - //DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY); - - //if(collision) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, screenHeight * 0.1f, 30, GREEN); + // Show some debug text + char line[1024]; + sprintf( line, "Hit Object: %s\n", hitObjectName ); + DrawText( line, 10, 30, 15, BLACK ); + + if (nearestHit.hit) { + int ypos = 45; + sprintf( line, "Distance: %3.2f", nearestHit.distance ); + DrawText( line, 10, ypos, 15, BLACK ); + ypos += 15; + + sprintf( line, "Hit Pos: %3.2f %3.2f %3.2f", + nearestHit.hitPosition.x, nearestHit.hitPosition.y, nearestHit.hitPosition.z ); + DrawText( line, 10, ypos, 15, BLACK ); + ypos += 15; + + sprintf( line, "Hit Norm: %3.2f %3.2f %3.2f", + nearestHit.hitNormal.x, nearestHit.hitNormal.y, nearestHit.hitNormal.z ); + DrawText( line, 10, ypos, 15, BLACK ); + ypos += 15; + + if (hitTriangle) { + sprintf( line, "Barycentric: %3.2f %3.2f %3.2f", + bary.x, bary.y, bary.z ); + DrawText( line, 10, ypos, 15, BLACK ); + } + } + + DrawText( "Use Mouse to Move Camera", 10, 420, 15, LIGHTGRAY ); DrawFPS(10, 10); diff --git a/examples/resources/model/lowpoly-tower.obj b/examples/resources/model/lowpoly-tower.obj new file mode 100644 index 00000000..ea03a9fc --- /dev/null +++ b/examples/resources/model/lowpoly-tower.obj @@ -0,0 +1,456 @@ +# Blender v2.78 (sub 0) OBJ File: 'lowpoly-tower.blend' +# www.blender.org +o Grid +v -4.000000 0.000000 4.000000 +v -2.327363 0.000000 4.654725 +v 0.000000 0.000000 4.654725 +v 2.327363 0.000000 4.654725 +v 4.000000 0.000000 4.000000 +v -4.654725 0.955085 2.327363 +v -2.000000 0.815050 2.000000 +v 0.000000 0.476341 2.423448 +v 2.000000 0.476341 2.000000 +v 4.654725 0.000000 2.327363 +v -4.654725 1.649076 0.000000 +v -2.423448 1.092402 0.000000 +v 2.423448 0.198579 0.000000 +v 4.654725 0.000000 0.000000 +v -4.654725 1.649076 -2.327363 +v -2.000000 1.092402 -2.000000 +v 0.000000 0.476341 -2.423448 +v 2.000000 -0.012791 -2.000000 +v 4.654725 0.000000 -2.612731 +v -4.000000 0.955085 -4.000000 +v -2.327363 0.955085 -4.654725 +v 0.000000 0.955085 -4.654725 +v 2.327363 0.000000 -4.654725 +v 4.000000 0.000000 -4.000000 +v 2.423448 0.682825 0.000000 +v 2.000000 0.565423 -2.000000 +v -4.654725 -0.020560 2.327363 +v -4.654725 0.000000 0.000000 +v -4.654725 0.000000 -2.327363 +v -4.000000 0.000000 -4.000000 +v -2.327363 0.000000 -4.654725 +v 0.000000 -0.020560 -4.654725 +v 0.000000 0.709880 -1.230535 +v -0.000000 7.395413 0.000000 +v 0.962071 0.709880 -0.767226 +v -0.533909 0.709880 1.108674 +v -1.199683 0.709880 0.273820 +v -0.962071 0.709880 -0.767226 +v 1.506076 0.859071 1.325337 +v 1.199683 0.709880 0.273820 +v 0.533909 0.709880 1.108674 +v 0.000000 1.875340 -1.177842 +v -0.000000 2.293973 -0.649884 +v -0.000000 4.365648 -0.627970 +v 0.000000 6.167194 -0.942957 +v 0.000000 6.232434 -1.708677 +v 1.335898 6.232434 -1.065343 +v 0.737233 6.167195 -0.587924 +v 0.490966 4.365648 -0.391533 +v 0.508100 2.293973 -0.405196 +v 0.920874 1.875340 -0.734372 +v -0.741367 6.232434 1.539465 +v -0.409133 6.167195 0.849574 +v -0.272466 4.365648 0.565781 +v -0.281974 2.293973 0.585526 +v -0.511047 1.875340 1.061199 +v -1.665837 6.232434 0.380217 +v -0.919314 6.167195 0.209828 +v -0.612225 4.365648 0.139736 +v -0.633590 2.293973 0.144613 +v -1.148311 1.875340 0.262095 +v -1.335898 6.232434 -1.065343 +v -0.737233 6.167195 -0.587924 +v -0.490967 4.365648 -0.391533 +v -0.508100 2.293973 -0.405196 +v -0.920874 1.875340 -0.734372 +v 1.665837 6.232434 0.380216 +v 0.919315 6.167195 0.209828 +v 0.612225 4.365648 0.139736 +v 0.633590 2.293973 0.144613 +v 1.148311 1.875340 0.262095 +v 0.741367 6.232434 1.539465 +v 0.409133 6.167195 0.849575 +v 0.272466 4.365648 0.565781 +v 0.281974 2.293973 0.585526 +v 0.511046 1.875340 1.061199 +v 0.000000 5.012550 -0.969733 +v 0.758168 5.012550 -0.604618 +v -0.420751 5.012550 0.873699 +v -0.945419 5.012550 0.215786 +v -0.758168 5.012550 -0.604618 +v 0.945419 5.012550 0.215786 +v 0.420751 5.012550 0.873699 +vt 0.0523 0.5444 +vt 0.1817 0.4284 +vt 0.1641 0.5859 +vt 0.0177 0.4451 +vt 0.1526 0.3090 +vt 0.0189 0.1737 +vt 0.0188 0.3088 +vt 0.0561 0.0762 +vt 0.1757 0.1924 +vt 0.3024 0.4534 +vt 0.3071 0.5902 +vt 0.3413 0.2459 +vt 0.2906 0.1614 +vt 0.4116 0.1801 +vt 0.2834 0.3774 +vt 0.1526 0.0362 +vt 0.2917 0.1622 +vt 0.4446 0.5865 +vt 0.4443 0.2989 +vt 0.3711 0.3021 +vt 0.4396 0.0275 +vt 0.4094 0.1829 +vt 0.4219 0.4255 +vt 0.5474 0.5381 +vt 0.5811 0.4376 +vt 0.5715 0.1505 +vt 0.5811 0.2997 +vt 0.5272 0.0533 +vt 0.2208 0.2194 +vt 0.3456 0.3610 +vt 0.2878 0.0321 +vt 0.2321 0.3392 +vt 0.4432 0.0177 +vt 0.7347 0.7934 +vt 0.7382 0.7595 +vt 0.8982 0.7768 +vt 0.6169 0.7595 +vt 0.6139 0.7879 +vt 0.4951 0.7634 +vt 0.1551 0.6832 +vt 0.2925 0.6268 +vt 0.2925 0.6832 +vt 0.7795 0.6832 +vt 0.6421 0.6268 +vt 0.7795 0.6255 +vt 0.5046 0.7241 +vt 0.6421 0.7241 +vt 0.3986 0.6268 +vt 0.3986 0.6832 +vt 0.5046 0.6268 +vt 0.0177 0.6268 +vt 0.1551 0.6255 +vt 0.8856 0.6268 +vt 0.1899 0.9579 +vt 0.1194 0.8696 +vt 0.2324 0.8696 +vt 0.1899 0.7813 +vt 0.0943 0.7595 +vt 0.0177 0.8206 +vt 0.0177 0.9186 +vt 0.0943 0.9797 +vt 0.2793 0.2349 +vt 0.2304 0.2758 +vt 0.6597 0.0177 +vt 0.6954 0.0993 +vt 0.6367 0.0768 +vt 0.7558 0.0777 +vt 0.7238 0.0440 +vt 0.8840 0.1330 +vt 0.7385 0.1141 +vt 0.9157 0.0886 +vt 0.9781 0.1232 +vt 0.9224 0.1276 +vt 0.2677 0.8141 +vt 0.3463 0.8037 +vt 0.3086 0.8339 +vt 0.6387 0.3550 +vt 0.7130 0.3801 +vt 0.6596 0.4053 +vt 0.7245 0.3245 +vt 0.6919 0.3383 +vt 0.8655 0.3566 +vt 0.7351 0.3577 +vt 0.9770 0.3365 +vt 0.9078 0.3751 +vt 0.9174 0.3282 +vt 0.2677 0.9018 +vt 0.3086 0.8821 +vt 0.6803 0.2948 +vt 0.6251 0.3035 +vt 0.7194 0.2854 +vt 0.8764 0.2832 +vt 0.9221 0.2861 +vt 0.3363 0.9565 +vt 0.3464 0.9122 +vt 0.6751 0.2482 +vt 0.6178 0.2499 +vt 0.7179 0.2431 +vt 0.9823 0.2484 +vt 0.9247 0.2452 +vt 0.3935 0.9014 +vt 0.6755 0.1996 +vt 0.6164 0.1941 +vt 0.7201 0.1992 +vt 0.8793 0.2446 +vt 0.9823 0.2060 +vt 0.9257 0.2051 +vt 0.4598 0.8580 +vt 0.4144 0.8579 +vt 0.6819 0.1498 +vt 0.6222 0.1361 +vt 0.7266 0.1555 +vt 0.8831 0.1684 +vt 0.9252 0.1659 +vt 0.4218 0.7790 +vt 0.3934 0.8145 +vt 0.3363 0.7595 +vt 0.8815 0.2060 +vt 0.8720 0.3208 +vt 0.8825 0.1012 +vt 0.9735 0.0816 +vt 0.9718 0.3817 +vt 0.9807 0.2918 +vt 0.4218 0.9370 +vt 0.9810 0.1644 +vn 0.1035 0.8806 0.4623 +vn 0.0964 0.9481 0.3030 +vn 0.0000 0.9780 0.2088 +vn 0.0659 0.9835 0.1683 +vn 0.2325 0.9320 0.2779 +vn 0.0553 0.9960 -0.0702 +vn 0.2827 0.9564 0.0728 +vn 0.1873 0.9776 -0.0961 +vn 0.2421 0.9703 0.0000 +vn 0.0921 0.9772 -0.1913 +vn -0.0277 0.9947 -0.0993 +vn 0.2308 0.9274 -0.2944 +vn 0.2771 0.9572 -0.0837 +vn 0.3724 0.9074 0.1947 +vn 0.0777 0.9770 -0.1985 +vn -0.1094 0.9539 0.2794 +vn 0.0364 0.9844 0.1721 +vn 0.1683 0.9835 0.0659 +vn 0.0674 0.9901 0.1230 +vn 0.4338 0.8823 0.1829 +vn 0.2845 0.9565 0.0649 +vn 0.0886 0.9961 0.0000 +vn 0.2000 0.9789 0.0424 +vn 0.1417 0.9830 0.1171 +vn 0.3021 0.9524 0.0412 +vn -0.0193 0.9986 -0.0493 +vn 0.0000 0.9777 0.2098 +vn 0.0005 0.9781 -0.2083 +vn 0.1879 0.9782 -0.0887 +vn 0.2249 0.0000 0.9744 +vn 0.9783 0.0000 -0.2071 +vn 0.9783 0.0000 0.2071 +vn 0.0000 0.0000 -1.0000 +vn -1.0000 0.0000 0.0000 +vn -0.3645 0.0000 -0.9312 +vn -0.9312 0.0000 -0.3645 +vn -0.9312 0.0000 0.3645 +vn 0.2615 0.7979 -0.5431 +vn 0.5877 0.7979 -0.1341 +vn 0.4713 0.7979 0.3758 +vn -0.0000 0.7979 0.6028 +vn -0.4713 0.7979 0.3758 +vn -0.5877 0.7979 -0.1341 +vn -0.2615 0.7979 -0.5431 +vn -0.1285 0.9864 -0.1025 +vn 0.0929 0.8937 0.4389 +vn -0.4335 0.0407 -0.9002 +vn -0.2867 0.7507 -0.5952 +vn -0.4339 0.0095 -0.9009 +vn -0.4338 0.0209 -0.9008 +vn -0.0408 -0.9956 -0.0848 +vn -0.9741 0.0407 -0.2223 +vn -0.6441 0.7507 -0.1470 +vn -0.9749 0.0095 -0.2225 +vn -0.9747 0.0209 -0.2225 +vn -0.0918 -0.9956 -0.0209 +vn -0.7812 0.0407 0.6230 +vn -0.5165 0.7507 0.4119 +vn -0.7818 0.0095 0.6235 +vn -0.7817 0.0209 0.6234 +vn -0.0736 -0.9956 0.0587 +vn -0.0000 0.0407 0.9992 +vn 0.0000 0.7507 0.6607 +vn 0.0000 0.0095 1.0000 +vn -0.0000 0.0209 0.9998 +vn -0.0000 -0.9956 0.0941 +vn 0.7812 0.0407 0.6230 +vn 0.5165 0.7507 0.4119 +vn 0.7818 0.0095 0.6235 +vn 0.7817 0.0209 0.6234 +vn 0.0736 -0.9956 0.0587 +vn 0.9741 0.0407 -0.2223 +vn 0.6441 0.7507 -0.1470 +vn 0.9749 0.0095 -0.2225 +vn 0.9747 0.0209 -0.2225 +vn 0.0918 -0.9956 -0.0209 +vn 0.4335 0.0407 -0.9002 +vn 0.2867 0.7507 -0.5952 +vn 0.4339 0.0095 -0.9009 +vn 0.4338 0.0209 -0.9008 +vn 0.0408 -0.9956 -0.0848 +vn 0.3918 -0.4298 -0.8135 +vn 0.8803 -0.4298 -0.2009 +vn 0.7059 -0.4298 0.5630 +vn -0.0000 -0.4298 0.9029 +vn -0.7059 -0.4298 0.5630 +vn -0.8803 -0.4298 -0.2009 +vn -0.3918 -0.4298 -0.8135 +vn 0.0210 0.9998 -0.0048 +vn 0.0482 0.9981 -0.0385 +vn -0.0166 0.9914 -0.1301 +vn -0.0090 0.9904 -0.1379 +vn 0.2820 0.9576 0.0597 +vn -0.0000 0.9846 0.1749 +vn -0.0921 0.9772 -0.1913 +vn -0.1734 0.9794 0.1036 +s off +f 1/1/1 7/2/1 6/3/1 +f 2/4/2 8/5/2 7/2/2 +f 4/6/3 8/5/3 3/7/3 +f 5/8/4 9/9/4 4/6/4 +f 6/3/5 12/10/5 11/11/5 +f 35/12/6 25/13/6 26/14/6 +f 7/2/7 37/15/7 12/10/7 +f 10/16/8 13/17/8 9/9/8 +f 12/10/9 15/18/9 11/11/9 +f 35/12/10 17/19/10 33/20/10 +f 13/17/11 19/21/11 18/22/11 +f 16/23/12 20/24/12 15/18/12 +f 17/19/13 21/25/13 16/23/13 +f 17/19/14 23/26/14 22/27/14 +f 26/14/15 24/28/15 23/26/15 +f 1/1/16 2/4/16 7/2/16 +f 2/4/3 3/7/3 8/5/3 +f 4/6/17 9/9/17 8/5/17 +f 5/8/18 10/16/18 9/9/18 +f 6/3/19 7/2/19 12/10/19 +f 25/13/20 39/29/20 9/9/20 +f 38/30/21 12/10/21 37/15/21 +f 10/16/22 14/31/22 13/17/22 +f 12/10/23 16/23/23 15/18/23 +f 8/5/24 36/32/24 7/2/24 +f 38/30/25 17/19/25 16/23/25 +f 13/17/22 14/31/22 19/21/22 +f 16/23/26 21/25/26 20/24/26 +f 17/19/27 22/27/27 21/25/27 +f 17/19/28 26/14/28 23/26/28 +f 26/14/29 19/33/29 24/28/29 +f 26/34/30 18/35/30 19/36/30 +f 26/34/31 13/37/31 18/35/31 +f 25/38/32 9/39/32 13/37/32 +f 22/40/33 31/41/33 21/42/33 +f 6/43/34 28/44/34 27/45/34 +f 15/46/34 28/44/34 11/47/34 +f 21/42/35 30/48/35 20/49/35 +f 20/49/36 29/50/36 15/46/36 +f 22/40/33 23/51/33 32/52/33 +f 6/43/37 27/45/37 1/53/37 +f 46/54/38 34/55/38 47/56/38 +f 47/56/39 34/55/39 67/57/39 +f 67/57/40 34/55/40 72/58/40 +f 72/58/41 34/55/41 52/59/41 +f 52/59/42 34/55/42 57/60/42 +f 57/60/43 34/55/43 62/61/43 +f 62/61/44 34/55/44 46/54/44 +f 40/62/45 41/63/45 39/29/45 +f 39/29/46 8/5/46 9/9/46 +f 38/64/47 42/65/47 33/66/47 +f 65/67/48 42/65/48 66/68/48 +f 65/67/49 44/69/49 43/70/49 +f 81/71/50 45/72/50 77/73/50 +f 62/74/51 45/75/51 63/76/51 +f 37/77/52 66/78/52 38/79/52 +f 60/80/53 66/78/53 61/81/53 +f 60/80/54 64/82/54 65/83/54 +f 58/84/55 81/85/55 80/86/55 +f 57/87/56 63/76/56 58/88/56 +f 56/89/57 37/77/57 36/90/57 +f 55/91/58 61/81/58 56/89/58 +f 54/92/59 60/80/59 55/91/59 +f 79/93/60 58/84/60 80/86/60 +f 52/94/61 58/88/61 53/95/61 +f 76/96/62 36/90/62 41/97/62 +f 75/98/63 56/89/63 76/96/63 +f 75/98/64 54/92/64 55/91/64 +f 73/99/65 79/93/65 83/100/65 +f 73/101/66 52/94/66 53/95/66 +f 71/102/67 41/97/67 40/103/67 +f 70/104/68 76/96/68 71/102/68 +f 70/104/69 74/105/69 75/98/69 +f 68/106/70 83/100/70 82/107/70 +f 67/108/71 73/101/71 68/109/71 +f 51/110/72 40/103/72 35/111/72 +f 50/112/73 71/102/73 51/110/73 +f 49/113/74 70/104/74 50/112/74 +f 78/114/75 68/106/75 82/107/75 +f 47/115/76 68/109/76 48/116/76 +f 42/65/77 35/111/77 33/66/77 +f 43/70/78 51/110/78 42/65/78 +f 44/69/79 50/112/79 43/70/79 +f 45/72/80 78/114/80 77/73/80 +f 46/117/81 48/116/81 45/75/81 +f 44/69/82 78/114/82 49/113/82 +f 49/113/83 82/107/83 69/118/83 +f 82/107/84 74/105/84 69/118/84 +f 83/100/85 54/92/85 74/105/85 +f 79/93/86 59/119/86 54/92/86 +f 80/86/87 64/82/87 59/119/87 +f 64/120/88 77/73/88 44/69/88 +f 35/12/89 40/62/89 25/13/89 +f 7/2/90 36/32/90 37/15/90 +f 35/12/91 26/14/91 17/19/91 +f 25/13/92 40/62/92 39/29/92 +f 38/30/93 16/23/93 12/10/93 +f 8/5/94 41/63/94 36/32/94 +f 38/30/95 33/20/95 17/19/95 +f 26/34/31 25/38/31 13/37/31 +f 22/40/33 32/52/33 31/41/33 +f 6/43/34 11/47/34 28/44/34 +f 15/46/34 29/50/34 28/44/34 +f 21/42/35 31/41/35 30/48/35 +f 20/49/36 30/48/36 29/50/36 +f 39/29/96 41/63/96 8/5/96 +f 38/64/47 66/68/47 42/65/47 +f 65/67/48 43/70/48 42/65/48 +f 65/67/49 64/120/49 44/69/49 +f 81/71/50 63/121/50 45/72/50 +f 62/74/51 46/117/51 45/75/51 +f 37/77/52 61/81/52 66/78/52 +f 60/80/53 65/83/53 66/78/53 +f 60/80/54 59/119/54 64/82/54 +f 58/84/55 63/122/55 81/85/55 +f 57/87/56 62/74/56 63/76/56 +f 56/89/57 61/81/57 37/77/57 +f 55/91/58 60/80/58 61/81/58 +f 54/92/59 59/119/59 60/80/59 +f 79/93/60 53/123/60 58/84/60 +f 52/94/61 57/87/61 58/88/61 +f 76/96/62 56/89/62 36/90/62 +f 75/98/63 55/91/63 56/89/63 +f 75/98/64 74/105/64 54/92/64 +f 73/99/65 53/123/65 79/93/65 +f 73/101/66 72/124/66 52/94/66 +f 71/102/67 76/96/67 41/97/67 +f 70/104/68 75/98/68 76/96/68 +f 70/104/69 69/118/69 74/105/69 +f 68/106/70 73/99/70 83/100/70 +f 67/108/71 72/124/71 73/101/71 +f 51/110/72 71/102/72 40/103/72 +f 50/112/73 70/104/73 71/102/73 +f 49/113/74 69/118/74 70/104/74 +f 78/114/75 48/125/75 68/106/75 +f 47/115/76 67/108/76 68/109/76 +f 42/65/77 51/110/77 35/111/77 +f 43/70/78 50/112/78 51/110/78 +f 44/69/79 49/113/79 50/112/79 +f 45/72/80 48/125/80 78/114/80 +f 46/117/81 47/115/81 48/116/81 +f 44/69/82 77/73/82 78/114/82 +f 49/113/83 78/114/83 82/107/83 +f 82/107/84 83/100/84 74/105/84 +f 83/100/85 79/93/85 54/92/85 +f 79/93/86 80/86/86 59/119/86 +f 80/86/87 81/85/87 64/82/87 +f 64/120/88 81/71/88 77/73/88 diff --git a/examples/resources/model/lowpoly-tower.png b/examples/resources/model/lowpoly-tower.png new file mode 100644 index 00000000..7c9239e2 Binary files /dev/null and b/examples/resources/model/lowpoly-tower.png differ diff --git a/src/models.c b/src/models.c index a2043913..41e527dc 100644 --- a/src/models.c +++ b/src/models.c @@ -1918,3 +1918,41 @@ static Material LoadMTL(const char *fileName) return material; } + +RayHitInfo RaycastMesh( Ray ray, Mesh *mesh ) +{ + RayHitInfo result = {0}; + + // If mesh doesn't have vertex data on CPU, can't test it. + if (!mesh->vertices) { + return result; + } + + // mesh->triangleCount may not be set, vertexCount is more reliable + int triangleCount = mesh->vertexCount / 3; + + // Test against all triangles in mesh + for (int i=0; i < triangleCount; i++) { + Vector3 a, b, c; + Vector3 *vertdata = (Vector3*)mesh->vertices; + if (mesh->indices) { + a = vertdata[ mesh->indices[i*3+0] ]; + b = vertdata[ mesh->indices[i*3+1] ]; + c = vertdata[ mesh->indices[i*3+2] ]; + } else { + a = vertdata[i*3+0]; + b = vertdata[i*3+1]; + c = vertdata[i*3+2]; + } + + RayHitInfo triHitInfo = RaycastTriangle( ray, a, b, c ); + if (triHitInfo.hit) { + // Save the closest hit triangle + if ((!result.hit)||(result.distance > triHitInfo.distance)) { + result = triHitInfo; + } + } + } + + return result; +} diff --git a/src/raylib.h b/src/raylib.h index f291ce85..7252ba4e 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -497,6 +497,7 @@ typedef struct Ray { // Information returned from a raycast typedef struct RayHitInfo { bool hit; // Did the ray hit something? + float distance; // Distance to nearest hit Vector3 hitPosition; // Position of nearest hit Vector3 hitNormal; // Surface normal of hit } RayHitInfo; @@ -924,6 +925,8 @@ RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Ray Casts //------------------------------------------------------------------------------------ RLAPI RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight ); +RLAPI RayHitInfo RaycastTriangle( Ray ray, Vector3 a, Vector3 b, Vector3 c ); +RLAPI RayHitInfo RaycastMesh( Ray ray, Mesh *mesh ); //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) diff --git a/src/raymath.h b/src/raymath.h index 3cd1394e..5871e350 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -130,6 +130,7 @@ RMDEF void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Ve RMDEF Vector3 VectorZero(void); // Return a Vector3 init to zero RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2); // Return min value for each pair of components RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2); // Return max value for each pair of components +RMDEF Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Barycentric coords for p in triangle abc //------------------------------------------------------------------------------------ // Functions Declaration to work with Matrix @@ -382,6 +383,31 @@ RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2) return result; } +// Compute barycentric coordinates (u, v, w) for +// point p with respect to triangle (a, b, c) +// Assumes P is on the plane of the triangle +RMDEF Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c) +{ + + //Vector v0 = b - a, v1 = c - a, v2 = p - a; + Vector3 v0 = VectorSubtract( b, a ); + Vector3 v1 = VectorSubtract( c, a ); + Vector3 v2 = VectorSubtract( p, a ); + float d00 = VectorDotProduct(v0, v0); + float d01 = VectorDotProduct(v0, v1); + float d11 = VectorDotProduct(v1, v1); + float d20 = VectorDotProduct(v2, v0); + float d21 = VectorDotProduct(v2, v1); + float denom = d00 * d11 - d01 * d01; + + Vector3 result; + result.y = (d11 * d20 - d01 * d21) / denom; + result.z = (d00 * d21 - d01 * d20) / denom; + result.x = 1.0f - (result.z + result.y); + + return result; +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Matrix math //---------------------------------------------------------------------------------- diff --git a/src/shapes.c b/src/shapes.c index 4b2de4f2..74480c83 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -544,13 +544,74 @@ RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight ) { float t = (ray.position.y - groundHeight) / -ray.direction.y; if (t >= 0.0) { - Vector3 camDir = ray.direction; - VectorScale( &camDir, t ); - result.hit = true; - result.hitNormal = (Vector3){ 0.0, 1.0, 0.0}; - result.hitPosition = VectorAdd( ray.position, camDir ); + Vector3 rayDir = ray.direction; + VectorScale( &rayDir, t ); + result.hit = true; + result.distance = t; + result.hitNormal = (Vector3){ 0.0, 1.0, 0.0}; + result.hitPosition = VectorAdd( ray.position, rayDir ); } } + return result; +} +// Adapted from: +// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm +RayHitInfo RaycastTriangle( Ray ray, Vector3 a, Vector3 b, Vector3 c ) +{ + Vector3 e1, e2; //Edge1, Edge2 + Vector3 p, q, tv; + float det, inv_det, u, v; + float t; + RayHitInfo result = {0}; + + //Find vectors for two edges sharing V1 + e1 = VectorSubtract( b, a); + e2 = VectorSubtract( c, a); + + //Begin calculating determinant - also used to calculate u parameter + p = VectorCrossProduct( ray.direction, e2); + + //if determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle + det = VectorDotProduct(e1, p); + + //NOT CULLING + if(det > -EPSILON && det < EPSILON) return result; + inv_det = 1.f / det; + + //calculate distance from V1 to ray origin + tv = VectorSubtract( ray.position, a ); + + //Calculate u parameter and test bound + u = VectorDotProduct(tv, p) * inv_det; + + //The intersection lies outside of the triangle + if(u < 0.f || u > 1.f) return result; + + //Prepare to test v parameter + q = VectorCrossProduct( tv, e1 ); + + //Calculate V parameter and test bound + v = VectorDotProduct( ray.direction, q) * inv_det; + + //The intersection lies outside of the triangle + if(v < 0.f || (u + v) > 1.f) return result; + + t = VectorDotProduct(e2, q) * inv_det; + + + if(t > EPSILON) { + // ray hit, get hit point and normal + result.hit = true; + result.distance = t; + result.hit = true; + result.hitNormal = VectorCrossProduct( e1, e2 ); + VectorNormalize( &result.hitNormal ); + Vector3 rayDir = ray.direction; + VectorScale( &rayDir, t ); + result.hitPosition = VectorAdd( ray.position, rayDir ); + } + return result; -} \ No newline at end of file +} + -- cgit v1.2.3 From f164ec80d6f1ca7afb7aec6a1e525cd67d401c14 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 22 Jan 2017 15:31:56 +0100 Subject: Upload wave collector - GGJ17 game --- examples/audio_sound_loading.c | 2 +- examples/resources/audio/sound.wav | Bin 0 -> 97512 bytes examples/shaders_standard_lighting.c | 4 +- games/wave_collector/Makefile | 233 ++++++++++ games/wave_collector/resources/audio/pause.wav | Bin 0 -> 25906 bytes .../wave_collector/resources/audio/sample_off.wav | Bin 0 -> 9291 bytes games/wave_collector/resources/audio/sample_on.wav | Bin 0 -> 2335 bytes games/wave_collector/resources/audio/start.wav | Bin 0 -> 14079 bytes games/wave_collector/resources/audio/wave.ogg | Bin 0 -> 1364969 bytes games/wave_collector/resources/font.fnt | 100 +++++ games/wave_collector/resources/font.png | Bin 0 -> 140998 bytes .../resources/textures/background.png | Bin 0 -> 840327 bytes .../resources/textures/background_gameplay.png | Bin 0 -> 561566 bytes .../resources/textures/background_title.png | Bin 0 -> 606904 bytes .../resources/textures/icon_synchro.png | Bin 0 -> 10015 bytes .../resources/textures/icon_warp.png | Bin 0 -> 11832 bytes games/wave_collector/resources/textures/line.png | Bin 0 -> 977 bytes .../resources/textures/logo_raylib.png | Bin 0 -> 1868 bytes games/wave_collector/resources/textures/lose.png | Bin 0 -> 79189 bytes games/wave_collector/resources/textures/player.png | Bin 0 -> 11785 bytes .../resources/textures/sample_big.png | Bin 0 -> 3006 bytes .../resources/textures/sample_mid.png | Bin 0 -> 1720 bytes .../resources/textures/sample_small.png | Bin 0 -> 1857 bytes games/wave_collector/resources/textures/title.png | Bin 0 -> 125004 bytes games/wave_collector/resources/textures/win.png | Bin 0 -> 33189 bytes games/wave_collector/screens/screen_ending.c | 111 +++++ games/wave_collector/screens/screen_gameplay.c | 490 +++++++++++++++++++++ games/wave_collector/screens/screen_logo.c | 181 ++++++++ games/wave_collector/screens/screen_title.c | 112 +++++ games/wave_collector/screens/screens.h | 87 ++++ games/wave_collector/wave_collector.c | 310 +++++++++++++ release/html5/libraylib.bc | Bin 753552 -> 788572 bytes release/html5/raylib.h | 163 ++++--- release/win32/mingw32/libraylib.a | Bin 675332 -> 695888 bytes release/win32/raylib.h | 163 ++++--- src/audio.c | 8 +- src/rlgl.h | 2 +- 37 files changed, 1836 insertions(+), 130 deletions(-) create mode 100644 examples/resources/audio/sound.wav create mode 100644 games/wave_collector/Makefile create mode 100644 games/wave_collector/resources/audio/pause.wav create mode 100644 games/wave_collector/resources/audio/sample_off.wav create mode 100644 games/wave_collector/resources/audio/sample_on.wav create mode 100644 games/wave_collector/resources/audio/start.wav create mode 100644 games/wave_collector/resources/audio/wave.ogg create mode 100644 games/wave_collector/resources/font.fnt create mode 100644 games/wave_collector/resources/font.png create mode 100644 games/wave_collector/resources/textures/background.png create mode 100644 games/wave_collector/resources/textures/background_gameplay.png create mode 100644 games/wave_collector/resources/textures/background_title.png create mode 100644 games/wave_collector/resources/textures/icon_synchro.png create mode 100644 games/wave_collector/resources/textures/icon_warp.png create mode 100644 games/wave_collector/resources/textures/line.png create mode 100644 games/wave_collector/resources/textures/logo_raylib.png create mode 100644 games/wave_collector/resources/textures/lose.png create mode 100644 games/wave_collector/resources/textures/player.png create mode 100644 games/wave_collector/resources/textures/sample_big.png create mode 100644 games/wave_collector/resources/textures/sample_mid.png create mode 100644 games/wave_collector/resources/textures/sample_small.png create mode 100644 games/wave_collector/resources/textures/title.png create mode 100644 games/wave_collector/resources/textures/win.png create mode 100644 games/wave_collector/screens/screen_ending.c create mode 100644 games/wave_collector/screens/screen_gameplay.c create mode 100644 games/wave_collector/screens/screen_logo.c create mode 100644 games/wave_collector/screens/screen_title.c create mode 100644 games/wave_collector/screens/screens.h create mode 100644 games/wave_collector/wave_collector.c (limited to 'examples/resources') diff --git a/examples/audio_sound_loading.c b/examples/audio_sound_loading.c index f081e8ed..feb30563 100644 --- a/examples/audio_sound_loading.c +++ b/examples/audio_sound_loading.c @@ -24,7 +24,7 @@ int main() InitAudioDevice(); // Initialize audio device - Sound fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file + Sound fxWav = LoadSound("resources/audio/sound.wav"); // Load WAV audio file Sound fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file SetTargetFPS(60); diff --git a/examples/resources/audio/sound.wav b/examples/resources/audio/sound.wav new file mode 100644 index 00000000..b5d01c9b Binary files /dev/null and b/examples/resources/audio/sound.wav differ diff --git a/examples/shaders_standard_lighting.c b/examples/shaders_standard_lighting.c index e539ec47..728bdae0 100644 --- a/examples/shaders_standard_lighting.c +++ b/examples/shaders_standard_lighting.c @@ -35,7 +35,9 @@ int main() Model dwarf = LoadModel("resources/model/dwarf.obj"); // Load OBJ model - Material material = LoadStandardMaterial(); + Material material;// = LoadStandardMaterial(); + + material.shader = LoadShader("resources/shaders/glsl330/standard.vs", "resources/shaders/glsl330/standard.fs"); material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png"); // Load model diffuse texture material.texNormal = LoadTexture("resources/model/dwarf_normal.png"); // Load model normal texture diff --git a/games/wave_collector/Makefile b/games/wave_collector/Makefile new file mode 100644 index 00000000..bac51ef1 --- /dev/null +++ b/games/wave_collector/Makefile @@ -0,0 +1,233 @@ +#************************************************************************************************** +# +# raylib - Advance Game +# +# makefile to compile advance game for desktop platforms, Raspberry Pi and HTML5 (emscripten) +# +# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +# +# This software is provided "as-is", without any express or implied warranty. In no event +# will the authors be held liable for any damages arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, including commercial +# applications, and to alter it and redistribute it freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not claim that you +# wrote the original software. If you use this software in a product, an acknowledgment +# in the product documentation would be appreciated but is not required. +# +# 2. Altered source versions must be plainly marked as such, and must not be misrepresented +# as being the original software. +# +# 3. This notice may not be removed or altered from any source distribution. +# +#************************************************************************************************** + +.PHONY: all clean + +# define raylib platform to compile for +# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB +# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop() +PLATFORM ?= PLATFORM_DESKTOP + +# determine PLATFORM_OS in case PLATFORM_DESKTOP selected +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + # No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows + ifeq ($(OS),Windows_NT) + PLATFORM_OS=WINDOWS + LIBPATH=win32 + else + UNAMEOS:=$(shell uname) + ifeq ($(UNAMEOS),Linux) + PLATFORM_OS=LINUX + LIBPATH=linux + else + ifeq ($(UNAMEOS),Darwin) + PLATFORM_OS=OSX + LIBPATH=osx + endif + endif + endif +endif + +# define compiler: gcc for C program, define as g++ for C++ +ifeq ($(PLATFORM),PLATFORM_WEB) + # define emscripten compiler + CC = emcc +else +ifeq ($(PLATFORM_OS),OSX) + # define llvm compiler for mac + CC = clang +else + # define default gcc compiler + CC = gcc +endif +endif + +# define compiler flags: +# -O2 defines optimization level +# -Wall turns on most, but not all, compiler warnings +# -std=c99 use standard C from 1999 revision +ifeq ($(PLATFORM),PLATFORM_RPI) + CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline +else + CFLAGS = -O2 -Wall -std=c99 +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 -s ALLOW_MEMORY_GROWTH=1 --preload-file resources --shell-file C:/raylib/raylib/templates/web_shell/shell.html + #-s ASSERTIONS=1 # to check for memory allocation errors (-O1 disables it) + #-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing + #-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) +endif + +#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes + +# define any directories containing required header files +ifeq ($(PLATFORM),PLATFORM_RPI) + INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads +endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + # add standard directories for GNU/Linux + ifeq ($(PLATFORM_OS),LINUX) + INCLUDES = -I. -I../src -I/usr/local/include/raylib/ + else + INCLUDES = -I. -I../../src -IC:/raylib/raylib/src + # external libraries headers + # GLFW3 + INCLUDES += -I../../external/glfw3/include + # OpenAL Soft + INCLUDES += -I../../external/openal_soft/include + endif +endif + +# define library paths containing required libs +ifeq ($(PLATFORM),PLATFORM_RPI) + LFLAGS = -L. -L../../src -L/opt/vc/lib +endif +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + # add standard directories for GNU/Linux + ifeq ($(PLATFORM_OS),LINUX) + LFLAGS = -L. -L../../src + else + LFLAGS = -L. -L../../src + ifeq ($(PLATFORM_OS),WINDOWS) + LFLAGS += -LC:/GitHub/raylib/src + endif + # external libraries to link with + # GLFW3 + LFLAGS += -L../../external/glfw3/lib/$(LIBPATH) + ifneq ($(PLATFORM_OS),OSX) + # OpenAL Soft + LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH) + endif + endif +endif + +ifeq ($(PLATFORM),PLATFORM_WEB) + INCLUDES = -I. -I.. + LFLAGS = -L. -L.. +endif + +# define any libraries to link into executable +# if you want to link libraries (libname.so or libname.a), use the -lname +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),LINUX) + # libraries for Debian GNU/Linux desktop compiling + # requires the following packages: + # libglfw3-dev libopenal-dev libegl1-mesa-dev + LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -pthread -ldl -lX11 \ + -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor + else + ifeq ($(PLATFORM_OS),OSX) + # libraries for OS X 10.9 desktop compiling + # requires the following packages: + # libglfw3-dev libopenal-dev libegl1-mesa-dev + LIBS = -lraylib -lglfw3 -framework OpenGL -framework OpenAl -framework Cocoa + else + # libraries for Windows desktop compiling + # NOTE: GLFW3 and OpenAL Soft libraries should be installed + LIBS = -lraylib -lglfw3 -lopengl32 -lopenal32 -lwinmm -lgdi32 + endif + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + # libraries for Raspberry Pi compiling + # NOTE: OpenAL Soft library should be installed (libopenal1 package) + LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + # NOTE: Set the correct path to libraylib.bc + LIBS = libraylib.bc +endif + +# define additional parameters and flags for windows +ifeq ($(PLATFORM_OS),WINDOWS) + # resources file contains windows exe icon + # -Wl,--subsystem,windows hides the console window + WINFLAGS = C:/raylib/raylib/src/resources -Wl,-allow-multiple-definition + # -Wl,--subsystem,windows +endif + +ifeq ($(PLATFORM),PLATFORM_WEB) + EXT = .html +endif + +# define all screen object files required +SCREENS = \ + screens/screen_logo.o \ + screens/screen_title.o \ + screens/screen_gameplay.o \ + screens/screen_ending.o \ + +# typing 'make' will invoke the default target entry called 'all', +# in this case, the 'default' target entry is advance_game +default: wave_collector + +# compile template - advance_game +wave_collector: wave_collector.c $(SCREENS) + $(CC) -o $@$(EXT) $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS) + +# compile screen LOGO +screens/screen_logo.o: screens/screen_logo.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM) + +# compile screen TITLE +screens/screen_title.o: screens/screen_title.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM) + +# compile screen GAMEPLAY +screens/screen_gameplay.o: screens/screen_gameplay.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM) + +# compile screen ENDING +screens/screen_ending.o: screens/screen_ending.c + $(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM) + +# clean everything +clean: +ifeq ($(PLATFORM),PLATFORM_DESKTOP) + ifeq ($(PLATFORM_OS),OSX) + find . -type f -perm +ugo+x -delete + rm -f screens/*.o + else + ifeq ($(PLATFORM_OS),LINUX) + find . -type f -executable -delete + rm -f screens/*.o + else + del screens\*.o *.exe + endif + endif +endif +ifeq ($(PLATFORM),PLATFORM_RPI) + find . -type f -executable -delete + rm -f screens/*.o +endif +ifeq ($(PLATFORM),PLATFORM_WEB) + del screens/*.o *.html *.js +endif + @echo Cleaning done + +# instead of defining every module one by one, we can define a pattern +# this pattern below will automatically compile every module defined on $(OBJS) +#%.exe : %.c +# $(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) diff --git a/games/wave_collector/resources/audio/pause.wav b/games/wave_collector/resources/audio/pause.wav new file mode 100644 index 00000000..f35301ee Binary files /dev/null and b/games/wave_collector/resources/audio/pause.wav differ diff --git a/games/wave_collector/resources/audio/sample_off.wav b/games/wave_collector/resources/audio/sample_off.wav new file mode 100644 index 00000000..d2203e72 Binary files /dev/null and b/games/wave_collector/resources/audio/sample_off.wav differ diff --git a/games/wave_collector/resources/audio/sample_on.wav b/games/wave_collector/resources/audio/sample_on.wav new file mode 100644 index 00000000..38b7ca58 Binary files /dev/null and b/games/wave_collector/resources/audio/sample_on.wav differ diff --git a/games/wave_collector/resources/audio/start.wav b/games/wave_collector/resources/audio/start.wav new file mode 100644 index 00000000..66ce7ac1 Binary files /dev/null and b/games/wave_collector/resources/audio/start.wav differ diff --git a/games/wave_collector/resources/audio/wave.ogg b/games/wave_collector/resources/audio/wave.ogg new file mode 100644 index 00000000..a5b0dea4 Binary files /dev/null and b/games/wave_collector/resources/audio/wave.ogg differ diff --git a/games/wave_collector/resources/font.fnt b/games/wave_collector/resources/font.fnt new file mode 100644 index 00000000..607e5a4d --- /dev/null +++ b/games/wave_collector/resources/font.fnt @@ -0,0 +1,100 @@ +info face=font size=57 bold=0 italic=0 charset= unicode= stretchH=100 smooth=1 aa=1 padding=2,2,2,2 spacing=0,0 outline=0 +common lineHeight=68 base=55 scaleW=512 scaleH=1024 pages=1 packed=0 +page id=0 file="font.png" +chars count=95 +char id=32 x=2 y=57 width=0 height=0 xoffset=0 yoffset=55 xadvance=29 page=0 chnl=15 +char id=33 x=4 y=5 width=16 height=61 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15 +char id=34 x=22 y=10 width=25 height=27 xoffset=0 yoffset=8 xadvance=23 page=0 chnl=15 +char id=35 x=49 y=26 width=41 height=27 xoffset=-3 yoffset=24 xadvance=34 page=0 chnl=15 +char id=36 x=92 y=26 width=41 height=27 xoffset=-3 yoffset=24 xadvance=34 page=0 chnl=15 +char id=37 x=135 y=13 width=34 height=49 xoffset=-1 yoffset=12 xadvance=30 page=0 chnl=15 +char id=38 x=171 y=16 width=51 height=46 xoffset=-1 yoffset=14 xadvance=47 page=0 chnl=15 +char id=39 x=224 y=10 width=16 height=27 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 +char id=40 x=242 y=8 width=18 height=60 xoffset=0 yoffset=6 xadvance=16 page=0 chnl=15 +char id=41 x=262 y=8 width=18 height=60 xoffset=-1 yoffset=6 xadvance=15 page=0 chnl=15 +char id=42 x=282 y=11 width=29 height=32 xoffset=-1 yoffset=10 xadvance=25 page=0 chnl=15 +char id=43 x=313 y=25 width=29 height=29 xoffset=-2 yoffset=24 xadvance=24 page=0 chnl=15 +char id=44 x=344 y=45 width=16 height=29 xoffset=0 yoffset=44 xadvance=13 page=0 chnl=15 +char id=45 x=362 y=33 width=29 height=15 xoffset=1 yoffset=31 xadvance=28 page=0 chnl=15 +char id=46 x=393 y=45 width=16 height=17 xoffset=-1 yoffset=44 xadvance=13 page=0 chnl=15 +char id=47 x=411 y=6 width=37 height=61 xoffset=-3 yoffset=4 xadvance=30 page=0 chnl=15 +char id=48 x=450 y=14 width=43 height=49 xoffset=-1 yoffset=12 xadvance=39 page=0 chnl=15 +char id=49 x=2 y=91 width=22 height=49 xoffset=-1 yoffset=12 xadvance=19 page=0 chnl=15 +char id=50 x=26 y=91 width=42 height=49 xoffset=-1 yoffset=12 xadvance=39 page=0 chnl=15 +char id=51 x=70 y=91 width=41 height=48 xoffset=-2 yoffset=12 xadvance=35 page=0 chnl=15 +char id=52 x=113 y=91 width=40 height=48 xoffset=-2 yoffset=12 xadvance=35 page=0 chnl=15 +char id=53 x=155 y=91 width=35 height=49 xoffset=-1 yoffset=12 xadvance=31 page=0 chnl=15 +char id=54 x=192 y=91 width=48 height=48 xoffset=-2 yoffset=13 xadvance=43 page=0 chnl=15 +char id=55 x=242 y=91 width=38 height=49 xoffset=-2 yoffset=12 xadvance=33 page=0 chnl=15 +char id=56 x=282 y=91 width=49 height=49 xoffset=-2 yoffset=12 xadvance=43 page=0 chnl=15 +char id=57 x=333 y=91 width=46 height=49 xoffset=-2 yoffset=12 xadvance=41 page=0 chnl=15 +char id=58 x=381 y=102 width=16 height=37 xoffset=0 yoffset=24 xadvance=14 page=0 chnl=15 +char id=59 x=399 y=102 width=16 height=48 xoffset=0 yoffset=24 xadvance=15 page=0 chnl=15 +char id=60 x=417 y=98 width=41 height=42 xoffset=-2 yoffset=19 xadvance=37 page=0 chnl=15 +char id=61 x=460 y=104 width=29 height=30 xoffset=0 yoffset=25 xadvance=27 page=0 chnl=15 +char id=62 x=2 y=173 width=42 height=42 xoffset=-1 yoffset=19 xadvance=36 page=0 chnl=15 +char id=63 x=46 y=155 width=39 height=61 xoffset=0 yoffset=0 xadvance=35 page=0 chnl=15 +char id=64 x=87 y=167 width=58 height=53 xoffset=-1 yoffset=12 xadvance=54 page=0 chnl=15 +char id=65 x=147 y=169 width=47 height=47 xoffset=-2 yoffset=14 xadvance=41 page=0 chnl=15 +char id=66 x=196 y=169 width=47 height=46 xoffset=0 yoffset=14 xadvance=42 page=0 chnl=15 +char id=67 x=245 y=169 width=41 height=47 xoffset=-1 yoffset=14 xadvance=37 page=0 chnl=15 +char id=68 x=288 y=169 width=43 height=47 xoffset=0 yoffset=14 xadvance=39 page=0 chnl=15 +char id=69 x=333 y=169 width=43 height=46 xoffset=-2 yoffset=14 xadvance=39 page=0 chnl=15 +char id=70 x=378 y=169 width=40 height=46 xoffset=-2 yoffset=14 xadvance=35 page=0 chnl=15 +char id=71 x=420 y=169 width=41 height=46 xoffset=-2 yoffset=14 xadvance=37 page=0 chnl=15 +char id=72 x=463 y=167 width=43 height=48 xoffset=1 yoffset=12 xadvance=43 page=0 chnl=15 +char id=73 x=2 y=237 width=16 height=48 xoffset=1 yoffset=12 xadvance=15 page=0 chnl=15 +char id=74 x=20 y=239 width=25 height=46 xoffset=-2 yoffset=14 xadvance=21 page=0 chnl=15 +char id=75 x=47 y=238 width=45 height=49 xoffset=1 yoffset=14 xadvance=41 page=0 chnl=15 +char id=76 x=94 y=237 width=31 height=48 xoffset=1 yoffset=13 xadvance=28 page=0 chnl=15 +char id=77 x=127 y=239 width=51 height=46 xoffset=0 yoffset=14 xadvance=49 page=0 chnl=15 +char id=78 x=180 y=239 width=40 height=46 xoffset=0 yoffset=14 xadvance=39 page=0 chnl=15 +char id=79 x=222 y=239 width=51 height=46 xoffset=-2 yoffset=14 xadvance=45 page=0 chnl=15 +char id=80 x=275 y=239 width=44 height=46 xoffset=0 yoffset=14 xadvance=40 page=0 chnl=15 +char id=81 x=321 y=239 width=51 height=46 xoffset=-2 yoffset=14 xadvance=45 page=0 chnl=15 +char id=82 x=374 y=239 width=45 height=48 xoffset=0 yoffset=15 xadvance=41 page=0 chnl=15 +char id=83 x=421 y=238 width=34 height=48 xoffset=-2 yoffset=13 xadvance=28 page=0 chnl=15 +char id=84 x=457 y=239 width=41 height=47 xoffset=-2 yoffset=14 xadvance=36 page=0 chnl=15 +char id=85 x=2 y=306 width=46 height=46 xoffset=0 yoffset=15 xadvance=43 page=0 chnl=15 +char id=86 x=50 y=305 width=44 height=48 xoffset=-2 yoffset=13 xadvance=38 page=0 chnl=15 +char id=87 x=96 y=305 width=55 height=47 xoffset=-2 yoffset=13 xadvance=49 page=0 chnl=15 +char id=88 x=153 y=306 width=43 height=46 xoffset=-2 yoffset=14 xadvance=38 page=0 chnl=15 +char id=89 x=198 y=305 width=38 height=47 xoffset=-2 yoffset=13 xadvance=31 page=0 chnl=15 +char id=90 x=238 y=306 width=40 height=47 xoffset=-2 yoffset=14 xadvance=35 page=0 chnl=15 +char id=91 x=280 y=295 width=26 height=66 xoffset=1 yoffset=4 xadvance=24 page=0 chnl=15 +char id=92 x=308 y=293 width=37 height=61 xoffset=-4 yoffset=2 xadvance=29 page=0 chnl=15 +char id=93 x=347 y=295 width=26 height=66 xoffset=-2 yoffset=4 xadvance=22 page=0 chnl=15 +char id=94 x=375 y=294 width=28 height=17 xoffset=-1 yoffset=3 xadvance=24 page=0 chnl=15 +char id=95 x=405 y=346 width=49 height=15 xoffset=-1 yoffset=55 xadvance=45 page=0 chnl=15 +char id=96 x=456 y=295 width=20 height=17 xoffset=1 yoffset=3 xadvance=18 page=0 chnl=15 +char id=97 x=2 y=387 width=38 height=39 xoffset=-2 yoffset=22 xadvance=35 page=0 chnl=15 +char id=98 x=42 y=375 width=41 height=52 xoffset=1 yoffset=9 xadvance=38 page=0 chnl=15 +char id=99 x=85 y=387 width=38 height=39 xoffset=-2 yoffset=22 xadvance=34 page=0 chnl=15 +char id=100 x=125 y=375 width=41 height=52 xoffset=-2 yoffset=9 xadvance=38 page=0 chnl=15 +char id=101 x=168 y=387 width=38 height=39 xoffset=1 yoffset=22 xadvance=34 page=0 chnl=15 +char id=102 x=208 y=375 width=27 height=52 xoffset=1 yoffset=9 xadvance=23 page=0 chnl=15 +char id=103 x=237 y=387 width=41 height=52 xoffset=-2 yoffset=21 xadvance=38 page=0 chnl=15 +char id=104 x=280 y=375 width=37 height=51 xoffset=1 yoffset=9 xadvance=34 page=0 chnl=15 +char id=105 x=319 y=380 width=15 height=47 xoffset=2 yoffset=14 xadvance=16 page=0 chnl=15 +char id=106 x=336 y=378 width=25 height=60 xoffset=-6 yoffset=12 xadvance=18 page=0 chnl=15 +char id=107 x=363 y=375 width=40 height=51 xoffset=2 yoffset=9 xadvance=38 page=0 chnl=15 +char id=108 x=405 y=379 width=15 height=48 xoffset=1 yoffset=13 xadvance=16 page=0 chnl=15 +char id=109 x=422 y=387 width=47 height=39 xoffset=0 yoffset=22 xadvance=46 page=0 chnl=15 +char id=110 x=2 y=465 width=37 height=39 xoffset=0 yoffset=22 xadvance=34 page=0 chnl=15 +char id=111 x=41 y=465 width=41 height=40 xoffset=-1 yoffset=21 xadvance=37 page=0 chnl=15 +char id=112 x=84 y=465 width=41 height=52 xoffset=1 yoffset=22 xadvance=37 page=0 chnl=15 +char id=113 x=127 y=465 width=41 height=51 xoffset=-2 yoffset=22 xadvance=38 page=0 chnl=15 +char id=114 x=170 y=465 width=34 height=39 xoffset=1 yoffset=22 xadvance=30 page=0 chnl=15 +char id=115 x=206 y=462 width=37 height=42 xoffset=-2 yoffset=19 xadvance=31 page=0 chnl=15 +char id=116 x=245 y=453 width=36 height=52 xoffset=0 yoffset=9 xadvance=31 page=0 chnl=15 +char id=117 x=283 y=465 width=37 height=39 xoffset=0 yoffset=22 xadvance=35 page=0 chnl=15 +char id=118 x=322 y=463 width=35 height=41 xoffset=-2 yoffset=19 xadvance=28 page=0 chnl=15 +char id=119 x=359 y=463 width=51 height=41 xoffset=-2 yoffset=19 xadvance=44 page=0 chnl=15 +char id=120 x=412 y=465 width=35 height=40 xoffset=-2 yoffset=21 xadvance=29 page=0 chnl=15 +char id=121 x=449 y=465 width=37 height=52 xoffset=0 yoffset=22 xadvance=35 page=0 chnl=15 +char id=122 x=2 y=543 width=38 height=40 xoffset=-3 yoffset=21 xadvance=31 page=0 chnl=15 +char id=123 x=42 y=527 width=24 height=61 xoffset=-3 yoffset=5 xadvance=18 page=0 chnl=15 +char id=124 x=68 y=522 width=16 height=66 xoffset=1 yoffset=1 xadvance=15 page=0 chnl=15 +char id=125 x=86 y=527 width=24 height=61 xoffset=-1 yoffset=5 xadvance=18 page=0 chnl=15 +char id=126 x=112 y=526 width=32 height=16 xoffset=0 yoffset=4 xadvance=29 page=0 chnl=15 +char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=4 xadvance=29 page=0 chnl=15 \ No newline at end of file diff --git a/games/wave_collector/resources/font.png b/games/wave_collector/resources/font.png new file mode 100644 index 00000000..15287ccb Binary files /dev/null and b/games/wave_collector/resources/font.png differ diff --git a/games/wave_collector/resources/textures/background.png b/games/wave_collector/resources/textures/background.png new file mode 100644 index 00000000..f8613f82 Binary files /dev/null and b/games/wave_collector/resources/textures/background.png differ diff --git a/games/wave_collector/resources/textures/background_gameplay.png b/games/wave_collector/resources/textures/background_gameplay.png new file mode 100644 index 00000000..e4180288 Binary files /dev/null and b/games/wave_collector/resources/textures/background_gameplay.png differ diff --git a/games/wave_collector/resources/textures/background_title.png b/games/wave_collector/resources/textures/background_title.png new file mode 100644 index 00000000..01fc46d3 Binary files /dev/null and b/games/wave_collector/resources/textures/background_title.png differ diff --git a/games/wave_collector/resources/textures/icon_synchro.png b/games/wave_collector/resources/textures/icon_synchro.png new file mode 100644 index 00000000..b7172823 Binary files /dev/null and b/games/wave_collector/resources/textures/icon_synchro.png differ diff --git a/games/wave_collector/resources/textures/icon_warp.png b/games/wave_collector/resources/textures/icon_warp.png new file mode 100644 index 00000000..2a5eb7bb Binary files /dev/null and b/games/wave_collector/resources/textures/icon_warp.png differ diff --git a/games/wave_collector/resources/textures/line.png b/games/wave_collector/resources/textures/line.png new file mode 100644 index 00000000..6c338710 Binary files /dev/null and b/games/wave_collector/resources/textures/line.png differ diff --git a/games/wave_collector/resources/textures/logo_raylib.png b/games/wave_collector/resources/textures/logo_raylib.png new file mode 100644 index 00000000..99ba5437 Binary files /dev/null and b/games/wave_collector/resources/textures/logo_raylib.png differ diff --git a/games/wave_collector/resources/textures/lose.png b/games/wave_collector/resources/textures/lose.png new file mode 100644 index 00000000..f01c0284 Binary files /dev/null and b/games/wave_collector/resources/textures/lose.png differ diff --git a/games/wave_collector/resources/textures/player.png b/games/wave_collector/resources/textures/player.png new file mode 100644 index 00000000..c8913a8f Binary files /dev/null and b/games/wave_collector/resources/textures/player.png differ diff --git a/games/wave_collector/resources/textures/sample_big.png b/games/wave_collector/resources/textures/sample_big.png new file mode 100644 index 00000000..b4c4be97 Binary files /dev/null and b/games/wave_collector/resources/textures/sample_big.png differ diff --git a/games/wave_collector/resources/textures/sample_mid.png b/games/wave_collector/resources/textures/sample_mid.png new file mode 100644 index 00000000..20ec5868 Binary files /dev/null and b/games/wave_collector/resources/textures/sample_mid.png differ diff --git a/games/wave_collector/resources/textures/sample_small.png b/games/wave_collector/resources/textures/sample_small.png new file mode 100644 index 00000000..7b624f7f Binary files /dev/null and b/games/wave_collector/resources/textures/sample_small.png differ diff --git a/games/wave_collector/resources/textures/title.png b/games/wave_collector/resources/textures/title.png new file mode 100644 index 00000000..383dfdc3 Binary files /dev/null and b/games/wave_collector/resources/textures/title.png differ diff --git a/games/wave_collector/resources/textures/win.png b/games/wave_collector/resources/textures/win.png new file mode 100644 index 00000000..d7afdc25 Binary files /dev/null and b/games/wave_collector/resources/textures/win.png differ diff --git a/games/wave_collector/screens/screen_ending.c b/games/wave_collector/screens/screen_ending.c new file mode 100644 index 00000000..d246005c --- /dev/null +++ b/games/wave_collector/screens/screen_ending.c @@ -0,0 +1,111 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Ending Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raylib.h" +#include "screens.h" + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Ending screen global variables +static int framesCounter; +static int finishScreen; + +static Texture2D texBackground; +static Texture2D texWin; +static Texture2D texLose; +static Texture2D texLogo; + +//---------------------------------------------------------------------------------- +// Ending Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Ending Screen Initialization logic +void InitEndingScreen(void) +{ + // TODO: Initialize ENDING screen variables here! + framesCounter = 0; + finishScreen = 0; + + texBackground = LoadTexture("resources/textures/background.png"); + texWin = LoadTexture("resources/textures/win.png"); + texLose = LoadTexture("resources/textures/lose.png"); + texLogo = LoadTexture("resources/textures/logo_raylib.png"); +} + +// Ending Screen Update logic +void UpdateEndingScreen(void) +{ + // TODO: Update ENDING screen variables here! + framesCounter++; + + // Press enter to return to TITLE screen + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + finishScreen = 1; + } +} + +// Ending Screen Draw logic +void DrawEndingScreen(void) +{ + DrawTexture(texBackground, 0, 0, WHITE); + + if (endingStatus == 1) // Win + { + DrawTexture(texWin, GetScreenWidth()/2 - texWin.width/2, 90, WHITE); + DrawTextEx(font, "congrats, you got the wave!", (Vector2){ 200, 335 }, font.size, 0, WHITE); + } + else if (endingStatus == 2) // Lose + { + DrawTexture(texLose, GetScreenWidth()/2 - texWin.width/2, 90, WHITE); + DrawTextEx(font, "it seems you lose the wave...", (Vector2){ 205, 335 }, font.size, 0, WHITE); + } + + DrawRectangle(0, GetScreenHeight() - 70, 560, 40, Fade(RAYWHITE, 0.8f)); + DrawText("(c) Developed by Ramon Santamaria (@raysan5)", 36, GetScreenHeight() - 60, 20, DARKBLUE); + + DrawText("powered by", GetScreenWidth() - 162, GetScreenHeight() - 190, 20, DARKGRAY); + DrawTexture(texLogo, GetScreenWidth() - 128 - 34, GetScreenHeight() - 128 - 36, WHITE); + + if ((framesCounter > 80) && ((framesCounter/40)%2)) DrawTextEx(font, "mouse click to return", (Vector2){ 300, 464 }, font.size, 0, SKYBLUE); +} + +// Ending Screen Unload logic +void UnloadEndingScreen(void) +{ + // TODO: Unload ENDING screen variables here! + UnloadTexture(texBackground); + UnloadTexture(texWin); + UnloadTexture(texLose); + UnloadTexture(texLogo); +} + +// Ending Screen should finish? +int FinishEndingScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/wave_collector/screens/screen_gameplay.c b/games/wave_collector/screens/screen_gameplay.c new file mode 100644 index 00000000..a3a9394a --- /dev/null +++ b/games/wave_collector/screens/screen_gameplay.c @@ -0,0 +1,490 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raylib.h" +#include "screens.h" + +#include // Required for: malloc(), free() +#include // Required for: sqrtf(), asinf() + +#define MAX_SAMPLES_SPEED 7 // Max speed for samples movement +#define MIN_SAMPLES_SPEED 3 // Min speed for samples movement +#define SAMPLES_SPACING 100 // Separation between samples in pixels +#define SAMPLES_MULTIPLIER 500 // Defines sample data scaling value (it would be adjusted to MAX_GAME_HEIGHT) +#define MAX_GAME_HEIGHT 400 // Defines max possible amplitude between samples (game area) + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef struct Player { + Vector2 position; + Vector2 speed; + int width; + int height; + Color color; +} Player; + +typedef struct Sample { + float value; + Vector2 position; + int radius; + bool active; // Define if sample is active (can be collected) + bool collected; // Define if sample has been collected + bool renderable; // Define if sample should be rendered + Color color; +} Sample; + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Gameplay screen global variables +static int framesCounter; +static int finishScreen; +static bool pause; + +// Player variables +static Player player; +static Rectangle playerArea; // Define player movement area (and sample collection limits) + +static float warpCounter; // Time warp counter +static float synchro; // Calculates collected samples relation [0..1] + +//static int combo; +//static int maxCombo; + +static Rectangle waveRec; + +// Samples variables +static Sample *samples; // Game samples +static int totalSamples = 0; // Total game samples (proportional to waveData num samples) +static int collectedSamples; // Samples collected by player +static int currentSample; // Last sample to go through player collect area +static float samplesSpeed; // All samples move at the same speed +static float waveTime; // Total sample time in ms + +// Resources variables +static Texture2D texBackground; +static Texture2D texPlayer; +static Texture2D texSampleSmall; +static Texture2D texSampleMid; +static Texture2D texSampleBig; +static Texture2D texLine; + +//static RenderTexture2D waveTarget; + +static Sound fxSampleOn; // Collected sample sound +static Sound fxSampleOff; // Miss sample sound +static Sound fxWave; // Sound from wave sample +static Sound fxPause; // Pause sound +// Debug variables + +//------------------------------------------------------------------------------------ +// Module Functions Declaration (local) +//------------------------------------------------------------------------------------ +//static void DrawWave(float *waveData, int sampleCount, Rectangle bounds, Color color); +//static void DrawWaveEx(float *waveData, int sampleCount, int playedSamples, Rectangle bounds, Color color); +static void DrawSamples(Sample *samples, int sampleCount, int playedSamples, Rectangle bounds, Color color); + +//---------------------------------------------------------------------------------- +// Gameplay Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Gameplay Screen Initialization logic +void InitGameplayScreen(void) +{ + framesCounter = 0; + finishScreen = 0; + pause = false; + endingStatus = 0; + + // Textures loading + texBackground = LoadTexture("resources/textures/background_gameplay.png"); + texPlayer = LoadTexture("resources/textures/player.png"); + texSampleSmall = LoadTexture("resources/textures/sample_small.png"); + texSampleMid = LoadTexture("resources/textures/sample_mid.png"); + texSampleBig = LoadTexture("resources/textures/sample_big.png"); + texLine = LoadTexture("resources/textures/line.png"); + + waveRec = (Rectangle){ 32, 32, 1280 - 64, 105 }; + //RenderTexture2D waveTarget = LoadRenderTexture(waveRec.width, waveRec.height); + + // Sound loading + fxSampleOn = LoadSound("resources/audio/sample_on.wav"); + fxSampleOff = LoadSound("resources/audio/sample_off.wav"); + fxPause = LoadSound("resources/audio/pause.wav"); + + SetSoundVolume(fxSampleOn, 0.6f); + SetSoundVolume(fxPause, 0.5f); + + // Initialize player data + playerArea = (Rectangle){ 200, 160, 80, 400 }; + + player.width = 20; + player.height = 60; + player.speed = (Vector2){ 15, 15 }; + player.color = GOLD; + player.position = (Vector2){ playerArea.x + playerArea.width/2 - texPlayer.width/2, + playerArea.y + playerArea.height/2 - texPlayer.height/2 }; + + warpCounter = 395; + synchro = 0.2f; + + // Initialize wave and samples data + Wave wave = LoadWave("resources/audio/wave.ogg"); + float *waveData = GetWaveData(wave); + //printf("Wave total samples: %i\n", wave.sampleCount); + + // We calculate the required parameters to adjust audio time to gameplay time + // that way samples collected correspond to audio playing + // Synchonization is not perfect due to possible rounding issues (float to int) + waveTime = wave.sampleCount/wave.sampleRate; // Total sample time in seconds + float requiredSamples = (MAX_SAMPLES_SPEED*waveTime*60 - 1000)/SAMPLES_SPACING; + int samplesDivision = (int)(wave.sampleCount/requiredSamples); + + totalSamples = wave.sampleCount/samplesDivision; + + fxWave = LoadSoundFromWave(wave); + UnloadWave(wave); + + collectedSamples = 0; + + // Init samples + samples = (Sample *)malloc(totalSamples*sizeof(Sample)); + + // Normalize wave data (min vs max values) to scale properly + float minSampleValue = 0.0f; + float maxSampleValue = 0.0f; + + for (int i = 0; i < totalSamples; i++) + { + if (waveData[i*samplesDivision] < minSampleValue) minSampleValue = waveData[i*samplesDivision]; + if (waveData[i*samplesDivision] > maxSampleValue) maxSampleValue = waveData[i*samplesDivision]; + } + + float sampleScaleFactor = 1.0f/(maxSampleValue - minSampleValue); // 400 pixels maximum size + + // Initialize samples + for (int i = 0; i < totalSamples; i++) + { + samples[i].value = waveData[i*samplesDivision]*sampleScaleFactor; // Normalized value [-1.0..1.0] + samples[i].position.x = player.position.x + 1000 + i*SAMPLES_SPACING; + + samples[i].position.y = GetScreenHeight()/2 + samples[i].value*SAMPLES_MULTIPLIER; + + if (samples[i].position.y > GetScreenHeight()/2 + MAX_GAME_HEIGHT/2) samples[i].position.y = GetScreenHeight()/2 - MAX_GAME_HEIGHT/2; + else if (samples[i].position.y < GetScreenHeight()/2 - MAX_GAME_HEIGHT/2) samples[i].position.y = GetScreenHeight()/2 + MAX_GAME_HEIGHT/2; + + samples[i].radius = 6; + samples[i].active = true; + samples[i].collected = false; + samples[i].color = RED; + } + + samplesSpeed = MAX_SAMPLES_SPEED; + currentSample = 0; + + // We already saved the samples we needed for the game, we can free waveData + free(waveData); + + // Load and start playing music + // NOTE: Music is loaded in main code base + PlayMusicStream(music); +} + +// Gameplay Screen Update logic +void UpdateGameplayScreen(void) +{ + if (IsKeyPressed('P')) + { + PlaySound(fxPause); + pause = !pause; + + if (pause) PauseMusicStream(music); + else ResumeMusicStream(music); + } + + if (!pause) + { + framesCounter++; // Time starts counting to awake enemies + + // Player movement logic (mouse) + player.position.y = GetMousePosition().y; + + // Player movement logic (keyboard) + if (IsKeyDown(KEY_W)) player.position.y -= player.speed.y; + else if (IsKeyDown(KEY_S)) player.position.y += player.speed.y; + + // Player movement logic (gamepad) + /* + if (IsGamepadAvailable(GAMEPAD_PLAYER1)) + { + Vector2 movement = { 0.0f }; + + movement.x = GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_X); + movement.y = GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_PS3_AXIS_LEFT_Y); + + player.position.x += movement.x*0.1f; // Scale gamepad movement value + player.position.y += movement.y*0.1f; // Scale gamepad movement value + } + */ + + // Player logic: check player area limits + if (player.position.x < playerArea.x) player.position.x = playerArea.x; + else if ((player.position.x + player.width) > (playerArea.x + playerArea.width)) player.position.x = playerArea.x + playerArea.width - player.width; + + if (player.position.y < playerArea.y) player.position.y = playerArea.y; + else if ((player.position.y + player.height) > (playerArea.y + playerArea.height)) player.position.y = playerArea.y + playerArea.height - player.height; + + // Samples logic + for (int i = 0; i < totalSamples; i++) + { + // Samples movement logic + samples[i].position.x -= samplesSpeed; + + if (((samples[i].position.x + samples[i].radius) > -SAMPLES_SPACING) && + ((samples[i].position.x - samples[i].radius) < GetScreenWidth())) samples[i].renderable = true; + else samples[i].renderable = false; + + // Samples catch logic + if (!samples[i].collected && CheckCollisionCircleRec(samples[i].position, samples[i].radius, (Rectangle){ (int)player.position.x, (int)player.position.y, player.width, player.height })) + { + samples[i].collected = true; + collectedSamples++; + synchro += 0.02; + + if (synchro >= 1.0f) synchro = 1.0f; + + // Set sound pitch depending on sample position (base pitch: 1.0f) + // NOTE: waveData[i*WAVE_SAMPLES_DIV] is scaled to [0.3..1.7] + SetSoundPitch(fxSampleOn, samples[i].value*1.4f + 0.7f); + + PlaySound(fxSampleOn); + } + + if ((samples[i].position.x - samples[i].radius) < player.position.x) + { + currentSample = i; // Register last sample going out range + + if (samples[i].active) + { + samples[i].active = false; + + //PlaySound(fxSampleOff); + + if (!samples[i].collected) synchro -= 0.05f; + } + } + } + + if (IsKeyDown(KEY_SPACE) && (warpCounter > 0)) + { + warpCounter--; + if (warpCounter < 0) warpCounter = 0; + + samplesSpeed -= 0.1f; + if (samplesSpeed <= MIN_SAMPLES_SPEED) samplesSpeed = MIN_SAMPLES_SPEED; + + SetMusicPitch(music, samplesSpeed/MAX_SAMPLES_SPEED); + } + else + { + warpCounter++; + if (warpCounter > 395) warpCounter = 395; + + samplesSpeed += 0.1f; + if (samplesSpeed >= MAX_SAMPLES_SPEED) samplesSpeed = MAX_SAMPLES_SPEED; + + SetMusicPitch(music, samplesSpeed/MAX_SAMPLES_SPEED); + } + + // Check ending conditions + if (currentSample >= totalSamples) + { + StopMusicStream(music); + endingStatus = 1; // Win + finishScreen = 1; + } + + if (synchro <= 0.0f) + { + synchro = 0.0f; + StopMusicStream(music); + endingStatus = 2; // Loose + finishScreen = 1; + } + } +} + +// Gameplay Screen Draw logic +void DrawGameplayScreen(void) +{ + // Draw background + DrawTexture(texBackground, 0, 0, WHITE); + + // Screen elements drawing + //DrawRectangleLines(playerArea.x, playerArea.y, playerArea.width, playerArea.height, BLUE); + DrawRectangle(0, GetScreenHeight()/2 - 1, GetScreenWidth(), 2, Fade(BLUE, 0.3f)); + //DrawRectangleLines(0, GetScreenHeight()/2 - MAX_GAME_HEIGHT/2, GetScreenWidth(), MAX_GAME_HEIGHT, GRAY); + + // Draw samples + for (int i = 0; i < totalSamples - 1; i++) + { + if (samples[i].renderable) + { + Color col = samples[i].color; + + if (i < (currentSample + 1)) col = Fade(DARKGRAY, 0.5f); + else col = WHITE; + + //DrawCircleV(samples[i].position, samples[i].radius, col); + if (!samples[i].collected) + { + // TODO: Draw differnt size samples + DrawTexture(texSampleMid, samples[i].position.x - texSampleMid.width/2, samples[i].position.y - texSampleMid.height/2, col); + + } + + if (i < (currentSample + 1)) col = Fade(GRAY, 0.3f); + else col = Fade(WHITE, 0.5f); + + // Draw line between samples + //DrawLine(samples[i].position.x, samples[i].position.y, samples[i + 1].position.x, samples[i + 1].position.y, col); + + float dx = samples[i + 1].position.x - samples[i].position.x; + float dy = samples[i + 1].position.y - samples[i].position.y; + float d = sqrtf(dx*dx + dy*dy); + float angle = asinf(dy/d); + + // TODO: Draw lines using textures - IMPROVE! + //DrawTextureEx(texLine, (Vector2){ samples[i].position.x - 2, samples[i].position.y - 2 }, -RAD2DEG*angle, d/SAMPLES_SPACING, col); + + DrawTexturePro(texLine, (Rectangle){ 0, 0, texLine.width, texLine.height }, + (Rectangle){ samples[i].position.x, samples[i].position.y, (float)texLine.width*d/SAMPLES_SPACING, texLine.height }, + (Vector2){ 0, (float)texLine.height/2 }, -RAD2DEG*angle, col); + } + } + + // Draw player + //DrawRectangle((int)player.position.x, (int)player.position.y, player.width, player.height, player.color); + DrawTexture(texPlayer, player.position.x - 32, player.position.y - 24, WHITE); + + // Draw pause message + if (pause) DrawTextEx(font, "WAVE PAUSED", (Vector2){ 235, 400 }, font.size*2, 0, WHITE); + + // Draw number of samples + //DrawText(FormatText("%05i", collectedSamples), 900, 200, 40, GRAY); + //DrawText(FormatText("%05i", totalSamples), 900, 250, 40, GRAY); + DrawTextEx(font, FormatText("%05i / %05i", collectedSamples, totalSamples), (Vector2){810, 170}, font.size, -2, SKYBLUE); + + // Draw synchonicity level + DrawRectangle(99, 622, 395, 32, Fade(RAYWHITE, 0.8f)); + + if (synchro <= 0.3f) DrawRectangle(99, 622, synchro*395, 32, Fade(RED, 0.8f)); + else if (synchro <= 0.8f) DrawRectangle(99, 622, synchro*395, 32, Fade(ORANGE,0.8f)); + else if (synchro < 1.0f) DrawRectangle(99, 622, synchro*395, 32, Fade(LIME,0.8f)); + else DrawRectangle(99, 622, synchro*395, 32, Fade(GREEN, 0.9f)); + + DrawRectangleLines(99, 622, 395, 32, MAROON); + + if (synchro == 1.0f) DrawTextEx(font, FormatText("%02i%%", (int)(synchro*100)), (Vector2){99 + 390, 600}, font.size, -2, GREEN); + else DrawTextEx(font, FormatText("%02i%%", (int)(synchro*100)), (Vector2){99 + 390, 600}, font.size, -2, SKYBLUE); + + // Draw time warp coool-down bar + DrawRectangle(754, 622, 395, 32, Fade(RAYWHITE, 0.8f)); + DrawRectangle(754, 622, warpCounter, 32, Fade(SKYBLUE, 0.8f)); + DrawRectangleLines(754, 622, 395, 32, DARKGRAY); + //DrawText(FormatText("%02i%%", (int)(synchro*100)), 754 + 410, 628, 20, DARKGRAY); + DrawTextEx(font, FormatText("%02i%%", (int)((float)warpCounter/395.0f*100.0f)), (Vector2){754 + 390, 600}, font.size, -2, SKYBLUE); + + // Draw wave + // NOTE: Old drawing method, replaced by rendertarget + DrawSamples(samples, totalSamples, currentSample, waveRec, MAROON); + DrawRectangle(waveRec.x + (int)currentSample*1240/totalSamples, waveRec.y, 2, 99, DARKGRAY); + //DrawRectangleLines(20, 20, 1240, 140, DARKGRAY); + //DrawRectangle(20, 150, (float)currentSample/totalSamples*1240, 10, GRAY); + + // TODO: Draw wave using render target --> It FAILS! Need to review... + /* + BeginTextureMode(waveTarget); + DrawSamples(samples, totalSamples, currentSample, (Rectangle){ 0, 0, waveTarget.texture.width, waveTarget.texture.height }, MAROON); + EndTextureMode(); + + DrawTextureEx(waveTarget.texture, (Vector2){ waveRec.x, waveRec.y }, 0.0f, 1.0f, WHITE); + */ +} + +// Gameplay Screen Unload logic +void UnloadGameplayScreen(void) +{ + // Unload textures + UnloadTexture(texBackground); + UnloadTexture(texPlayer); + UnloadTexture(texSampleSmall); + UnloadTexture(texSampleMid); + UnloadTexture(texSampleBig); + UnloadTexture(texLine); + + //UnloadRenderTexture(waveTarget); + + // Unload sounds + UnloadSound(fxSampleOn); + UnloadSound(fxSampleOff); + UnloadSound(fxWave); + UnloadSound(fxPause); + + //free(samples); // Unload game samples (crashes game) +} + +// Gameplay Screen should finish? +int FinishGameplayScreen(void) +{ + return finishScreen; +} + +//------------------------------------------------------------------------------------ +// Module Functions Definitions (local) +//------------------------------------------------------------------------------------ + +// Draw samples in wave form (including already played samples in a different color!) +// NOTE: For proper visualization, MSAA x4 is recommended, alternatively +// it should be rendered to a bigger texture and then scaled down with +// bilinear/trilinear texture filtering +static void DrawSamples(Sample *samples, int sampleCount, int playedSamples, Rectangle bounds, Color color) +{ + // NOTE: We just pick a sample to draw every increment + float sampleIncrementX = (float)bounds.width/sampleCount; + + Color col = color; + + for (int i = 0; i < sampleCount - 1; i++) + { + if (i < playedSamples) col = GRAY; + else col = color; + + DrawLineV((Vector2){ (float)bounds.x + (float)i*sampleIncrementX, (float)(bounds.y + bounds.height/2) + samples[i].value*bounds.height }, + (Vector2){ (float)bounds.x + (float)(i + 1)*sampleIncrementX, (float)(bounds.y + bounds.height/2) + + samples[i + 1].value*bounds.height }, col); + } +} \ No newline at end of file diff --git a/games/wave_collector/screens/screen_logo.c b/games/wave_collector/screens/screen_logo.c new file mode 100644 index 00000000..e855752e --- /dev/null +++ b/games/wave_collector/screens/screen_logo.c @@ -0,0 +1,181 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Logo Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raylib.h" +#include "screens.h" + +#define LOGO_RECS_SIDE 16 + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Logo screen global variables +static int framesCounter; +static int finishScreen; + +static int logoPositionX; +static int logoPositionY; + +static int lettersCount; + +static int topSideRecWidth; +static int leftSideRecHeight; + +static int bottomSideRecWidth; +static int rightSideRecHeight; + +static int state; // Tracking animation states (State Machine) +static float alpha = 1.0f; // Useful for fading + +//---------------------------------------------------------------------------------- +// Logo Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Logo Screen Initialization logic +void InitLogoScreen(void) +{ + // Initialize LOGO screen variables here! + finishScreen = 0; + framesCounter = 0; + lettersCount = 0; + + logoPositionX = GetScreenWidth()/2 - 128; + logoPositionY = GetScreenHeight()/2 - 128; + + topSideRecWidth = LOGO_RECS_SIDE; + leftSideRecHeight = LOGO_RECS_SIDE; + bottomSideRecWidth = LOGO_RECS_SIDE; + rightSideRecHeight = LOGO_RECS_SIDE; + + state = 0; + alpha = 1.0f; +} + +// Logo Screen Update logic +void UpdateLogoScreen(void) +{ + // Update LOGO screen variables here! + if (state == 0) // State 0: Small box blinking + { + framesCounter++; + + if (framesCounter == 80) + { + state = 1; + framesCounter = 0; // Reset counter... will be used later... + + PlayMusicStream(music); // Start playing music... ;) + } + } + else if (state == 1) // State 1: Top and left bars growing + { + topSideRecWidth += 8; + leftSideRecHeight += 8; + + if (topSideRecWidth == 256) state = 2; + } + else if (state == 2) // State 2: Bottom and right bars growing + { + bottomSideRecWidth += 8; + rightSideRecHeight += 8; + + if (bottomSideRecWidth == 256) state = 3; + } + else if (state == 3) // State 3: Letters appearing (one by one) + { + framesCounter++; + + if (lettersCount < 10) + { + if (framesCounter/15) // Every 12 frames, one more letter! + { + lettersCount++; + framesCounter = 0; + } + } + else // When all letters have appeared, just fade out everything + { + if (framesCounter > 200) + { + alpha -= 0.02f; + + if (alpha <= 0.0f) + { + alpha = 0.0f; + finishScreen = 1; + } + } + } + } +} + +// Logo Screen Draw logic +void DrawLogoScreen(void) +{ + if (state == 0) + { + if ((framesCounter/10)%2) DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK); + } + else if (state == 1) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK); + DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK); + } + else if (state == 2) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK); + DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK); + + DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK); + DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK); + } + else if (state == 3) + { + DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha)); + DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha)); + + DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha)); + DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha)); + + DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha)); + + DrawText(SubText("raylib", 0, lettersCount), GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha)); + + if (framesCounter > 20) DrawText("powered by", logoPositionX, logoPositionY - 27, 20, Fade(DARKGRAY, alpha)); + } +} + +// Logo Screen Unload logic +void UnloadLogoScreen(void) +{ + // Unload LOGO screen variables here! +} + +// Logo Screen should finish? +int FinishLogoScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/wave_collector/screens/screen_title.c b/games/wave_collector/screens/screen_title.c new file mode 100644 index 00000000..1d33e3ba --- /dev/null +++ b/games/wave_collector/screens/screen_title.c @@ -0,0 +1,112 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Title Screen Functions Definitions (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#include "raylib.h" +#include "screens.h" + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- + +// Title screen global variables +static int framesCounter; +static int finishScreen; + +static Texture2D texBackground; +static Texture2D texTitle; +static Texture2D texLogo; + +static float titleAlpha = 0.0f; + +static Sound fxStart; + +//---------------------------------------------------------------------------------- +// Title Screen Functions Definition +//---------------------------------------------------------------------------------- + +// Title Screen Initialization logic +void InitTitleScreen(void) +{ + // Initialize TITLE screen variables here! + framesCounter = 0; + finishScreen = 0; + + texBackground = LoadTexture("resources/textures/background_title.png"); + texTitle = LoadTexture("resources/textures/title.png"); + texLogo = LoadTexture("resources/textures/logo_raylib.png"); + + fxStart = LoadSound("resources/audio/start.wav"); +} + +// Title Screen Update logic +void UpdateTitleScreen(void) +{ + // Update TITLE screen variables here! + framesCounter++; + + titleAlpha += 0.005f; + + if (titleAlpha >= 1.0f) titleAlpha = 1.0f; + + // Press enter to change to ATTIC screen + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + { + PlaySound(fxStart); + StopMusicStream(music); + finishScreen = 1; + } +} + +// Title Screen Draw logic +void DrawTitleScreen(void) +{ + DrawTexture(texBackground, 0, 0, WHITE); + DrawTexture(texTitle, GetScreenWidth()/2 - texTitle.width/2, -25, Fade(WHITE, titleAlpha)); + + DrawRectangle(0, GetScreenHeight() - 70, 560, 40, Fade(RAYWHITE, 0.8f)); + DrawText("(c) Developed by Ramon Santamaria (@raysan5)", 36, GetScreenHeight() - 60, 20, DARKBLUE); + + DrawText("powered by", GetScreenWidth() - 162, GetScreenHeight() - 190, 20, DARKGRAY); + DrawTexture(texLogo, GetScreenWidth() - 128 - 34, GetScreenHeight() - 128 - 36, WHITE); + + if ((framesCounter > 160) && ((framesCounter/40)%2)) DrawTextEx(font, "mouse click to start", (Vector2){ 325, 500 }, font.size, 0, SKYBLUE); +} + +// Title Screen Unload logic +void UnloadTitleScreen(void) +{ + // Unload TITLE screen variables here! + UnloadTexture(texBackground); + UnloadTexture(texTitle); + UnloadTexture(texLogo); + + UnloadSound(fxStart); +} + +// Title Screen should finish? +int FinishTitleScreen(void) +{ + return finishScreen; +} \ No newline at end of file diff --git a/games/wave_collector/screens/screens.h b/games/wave_collector/screens/screens.h new file mode 100644 index 00000000..9c9c5175 --- /dev/null +++ b/games/wave_collector/screens/screens.h @@ -0,0 +1,87 @@ +/********************************************************************************************** +* +* raylib - Advance Game template +* +* Screens Functions Declarations (Init, Update, Draw, Unload) +* +* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +#ifndef SCREENS_H +#define SCREENS_H + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef enum GameScreen { LOGO = 0, TITLE, GAMEPLAY, ENDING } GameScreen; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +GameScreen currentScreen; +SpriteFont font; +Music music; +int endingStatus; // 1 - Win, 2 - Lose +//char *sampleFilename; + +#ifdef __cplusplus +extern "C" { // Prevents name mangling of functions +#endif + +//---------------------------------------------------------------------------------- +// Logo Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitLogoScreen(void); +void UpdateLogoScreen(void); +void DrawLogoScreen(void); +void UnloadLogoScreen(void); +int FinishLogoScreen(void); + +//---------------------------------------------------------------------------------- +// Title Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitTitleScreen(void); +void UpdateTitleScreen(void); +void DrawTitleScreen(void); +void UnloadTitleScreen(void); +int FinishTitleScreen(void); + +//---------------------------------------------------------------------------------- +// Gameplay Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitGameplayScreen(void); +void UpdateGameplayScreen(void); +void DrawGameplayScreen(void); +void UnloadGameplayScreen(void); +int FinishGameplayScreen(void); + +//---------------------------------------------------------------------------------- +// Ending Screen Functions Declaration +//---------------------------------------------------------------------------------- +void InitEndingScreen(void); +void UpdateEndingScreen(void); +void DrawEndingScreen(void); +void UnloadEndingScreen(void); +int FinishEndingScreen(void); + +#ifdef __cplusplus +} +#endif + +#endif // SCREENS_H \ No newline at end of file diff --git a/games/wave_collector/wave_collector.c b/games/wave_collector/wave_collector.c new file mode 100644 index 00000000..8c271604 --- /dev/null +++ b/games/wave_collector/wave_collector.c @@ -0,0 +1,310 @@ +/******************************************************************************************* +* +* GLOBAL GAME JAM 2017 - WAVE COLLECTOR +* +* The ultimate wave particles collector is here! +* You must follow the wave and collect all the particles +* The level is actually the wave and the wave is the level! +* Be fast! Be smart! Be the best wave collector! +* +* This game has been created using raylib (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2017 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" +#include "screens/screens.h" // NOTE: Defines global variable: currentScreen + +#include + +#if defined(PLATFORM_WEB) + #include +#endif + +//---------------------------------------------------------------------------------- +// Global Variables Definition (local to this module) +//---------------------------------------------------------------------------------- +const int screenWidth = 1280; +const int screenHeight = 720; + +// Required variables to manage screen transitions (fade-in, fade-out) +float transAlpha = 0; +bool onTransition = false; +bool transFadeOut = false; +int transFromScreen = -1; +int transToScreen = -1; + +//---------------------------------------------------------------------------------- +// Local Functions Declaration +//---------------------------------------------------------------------------------- +void TransitionToScreen(int screen); +void ChangeToScreen(int screen); // No transition effect +void UpdateTransition(void); +void DrawTransition(void); + +void UpdateDrawFrame(void); // Update and Draw one frame + +//static const char *GetExtension(const char *fileName); + +//---------------------------------------------------------------------------------- +// Main entry point +//---------------------------------------------------------------------------------- +int main(int argc, char *argv[]) +{ + // Initialization + //--------------------------------------------------------- + /* +#if !defined(PLATFORM_WEB) + // TODO: Add support for dropped files on the exe + sampleFilename = (char *)malloc(256); + if (argc > 1) + { + if ((strcmp(GetExtension(argv[1]), "ogg") == 0) || + (strcmp(GetExtension(argv[1]), "wav") == 0)) + { + strcpy(sampleFilename, argv[1]); + } + } +#endif + */ + SetConfigFlags(FLAG_MSAA_4X_HINT); + InitWindow(screenWidth, screenHeight, "GGJ17 - WAVE COLLECTOR"); + + // Global data loading (assets that must be available in all screens, i.e. fonts) + InitAudioDevice(); + + font = LoadSpriteFont("resources/font.fnt"); + music = LoadMusicStream("resources/audio/wave.ogg"); + + SetMusicVolume(music, 1.0f); + + // Setup and Init first screen + currentScreen = LOGO; + InitLogoScreen(); + //InitTitleScreen(); + //InitGameplayScreen(); + //InitEndingScreen(); + +#if defined(PLATFORM_WEB) + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); +#else + SetTargetFPS(60); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + UpdateDrawFrame(); + } +#endif + + // De-Initialization + //-------------------------------------------------------------------------------------- + switch (currentScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + // Unload all global loaded data (i.e. fonts) here! + UnloadSpriteFont(font); + UnloadMusicStream(music); + + CloseAudioDevice(); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +void TransitionToScreen(int screen) +{ + onTransition = true; + transFromScreen = currentScreen; + transToScreen = screen; +} + +void ChangeToScreen(int screen) +{ + switch (currentScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + switch (screen) + { + case LOGO: InitLogoScreen(); break; + case TITLE: InitTitleScreen(); break; + case GAMEPLAY: InitGameplayScreen(); break; + case ENDING: InitEndingScreen(); break; + default: break; + } + + currentScreen = screen; +} + +void UpdateTransition(void) +{ + if (!transFadeOut) + { + transAlpha += 0.05f; + + if (transAlpha >= 1.0) + { + transAlpha = 1.0; + + switch (transFromScreen) + { + case LOGO: UnloadLogoScreen(); break; + case TITLE: UnloadTitleScreen(); break; + case GAMEPLAY: UnloadGameplayScreen(); break; + case ENDING: UnloadEndingScreen(); break; + default: break; + } + + switch (transToScreen) + { + case LOGO: + { + InitLogoScreen(); + currentScreen = LOGO; + } break; + case TITLE: + { + InitTitleScreen(); + currentScreen = TITLE; + } break; + case GAMEPLAY: + { + InitGameplayScreen(); + currentScreen = GAMEPLAY; + } break; + case ENDING: + { + InitEndingScreen(); + currentScreen = ENDING; + } break; + default: break; + } + + transFadeOut = true; + } + } + else // Transition fade out logic + { + transAlpha -= 0.05f; + + if (transAlpha <= 0) + { + transAlpha = 0; + transFadeOut = false; + onTransition = false; + transFromScreen = -1; + transToScreen = -1; + } + } +} + +void DrawTransition(void) +{ + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(RAYWHITE, transAlpha)); +} + +// Update and draw game frame +void UpdateDrawFrame(void) +{ + // Update + //---------------------------------------------------------------------------------- + if (!onTransition) + { + switch(currentScreen) + { + case LOGO: + { + UpdateLogoScreen(); + + if (FinishLogoScreen()) TransitionToScreen(TITLE); + + } break; + case TITLE: + { + UpdateTitleScreen(); + + if (FinishTitleScreen() == 1) + { + StopMusicStream(music); + TransitionToScreen(GAMEPLAY); + } + + } break; + case GAMEPLAY: + { + UpdateGameplayScreen(); + + if (FinishGameplayScreen() == 1) TransitionToScreen(ENDING); + //else if (FinishGameplayScreen() == 2) TransitionToScreen(TITLE); + + } break; + case ENDING: + { + UpdateEndingScreen(); + + if (FinishEndingScreen() == 1) TransitionToScreen(TITLE); + + } break; + default: break; + } + } + else + { + // Update transition (fade-in, fade-out) + UpdateTransition(); + } + + if (currentScreen != ENDING) UpdateMusicStream(music); + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + switch(currentScreen) + { + case LOGO: DrawLogoScreen(); break; + case TITLE: DrawTitleScreen(); break; + case GAMEPLAY: DrawGameplayScreen(); break; + case ENDING: DrawEndingScreen(); break; + default: break; + } + + if (onTransition) DrawTransition(); + + //DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- +} + +/* +#if !defined(PLATFORM_WEB) +// Get the extension for a filename +static const char *GetExtension(const char *fileName) +{ + const char *dot = strrchr(fileName, '.'); + if (!dot || dot == fileName) return ""; + return (dot + 1); +} +#endif +*/ \ No newline at end of file diff --git a/release/html5/libraylib.bc b/release/html5/libraylib.bc index 4a7b8fa8..083a3c3d 100644 Binary files a/release/html5/libraylib.bc and b/release/html5/libraylib.bc differ diff --git a/release/html5/raylib.h b/release/html5/raylib.h index d28b07a3..a47d3c59 100644 --- a/release/html5/raylib.h +++ b/release/html5/raylib.h @@ -19,7 +19,7 @@ * Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1 * Custom color palette for fancy visuals on raywhite background * Minimal external dependencies (GLFW3, OpenGL, OpenAL) -* Complete binding for LUA [rlua] +* Complete binding for Lua [rlua] * * External libs: * GLFW3 (www.glfw.org) for window/context management and input [core] @@ -351,7 +351,7 @@ typedef struct Image { int width; // Image base width int height; // Image base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Image; // Texture2D type, bpp always RGBA (32bit) @@ -361,12 +361,12 @@ typedef struct Texture2D { int width; // Texture base width int height; // Texture base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Texture2D; // RenderTexture2D type, for texture rendering typedef struct RenderTexture2D { - unsigned int id; // Render texture (fbo) id + unsigned int id; // OpenGL Framebuffer Object (FBO) id Texture2D texture; // Color buffer attachment texture Texture2D depth; // Depth buffer attachment texture } RenderTexture2D; @@ -491,6 +491,14 @@ typedef struct Ray { Vector3 direction; // Ray direction } Ray; +// Information returned from a raycast +typedef struct RayHitInfo { + bool hit; // Did the ray hit something? + float distance; // Distance to nearest hit + Vector3 hitPosition; // Position of nearest hit + Vector3 hitNormal; // Surface normal of hit +} RayHitInfo; + // Wave type, defines audio wave data typedef struct Wave { unsigned int sampleCount; // Number of samples @@ -549,7 +557,7 @@ typedef enum { // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 2: Filter is accordingly set for minification and magnification -typedef enum { +typedef enum { FILTER_POINT = 0, // No filter, just pixel aproximation FILTER_BILINEAR, // Linear filtering FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) @@ -581,12 +589,12 @@ typedef enum { } Gestures; // Camera system modes -typedef enum { - CAMERA_CUSTOM = 0, - CAMERA_FREE, - CAMERA_ORBITAL, - CAMERA_FIRST_PERSON, - CAMERA_THIRD_PERSON +typedef enum { + CAMERA_CUSTOM = 0, + CAMERA_FREE, + CAMERA_ORBITAL, + CAMERA_FIRST_PERSON, + CAMERA_THIRD_PERSON } CameraMode; // Head Mounted Display devices @@ -602,6 +610,26 @@ typedef enum { HMD_FOVE_VR, } VrDevice; +// rRES data returned when reading a resource, it contains all required data for user (24 byte) +typedef struct { + unsigned int type; // Resource type (4 byte) + + unsigned int param1; // Resouce parameter 1 (4 byte) + unsigned int param2; // Resouce parameter 2 (4 byte) + unsigned int param3; // Resouce parameter 3 (4 byte) + unsigned int param4; // Resouce parameter 4 (4 byte) + + void *data; // Resource data pointer (4 byte) +} RRESData; + +typedef enum { + RRES_RAW = 0, + RRES_IMAGE, + RRES_WAVE, + RRES_VERTEX, + RRES_TEXT +} RRESDataType; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -767,21 +795,19 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve //------------------------------------------------------------------------------------ // Texture Loading and Drawing Functions (Module: textures) //------------------------------------------------------------------------------------ -RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) -RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) -RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file -RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) -RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory -RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory -RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) -RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data -RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering +RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) +RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit) +RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters +RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data +RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) +RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data +RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) -RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory -RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory +RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) +RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image -RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data +RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image @@ -794,7 +820,8 @@ RLAPI Image ImageText(const char *text, int fontSize, Color color); RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) -RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) +RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, + float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint @@ -817,9 +844,9 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest // Font Loading and Text Drawing Functions (Module: text) //------------------------------------------------------------------------------------ RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont -RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory -RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load a SpriteFont from TTF font with parameters -RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory +RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) +RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load SpriteFont from TTF font file with generation parameters +RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters @@ -855,41 +882,52 @@ RLAPI void DrawLight(Light light); //------------------------------------------------------------------------------------ // Model 3d Loading and Drawing Functions (Module: models) //------------------------------------------------------------------------------------ -RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) -RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) -RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource) -RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model -RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) -RLAPI void UnloadModel(Model model); // Unload 3d model from memory - -RLAPI Material LoadMaterial(const char *fileName); // Load material data (.MTL) -RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) -RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) -RLAPI void UnloadMaterial(Material material); // Unload material textures from VRAM - -RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters +RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file +RLAPI Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); // Load mesh from vertex data +RLAPI Model LoadModel(const char *fileName); // Load model from file +RLAPI Model LoadModelFromMesh(Mesh data, bool dynamic); // Load model from mesh data +RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load heightmap model from image data +RLAPI Model LoadCubicmap(Image cubicmap); // Load cubes-based map model from image data +RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM) +RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM) + +RLAPI Material LoadMaterial(const char *fileName); // Load material from file +RLAPI Material LoadMaterialEx(Shader shader, Texture2D diffuse, Color color); // Load material from basic shading data +RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) +RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) +RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) + +RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) +RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) -RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters -RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) - -RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture -RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec - -RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits -RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres -RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes -RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere -RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere -RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection -RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) + +RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture +RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, + Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec + +RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits +RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres +RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes +RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere +RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere +RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, + Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point +RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh +RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle +RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane) //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations -RLAPI void UnloadShader(Shader shader); // Unload a custom shader from memory +RLAPI char *LoadText(const char *fileName); // Load chars array from text file +RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations +RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) RLAPI Shader GetDefaultShader(void); // Get default shader RLAPI Shader GetStandardShader(void); // Get standard shader @@ -929,12 +967,11 @@ RLAPI void InitAudioDevice(void); // Initial RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully -RLAPI Wave LoadWave(const char *fileName); // Load wave data from file into RAM -RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) -RLAPI Sound LoadSound(const char *fileName); // Load sound to memory -RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data -RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) -RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data +RLAPI Wave LoadWave(const char *fileName); // Load wave data from file +RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data +RLAPI Sound LoadSound(const char *fileName); // Load sound from file +RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data +RLAPI void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void PlaySound(Sound sound); // Play a sound @@ -964,7 +1001,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data) -RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int numSamples); // Update audio stream buffers with data RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream diff --git a/release/win32/mingw32/libraylib.a b/release/win32/mingw32/libraylib.a index e0136aed..22d066aa 100644 Binary files a/release/win32/mingw32/libraylib.a and b/release/win32/mingw32/libraylib.a differ diff --git a/release/win32/raylib.h b/release/win32/raylib.h index d28b07a3..a47d3c59 100644 --- a/release/win32/raylib.h +++ b/release/win32/raylib.h @@ -19,7 +19,7 @@ * Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1 * Custom color palette for fancy visuals on raywhite background * Minimal external dependencies (GLFW3, OpenGL, OpenAL) -* Complete binding for LUA [rlua] +* Complete binding for Lua [rlua] * * External libs: * GLFW3 (www.glfw.org) for window/context management and input [core] @@ -351,7 +351,7 @@ typedef struct Image { int width; // Image base width int height; // Image base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Image; // Texture2D type, bpp always RGBA (32bit) @@ -361,12 +361,12 @@ typedef struct Texture2D { int width; // Texture base width int height; // Texture base height int mipmaps; // Mipmap levels, 1 by default - int format; // Data format (TextureFormat) + int format; // Data format (TextureFormat type) } Texture2D; // RenderTexture2D type, for texture rendering typedef struct RenderTexture2D { - unsigned int id; // Render texture (fbo) id + unsigned int id; // OpenGL Framebuffer Object (FBO) id Texture2D texture; // Color buffer attachment texture Texture2D depth; // Depth buffer attachment texture } RenderTexture2D; @@ -491,6 +491,14 @@ typedef struct Ray { Vector3 direction; // Ray direction } Ray; +// Information returned from a raycast +typedef struct RayHitInfo { + bool hit; // Did the ray hit something? + float distance; // Distance to nearest hit + Vector3 hitPosition; // Position of nearest hit + Vector3 hitNormal; // Surface normal of hit +} RayHitInfo; + // Wave type, defines audio wave data typedef struct Wave { unsigned int sampleCount; // Number of samples @@ -549,7 +557,7 @@ typedef enum { // Texture parameters: filter mode // NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 2: Filter is accordingly set for minification and magnification -typedef enum { +typedef enum { FILTER_POINT = 0, // No filter, just pixel aproximation FILTER_BILINEAR, // Linear filtering FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) @@ -581,12 +589,12 @@ typedef enum { } Gestures; // Camera system modes -typedef enum { - CAMERA_CUSTOM = 0, - CAMERA_FREE, - CAMERA_ORBITAL, - CAMERA_FIRST_PERSON, - CAMERA_THIRD_PERSON +typedef enum { + CAMERA_CUSTOM = 0, + CAMERA_FREE, + CAMERA_ORBITAL, + CAMERA_FIRST_PERSON, + CAMERA_THIRD_PERSON } CameraMode; // Head Mounted Display devices @@ -602,6 +610,26 @@ typedef enum { HMD_FOVE_VR, } VrDevice; +// rRES data returned when reading a resource, it contains all required data for user (24 byte) +typedef struct { + unsigned int type; // Resource type (4 byte) + + unsigned int param1; // Resouce parameter 1 (4 byte) + unsigned int param2; // Resouce parameter 2 (4 byte) + unsigned int param3; // Resouce parameter 3 (4 byte) + unsigned int param4; // Resouce parameter 4 (4 byte) + + void *data; // Resource data pointer (4 byte) +} RRESData; + +typedef enum { + RRES_RAW = 0, + RRES_IMAGE, + RRES_WAVE, + RRES_VERTEX, + RRES_TEXT +} RRESDataType; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -767,21 +795,19 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve //------------------------------------------------------------------------------------ // Texture Loading and Drawing Functions (Module: textures) //------------------------------------------------------------------------------------ -RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) -RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) -RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file -RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource) -RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory -RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory -RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource) -RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data -RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering +RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM) +RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit) +RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters +RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image from RAW file data +RLAPI Texture2D LoadTexture(const char *fileName); // Load texture from file into GPU memory (VRAM) +RLAPI Texture2D LoadTextureFromImage(Image image); // Load texture from image data +RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load texture for rendering (framebuffer) RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) -RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory -RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory +RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory (VRAM) +RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory (VRAM) RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image -RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data +RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two) RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image @@ -794,7 +820,8 @@ RLAPI Image ImageText(const char *text, int fontSize, Color color); RLAPI Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint); // Create an image from text (custom sprite font) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination) -RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) +RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, + float fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination) RLAPI void ImageFlipVertical(Image *image); // Flip image vertically RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint @@ -817,9 +844,9 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest // Font Loading and Text Drawing Functions (Module: text) //------------------------------------------------------------------------------------ RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont -RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory -RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load a SpriteFont from TTF font with parameters -RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory +RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM) +RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars); // Load SpriteFont from TTF font file with generation parameters +RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters @@ -855,41 +882,52 @@ RLAPI void DrawLight(Light light); //------------------------------------------------------------------------------------ // Model 3d Loading and Drawing Functions (Module: models) //------------------------------------------------------------------------------------ -RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) -RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) -RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource) -RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model -RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) -RLAPI void UnloadModel(Model model); // Unload 3d model from memory - -RLAPI Material LoadMaterial(const char *fileName); // Load material data (.MTL) -RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) -RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) -RLAPI void UnloadMaterial(Material material); // Unload material textures from VRAM - -RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) -RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters +RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file +RLAPI Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); // Load mesh from vertex data +RLAPI Model LoadModel(const char *fileName); // Load model from file +RLAPI Model LoadModelFromMesh(Mesh data, bool dynamic); // Load model from mesh data +RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load heightmap model from image data +RLAPI Model LoadCubicmap(Image cubicmap); // Load cubes-based map model from image data +RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM) +RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM) + +RLAPI Material LoadMaterial(const char *fileName); // Load material from file +RLAPI Material LoadMaterialEx(Shader shader, Texture2D diffuse, Color color); // Load material from basic shading data +RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader) +RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader) +RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM) + +RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) +RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) -RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters -RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) - -RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture -RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec - -RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits -RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres -RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes -RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere -RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere -RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection -RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, + float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires) + +RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture +RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, + Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec + +RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits +RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres +RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes +RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere +RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere +RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, + Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point +RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box +RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh +RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle +RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane) //------------------------------------------------------------------------------------ // Shaders System Functions (Module: rlgl) // NOTE: This functions are useless when using OpenGL 1.1 //------------------------------------------------------------------------------------ -RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations -RLAPI void UnloadShader(Shader shader); // Unload a custom shader from memory +RLAPI char *LoadText(const char *fileName); // Load chars array from text file +RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations +RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM) RLAPI Shader GetDefaultShader(void); // Get default shader RLAPI Shader GetStandardShader(void); // Get standard shader @@ -929,12 +967,11 @@ RLAPI void InitAudioDevice(void); // Initial RLAPI void CloseAudioDevice(void); // Close the audio device and context RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully -RLAPI Wave LoadWave(const char *fileName); // Load wave data from file into RAM -RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) -RLAPI Sound LoadSound(const char *fileName); // Load sound to memory -RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data -RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) -RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data +RLAPI Wave LoadWave(const char *fileName); // Load wave data from file +RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data +RLAPI Sound LoadSound(const char *fileName); // Load sound from file +RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data +RLAPI void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void PlaySound(Sound sound); // Play a sound @@ -964,7 +1001,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Init audio stream (to stream raw audio pcm data) -RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data +RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int numSamples); // Update audio stream buffers with data RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory RLAPI bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream diff --git a/src/audio.c b/src/audio.c index 74a54b04..3b463df3 100644 --- a/src/audio.c +++ b/src/audio.c @@ -839,7 +839,13 @@ void SetMusicPitch(Music music, float pitch) { alSourcef(music->stream.source, AL_PITCH, pitch); } - +/* +// Set music speed +void SetMusicSpeed(Music music, float pitch) +{ + alSourcef(music->stream.source, AL_PITCH, 0.5f); +} +*/ // Get music time length (in seconds) float GetMusicTimeLength(Music music) { diff --git a/src/rlgl.h b/src/rlgl.h index b7c9df00..9cee39cc 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -97,7 +97,7 @@ // NOTE: This is the maximum amount of lines, triangles and quads per frame, be careful! #define MAX_LINES_BATCH 8192 #define MAX_TRIANGLES_BATCH 4096 - #define MAX_QUADS_BATCH 4096 + #define MAX_QUADS_BATCH 8192 #elif defined(GRAPHICS_API_OPENGL_ES2) // NOTE: Reduce memory sizes for embedded systems (RPI and HTML5) // NOTE: On HTML5 (emscripten) this is allocated on heap, by default it's only 16MB!...just take care... -- cgit v1.2.3