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 #if !defined(GL_ES_VERSION_2_0)
68 /*-----------------------------------------------------------------*/
72 static void bindLight (const OpenGl_Light& theLight,
74 Graphic3d_Vec4& theAmbientColor,
75 const Handle(OpenGl_Workspace)& theWorkspace)
77 // Only 8 lights in OpenGL...
78 if (theLightGlId > GL_LIGHT7)
83 if (theLight.Type == Visual3d_TOLS_AMBIENT)
85 // add RGBA intensity of the ambient light
86 theAmbientColor += theLight.Color;
90 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
92 // the light is a headlight?
93 if (theLight.IsHeadlight)
96 aContext->WorldViewState.Push();
97 aContext->WorldViewState.SetIdentity();
99 aContext->ApplyWorldViewMatrix();
103 switch (theLight.Type)
105 case Visual3d_TOLS_DIRECTIONAL:
107 // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
108 const OpenGl_Vec4 anInfDir = -theLight.Direction;
110 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
111 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
112 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
113 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
114 glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData());
115 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
116 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
117 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
120 case Visual3d_TOLS_POSITIONAL:
122 // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
123 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
124 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
125 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
126 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
127 glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR);
128 glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT);
129 glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF);
130 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
131 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
132 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0);
135 case Visual3d_TOLS_SPOT:
137 glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT);
138 glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData());
139 glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData());
140 glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData());
141 glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData());
142 glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f);
143 glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI));
144 glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation());
145 glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation());
146 glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f);
151 // restore matrix in case of headlight
152 if (theLight.IsHeadlight)
154 aContext->WorldViewState.Pop();
157 glEnable (theLightGlId++);
161 /*----------------------------------------------------------------------*/
163 void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
165 #if !defined(GL_ES_VERSION_2_0)
166 if ( (theWorkspace.NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
167 ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
169 const Standard_Integer aViewWidth = theWorkspace.Width();
170 const Standard_Integer aViewHeight = theWorkspace.Height();
172 glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
174 const Handle(OpenGl_Context)& aContext = theWorkspace.GetGlContext();
176 aContext->WorldViewState.Push();
177 aContext->ProjectionState.Push();
179 aContext->WorldViewState.SetIdentity();
180 aContext->ProjectionState.SetIdentity();
182 aContext->ApplyProjectionMatrix();
183 aContext->ApplyWorldViewMatrix();
185 if ( glIsEnabled( GL_DEPTH_TEST ) )
186 glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
188 // drawing bg gradient if:
189 // - gradient fill type is not Aspect_GFM_NONE and
190 // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
191 if ( ( myBgGradient.type != Aspect_GFM_NONE ) &&
192 ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
193 myBgTexture.Style == Aspect_FM_NONE ) )
195 Tfloat* corner1 = 0;/* -1,-1*/
196 Tfloat* corner2 = 0;/* 1,-1*/
197 Tfloat* corner3 = 0;/* 1, 1*/
198 Tfloat* corner4 = 0;/* -1, 1*/
202 switch( myBgGradient.type )
205 corner1 = myBgGradient.color1.rgb;
206 corner2 = myBgGradient.color2.rgb;
207 corner3 = myBgGradient.color2.rgb;
208 corner4 = myBgGradient.color1.rgb;
211 corner1 = myBgGradient.color2.rgb;
212 corner2 = myBgGradient.color2.rgb;
213 corner3 = myBgGradient.color1.rgb;
214 corner4 = myBgGradient.color1.rgb;
216 case Aspect_GFM_DIAG1:
217 corner2 = myBgGradient.color2.rgb;
218 corner4 = myBgGradient.color1.rgb;
219 dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
220 dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
221 dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
225 case Aspect_GFM_DIAG2:
226 corner1 = myBgGradient.color2.rgb;
227 corner3 = myBgGradient.color1.rgb;
228 dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
229 dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
230 dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
234 case Aspect_GFM_CORNER1:
235 corner1 = myBgGradient.color2.rgb;
236 corner2 = myBgGradient.color2.rgb;
237 corner3 = myBgGradient.color2.rgb;
238 corner4 = myBgGradient.color1.rgb;
240 case Aspect_GFM_CORNER2:
241 corner1 = myBgGradient.color2.rgb;
242 corner2 = myBgGradient.color2.rgb;
243 corner3 = myBgGradient.color1.rgb;
244 corner4 = myBgGradient.color2.rgb;
246 case Aspect_GFM_CORNER3:
247 corner1 = myBgGradient.color2.rgb;
248 corner2 = myBgGradient.color1.rgb;
249 corner3 = myBgGradient.color2.rgb;
250 corner4 = myBgGradient.color2.rgb;
252 case Aspect_GFM_CORNER4:
253 corner1 = myBgGradient.color1.rgb;
254 corner2 = myBgGradient.color2.rgb;
255 corner3 = myBgGradient.color2.rgb;
256 corner4 = myBgGradient.color2.rgb;
259 //printf("gradient background type not right\n");
263 // Save GL parameters
264 glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
267 glGetIntegerv( GL_SHADE_MODEL, &curSM );
268 if ( curSM != GL_SMOOTH )
269 glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
271 glBegin(GL_TRIANGLE_FAN);
272 if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
274 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
275 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
276 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
277 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
279 else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
281 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
282 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
283 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
284 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
288 // Restore GL parameters
289 if ( curSM != GL_SMOOTH )
290 glShadeModel( curSM );
292 // drawing bg image if:
293 // - it is defined and
294 // - fill type is not Aspect_FM_NONE
295 if ( myBgTexture.TexId != 0 && myBgTexture.Style != Aspect_FM_NONE )
297 GLfloat texX_range = 1.F; // texture <s> coordinate
298 GLfloat texY_range = 1.F; // texture <t> coordinate
300 // Set up for stretching or tiling
301 GLfloat x_offset, y_offset;
302 if ( myBgTexture.Style == Aspect_FM_CENTERED )
304 x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
305 y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
311 if ( myBgTexture.Style == Aspect_FM_TILED )
313 texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
314 texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
318 // OCCT issue 0023000: Improve the way the gradient and textured
319 // background is managed in 3d viewer (note 0020339)
320 // Setting this coefficient to -1.F allows to tile textures relatively
321 // to the top-left corner of the view (value 1.F corresponds to the
322 // initial behaviour - tiling from the bottom-left corner)
323 GLfloat aCoef = -1.F;
325 glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
326 glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
328 glDisable( GL_BLEND ); //push GL_ENABLE_BIT
330 glColor3fv (theWorkspace.BackgroundColor().rgb);
331 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
333 // Note that texture is mapped using GL_REPEAT wrapping mode so integer part
334 // is simply ignored, and negative multiplier is here for convenience only
335 // and does not result e.g. in texture mirroring
337 glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -aCoef * y_offset );
338 glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -aCoef * y_offset );
339 glTexCoord2f(texX_range, aCoef * texY_range); glVertex2f( x_offset, aCoef * y_offset );
340 glTexCoord2f(0.F, aCoef * texY_range); glVertex2f( -x_offset, aCoef * y_offset );
344 aContext->WorldViewState.Pop();
345 aContext->ProjectionState.Pop();
347 aContext->ApplyProjectionMatrix();
349 glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
351 if (theWorkspace.UseZBuffer())
353 glEnable (GL_DEPTH_TEST);
359 /*----------------------------------------------------------------------*/
361 //call_func_redraw_all_structs_proc
362 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
363 const Handle(OpenGl_Workspace) &theWorkspace,
364 const Graphic3d_CView& theCView,
365 const Aspect_CLayer2d& theCUnderLayer,
366 const Aspect_CLayer2d& theCOverLayer)
368 // ==================================
369 // Step 1: Prepare for redraw
370 // ==================================
372 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
374 #if !defined(GL_ES_VERSION_2_0)
375 // store and disable current clipping planes
376 const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
377 NCollection_Array1<OPENGL_CLIP_PLANE> aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1);
378 if (aContext->core11 != NULL)
380 for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
382 OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
383 aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation);
384 if (aPlane.isEnabled)
386 aContext->core11fwd->glDisable (aClipPlaneId);
387 aPlane.isEnabled = GL_TRUE;
391 aPlane.isEnabled = GL_FALSE;
397 // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm).
398 Standard_Boolean isProjectionMatUpdateNeeded = Standard_False;
399 Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
400 if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
402 isProjectionMatUpdateNeeded = Standard_True;
403 myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
405 if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
407 isOrientationMatUpdateNeeded = Standard_True;
408 myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
411 if (isProjectionMatUpdateNeeded
412 || isOrientationMatUpdateNeeded)
414 myBVHSelector.SetViewVolume (myCamera);
417 const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
418 const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed
419 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
421 aManager->UpdateLightSourceStateTo (&myLights);
422 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
425 if (myProjectionState != myCamera->ProjectionState()
428 myProjectionState = myCamera->ProjectionState();
429 aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF());
430 aContext->ApplyProjectionMatrix();
433 if (myModelViewState != myCamera->ModelViewState()
436 myModelViewState = myCamera->ModelViewState();
437 aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF());
438 aContext->ApplyWorldViewMatrix();
441 if (aManager->ModelWorldState().Index() == 0)
443 aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4());
446 // ====================================
447 // Step 2: Redraw background
448 // ====================================
451 if (theWorkspace->ToRedrawGL())
453 DrawBackground (*theWorkspace);
456 #if !defined(GL_ES_VERSION_2_0)
457 // Switch off lighting by default
458 glDisable(GL_LIGHTING);
461 // =================================
462 // Step 3: Draw underlayer
463 // =================================
465 RedrawLayer2d (thePrintContext, theWorkspace, 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 !defined(GL_ES_VERSION_2_0)
486 // if the view is scaled normal vectors are scaled to unit
487 // length for correct displaying of shaded objects
488 const gp_Pnt anAxialScale = myCamera->AxialScale();
489 if (anAxialScale.X() != 1.F ||
490 anAxialScale.Y() != 1.F ||
491 anAxialScale.Z() != 1.F)
493 aContext->SetGlNormalizeEnabled (Standard_True);
497 aContext->SetGlNormalizeEnabled (Standard_False);
503 Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
504 if (myCamera->ZFar() < aFogFrontConverted)
506 aFogFrontConverted = myCamera->ZFar();
507 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
510 Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
511 if (myCamera->ZFar() < aFogFrontConverted)
513 aFogBackConverted = myCamera->ZFar();
514 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
517 if (aFogFrontConverted > aFogBackConverted)
519 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
520 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
523 glFogi(GL_FOG_MODE, GL_LINEAR);
524 glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
525 glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
526 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
532 // Apply InteriorShadingMethod
533 aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
534 || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
537 aManager->SetShadingModel (myShadingModel);
539 // Apply AntiAliasing
541 theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
543 theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
545 if (!aManager->IsEmpty())
547 aManager->UpdateClippingState();
551 if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
553 // single-pass monographic rendering
554 // redraw scene with normal orientation and projection
555 RedrawScene (thePrintContext, theWorkspace);
559 // two stereographic passes
561 // safely switch to left Eye buffer
562 aContext->SetDrawBufferLeft();
564 aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF());
565 aContext->ApplyProjectionMatrix();
568 RedrawScene (thePrintContext, theWorkspace);
570 // reset depth buffer of first rendering pass
571 if (theWorkspace->UseDepthTest())
573 glClear (GL_DEPTH_BUFFER_BIT);
575 // safely switch to right Eye buffer
576 aContext->SetDrawBufferRight();
578 aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF());
579 aContext->ApplyProjectionMatrix();
582 RedrawScene (thePrintContext, theWorkspace);
584 // switch back to monographic rendering
585 aContext->SetDrawBufferMono();
588 // ===============================
590 // ===============================
592 // Resetting GL parameters according to the default aspects
593 // in order to synchronize GL state with the graphic driver state
594 // before drawing auxiliary stuff (trihedrons, overlayer)
595 // and invoking optional callbacks
596 theWorkspace->ResetAppliedAspect();
598 aContext->ChangeClipping().RemoveAll();
600 if (!aManager->IsEmpty())
602 aManager->ResetMaterialStates();
603 aManager->RevertClippingState();
605 // We need to disable (unbind) all shaders programs to ensure
606 // that all objects without specified aspect will be drawn
607 // correctly (such as background)
608 aContext->BindProgram (NULL);
612 if (theWorkspace->ToRedrawGL())
614 RedrawTrihedron (theWorkspace);
616 // Restore face culling
621 glEnable ( GL_CULL_FACE );
622 glCullFace ( GL_BACK );
625 glDisable ( GL_CULL_FACE );
629 // ===============================
630 // Step 6: Redraw overlay
631 // ===============================
634 theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
636 RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer);
638 theWorkspace->DisplayCallback (theCView, aMode);
640 // ===============================
642 // ===============================
644 #if !defined(GL_ES_VERSION_2_0)
645 // restore clipping planes
646 if (aContext->core11 != NULL)
648 for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
650 const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
651 aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation);
652 if (aPlane.isEnabled)
653 aContext->core11fwd->glEnable (aClipPlaneId);
655 aContext->core11fwd->glDisable (aClipPlaneId);
660 // ==============================================================
661 // Step 8: Keep shader manager informed about last View
662 // ==============================================================
664 if (!aManager.IsNull())
666 aManager->SetLastView (this);
670 // =======================================================================
671 // function : InvalidateBVHData
673 // =======================================================================
674 void OpenGl_View::InvalidateBVHData (const Standard_Integer theLayerId)
676 myZLayers.InvalidateBVHData (theLayerId);
679 /*----------------------------------------------------------------------*/
682 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
684 if ( myZLayers.NbStructures() <= 0 )
687 #if !defined(GL_ES_VERSION_2_0)
688 glPushAttrib ( GL_DEPTH_BUFFER_BIT );
691 //TsmPushAttri(); /* save previous graphics context */
693 if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
695 #if !defined(GL_ES_VERSION_2_0)
696 const int antiAliasingMode = AWorkspace->AntiAliasingMode();
699 if ( !myAntiAliasing )
701 #if !defined(GL_ES_VERSION_2_0)
702 glDisable(GL_POINT_SMOOTH);
703 glDisable(GL_LINE_SMOOTH);
704 if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
706 glBlendFunc (GL_ONE, GL_ZERO);
707 glDisable (GL_BLEND);
711 #if !defined(GL_ES_VERSION_2_0)
712 glEnable(GL_POINT_SMOOTH);
713 glEnable(GL_LINE_SMOOTH);
714 if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
716 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
721 myZLayers.Render (AWorkspace);
723 #if !defined(GL_ES_VERSION_2_0)
724 //TsmPopAttri(); /* restore previous graphics context; before update lights */
729 /*----------------------------------------------------------------------*/
731 //call_togl_redraw_layer2d
732 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
733 const Handle(OpenGl_Workspace)& theWorkspace,
734 const Graphic3d_CView& ACView,
735 const Aspect_CLayer2d& ACLayer)
737 #if !defined(GL_ES_VERSION_2_0)
739 || ACLayer.ptrLayer == NULL
740 || ACLayer.ptrLayer->listIndex == 0) return;
742 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
744 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
745 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
747 aContext->WorldViewState.Push();
748 aContext->ProjectionState.Push();
750 aContext->WorldViewState.SetIdentity();
751 aContext->ProjectionState.SetIdentity();
753 aContext->ApplyWorldViewMatrix();
754 aContext->ApplyProjectionMatrix();
756 if (!ACLayer.sizeDependent)
757 aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight);
759 float left = ACLayer.ortho[0];
760 float right = ACLayer.ortho[1];
761 float bottom = ACLayer.ortho[2];
762 float top = ACLayer.ortho[3];
764 int attach = ACLayer.attach;
766 const float ratio = !ACLayer.sizeDependent
767 ? float(dispWidth) / float(dispHeight)
768 : float(theWorkspace->Width()) / float(theWorkspace->Height());
772 delta = (float )((top - bottom)/2.0);
774 case 0: /* Aspect_TOC_BOTTOM_LEFT */
775 top = bottom + 2*delta/ratio;
777 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
778 top = bottom + 2*delta/ratio;
780 case 2: /* Aspect_TOC_TOP_LEFT */
781 bottom = top - 2*delta/ratio;
783 case 3: /* Aspect_TOC_TOP_RIGHT */
784 bottom = top - 2*delta/ratio;
789 delta = (float )((right - left)/2.0);
791 case 0: /* Aspect_TOC_BOTTOM_LEFT */
792 right = left + 2*delta*ratio;
794 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
795 left = right - 2*delta*ratio;
797 case 2: /* Aspect_TOC_TOP_LEFT */
798 right = left + 2*delta*ratio;
800 case 3: /* Aspect_TOC_TOP_RIGHT */
801 left = right - 2*delta*ratio;
807 // Check printer context that exists only for print operation
808 if (!thePrintContext.IsNull())
810 // additional transformation matrix could be applied to
811 // render only those parts of viewport that will be
812 // passed to a printer as a current "frame" to provide
813 // tiling; scaling of graphics by matrix helps render a
814 // part of a view (frame) in same viewport, but with higher
817 // set printing scale/tiling transformation
818 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation());
819 aContext->ApplyProjectionMatrix();
821 // printing operation also assumes other viewport dimension
822 // to comply with transformation matrix or graphics scaling
823 // factors for tiling for layer redraw
824 GLsizei anViewportX = 0;
825 GLsizei anViewportY = 0;
826 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
827 if (anViewportX != 0 && anViewportY != 0)
828 aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY);
832 glOrtho (left, right, bottom, top, -1.0, 1.0);
835 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
836 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
838 glDisable (GL_DEPTH_TEST);
839 glDisable (GL_TEXTURE_1D);
840 glDisable (GL_TEXTURE_2D);
841 glDisable (GL_LIGHTING);
843 // TODO: Obsolete code, the display list is always empty now, to be removed
844 glCallList (ACLayer.ptrLayer->listIndex);
846 //calling dynamic render of LayerItems
847 if ( ACLayer.ptrLayer->layerData )
849 InitLayerProp (ACLayer.ptrLayer->listIndex);
850 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
856 aContext->WorldViewState.Pop();
857 aContext->ProjectionState.Pop();
859 aContext->ApplyProjectionMatrix();
860 aContext->ApplyWorldViewMatrix();
862 if (!ACLayer.sizeDependent)
863 aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height());
869 /*----------------------------------------------------------------------*/
871 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
873 // display global trihedron
874 if (myTrihedron != NULL)
876 myTrihedron->Render (theWorkspace);
878 if (myGraduatedTrihedron != NULL)
880 myGraduatedTrihedron->Render (theWorkspace);
884 /*----------------------------------------------------------------------*/
886 //call_togl_create_bg_texture
887 void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
888 const Aspect_FillMethod theFillStyle)
890 if (myBgTexture.TexId != 0)
892 // delete existing texture
893 glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
894 myBgTexture.TexId = 0;
897 // load image from file
898 Image_AlienPixMap anImageLoaded;
899 if (!anImageLoaded.Load (theFilePath))
904 Image_PixMap anImage;
905 if (anImageLoaded.RowExtraBytes() == 0 &&
906 (anImageLoaded.Format() == Image_PixMap::ImgRGB
907 || anImageLoaded.Format() == Image_PixMap::ImgRGB32
908 || anImageLoaded.Format() == Image_PixMap::ImgRGBA))
910 anImage.InitWrapper (anImageLoaded.Format(), anImageLoaded.ChangeData(),
911 anImageLoaded.SizeX(), anImageLoaded.SizeY(), anImageLoaded.SizeRowBytes());
915 // convert image to RGB format
916 if (!anImage.InitTrash (Image_PixMap::ImgRGB, anImageLoaded.SizeX(), anImageLoaded.SizeY()))
921 anImage.SetTopDown (false);
922 Quantity_Color aSrcColor;
923 for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
925 for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
927 aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
928 Image_ColorRGB& aColor = anImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
929 aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
930 aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
931 aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
934 anImageLoaded.Clear();
937 // create MipMapped texture
938 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
940 GLuint aTextureId = 0;
941 glGenTextures (1, &aTextureId);
942 glBindTexture (GL_TEXTURE_2D, aTextureId);
944 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
945 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
946 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
947 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
949 const GLenum aDataFormat = (anImage.Format() == Image_PixMap::ImgRGB) ? GL_RGB : GL_RGBA;
951 #if !defined(GL_ES_VERSION_2_0)
952 gluBuild2DMipmaps (GL_TEXTURE_2D, 3/*4*/,
953 GLint(anImage.SizeX()), GLint(anImage.SizeY()),
954 aDataFormat, GL_UNSIGNED_BYTE, anImage.Data());
957 myBgTexture.TexId = aTextureId;
958 myBgTexture.Width = (Standard_Integer )anImage.SizeX();
959 myBgTexture.Height = (Standard_Integer )anImage.SizeY();
960 myBgTexture.Style = theFillStyle;
963 /*----------------------------------------------------------------------*/
965 //call_togl_set_bg_texture_style
966 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
968 myBgTexture.Style = AFillStyle;
971 /*----------------------------------------------------------------------*/
973 //call_togl_gradient_background
974 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
975 const Quantity_Color& AColor2,
976 const Aspect_GradientFillMethod AType)
979 AColor1.Values( R, G, B, Quantity_TOC_RGB );
980 myBgGradient.color1.rgb[0] = ( Tfloat )R;
981 myBgGradient.color1.rgb[1] = ( Tfloat )G;
982 myBgGradient.color1.rgb[2] = ( Tfloat )B;
983 myBgGradient.color1.rgb[3] = 0.F;
985 AColor2.Values( R, G, B, Quantity_TOC_RGB );
986 myBgGradient.color2.rgb[0] = ( Tfloat )R;
987 myBgGradient.color2.rgb[1] = ( Tfloat )G;
988 myBgGradient.color2.rgb[2] = ( Tfloat )B;
989 myBgGradient.color2.rgb[3] = 0.F;
991 myBgGradient.type = AType;
994 /*----------------------------------------------------------------------*/
996 //call_togl_set_gradient_type
997 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
999 myBgGradient.type = AType;
1002 //=======================================================================
1003 //function : AddZLayer
1005 //=======================================================================
1007 void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
1009 myZLayers.AddLayer (theLayerId);
1012 //=======================================================================
1013 //function : RemoveZLayer
1015 //=======================================================================
1017 void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
1019 myZLayers.RemoveLayer (theLayerId);
1022 //=======================================================================
1023 //function : DisplayStructure
1025 //=======================================================================
1027 void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
1028 const Standard_Integer thePriority)
1030 Standard_Integer aZLayer = theStructure->GetZLayer ();
1031 myZLayers.AddStructure (theStructure, aZLayer, thePriority);
1034 //=======================================================================
1035 //function : DisplayImmediateStructure
1037 //=======================================================================
1039 void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructure)
1041 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1042 anIter.More(); anIter.Next())
1044 if (anIter.Value() == theStructure)
1050 myImmediateList.Append (theStructure);
1053 //=======================================================================
1054 //function : EraseStructure
1056 //=======================================================================
1058 void OpenGl_View::EraseStructure (const OpenGl_Structure *theStructure)
1060 Standard_Integer aZLayer = theStructure->GetZLayer ();
1061 myZLayers.RemoveStructure (theStructure, aZLayer);
1064 //=======================================================================
1065 //function : EraseImmediateStructure
1067 //=======================================================================
1069 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
1071 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1072 anIter.More(); anIter.Next())
1074 if (anIter.Value() == theStructure)
1076 myImmediateList.Remove (anIter);
1082 //=======================================================================
1083 //function : ChangeZLayer
1085 //=======================================================================
1087 void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
1088 const Standard_Integer theNewLayerId)
1090 Standard_Integer anOldLayer = theStructure->GetZLayer ();
1091 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
1094 //=======================================================================
1095 //function : SetZLayerSettings
1097 //=======================================================================
1098 void OpenGl_View::SetZLayerSettings (const Standard_Integer theLayerId,
1099 const Graphic3d_ZLayerSettings theSettings)
1101 myZLayers.Layer (theLayerId).SetLayerSettings (theSettings);
1104 //=======================================================================
1105 //function : ChangePriority
1107 //=======================================================================
1108 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
1109 const Standard_Integer theNewPriority)
1111 Standard_Integer aLayerId = theStructure->GetZLayer();
1112 myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
1115 //=======================================================================
1116 //function : RedrawScene
1118 //=======================================================================
1120 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
1121 const Handle(OpenGl_Workspace)& theWorkspace)
1123 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1125 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1127 Handle(Graphic3d_ClipPlane) aPlaneBack;
1128 Handle(Graphic3d_ClipPlane) aPlaneFront;
1130 if (myZClip.Back.IsOn)
1132 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1133 if (myCamera->ZFar() < aClipBackConverted)
1135 aClipBackConverted = myCamera->ZFar();
1136 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1138 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1139 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1142 if (myZClip.Front.IsOn)
1144 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1145 if (myCamera->ZNear() > aClipFrontConverted)
1147 aClipFrontConverted = myCamera->ZNear();
1148 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1150 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1151 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1154 // Specify slicing planes with identity transformation
1155 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1157 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1158 if (!aPlaneBack.IsNull())
1160 aSlicingPlanes.Append (aPlaneBack);
1163 if (!aPlaneFront.IsNull())
1165 aSlicingPlanes.Append (aPlaneFront);
1168 // add planes at loaded view matrix state
1169 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1174 // set printing scale/tiling transformation
1175 if (!thePrintContext.IsNull())
1177 aContext->ProjectionState.Push();
1178 aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current());
1179 aContext->ApplyProjectionMatrix();
1183 // Specify clipping planes in view transformation space
1184 if (!myClipPlanes.IsEmpty())
1186 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1187 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1188 for (; aClippingIt.More(); aClippingIt.Next())
1190 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1191 if (aClipPlane->IsOn())
1193 aUserPlanes.Append (aClipPlane);
1197 if (!aUserPlanes.IsEmpty())
1199 aContext->ChangeClipping().AddWorld (aUserPlanes);
1202 if (!aContext->ShaderManager()->IsEmpty())
1204 aContext->ShaderManager()->UpdateClippingState();
1208 #if !defined(GL_ES_VERSION_2_0)
1212 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1213 THE_DEFAULT_AMBIENT[1],
1214 THE_DEFAULT_AMBIENT[2],
1215 THE_DEFAULT_AMBIENT[3]);
1216 GLenum aLightGlId = GL_LIGHT0;
1217 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1218 aLightIt.More(); aLightIt.Next())
1220 bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace);
1223 // apply accumulated ambient color
1224 anAmbientColor.a() = 1.0f;
1225 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1227 if (aLightGlId != GL_LIGHT0)
1229 glEnable (GL_LIGHTING);
1231 // switch off unused lights
1232 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1234 glDisable (aLightGlId);
1239 // Clear status bitfields
1240 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1242 // Added PCT for handling of textures
1243 switch (mySurfaceDetail)
1245 case Visual3d_TOD_NONE:
1246 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1247 theWorkspace->DisableTexture();
1249 RenderStructs (theWorkspace);
1252 case Visual3d_TOD_ENVIRONMENT:
1253 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1254 theWorkspace->EnableTexture (myTextureEnv);
1256 RenderStructs (theWorkspace);
1257 theWorkspace->DisableTexture();
1260 case Visual3d_TOD_ALL:
1262 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1264 RenderStructs (theWorkspace);
1265 theWorkspace->DisableTexture();
1268 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1270 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1271 theWorkspace->EnableTexture (myTextureEnv);
1273 // Remember OpenGl properties
1274 GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1275 GLint aSaveZbuffFunc;
1276 GLboolean aSaveZbuffWrite;
1277 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1278 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1279 #if !defined(GL_ES_VERSION_2_0)
1280 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1281 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1283 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1284 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1286 // Change the properties for second rendering pass
1287 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1288 glEnable (GL_BLEND);
1290 glDepthFunc (GL_EQUAL);
1291 glDepthMask (GL_FALSE);
1292 glEnable (GL_DEPTH_TEST);
1294 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1297 RenderStructs (theWorkspace);
1298 theWorkspace->DisableTexture();
1300 // Restore properties back
1301 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1302 if (!wasBlendEnabled)
1303 glDisable (GL_BLEND);
1305 glDepthFunc (aSaveZbuffFunc);
1306 glDepthMask (aSaveZbuffWrite);
1307 if (!wasZbuffEnabled)
1308 glDisable (GL_DEPTH_FUNC);
1313 // Apply restored view matrix.
1314 aContext->ApplyWorldViewMatrix();
1317 // set printing scale/tiling transformation
1318 if (!thePrintContext.IsNull())
1320 aContext->ProjectionState.Pop();
1321 aContext->ApplyProjectionMatrix();