1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
19 #include <OpenGl_GlCore11.hxx>
20 #include <OpenGl_tgl_funcs.hxx>
22 #include <Image_AlienPixMap.hxx>
23 #include <Visual3d_Layer.hxx>
25 #include <NCollection_Mat4.hxx>
27 #include <OpenGl_AspectLine.hxx>
28 #include <OpenGl_Context.hxx>
29 #include <OpenGl_Matrix.hxx>
30 #include <OpenGl_Workspace.hxx>
31 #include <OpenGl_View.hxx>
32 #include <OpenGl_Trihedron.hxx>
33 #include <OpenGl_GraduatedTrihedron.hxx>
34 #include <OpenGl_PrinterContext.hxx>
35 #include <OpenGl_ShaderManager.hxx>
36 #include <OpenGl_ShaderProgram.hxx>
37 #include <OpenGl_Structure.hxx>
44 static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
45 static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
46 static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
47 static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
51 extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
53 /*----------------------------------------------------------------------*/
55 struct OPENGL_CLIP_PLANE
62 /*----------------------------------------------------------------------*/
67 /*-----------------------------------------------------------------*/
71 static void bind_light (const OpenGl_Light& theLight,
73 Graphic3d_Vec4& theAmbientColor)
75 // Only 8 lights in OpenGL...
76 if (theLightGlId > GL_LIGHT7)
81 if (theLight.Type == Visual3d_TOLS_AMBIENT)
83 // add RGBA intensity of the ambient light
84 theAmbientColor += theLight.Color;
88 // the light is a headlight?
89 GLint aMatrixModeOld = 0;
90 if (theLight.IsHeadlight)
92 glGetIntegerv (GL_MATRIX_MODE, &aMatrixModeOld);
93 glMatrixMode (GL_MODELVIEW);
99 switch (theLight.Type)
101 case Visual3d_TOLS_DIRECTIONAL:
103 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
104 const OpenGl_Vec4 anInfDir = -theLight.Direction;
106 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
107 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
108 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
109 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
110 glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
111 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
112 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
113 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
116 case Visual3d_TOLS_POSITIONAL:
118 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
119 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
120 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
121 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
122 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
123 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
124 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
125 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
126 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
127 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
128 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
131 case Visual3d_TOLS_SPOT:
133 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
134 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
135 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
136 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
137 glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
138 glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
139 glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
140 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
141 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
142 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
147 // restore matrix in case of headlight
148 if (theLight.IsHeadlight)
151 glMatrixMode (aMatrixModeOld);
154 glEnable (theLightGlId++);
157 /*----------------------------------------------------------------------*/
159 void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
161 if ( (theWorkspace.NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
162 ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
164 const Standard_Integer aViewWidth = theWorkspace.Width();
165 const Standard_Integer aViewHeight = theWorkspace.Height();
167 glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
169 glMatrixMode( GL_PROJECTION );
172 glMatrixMode( GL_MODELVIEW );
176 if ( glIsEnabled( GL_DEPTH_TEST ) )
177 glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
179 // drawing bg gradient if:
180 // - gradient fill type is not Aspect_GFM_NONE and
181 // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
182 if ( ( myBgGradient.type != Aspect_GFM_NONE ) &&
183 ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
184 myBgTexture.Style == Aspect_FM_NONE ) )
186 Tfloat* corner1 = 0;/* -1,-1*/
187 Tfloat* corner2 = 0;/* 1,-1*/
188 Tfloat* corner3 = 0;/* 1, 1*/
189 Tfloat* corner4 = 0;/* -1, 1*/
193 switch( myBgGradient.type )
196 corner1 = myBgGradient.color1.rgb;
197 corner2 = myBgGradient.color2.rgb;
198 corner3 = myBgGradient.color2.rgb;
199 corner4 = myBgGradient.color1.rgb;
202 corner1 = myBgGradient.color2.rgb;
203 corner2 = myBgGradient.color2.rgb;
204 corner3 = myBgGradient.color1.rgb;
205 corner4 = myBgGradient.color1.rgb;
207 case Aspect_GFM_DIAG1:
208 corner2 = myBgGradient.color2.rgb;
209 corner4 = myBgGradient.color1.rgb;
210 dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
211 dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
212 dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
216 case Aspect_GFM_DIAG2:
217 corner1 = myBgGradient.color2.rgb;
218 corner3 = myBgGradient.color1.rgb;
219 dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
220 dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
221 dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
225 case Aspect_GFM_CORNER1:
226 corner1 = myBgGradient.color2.rgb;
227 corner2 = myBgGradient.color2.rgb;
228 corner3 = myBgGradient.color2.rgb;
229 corner4 = myBgGradient.color1.rgb;
231 case Aspect_GFM_CORNER2:
232 corner1 = myBgGradient.color2.rgb;
233 corner2 = myBgGradient.color2.rgb;
234 corner3 = myBgGradient.color1.rgb;
235 corner4 = myBgGradient.color2.rgb;
237 case Aspect_GFM_CORNER3:
238 corner1 = myBgGradient.color2.rgb;
239 corner2 = myBgGradient.color1.rgb;
240 corner3 = myBgGradient.color2.rgb;
241 corner4 = myBgGradient.color2.rgb;
243 case Aspect_GFM_CORNER4:
244 corner1 = myBgGradient.color1.rgb;
245 corner2 = myBgGradient.color2.rgb;
246 corner3 = myBgGradient.color2.rgb;
247 corner4 = myBgGradient.color2.rgb;
250 //printf("gradient background type not right\n");
254 // Save GL parameters
255 glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
258 glGetIntegerv( GL_SHADE_MODEL, &curSM );
259 if ( curSM != GL_SMOOTH )
260 glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
262 glBegin(GL_TRIANGLE_FAN);
263 if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
265 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
266 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
267 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
268 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
270 else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
272 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
273 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
274 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
275 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
279 // Restore GL parameters
280 if ( curSM != GL_SMOOTH )
281 glShadeModel( curSM );
283 // drawing bg image if:
284 // - it is defined and
285 // - fill type is not Aspect_FM_NONE
286 if ( myBgTexture.TexId != 0 && myBgTexture.Style != Aspect_FM_NONE )
288 GLfloat texX_range = 1.F; // texture <s> coordinate
289 GLfloat texY_range = 1.F; // texture <t> coordinate
291 // Set up for stretching or tiling
292 GLfloat x_offset, y_offset;
293 if ( myBgTexture.Style == Aspect_FM_CENTERED )
295 x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
296 y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
302 if ( myBgTexture.Style == Aspect_FM_TILED )
304 texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
305 texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
309 // OCCT issue 0023000: Improve the way the gradient and textured
310 // background is managed in 3d viewer (note 0020339)
311 // Setting this coefficient to -1.F allows to tile textures relatively
312 // to the top-left corner of the view (value 1.F corresponds to the
313 // initial behaviour - tiling from the bottom-left corner)
314 GLfloat aCoef = -1.F;
316 glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
317 glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
319 glDisable( GL_BLEND ); //push GL_ENABLE_BIT
321 glColor3fv (theWorkspace.BackgroundColor().rgb);
322 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
324 // Note that texture is mapped using GL_REPEAT wrapping mode so integer part
325 // is simply ignored, and negative multiplier is here for convenience only
326 // and does not result e.g. in texture mirroring
328 glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -aCoef * y_offset );
329 glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -aCoef * y_offset );
330 glTexCoord2f(texX_range, aCoef * texY_range); glVertex2f( x_offset, aCoef * y_offset );
331 glTexCoord2f(0.F, aCoef * texY_range); glVertex2f( -x_offset, aCoef * y_offset );
336 glMatrixMode( GL_PROJECTION );
338 glMatrixMode( GL_MODELVIEW );
340 glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
342 if (theWorkspace.UseZBuffer())
344 glEnable (GL_DEPTH_TEST);
349 /*----------------------------------------------------------------------*/
351 //call_func_redraw_all_structs_proc
352 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
353 const Handle(OpenGl_Workspace) &theWorkspace,
354 const Graphic3d_CView& theCView,
355 const Aspect_CLayer2d& theCUnderLayer,
356 const Aspect_CLayer2d& theCOverLayer)
358 // ==================================
359 // Step 1: Prepare for redraw
360 // ==================================
362 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
364 // Store and disable current clipping planes
365 Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
367 OPENGL_CLIP_PLANE *aOldPlanes = new OPENGL_CLIP_PLANE[aMaxPlanes];
368 OPENGL_CLIP_PLANE *aPtrPlane = aOldPlanes;
370 GLenum aClipPlaneId = GL_CLIP_PLANE0;
371 const GLenum aClipLastId = GL_CLIP_PLANE0 + aMaxPlanes;
372 for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
374 glGetClipPlane (aClipPlaneId, aPtrPlane->Equation);
375 if (aPtrPlane->isEnabled)
377 glDisable (aClipPlaneId);
378 aPtrPlane->isEnabled = GL_TRUE;
382 aPtrPlane->isEnabled = GL_FALSE;
386 Standard_Boolean isProjectionMatUpdateNeeded = Standard_False;
387 Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
388 if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
390 isProjectionMatUpdateNeeded = Standard_True;
391 myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
393 if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
395 isOrientationMatUpdateNeeded = Standard_True;
396 myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
399 // Set OCCT state uniform variables
400 const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
401 if (!aManager->IsEmpty())
403 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
405 aManager->UpdateLightSourceStateTo (&myLights);
406 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
409 if (myProjectionState != myCamera->ProjectionState())
411 myProjectionState = myCamera->ProjectionState();
412 aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
415 if (myModelViewState != myCamera->ModelViewState())
417 myModelViewState = myCamera->ModelViewState();
418 aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
421 if (aManager->ModelWorldState().Index() == 0)
423 Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
424 { 0.f, 1.f, 0.f, 0.f },
425 { 0.f, 0.f, 1.f, 0.f },
426 { 0.f, 0.f, 0.f, 1.f } };
428 aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorldState);
432 if (!aManager.IsNull())
434 if (!aManager->IsSameView (this))
436 // Force update camera states
437 myProjectionState = myCamera->ProjectionState();
438 aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
440 myModelViewState = myCamera->ModelViewState();
441 aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
445 if (isProjectionMatUpdateNeeded
446 || isOrientationMatUpdateNeeded)
448 myBVHSelector.SetViewVolume (myCamera);
451 // ====================================
452 // Step 2: Redraw background
453 // ====================================
456 DrawBackground (*theWorkspace);
458 // Switch off lighting by default
459 glDisable(GL_LIGHTING);
461 // =================================
462 // Step 3: Draw underlayer
463 // =================================
465 RedrawLayer2d (thePrintContext, theCView, theCUnderLayer);
467 // =================================
468 // Step 4: Redraw main plane
469 // =================================
471 // Setup face culling
472 GLboolean isCullFace = GL_FALSE;
475 isCullFace = glIsEnabled( GL_CULL_FACE );
476 if ( myBackfacing < 0 )
478 glEnable( GL_CULL_FACE );
479 glCullFace( GL_BACK );
482 glDisable( GL_CULL_FACE );
485 // if the view is scaled normal vectors are scaled to unit
486 // length for correct displaying of shaded objects
487 const gp_Pnt anAxialScale = myCamera->AxialScale();
488 if(anAxialScale.X() != 1.F ||
489 anAxialScale.Y() != 1.F ||
490 anAxialScale.Z() != 1.F)
491 glEnable(GL_NORMALIZE);
492 else if(glIsEnabled(GL_NORMALIZE))
493 glDisable(GL_NORMALIZE);
498 Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
499 if (myCamera->ZFar() < aFogFrontConverted)
501 aFogFrontConverted = myCamera->ZFar();
502 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
505 Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
506 if (myCamera->ZFar() < aFogFrontConverted)
508 aFogBackConverted = myCamera->ZFar();
509 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
512 if (aFogFrontConverted > aFogBackConverted)
514 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
515 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
518 glFogi(GL_FOG_MODE, GL_LINEAR);
519 glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
520 glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
521 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
527 // Apply InteriorShadingMethod
528 glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
530 // Apply AntiAliasing
532 theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
534 theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
536 if (!aManager->IsEmpty())
538 aManager->UpdateClippingState();
542 if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
544 // single-pass monographic rendering
545 const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
547 const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
549 // redraw scene with normal orientation and projection
550 RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
554 // two stereographic passes
555 const OpenGl_Matrix* aLProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
556 const OpenGl_Matrix* aRProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
557 const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
559 // safely switch to left Eye buffer
560 aContext->SetDrawBufferLeft();
563 RedrawScene (thePrintContext, theWorkspace, aLProj, aOrient);
565 // reset depth buffer of first rendering pass
566 if (theWorkspace->UseDepthTest())
568 glClear (GL_DEPTH_BUFFER_BIT);
570 // safely switch to right Eye buffer
571 aContext->SetDrawBufferRight();
574 RedrawScene (thePrintContext, theWorkspace, aRProj, aOrient);
576 // switch back to monographic rendering
577 aContext->SetDrawBufferMono();
580 // ===============================
582 // ===============================
584 // Resetting GL parameters according to the default aspects
585 // in order to synchronize GL state with the graphic driver state
586 // before drawing auxiliary stuff (trihedrons, overlayer)
587 // and invoking optional callbacks
588 theWorkspace->ResetAppliedAspect();
590 aContext->ChangeClipping().RemoveAll();
592 if (!aManager->IsEmpty())
594 aManager->ResetMaterialStates();
595 aManager->RevertClippingState();
597 // We need to disable (unbind) all shaders programs to ensure
598 // that all objects without specified aspect will be drawn
599 // correctly (such as background)
600 OpenGl_ShaderProgram::Unbind (aContext);
603 // display global trihedron
604 if (myTrihedron != NULL)
606 myTrihedron->Render (theWorkspace);
608 if (myGraduatedTrihedron != NULL)
610 myGraduatedTrihedron->Render (theWorkspace);
613 // Restore face culling
618 glEnable ( GL_CULL_FACE );
619 glCullFace ( GL_BACK );
622 glDisable ( GL_CULL_FACE );
625 // ===============================
626 // Step 6: Redraw overlay
627 // ===============================
630 theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
632 RedrawLayer2d (thePrintContext, theCView, theCOverLayer);
634 theWorkspace->DisplayCallback (theCView, aMode);
636 // ===============================
638 // ===============================
640 // Restore clipping planes
641 aClipPlaneId = GL_CLIP_PLANE0;
642 aPtrPlane = aOldPlanes;
644 for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
646 glClipPlane (aClipPlaneId, aPtrPlane->Equation);
647 if (aPtrPlane->isEnabled)
648 glEnable (aClipPlaneId);
650 glDisable (aClipPlaneId);
655 // ==============================================================
656 // Step 8: Keep shader manager informed about last View
657 // ==============================================================
659 if (!aManager.IsNull())
661 aManager->SetLastView (this);
665 // =======================================================================
666 // function : InvalidateBVHData
668 // =======================================================================
669 void OpenGl_View::InvalidateBVHData (const Standard_Integer theLayerId)
671 myZLayers.InvalidateBVHData (theLayerId);
674 /*----------------------------------------------------------------------*/
677 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
679 if ( myZLayers.NbStructures() <= 0 )
682 glPushAttrib ( GL_DEPTH_BUFFER_BIT );
684 //TsmPushAttri(); /* save previous graphics context */
686 if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
688 const int antiAliasingMode = AWorkspace->AntiAliasingMode();
690 if ( !myAntiAliasing )
692 glDisable(GL_POINT_SMOOTH);
693 glDisable(GL_LINE_SMOOTH);
694 if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
695 glBlendFunc (GL_ONE, GL_ZERO);
696 glDisable (GL_BLEND);
700 glEnable(GL_POINT_SMOOTH);
701 glEnable(GL_LINE_SMOOTH);
702 if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
703 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
708 myZLayers.Render (AWorkspace);
710 //TsmPopAttri(); /* restore previous graphics context; before update lights */
714 /*----------------------------------------------------------------------*/
716 //call_togl_redraw_layer2d
717 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
718 const Graphic3d_CView& ACView,
719 const Aspect_CLayer2d& ACLayer)
722 || ACLayer.ptrLayer == NULL
723 || ACLayer.ptrLayer->listIndex == 0) return;
725 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
726 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
728 glMatrixMode( GL_MODELVIEW );
732 glMatrixMode (GL_PROJECTION);
736 if (!ACLayer.sizeDependent)
737 glViewport (0, 0, dispWidth, dispHeight);
739 float left = ACLayer.ortho[0];
740 float right = ACLayer.ortho[1];
741 float bottom = ACLayer.ortho[2];
742 float top = ACLayer.ortho[3];
744 int attach = ACLayer.attach;
747 if (!ACLayer.sizeDependent)
748 ratio = (float) dispWidth/dispHeight;
750 ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
754 delta = (float )((top - bottom)/2.0);
756 case 0: /* Aspect_TOC_BOTTOM_LEFT */
757 top = bottom + 2*delta/ratio;
759 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
760 top = bottom + 2*delta/ratio;
762 case 2: /* Aspect_TOC_TOP_LEFT */
763 bottom = top - 2*delta/ratio;
765 case 3: /* Aspect_TOC_TOP_RIGHT */
766 bottom = top - 2*delta/ratio;
771 delta = (float )((right - left)/2.0);
773 case 0: /* Aspect_TOC_BOTTOM_LEFT */
774 right = left + 2*delta*ratio;
776 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
777 left = right - 2*delta*ratio;
779 case 2: /* Aspect_TOC_TOP_LEFT */
780 right = left + 2*delta*ratio;
782 case 3: /* Aspect_TOC_TOP_RIGHT */
783 left = right - 2*delta*ratio;
789 // Check printer context that exists only for print operation
790 if (!thePrintContext.IsNull())
792 // additional transformation matrix could be applied to
793 // render only those parts of viewport that will be
794 // passed to a printer as a current "frame" to provide
795 // tiling; scaling of graphics by matrix helps render a
796 // part of a view (frame) in same viewport, but with higher
798 thePrintContext->LoadProjTransformation();
800 // printing operation also assumes other viewport dimension
801 // to comply with transformation matrix or graphics scaling
802 // factors for tiling for layer redraw
803 GLsizei anViewportX = 0;
804 GLsizei anViewportY = 0;
805 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
806 if (anViewportX != 0 && anViewportY != 0)
807 glViewport (0, 0, anViewportX, anViewportY);
811 glOrtho (left, right, bottom, top, -1.0, 1.0);
814 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
815 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
817 glDisable (GL_DEPTH_TEST);
818 glDisable (GL_TEXTURE_1D);
819 glDisable (GL_TEXTURE_2D);
820 glDisable (GL_LIGHTING);
822 // TODO: Obsolete code, the display list is always empty now, to be removed
823 glCallList (ACLayer.ptrLayer->listIndex);
825 //calling dynamic render of LayerItems
826 if ( ACLayer.ptrLayer->layerData )
828 InitLayerProp (ACLayer.ptrLayer->listIndex);
829 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
835 glMatrixMode (GL_PROJECTION);
838 glMatrixMode( GL_MODELVIEW );
841 if (!ACLayer.sizeDependent)
842 glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
847 /*----------------------------------------------------------------------*/
849 //call_togl_create_bg_texture
850 void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
851 const Aspect_FillMethod theFillStyle)
853 if (myBgTexture.TexId != 0)
855 // delete existing texture
856 glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
857 myBgTexture.TexId = 0;
860 // load image from file
861 Image_AlienPixMap anImageLoaded;
862 if (!anImageLoaded.Load (theFilePath))
867 Image_PixMap anImage;
868 if (anImageLoaded.RowExtraBytes() == 0 &&
869 (anImageLoaded.Format() == Image_PixMap::ImgRGB
870 || anImageLoaded.Format() == Image_PixMap::ImgRGB32
871 || anImageLoaded.Format() == Image_PixMap::ImgRGBA))
873 anImage.InitWrapper (anImageLoaded.Format(), anImageLoaded.ChangeData(),
874 anImageLoaded.SizeX(), anImageLoaded.SizeY(), anImageLoaded.SizeRowBytes());
878 // convert image to RGB format
879 if (!anImage.InitTrash (Image_PixMap::ImgRGB, anImageLoaded.SizeX(), anImageLoaded.SizeY()))
884 anImage.SetTopDown (false);
885 Quantity_Color aSrcColor;
886 for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
888 for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
890 aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
891 Image_ColorRGB& aColor = anImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
892 aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
893 aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
894 aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
897 anImageLoaded.Clear();
900 // create MipMapped texture
901 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
903 GLuint aTextureId = 0;
904 glGenTextures (1, &aTextureId);
905 glBindTexture (GL_TEXTURE_2D, aTextureId);
907 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
908 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
909 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
910 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
912 const GLenum aDataFormat = (anImage.Format() == Image_PixMap::ImgRGB) ? GL_RGB : GL_RGBA;
913 gluBuild2DMipmaps (GL_TEXTURE_2D, 3/*4*/,
914 GLint(anImage.SizeX()), GLint(anImage.SizeY()),
915 aDataFormat, GL_UNSIGNED_BYTE, anImage.Data());
917 myBgTexture.TexId = aTextureId;
918 myBgTexture.Width = (Standard_Integer )anImage.SizeX();
919 myBgTexture.Height = (Standard_Integer )anImage.SizeY();
920 myBgTexture.Style = theFillStyle;
923 /*----------------------------------------------------------------------*/
925 //call_togl_set_bg_texture_style
926 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
928 myBgTexture.Style = AFillStyle;
931 /*----------------------------------------------------------------------*/
933 //call_togl_gradient_background
934 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
935 const Quantity_Color& AColor2,
936 const Aspect_GradientFillMethod AType)
939 AColor1.Values( R, G, B, Quantity_TOC_RGB );
940 myBgGradient.color1.rgb[0] = ( Tfloat )R;
941 myBgGradient.color1.rgb[1] = ( Tfloat )G;
942 myBgGradient.color1.rgb[2] = ( Tfloat )B;
943 myBgGradient.color1.rgb[3] = 0.F;
945 AColor2.Values( R, G, B, Quantity_TOC_RGB );
946 myBgGradient.color2.rgb[0] = ( Tfloat )R;
947 myBgGradient.color2.rgb[1] = ( Tfloat )G;
948 myBgGradient.color2.rgb[2] = ( Tfloat )B;
949 myBgGradient.color2.rgb[3] = 0.F;
951 myBgGradient.type = AType;
954 /*----------------------------------------------------------------------*/
956 //call_togl_set_gradient_type
957 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
959 myBgGradient.type = AType;
962 //=======================================================================
963 //function : AddZLayer
965 //=======================================================================
967 void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
969 myZLayers.AddLayer (theLayerId);
972 //=======================================================================
973 //function : RemoveZLayer
975 //=======================================================================
977 void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
979 myZLayers.RemoveLayer (theLayerId);
982 //=======================================================================
983 //function : DisplayStructure
985 //=======================================================================
987 void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
988 const Standard_Integer thePriority)
990 Standard_Integer aZLayer = theStructure->GetZLayer ();
991 myZLayers.AddStructure (theStructure, aZLayer, thePriority);
994 //=======================================================================
995 //function : DisplayImmediateStructure
997 //=======================================================================
999 void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructure)
1001 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1002 anIter.More(); anIter.Next())
1004 if (anIter.Value() == theStructure)
1010 myImmediateList.Append (theStructure);
1013 //=======================================================================
1014 //function : EraseStructure
1016 //=======================================================================
1018 void OpenGl_View::EraseStructure (const OpenGl_Structure *theStructure)
1020 Standard_Integer aZLayer = theStructure->GetZLayer ();
1021 myZLayers.RemoveStructure (theStructure, aZLayer);
1024 //=======================================================================
1025 //function : EraseImmediateStructure
1027 //=======================================================================
1029 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
1031 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1032 anIter.More(); anIter.Next())
1034 if (anIter.Value() == theStructure)
1036 myImmediateList.Remove (anIter);
1042 //=======================================================================
1043 //function : ChangeZLayer
1045 //=======================================================================
1047 void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
1048 const Standard_Integer theNewLayerId)
1050 Standard_Integer anOldLayer = theStructure->GetZLayer ();
1051 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
1054 //=======================================================================
1055 //function : SetZLayerSettings
1057 //=======================================================================
1058 void OpenGl_View::SetZLayerSettings (const Standard_Integer theLayerId,
1059 const Graphic3d_ZLayerSettings theSettings)
1061 myZLayers.Layer (theLayerId).SetLayerSettings (theSettings);
1064 //=======================================================================
1065 //function : ChangePriority
1067 //=======================================================================
1068 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
1069 const Standard_Integer theNewPriority)
1071 Standard_Integer aLayerId = theStructure->GetZLayer();
1072 myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
1075 //=======================================================================
1076 //function : RedrawScene
1078 //=======================================================================
1080 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
1081 const Handle(OpenGl_Workspace)& theWorkspace,
1082 const OpenGl_Matrix* theProjection,
1083 const OpenGl_Matrix* theOrientation)
1085 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1087 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1089 Handle(Graphic3d_ClipPlane) aPlaneBack;
1090 Handle(Graphic3d_ClipPlane) aPlaneFront;
1092 if (myZClip.Back.IsOn)
1094 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1095 if (myCamera->ZFar() < aClipBackConverted)
1097 aClipBackConverted = myCamera->ZFar();
1098 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1100 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1101 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1104 if (myZClip.Front.IsOn)
1106 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1107 if (myCamera->ZNear() > aClipFrontConverted)
1109 aClipFrontConverted = myCamera->ZNear();
1110 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1112 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1113 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1116 // do some "memory allocation"-wise optimization
1117 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1119 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1120 if (!aPlaneBack.IsNull())
1122 aSlicingPlanes.Append (aPlaneBack);
1125 if (!aPlaneFront.IsNull())
1127 aSlicingPlanes.Append (aPlaneFront);
1130 // add planes at loaded view matrix state
1131 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1135 // Apply user clipping planes
1136 if (!myClipPlanes.IsEmpty())
1138 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1139 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1140 for (; aClippingIt.More(); aClippingIt.Next())
1142 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1143 if (aClipPlane->IsOn())
1145 aUserPlanes.Append (aClipPlane);
1149 if (!aUserPlanes.IsEmpty())
1151 // add planes at actual matrix state.
1152 aContext->ChangeClipping().AddWorld (aUserPlanes);
1155 if (!aContext->ShaderManager()->IsEmpty())
1157 aContext->ShaderManager()->UpdateClippingState();
1161 // Setup view projection
1162 glMatrixMode (GL_PROJECTION);
1165 // add printing scale/tiling transformation
1166 if (!thePrintContext.IsNull())
1168 thePrintContext->LoadProjTransformation();
1174 glMultMatrixf ((const GLfloat*)theProjection);
1176 if (!thePrintContext.IsNull())
1178 // update shader uniform projection matrix with new data
1179 Tmatrix3 aResultProjection;
1180 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
1181 aContext->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
1183 // force shader uniform restore on next frame
1184 myProjectionState = 0;
1187 // Setup view orientation
1188 theWorkspace->SetViewMatrix (theOrientation);
1193 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1194 THE_DEFAULT_AMBIENT[1],
1195 THE_DEFAULT_AMBIENT[2],
1196 THE_DEFAULT_AMBIENT[3]);
1197 GLenum aLightGlId = GL_LIGHT0;
1198 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1199 aLightIt.More(); aLightIt.Next())
1201 bind_light (aLightIt.Value(), aLightGlId, anAmbientColor);
1204 // apply accumulated ambient color
1205 anAmbientColor.a() = 1.0f;
1206 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1208 if (aLightGlId != GL_LIGHT0)
1210 glEnable (GL_LIGHTING);
1212 // switch off unused lights
1213 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1215 glDisable (aLightGlId);
1219 // Clear status bitfields
1220 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1222 // Added PCT for handling of textures
1223 switch (mySurfaceDetail)
1225 case Visual3d_TOD_NONE:
1226 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1227 theWorkspace->DisableTexture();
1229 RenderStructs (theWorkspace);
1232 case Visual3d_TOD_ENVIRONMENT:
1233 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1234 theWorkspace->EnableTexture (myTextureEnv);
1236 RenderStructs (theWorkspace);
1237 theWorkspace->DisableTexture();
1240 case Visual3d_TOD_ALL:
1242 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1244 RenderStructs (theWorkspace);
1245 theWorkspace->DisableTexture();
1248 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1250 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1251 theWorkspace->EnableTexture (myTextureEnv);
1253 // Remember OpenGl properties
1254 GLint aSaveBlendDst, aSaveBlendSrc;
1255 GLint aSaveZbuffFunc;
1256 GLboolean aSaveZbuffWrite;
1257 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1258 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1259 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1260 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1261 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1262 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1264 // Change the properties for second rendering pass
1265 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1266 glEnable (GL_BLEND);
1268 glDepthFunc (GL_EQUAL);
1269 glDepthMask (GL_FALSE);
1270 glEnable (GL_DEPTH_TEST);
1272 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1275 RenderStructs (theWorkspace);
1276 theWorkspace->DisableTexture();
1278 // Restore properties back
1279 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1280 if (!wasBlendEnabled)
1281 glDisable (GL_BLEND);
1283 glDepthFunc (aSaveZbuffFunc);
1284 glDepthMask (aSaveZbuffWrite);
1285 if (!wasZbuffEnabled)
1286 glDisable (GL_DEPTH_FUNC);