Reputation: 979
I'm having a problem building this on my raspberry. This same shader code works on several other computers, even if I force usage of OpenGL ES, and force the GLSL version to 1.0 es.
The #version string is added programatically to each of the shaders.
Vertex shader:
#version 100
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
#if (__VERSION__ > 120)
#define IN in
#define OUT out
#else
#define IN attribute
#define OUT varying
#endif // __VERSION
#define MAX_LIGHTS 8
struct SLight
{
vec3 Position;
vec3 DiffuseColor;
float Intensity;
float ConstantAttenuation;
float LinearAttenuation;
float ExponentialAttenuation;
float CutoffDistance;
float CutoffIntensity;
};
struct SMaterial
{
vec3 Specular, Diffuse, Ambient;
float Shininess;
};
uniform SLight Lights[MAX_LIGHTS];
uniform int LightCount;
uniform SMaterial Material;
struct SAmbientLight
{
vec3 Color;
float Intensity;
};
uniform mat4 ModelMatrix, ViewMatrix, MVPMatrix;
uniform SAmbientLight AmbientLight;
IN vec3 VertexPosition, VertexNormal;
IN vec2 VertexTexCoord;
IN vec4 VertexColor;
OUT vec2 PerVertex_TexCoord;
OUT vec4 PerVertex_Color;
OUT vec3 PerVertex_ViewSpaceNormal, PerVertex_ViewVector;
OUT vec4 PerVertex_LightVectors[MAX_LIGHTS];
uniform bool ColoringEnabled, TexturingEnabled, LightingEnabled;
vec4 ViewSpaceLightPositions[MAX_LIGHTS];
void main()
{
mat4 ObjectToViewMatrix = ViewMatrix * ModelMatrix;
vec4 ViewSpaceCoordinate = ObjectToViewMatrix * vec4 ( VertexPosition, 1.0f );
// Calculate normal in view-space
PerVertex_ViewSpaceNormal = mat3 ( ObjectToViewMatrix ) * VertexNormal;
// Calculate light position in view-space
for ( int cont = 0; cont < LightCount; ++cont )
ViewSpaceLightPositions[cont] = ( ViewMatrix * vec4 ( Lights[cont].Position, 1.0f ) );
// Calculate vectors from the lights to this vertex
for ( int cont = 0; cont < LightCount; ++cont )
PerVertex_LightVectors[cont] = ViewSpaceLightPositions[cont] - ViewSpaceCoordinate;
// Calculate view vector
PerVertex_ViewVector = -ViewSpaceCoordinate.xyz;
gl_Position = MVPMatrix * vec4 ( VertexPosition, 1.0f );
PerVertex_TexCoord = VertexTexCoord;
if ( ColoringEnabled )
PerVertex_Color = VertexColor;
}
fragment shader:
#version 100
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
#if (__VERSION__ > 120)
#define IN in
#else
#define IN varying
#endif // __VERSION __
#if ( __VERSION__ > 330 )
#define texture2D texture
#endif
#if ( __VERSION__ >= 300 )
#define FRAG_OUTPUT FragOutput
out vec4 FragOutput;
#else
#define FRAG_OUTPUT gl_FragColor
#endif
#define MAX_LIGHTS 8
struct SLight
{
vec3 Position;
vec3 DiffuseColor;
float Intensity;
float ConstantAttenuation;
float LinearAttenuation;
float ExponentialAttenuation;
float CutoffDistance;
float CutoffIntensity;
};
struct SMaterial
{
vec3 Specular, Diffuse, Ambient;
float Shininess;
};
uniform SLight Lights[MAX_LIGHTS];
uniform int LightCount;
uniform SMaterial Material;
struct SAmbientLight
{
vec3 Color;
float Intensity;
};
uniform mat4 ModelMatrix, ViewMatrix, MVPMatrix;
uniform SAmbientLight AmbientLight;
IN vec2 PerVertex_TexCoord;
IN vec4 PerVertex_Color;
IN vec3 PerVertex_ViewSpaceNormal, PerVertex_ViewVector;
IN vec4 PerVertex_LightVectors[MAX_LIGHTS];
uniform bool ColoringEnabled, TexturingEnabled, LightingEnabled;
uniform sampler2D TextureSampler;
vec4 CalculateLights ( void )
{
vec4 LightResult;
LightResult = vec4 ( 0.0f, 0.0f, 0.0f, 1.0f );
vec3 N = normalize ( PerVertex_ViewSpaceNormal );
vec3 V = normalize ( PerVertex_ViewVector );
for ( int cont = 0; cont < LightCount; ++cont )
{
float Distance = length ( PerVertex_LightVectors[cont] );
if ( Distance > Lights[cont].CutoffDistance )
continue;
// Normalize the incoming N, L and V vectors
vec3 L = normalize ( PerVertex_LightVectors[cont] ).xyz;
vec3 H = normalize ( L + V );
// Compute the diffuse and specular components for each fragment
vec3 diffuse = max ( dot ( N, L ), 0.0f ) * Material.Diffuse * Lights[cont].DiffuseColor /** Lights[cont].Intensity*/;
vec3 specular = pow ( max ( dot ( N, H ), 0.0f ), Material.Shininess ) * Material.Specular;
// Compute attenuation
float Attenuation = Lights[cont].ConstantAttenuation + Lights[cont].LinearAttenuation * Distance + Lights[cont].ExponentialAttenuation * pow ( Distance, 2.0f );
// Final color contribution from this light
vec3 LightContribution = vec3 ( diffuse + specular ) / Attenuation;
if ( length ( LightContribution ) < Lights[cont].CutoffIntensity )
continue;
LightResult += vec4 ( LightContribution, 1.0f );
// LightResult += vec4 ( diffuse + specular, 1.0f );
}
LightResult += vec4 ( AmbientLight.Color * AmbientLight.Intensity * Material.Ambient, 1.0f );
return LightResult;
}
void main()
{
vec4 FragmentOriginalColor;
if ( TexturingEnabled )
FragmentOriginalColor = texture2D ( TextureSampler, PerVertex_TexCoord );
else if ( ColoringEnabled )
FragmentOriginalColor = PerVertex_Color;
else
FragmentOriginalColor = vec4 ( Material.Diffuse, 1.0f );
if ( LightingEnabled )
FragmentOriginalColor *= CalculateLights();
if ( FragmentOriginalColor.a == 0.0 )
discard;
FRAG_OUTPUT = FragmentOriginalColor;
}
This is the output from my app:
DEBUG: Video driver 1: RPI
DEBUG: Video driver 2: dummy
DEBUG: Current video driver: RPI
INFO: Initializing OpenGLES2
INFO: Initializing OpenGLES2
DEBUG: Reported GL version string : OpenGL ES 2.0
DEBUG: Reported GLSL version string : OpenGL ES GLSL ES 1.00
DEBUG: Parsed GLSL version 1.0 es
glGetError 0x500
glGetError 0x500
DEBUG: OpenGL version 2.0 es
DEBUG: GLSL version 1.0 es
DEBUG: Created window 0x160a960
DEBUG: GL program info log length 9
DEBUG: vertex shader ID 1 successfully compiled
DEBUG: GL program info log length 9
DEBUG: fragment shader ID 2 successfully compiled
DEBUG: Created shader program 3
DEBUG: GL program info log length 56
ERROR: Shader program 3 link error. ERROR:LEX/PARSE-1 (vertex shader, line 61) Syntax error
Line 61 appears to be the first line inside main, where the two matrices are multiplied. What am I doing wrong?
Upvotes: 2
Views: 1237
Reputation: 1773
I tried to compile the vertex shader for GLES with PVRShaderEditor (from the Power VR SDK, usefull tool to check for GLES related errors, it allows compiling shader like if you were on an iPhone).
It reports three errors:
ERROR: 0:62: 'f' : suffix for floats requires language version 300
ERROR: 0:69: 'f' : suffix for floats requires language version 300
ERROR: 0:78: 'f' : suffix for floats requires language version 300
So you just need to replace all 1.0f
with 1.0
in vertex AND fragment shaders and the problem should be solved, seems like the f suffix is not supported in GLES2.0.
Note that it seems there is a bug on Pi which causes compilation errors to be shown at program linking time while they should be shown at shader compilation time... No idea why the error message you get is not more detailled ...
Upvotes: 1