Added new type of graphic3d limit Graphic3d_TypeOfLimit_HasFlatShading.
Added workaround for unexpected behaviour of mobile devices with Adreno GPU.
Added new complex flag hasFlatShading to OpenGl_Context for indicating support of flat shading.
Graphic3d_TypeOfLimit_HasRayTracingAdaptiveSampling, //!< indicates whether adaptive screen sampling is supported
Graphic3d_TypeOfLimit_HasBlendedOit, //!< indicates whether necessary GL extensions for Weighted, Blended OIT available (without MSAA).
Graphic3d_TypeOfLimit_HasBlendedOitMsaa, //!< indicates whether necessary GL extensions for Weighted, Blended OIT available (with MSAA).
+ Graphic3d_TypeOfLimit_HasFlatShading, //!< indicates whether Flat shading (Graphic3d_TOSM_FACET) is supported
Graphic3d_TypeOfLimit_NB //!< number of elements in this enumeration
};
hasHighp (Standard_False),
hasUintIndex(Standard_False),
hasTexRGBA8(Standard_False),
+ hasFlatShading (OpenGl_FeatureNotAvailable),
#else
hasHighp (Standard_True),
hasUintIndex(Standard_True),
hasTexRGBA8(Standard_True),
+ hasFlatShading (OpenGl_FeatureInCore),
#endif
hasDrawBuffers (OpenGl_FeatureNotAvailable),
hasFloatBuffer (OpenGl_FeatureNotAvailable),
hasSampleVariables = IsGlGreaterEqual (3, 2) ? OpenGl_FeatureInCore :
oesSampleVariables ? OpenGl_FeatureInExtensions
: OpenGl_FeatureNotAvailable;
+ // without hasHighp, dFdx/dFdy precision is considered too low for flat shading (visual artifacts)
+ hasFlatShading = IsGlGreaterEqual (3, 0)
+ ? OpenGl_FeatureInCore
+ : (oesStdDerivatives && hasHighp
+ ? OpenGl_FeatureInExtensions
+ : OpenGl_FeatureNotAvailable);
+ if (!IsGlGreaterEqual (3, 1)
+ && myVendor.Search("Qualcomm") != -1)
+ {
+ // dFdx/dFdy are completely broken on tested Adreno devices with versions below OpenGl ES 3.1
+ hasFlatShading = OpenGl_FeatureNotAvailable;
+ }
#else
myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
myLineWidthScale = Max (1.0f, std::floor (theRatio + 0.5f));
}
+ //! Return Graphics Driver's vendor.
+ const TCollection_AsciiString& Vendor() const { return myVendor; }
+
private:
//! Wrapper to system function to retrieve GL function pointer by name.
Standard_Boolean hasHighp; //!< highp in GLSL ES fragment shader is supported
Standard_Boolean hasUintIndex; //!< GLuint for index buffer is supported (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_element_index_uint)
Standard_Boolean hasTexRGBA8; //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8
+ OpenGl_FeatureFlag hasFlatShading; //!< Complex flag indicating support of Flat shading (Graphic3d_TOSM_FACET) (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_standard_derivatives)
OpenGl_FeatureFlag hasDrawBuffers; //!< Complex flag indicating support of multiple draw buffers (desktop OpenGL 2.0, OpenGL ES 3.0, GL_ARB_draw_buffers, GL_EXT_draw_buffers)
OpenGl_FeatureFlag hasFloatBuffer; //!< Complex flag indicating support of float color buffer format (desktop OpenGL 3.0, GL_ARB_color_buffer_float, GL_EXT_color_buffer_float)
OpenGl_FeatureFlag hasHalfFloatBuffer; //!< Complex flag indicating support of half-float color buffer format (desktop OpenGL 3.0, GL_ARB_color_buffer_float, GL_EXT_color_buffer_half_float)
return (!aCtx.IsNull()
&& aCtx->hasSampleVariables != OpenGl_FeatureNotAvailable
&& (InquireLimit (Graphic3d_TypeOfLimit_HasBlendedOit) == 1)) ? 1 : 0;
+ case Graphic3d_TypeOfLimit_HasFlatShading:
+ return !aCtx.IsNull() && aCtx->hasFlatShading != OpenGl_FeatureNotAvailable ? 1 : 0;
case Graphic3d_TypeOfLimit_NB:
return 0;
}
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;
+ && myContext->hasFlatShading != OpenGl_FeatureNotAvailable;
+ const char* aDFdxSignReversion = "";
+#if defined(GL_ES_VERSION_2_0)
+ if (isFlatNormal != theIsFlatNormal)
+ {
+ 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.");
+ }
+ else if (isFlatNormal
+ && myContext->Vendor().Search("Qualcomm") != -1)
+ {
+ // workaround Adreno driver bug computing reversed normal using dFdx/dFdy
+ aDFdxSignReversion = "-";
+ myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
+ "Warning: applied workaround for flat shading normal computation using dFdx/dFdy on Adreno");
+ }
#endif
Handle(Graphic3d_ShaderProgram) aProgramSrc = new Graphic3d_ShaderProgram();
EOL"{"
+ aSrcFragExtraMain
+ (isFlatNormal
- ? EOL" Normal = normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
- EOL" if (!gl_FrontFacing) { Normal = -Normal; }"
+ ? TCollection_AsciiString()
+ + EOL" Normal = " + aDFdxSignReversion + "normalize (cross (dFdx (Position.xyz / Position.w), dFdy (Position.xyz / Position.w)));"
+ EOL" if (!gl_FrontFacing) { Normal = -Normal; }"
: "")
+ EOL" occSetFragColor (getColor());"
+ aSrcFragWriteOit
{
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->SetNbLightsMax (aNbLights);