atiMem (Standard_False),
nvxMem (Standard_False),
oesSampleVariables (Standard_False),
+ oesStdDerivatives (Standard_False),
mySharedResources (new OpenGl_ResourcesMap()),
myDelayed (new OpenGl_DelayReleaseMap()),
myUnusedResources (new OpenGl_ResourcesStack()),
: OpenGl_FeatureNotAvailable;
oesSampleVariables = CheckExtension ("GL_OES_sample_variables");
+ oesStdDerivatives = CheckExtension ("GL_OES_standard_derivatives");
hasSampleVariables = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
oesSampleVariables ? OpenGl_FeatureInExtensions
: OpenGl_FeatureNotAvailable;
// =======================================================================
void OpenGl_ShaderManager::switchLightPrograms()
{
- TCollection_AsciiString aKey (myShadingModel == Graphic3d_TOSM_FRAGMENT ? "p_" : "g_");
+ TCollection_AsciiString aKey;
+ switch (myShadingModel)
+ {
+ case Graphic3d_TOSM_NONE: aKey = "c_"; break;
+ case Graphic3d_TOSM_FACET: aKey = "f_"; break;
+ case Graphic3d_TOSM_VERTEX: aKey = "g_"; break;
+ case Graphic3d_TOSM_FRAGMENT: aKey = "p_"; break;
+ }
const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
if (aLights != NULL)
{
// purpose :
// =======================================================================
Standard_Boolean OpenGl_ShaderManager::prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
- const Standard_Integer theBits)
+ const Standard_Integer theBits,
+ const Standard_Boolean theIsFlatNormal)
{
#define thePhongCompLight "computeLighting (normalize (Normal), normalize (View), Position, gl_FrontFacing)"
+#if defined(GL_ES_VERSION_2_0)
+ const bool isFlatNormal = theIsFlatNormal
+ && (myContext->IsGlGreaterEqual (3, 0)
+ || myContext->oesStdDerivatives);
+#else
+ const bool isFlatNormal = theIsFlatNormal;
+#endif
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
TCollection_AsciiString aSrcVert, aSrcVertExtraOut, aSrcVertExtraMain;
}
aSrcVert = TCollection_AsciiString()
- + THE_FUNC_transformNormal
+ + (isFlatNormal ? "" : THE_FUNC_transformNormal)
+ EOL
EOL"THE_SHADER_OUT vec4 PositionWorld;"
EOL"THE_SHADER_OUT vec4 Position;"
- EOL"THE_SHADER_OUT vec3 Normal;"
EOL"THE_SHADER_OUT vec3 View;"
- EOL
+ + (isFlatNormal ? ""
+ : EOL"THE_SHADER_OUT vec3 Normal;")
+ + EOL
+ aSrcVertExtraOut
+ EOL"void main()"
EOL"{"
EOL" PositionWorld = occModelWorldMatrix * occVertex;"
EOL" Position = occWorldViewMatrix * PositionWorld;"
- EOL" Normal = transformNormal (occNormal);"
- EOL" View = vec3 (0.0, 0.0, 1.0);"
+ + (isFlatNormal ? ""
+ : EOL" Normal = transformNormal (occNormal);")
+ + EOL" View = vec3 (0.0, 0.0, 1.0);"
+ aSrcVertExtraMain
+ EOL" gl_Position = occProjectionMatrix * occWorldViewMatrix * occModelWorldMatrix * occVertex;"
EOL"}";
aSrcFrag = TCollection_AsciiString()
+ EOL"THE_SHADER_IN vec4 PositionWorld;"
EOL"THE_SHADER_IN vec4 Position;"
- EOL"THE_SHADER_IN vec3 Normal;"
EOL"THE_SHADER_IN vec3 View;"
+ + (isFlatNormal
+ ? EOL"vec3 Normal;"
+ : EOL"THE_SHADER_IN vec3 Normal;")
+ EOL
+ aSrcFragExtraOut
+ aSrcFragGetVertColor
EOL"void main()"
EOL"{"
+ aSrcFragExtraMain
+ + (isFlatNormal
+ ? EOL" Normal = normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
+ : "")
+ EOL" occFragColor = getColor();"
+ aSrcFragWriteOit
+ EOL"}";
{
aProgramSrc->SetHeader ("#version 300 es");
}
+ else if (isFlatNormal)
+ {
+ if (myContext->oesStdDerivatives)
+ {
+ aProgramSrc->SetHeader ("#extension GL_OES_standard_derivatives : enable");
+ }
+ else
+ {
+ myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
+ "Warning: flat shading requires OpenGL ES 3.0+ or GL_OES_standard_derivatives extension.");
+ }
+ }
#endif
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_VERTEX, aSrcVert));
aProgramSrc->AttachShader (Graphic3d_ShaderObject::CreateFromSource (Graphic3d_TOS_FRAGMENT, aSrcFrag));
Standard_Boolean prepareStdProgramLight (Handle(OpenGl_ShaderProgram)& theProgram,
const Standard_Integer theBits)
{
- return myShadingModel == Graphic3d_TOSM_FRAGMENT
- ? prepareStdProgramPhong (theProgram, theBits)
- : prepareStdProgramGouraud (theProgram, theBits);
+ switch (myShadingModel)
+ {
+ case Graphic3d_TOSM_NONE: return prepareStdProgramFlat (theProgram, theBits);
+ case Graphic3d_TOSM_FACET: return prepareStdProgramPhong (theProgram, theBits, true);
+ case Graphic3d_TOSM_VERTEX: return prepareStdProgramGouraud(theProgram, theBits);
+ case Graphic3d_TOSM_FRAGMENT: return prepareStdProgramPhong (theProgram, theBits, false);
+ }
+ return false;
}
//! Prepare standard GLSL program with per-vertex lighting.
const Standard_Integer theBits);
//! Prepare standard GLSL program with per-pixel lighting.
+ //! @param theIsFlatNormal when TRUE, the Vertex normals will be ignored and Face normal will be computed instead
Standard_EXPORT Standard_Boolean prepareStdProgramPhong (Handle(OpenGl_ShaderProgram)& theProgram,
- const Standard_Integer theBits);
+ const Standard_Integer theBits,
+ const Standard_Boolean theIsFlatNormal = false);
//! Define computeLighting GLSL function depending on current lights configuration
//! @param theHasVertColor flag to use getVertColor() instead of Ambient and Diffuse components of active material