#include <TCollection_ExtendedString.hxx>
-
-
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
namespace
{
+ //! Clipping planes limit (see the same definition in Declarations.glsl).
+ static const Standard_Size THE_MAX_CLIP_PLANES = 8;
+
#define EOL "\n"
//! Definition of TexCoord varying.
EOL" aTex2.y = aCopy.x * aRotSin + aCopy.y * aRotCos;"
EOL" TexCoord = vec4(aTex2, occTexCoord.zw);";
+//! Auxiliary function to flip gl_PointCoord vertically
+#define THE_VEC2_glPointCoord "vec2 (gl_PointCoord.x, 1.0 - gl_PointCoord.y)"
+
//! Auxiliary function to transform normal
const char THE_FUNC_transformNormal[] =
EOL"vec3 transformNormal (in vec3 theNormal)"
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[] =
EOL" for (int aPlaneIter = 0; aPlaneIter < occClipPlaneCount; ++aPlaneIter)"
EOL" {"
EOL" vec4 aClipEquation = occClipPlaneEquations[aPlaneIter];"
- EOL" int aClipSpace = occClipPlaneSpaces[aPlaneIter];"
- EOL" if (aClipSpace == OccEquationCoords_World)"
- EOL" {"
- EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz) + aClipEquation.w < 0.0)"
- EOL" {"
- EOL" discard;"
- EOL" }"
- EOL" }"
- EOL" else if (aClipSpace == OccEquationCoords_View)"
+ EOL" if (dot (aClipEquation.xyz, PositionWorld.xyz / PositionWorld.w) + aClipEquation.w < 0.0)"
EOL" {"
- EOL" if (dot (aClipEquation.xyz, Position.xyz) + aClipEquation.w < 0.0)"
- EOL" {"
- EOL" discard;"
- EOL" }"
+ EOL" discard;"
EOL" }"
EOL" }";
}
myProgramList.Remove (anIt);
- myMaterialStates.UnBind (theProgram);
break;
}
}
theProgram->UpdateState (OpenGl_CLIP_PLANES_STATE, myClippingState.Index());
const GLint aLocEquations = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_EQUATIONS);
- const GLint aLocSpaces = theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_SPACES);
- if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION
- && aLocSpaces == OpenGl_ShaderProgram::INVALID_LOCATION)
+ if (aLocEquations == OpenGl_ShaderProgram::INVALID_LOCATION)
{
return;
}
return;
}
- const Standard_Size MAX_CLIP_PLANES = 8;
- OpenGl_Vec4* anEquations = new OpenGl_Vec4[MAX_CLIP_PLANES];
- GLint* aSpaces = new GLint [MAX_CLIP_PLANES];
+ OpenGl_Vec4 anEquations[THE_MAX_CLIP_PLANES];
GLuint aPlaneId = 0;
for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes());
anIter.More(); anIter.Next())
{
continue;
}
+ else if (aPlaneId >= THE_MAX_CLIP_PLANES)
+ {
+ myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
+ "Warning: clipping planes limit (8) has been exceeded.");
+ break;
+ }
const Graphic3d_ClipPlane::Equation& anEquation = aPlane->GetEquation();
anEquations[aPlaneId] = OpenGl_Vec4 ((float) anEquation.x(),
(float) anEquation.y(),
(float) anEquation.z(),
(float) anEquation.w());
- aSpaces[aPlaneId] = myContext->Clipping().GetEquationSpace (aPlane);
++aPlaneId;
}
theProgram->SetUniform (myContext,
theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT),
aPlanesNb);
- theProgram->SetUniform (myContext, aLocEquations, MAX_CLIP_PLANES, anEquations);
- theProgram->SetUniform (myContext, aLocSpaces, MAX_CLIP_PLANES, aSpaces);
-
- delete[] anEquations;
- delete[] aSpaces;
-}
-
-// =======================================================================
-// function : UpdateMaterialStateTo
-// purpose : Updates state of OCCT material for specified program
-// =======================================================================
-void OpenGl_ShaderManager::UpdateMaterialStateTo (const Handle(OpenGl_ShaderProgram)& theProgram,
- const OpenGl_Element* theAspect)
-{
- if (myMaterialStates.IsBound (theProgram))
- {
- OpenGl_MaterialState& aState = myMaterialStates.ChangeFind (theProgram);
- aState.Set (theAspect);
- aState.Update();
- }
- else
- {
- myMaterialStates.Bind (theProgram, OpenGl_MaterialState (theAspect));
- myMaterialStates.ChangeFind (theProgram).Update();
- }
-}
-
-// =======================================================================
-// function : ResetMaterialStates
-// purpose : Resets state of OCCT material for all programs
-// =======================================================================
-void OpenGl_ShaderManager::ResetMaterialStates()
-{
- for (OpenGl_ShaderProgramList::Iterator anIt (myProgramList); anIt.More(); anIt.Next())
- {
- anIt.Value()->UpdateState (OpenGl_MATERIALS_STATE, 0);
- }
-}
-
-// =======================================================================
-// function : MaterialState
-// purpose : Returns state of OCCT material for specified program
-// =======================================================================
-const OpenGl_MaterialState* OpenGl_ShaderManager::MaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
-{
- if (!myMaterialStates.IsBound (theProgram))
- return NULL;
-
- return &myMaterialStates.Find (theProgram);
-}
-
-// =======================================================================
-// function : SurfaceDetailState
-// purpose : Returns current state of OCCT surface detail
-// =======================================================================
-const OpenGl_SurfaceDetailState& OpenGl_ShaderManager::SurfaceDetailState() const
-{
- return mySurfaceDetailState;
-}
-
-// =======================================================================
-// function : UpdateSurfaceDetailStateTo
-// purpose : Updates state of OCCT surface detail
-// =======================================================================
-void OpenGl_ShaderManager::UpdateSurfaceDetailStateTo (const Graphic3d_TypeOfSurfaceDetail theDetail)
-{
- mySurfaceDetailState.Set (theDetail);
- mySurfaceDetailState.Update();
-}
-
-namespace
-{
-
-static const OpenGl_Vec4 THE_COLOR_BLACK_VEC4 (0.0f, 0.0f, 0.0f, 0.0f);
-
-// =======================================================================
-// function : PushAspectFace
-// purpose :
-// =======================================================================
-static void PushAspectFace (const Handle(OpenGl_Context)& theCtx,
- const Handle(OpenGl_ShaderProgram)& theProgram,
- const OpenGl_AspectFace* theAspect)
-{
- theProgram->SetUniform (theCtx,
- theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
- theAspect->DoTextureMap());
- theProgram->SetUniform (theCtx,
- theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER),
- 0 /* GL_TEXTURE0 */);
- theProgram->SetUniform (theCtx,
- theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
- theAspect->DistinguishingMode());
-
- OpenGl_Material aParams;
- for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
- {
- const GLint aLoc = theProgram->GetStateLocation (anIndex == 0
- ? OpenGl_OCCT_FRONT_MATERIAL
- : OpenGl_OCCT_BACK_MATERIAL);
- if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
- {
- continue;
- }
-
- const OPENGL_SURF_PROP& aProp = anIndex == 0 || theAspect->DistinguishingMode() != TOn
- ? theAspect->IntFront()
- : theAspect->IntBack();
- aParams.Init (aProp);
- aParams.Diffuse.a() = aProp.trans;
- theProgram->SetUniform (theCtx, aLoc, OpenGl_Material::NbOfVec4(),
- aParams.Packed());
- }
-}
-
-// =======================================================================
-// function : PushAspectLine
-// purpose :
-// =======================================================================
-static void PushAspectLine (const Handle(OpenGl_Context)& theCtx,
- const Handle(OpenGl_ShaderProgram)& theProgram,
- const OpenGl_AspectLine* theAspect)
-{
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOff);
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
-
- const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
- theAspect->Color().rgb[1],
- theAspect->Color().rgb[2],
- theAspect->Color().rgb[3]);
- OpenGl_Vec4 aParams[5];
- aParams[0] = THE_COLOR_BLACK_VEC4;
- aParams[1] = THE_COLOR_BLACK_VEC4;
- aParams[2] = aDiffuse;
- aParams[3] = THE_COLOR_BLACK_VEC4;
- aParams[4].x() = 0.0f; // shininess
- aParams[4].y() = 0.0f; // transparency
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
- 5, aParams);
-}
-
-// =======================================================================
-// function : PushAspectText
-// purpose :
-// =======================================================================
-static void PushAspectText (const Handle(OpenGl_Context)& theCtx,
- const Handle(OpenGl_ShaderProgram)& theProgram,
- const OpenGl_AspectText* theAspect)
-{
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
-
- OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
- theAspect->Color().rgb[1],
- theAspect->Color().rgb[2],
- theAspect->Color().rgb[3]);
- if (theAspect->DisplayType() == Aspect_TODT_DEKALE
- || theAspect->DisplayType() == Aspect_TODT_SUBTITLE)
- {
- aDiffuse = OpenGl_Vec4 (theAspect->SubtitleColor().rgb[0],
- theAspect->SubtitleColor().rgb[1],
- theAspect->SubtitleColor().rgb[2],
- theAspect->SubtitleColor().rgb[3]);
- }
-
- OpenGl_Vec4 aParams[5];
- aParams[0] = THE_COLOR_BLACK_VEC4;
- aParams[1] = THE_COLOR_BLACK_VEC4;
- aParams[2] = aDiffuse;
- aParams[3] = THE_COLOR_BLACK_VEC4;
- aParams[4].x() = 0.0f; // shininess
- aParams[4].y() = 0.0f; // transparency
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
- 5, aParams);
-}
-
-// =======================================================================
-// function : PushAspectMarker
-// purpose :
-// =======================================================================
-static void PushAspectMarker (const Handle(OpenGl_Context)& theCtx,
- const Handle(OpenGl_ShaderProgram)& theProgram,
- const OpenGl_AspectMarker* theAspect)
-{
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE), TOn);
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE), TOff);
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_ACTIVE_SAMPLER), 0 /* GL_TEXTURE0 */);
-
- const OpenGl_Vec4 aDiffuse (theAspect->Color().rgb[0],
- theAspect->Color().rgb[1],
- theAspect->Color().rgb[2],
- theAspect->Color().rgb[3]);
- OpenGl_Vec4 aParams[5];
- aParams[0] = THE_COLOR_BLACK_VEC4;
- aParams[1] = THE_COLOR_BLACK_VEC4;
- aParams[2] = aDiffuse;
- aParams[3] = THE_COLOR_BLACK_VEC4;
- aParams[4].x() = 0.0f; // shininess
- aParams[4].y() = 0.0f; // transparency
- theProgram->SetUniform (theCtx, theProgram->GetStateLocation (OpenGl_OCCT_FRONT_MATERIAL),
- 5, aParams);
-}
-
-}; // nameless namespace
-
-// =======================================================================
-// function : PushMaterialState
-// purpose : Pushes current state of OCCT material to the program
-// =======================================================================
-void OpenGl_ShaderManager::PushMaterialState (const Handle(OpenGl_ShaderProgram)& theProgram) const
-{
- if (!myMaterialStates.IsBound (theProgram))
- {
- return;
- }
-
- const OpenGl_MaterialState& aState = myMaterialStates.Find (theProgram);
- if (aState.Index() == theProgram->ActiveState (OpenGl_MATERIALS_STATE))
- {
- return;
- }
-
- if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectFace))
- {
- PushAspectFace (myContext, theProgram, dynamic_cast<const OpenGl_AspectFace*> (aState.Aspect()));
- }
- else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectLine))
- {
- PushAspectLine (myContext, theProgram, dynamic_cast<const OpenGl_AspectLine*> (aState.Aspect()));
- }
- else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectText))
- {
- PushAspectText (myContext, theProgram, dynamic_cast<const OpenGl_AspectText*> (aState.Aspect()));
- }
- else if (typeid (*aState.Aspect()) == typeid (OpenGl_AspectMarker))
- {
- PushAspectMarker (myContext, theProgram, dynamic_cast<const OpenGl_AspectMarker*> (aState.Aspect()));
- }
-
- theProgram->UpdateState (OpenGl_MATERIALS_STATE, aState.Index());
+ theProgram->SetUniform (myContext, aLocEquations, THE_MAX_CLIP_PLANES, anEquations);
}
// =======================================================================
void OpenGl_ShaderManager::PushState (const Handle(OpenGl_ShaderProgram)& theProgram) const
{
PushClippingState (theProgram);
- PushMaterialState (theProgram);
PushWorldViewState (theProgram);
PushModelWorldState (theProgram);
PushProjectionState (theProgram);
return Standard_True;
}
+// =======================================================================
+// function : pointSpriteAlphaSrc
+// purpose :
+// =======================================================================
+TCollection_AsciiString OpenGl_ShaderManager::pointSpriteAlphaSrc (const Standard_Integer theBits)
+{
+ TCollection_AsciiString aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ").a; }";
+#if !defined(GL_ES_VERSION_2_0)
+ if (myContext->core11 == NULL
+ && (theBits & OpenGl_PO_TextureA) != 0)
+ {
+ aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ").r; }";
+ }
+#else
+ (void )theBits;
+#endif
+ return aSrcGetAlpha;
+}
+
+namespace
+{
+
+ // =======================================================================
+ // function : textureUsed
+ // purpose :
+ // =======================================================================
+ static bool textureUsed (const Standard_Integer theBits)
+ {
+ return (theBits & OpenGl_PO_TextureA) != 0 || (theBits & OpenGl_PO_TextureRGB) != 0;
+ }
+
+}
+
// =======================================================================
// function : prepareStdProgramFlat
// purpose :
const Standard_Integer theBits)
{
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
- TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
+ TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain, aSrcVertExtraFunc, aSrcGetAlpha, aSrcFrag, aSrcFragExtraOut, aSrcFragExtraMain;
TCollection_AsciiString aSrcFragGetColor = EOL"vec4 getColor(void) { return occColor; }";
TCollection_AsciiString aSrcFragMainGetColor = EOL" occFragColor = getColor();";
if ((theBits & OpenGl_PO_Point) != 0)
#if defined(GL_ES_VERSION_2_0)
aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
#endif
- if ((theBits & OpenGl_PO_TextureA) != 0)
+
+ if ((theBits & OpenGl_PO_TextureRGB) != 0)
{
- TCollection_AsciiString
- aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).a; }";
+ aSrcFragGetColor =
+ EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord "); }";
+ }
+
+ if (textureUsed (theBits))
+ {
+ aSrcGetAlpha = pointSpriteAlphaSrc (theBits);
+
#if !defined(GL_ES_VERSION_2_0)
- if (myContext->core11 == NULL)
- {
- aSrcGetAlpha = EOL"float getAlpha(void) { return occTexture2D(occActiveSampler, gl_PointCoord).r; }";
- }
- else if (myContext->IsGlGreaterEqual (2, 1))
+ if (myContext->core11 != NULL
+ && myContext->IsGlGreaterEqual (2, 1))
{
aProgramSrc->SetHeader ("#version 120"); // gl_PointCoord has been added since GLSL 1.2
}
#endif
- aSrcFragGetColor = aSrcGetAlpha
- + EOL"vec4 getColor(void)"
- EOL"{"
- EOL" vec4 aColor = occColor;"
- EOL" aColor.a *= getAlpha();"
- EOL" return aColor;"
- EOL"}";
-
aSrcFragMainGetColor =
EOL" vec4 aColor = getColor();"
+ EOL" aColor.a = getAlpha();"
EOL" if (aColor.a <= 0.1) discard;"
EOL" occFragColor = aColor;";
}
- else if ((theBits & OpenGl_PO_TextureRGB) != 0)
+ else
{
- aSrcFragGetColor =
- EOL"vec4 getColor(void) { return occTexture2D(occActiveSampler, gl_PointCoord); }";
aSrcFragMainGetColor =
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); }";
aSrcFrag =
aSrcFragExtraOut
+ aSrcFragGetColor
+ + aSrcGetAlpha
+ EOL"void main()"
EOL"{"
+ aSrcFragExtraMain
return Standard_True;
}
+// =======================================================================
+// function : pointSpriteShadingSrc
+// purpose :
+// =======================================================================
+TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TCollection_AsciiString theBaseColorSrc,
+ const Standard_Integer theBits)
+{
+ TCollection_AsciiString aSrcFragGetColor;
+ if ((theBits & OpenGl_PO_TextureA) != 0)
+ {
+ aSrcFragGetColor = pointSpriteAlphaSrc (theBits) +
+ EOL"vec4 getColor(void)"
+ EOL"{"
+ EOL" vec4 aColor = " + theBaseColorSrc + ";"
+ EOL" aColor.a = getAlpha();"
+ EOL" if (aColor.a <= 0.1) discard;"
+ EOL" return aColor;"
+ EOL"}";
+ }
+ else if ((theBits & OpenGl_PO_TextureRGB) != 0)
+ {
+ aSrcFragGetColor = TCollection_AsciiString() +
+ EOL"vec4 getColor(void)"
+ EOL"{"
+ EOL" vec4 aColor = " + theBaseColorSrc + ";"
+ EOL" aColor = occTexture2D(occActiveSampler, " THE_VEC2_glPointCoord ") * aColor;"
+ EOL" if (aColor.a <= 0.1) discard;"
+ EOL" return aColor;"
+ EOL"}";
+ }
+
+ return aSrcFragGetColor;
+}
+
// =======================================================================
// function : stdComputeLighting
// purpose :
// =======================================================================
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;
}
}
#if defined(GL_ES_VERSION_2_0)
aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
#endif
- }
- if ((theBits & OpenGl_PO_VertColor) != 0)
- {
- aSrcVertColor = EOL"vec4 getVertColor(void) { return occVertColor; }";
- }
- if ((theBits & OpenGl_PO_Point) != 0)
- {
- if ((theBits & OpenGl_PO_TextureRGB) != 0)
+
+ if (textureUsed (theBits))
{
- aSrcFragGetColor =
- EOL"vec4 getColor(void)"
- EOL"{"
- 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
+ #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
+
+ aSrcFragGetColor = pointSpriteShadingSrc ("gl_FrontFacing ? FrontColor : BackColor", theBits);
}
}
else
EOL"}";
}
}
+
+ if ((theBits & OpenGl_PO_VertColor) != 0)
+ {
+ aSrcVertColor = EOL"vec4 getVertColor(void) { return occVertColor; }";
+ }
+
if ((theBits & OpenGl_PO_ClipPlanes) != 0)
{
aSrcVertExtraOut +=
#if defined(GL_ES_VERSION_2_0)
aSrcVertExtraMain += EOL" gl_PointSize = occPointSize;";
#endif
- }
- if ((theBits & OpenGl_PO_VertColor) != 0)
- {
- aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
- aSrcVertExtraMain += EOL" VertColor = occVertColor;";
- aSrcFragGetVertColor = EOL"THE_SHADER_IN vec4 VertColor;"
- EOL"vec4 getVertColor(void) { return VertColor; }";
- }
- if ((theBits & OpenGl_PO_Point) != 0)
- {
- if ((theBits & OpenGl_PO_TextureRGB) != 0)
+ if (textureUsed (theBits))
{
- aSrcFragGetColor =
- EOL"vec4 getColor(void)"
- EOL"{"
- 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
+ #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
+
+ aSrcFragGetColor = pointSpriteShadingSrc (thePhongCompLight, theBits);
}
}
else
}
}
+ if ((theBits & OpenGl_PO_VertColor) != 0)
+ {
+ aSrcVertExtraOut += EOL"THE_SHADER_OUT vec4 VertColor;";
+ aSrcVertExtraMain += EOL" VertColor = occVertColor;";
+ aSrcFragGetVertColor = EOL"THE_SHADER_IN vec4 VertColor;"
+ EOL"vec4 getVertColor(void) { return VertColor; }";
+ }
+
if ((theBits & OpenGl_PO_ClipPlanes) != 0)
{
aSrcFragExtraMain += THE_FRAG_CLIP_PLANES;
// function : bindProgramWithState
// purpose :
// =======================================================================
-Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram,
- const OpenGl_Element* theAspect)
+Standard_Boolean OpenGl_ShaderManager::bindProgramWithState (const Handle(OpenGl_ShaderProgram)& theProgram)
{
if (!myContext->BindProgram (theProgram))
{
}
theProgram->ApplyVariables (myContext);
- const OpenGl_MaterialState* aMaterialState = MaterialState (theProgram);
- if (aMaterialState == NULL || aMaterialState->Aspect() != theAspect)
- {
- UpdateMaterialStateTo (theProgram, theAspect);
- }
-
PushState (theProgram);
return Standard_True;
}