#include <stdlib.h>
#include <OpenGl_GlCore11.hxx>
-#include <OpenGl_tgl_funcs.hxx>
#include <Graphic3d_GraphicDriver.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <OpenGl_Matrix.hxx>
#include <OpenGl_Workspace.hxx>
#include <OpenGl_View.hxx>
-#include <OpenGl_Trihedron.hxx>
#include <OpenGl_GraduatedTrihedron.hxx>
#include <OpenGl_PrimitiveArray.hxx>
-#include <OpenGl_PrinterContext.hxx>
#include <OpenGl_ShaderManager.hxx>
#include <OpenGl_ShaderProgram.hxx>
#include <OpenGl_Structure.hxx>
#include <OpenGl_ArbFBO.hxx>
-#define EPSI 0.0001
-
-namespace
-{
- static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
- static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
- static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
- static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
-}
-
-extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
-
-#if !defined(GL_ES_VERSION_2_0)
-
-//=======================================================================
-//function : bindLight
-//purpose :
-//=======================================================================
-static void bindLight (const OpenGl_Light& theLight,
- GLenum& theLightGlId,
- Graphic3d_Vec4& theAmbientColor,
- const Handle(OpenGl_Workspace)& theWorkspace)
-{
- // Only 8 lights in OpenGL...
- if (theLightGlId > GL_LIGHT7)
- {
- return;
- }
-
- if (theLight.Type == Graphic3d_TOLS_AMBIENT)
- {
- // add RGBA intensity of the ambient light
- theAmbientColor += theLight.Color;
- return;
- }
-
- const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
-
- // the light is a headlight?
- if (theLight.IsHeadlight)
- {
- aContext->WorldViewState.Push();
- aContext->WorldViewState.SetIdentity();
-
- aContext->ApplyWorldViewMatrix();
- }
-
- // setup light type
- switch (theLight.Type)
- {
- case Graphic3d_TOLS_AMBIENT : break; // handled by separate if-clause at beginning of method
- case Graphic3d_TOLS_DIRECTIONAL:
- {
- // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
- const OpenGl_Vec4 anInfDir = -theLight.Direction;
-
- // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
- glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
- glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
- glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
- glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
- glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
- glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
- glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
- break;
- }
- case Graphic3d_TOLS_POSITIONAL:
- {
- // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
- glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
- glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
- glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
- glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
- glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
- glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
- glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
- glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
- glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
- glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
- break;
- }
- case Graphic3d_TOLS_SPOT:
- {
- glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
- glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
- glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
- glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
- glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
- glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
- glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
- glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
- glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
- glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
- break;
- }
- }
-
- // restore matrix in case of headlight
- if (theLight.IsHeadlight)
- {
- aContext->WorldViewState.Pop();
- }
-
- glEnable (theLightGlId++);
-}
-#endif
-
//=======================================================================
//function : drawBackground
//purpose :
{
const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
- if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background
- || (!myBgTextureArray->IsDefined() // no texture
- && !myBgGradientArray->IsDefined())) // no gradient
+ if (!myBgTextureArray->IsDefined() // no texture
+ && !myBgGradientArray->IsDefined()) // no gradient
{
return;
}
aCtx->core11fwd->glDisable (GL_DEPTH_TEST);
}
- aCtx->ProjectionState.Push();
- aCtx->WorldViewState.Push();
- aCtx->ModelWorldState.Push();
- aCtx->ProjectionState.SetIdentity();
- aCtx->WorldViewState.SetIdentity();
- aCtx->ModelWorldState.SetIdentity();
- aCtx->ApplyProjectionMatrix();
- aCtx->ApplyModelViewMatrix();
-
// Drawing background gradient if:
// - gradient fill type is not Aspect_GFM_NONE and
// - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
if (myBgGradientArray->IsDefined()
- && (!myTextureParams->DoTextureMap()
+ && (!myTextureParams->Aspect()->ToMapTexture()
|| myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED
|| myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE))
{
}
#endif
- if (myBgGradientArray->IsDataChanged())
- {
- myBgGradientArray->Init (theWorkspace);
- }
-
myBgGradientArray->Render (theWorkspace);
#if !defined(GL_ES_VERSION_2_0)
// Drawing background image if it is defined
// (texture is defined and fill type is not Aspect_FM_NONE)
if (myBgTextureArray->IsDefined()
- && myTextureParams->DoTextureMap())
+ && myTextureParams->Aspect()->ToMapTexture())
{
aCtx->core11fwd->glDisable (GL_BLEND);
const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams);
-
- if (myBgTextureArray->IsDataChanged()
- || myBgTextureArray->IsViewSizeChanged (theWorkspace))
- {
- myBgTextureArray->Init (theWorkspace);
- }
-
myBgTextureArray->Render (theWorkspace);
-
- // restore aspects
theWorkspace->SetAspectFace (anOldAspectFace);
}
- aCtx->ModelWorldState.Pop();
- aCtx->WorldViewState.Pop();
- aCtx->ProjectionState.Pop();
- aCtx->ApplyProjectionMatrix();
- aCtx->ApplyModelViewMatrix();
-
if (wasUsedZBuffer)
{
theWorkspace->SetUseZBuffer (Standard_True);
//=======================================================================
void OpenGl_View::Redraw()
{
+ const Standard_Boolean wasDisabledMSAA = myToDisableMSAA;
+ const Standard_Boolean hadFboBlit = myHasFboBlit;
if (myRenderParams.Method == Graphic3d_RM_RAYTRACING
&& !myCaps->vboDisable
&& !myCaps->keepArrayData)
myWindow->SetSwapInterval();
++myFrameCounter;
- const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode;
- Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType();
- Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
+ const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode;
+ Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType();
+ Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
// release pending GL resources
aCtx->ReleaseDelayed();
// fetch OpenGl context state
aCtx->FetchState();
- OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )myFBO;
+ OpenGl_FrameBuffer* aFrameBuffer = myFBO.operator->();
bool toSwap = aCtx->IsRender()
&& !aCtx->caps->buffersNoSwap
&& aFrameBuffer == NULL;
Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWindow->Width();
Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myWindow->Height();
+ Standard_Integer aRendSizeX = Standard_Integer(myRenderParams.RenderResolutionScale * aSizeX + 0.5f);
+ Standard_Integer aRendSizeY = Standard_Integer(myRenderParams.RenderResolutionScale * aSizeY + 0.5f);
// determine multisampling parameters
- Standard_Integer aNbSamples = Max (Min (myRenderParams.NbMsaaSamples, aCtx->MaxMsaaSamples()), 0);
+ Standard_Integer aNbSamples = !myToDisableMSAA && aSizeX == aRendSizeX
+ ? Max (Min (myRenderParams.NbMsaaSamples, aCtx->MaxMsaaSamples()), 0)
+ : 0;
if (aNbSamples != 0)
{
aNbSamples = OpenGl_Context::GetPowerOfTwo (aNbSamples, aCtx->MaxMsaaSamples());
}
+ bool toUseOit = myRenderParams.TransparencyMethod == Graphic3d_RTM_BLEND_OIT
+ && checkOitCompatibility (aCtx, aNbSamples > 0);
+
+ const bool toInitImmediateFbo = myTransientDrawToFront
+ && (!aCtx->caps->useSystemBuffer || (toUseOit && HasImmediateStructures()));
+
if ( aFrameBuffer == NULL
&& !aCtx->DefaultFrameBuffer().IsNull()
&& aCtx->DefaultFrameBuffer()->IsValid())
if (myHasFboBlit
&& (myTransientDrawToFront
|| aProjectType == Graphic3d_Camera::Projection_Stereo
- || aNbSamples != 0))
+ || aNbSamples != 0
+ || toUseOit
+ || aSizeX != aRendSizeX))
{
- if (myMainSceneFbos[0]->GetVPSizeX() != aSizeX
- || myMainSceneFbos[0]->GetVPSizeY() != aSizeY
+ if (myMainSceneFbos[0]->GetVPSizeX() != aRendSizeX
+ || myMainSceneFbos[0]->GetVPSizeY() != aRendSizeY
|| myMainSceneFbos[0]->NbSamples() != aNbSamples)
{
+ if (!myTransientDrawToFront)
+ {
+ myImmediateSceneFbos[0]->Release (aCtx.operator->());
+ myImmediateSceneFbos[1]->Release (aCtx.operator->());
+ myImmediateSceneFbos[0]->ChangeViewport (0, 0);
+ myImmediateSceneFbos[1]->ChangeViewport (0, 0);
+ }
+
// prepare FBOs containing main scene
// for further blitting and rendering immediate presentations on top
if (aCtx->core20fwd != NULL)
{
- myMainSceneFbos[0]->Init (aCtx, aSizeX, aSizeY, myFboColorFormat, myFboDepthFormat, aNbSamples);
- }
- if (!aCtx->caps->useSystemBuffer && myMainSceneFbos[0]->IsValid())
- {
- myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]);
+ myMainSceneFbos[0]->Init (aCtx, aRendSizeX, aRendSizeY, myFboColorFormat, myFboDepthFormat, aNbSamples);
}
}
+ if (myMainSceneFbos[0]->IsValid() && (toInitImmediateFbo || myImmediateSceneFbos[0]->IsValid()))
+ {
+ myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]);
+ }
}
else
{
}
}
+ // create color and coverage accumulation buffers required for OIT algorithm
+ if (toUseOit)
+ {
+ Standard_Integer anFboIt = 0;
+ for (; anFboIt < 2; ++anFboIt)
+ {
+ Handle(OpenGl_FrameBuffer)& aMainSceneFbo = myMainSceneFbos [anFboIt];
+ Handle(OpenGl_FrameBuffer)& aMainSceneFboOit = myMainSceneFbosOit [anFboIt];
+ Handle(OpenGl_FrameBuffer)& anImmediateSceneFbo = myImmediateSceneFbos [anFboIt];
+ Handle(OpenGl_FrameBuffer)& anImmediateSceneFboOit = myImmediateSceneFbosOit[anFboIt];
+ if (aMainSceneFbo->IsValid()
+ && (aMainSceneFboOit->GetVPSizeX() != aRendSizeX
+ || aMainSceneFboOit->GetVPSizeY() != aRendSizeY
+ || aMainSceneFboOit->NbSamples() != aNbSamples))
+ {
+ Standard_Integer aColorConfig = 0;
+ for (;;) // seemly responding to driver limitation (GL_FRAMEBUFFER_UNSUPPORTED)
+ {
+ if (myFboOitColorConfig.IsEmpty())
+ {
+ if (!chooseOitColorConfiguration (aCtx, aColorConfig++, myFboOitColorConfig))
+ {
+ break;
+ }
+ }
+ if (aMainSceneFboOit->Init (aCtx, aRendSizeX, aRendSizeY, myFboOitColorConfig, aMainSceneFbo->DepthStencilTexture(), aNbSamples))
+ {
+ break;
+ }
+ myFboOitColorConfig.Clear();
+ }
+ if (!aMainSceneFboOit->IsValid())
+ {
+ break;
+ }
+ }
+ else if (!aMainSceneFbo->IsValid())
+ {
+ aMainSceneFboOit->Release (aCtx.operator->());
+ aMainSceneFboOit->ChangeViewport (0, 0);
+ }
+
+ if (anImmediateSceneFbo->IsValid()
+ && (anImmediateSceneFboOit->GetVPSizeX() != aRendSizeX
+ || anImmediateSceneFboOit->GetVPSizeY() != aRendSizeY
+ || anImmediateSceneFboOit->NbSamples() != aNbSamples))
+ {
+ if (!anImmediateSceneFboOit->Init (aCtx, aRendSizeX, aRendSizeY, myFboOitColorConfig,
+ anImmediateSceneFbo->DepthStencilTexture(), aNbSamples))
+ {
+ break;
+ }
+ }
+ else if (!anImmediateSceneFbo->IsValid())
+ {
+ anImmediateSceneFboOit->Release (aCtx.operator->());
+ anImmediateSceneFboOit->ChangeViewport (0, 0);
+ }
+ }
+ if (anFboIt == 0) // only the first OIT framebuffer is mandatory
+ {
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ "Initialization of float texture framebuffer for use with\n"
+ " blended order-independent transparency rendering algorithm has failed.\n"
+ " Blended order-independent transparency will not be available.\n");
+ if (aNbSamples > 0)
+ {
+ myToDisableOITMSAA = Standard_True;
+ }
+ else
+ {
+ myToDisableOIT = Standard_True;
+ }
+ toUseOit = false;
+ }
+ }
+ if (!toUseOit && myMainSceneFbosOit[0]->IsValid())
+ {
+ myMainSceneFbosOit [0]->Release (aCtx.operator->());
+ myMainSceneFbosOit [1]->Release (aCtx.operator->());
+ myImmediateSceneFbosOit[0]->Release (aCtx.operator->());
+ myImmediateSceneFbosOit[1]->Release (aCtx.operator->());
+ myMainSceneFbosOit [0]->ChangeViewport (0, 0);
+ myMainSceneFbosOit [1]->ChangeViewport (0, 0);
+ myImmediateSceneFbosOit[0]->ChangeViewport (0, 0);
+ myImmediateSceneFbosOit[1]->ChangeViewport (0, 0);
+ }
+
if (aProjectType == Graphic3d_Camera::Projection_Stereo)
{
OpenGl_FrameBuffer* aMainFbos[2] =
myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL,
myMainSceneFbos[1]->IsValid() ? myMainSceneFbos[1].operator->() : NULL
};
+ OpenGl_FrameBuffer* aMainFbosOit[2] =
+ {
+ myMainSceneFbosOit[0]->IsValid() ? myMainSceneFbosOit[0].operator->() : NULL,
+ myMainSceneFbosOit[1]->IsValid() ? myMainSceneFbosOit[1].operator->() :
+ myMainSceneFbosOit[0]->IsValid() ? myMainSceneFbosOit[0].operator->() : NULL
+ };
+
OpenGl_FrameBuffer* anImmFbos[2] =
{
myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
};
+ OpenGl_FrameBuffer* anImmFbosOit[2] =
+ {
+ myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL,
+ myImmediateSceneFbosOit[1]->IsValid() ? myImmediateSceneFbosOit[1].operator->() :
+ myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL
+ };
if (!myTransientDrawToFront)
{
- anImmFbos[0] = aMainFbos[0];
- anImmFbos[1] = aMainFbos[1];
+ anImmFbos [0] = aMainFbos [0];
+ anImmFbos [1] = aMainFbos [1];
+ anImmFbosOit[0] = aMainFbosOit[0];
+ anImmFbosOit[1] = aMainFbosOit[1];
}
else if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
|| aStereoMode == Graphic3d_StereoMode_QuadBuffer)
{
- anImmFbos[0] = NULL;
- anImmFbos[1] = NULL;
+ anImmFbos [0] = NULL;
+ anImmFbos [1] = NULL;
+ anImmFbosOit[0] = NULL;
+ anImmFbosOit[1] = NULL;
}
#if !defined(GL_ES_VERSION_2_0)
aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
#endif
- redraw (Graphic3d_Camera::Projection_MonoLeftEye, aMainFbos[0]);
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ aMainFbos[0] != NULL ? myRenderParams.RenderResolutionScale : 1.0f);
+
+ redraw (Graphic3d_Camera::Projection_MonoLeftEye, aMainFbos[0], aMainFbosOit[0]);
myBackBufferRestored = Standard_True;
myIsImmediateDrawn = Standard_False;
#if !defined(GL_ES_VERSION_2_0)
aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
#endif
- if (!redrawImmediate (Graphic3d_Camera::Projection_MonoLeftEye, aMainFbos[0], anImmFbos[0]))
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ anImmFbos[0] != NULL ? myRenderParams.RenderResolutionScale : 1.0f);
+ if (!redrawImmediate (Graphic3d_Camera::Projection_MonoLeftEye, aMainFbos[0], anImmFbos[0], anImmFbosOit[0]))
{
toSwap = false;
}
#if !defined(GL_ES_VERSION_2_0)
aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK);
#endif
- redraw (Graphic3d_Camera::Projection_MonoRightEye, aMainFbos[1]);
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ aMainFbos[1] != NULL ? myRenderParams.RenderResolutionScale : 1.0f);
+
+ redraw (Graphic3d_Camera::Projection_MonoRightEye, aMainFbos[1], aMainFbosOit[1]);
myBackBufferRestored = Standard_True;
myIsImmediateDrawn = Standard_False;
- if (!redrawImmediate (Graphic3d_Camera::Projection_MonoRightEye, aMainFbos[1], anImmFbos[1]))
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ anImmFbos[1] != NULL ? myRenderParams.RenderResolutionScale : 1.0f);
+ if (!redrawImmediate (Graphic3d_Camera::Projection_MonoRightEye, aMainFbos[1], anImmFbos[1], anImmFbosOit[1]))
{
toSwap = false;
}
if (anImmFbos[0] != NULL)
{
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(), 1.0f);
drawStereoPair (aFrameBuffer);
}
}
else
{
- OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
- OpenGl_FrameBuffer* anImmFbo = aFrameBuffer;
- if (!aCtx->caps->useSystemBuffer && myImmediateSceneFbos[0]->IsValid())
+ OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : aFrameBuffer;
+ OpenGl_FrameBuffer* aMainFboOit = myMainSceneFbosOit[0]->IsValid() ? myMainSceneFbosOit[0].operator->() : NULL;
+ OpenGl_FrameBuffer* anImmFbo = aFrameBuffer;
+ OpenGl_FrameBuffer* anImmFboOit = NULL;
+ if (!myTransientDrawToFront)
+ {
+ anImmFbo = aMainFbo;
+ anImmFboOit = aMainFboOit;
+ }
+ else if (myImmediateSceneFbos[0]->IsValid())
{
- anImmFbo = myImmediateSceneFbos[0].operator->();
+ anImmFbo = myImmediateSceneFbos[0].operator->();
+ anImmFboOit = myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL;
}
#if !defined(GL_ES_VERSION_2_0)
- if (aMainFbo == NULL
- && aFrameBuffer == NULL)
+ if (aMainFbo == NULL)
{
aCtx->SetReadDrawBuffer (GL_BACK);
}
#endif
- redraw (aProjectType, aMainFbo != NULL ? aMainFbo : aFrameBuffer);
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ aMainFbo != aFrameBuffer ? myRenderParams.RenderResolutionScale : 1.0f);
+
+ redraw (aProjectType, aMainFbo, aMainFboOit);
myBackBufferRestored = Standard_True;
myIsImmediateDrawn = Standard_False;
- if (!redrawImmediate (aProjectType, aMainFbo, anImmFbo))
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ anImmFbo != aFrameBuffer ? myRenderParams.RenderResolutionScale : 1.0f);
+ if (!redrawImmediate (aProjectType, aMainFbo, anImmFbo, anImmFboOit))
{
toSwap = false;
}
}
}
-#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
- if (OpenGl_AVIWriter_AllowWriting (myWindow->PlatformWindow()->NativeHandle()))
- {
- GLint params[4];
- glGetIntegerv (GL_VIEWPORT, params);
- int nWidth = params[2] & ~0x7;
- int nHeight = params[3] & ~0x7;
-
- const int nBitsPerPixel = 24;
- GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8];
-
- glPixelStorei (GL_PACK_ALIGNMENT, 1);
- glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData);
- OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel);
- delete[] aDumpData;
- }
-#endif
-
if (myRenderParams.Method == Graphic3d_RM_RAYTRACING
&& myRenderParams.IsGlobalIlluminationEnabled)
{
// bind default FBO
bindDefaultFbo();
+ if (wasDisabledMSAA != myToDisableMSAA
+ || hadFboBlit != myHasFboBlit)
+ {
+ // retry on error
+ Redraw();
+ }
+
+ // reset state for safety
+ aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
+ aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
+
// Swap the buffers
if (toSwap)
{
const Graphic3d_StereoMode aStereoMode = myRenderParams.StereoMode;
Graphic3d_Camera::Projection aProjectType = myCamera->ProjectionType();
- OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )myFBO;
+ OpenGl_FrameBuffer* aFrameBuffer = myFBO.operator->();
if ( aFrameBuffer == NULL
&& !aCtx->DefaultFrameBuffer().IsNull()
myImmediateSceneFbos[0]->IsValid() ? myImmediateSceneFbos[0].operator->() : NULL,
myImmediateSceneFbos[1]->IsValid() ? myImmediateSceneFbos[1].operator->() : NULL
};
+ OpenGl_FrameBuffer* anImmFbosOit[2] =
+ {
+ myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL,
+ myImmediateSceneFbosOit[1]->IsValid() ? myImmediateSceneFbosOit[1].operator->() :
+ myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL
+ };
if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
|| aStereoMode == Graphic3d_StereoMode_QuadBuffer)
{
- anImmFbos[0] = NULL;
- anImmFbos[1] = NULL;
+ anImmFbos[0] = NULL;
+ anImmFbos[1] = NULL;
+ anImmFbosOit[0] = NULL;
+ anImmFbosOit[1] = NULL;
}
if (aCtx->arbFBO != NULL)
aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_LEFT : GL_BACK);
}
#endif
+
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ anImmFbos[0] != NULL ? myRenderParams.RenderResolutionScale : 1.0f);
toSwap = redrawImmediate (Graphic3d_Camera::Projection_MonoLeftEye,
aMainFbos[0],
anImmFbos[0],
+ anImmFbosOit[0],
Standard_True) || toSwap;
if (aStereoMode == Graphic3d_StereoMode_SoftPageFlip
&& toSwap
aCtx->SetReadDrawBuffer (aStereoMode == Graphic3d_StereoMode_QuadBuffer ? GL_BACK_RIGHT : GL_BACK);
}
#endif
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ anImmFbos[1] != NULL ? myRenderParams.RenderResolutionScale : 1.0f);
toSwap = redrawImmediate (Graphic3d_Camera::Projection_MonoRightEye,
aMainFbos[1],
anImmFbos[1],
+ anImmFbosOit[1],
Standard_True) || toSwap;
if (anImmFbos[0] != NULL)
{
{
OpenGl_FrameBuffer* aMainFbo = myMainSceneFbos[0]->IsValid() ? myMainSceneFbos[0].operator->() : NULL;
OpenGl_FrameBuffer* anImmFbo = aFrameBuffer;
- if (!aCtx->caps->useSystemBuffer && myImmediateSceneFbos[0]->IsValid())
+ OpenGl_FrameBuffer* anImmFboOit = NULL;
+ if (myImmediateSceneFbos[0]->IsValid())
{
- anImmFbo = myImmediateSceneFbos[0].operator->();
+ anImmFbo = myImmediateSceneFbos[0].operator->();
+ anImmFboOit = myImmediateSceneFbosOit[0]->IsValid() ? myImmediateSceneFbosOit[0].operator->() : NULL;
}
#if !defined(GL_ES_VERSION_2_0)
if (aMainFbo == NULL)
aCtx->SetReadDrawBuffer (GL_BACK);
}
#endif
+ aCtx->SetResolution (myRenderParams.Resolution, myRenderParams.ResolutionRatio(),
+ anImmFbo != aFrameBuffer ? myRenderParams.RenderResolutionScale : 1.0f);
toSwap = redrawImmediate (aProjectType,
aMainFbo,
anImmFbo,
+ anImmFboOit,
Standard_True) || toSwap;
if (anImmFbo != NULL
&& anImmFbo != aFrameBuffer)
// bind default FBO
bindDefaultFbo();
+ // reset state for safety
+ aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
+ aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
+
if (toSwap && !aCtx->caps->buffersNoSwap)
{
aCtx->SwapBuffers();
// function : redraw
// purpose :
// =======================================================================
-void OpenGl_View::redraw (const Graphic3d_Camera::Projection theProjection, OpenGl_FrameBuffer* theReadDrawFbo)
+void OpenGl_View::redraw (const Graphic3d_Camera::Projection theProjection,
+ OpenGl_FrameBuffer* theReadDrawFbo,
+ OpenGl_FrameBuffer* theOitAccumFbo)
{
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
if (theReadDrawFbo != NULL)
}
else
{
- aCtx->core11fwd->glViewport (0, 0, myWindow->Width(), myWindow->Height());
+ const Standard_Integer aViewport[4] = { 0, 0, myWindow->Width(), myWindow->Height() };
+ aCtx->ResizeViewport (aViewport);
}
// request reset of material
- myWorkspace->NamedStatus |= OPENGL_NS_RESMAT;
+ aCtx->ShaderManager()->UpdateMaterialState();
+
myWorkspace->UseZBuffer() = Standard_True;
myWorkspace->UseDepthWrite() = Standard_True;
GLbitfield toClear = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
glClearDepthf (1.0f);
#endif
- if (myWorkspace->NamedStatus & OPENGL_NS_WHITEBACK)
- {
- // set background to white
- glClearColor (1.0f, 1.0f, 1.0f, 1.0f);
- }
- else
- {
- glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f);
- }
+ const OpenGl_Vec4& aBgColor = myBgColor;
+ glClearColor (aBgColor.r(), aBgColor.g(), aBgColor.b(), 0.0f);
glClear (toClear);
- render (theProjection, theReadDrawFbo, Standard_False);
+ render (theProjection, theReadDrawFbo, theOitAccumFbo, Standard_False);
}
// =======================================================================
// purpose :
// =======================================================================
bool OpenGl_View::redrawImmediate (const Graphic3d_Camera::Projection theProjection,
- OpenGl_FrameBuffer* theReadFbo,
- OpenGl_FrameBuffer* theDrawFbo,
- const Standard_Boolean theIsPartialUpdate)
+ OpenGl_FrameBuffer* theReadFbo,
+ OpenGl_FrameBuffer* theDrawFbo,
+ OpenGl_FrameBuffer* theOitAccumFbo,
+ const Standard_Boolean theIsPartialUpdate)
{
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
GLboolean toCopyBackToFront = GL_FALSE;
- if (!myTransientDrawToFront)
+ if (theDrawFbo == theReadFbo
+ && theDrawFbo != NULL)
{
myBackBufferRestored = Standard_False;
}
glClearDepthf (1.0f);
#endif
- render (theProjection, theDrawFbo, Standard_True);
+ render (theProjection, theDrawFbo, theOitAccumFbo, Standard_True);
return !toCopyBackToFront;
}
//=======================================================================
void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
OpenGl_FrameBuffer* theOutputFBO,
+ OpenGl_FrameBuffer* theOitAccumFbo,
const Standard_Boolean theToDrawImmediate)
{
// ==================================
// Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
myBVHSelector.SetViewVolume (myCamera);
+ myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height());
const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
{
- aManager->UpdateLightSourceStateTo (myShadingModel == Graphic3d_TOSM_NONE ? &OpenGl_NoShadingLight() : &myLights);
+ aManager->UpdateLightSourceStateTo (myShadingModel == Graphic3d_TOSM_NONE ? &myNoShadingLight : &myLights);
myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
}
// Update matrices if camera has changed.
Graphic3d_WorldViewProjState aWVPState = myCamera->WorldViewProjState();
- const Standard_Boolean isCameraChanged = myWorldViewProjState != aWVPState;
- const Standard_Boolean isSameView = aManager->IsSameView (this);
- if (isCameraChanged)
+ if (myWorldViewProjState != aWVPState)
{
- aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
- aContext->WorldViewState .SetCurrent (myCamera->OrientationMatrixF());
myAccumFrames = 0;
+ myWorldViewProjState = aWVPState;
}
- // Apply new matrix state if camera has changed or this view differs from the one
- // that was previously used for configuring matrices of shader manager
- // (ApplyProjectionMatrix and ApplyWorldViewMatrix will affect the manager).
- if (isCameraChanged || !isSameView)
- {
- aContext->ApplyProjectionMatrix();
- aContext->ApplyWorldViewMatrix();
- }
-
+ myLocalOrigin.SetCoord (0.0, 0.0, 0.0);
+ aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
+ aContext->WorldViewState .SetCurrent (myCamera->OrientationMatrixF());
+ aContext->ApplyProjectionMatrix();
+ aContext->ApplyWorldViewMatrix();
if (aManager->ModelWorldState().Index() == 0)
{
aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
}
- myWorldViewProjState = aWVPState;
-
// ====================================
// Step 2: Redraw background
// ====================================
aContext->SetGlNormalizeEnabled (Standard_False);
}
- // Apply Fog
- if (myFog.IsOn
- && aContext->core11 != NULL)
- {
- Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
- if (myCamera->ZFar() < aFogFrontConverted)
- {
- aFogFrontConverted = myCamera->ZFar();
- myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
- }
-
- Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
- if (myCamera->ZFar() < aFogFrontConverted)
- {
- aFogBackConverted = myCamera->ZFar();
- myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
- }
-
- if (aFogFrontConverted > aFogBackConverted)
- {
- myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
- myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
- }
-
- glFogi(GL_FOG_MODE, GL_LINEAR);
- glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
- glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
- glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
- glEnable(GL_FOG);
- }
- else if (aContext->core11 != NULL)
- {
- glDisable (GL_FOG);
- }
-
// Apply InteriorShadingMethod
if (aContext->core11 != NULL)
{
aManager->SetShadingModel (myShadingModel);
- // Apply AntiAliasing
- if (myAntiAliasing)
- myWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
- else
- myWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
-
- if (!aManager->IsEmpty())
- {
- aManager->UpdateClippingState();
- }
-
// Redraw 3d scene
if (theProjection == Graphic3d_Camera::Projection_MonoLeftEye)
{
aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
aContext->ApplyProjectionMatrix();
}
- renderScene (theProjection, theOutputFBO, theToDrawImmediate);
+
+ myWorkspace->SetEnvironmentTexture (myTextureEnv);
+
+ renderScene (theProjection, theOutputFBO, theOitAccumFbo, theToDrawImmediate);
+
+ myWorkspace->SetEnvironmentTexture (Handle(OpenGl_Texture)());
// ===============================
// Step 4: Trihedron
// before drawing auxiliary stuff (trihedrons, overlayer)
myWorkspace->ResetAppliedAspect();
- aContext->ChangeClipping().RemoveAll (aContext);
-
- if (!aManager->IsEmpty())
- {
- aManager->ResetMaterialStates();
- aManager->RevertClippingState();
-
- // We need to disable (unbind) all shaders programs to ensure
- // that all objects without specified aspect will be drawn
- // correctly (such as background)
- aContext->BindProgram (NULL);
- }
-
// Render trihedron
if (!theToDrawImmediate)
{
}
}
+ // reset FFP state for safety
+ aContext->BindProgram (Handle(OpenGl_ShaderProgram)());
+ aContext->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
+
// ==============================================================
// Step 6: Keep shader manager informed about last View
// ==============================================================
//=======================================================================
void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
OpenGl_FrameBuffer* theReadDrawFbo,
+ OpenGl_FrameBuffer* theOitAccumFbo,
const Standard_Boolean theToDrawImmediate)
{
if ( myZLayers.NbStructures() <= 0 )
return;
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
- if ( (myWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
- {
- #if !defined(GL_ES_VERSION_2_0)
- const int anAntiAliasingMode = myWorkspace->AntiAliasingMode();
- #endif
-
- if ( !myAntiAliasing )
- {
- #if !defined(GL_ES_VERSION_2_0)
- if (aCtx->core11 != NULL)
- {
- glDisable (GL_POINT_SMOOTH);
- }
- glDisable(GL_LINE_SMOOTH);
- if( anAntiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
- #endif
- glBlendFunc (GL_ONE, GL_ZERO);
- glDisable (GL_BLEND);
- }
- else
- {
- #if !defined(GL_ES_VERSION_2_0)
- if (aCtx->core11 != NULL)
- {
- glEnable(GL_POINT_SMOOTH);
- }
- glEnable(GL_LINE_SMOOTH);
- if( anAntiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
- #endif
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- }
- }
-
Standard_Boolean toRenderGL = theToDrawImmediate ||
myRenderParams.Method != Graphic3d_RM_RAYTRACING ||
myRaytraceInitStatus == OpenGl_RT_FAIL ||
if (aCtx->arbFBOBlit != NULL)
{
// Render bottom OSD layer
- myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom);
+ myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom, theReadDrawFbo, theOitAccumFbo);
myWorkspace->SetRenderFilter (myRaytraceFilter);
{
if (theReadDrawFbo != NULL)
{
- theReadDrawFbo->BindReadBuffer (aCtx);
+ theReadDrawFbo->BindDrawBuffer (aCtx);
}
else
{
- aCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
+ aCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);
}
- myOpenGlFBO->BindDrawBuffer (aCtx);
-
- aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aSizeX, aSizeY,
- 0, 0, aSizeX, aSizeY,
- GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
- GL_NEAREST);
-
// Render non-polygonal elements in default layer
- myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Default);
+ myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Default, theReadDrawFbo, theOitAccumFbo);
}
myWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
}
aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, 0);
}
+ // Reset OpenGl aspects state to default to avoid enabling of
+ // backface culling which is not supported in ray-tracing.
+ myWorkspace->ResetAppliedAspect();
+
// Ray-tracing polygonal primitive arrays
raytrace (aSizeX, aSizeY, theProjection, theReadDrawFbo, aCtx);
// Render upper (top and topmost) OpenGL layers
- myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Upper);
+ myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Upper, theReadDrawFbo, theOitAccumFbo);
}
}
// mode or in case of ray-tracing failure
if (toRenderGL)
{
- myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_All);
+ myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_All, theReadDrawFbo, theOitAccumFbo);
// Set flag that scene was redrawn by standard pipeline
myWasRedrawnGL = Standard_True;
//=======================================================================
void OpenGl_View::renderTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
{
- // display global trihedron
- if (myToShowTrihedron)
- {
- myTrihedron.Render (theWorkspace);
- }
if (myToShowGradTrihedron)
{
myGraduatedTrihedron.Render (theWorkspace);
//=======================================================================
void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection,
OpenGl_FrameBuffer* theReadDrawFbo,
+ OpenGl_FrameBuffer* theOitAccumFbo,
const Standard_Boolean theToDrawImmediate)
{
const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext();
- if (myZClip.Back.IsOn || myZClip.Front.IsOn)
- {
- Handle(Graphic3d_ClipPlane) aPlaneBack;
- Handle(Graphic3d_ClipPlane) aPlaneFront;
-
- if (myZClip.Back.IsOn)
- {
- Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
- if (myCamera->ZFar() < aClipBackConverted)
- {
- aClipBackConverted = myCamera->ZFar();
- myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
- }
- const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
- aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
- }
-
- if (myZClip.Front.IsOn)
- {
- Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
- if (myCamera->ZNear() > aClipFrontConverted)
- {
- aClipFrontConverted = myCamera->ZNear();
- myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
- }
- const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
- aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
- }
-
- // Specify slicing planes with identity transformation
- if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
- {
- Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
- if (!aPlaneBack.IsNull())
- {
- aSlicingPlanes.Append (aPlaneBack);
- }
-
- if (!aPlaneFront.IsNull())
- {
- aSlicingPlanes.Append (aPlaneFront);
- }
-
- // add planes at loaded view matrix state
- aContext->ChangeClipping().AddView (aContext, aSlicingPlanes);
- }
- }
-
-#ifdef _WIN32
- // set printing scale/tiling transformation
- Handle(OpenGl_PrinterContext) aPrintContext = myWorkspace->PrinterContext();
- if (!aPrintContext.IsNull())
- {
- aContext->ProjectionState.Push();
- aContext->ProjectionState.SetCurrent (aPrintContext->ProjTransformation() * aContext->ProjectionState.Current());
- aContext->ApplyProjectionMatrix();
- }
-#endif
-
// Specify clipping planes in view transformation space
- if (!myClipPlanes.IsEmpty())
+ aContext->ChangeClipping().Reset (aContext, myClipPlanes);
+ if (!myClipPlanes.IsNull()
+ && !myClipPlanes->IsEmpty())
{
- Graphic3d_SequenceOfHClipPlane aUserPlanes;
- Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
- for (; aClippingIt.More(); aClippingIt.Next())
- {
- const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
- if (aClipPlane->IsOn())
- {
- aUserPlanes.Append (aClipPlane);
- }
- }
-
- if (!aUserPlanes.IsEmpty())
- {
- aContext->ChangeClipping().AddWorldLazy (aContext, aUserPlanes);
- }
-
- if (!aContext->ShaderManager()->IsEmpty())
- {
- aContext->ShaderManager()->UpdateClippingState();
- }
- }
-
-#if !defined(GL_ES_VERSION_2_0)
- // Apply Lights
- if (aContext->core11 != NULL)
- {
- // setup lights
- Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
- THE_DEFAULT_AMBIENT[1],
- THE_DEFAULT_AMBIENT[2],
- THE_DEFAULT_AMBIENT[3]);
- GLenum aLightGlId = GL_LIGHT0;
-
- OpenGl_ListOfLight::Iterator aLightIt (myShadingModel == Graphic3d_TOSM_NONE ? OpenGl_NoShadingLight() : myLights);
- for (; aLightIt.More(); aLightIt.Next())
- {
- bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, myWorkspace);
- }
-
- // apply accumulated ambient color
- anAmbientColor.a() = 1.0f;
- glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
-
- if (aLightGlId != GL_LIGHT0)
- {
- glEnable (GL_LIGHTING);
- }
- // switch off unused lights
- for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
- {
- glDisable (aLightGlId);
- }
+ aContext->ShaderManager()->UpdateClippingState();
}
-#endif
-
- // Clear status bitfields
- myWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
-
- // Update state of surface detail level
- myWorkspace->GetGlContext()->ShaderManager()->UpdateSurfaceDetailStateTo (mySurfaceDetail);
-
- // Added PCT for handling of textures
- switch (mySurfaceDetail)
- {
- case Graphic3d_TOD_NONE:
- myWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
- myWorkspace->DisableTexture();
- // Render the view
- renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
- break;
- case Graphic3d_TOD_ENVIRONMENT:
- myWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
- if (myRenderParams.Method != Graphic3d_RM_RAYTRACING)
- {
- myWorkspace->EnableTexture (myTextureEnv);
- }
- // Render the view
- renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
- myWorkspace->DisableTexture();
- break;
-
- case Graphic3d_TOD_ALL:
- // First pass
- myWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
- // Render the view
- renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
- myWorkspace->DisableTexture();
-
- // Second pass
- if (myWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
- {
- myWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
- if (myRenderParams.Method != Graphic3d_RM_RAYTRACING)
- {
- myWorkspace->EnableTexture (myTextureEnv);
- }
-
- // Remember OpenGl properties
- GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
- GLint aSaveZbuffFunc;
- GLboolean aSaveZbuffWrite;
- glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
- glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
- #if !defined(GL_ES_VERSION_2_0)
- glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
- glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
- #endif
- GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
- GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
-
- // Change the properties for second rendering pass
- glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
-
- glDepthFunc (GL_EQUAL);
- glDepthMask (GL_FALSE);
- glEnable (GL_DEPTH_TEST);
-
- myWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
-
- // Render the view
- renderStructs (theProjection, theReadDrawFbo, theToDrawImmediate);
- myWorkspace->DisableTexture();
-
- // Restore properties back
- glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
- if (!wasBlendEnabled)
- glDisable (GL_BLEND);
-
- glDepthFunc (aSaveZbuffFunc);
- glDepthMask (aSaveZbuffWrite);
- if (!wasZbuffEnabled)
- glDisable (GL_DEPTH_FUNC);
- }
- break;
- }
+ renderStructs (theProjection, theReadDrawFbo, theOitAccumFbo, theToDrawImmediate);
+ myWorkspace->DisableTexture();
// Apply restored view matrix.
aContext->ApplyWorldViewMatrix();
-#ifdef _WIN32
- // set printing scale/tiling transformation
- if (!aPrintContext.IsNull())
+ aContext->ChangeClipping().Reset (aContext, Handle(Graphic3d_SequenceOfHClipPlane)());
+ if (!myClipPlanes.IsNull()
+ && !myClipPlanes->IsEmpty())
{
- aContext->ProjectionState.Pop();
- aContext->ApplyProjectionMatrix();
+ aContext->ShaderManager()->RevertClippingState();
}
-#endif
}
// =======================================================================
if (anFbo != NULL)
{
anFbo->BindBuffer (aCtx);
+ anFbo->SetupViewport (aCtx);
}
else
{
aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
}
#endif
+ const Standard_Integer aViewport[4] = { 0, 0, myWindow->Width(), myWindow->Height() };
+ aCtx->ResizeViewport (aViewport);
}
- aCtx->core11fwd->glViewport (0, 0, myWindow->Width(), myWindow->Height());
}
// =======================================================================
const Standard_Boolean theToFlip)
{
Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
+ const Standard_Integer aReadSizeX = theReadFbo != NULL ? theReadFbo->GetVPSizeX() : myWindow->Width();
+ const Standard_Integer aReadSizeY = theReadFbo != NULL ? theReadFbo->GetVPSizeY() : myWindow->Height();
+ const Standard_Integer aDrawSizeX = theDrawFbo != NULL ? theDrawFbo->GetVPSizeX() : myWindow->Width();
+ const Standard_Integer aDrawSizeY = theDrawFbo != NULL ? theDrawFbo->GetVPSizeY() : myWindow->Height();
if (theReadFbo == NULL || aCtx->IsFeedback())
{
return false;
{
aCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
}
+ const Standard_Integer aViewport[4] = { 0, 0, aDrawSizeX, aDrawSizeY };
+ aCtx->ResizeViewport (aViewport);
+
#if !defined(GL_ES_VERSION_2_0)
aCtx->core20fwd->glClearDepth (1.0);
#else
#endif
aCtx->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-#if !defined(GL_ES_VERSION_2_0)
if (aCtx->arbFBOBlit != NULL
&& theReadFbo->NbSamples() != 0)
{
}
// we don't copy stencil buffer here... does it matter for performance?
- aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
- 0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
+ aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, aReadSizeX, aReadSizeY,
+ 0, 0, aDrawSizeX, aDrawSizeY,
aCopyMask, GL_NEAREST);
+ const int anErr = ::glGetError();
+ if (anErr != GL_NO_ERROR)
+ {
+ // glBlitFramebuffer() might fail in several cases:
+ // - Both FBOs have MSAA and they are samples number does not match.
+ // OCCT checks that this does not happen,
+ // however some graphics drivers provide an option for overriding MSAA.
+ // In this case window MSAA might be non-zero (and application can not check it)
+ // and might not match MSAA of our offscreen FBOs.
+ // - Pixel formats of FBOs do not match.
+ // This also might happen with window has pixel format,
+ // e.g. Mesa fails blitting RGBA8 -> RGB8 while other drivers support this conversion.
+ TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "FBO blitting has failed [Error #" + anErr + "]\n"
+ + " Please check your graphics driver settings or try updating driver.";
+ if (theReadFbo->NbSamples() != 0)
+ {
+ myToDisableMSAA = true;
+ aMsg += "\n MSAA settings should not be overridden by driver!";
+ }
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
+ 0,
+ GL_DEBUG_SEVERITY_HIGH,
+ aMsg);
+ }
+
if (theDrawFbo != NULL
&& theDrawFbo->IsValid())
{
}
}
else
-#endif
{
aCtx->core20fwd->glDepthFunc (GL_ALWAYS);
aCtx->core20fwd->glDepthMask (GL_TRUE);
aCtx->core20fwd->glEnable (GL_DEPTH_TEST);
+ #if defined(GL_ES_VERSION_2_0)
+ if (!aCtx->IsGlGreaterEqual (3, 0)
+ && !aCtx->extFragDepth)
+ {
+ aCtx->core20fwd->glDisable (GL_DEPTH_TEST);
+ }
+ #endif
myWorkspace->DisableTexture();
+ const Graphic3d_TypeOfTextureFilter aFilter = (aDrawSizeX == aReadSizeX && aDrawSizeY == aReadSizeY) ? Graphic3d_TOTF_NEAREST : Graphic3d_TOTF_BILINEAR;
+ const GLint aFilterGl = aFilter == Graphic3d_TOTF_NEAREST ? GL_NEAREST : GL_LINEAR;
+
OpenGl_VertexBuffer* aVerts = initBlitQuad (theToFlip);
const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
if (aVerts->IsValid()
&& aManager->BindFboBlitProgram())
{
- theReadFbo->ColorTexture() ->Bind (aCtx, GL_TEXTURE0 + 0);
- theReadFbo->DepthStencilTexture()->Bind (aCtx, GL_TEXTURE0 + 1);
+ theReadFbo->ColorTexture()->Bind (aCtx, GL_TEXTURE0 + 0);
+ if (theReadFbo->ColorTexture()->GetParams()->Filter() != aFilter)
+ {
+ theReadFbo->ColorTexture()->GetParams()->SetFilter (aFilter);
+ aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterGl);
+ aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilterGl);
+ }
+
+ theReadFbo->DepthStencilTexture()->Bind (aCtx, GL_TEXTURE0 + 1);
+ if (theReadFbo->DepthStencilTexture()->GetParams()->Filter() != aFilter)
+ {
+ theReadFbo->DepthStencilTexture()->GetParams()->SetFilter (aFilter);
+ aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterGl);
+ aCtx->core20fwd->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilterGl);
+ }
+
aVerts->BindVertexAttrib (aCtx, Graphic3d_TOA_POS);
aCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
{
TCollection_ExtendedString aMsg = TCollection_ExtendedString()
+ "Error! FBO blitting has failed";
- aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
+ GL_DEBUG_SEVERITY_HIGH,
aMsg);
myHasFboBlit = Standard_False;
theReadFbo->Release (aCtx.operator->());
if (!myOpenGlFBO ->InitLazy (aCtx, aPair[0]->GetVPSizeX(), aPair[0]->GetVPSizeY(), myFboColorFormat, myFboDepthFormat, 0)
|| !myOpenGlFBO2->InitLazy (aCtx, aPair[0]->GetVPSizeX(), aPair[0]->GetVPSizeY(), myFboColorFormat, 0, 0))
{
- aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
+ GL_DEBUG_SEVERITY_HIGH,
"Error! Unable to allocate FBO for blitting stereo pair");
bindDefaultFbo (theDrawFbo);
return;
{
TCollection_ExtendedString aMsg = TCollection_ExtendedString()
+ "Error! Anaglyph has failed";
- aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
- GL_DEBUG_TYPE_ERROR_ARB,
+ aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
0,
- GL_DEBUG_SEVERITY_HIGH_ARB,
+ GL_DEBUG_SEVERITY_HIGH,
aMsg);
}
}
OpenGl_Mat4 aProjectMat;
Graphic3d_TransformUtils::Ortho2D (aProjectMat,
- 0.f, static_cast<GLfloat> (myWindow->Width()), 0.f, static_cast<GLfloat> (myWindow->Height()));
+ 0.0f, static_cast<GLfloat> (myWindow->Width()),
+ 0.0f, static_cast<GLfloat> (myWindow->Height()));
+
+ const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
- Handle(OpenGl_Context) aCtx = myWorkspace->GetGlContext();
aCtx->WorldViewState.Push();
aCtx->ProjectionState.Push();
aCtx->ApplyProjectionMatrix();
aCtx->ApplyWorldViewMatrix();
+ // synchronize FFP state before copying pixels
+ aCtx->BindProgram (Handle(OpenGl_ShaderProgram)());
+ aCtx->ShaderManager()->PushState (Handle(OpenGl_ShaderProgram)());
aCtx->DisableFeatures();
switch (aCtx->DrawBuffer())
#endif
myIsImmediateDrawn = Standard_False;
}
+
+// =======================================================================
+// function : checkOitCompatibility
+// purpose :
+// =======================================================================
+Standard_Boolean OpenGl_View::checkOitCompatibility (const Handle(OpenGl_Context)& theGlContext,
+ const Standard_Boolean theMSAA)
+{
+ // determine if OIT is supported by current OpenGl context
+ Standard_Boolean& aToDisableOIT = theMSAA ? myToDisableMSAA : myToDisableOIT;
+ if (aToDisableOIT)
+ {
+ return Standard_False;
+ }
+
+ TCollection_ExtendedString aCompatibilityMsg;
+ if (!theGlContext->hasFloatBuffer
+ && !theGlContext->hasHalfFloatBuffer)
+ {
+ aCompatibilityMsg += "OpenGL context does not support floating-point RGBA color buffer format.\n";
+ }
+ if (theMSAA && !theGlContext->hasSampleVariables)
+ {
+ aCompatibilityMsg += "Current version of GLSL does not support built-in sample variables.\n";
+ }
+ if (!theGlContext->hasDrawBuffers)
+ {
+ aCompatibilityMsg += "OpenGL context does not support multiple draw buffers.\n";
+ }
+ if (aCompatibilityMsg.IsEmpty())
+ {
+ return Standard_True;
+ }
+
+ aCompatibilityMsg += " Blended order-independent transparency will not be available.\n";
+ theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+ GL_DEBUG_TYPE_ERROR,
+ 0,
+ GL_DEBUG_SEVERITY_HIGH,
+ aCompatibilityMsg);
+
+ aToDisableOIT = Standard_True;
+ return Standard_False;
+}
+
+// =======================================================================
+// function : chooseOitColorConfiguration
+// purpose :
+// =======================================================================
+bool OpenGl_View::chooseOitColorConfiguration (const Handle(OpenGl_Context)& theGlContext,
+ const Standard_Integer theConfigIndex,
+ OpenGl_ColorFormats& theFormats)
+{
+ theFormats.Clear();
+ switch (theConfigIndex)
+ {
+ case 0: // choose best applicable color format combination
+ {
+ theFormats.Append (theGlContext->hasHalfFloatBuffer ? GL_RGBA16F : GL_RGBA32F);
+ theFormats.Append (theGlContext->hasHalfFloatBuffer ? GL_R16F : GL_R32F);
+ return true;
+ }
+ case 1: // choose non-optimal applicable color format combination
+ {
+ theFormats.Append (theGlContext->hasHalfFloatBuffer ? GL_RGBA16F : GL_RGBA32F);
+ theFormats.Append (theGlContext->hasHalfFloatBuffer ? GL_RGBA16F : GL_RGBA32F);
+ return true;
+ }
+ }
+ return false; // color combination does not exist
+}