+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
+
namespace
{
EOL" Specular += occLight_Specular (theId).rgb * aSpecl;"
EOL"}";
+//! The same as THE_FUNC_directionalLight but for the light with zero index
+//! (avoids limitations on some mobile devices).
+const char THE_FUNC_directionalLightFirst[] =
+ EOL"void directionalLightFirst (in vec3 theNormal,"
+ EOL" in vec3 theView,"
+ EOL" in bool theIsFront)"
+ EOL"{"
+ EOL" vec3 aLight = normalize (occLightSources[1].xyz);"
+ EOL" if (occLight_IsHeadlight (0) == 0)"
+ EOL" {"
+ EOL" aLight = vec3 (occWorldViewMatrix * occModelWorldMatrix * vec4 (aLight, 0.0));"
+ EOL" }"
+ EOL
+ EOL" vec3 aHalf = normalize (aLight + theView);"
+ EOL
+ EOL" vec3 aFaceSideNormal = theIsFront ? theNormal : -theNormal;"
+ EOL" float aNdotL = max (0.0, dot (aFaceSideNormal, aLight));"
+ EOL" float aNdotH = max (0.0, dot (aFaceSideNormal, aHalf ));"
+ EOL
+ EOL" float aSpecl = 0.0;"
+ EOL" if (aNdotL > 0.0)"
+ EOL" {"
+ EOL" aSpecl = pow (aNdotH, theIsFront ? occFrontMaterial_Shininess() : occBackMaterial_Shininess());"
+ EOL" }"
+ EOL
+ EOL" Diffuse += occLightSources[0].rgb * aNdotL;"
+ EOL" Specular += occLightSources[0].rgb * aSpecl;"
+ EOL"}";
+
//! Process clipping planes in Fragment Shader.
//! Should be added at the beginning of the main() function.
const char THE_FRAG_CLIP_PLANES[] =
5, aParams);
}
-}; // nameless namespace
+} // nameless namespace
// =======================================================================
// function : PushMaterialState
return;
}
- if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
+ const OpenGl_Element* anAspect = aState.Aspect();
+ if (typeid (*anAspect) == typeid (OpenGl_AspectFace))
{
- PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
+ PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (anAspect));
}
- else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
+ else if (typeid (*anAspect) == typeid (OpenGl_AspectLine))
{
- PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
+ PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (anAspect));
}
- else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
+ else if (typeid (*anAspect) == typeid (OpenGl_AspectText))
{
- PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
+ PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (anAspect));
}
- else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
+ else if (typeid (*anAspect) == typeid (OpenGl_AspectMarker))
{
- PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
+ PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (anAspect));
}
theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
{
aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).r; }";
}
+ else if (myContext->IsGlGreaterEqual (2, 1))
+ {
+ aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
+ }
#endif
aSrcFragGetColor = aSrcGetAlpha
EOL" vec4 aColor = getColor();"
EOL" if (aColor.a <= 0.1) discard;"
EOL" occFragColor = aColor;";
+ #if !defined(GL_ES_VERSION_2_0)
+ if (myContext->core11 != NULL
+ && myContext->IsGlGreaterEqual (2, 1))
+ {
+ aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
+ }
+ #endif
}
}
else
EOL" vec3 aNormal = transformNormal (occNormal);"
EOL" vec3 aReflect = reflect (normalize (aPosition.xyz), aNormal);"
EOL" aReflect.z += 1.0;"
- EOL" TexCoord = aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5);";
+ EOL" TexCoord = vec4(aReflect.xy * inversesqrt (dot (aReflect, aReflect)) * 0.5 + vec2 (0.5), 0.0, 1.0);";
aSrcFragGetColor =
EOL"vec4 getColor(void) { return occTexture2D (occActiveSampler, TexCoord.st); }";
TCollection_AsciiString aSrcVertEndMain;
if ((theBits & OpenGl_PO_StippleLine) != 0)
{
- bool hasCaps = false;
+ bool hasGlslBitOps = false;
#if defined(GL_ES_VERSION_2_0)
if (myContext->IsGlGreaterEqual (3, 0))
{
aProgramSrc->SetHeader ("#version 300 es");
- hasCaps = true;
+ hasGlslBitOps = true;
}
#else
- if (myContext->core32 != NULL)
+ if (myContext->IsGlGreaterEqual (3, 0))
+ {
+ aProgramSrc->SetHeader ("#version 130");
+ hasGlslBitOps = true;
+ }
+ else if(myContext->CheckExtension("GL_EXT_gpu_shader4"))
{
- aProgramSrc->SetHeader ("#version 150");
- hasCaps = true;
+ aProgramSrc->SetHeader ("#extension GL_EXT_gpu_shader4 : enable");
+ hasGlslBitOps = true;
}
#endif
- if (hasCaps)
+ if (hasGlslBitOps)
{
aSrcVertExtraOut +=
EOL"THE_SHADER_OUT vec2 ScreenSpaceCoord;";
{
const TCollection_ExtendedString aWarnMessage =
"Warning: stipple lines in GLSL will be ignored.";
- myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_PORTABILITY_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB, aWarnMessage);
+ myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
}
}
// =======================================================================
TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (const Standard_Boolean theHasVertColor)
{
- bool aLightsMap[Graphic3d_TOLS_SPOT + 1] = { false, false, false, false };
+ Standard_Integer aLightsMap[Graphic3d_TOLS_SPOT + 1] = { 0, 0, 0, 0 };
TCollection_AsciiString aLightsFunc, aLightsLoop;
const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
if (aLights != NULL)
aLightsLoop = aLightsLoop + EOL" spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
break;
}
-
- bool& aTypeBit = aLightsMap[aLightIter.Value().Type];
- if (aTypeBit)
- {
- continue;
- }
-
- aTypeBit = true;
- switch (aLightIter.Value().Type)
- {
- case Graphic3d_TOLS_AMBIENT: break;
- case Graphic3d_TOLS_DIRECTIONAL: aLightsFunc += THE_FUNC_directionalLight; break;
- case Graphic3d_TOLS_POSITIONAL: aLightsFunc += THE_FUNC_pointLight; break;
- case Graphic3d_TOLS_SPOT: aLightsFunc += THE_FUNC_spotLight; break;
- }
+ aLightsMap[aLightIter.Value().Type] += 1;
+ }
+ const Standard_Integer aNbLoopLights = aLightsMap[Graphic3d_TOLS_DIRECTIONAL]
+ + aLightsMap[Graphic3d_TOLS_POSITIONAL]
+ + aLightsMap[Graphic3d_TOLS_SPOT];
+ if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] == 1
+ && aNbLoopLights == 1)
+ {
+ // use the version with hard-coded first index
+ aLightsLoop = EOL" directionalLightFirst(theNormal, theView, theIsFront);";
+ aLightsFunc += THE_FUNC_directionalLightFirst;
+ }
+ else if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] > 0)
+ {
+ aLightsFunc += THE_FUNC_directionalLight;
+ }
+ if (aLightsMap[Graphic3d_TOLS_POSITIONAL] > 0)
+ {
+ aLightsFunc += THE_FUNC_pointLight;
+ }
+ if (aLightsMap[Graphic3d_TOLS_SPOT] > 0)
+ {
+ aLightsFunc += THE_FUNC_spotLight;
}
}
EOL" vec4 aColor = gl_FrontFacing ? FrontColor : BackColor;"
EOL" return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
EOL"}";
+ #if !defined(GL_ES_VERSION_2_0)
+ if (myContext->core11 != NULL
+ && myContext->IsGlGreaterEqual (2, 1))
+ {
+ aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
+ }
+ #endif
}
}
else
EOL" vec4 aColor = " thePhongCompLight ";"
EOL" return occTexture2D(occActiveSampler, gl_PointCoord) * aColor;"
EOL"}";
+ #if !defined(GL_ES_VERSION_2_0)
+ if (myContext->core11 != NULL
+ && myContext->IsGlGreaterEqual (2, 1))
+ {
+ aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
+ }
+ #endif
}
}
else