Вот шейдер из примера программы, с которой я работаю:
static const char* pFS = " \n\
#version 330 \n\
\n\
const int MAX_POINT_LIGHTS = 2; \n\
const int MAX_SPOT_LIGHTS = 2; \n\
\n\
in vec4 LightSpacePos; \n\
in vec2 TexCoord0; \n\
in vec3 Normal0; \n\
in vec3 WorldPos0; \n\
in vec3 Tangent0; \n\
\n\
out vec4 FragColor; \n\
\n\
struct BaseLight \n\
{ \n\
vec3 Color; \n\
float AmbientIntensity; \n\
float DiffuseIntensity; \n\
}; \n\
\n\
struct DirectionalLight \n\
{ \n\
struct BaseLight Base; \n\
vec3 Direction; \n\
}; \n\
\n\
struct Attenuation \n\
{ \n\
float Constant; \n\
float Linear; \n\
float Exp; \n\
}; \n\
\n\
struct PointLight \n\
{ \n\
struct BaseLight Base; \n\
vec3 Position; \n\
Attenuation Atten; \n\
}; \n\
\n\
struct SpotLight \n\
{ \n\
struct PointLight Base; \n\
vec3 Direction; \n\
float Cutoff; \n\
}; \n\
\n\
uniform int gNumPointLights; \n\
uniform int gNumSpotLights; \n\
uniform DirectionalLight gDirectionalLight; \n\
uniform PointLight gPointLights[MAX_POINT_LIGHTS]; \n\
uniform SpotLight gSpotLights[MAX_SPOT_LIGHTS]; \n\
uniform sampler2D gColorMap; \n\
uniform sampler2D gShadowMap; \n\
uniform sampler2D gNormalMap; \n\
uniform vec3 gEyeWorldPos; \n\
uniform float gMatSpecularIntensity; \n\
uniform float gSpecularPower; \n\
\n\
float CalcShadowFactor(vec4 LightSpacePos) \n\
{ \n\
vec3 ProjCoords = LightSpacePos.xyz / LightSpacePos.w; \n\
vec2 UVCoords; \n\
UVCoords.x = 0.5 * ProjCoords.x + 0.5; \n\
UVCoords.y = 0.5 * ProjCoords.y + 0.5; \n\
float Depth = texture(gShadowMap, UVCoords).x; \n\
if (Depth <= (ProjCoords.z + 0.005)) \n\
return 0.5; \n\
else \n\
return 1.0; \n\
} \n\
\n\
vec4 CalcLightInternal(struct BaseLight Light, vec3 LightDirection, vec3 Normal, \n\
float ShadowFactor) \n\
{ \n\
vec4 AmbientColor = vec4(Light.Color, 1.0f) * Light.AmbientIntensity; \n\
float DiffuseFactor = dot(Normal, -LightDirection); \n\
\n\
vec4 DiffuseColor = vec4(0, 0, 0, 0); \n\
vec4 SpecularColor = vec4(0, 0, 0, 0); \n\
\n\
if (DiffuseFactor > 0) { \n\
DiffuseColor = vec4(Light.Color, 1.0f) * Light.DiffuseIntensity * DiffuseFactor; \n\
\n\
vec3 VertexToEye = normalize(gEyeWorldPos - WorldPos0); \n\
vec3 LightReflect = normalize(reflect(LightDirection, Normal)); \n\
float SpecularFactor = dot(VertexToEye, LightReflect); \n\
SpecularFactor = pow(SpecularFactor, gSpecularPower); \n\
if (SpecularFactor > 0) { \n\
SpecularColor = vec4(Light.Color, 1.0f) * \n\
gMatSpecularIntensity * SpecularFactor; \n\
} \n\
} \n\
\n\
return (AmbientColor + ShadowFactor * (DiffuseColor + SpecularColor)); \n\
} \n\
\n\
vec4 CalcDirectionalLight(vec3 Normal) \n\
{ \n\
return CalcLightInternal(gDirectionalLight.Base, gDirectionalLight.Direction, Normal, 1.0); \n\
} \n\
\n\
vec4 CalcPointLight(struct PointLight l, vec3 Normal, vec4 LightSpacePos) \n\
{ \n\
vec3 LightDirection = WorldPos0 - l.Position; \n\
float Distance = length(LightDirection); \n\
LightDirection = normalize(LightDirection); \n\
float ShadowFactor = CalcShadowFactor(LightSpacePos); \n\
\n\
vec4 Color = CalcLightInternal(l.Base, LightDirection, Normal, ShadowFactor); \n\
float Attenuation = l.Atten.Constant + \n\
l.Atten.Linear * Distance + \n\
l.Atten.Exp * Distance * Distance; \n\
\n\
return Color / Attenuation; \n\
} \n\
\n\
vec4 CalcSpotLight(struct SpotLight l, vec3 Normal, vec4 LightSpacePos) \n\
{ \n\
vec3 LightToPixel = normalize(WorldPos0 - l.Base.Position); \n\
float SpotFactor = dot(LightToPixel, l.Direction); \n\
\n\
if (SpotFactor > l.Cutoff) { \n\
vec4 Color = CalcPointLight(l.Base, Normal, LightSpacePos); \n\
return Color * (1.0 - (1.0 - SpotFactor) * 1.0/(1.0 - l.Cutoff)); \n\
} \n\
else { \n\
return vec4(0,0,0,0); \n\
} \n\
} \n\
\n\
vec3 CalcBumpedNormal() \n\
{ \n\
vec3 Normal = normalize(Normal0); \n\
vec3 Tangent = normalize(Tangent0); \n\
Tangent = normalize(Tangent - dot(Tangent, Normal) * Normal); \n\
vec3 Bitangent = cross(Tangent, Normal); \n\
vec3 BumpMapNormal = texture(gNormalMap, TexCoord0).xyz; \n\
BumpMapNormal = 2.0 * BumpMapNormal - vec3(1.0, 1.0, 1.0); \n\
vec3 NewNormal; \n\
mat3 TBN = mat3(Tangent, Bitangent, Normal); \n\
NewNormal = TBN * BumpMapNormal; \n\
NewNormal = normalize(NewNormal); \n\
return NewNormal; \n\
} \n\
\n\
void main() \n\
{ \n\
vec3 Normal = CalcBumpedNormal(); \n\
vec4 TotalLight = CalcDirectionalLight(Normal); \n\
\n\
for (int i = 0 ; i < gNumPointLights ; i++) { \n\
TotalLight += CalcPointLight(gPointLights[i], Normal, LightSpacePos); \n\
} \n\
\n\
for (int i = 0 ; i < gNumSpotLights ; i++) { \n\
TotalLight += CalcSpotLight(gSpotLights[i], Normal, LightSpacePos); \n\
} \n\
\n\
vec4 SampledColor = texture2D(gColorMap, TexCoord0.xy); \n\
FragColor = SampledColor * TotalLight; \n\
}";
GLSL жалуется, что:
Ошибка компиляции FS: 'Фрагмент шейдера не смог скомпилировать со следующими ошибками:
ОШИБКА: 0:24: ошибка (# 132) Синтаксическая ошибка: ошибка разбора 'Base'
ОШИБКА: ошибка (# 273) 1 ошибки компиляции. Код не сгенерирован '
Однако стандарт GLSL четко гласит:
... это тоже
создает переменную этого типа с именем variableName. Как и в C / C ++,
имя переменной может быть опущено. Структуры не могут содержать переменные
типы сэмплеров. Они могут содержать переменные других структурных типов.
Структуры определяют именованный тип. Но есть ограничения на тип
квалификаторы, которые можно использовать с типами структур. Униформа может использовать структуру
типы, а также регулярные глобальные, локальные и постоянные переменные.
Структуры нельзя использовать с другими квалификаторами хранения.
Почему это не компилируется?