Преглед на файлове

Fix shader compile errors with Mesa

Error was "error: sampler arrays indexed with non-constant
expressions are forbidden in GLSL 1.30 and later". Fix by
unrolling the loops in Go templating.

Fixes g3n/engine#2.
Jeff Allen преди 8 години
родител
ревизия
3da4ea47ee

+ 32 - 34
renderer/shader/chunkPhongModel.go

@@ -36,84 +36,82 @@ void phongModel(vec4 position, vec3 normal, vec3 camDir, vec3 matAmbient, vec3 m
     vec3 diffuseTotal  = vec3(0.0);
     vec3 specularTotal = vec3(0.0);
 
-    {{if .AmbientLightsMax }}
-    for (int i = 0; i < {{.AmbientLightsMax}}; i++) {
-        ambientTotal += AmbientLightColor[i] * matAmbient;
-    }
+    {{ range loop .AmbientLightsMax }}
+        ambientTotal += AmbientLightColor[{{.}}] * matAmbient;
     {{ end }}
 
-    {{if .DirLightsMax }}
-    for (int i = 0; i < {{.DirLightsMax}}; i++) {
+    {{ range loop .DirLightsMax }}
+    {
         // Diffuse reflection
         // DirLightPosition is the direction of the current light
-        vec3 lightDirection = normalize(DirLightPosition[i]);
+        vec3 lightDirection = normalize(DirLightPosition[{{.}}]);
         // Calculates the dot product between the light direction and this vertex normal.
         float dotNormal = max(dot(lightDirection, normal), 0.0);
-        diffuseTotal += DirLightColor[i] * matDiffuse * dotNormal;
+        diffuseTotal += DirLightColor[{{.}}] * matDiffuse * dotNormal;
 
         // Specular reflection
         // Calculates the light reflection vector 
         vec3 ref = reflect(-lightDirection, normal);
         if (dotNormal > 0.0) {
-            specularTotal += DirLightColor[i] * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess);
+            specularTotal += DirLightColor[{{.}}] * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess);
         }
     }
     {{ end }}
 
