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_Display.hxx>
30 #include <OpenGl_Matrix.hxx>
31 #include <OpenGl_Workspace.hxx>
32 #include <OpenGl_View.hxx>
33 #include <OpenGl_Trihedron.hxx>
34 #include <OpenGl_GraduatedTrihedron.hxx>
35 #include <OpenGl_PrinterContext.hxx>
36 #include <OpenGl_ShaderManager.hxx>
37 #include <OpenGl_ShaderProgram.hxx>
38 #include <OpenGl_Structure.hxx>
45 static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
46 static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f };
47 static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f;
48 static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f;
52 extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
54 /*----------------------------------------------------------------------*/
56 struct OPENGL_CLIP_PLANE
63 /*----------------------------------------------------------------------*/
68 /*-----------------------------------------------------------------*/
72 static void bind_light (const OpenGl_Light& theLight,
74 Graphic3d_Vec4& theAmbientColor)
76 // Only 8 lights in OpenGL...
77 if (theLightGlId > GL_LIGHT7)
82 if (theLight.Type == Visual3d_TOLS_AMBIENT)
84 // add RGBA intensity of the ambient light
85 theAmbientColor += theLight.Color;
89 // the light is a headlight?
90 GLint aMatrixModeOld = 0;
91 if (theLight.IsHeadlight)
93 glGetIntegerv (GL_MATRIX_MODE, &aMatrixModeOld);
94 glMatrixMode (GL_MODELVIEW);
100 switch (theLight.Type)
102 case Visual3d_TOLS_DIRECTIONAL:
104 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
105 const OpenGl_Vec4 anInfDir = -theLight.Direction;
107 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
108 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
109 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
110 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
111 glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
112 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
113 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
114 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
117 case Visual3d_TOLS_POSITIONAL:
119 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
120 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
121 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
122 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
123 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
124 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
125 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
126 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
127 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
128 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
129 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
132 case Visual3d_TOLS_SPOT:
134 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
135 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
136 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
137 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
138 glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
139 glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
140 glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
141 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
142 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
143 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
148 // restore matrix in case of headlight
149 if (theLight.IsHeadlight)
152 glMatrixMode (aMatrixModeOld);
155 glEnable (theLightGlId++);
158 /*----------------------------------------------------------------------*/
160 void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
162 if ( (theWorkspace.NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
163 ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
165 const Standard_Integer aViewWidth = theWorkspace.Width();
166 const Standard_Integer aViewHeight = theWorkspace.Height();
168 glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
170 glMatrixMode( GL_PROJECTION );
173 glMatrixMode( GL_MODELVIEW );
177 if ( glIsEnabled( GL_DEPTH_TEST ) )
178 glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
180 // drawing bg gradient if:
181 // - gradient fill type is not Aspect_GFM_NONE and
182 // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
183 if ( ( myBgGradient.type != Aspect_GFM_NONE ) &&
184 ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
185 myBgTexture.Style == Aspect_FM_NONE ) )
187 Tfloat* corner1 = 0;/* -1,-1*/
188 Tfloat* corner2 = 0;/* 1,-1*/
189 Tfloat* corner3 = 0;/* 1, 1*/
190 Tfloat* corner4 = 0;/* -1, 1*/
194 switch( myBgGradient.type )
197 corner1 = myBgGradient.color1.rgb;
198 corner2 = myBgGradient.color2.rgb;
199 corner3 = myBgGradient.color2.rgb;
200 corner4 = myBgGradient.color1.rgb;
203 corner1 = myBgGradient.color2.rgb;
204 corner2 = myBgGradient.color2.rgb;
205 corner3 = myBgGradient.color1.rgb;
206 corner4 = myBgGradient.color1.rgb;
208 case Aspect_GFM_DIAG1:
209 corner2 = myBgGradient.color2.rgb;
210 corner4 = myBgGradient.color1.rgb;
211 dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
212 dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
213 dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
217 case Aspect_GFM_DIAG2:
218 corner1 = myBgGradient.color2.rgb;
219 corner3 = myBgGradient.color1.rgb;
220 dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
221 dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
222 dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
226 case Aspect_GFM_CORNER1:
227 corner1 = myBgGradient.color2.rgb;
228 corner2 = myBgGradient.color2.rgb;
229 corner3 = myBgGradient.color2.rgb;
230 corner4 = myBgGradient.color1.rgb;
232 case Aspect_GFM_CORNER2:
233 corner1 = myBgGradient.color2.rgb;
234 corner2 = myBgGradient.color2.rgb;
235 corner3 = myBgGradient.color1.rgb;
236 corner4 = myBgGradient.color2.rgb;
238 case Aspect_GFM_CORNER3:
239 corner1 = myBgGradient.color2.rgb;
240 corner2 = myBgGradient.color1.rgb;
241 corner3 = myBgGradient.color2.rgb;
242 corner4 = myBgGradient.color2.rgb;
244 case Aspect_GFM_CORNER4:
245 corner1 = myBgGradient.color1.rgb;
246 corner2 = myBgGradient.color2.rgb;
247 corner3 = myBgGradient.color2.rgb;
248 corner4 = myBgGradient.color2.rgb;
251 //printf("gradient background type not right\n");
255 // Save GL parameters
256 glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
259 glGetIntegerv( GL_SHADE_MODEL, &curSM );
260 if ( curSM != GL_SMOOTH )
261 glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
263 glBegin(GL_TRIANGLE_FAN);
264 if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
266 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
267 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
268 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
269 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
271 else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
273 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
274 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
275 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
276 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
280 // Restore GL parameters
281 if ( curSM != GL_SMOOTH )
282 glShadeModel( curSM );
284 // drawing bg image if:
285 // - it is defined and
286 // - fill type is not Aspect_FM_NONE
287 if ( myBgTexture.TexId != 0 && myBgTexture.Style != Aspect_FM_NONE )
289 GLfloat texX_range = 1.F; // texture <s> coordinate
290 GLfloat texY_range = 1.F; // texture <t> coordinate
292 // Set up for stretching or tiling
293 GLfloat x_offset, y_offset;
294 if ( myBgTexture.Style == Aspect_FM_CENTERED )
296 x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
297 y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
303 if ( myBgTexture.Style == Aspect_FM_TILED )
305 texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
306 texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
310 // OCCT issue 0023000: Improve the way the gradient and textured
311 // background is managed in 3d viewer (note 0020339)
312 // Setting this coefficient to -1.F allows to tile textures relatively
313 // to the top-left corner of the view (value 1.F corresponds to the
314 // initial behaviour - tiling from the bottom-left corner)
315 GLfloat aCoef = -1.F;
317 glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
318 glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
320 glDisable( GL_BLEND ); //push GL_ENABLE_BIT
322 glColor3fv (theWorkspace.BackgroundColor().rgb);
323 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
325 // Note that texture is mapped using GL_REPEAT wrapping mode so integer part
326 // is simply ignored, and negative multiplier is here for convenience only
327 // and does not result e.g. in texture mirroring
329 glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -aCoef * y_offset );
330 glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -aCoef * y_offset );
331 glTexCoord2f(texX_range, aCoef * texY_range); glVertex2f( x_offset, aCoef * y_offset );
332 glTexCoord2f(0.F, aCoef * texY_range); glVertex2f( -x_offset, aCoef * y_offset );
337 glMatrixMode( GL_PROJECTION );
339 glMatrixMode( GL_MODELVIEW );
341 glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
343 if (theWorkspace.UseZBuffer())
344 glEnable (GL_DEPTH_TEST);
346 /* GL_DITHER on/off pour le trace */
347 if (theWorkspace.Dither())
348 glEnable (GL_DITHER);
350 glDisable (GL_DITHER);
354 /*----------------------------------------------------------------------*/
356 //call_func_redraw_all_structs_proc
357 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
358 const Handle(OpenGl_Workspace) &theWorkspace,
359 const Graphic3d_CView& theCView,
360 const Aspect_CLayer2d& theCUnderLayer,
361 const Aspect_CLayer2d& theCOverLayer)
363 // ==================================
364 // Step 1: Prepare for redraw
365 // ==================================
367 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
369 // Store and disable current clipping planes
370 Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
372 OPENGL_CLIP_PLANE *aOldPlanes = new OPENGL_CLIP_PLANE[aMaxPlanes];
373 OPENGL_CLIP_PLANE *aPtrPlane = aOldPlanes;
375 GLenum aClipPlaneId = GL_CLIP_PLANE0;
376 const GLenum aClipLastId = GL_CLIP_PLANE0 + aMaxPlanes;
377 for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
379 glGetClipPlane (aClipPlaneId, aPtrPlane->Equation);
380 if (aPtrPlane->isEnabled)
382 glDisable (aClipPlaneId);
383 aPtrPlane->isEnabled = GL_TRUE;
387 aPtrPlane->isEnabled = GL_FALSE;
391 // Set OCCT state uniform variables
392 const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
393 if (!aManager->IsEmpty())
395 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
397 aManager->UpdateLightSourceStateTo (&myLights);
398 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
401 if (myProjectionState != myCamera->ProjectionState())
403 myProjectionState = myCamera->ProjectionState();
404 aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
407 if (myModelViewState != myCamera->ModelViewState())
409 myModelViewState = myCamera->ModelViewState();
410 aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
413 if (aManager->ModelWorldState().Index() == 0)
415 Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
416 { 0.f, 1.f, 0.f, 0.f },
417 { 0.f, 0.f, 1.f, 0.f },
418 { 0.f, 0.f, 0.f, 1.f } };
420 aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorldState);
424 if (!aManager.IsNull())
426 if (!aManager->IsSameView (this))
428 // Force update camera states
429 myProjectionState = myCamera->ProjectionState();
430 aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
432 myModelViewState = myCamera->ModelViewState();
433 aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
437 // ====================================
438 // Step 2: Redraw background
439 // ====================================
442 DrawBackground (*theWorkspace);
444 // Switch off lighting by default
445 glDisable(GL_LIGHTING);
447 // =================================
448 // Step 3: Draw underlayer
449 // =================================
451 RedrawLayer2d (thePrintContext, theCView, theCUnderLayer);
453 // =================================
454 // Step 4: Redraw main plane
455 // =================================
457 // Setup face culling
458 GLboolean isCullFace = GL_FALSE;
461 isCullFace = glIsEnabled( GL_CULL_FACE );
462 if ( myBackfacing < 0 )
464 glEnable( GL_CULL_FACE );
465 glCullFace( GL_BACK );
468 glDisable( GL_CULL_FACE );
471 // if the view is scaled normal vectors are scaled to unit
472 // length for correct displaying of shaded objects
473 const gp_Pnt anAxialScale = myCamera->AxialScale();
474 if(anAxialScale.X() != 1.F ||
475 anAxialScale.Y() != 1.F ||
476 anAxialScale.Z() != 1.F)
477 glEnable(GL_NORMALIZE);
478 else if(glIsEnabled(GL_NORMALIZE))
479 glDisable(GL_NORMALIZE);
484 Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
485 if (myCamera->ZFar() < aFogFrontConverted)
487 aFogFrontConverted = myCamera->ZFar();
488 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
491 Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
492 if (myCamera->ZFar() < aFogFrontConverted)
494 aFogBackConverted = myCamera->ZFar();
495 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
498 if (aFogFrontConverted > aFogBackConverted)
500 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
501 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
504 glFogi(GL_FOG_MODE, GL_LINEAR);
505 glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
506 glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
507 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
513 // Apply InteriorShadingMethod
514 glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
516 // Apply AntiAliasing
518 theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
520 theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
522 if (!aManager->IsEmpty())
524 aManager->UpdateClippingState();
528 if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
530 // single-pass monographic rendering
531 const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
533 const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
535 // redraw scene with normal orientation and projection
536 RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
540 // two stereographic passes
541 const OpenGl_Matrix* aLProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
542 const OpenGl_Matrix* aRProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
543 const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
545 // safely switch to left Eye buffer
546 aContext->SetDrawBufferLeft();
549 RedrawScene (thePrintContext, theWorkspace, aLProj, aOrient);
551 // reset depth buffer of first rendering pass
552 if (theWorkspace->UseDepthTest())
554 glClear (GL_DEPTH_BUFFER_BIT);
556 // safely switch to right Eye buffer
557 aContext->SetDrawBufferRight();
560 RedrawScene (thePrintContext, theWorkspace, aRProj, aOrient);
562 // switch back to monographic rendering
563 aContext->SetDrawBufferMono();
566 // ===============================
568 // ===============================
570 // Resetting GL parameters according to the default aspects
571 // in order to synchronize GL state with the graphic driver state
572 // before drawing auxiliary stuff (trihedrons, overlayer)
573 // and invoking optional callbacks
574 theWorkspace->ResetAppliedAspect();
576 aContext->ChangeClipping().RemoveAll();
578 if (!aManager->IsEmpty())
580 aManager->ResetMaterialStates();
581 aManager->RevertClippingState();
583 // We need to disable (unbind) all shaders programs to ensure
584 // that all objects without specified aspect will be drawn
585 // correctly (such as background)
586 OpenGl_ShaderProgram::Unbind (aContext);
589 // display global trihedron
590 if (myTrihedron != NULL)
592 myTrihedron->Render (theWorkspace);
594 if (myGraduatedTrihedron != NULL)
596 myGraduatedTrihedron->Render (theWorkspace);
599 // Restore face culling
604 glEnable ( GL_CULL_FACE );
605 glCullFace ( GL_BACK );
608 glDisable ( GL_CULL_FACE );
611 // ===============================
612 // Step 6: Redraw overlay
613 // ===============================
616 theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
618 RedrawLayer2d (thePrintContext, theCView, theCOverLayer);
620 theWorkspace->DisplayCallback (theCView, aMode);
622 // ===============================
624 // ===============================
626 // Restore clipping planes
627 aClipPlaneId = GL_CLIP_PLANE0;
628 aPtrPlane = aOldPlanes;
630 for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
632 glClipPlane (aClipPlaneId, aPtrPlane->Equation);
633 if (aPtrPlane->isEnabled)
634 glEnable (aClipPlaneId);
636 glDisable (aClipPlaneId);
641 // ==============================================================
642 // Step 8: Keep shader manager informed about last View
643 // ==============================================================
645 if (!aManager.IsNull())
647 aManager->SetLastView (this);
651 /*----------------------------------------------------------------------*/
654 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
656 if ( myZLayers.NbStructures() <= 0 )
659 glPushAttrib ( GL_DEPTH_BUFFER_BIT );
661 //TsmPushAttri(); /* save previous graphics context */
663 if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
665 const int antiAliasingMode = AWorkspace->GetDisplay()->AntiAliasingMode();
667 if ( !myAntiAliasing )
669 glDisable(GL_POINT_SMOOTH);
670 glDisable(GL_LINE_SMOOTH);
671 if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
672 glBlendFunc (GL_ONE, GL_ZERO);
673 glDisable (GL_BLEND);
677 glEnable(GL_POINT_SMOOTH);
678 glEnable(GL_LINE_SMOOTH);
679 if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
680 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
685 myZLayers.Render (AWorkspace);
687 //TsmPopAttri(); /* restore previous graphics context; before update lights */
691 /*----------------------------------------------------------------------*/
693 //call_togl_redraw_layer2d
694 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
695 const Graphic3d_CView& ACView,
696 const Aspect_CLayer2d& ACLayer)
699 || ACLayer.ptrLayer == NULL
700 || ACLayer.ptrLayer->listIndex == 0) return;
702 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
703 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
705 glMatrixMode( GL_MODELVIEW );
709 glMatrixMode (GL_PROJECTION);
713 if (!ACLayer.sizeDependent)
714 glViewport (0, 0, dispWidth, dispHeight);
716 float left = ACLayer.ortho[0];
717 float right = ACLayer.ortho[1];
718 float bottom = ACLayer.ortho[2];
719 float top = ACLayer.ortho[3];
721 int attach = ACLayer.attach;
724 if (!ACLayer.sizeDependent)
725 ratio = (float) dispWidth/dispHeight;
727 ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
731 delta = (float )((top - bottom)/2.0);
733 case 0: /* Aspect_TOC_BOTTOM_LEFT */
734 top = bottom + 2*delta/ratio;
736 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
737 top = bottom + 2*delta/ratio;
739 case 2: /* Aspect_TOC_TOP_LEFT */
740 bottom = top - 2*delta/ratio;
742 case 3: /* Aspect_TOC_TOP_RIGHT */
743 bottom = top - 2*delta/ratio;
748 delta = (float )((right - left)/2.0);
750 case 0: /* Aspect_TOC_BOTTOM_LEFT */
751 right = left + 2*delta*ratio;
753 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
754 left = right - 2*delta*ratio;
756 case 2: /* Aspect_TOC_TOP_LEFT */
757 right = left + 2*delta*ratio;
759 case 3: /* Aspect_TOC_TOP_RIGHT */
760 left = right - 2*delta*ratio;
766 // Check printer context that exists only for print operation
767 if (!thePrintContext.IsNull())
769 // additional transformation matrix could be applied to
770 // render only those parts of viewport that will be
771 // passed to a printer as a current "frame" to provide
772 // tiling; scaling of graphics by matrix helps render a
773 // part of a view (frame) in same viewport, but with higher
775 thePrintContext->LoadProjTransformation();
777 // printing operation also assumes other viewport dimension
778 // to comply with transformation matrix or graphics scaling
779 // factors for tiling for layer redraw
780 GLsizei anViewportX = 0;
781 GLsizei anViewportY = 0;
782 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
783 if (anViewportX != 0 && anViewportY != 0)
784 glViewport (0, 0, anViewportX, anViewportY);
788 glOrtho (left, right, bottom, top, -1.0, 1.0);
791 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
792 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
794 glDisable (GL_DEPTH_TEST);
795 glDisable (GL_TEXTURE_1D);
796 glDisable (GL_TEXTURE_2D);
797 glDisable (GL_LIGHTING);
799 // TODO: Obsolete code, the display list is always empty now, to be removed
800 glCallList (ACLayer.ptrLayer->listIndex);
802 //calling dynamic render of LayerItems
803 if ( ACLayer.ptrLayer->layerData )
805 InitLayerProp (ACLayer.ptrLayer->listIndex);
806 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
812 glMatrixMode (GL_PROJECTION);
815 glMatrixMode( GL_MODELVIEW );
818 if (!ACLayer.sizeDependent)
819 glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
824 /*----------------------------------------------------------------------*/
826 //call_togl_create_bg_texture
827 void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
828 const Aspect_FillMethod theFillStyle)
830 if (myBgTexture.TexId != 0)
832 // delete existing texture
833 glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
834 myBgTexture.TexId = 0;
837 // load image from file
838 Image_AlienPixMap anImageLoaded;
839 if (!anImageLoaded.Load (theFilePath))
844 Image_PixMap anImage;
845 if (anImageLoaded.RowExtraBytes() == 0 &&
846 (anImageLoaded.Format() == Image_PixMap::ImgRGB
847 || anImageLoaded.Format() == Image_PixMap::ImgRGB32
848 || anImageLoaded.Format() == Image_PixMap::ImgRGBA))
850 anImage.InitWrapper (anImageLoaded.Format(), anImageLoaded.ChangeData(),
851 anImageLoaded.SizeX(), anImageLoaded.SizeY(), anImageLoaded.SizeRowBytes());
855 // convert image to RGB format
856 if (!anImage.InitTrash (Image_PixMap::ImgRGB, anImageLoaded.SizeX(), anImageLoaded.SizeY()))
861 anImage.SetTopDown (false);
862 Quantity_Color aSrcColor;
863 for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
865 for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
867 aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
868 Image_ColorRGB& aColor = anImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
869 aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
870 aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
871 aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
874 anImageLoaded.Clear();
877 // create MipMapped texture
878 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
880 GLuint aTextureId = 0;
881 glGenTextures (1, &aTextureId);
882 glBindTexture (GL_TEXTURE_2D, aTextureId);
884 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
885 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
886 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
887 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
889 const GLenum aDataFormat = (anImage.Format() == Image_PixMap::ImgRGB) ? GL_RGB : GL_RGBA;
890 gluBuild2DMipmaps (GL_TEXTURE_2D, 3/*4*/,
891 GLint(anImage.SizeX()), GLint(anImage.SizeY()),
892 aDataFormat, GL_UNSIGNED_BYTE, anImage.Data());
894 myBgTexture.TexId = aTextureId;
895 myBgTexture.Width = (Standard_Integer )anImage.SizeX();
896 myBgTexture.Height = (Standard_Integer )anImage.SizeY();
897 myBgTexture.Style = theFillStyle;
900 /*----------------------------------------------------------------------*/
902 //call_togl_set_bg_texture_style
903 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
905 myBgTexture.Style = AFillStyle;
908 /*----------------------------------------------------------------------*/
910 //call_togl_gradient_background
911 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
912 const Quantity_Color& AColor2,
913 const Aspect_GradientFillMethod AType)
916 AColor1.Values( R, G, B, Quantity_TOC_RGB );
917 myBgGradient.color1.rgb[0] = ( Tfloat )R;
918 myBgGradient.color1.rgb[1] = ( Tfloat )G;
919 myBgGradient.color1.rgb[2] = ( Tfloat )B;
920 myBgGradient.color1.rgb[3] = 0.F;
922 AColor2.Values( R, G, B, Quantity_TOC_RGB );
923 myBgGradient.color2.rgb[0] = ( Tfloat )R;
924 myBgGradient.color2.rgb[1] = ( Tfloat )G;
925 myBgGradient.color2.rgb[2] = ( Tfloat )B;
926 myBgGradient.color2.rgb[3] = 0.F;
928 myBgGradient.type = AType;
931 /*----------------------------------------------------------------------*/
933 //call_togl_set_gradient_type
934 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
936 myBgGradient.type = AType;
939 //=======================================================================
940 //function : AddZLayer
942 //=======================================================================
944 void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
946 myZLayers.AddLayer (theLayerId);
949 //=======================================================================
950 //function : RemoveZLayer
952 //=======================================================================
954 void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
956 myZLayers.RemoveLayer (theLayerId);
959 //=======================================================================
960 //function : DisplayStructure
962 //=======================================================================
964 void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
965 const Standard_Integer thePriority)
967 Standard_Integer aZLayer = theStructure->GetZLayer ();
968 myZLayers.AddStructure (theStructure, aZLayer, thePriority);
971 //=======================================================================
972 //function : DisplayImmediateStructure
974 //=======================================================================
976 void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructure)
978 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
979 anIter.More(); anIter.Next())
981 if (anIter.Value() == theStructure)
987 myImmediateList.Append (theStructure);
990 //=======================================================================
991 //function : EraseStructure
993 //=======================================================================
995 void OpenGl_View::EraseStructure (const OpenGl_Structure *theStructure)
997 Standard_Integer aZLayer = theStructure->GetZLayer ();
998 myZLayers.RemoveStructure (theStructure, aZLayer);
1001 //=======================================================================
1002 //function : EraseImmediateStructure
1004 //=======================================================================
1006 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
1008 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1009 anIter.More(); anIter.Next())
1011 if (anIter.Value() == theStructure)
1013 myImmediateList.Remove (anIter);
1019 //=======================================================================
1020 //function : ChangeZLayer
1022 //=======================================================================
1024 void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
1025 const Standard_Integer theNewLayerId)
1027 Standard_Integer anOldLayer = theStructure->GetZLayer ();
1028 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
1031 //=======================================================================
1032 //function : RedrawScene
1034 //=======================================================================
1036 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
1037 const Handle(OpenGl_Workspace)& theWorkspace,
1038 const OpenGl_Matrix* theProjection,
1039 const OpenGl_Matrix* theOrientation)
1041 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1043 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1045 Handle(Graphic3d_ClipPlane) aPlaneBack;
1046 Handle(Graphic3d_ClipPlane) aPlaneFront;
1048 if (myZClip.Back.IsOn)
1050 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1051 if (myCamera->ZFar() < aClipBackConverted)
1053 aClipBackConverted = myCamera->ZFar();
1054 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1056 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1057 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1060 if (myZClip.Front.IsOn)
1062 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1063 if (myCamera->ZNear() > aClipFrontConverted)
1065 aClipFrontConverted = myCamera->ZNear();
1066 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1068 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1069 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1072 // do some "memory allocation"-wise optimization
1073 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1075 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1076 if (!aPlaneBack.IsNull())
1078 aSlicingPlanes.Append (aPlaneBack);
1081 if (!aPlaneFront.IsNull())
1083 aSlicingPlanes.Append (aPlaneFront);
1086 // add planes at loaded view matrix state
1087 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1091 // Apply user clipping planes
1092 if (!myClipPlanes.IsEmpty())
1094 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1095 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1096 for (; aClippingIt.More(); aClippingIt.Next())
1098 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1099 if (aClipPlane->IsOn())
1101 aUserPlanes.Append (aClipPlane);
1105 if (!aUserPlanes.IsEmpty())
1107 // add planes at actual matrix state.
1108 aContext->ChangeClipping().AddWorld (aUserPlanes);
1111 if (!aContext->ShaderManager()->IsEmpty())
1113 aContext->ShaderManager()->UpdateClippingState();
1117 // Setup view projection
1118 glMatrixMode (GL_PROJECTION);
1121 // add printing scale/tiling transformation
1122 if (!thePrintContext.IsNull())
1124 thePrintContext->LoadProjTransformation();
1130 glMultMatrixf ((const GLfloat*)theProjection);
1132 if (!thePrintContext.IsNull())
1134 // update shader uniform projection matrix with new data
1135 Tmatrix3 aResultProjection;
1136 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
1137 aContext->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
1139 // force shader uniform restore on next frame
1140 myProjectionState = 0;
1143 // Setup view orientation
1144 theWorkspace->SetViewMatrix (theOrientation);
1149 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1150 THE_DEFAULT_AMBIENT[1],
1151 THE_DEFAULT_AMBIENT[2],
1152 THE_DEFAULT_AMBIENT[3]);
1153 GLenum aLightGlId = GL_LIGHT0;
1154 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1155 aLightIt.More(); aLightIt.Next())
1157 bind_light (aLightIt.Value(), aLightGlId, anAmbientColor);
1160 // apply accumulated ambient color
1161 anAmbientColor.a() = 1.0f;
1162 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1164 if (aLightGlId != GL_LIGHT0)
1166 glEnable (GL_LIGHTING);
1168 // switch off unused lights
1169 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1171 glDisable (aLightGlId);
1175 // Clear status bitfields
1176 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1178 // Added PCT for handling of textures
1179 switch (mySurfaceDetail)
1181 case Visual3d_TOD_NONE:
1182 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1183 theWorkspace->DisableTexture();
1185 RenderStructs (theWorkspace);
1188 case Visual3d_TOD_ENVIRONMENT:
1189 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1190 theWorkspace->EnableTexture (myTextureEnv);
1192 RenderStructs (theWorkspace);
1193 theWorkspace->DisableTexture();
1196 case Visual3d_TOD_ALL:
1198 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1200 RenderStructs (theWorkspace);
1201 theWorkspace->DisableTexture();
1204 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1206 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1207 theWorkspace->EnableTexture (myTextureEnv);
1209 // Remember OpenGl properties
1210 GLint aSaveBlendDst, aSaveBlendSrc;
1211 GLint aSaveZbuffFunc;
1212 GLboolean aSaveZbuffWrite;
1213 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1214 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1215 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1216 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1217 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1218 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1220 // Change the properties for second rendering pass
1221 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1222 glEnable (GL_BLEND);
1224 glDepthFunc (GL_EQUAL);
1225 glDepthMask (GL_FALSE);
1226 glEnable (GL_DEPTH_TEST);
1228 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1231 RenderStructs (theWorkspace);
1232 theWorkspace->DisableTexture();
1234 // Restore properties back
1235 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1236 if (!wasBlendEnabled)
1237 glDisable (GL_BLEND);
1239 glDepthFunc (aSaveZbuffFunc);
1240 glDepthMask (aSaveZbuffWrite);
1241 if (!wasZbuffEnabled)
1242 glDisable (GL_DEPTH_FUNC);