mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-24 13:50:49 +03:00
0024381: Visualization, TKOpenGl - revise matrices stack and usage of temporary matrices
0025301: Visualization, TKOpenGl - transpose matrix manually before glUniformMatrix4fv() OpenGl_View::ReleaseGlResources() - release GL resources of trihedron, do not destroy it
This commit is contained in:
@@ -69,9 +69,10 @@ struct OPENGL_CLIP_PLANE
|
||||
/*
|
||||
* Set des lumieres
|
||||
*/
|
||||
static void bind_light (const OpenGl_Light& theLight,
|
||||
GLenum& theLightGlId,
|
||||
Graphic3d_Vec4& theAmbientColor)
|
||||
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)
|
||||
@@ -86,14 +87,16 @@ static void bind_light (const OpenGl_Light& theLight,
|
||||
return;
|
||||
}
|
||||
|
||||
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
|
||||
|
||||
// the light is a headlight?
|
||||
GLint aMatrixModeOld = 0;
|
||||
if (theLight.IsHeadlight)
|
||||
{
|
||||
glGetIntegerv (GL_MATRIX_MODE, &aMatrixModeOld);
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
aContext->WorldViewState.Push();
|
||||
aContext->WorldViewState.SetIdentity();
|
||||
|
||||
aContext->ApplyWorldViewMatrix();
|
||||
}
|
||||
|
||||
// setup light type
|
||||
@@ -148,8 +151,7 @@ static void bind_light (const OpenGl_Light& theLight,
|
||||
// restore matrix in case of headlight
|
||||
if (theLight.IsHeadlight)
|
||||
{
|
||||
glPopMatrix();
|
||||
glMatrixMode (aMatrixModeOld);
|
||||
aContext->WorldViewState.Pop();
|
||||
}
|
||||
|
||||
glEnable (theLightGlId++);
|
||||
@@ -169,12 +171,16 @@ void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
|
||||
|
||||
glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
const Handle(OpenGl_Context)& aContext = theWorkspace.GetGlContext();
|
||||
|
||||
aContext->WorldViewState.Push();
|
||||
aContext->ProjectionState.Push();
|
||||
|
||||
aContext->WorldViewState.SetIdentity();
|
||||
aContext->ProjectionState.SetIdentity();
|
||||
|
||||
aContext->ApplyProjectionMatrix();
|
||||
aContext->ApplyWorldViewMatrix();
|
||||
|
||||
if ( glIsEnabled( GL_DEPTH_TEST ) )
|
||||
glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
|
||||
@@ -335,10 +341,10 @@ void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPopMatrix();
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
aContext->WorldViewState.Pop();
|
||||
aContext->ProjectionState.Pop();
|
||||
|
||||
aContext->ApplyProjectionMatrix();
|
||||
|
||||
glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
|
||||
|
||||
@@ -388,6 +394,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
|
||||
Standard_Boolean isProjectionMatUpdateNeeded = Standard_False;
|
||||
Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
|
||||
if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
|
||||
@@ -401,7 +408,12 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
|
||||
}
|
||||
|
||||
// Set OCCT state uniform variables
|
||||
if (isProjectionMatUpdateNeeded
|
||||
|| isOrientationMatUpdateNeeded)
|
||||
{
|
||||
myBVHSelector.SetViewVolume (myCamera);
|
||||
}
|
||||
|
||||
const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
|
||||
const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed
|
||||
if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
|
||||
@@ -414,30 +426,21 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
|| !isSameView)
|
||||
{
|
||||
myProjectionState = myCamera->ProjectionState();
|
||||
aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
|
||||
aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
|
||||
aContext->ApplyProjectionMatrix();
|
||||
}
|
||||
|
||||
if (myModelViewState != myCamera->ModelViewState()
|
||||
|| !isSameView)
|
||||
{
|
||||
myModelViewState = myCamera->ModelViewState();
|
||||
aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
|
||||
aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF());
|
||||
aContext->ApplyWorldViewMatrix();
|
||||
}
|
||||
|
||||
if (aManager->ModelWorldState().Index() == 0)
|
||||
{
|
||||
Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
|
||||
{ 0.f, 1.f, 0.f, 0.f },
|
||||
{ 0.f, 0.f, 1.f, 0.f },
|
||||
{ 0.f, 0.f, 0.f, 1.f } };
|
||||
|
||||
aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorldState);
|
||||
}
|
||||
|
||||
if (isProjectionMatUpdateNeeded
|
||||
|| isOrientationMatUpdateNeeded)
|
||||
{
|
||||
myBVHSelector.SetViewVolume (myCamera);
|
||||
aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
|
||||
}
|
||||
|
||||
// ====================================
|
||||
@@ -459,7 +462,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
// Step 3: Draw underlayer
|
||||
// =================================
|
||||
|
||||
RedrawLayer2d (thePrintContext, theCView, theCUnderLayer);
|
||||
RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer);
|
||||
|
||||
// =================================
|
||||
// Step 4: Redraw main plane
|
||||
@@ -548,25 +551,21 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
|
||||
{
|
||||
// single-pass monographic rendering
|
||||
const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
|
||||
|
||||
const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
|
||||
|
||||
// redraw scene with normal orientation and projection
|
||||
RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
|
||||
RedrawScene (thePrintContext, theWorkspace);
|
||||
}
|
||||
else
|
||||
{
|
||||
// two stereographic passes
|
||||
const OpenGl_Matrix* aLProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
|
||||
const OpenGl_Matrix* aRProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
|
||||
const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
|
||||
|
||||
// safely switch to left Eye buffer
|
||||
aContext->SetDrawBufferLeft();
|
||||
|
||||
aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
|
||||
aContext->ApplyProjectionMatrix();
|
||||
|
||||
// redraw left Eye
|
||||
RedrawScene (thePrintContext, theWorkspace, aLProj, aOrient);
|
||||
RedrawScene (thePrintContext, theWorkspace);
|
||||
|
||||
// reset depth buffer of first rendering pass
|
||||
if (theWorkspace->UseDepthTest())
|
||||
@@ -576,8 +575,11 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
// safely switch to right Eye buffer
|
||||
aContext->SetDrawBufferRight();
|
||||
|
||||
aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
|
||||
aContext->ApplyProjectionMatrix();
|
||||
|
||||
// redraw right Eye
|
||||
RedrawScene (thePrintContext, theWorkspace, aRProj, aOrient);
|
||||
RedrawScene (thePrintContext, theWorkspace);
|
||||
|
||||
// switch back to monographic rendering
|
||||
aContext->SetDrawBufferMono();
|
||||
@@ -631,7 +633,7 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
const int aMode = 0;
|
||||
theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
|
||||
|
||||
RedrawLayer2d (thePrintContext, theCView, theCOverLayer);
|
||||
RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
|
||||
|
||||
theWorkspace->DisplayCallback (theCView, aMode);
|
||||
|
||||
@@ -728,6 +730,7 @@ void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
|
||||
|
||||
//call_togl_redraw_layer2d
|
||||
void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
const Graphic3d_CView& ACView,
|
||||
const Aspect_CLayer2d& ACLayer)
|
||||
{
|
||||
@@ -736,16 +739,19 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
|
||||
|| ACLayer.ptrLayer == NULL
|
||||
|| ACLayer.ptrLayer->listIndex == 0) return;
|
||||
|
||||
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
|
||||
|
||||
GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
|
||||
GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPushMatrix ();
|
||||
glLoadIdentity ();
|
||||
aContext->WorldViewState.Push();
|
||||
aContext->ProjectionState.Push();
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPushMatrix ();
|
||||
glLoadIdentity ();
|
||||
aContext->WorldViewState.SetIdentity();
|
||||
aContext->ProjectionState.SetIdentity();
|
||||
|
||||
aContext->ApplyWorldViewMatrix();
|
||||
aContext->ApplyProjectionMatrix();
|
||||
|
||||
if (!ACLayer.sizeDependent)
|
||||
glViewport (0, 0, dispWidth, dispHeight);
|
||||
@@ -809,7 +815,10 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
|
||||
// tiling; scaling of graphics by matrix helps render a
|
||||
// part of a view (frame) in same viewport, but with higher
|
||||
// resolution
|
||||
thePrintContext->LoadProjTransformation();
|
||||
|
||||
// set printing scale/tiling transformation
|
||||
aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
|
||||
aContext->ApplyProjectionMatrix();
|
||||
|
||||
// printing operation also assumes other viewport dimension
|
||||
// to comply with transformation matrix or graphics scaling
|
||||
@@ -846,11 +855,11 @@ void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintCo
|
||||
|
||||
glPopAttrib ();
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix ();
|
||||
aContext->WorldViewState.Pop();
|
||||
aContext->ProjectionState.Pop();
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glPopMatrix ();
|
||||
aContext->ApplyProjectionMatrix();
|
||||
aContext->ApplyWorldViewMatrix();
|
||||
|
||||
if (!ACLayer.sizeDependent)
|
||||
glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
|
||||
@@ -1111,9 +1120,7 @@ void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
|
||||
//=======================================================================
|
||||
|
||||
void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
|
||||
const Handle(OpenGl_Workspace)& theWorkspace,
|
||||
const OpenGl_Matrix* theProjection,
|
||||
const OpenGl_Matrix* theOrientation)
|
||||
const Handle(OpenGl_Workspace)& theWorkspace)
|
||||
{
|
||||
const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
|
||||
|
||||
@@ -1165,37 +1172,16 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
// Setup view projection
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
|
||||
#ifdef _WIN32
|
||||
// add printing scale/tiling transformation
|
||||
// set printing scale/tiling transformation
|
||||
if (!thePrintContext.IsNull())
|
||||
{
|
||||
thePrintContext->LoadProjTransformation();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
glLoadIdentity();
|
||||
|
||||
glMultMatrixf ((const GLfloat*)theProjection);
|
||||
|
||||
if (!thePrintContext.IsNull())
|
||||
{
|
||||
// update shader uniform projection matrix with new data
|
||||
Tmatrix3 aResultProjection;
|
||||
glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
|
||||
aContext->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
|
||||
|
||||
// force shader uniform restore on next frame
|
||||
myProjectionState = 0;
|
||||
aContext->ProjectionState.Push();
|
||||
aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
|
||||
aContext->ApplyProjectionMatrix();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Setup view orientation
|
||||
theWorkspace->SetViewMatrix (theOrientation);
|
||||
|
||||
// Specify clipping planes in view transformation space
|
||||
if (!myClipPlanes.IsEmpty())
|
||||
{
|
||||
@@ -1233,7 +1219,7 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
|
||||
for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
|
||||
aLightIt.More(); aLightIt.Next())
|
||||
{
|
||||
bind_light (aLightIt.Value(), aLightGlId, anAmbientColor);
|
||||
bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
|
||||
}
|
||||
|
||||
// apply accumulated ambient color
|
||||
@@ -1325,4 +1311,17 @@ void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintCont
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply restored view matrix.
|
||||
aContext->ApplyWorldViewMatrix();
|
||||
|
||||
#ifdef _WIN32
|
||||
// set printing scale/tiling transformation
|
||||
if (!thePrintContext.IsNull())
|
||||
{
|
||||
aContext->ProjectionState.Pop();
|
||||
aContext->ApplyProjectionMatrix();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user