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