-    {{if .PointLightsMax }}
-    for (int i = 0; i < {{.PointLightsMax}}; i++) {
+    {{ range loop .PointLightsMax }}
+    {
         // Calculates the direction and distance from the current vertex to this point light.
-        vec3 lightDirection = PointLightPosition[i] - vec3(position);
+        vec3 lightDirection = PointLightPosition[{{.}}] - vec3(position);
         float lightDistance = length(lightDirection);
         // Normalizes the lightDirection
         lightDirection = lightDirection / lightDistance;
         // Calculates the attenuation due to the distance of the light
-        float attenuation = 1.0 / (1.0 + PointLightLinearDecay[i] * lightDistance +
-            PointLightQuadraticDecay[i] * lightDistance * lightDistance);
+        float attenuation = 1.0 / (1.0 + PointLightLinearDecay[{{.}}] * lightDistance +
+            PointLightQuadraticDecay[{{.}}] * lightDistance * lightDistance);
 
         // Diffuse reflection
         float dotNormal = max(dot(lightDirection, normal), 0.0);
-        diffuseTotal += PointLightColor[i] * matDiffuse * dotNormal * attenuation;
+        diffuseTotal += PointLightColor[{{.}}] * matDiffuse * dotNormal * attenuation;
         
         // Specular reflection
         // Calculates the light reflection vector 
         vec3 ref = reflect(-lightDirection, normal);
         if (dotNormal > 0.0) {
-            specularTotal += PointLightColor[i] * MatSpecularColor *
+            specularTotal += PointLightColor[{{.}}] * MatSpecularColor *
                 pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation;
         }
     }
     {{ end }}
 
-    {{if .SpotLightsMax }}
-    for (int i = 0; i < {{.SpotLightsMax}}; i++) {
+    {{ range loop .SpotLightsMax }}
+    {
         // Calculates the direction and distance from the current vertex to this spot light.
-        vec3 lightDirection = SpotLightPosition[i] - vec3(position);
+        vec3 lightDirection = SpotLightPosition[{{.}}] - vec3(position);
         float lightDistance = length(lightDirection);
         lightDirection = lightDirection / lightDistance;
 
         // Calculates the attenuation due to the distance of the light
-        float attenuation = 1.0 / (1.0 + SpotLightLinearDecay[i] * lightDistance +
-            SpotLightQuadraticDecay[i] * lightDistance * lightDistance);
+        float attenuation = 1.0 / (1.0 + SpotLightLinearDecay[{{.}}] * lightDistance +
+            SpotLightQuadraticDecay[{{.}}] * lightDistance * lightDistance);
 
         // Calculates the angle between the vertex direction and spot direction
         // If this angle is greater than the cutoff the spotlight will not contribute
         // to the final color.
-        float angle = acos(dot(-lightDirection, SpotLightDirection[i]));
-        float cutoff = radians(clamp(SpotLightCutoffAngle[i], 0.0, 90.0));
-        if (angle >= cutoff) {
-            continue;
-        }
-        float spotFactor = pow(dot(-lightDirection, SpotLightDirection[i]), SpotLightAngularDecay[i]);
+        float angle = acos(dot(-lightDirection, SpotLightDirection[{{.}}]));
+        float cutoff = radians(clamp(SpotLightCutoffAngle[{{.}}], 0.0, 90.0));
 
-        // Diffuse reflection
-        float dotNormal = max(dot(lightDirection, normal), 0.0);
-        diffuseTotal += SpotLightColor[i] * matDiffuse * dotNormal * attenuation * spotFactor;
+        if (angle < cutoff) {
+            float spotFactor = pow(dot(-lightDirection, SpotLightDirection[{{.}}]), SpotLightAngularDecay[{{.}}]);
 
-        // Specular reflection
-        vec3 ref = reflect(-lightDirection, normal);
-        if (dotNormal > 0.0) {
-            specularTotal += SpotLightColor[i] * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation * spotFactor;
+            // Diffuse reflection
+            float dotNormal = max(dot(lightDirection, normal), 0.0);
+            diffuseTotal += SpotLightColor[{{.}}] * matDiffuse * dotNormal * attenuation * spotFactor;
+
+            // Specular reflection
+            vec3 ref = reflect(-lightDirection, normal);
+            if (dotNormal > 0.0) {
+                specularTotal += SpotLightColor[{{.}}] * MatSpecularColor * pow(max(dot(ref, camDir), 0.0), MatShininess) * attenuation * spotFactor;
+            }
         }
     }
     {{ end }}

+ 4 - 7
renderer/shader/shaderPhong.go

@@ -79,13 +79,10 @@ void main() {
 
     // Combine all texture colors
     vec4 texCombined = vec4(1);
-    {{if .MatTexturesMax }}
-    for (int i = 0; i < {{.MatTexturesMax}}; i++) {
-        if (MatTexVisible[i] == false) {
-            continue;
-        }
-        vec4 texcolor = texture(MatTexture[i], FragTexcoord * MatTexRepeat[i] + MatTexOffset[i]);
-        if (i == 0) {
+    {{ range loop .MatTexturesMax }}
+    if (MatTexVisible[{{.}}] == true) {
+        vec4 texcolor = texture(MatTexture[{{.}}], FragTexcoord * MatTexRepeat[{{.}}] + MatTexOffset[{{.}}]);
+        if ({{.}} == 0) {
             texCombined = texcolor;
         } else {
             texCombined = mix(texCombined, texcolor, texcolor.a);

+ 4 - 4
renderer/shader/shaderPoint.go

@@ -70,11 +70,11 @@ void main() {
 
     // Combine all texture colors and opacity
     vec4 texCombined = vec4(1);
-    {{if .MatTexturesMax}}
-    for (int i = 0; i < {{.MatTexturesMax}}; i++) {
+    {{ range loop .MatTexturesMax }}
+    {
         vec2 pt = gl_PointCoord - vec2(0.5);
-        vec4 texcolor = texture(MatTexture[i], (Rotation * pt + vec2(0.5)) * MatTexRepeat[i] + MatTexOffset[i]);
-        if (i == 0) {
+        vec4 texcolor = texture(MatTexture[{{.}}], (Rotation * pt + vec2(0.5)) * MatTexRepeat[{{.}}] + MatTexOffset[{{.}}]);
+        if ({{.}} == 0) {
             texCombined = texcolor;
         } else {
             texCombined = mix(texCombined, texcolor, texcolor.a);

+ 4 - 4
renderer/shader/shaderSprite.go

@@ -56,10 +56,10 @@ void main() {
 
     // Combine all texture colors and opacity
     vec4 texCombined = vec4(1);
-    {{if .MatTexturesMax }}
-    for (int i = 0; i < {{.MatTexturesMax}}; i++) {
-        vec4 texcolor = texture(MatTexture[i], FragTexcoord * MatTexRepeat[i] + MatTexOffset[i]);
-        if (i == 0) {
+    {{ range loop .MatTexturesMax }}
+    {
+        vec4 texcolor = texture(MatTexture[{{.}}], FragTexcoord * MatTexRepeat[{{.}}] + MatTexOffset[{{.}}]);
+        if ({{.}} == 0) {
             texCombined = texcolor;
         } else {
             texCombined = mix(texCombined, texcolor, texcolor.a);

+ 7 - 7
renderer/shader/shaderStandard.go

@@ -87,14 +87,14 @@ out vec4 FragColor;
 void main() {
 
     vec4 texCombined = vec4(1);
-    {{if .MatTexturesMax }}
+
     // Combine all texture colors and opacity
-    for (int i = 0; i < {{.MatTexturesMax}}; i++) {
-        if (MatTexVisible[i] == false) {
-            continue;
-        }
-        vec4 texcolor = texture(MatTexture[i], FragTexcoord * MatTexRepeat[i] + MatTexOffset[i]);
-        if (i == 0) {
+    // Use Go templates to unroll the loop because non-const
+    // array indexes are not allowed until GLSL 4.00.
+    {{ range loop .MatTexturesMax }}
+    if (MatTexVisible[{{.}}] == true) {
+        vec4 texcolor = texture(MatTexture[{{.}}], FragTexcoord * MatTexRepeat[{{.}}] + MatTexOffset[{{.}}]);
+        if ({{.}} == 0) {
             texCombined = texcolor;
         } else {
             texCombined = mix(texCombined, texcolor, texcolor.a);

+ 4 - 4
renderer/shader/shaderTiles.go

@@ -87,11 +87,11 @@ void main() {
     vec4 texCombined = texture(MatTexture[0], FragTexcoord * repeat + offset);
 
 //    vec4 texCombined = vec4(1);
-//    {{ if .MatTexturesMax }}
+//    {{ range loop .MatTexturesMax }}
 //    // Combine all texture colors and opacity
-//    for (int i = 0; i < {{.MatTexturesMax}}; i++) {
-//        vec4 texcolor = texture(MatTexture[i], FragTexcoord * MatTexRepeat[i] + MatTexOffset[i]);
-//        if (i == 0) {
+//    {
+//        vec4 texcolor = texture(MatTexture[{{.}}], FragTexcoord * MatTexRepeat[{{.}}] + MatTexOffset[{{.}}]);
+//        if ({{.}} == 0) {
 //            texCombined = texcolor;
 //        } else {
 //            texCombined = mix(texCombined, texcolor, texcolor.a);

+ 12 - 1
renderer/shaman.go

@@ -7,10 +7,11 @@ package renderer
 import (
 	"bytes"
 	"fmt"
+	"text/template"
+
 	"github.com/g3n/engine/gls"
 	"github.com/g3n/engine/material"
 	"github.com/g3n/engine/renderer/shader"
-	"text/template"
 )
 
 type ShaderSpecs struct {
@@ -83,6 +84,15 @@ func (sm *Shaman) AddChunk(name, source string) error {
 	if err != nil {
 		return err
 	}
+	tmpl.Funcs(template.FuncMap{
+		"loop": func(n int) []int {
+			s := make([]int, n)
+			for i := range s {
+				s[i] = i
+			}
+			return s
+		},
+	})
 	return nil
 }
 
@@ -99,6 +109,7 @@ func (sm *Shaman) AddShader(name, source string) error {
 	if err != nil {
 		return err
 	}
+
 	sm.shaders[name] = tmpl
 	return nil
 }