From aaf85451c41d1419c62d16b568cf334d9f6cc76d Mon Sep 17 00:00:00 2001 From: David Thompson Date: Mon, 24 Aug 2020 16:11:27 -0400 Subject: render: Add shader compatibility for GLSL 3.3. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Big thanks to Aleix Conchillo FlaquƩ for working out the necessary changes while testing Chickadee on MacOS. --- chickadee/render/particles.scm | 26 ++++++++++++++++-------- chickadee/render/pbr.scm | 15 ++++++++++---- chickadee/render/phong.scm | 30 +++++++++++++++++++++++---- chickadee/render/shader.scm | 20 +++++++++++++++++- chickadee/render/shapes.scm | 46 +++++++++++++++++++++++++++++------------- chickadee/render/sprite.scm | 32 ++++++++++++++++++++++------- 6 files changed, 131 insertions(+), 38 deletions(-) diff --git a/chickadee/render/particles.scm b/chickadee/render/particles.scm index d8778da..d046caf 100644 --- a/chickadee/render/particles.scm +++ b/chickadee/render/particles.scm @@ -116,13 +116,18 @@ indefinitely." (define (make-particles-shader) (strings->shader " -#version 130 - +#ifdef GLSL330 +layout (location = 0) in vec2 position; +layout (location = 1) in vec2 tex; +layout (location = 2) in vec2 offset; +layout (location = 3) in float life; +#elif ifdef GLSL130 in vec2 position; in vec2 tex; in vec2 offset; in float life; -out vec2 frag_tex; +#endif +out vec2 fragTex; out float t; uniform mat4 mvp; uniform int lifetime; @@ -137,21 +142,26 @@ void main(void) { float ty = float(tile / animationColumns) / animationRows; float tw = 1.0 / animationColumns; float th = 1.0 / animationRows; - frag_tex = vec2(tx, ty) + tex * vec2(tw, th); + fragTex = vec2(tx, ty) + tex * vec2(tw, th); gl_Position = mvp * vec4(position.xy + offset, 0.0, 1.0); } " " -#version 130 - -in vec2 frag_tex; +in vec2 fragTex; in float t; +#ifdef GLSL330 +out vec4 fragColor; +#endif uniform sampler2D color_texture; uniform vec4 startColor; uniform vec4 endColor; void main (void) { - gl_FragColor = mix(endColor, startColor, t) * texture2D(color_texture, frag_tex); +#ifdef GLSL330 + fragColor = mix(endColor, startColor, t) * texture(color_texture, fragTex); +#elif ifdef GLSL130 + gl_FragColor = mix(endColor, startColor, t) * texture2D(color_texture, fragTex); +#endif } ")) diff --git a/chickadee/render/pbr.scm b/chickadee/render/pbr.scm index 2738b77..ab02659 100644 --- a/chickadee/render/pbr.scm +++ b/chickadee/render/pbr.scm @@ -91,10 +91,13 @@ (delay (strings->shader " -#version 130 - +#ifdef GLSL330 +layout (location = 0) in vec3 position; +layout (location = 1) in vec2 texcoord0; +#elif ifdef GLSL130 in vec3 position; in vec2 texcoord0; +#endif out vec2 fragTex; uniform mat4 model; uniform mat4 view; @@ -106,15 +109,19 @@ void main(void) { } " " -#version 130 - in vec2 fragTex; +out vec4 fragColor; uniform vec3 baseColorFactor; uniform sampler2D baseColorTexture; void main (void) { +#ifdef GLSL330 + fragColor = texture(baseColorTexture, fragTex) * + vec4(baseColorFactor, 1.0); +#elif ifdef GLSL130 gl_FragColor = texture2D(baseColorTexture, fragTex) * vec4(baseColorFactor, 1.0); +#endif } "))) diff --git a/chickadee/render/phong.scm b/chickadee/render/phong.scm index 0f2a938..08bd7c7 100644 --- a/chickadee/render/phong.scm +++ b/chickadee/render/phong.scm @@ -114,11 +114,15 @@ (delay (strings->shader " -#version 130 - +#ifdef GLSL330 +layout (location = 0) in vec3 position; +layout (location = 1) in vec2 texcoord; +layout (location = 2) in vec3 normal; +#elif ifdef GLSL130 in vec3 position; in vec2 texcoord; in vec3 normal; +#endif uniform mat4 model; uniform mat4 view; @@ -135,8 +139,6 @@ void main() { } " " -#version 130 - struct Material { vec3 ambient; sampler2D ambientMap; @@ -162,6 +164,10 @@ struct DirectionalLight { in vec3 fragNorm; in vec2 fragTex; +#ifdef GLSL330 +out vec4 fragColor; +#endif + uniform Material material; uniform DirectionalLight directionalLight; @@ -170,20 +176,32 @@ void main() { vec3 baseDiffuseColor; vec3 baseSpecularColor; if(material.useAmbientMap) { +#ifdef GLSL330 + baseAmbientColor = texture(material.ambientMap, fragTex).xyz; +#elif ifdef GLSL130 baseAmbientColor = texture2D(material.ambientMap, fragTex).xyz; +#endif } else { baseAmbientColor = vec3(1.0, 1.0, 1.0); } if(material.useDiffuseMap) { // discard transparent fragments. +#ifdef GLSL330 + vec4 color = texture(material.diffuseMap, fragTex); +#elif ifdef GLSL130 vec4 color = texture2D(material.diffuseMap, fragTex); +#endif if(color.a == 0.0) { discard; } baseDiffuseColor = color.xyz; } else { baseDiffuseColor = vec3(1.0, 1.0, 1.0); } if(material.useSpecularMap) { +#ifdef GLSL330 + baseSpecularColor = texture(material.specularMap, fragTex).xyz; +#elif ifdef GLSL130 baseSpecularColor = texture2D(material.specularMap, fragTex).xyz; +#endif } else { baseSpecularColor = vec3(1.0, 1.0, 1.0); } @@ -197,7 +215,11 @@ void main() { specularFactor = pow(max(dot(lightDir, reflectDir), 0.0), material.shininess); } vec3 specularColor = specularFactor * baseSpecularColor * material.specular; +#ifdef GLSL330 + fragColor = vec4(ambientColor + diffuseColor + specularColor, 1.0); +#elif ifdef GLSL130 gl_FragColor = vec4(ambientColor + diffuseColor + specularColor, 1.0); +#endif } "))) diff --git a/chickadee/render/shader.scm b/chickadee/render/shader.scm index baf0302..d393ef0 100644 --- a/chickadee/render/shader.scm +++ b/chickadee/render/shader.scm @@ -505,9 +505,27 @@ them into a GPU shader program." (info-log gl-get-shaderiv gl-get-shader-info-log id)) (define (linking-error id) (info-log gl-get-programiv gl-get-program-info-log id)) + (define (glsl-preprocessor-source) + ;; Set up preprocessor directives dynamically based on the current + ;; OpenGL context's GLSL version so that we can write shaders that + ;; are compatible with as many systems as possible. + (let ((glsl-version (gpu-glsl-version (current-gpu)))) + (cond + ((string>= glsl-version "3.3") + "#version 330 +#define GLSL330 +") + ((string>= glsl-version "1.3") + "#version 130 +#define GLSL130 +") + (else + (error "incompatible GLSL version" glsl-version))))) (define (make-shader-stage type port) (let ((id (gl-create-shader type)) - (source (get-bytevector-all port))) + (source (string->utf8 + (string-append (glsl-preprocessor-source) + (get-string-all port))))) (gl-shader-source id 1 (bytevector->pointer (u64vector diff --git a/chickadee/render/shapes.scm b/chickadee/render/shapes.scm index f7412e8..245bc51 100644 --- a/chickadee/render/shapes.scm +++ b/chickadee/render/shapes.scm @@ -58,9 +58,11 @@ (delay (strings->shader " -#version 130 - +#ifdef GLSL330 +layout (location = 0) in vec2 position; +#elif GLSL130 in vec2 position; +#endif uniform mat4 mvp; void main(void) { @@ -68,13 +70,17 @@ void main(void) { } " " -#version 130 - -in vec2 frag_tex; +#ifdef GLSL330 +out vec4 fragColor; +#endif uniform vec4 color; void main (void) { +#ifdef GLSL330 + fragColor = color; +#elif ifdef GLSL130 gl_FragColor = color; +#endif } "))) (mvp (make-null-matrix4))) @@ -133,22 +139,26 @@ void main (void) { (delay (strings->shader " -#version 130 - +#ifdef GLSL330 +layout (location = 0) in vec2 position; +layout (location = 1) in vec2 tex; +#elif ifdef GLSL130 in vec2 position; in vec2 tex; -out vec2 frag_tex; +#endif +out vec2 fragTex; uniform mat4 mvp; void main(void) { - frag_tex = tex; + fragTex = tex; gl_Position = mvp * vec4(position.xy, 0.0, 1.0); } " " -#version 130 - -in vec2 frag_tex; +in vec2 fragTex; +#ifdef GLSL330 +out vec4 fragColor; +#endif uniform vec4 color; uniform float r; uniform float w; @@ -159,8 +169,8 @@ float infinity = 1.0 / 0.0; void main (void) { float hw = w / 2.0; - float u = frag_tex.x; - float v = frag_tex.y; + float u = fragTex.x; + float v = fragTex.y; float dx; float dy; float d; @@ -204,9 +214,17 @@ void main (void) { } if (d <= hw) { +#ifdef GLSL330 + fragColor = color; +#elif ifdef GLSL130 gl_FragColor = color; +#endif } else { +#ifdef GLSL330 + fragColor = vec4(color.rgb, color.a * (1.0 - ((d - hw) / r))); +#elif ifdef GLSL130 gl_FragColor = vec4(color.rgb, color.a * (1.0 - ((d - hw) / r))); +#endif } } ")))) diff --git a/chickadee/render/sprite.scm b/chickadee/render/sprite.scm index b6a8232..c3b7efc 100644 --- a/chickadee/render/sprite.scm +++ b/chickadee/render/sprite.scm @@ -49,10 +49,13 @@ (delay (strings->shader " -#version 130 - +#ifdef GLSL330 +layout (location = 0) in vec2 position; +layout (location = 1) in vec2 tex; +#elif ifdef GLSL130 in vec2 position; in vec2 tex; +#endif out vec2 fragTex; uniform mat4 mvp; @@ -62,14 +65,20 @@ void main(void) { } " " -#version 130 in vec2 fragTex; +#ifdef GLSL330 +out vec4 fragColor; +#endif uniform sampler2D colorTexture; uniform vec4 tint; void main (void) { +#ifdef GLSL330 + fragColor = texture2D(colorTexture, fragTex) * tint; +#elif ifdef GLSL130 gl_FragColor = texture2D(colorTexture, fragTex) * tint; +#endif } "))) @@ -380,11 +389,15 @@ may be specified via the TEXTURE-REGION argument." (delay (strings->shader " -#version 130 - +#ifdef GLSL330 +layout (location = 0) in vec2 position; +layout (location = 1) in vec2 tex; +layout (location = 2) in vec4 tint; +#elif ifdef GLSL130 in vec2 position; in vec2 tex; in vec4 tint; +#endif out vec2 fragTex; out vec4 fragTint; uniform mat4 mvp; @@ -396,14 +409,19 @@ void main(void) { } " " -#version 130 - in vec2 fragTex; in vec4 fragTint; +#ifdef GLSL330 +out vec4 fragColor; +#endif uniform sampler2D colorTexture; void main (void) { +#ifdef GLSL330 + fragColor = texture(colorTexture, fragTex) * fragTint; +#elif ifdef GLSL130 gl_FragColor = texture2D(colorTexture, fragTex) * fragTint; +#endif } "))) -- cgit v1.2.3