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 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++);
159 /*----------------------------------------------------------------------*/
161 void OpenGl_View::DrawBackground (OpenGl_Workspace& theWorkspace)
163 #if !defined(GL_ES_VERSION_2_0)
164 if ( (theWorkspace.NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
165 ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
167 const Standard_Integer aViewWidth = theWorkspace.Width();
168 const Standard_Integer aViewHeight = theWorkspace.Height();
170 glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
172 glMatrixMode( GL_PROJECTION );
175 glMatrixMode( GL_MODELVIEW );
179 if ( glIsEnabled( GL_DEPTH_TEST ) )
180 glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
182 // drawing bg gradient if:
183 // - gradient fill type is not Aspect_GFM_NONE and
184 // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
185 if ( ( myBgGradient.type != Aspect_GFM_NONE ) &&
186 ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
187 myBgTexture.Style == Aspect_FM_NONE ) )
189 Tfloat* corner1 = 0;/* -1,-1*/
190 Tfloat* corner2 = 0;/* 1,-1*/
191 Tfloat* corner3 = 0;/* 1, 1*/
192 Tfloat* corner4 = 0;/* -1, 1*/
196 switch( myBgGradient.type )
199 corner1 = myBgGradient.color1.rgb;
200 corner2 = myBgGradient.color2.rgb;
201 corner3 = myBgGradient.color2.rgb;
202 corner4 = myBgGradient.color1.rgb;
205 corner1 = myBgGradient.color2.rgb;
206 corner2 = myBgGradient.color2.rgb;
207 corner3 = myBgGradient.color1.rgb;
208 corner4 = myBgGradient.color1.rgb;
210 case Aspect_GFM_DIAG1:
211 corner2 = myBgGradient.color2.rgb;
212 corner4 = myBgGradient.color1.rgb;
213 dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
214 dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
215 dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
219 case Aspect_GFM_DIAG2:
220 corner1 = myBgGradient.color2.rgb;
221 corner3 = myBgGradient.color1.rgb;
222 dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
223 dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
224 dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
228 case Aspect_GFM_CORNER1:
229 corner1 = myBgGradient.color2.rgb;
230 corner2 = myBgGradient.color2.rgb;
231 corner3 = myBgGradient.color2.rgb;
232 corner4 = myBgGradient.color1.rgb;
234 case Aspect_GFM_CORNER2:
235 corner1 = myBgGradient.color2.rgb;
236 corner2 = myBgGradient.color2.rgb;
237 corner3 = myBgGradient.color1.rgb;
238 corner4 = myBgGradient.color2.rgb;
240 case Aspect_GFM_CORNER3:
241 corner1 = myBgGradient.color2.rgb;
242 corner2 = myBgGradient.color1.rgb;
243 corner3 = myBgGradient.color2.rgb;
244 corner4 = myBgGradient.color2.rgb;
246 case Aspect_GFM_CORNER4:
247 corner1 = myBgGradient.color1.rgb;
248 corner2 = myBgGradient.color2.rgb;
249 corner3 = myBgGradient.color2.rgb;
250 corner4 = myBgGradient.color2.rgb;
253 //printf("gradient background type not right\n");
257 // Save GL parameters
258 glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
261 glGetIntegerv( GL_SHADE_MODEL, &curSM );
262 if ( curSM != GL_SMOOTH )
263 glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
265 glBegin(GL_TRIANGLE_FAN);
266 if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
268 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
269 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
270 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
271 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
273 else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
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.);
278 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
282 // Restore GL parameters
283 if ( curSM != GL_SMOOTH )
284 glShadeModel( curSM );
286 // drawing bg image if:
287 // - it is defined and
288 // - fill type is not Aspect_FM_NONE
289 if ( myBgTexture.TexId != 0 && myBgTexture.Style != Aspect_FM_NONE )
291 GLfloat texX_range = 1.F; // texture <s> coordinate
292 GLfloat texY_range = 1.F; // texture <t> coordinate
294 // Set up for stretching or tiling
295 GLfloat x_offset, y_offset;
296 if ( myBgTexture.Style == Aspect_FM_CENTERED )
298 x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
299 y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
305 if ( myBgTexture.Style == Aspect_FM_TILED )
307 texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
308 texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
312 // OCCT issue 0023000: Improve the way the gradient and textured
313 // background is managed in 3d viewer (note 0020339)
314 // Setting this coefficient to -1.F allows to tile textures relatively
315 // to the top-left corner of the view (value 1.F corresponds to the
316 // initial behaviour - tiling from the bottom-left corner)
317 GLfloat aCoef = -1.F;
319 glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
320 glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
322 glDisable( GL_BLEND ); //push GL_ENABLE_BIT
324 glColor3fv (theWorkspace.BackgroundColor().rgb);
325 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
327 // Note that texture is mapped using GL_REPEAT wrapping mode so integer part
328 // is simply ignored, and negative multiplier is here for convenience only
329 // and does not result e.g. in texture mirroring
331 glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -aCoef * y_offset );
332 glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -aCoef * y_offset );
333 glTexCoord2f(texX_range, aCoef * texY_range); glVertex2f( x_offset, aCoef * y_offset );
334 glTexCoord2f(0.F, aCoef * texY_range); glVertex2f( -x_offset, aCoef * y_offset );
339 glMatrixMode( GL_PROJECTION );
341 glMatrixMode( GL_MODELVIEW );
343 glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
345 if (theWorkspace.UseZBuffer())
347 glEnable (GL_DEPTH_TEST);
353 /*----------------------------------------------------------------------*/
355 //call_func_redraw_all_structs_proc
356 void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
357 const Handle(OpenGl_Workspace) &theWorkspace,
358 const Graphic3d_CView& theCView,
359 const Aspect_CLayer2d& theCUnderLayer,
360 const Aspect_CLayer2d& theCOverLayer)
362 // ==================================
363 // Step 1: Prepare for redraw
364 // ==================================
366 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
368 #if !defined(GL_ES_VERSION_2_0)
369 // store and disable current clipping planes
370 const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
371 NCollection_Array1<OPENGL_CLIP_PLANE> aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1);
372 if (aContext->core11 != NULL)
374 for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
376 OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
377 aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation);
378 if (aPlane.isEnabled)
380 aContext->core11fwd->glDisable (aClipPlaneId);
381 aPlane.isEnabled = GL_TRUE;
385 aPlane.isEnabled = GL_FALSE;
391 Standard_Boolean isProjectionMatUpdateNeeded = Standard_False;
392 Standard_Boolean isOrientationMatUpdateNeeded = Standard_False;
393 if (myBVHSelector.ProjectionState() != myCamera->ProjectionState())
395 isProjectionMatUpdateNeeded = Standard_True;
396 myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState();
398 if (myBVHSelector.ModelViewState() != myCamera->ModelViewState())
400 isOrientationMatUpdateNeeded = Standard_True;
401 myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState();
404 // Set OCCT state uniform variables
405 const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
406 const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed
407 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
409 aManager->UpdateLightSourceStateTo (&myLights);
410 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
413 if (myProjectionState != myCamera->ProjectionState()
416 myProjectionState = myCamera->ProjectionState();
417 aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
420 if (myModelViewState != myCamera->ModelViewState()
423 myModelViewState = myCamera->ModelViewState();
424 aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
427 if (aManager->ModelWorldState().Index() == 0)
429 Tmatrix3 aModelWorldState = { { 1.f, 0.f, 0.f, 0.f },
430 { 0.f, 1.f, 0.f, 0.f },
431 { 0.f, 0.f, 1.f, 0.f },
432 { 0.f, 0.f, 0.f, 1.f } };
434 aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorldState);
437 if (isProjectionMatUpdateNeeded
438 || isOrientationMatUpdateNeeded)
440 myBVHSelector.SetViewVolume (myCamera);
443 // ====================================
444 // Step 2: Redraw background
445 // ====================================
448 if (theWorkspace->ToRedrawGL())
450 DrawBackground (*theWorkspace);
453 #if !defined(GL_ES_VERSION_2_0)
454 // Switch off lighting by default
455 glDisable(GL_LIGHTING);
458 // =================================
459 // Step 3: Draw underlayer
460 // =================================
462 RedrawLayer2d (thePrintContext, theCView, theCUnderLayer);
464 // =================================
465 // Step 4: Redraw main plane
466 // =================================
468 // Setup face culling
469 GLboolean isCullFace = GL_FALSE;
472 isCullFace = glIsEnabled( GL_CULL_FACE );
473 if ( myBackfacing < 0 )
475 glEnable( GL_CULL_FACE );
476 glCullFace( GL_BACK );
479 glDisable( GL_CULL_FACE );
482 #if !defined(GL_ES_VERSION_2_0)
483 // if the view is scaled normal vectors are scaled to unit
484 // length for correct displaying of shaded objects
485 const gp_Pnt anAxialScale = myCamera->AxialScale();
486 if(anAxialScale.X() != 1.F ||
487 anAxialScale.Y() != 1.F ||
488 anAxialScale.Z() != 1.F)
489 glEnable(GL_NORMALIZE);
490 else if(glIsEnabled(GL_NORMALIZE))
491 glDisable(GL_NORMALIZE);
496 Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
497 if (myCamera->ZFar() < aFogFrontConverted)
499 aFogFrontConverted = myCamera->ZFar();
500 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
503 Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
504 if (myCamera->ZFar() < aFogFrontConverted)
506 aFogBackConverted = myCamera->ZFar();
507 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
510 if (aFogFrontConverted > aFogBackConverted)
512 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
513 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
516 glFogi(GL_FOG_MODE, GL_LINEAR);
517 glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
518 glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
519 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
525 // Apply InteriorShadingMethod
526 aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET
527 || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH);
530 aManager->SetShadingModel (myShadingModel);
532 // Apply AntiAliasing
534 theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
536 theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
538 if (!aManager->IsEmpty())
540 aManager->UpdateClippingState();
544 if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
546 // single-pass monographic rendering
547 const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
549 const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
551 // redraw scene with normal orientation and projection
552 RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
556 // two stereographic passes
557 const OpenGl_Matrix* aLProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
558 const OpenGl_Matrix* aRProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
559 const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
561 // safely switch to left Eye buffer
562 aContext->SetDrawBufferLeft();
565 RedrawScene (thePrintContext, theWorkspace, aLProj, aOrient);
567 // reset depth buffer of first rendering pass
568 if (theWorkspace->UseDepthTest())
570 glClear (GL_DEPTH_BUFFER_BIT);
572 // safely switch to right Eye buffer
573 aContext->SetDrawBufferRight();
576 RedrawScene (thePrintContext, theWorkspace, aRProj, aOrient);
578 // switch back to monographic rendering
579 aContext->SetDrawBufferMono();
582 // ===============================
584 // ===============================
586 // Resetting GL parameters according to the default aspects
587 // in order to synchronize GL state with the graphic driver state
588 // before drawing auxiliary stuff (trihedrons, overlayer)
589 // and invoking optional callbacks
590 theWorkspace->ResetAppliedAspect();
592 aContext->ChangeClipping().RemoveAll();
594 if (!aManager->IsEmpty())
596 aManager->ResetMaterialStates();
597 aManager->RevertClippingState();
599 // We need to disable (unbind) all shaders programs to ensure
600 // that all objects without specified aspect will be drawn
601 // correctly (such as background)
602 aContext->BindProgram (NULL);
606 if (theWorkspace->ToRedrawGL())
608 RedrawTrihedron (theWorkspace);
610 // Restore face culling
615 glEnable ( GL_CULL_FACE );
616 glCullFace ( GL_BACK );
619 glDisable ( GL_CULL_FACE );
623 // ===============================
624 // Step 6: Redraw overlay
625 // ===============================
628 theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
630 RedrawLayer2d (thePrintContext, theCView, theCOverLayer);
632 theWorkspace->DisplayCallback (theCView, aMode);
634 // ===============================
636 // ===============================
638 #if !defined(GL_ES_VERSION_2_0)
639 // restore clipping planes
640 if (aContext->core11 != NULL)
642 for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId)
644 const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId);
645 aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation);
646 if (aPlane.isEnabled)
647 aContext->core11fwd->glEnable (aClipPlaneId);
649 aContext->core11fwd->glDisable (aClipPlaneId);
654 // ==============================================================
655 // Step 8: Keep shader manager informed about last View
656 // ==============================================================
658 if (!aManager.IsNull())
660 aManager->SetLastView (this);
664 // =======================================================================
665 // function : InvalidateBVHData
667 // =======================================================================
668 void OpenGl_View::InvalidateBVHData (const Standard_Integer theLayerId)
670 myZLayers.InvalidateBVHData (theLayerId);
673 /*----------------------------------------------------------------------*/
676 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
678 if ( myZLayers.NbStructures() <= 0 )
681 #if !defined(GL_ES_VERSION_2_0)
682 glPushAttrib ( GL_DEPTH_BUFFER_BIT );
685 //TsmPushAttri(); /* save previous graphics context */
687 if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
689 #if !defined(GL_ES_VERSION_2_0)
690 const int antiAliasingMode = AWorkspace->AntiAliasingMode();
693 if ( !myAntiAliasing )
695 #if !defined(GL_ES_VERSION_2_0)
696 glDisable(GL_POINT_SMOOTH);
697 glDisable(GL_LINE_SMOOTH);
698 if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
700 glBlendFunc (GL_ONE, GL_ZERO);
701 glDisable (GL_BLEND);
705 #if !defined(GL_ES_VERSION_2_0)
706 glEnable(GL_POINT_SMOOTH);
707 glEnable(GL_LINE_SMOOTH);
708 if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
710 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
715 myZLayers.Render (AWorkspace);
717 #if !defined(GL_ES_VERSION_2_0)
718 //TsmPopAttri(); /* restore previous graphics context; before update lights */
723 /*----------------------------------------------------------------------*/
725 //call_togl_redraw_layer2d
726 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
727 const Graphic3d_CView& ACView,
728 const Aspect_CLayer2d& ACLayer)
730 #if !defined(GL_ES_VERSION_2_0)
732 || ACLayer.ptrLayer == NULL
733 || ACLayer.ptrLayer->listIndex == 0) return;
735 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
736 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
738 glMatrixMode( GL_MODELVIEW );
742 glMatrixMode (GL_PROJECTION);
746 if (!ACLayer.sizeDependent)
747 glViewport (0, 0, dispWidth, dispHeight);
749 float left = ACLayer.ortho[0];
750 float right = ACLayer.ortho[1];
751 float bottom = ACLayer.ortho[2];
752 float top = ACLayer.ortho[3];
754 int attach = ACLayer.attach;
757 if (!ACLayer.sizeDependent)
758 ratio = (float) dispWidth/dispHeight;
760 ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
764 delta = (float )((top - bottom)/2.0);
766 case 0: /* Aspect_TOC_BOTTOM_LEFT */
767 top = bottom + 2*delta/ratio;
769 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
770 top = bottom + 2*delta/ratio;
772 case 2: /* Aspect_TOC_TOP_LEFT */
773 bottom = top - 2*delta/ratio;
775 case 3: /* Aspect_TOC_TOP_RIGHT */
776 bottom = top - 2*delta/ratio;
781 delta = (float )((right - left)/2.0);
783 case 0: /* Aspect_TOC_BOTTOM_LEFT */
784 right = left + 2*delta*ratio;
786 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
787 left = right - 2*delta*ratio;
789 case 2: /* Aspect_TOC_TOP_LEFT */
790 right = left + 2*delta*ratio;
792 case 3: /* Aspect_TOC_TOP_RIGHT */
793 left = right - 2*delta*ratio;
799 // Check printer context that exists only for print operation
800 if (!thePrintContext.IsNull())
802 // additional transformation matrix could be applied to
803 // render only those parts of viewport that will be
804 // passed to a printer as a current "frame" to provide
805 // tiling; scaling of graphics by matrix helps render a
806 // part of a view (frame) in same viewport, but with higher
808 thePrintContext->LoadProjTransformation();
810 // printing operation also assumes other viewport dimension
811 // to comply with transformation matrix or graphics scaling
812 // factors for tiling for layer redraw
813 GLsizei anViewportX = 0;
814 GLsizei anViewportY = 0;
815 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
816 if (anViewportX != 0 && anViewportY != 0)
817 glViewport (0, 0, anViewportX, anViewportY);
821 glOrtho (left, right, bottom, top, -1.0, 1.0);
824 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
825 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
827 glDisable (GL_DEPTH_TEST);
828 glDisable (GL_TEXTURE_1D);
829 glDisable (GL_TEXTURE_2D);
830 glDisable (GL_LIGHTING);
832 // TODO: Obsolete code, the display list is always empty now, to be removed
833 glCallList (ACLayer.ptrLayer->listIndex);
835 //calling dynamic render of LayerItems
836 if ( ACLayer.ptrLayer->layerData )
838 InitLayerProp (ACLayer.ptrLayer->listIndex);
839 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
845 glMatrixMode (GL_PROJECTION);
848 glMatrixMode( GL_MODELVIEW );
851 if (!ACLayer.sizeDependent)
852 glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
858 /*----------------------------------------------------------------------*/
860 void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace)
862 // display global trihedron
863 if (myTrihedron != NULL)
865 myTrihedron->Render (theWorkspace);
867 if (myGraduatedTrihedron != NULL)
869 myGraduatedTrihedron->Render (theWorkspace);
873 /*----------------------------------------------------------------------*/
875 //call_togl_create_bg_texture
876 void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
877 const Aspect_FillMethod theFillStyle)
879 if (myBgTexture.TexId != 0)
881 // delete existing texture
882 glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
883 myBgTexture.TexId = 0;
886 // load image from file
887 Image_AlienPixMap anImageLoaded;
888 if (!anImageLoaded.Load (theFilePath))
893 Image_PixMap anImage;
894 if (anImageLoaded.RowExtraBytes() == 0 &&
895 (anImageLoaded.Format() == Image_PixMap::ImgRGB
896 || anImageLoaded.Format() == Image_PixMap::ImgRGB32
897 || anImageLoaded.Format() == Image_PixMap::ImgRGBA))
899 anImage.InitWrapper (anImageLoaded.Format(), anImageLoaded.ChangeData(),
900 anImageLoaded.SizeX(), anImageLoaded.SizeY(), anImageLoaded.SizeRowBytes());
904 // convert image to RGB format
905 if (!anImage.InitTrash (Image_PixMap::ImgRGB, anImageLoaded.SizeX(), anImageLoaded.SizeY()))
910 anImage.SetTopDown (false);
911 Quantity_Color aSrcColor;
912 for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
914 for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
916 aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
917 Image_ColorRGB& aColor = anImage.ChangeValue<Image_ColorRGB> (aRow, aCol);
918 aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
919 aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
920 aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
923 anImageLoaded.Clear();
926 // create MipMapped texture
927 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
929 GLuint aTextureId = 0;
930 glGenTextures (1, &aTextureId);
931 glBindTexture (GL_TEXTURE_2D, aTextureId);
933 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
934 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
935 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
936 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
938 const GLenum aDataFormat = (anImage.Format() == Image_PixMap::ImgRGB) ? GL_RGB : GL_RGBA;
940 #if !defined(GL_ES_VERSION_2_0)
941 gluBuild2DMipmaps (GL_TEXTURE_2D, 3/*4*/,
942 GLint(anImage.SizeX()), GLint(anImage.SizeY()),
943 aDataFormat, GL_UNSIGNED_BYTE, anImage.Data());
946 myBgTexture.TexId = aTextureId;
947 myBgTexture.Width = (Standard_Integer )anImage.SizeX();
948 myBgTexture.Height = (Standard_Integer )anImage.SizeY();
949 myBgTexture.Style = theFillStyle;
952 /*----------------------------------------------------------------------*/
954 //call_togl_set_bg_texture_style
955 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
957 myBgTexture.Style = AFillStyle;
960 /*----------------------------------------------------------------------*/
962 //call_togl_gradient_background
963 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
964 const Quantity_Color& AColor2,
965 const Aspect_GradientFillMethod AType)
968 AColor1.Values( R, G, B, Quantity_TOC_RGB );
969 myBgGradient.color1.rgb[0] = ( Tfloat )R;
970 myBgGradient.color1.rgb[1] = ( Tfloat )G;
971 myBgGradient.color1.rgb[2] = ( Tfloat )B;
972 myBgGradient.color1.rgb[3] = 0.F;
974 AColor2.Values( R, G, B, Quantity_TOC_RGB );
975 myBgGradient.color2.rgb[0] = ( Tfloat )R;
976 myBgGradient.color2.rgb[1] = ( Tfloat )G;
977 myBgGradient.color2.rgb[2] = ( Tfloat )B;
978 myBgGradient.color2.rgb[3] = 0.F;
980 myBgGradient.type = AType;
983 /*----------------------------------------------------------------------*/
985 //call_togl_set_gradient_type
986 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
988 myBgGradient.type = AType;
991 //=======================================================================
992 //function : AddZLayer
994 //=======================================================================
996 void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
998 myZLayers.AddLayer (theLayerId);
1001 //=======================================================================
1002 //function : RemoveZLayer
1004 //=======================================================================
1006 void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
1008 myZLayers.RemoveLayer (theLayerId);
1011 //=======================================================================
1012 //function : DisplayStructure
1014 //=======================================================================
1016 void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
1017 const Standard_Integer thePriority)
1019 Standard_Integer aZLayer = theStructure->GetZLayer ();
1020 myZLayers.AddStructure (theStructure, aZLayer, thePriority);
1023 //=======================================================================
1024 //function : DisplayImmediateStructure
1026 //=======================================================================
1028 void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructure)
1030 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1031 anIter.More(); anIter.Next())
1033 if (anIter.Value() == theStructure)
1039 myImmediateList.Append (theStructure);
1042 //=======================================================================
1043 //function : EraseStructure
1045 //=======================================================================
1047 void OpenGl_View::EraseStructure (const OpenGl_Structure *theStructure)
1049 Standard_Integer aZLayer = theStructure->GetZLayer ();
1050 myZLayers.RemoveStructure (theStructure, aZLayer);
1053 //=======================================================================
1054 //function : EraseImmediateStructure
1056 //=======================================================================
1058 void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
1060 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
1061 anIter.More(); anIter.Next())
1063 if (anIter.Value() == theStructure)
1065 myImmediateList.Remove (anIter);
1071 //=======================================================================
1072 //function : ChangeZLayer
1074 //=======================================================================
1076 void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
1077 const Standard_Integer theNewLayerId)
1079 Standard_Integer anOldLayer = theStructure->GetZLayer ();
1080 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
1083 //=======================================================================
1084 //function : SetZLayerSettings
1086 //=======================================================================
1087 void OpenGl_View::SetZLayerSettings (const Standard_Integer theLayerId,
1088 const Graphic3d_ZLayerSettings theSettings)
1090 myZLayers.Layer (theLayerId).SetLayerSettings (theSettings);
1093 //=======================================================================
1094 //function : ChangePriority
1096 //=======================================================================
1097 void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure,
1098 const Standard_Integer theNewPriority)
1100 Standard_Integer aLayerId = theStructure->GetZLayer();
1101 myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority);
1104 //=======================================================================
1105 //function : RedrawScene
1107 //=======================================================================
1109 void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
1110 const Handle(OpenGl_Workspace)& theWorkspace,
1111 const OpenGl_Matrix* theProjection,
1112 const OpenGl_Matrix* theOrientation)
1114 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1116 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1118 Handle(Graphic3d_ClipPlane) aPlaneBack;
1119 Handle(Graphic3d_ClipPlane) aPlaneFront;
1121 if (myZClip.Back.IsOn)
1123 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1124 if (myCamera->ZFar() < aClipBackConverted)
1126 aClipBackConverted = myCamera->ZFar();
1127 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1129 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1130 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1133 if (myZClip.Front.IsOn)
1135 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1136 if (myCamera->ZNear() > aClipFrontConverted)
1138 aClipFrontConverted = myCamera->ZNear();
1139 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1141 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1142 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1145 // Specify slicing planes with identity transformation
1146 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1148 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1149 if (!aPlaneBack.IsNull())
1151 aSlicingPlanes.Append (aPlaneBack);
1154 if (!aPlaneFront.IsNull())
1156 aSlicingPlanes.Append (aPlaneFront);
1159 // add planes at loaded view matrix state
1160 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1164 #if !defined(GL_ES_VERSION_2_0)
1165 // Setup view projection
1166 glMatrixMode (GL_PROJECTION);
1169 // add printing scale/tiling transformation
1170 if (!thePrintContext.IsNull())
1172 thePrintContext->LoadProjTransformation();
1178 glMultMatrixf ((const GLfloat*)theProjection);
1180 if (!thePrintContext.IsNull())
1182 // update shader uniform projection matrix with new data
1183 Tmatrix3 aResultProjection;
1184 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
1185 aContext->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
1187 // force shader uniform restore on next frame
1188 myProjectionState = 0;
1192 // Setup view orientation
1193 theWorkspace->SetViewMatrix (theOrientation);
1195 // Specify clipping planes in view transformation space
1196 if (!myClipPlanes.IsEmpty())
1198 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1199 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1200 for (; aClippingIt.More(); aClippingIt.Next())
1202 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1203 if (aClipPlane->IsOn())
1205 aUserPlanes.Append (aClipPlane);
1209 if (!aUserPlanes.IsEmpty())
1211 aContext->ChangeClipping().AddWorld (aUserPlanes);
1214 if (!aContext->ShaderManager()->IsEmpty())
1216 aContext->ShaderManager()->UpdateClippingState();
1220 #if !defined(GL_ES_VERSION_2_0)
1224 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1225 THE_DEFAULT_AMBIENT[1],
1226 THE_DEFAULT_AMBIENT[2],
1227 THE_DEFAULT_AMBIENT[3]);
1228 GLenum aLightGlId = GL_LIGHT0;
1229 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1230 aLightIt.More(); aLightIt.Next())
1232 bind_light (aLightIt.Value(), aLightGlId, anAmbientColor);
1235 // apply accumulated ambient color
1236 anAmbientColor.a() = 1.0f;
1237 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1239 if (aLightGlId != GL_LIGHT0)
1241 glEnable (GL_LIGHTING);
1243 // switch off unused lights
1244 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1246 glDisable (aLightGlId);
1251 // Clear status bitfields
1252 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1254 // Added PCT for handling of textures
1255 switch (mySurfaceDetail)
1257 case Visual3d_TOD_NONE:
1258 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1259 theWorkspace->DisableTexture();
1261 RenderStructs (theWorkspace);
1264 case Visual3d_TOD_ENVIRONMENT:
1265 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1266 theWorkspace->EnableTexture (myTextureEnv);
1268 RenderStructs (theWorkspace);
1269 theWorkspace->DisableTexture();
1272 case Visual3d_TOD_ALL:
1274 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1276 RenderStructs (theWorkspace);
1277 theWorkspace->DisableTexture();
1280 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1282 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1283 theWorkspace->EnableTexture (myTextureEnv);
1285 // Remember OpenGl properties
1286 GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA;
1287 GLint aSaveZbuffFunc;
1288 GLboolean aSaveZbuffWrite;
1289 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1290 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1291 #if !defined(GL_ES_VERSION_2_0)
1292 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1293 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1295 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1296 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1298 // Change the properties for second rendering pass
1299 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1300 glEnable (GL_BLEND);
1302 glDepthFunc (GL_EQUAL);
1303 glDepthMask (GL_FALSE);
1304 glEnable (GL_DEPTH_TEST);
1306 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1309 RenderStructs (theWorkspace);
1310 theWorkspace->DisableTexture();
1312 // Restore properties back
1313 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1314 if (!wasBlendEnabled)
1315 glDisable (GL_BLEND);
1317 glDepthFunc (aSaveZbuffFunc);
1318 glDepthMask (aSaveZbuffWrite);
1319 if (!wasZbuffEnabled)
1320 glDisable (GL_DEPTH_FUNC);