Enable GL_DEPTH_CLAMP while rendering skybox to workaround unexpected clamping issue on some GPUs.
arbFBO (NULL),
arbFBOBlit (NULL),
arbSampleShading (Standard_False),
+ arbDepthClamp (Standard_False),
extFragDepth (Standard_False),
extDrawBuffers (Standard_False),
extGS (NULL),
|| CheckExtension ("GL_ARB_texture_float");
hasTexFloatLinear = arbTexFloat;
arbSampleShading = CheckExtension ("GL_ARB_sample_shading");
+ arbDepthClamp = IsGlGreaterEqual (3, 2)
+ || CheckExtension ("GL_ARB_depth_clamp")
+ || CheckExtension ("NV_depth_clamp");
extBgra = IsGlGreaterEqual (1, 2)
|| CheckExtension ("GL_EXT_bgra");
extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
OpenGl_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object
OpenGl_ArbFBOBlit* arbFBOBlit; //!< glBlitFramebuffer function, moved out from OpenGl_ArbFBO structure for compatibility with OpenGL ES 2.0
Standard_Boolean arbSampleShading; //!< GL_ARB_sample_shading
+ Standard_Boolean arbDepthClamp; //!< GL_ARB_depth_clamp (on desktop OpenGL - since 3.2 or as extensions GL_ARB_depth_clamp,NV_depth_clamp; unavailable on OpenGL ES)
Standard_Boolean extFragDepth; //!< GL_EXT_frag_depth on OpenGL ES 2.0 (gl_FragDepthEXT built-in variable, before OpenGL ES 3.0)
Standard_Boolean extDrawBuffers; //!< GL_EXT_draw_buffers
OpenGl_ExtGS* extGS; //!< GL_EXT_geometry_shader4
EOL"{"
EOL" ViewDirection = cubemapVectorTransform (occVertex.xyz, uYCoeff, uZCoeff);"
EOL" vec4 aPos = occProjectionMatrix * occWorldViewMatrix * vec4(occVertex.xyz, 1.0);"
+ // setting Z to W ensures that final Z will be 1.0 after perspective division, (w/w=1))
+ // which allows rendering skybox after everything else with depth test enabled (GL_LEQUAL)
EOL" gl_Position = aPos.xyww;"
EOL"}";
- TCollection_AsciiString aSrcFrag =
- EOL"#define occEnvCubemap occSampler0"
+ TCollection_AsciiString aDepthClamp;
+ if (!myContext->arbDepthClamp)
+ {
+ // workaround Z clamping issues on some GPUs
+ aDepthClamp = EOL" gl_FragDepth = clamp (gl_FragDepth, 0.0, 1.0);";
+ #if defined(GL_ES_VERSION_2_0)
+ if (myContext->IsGlGreaterEqual (3, 0))
+ {
+ myBgCubeMapProgram->SetHeader ("#version 300 es");
+ }
+ else if (myContext->extFragDepth)
+ {
+ myBgCubeMapProgram->SetHeader ("#extension GL_EXT_frag_depth : enable"
+ EOL"#define gl_FragDepth gl_FragDepthEXT");
+ }
+ else
+ {
+ aDepthClamp.Clear();
+ }
+ #endif
+ }
+
+ TCollection_AsciiString aSrcFrag = TCollection_AsciiString()
+ + EOL"#define occEnvCubemap occSampler0"
EOL"void main()"
EOL"{"
EOL" occSetFragColor (vec4(occTextureCube (occEnvCubemap, ViewDirection).rgb, 1.0));"
- EOL"}";
+ + aDepthClamp
+ + EOL"}";
defaultGlslVersion (myBgCubeMapProgram, "background_cubemap", 0);
myBgCubeMapProgram->SetDefaultSampler (false);
Graphic3d_Camera::Projection theProjection)
{
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- const Standard_Boolean wasUsedZBuffer = theWorkspace->SetUseZBuffer (Standard_False);
+ const bool wasUsedZBuffer = theWorkspace->SetUseZBuffer (false);
if (wasUsedZBuffer)
{
aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
}
+#ifdef GL_DEPTH_CLAMP
+ const bool wasDepthClamped = aCtx->arbDepthClamp && glIsEnabled (GL_DEPTH_CLAMP);
+ if (aCtx->arbDepthClamp && !wasDepthClamped)
+ {
+ // make sure background is always drawn (workaround skybox rendering on some hardware)
+ aCtx->core11fwd->glEnable (GL_DEPTH_CLAMP);
+ }
+#endif
+
if (myBackgroundType == Graphic3d_TOB_CUBEMAP)
{
myCubeMapParams->Aspect()->ShaderProgram()->PushVariableInt ("uZCoeff", myBackgroundCubeMap->ZIsInverted() ? -1 : 1);
theWorkspace->SetUseZBuffer (Standard_True);
aCtx->core11fwd->glEnable (GL_DEPTH_TEST);
}
+#ifdef GL_DEPTH_CLAMP
+ if (aCtx->arbDepthClamp && !wasDepthClamped)
+ {
+ aCtx->core11fwd->glDisable (GL_DEPTH_CLAMP);
+ }
+#endif
}
//=======================================================================