0024637: Visualization - clean up implementation of rendering in immediate mode
[occt.git] / src / OpenGl / OpenGl_View_2.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
973c2be1 3// Copyright (c) 2011-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
2166f0fa
SK
16#include <stdio.h>
17#include <stdlib.h>
18
5f8b738e 19#include <OpenGl_GlCore11.hxx>
2166f0fa 20#include <OpenGl_tgl_funcs.hxx>
2166f0fa 21
3c3131a0 22#include <Image_AlienPixMap.hxx>
2166f0fa
SK
23#include <Visual3d_Layer.hxx>
24
30f0ad28 25#include <NCollection_Mat4.hxx>
26
2166f0fa 27#include <OpenGl_AspectLine.hxx>
30f0ad28 28#include <OpenGl_Context.hxx>
2166f0fa 29#include <OpenGl_Display.hxx>
30f0ad28 30#include <OpenGl_Matrix.hxx>
2166f0fa
SK
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>
30f0ad28 36#include <OpenGl_ShaderManager.hxx>
37#include <OpenGl_ShaderProgram.hxx>
59f45b7c 38#include <OpenGl_Structure.hxx>
2166f0fa 39
2166f0fa
SK
40#define EPSI 0.0001
41
12381341 42namespace
43{
44
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;
49
50};
2166f0fa 51
30f0ad28 52extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
2166f0fa
SK
53
54/*----------------------------------------------------------------------*/
55
56struct OPENGL_CLIP_PLANE
57{
58 GLboolean isEnabled;
59 GLdouble Equation[4];
1c35b92f 60 DEFINE_STANDARD_ALLOC
2166f0fa
SK
61};
62
63/*----------------------------------------------------------------------*/
64/*
65* Fonctions privees
66*/
67
68/*-----------------------------------------------------------------*/
69/*
70* Set des lumieres
71*/
12381341 72static void bind_light (const OpenGl_Light& theLight,
4fe9ad57 73 GLenum& theLightGlId,
74 Graphic3d_Vec4& theAmbientColor)
2166f0fa
SK
75{
76 // Only 8 lights in OpenGL...
12381341 77 if (theLightGlId > GL_LIGHT7)
2166f0fa 78 {
12381341 79 return;
2166f0fa
SK
80 }
81
12381341 82 if (theLight.Type == Visual3d_TOLS_AMBIENT)
2166f0fa 83 {
4fe9ad57 84 // add RGBA intensity of the ambient light
85 theAmbientColor += theLight.Color;
12381341 86 return;
87 }
2166f0fa 88
12381341 89 // the light is a headlight?
90 GLint aMatrixModeOld = 0;
91 if (theLight.IsHeadlight)
92 {
93 glGetIntegerv (GL_MATRIX_MODE, &aMatrixModeOld);
94 glMatrixMode (GL_MODELVIEW);
95 glPushMatrix();
96 glLoadIdentity();
2166f0fa
SK
97 }
98
12381341 99 // setup light type
100 switch (theLight.Type)
3c3131a0 101 {
12381341 102 case Visual3d_TOLS_DIRECTIONAL:
103 {
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;
106
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);
115 break;
116 }
117 case Visual3d_TOLS_POSITIONAL:
118 {
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);
130 break;
131 }
132 case Visual3d_TOLS_SPOT:
133 {
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);
144 break;
145 }
2166f0fa
SK
146 }
147
12381341 148 // restore matrix in case of headlight
149 if (theLight.IsHeadlight)
2166f0fa
SK
150 {
151 glPopMatrix();
12381341 152 glMatrixMode (aMatrixModeOld);
2166f0fa 153 }
12381341 154
155 glEnable (theLightGlId++);
2166f0fa
SK
156}
157
158/*----------------------------------------------------------------------*/
2166f0fa 159
b5ac8292 160void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
2166f0fa 161{
b5ac8292 162 if ( (theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
163 ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
2166f0fa 164 {
b5ac8292 165 const Standard_Integer aViewWidth = theWorkspace->Width();
166 const Standard_Integer aViewHeight = theWorkspace->Height();
2166f0fa
SK
167
168 glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
169
170 glMatrixMode( GL_PROJECTION );
171 glPushMatrix();
172 glLoadIdentity();
173 glMatrixMode( GL_MODELVIEW );
174 glPushMatrix();
175 glLoadIdentity();
176
177 if ( glIsEnabled( GL_DEPTH_TEST ) )
178 glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
179
f8b2ed36 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 ) &&
e276548b 184 ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
185 myBgTexture.Style == Aspect_FM_NONE ) )
2166f0fa
SK
186 {
187 Tfloat* corner1 = 0;/* -1,-1*/
188 Tfloat* corner2 = 0;/* 1,-1*/
189 Tfloat* corner3 = 0;/* 1, 1*/
190 Tfloat* corner4 = 0;/* -1, 1*/
191 Tfloat dcorner1[3];
192 Tfloat dcorner2[3];
193
194 switch( myBgGradient.type )
195 {
e276548b 196 case Aspect_GFM_HOR:
197 corner1 = myBgGradient.color1.rgb;
198 corner2 = myBgGradient.color2.rgb;
199 corner3 = myBgGradient.color2.rgb;
200 corner4 = myBgGradient.color1.rgb;
201 break;
202 case Aspect_GFM_VER:
203 corner1 = myBgGradient.color2.rgb;
204 corner2 = myBgGradient.color2.rgb;
205 corner3 = myBgGradient.color1.rgb;
206 corner4 = myBgGradient.color1.rgb;
207 break;
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]);
214 corner1 = dcorner1;
215 corner3 = dcorner2;
216 break;
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]);
223 corner2 = dcorner1;
224 corner4 = dcorner2;
225 break;
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;
231 break;
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;
237 break;
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;
243 break;
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;
249 break;
250 default:
251 //printf("gradient background type not right\n");
252 break;
2166f0fa
SK
253 }
254
255 // Save GL parameters
256 glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
257
258 GLint curSM;
259 glGetIntegerv( GL_SHADE_MODEL, &curSM );
260 if ( curSM != GL_SMOOTH )
261 glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
262
263 glBegin(GL_TRIANGLE_FAN);
f8b2ed36 264 if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
2166f0fa
SK
265 {
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.);
3c3131a0 270 }
f8b2ed36 271 else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
2166f0fa
SK
272 {
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.);
277 }
278 glEnd();
279
280 // Restore GL parameters
281 if ( curSM != GL_SMOOTH )
282 glShadeModel( curSM );
283 }
f8b2ed36 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 )
288 {
289 GLfloat texX_range = 1.F; // texture <s> coordinate
290 GLfloat texY_range = 1.F; // texture <t> coordinate
291
e276548b 292 // Set up for stretching or tiling
f8b2ed36 293 GLfloat x_offset, y_offset;
294 if ( myBgTexture.Style == Aspect_FM_CENTERED )
295 {
296 x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
297 y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
298 }
299 else
300 {
301 x_offset = 1.F;
302 y_offset = 1.F;
303 if ( myBgTexture.Style == Aspect_FM_TILED )
304 {
305 texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
306 texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
307 }
308 }
309
1e743e91 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;
316
f8b2ed36 317 glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
318 glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
319
320 glDisable( GL_BLEND ); //push GL_ENABLE_BIT
321
b5ac8292 322 glColor3fv (theWorkspace->BackgroundColor().rgb);
323 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
f8b2ed36 324
1e743e91 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
f8b2ed36 328 glBegin( GL_QUADS );
1e743e91 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 );
f8b2ed36 333 glEnd();
334 }
2166f0fa
SK
335
336 glPopMatrix();
337 glMatrixMode( GL_PROJECTION );
338 glPopMatrix();
339 glMatrixMode( GL_MODELVIEW );
340
341 glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
342
b5ac8292 343 if (theWorkspace->UseZBuffer())
344 glEnable (GL_DEPTH_TEST);
2166f0fa
SK
345
346 /* GL_DITHER on/off pour le trace */
b5ac8292 347 if (theWorkspace->Dither())
2166f0fa
SK
348 glEnable (GL_DITHER);
349 else
350 glDisable (GL_DITHER);
351 }
e276548b 352}
353
354/*----------------------------------------------------------------------*/
355
356//call_func_redraw_all_structs_proc
357void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
b5ac8292 358 const Handle(OpenGl_Workspace) &theWorkspace,
359 const Graphic3d_CView& theCView,
360 const Aspect_CLayer2d& theCUnderLayer,
361 const Aspect_CLayer2d& theCOverLayer)
e276548b 362{
b5ac8292 363 // ==================================
364 // Step 1: Prepare for redraw
365 // ==================================
366
367 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
368
e276548b 369 // Store and disable current clipping planes
b5ac8292 370 Standard_Integer aMaxPlanes = aContext->MaxClipPlanes();
371
372 OPENGL_CLIP_PLANE *aOldPlanes = new OPENGL_CLIP_PLANE[aMaxPlanes];
373 OPENGL_CLIP_PLANE *aPtrPlane = aOldPlanes;
374
375 GLenum aClipPlaneId = GL_CLIP_PLANE0;
376 const GLenum aClipLastId = GL_CLIP_PLANE0 + aMaxPlanes;
377 for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
e276548b 378 {
b5ac8292 379 glGetClipPlane (aClipPlaneId, aPtrPlane->Equation);
380 if (aPtrPlane->isEnabled)
e276548b 381 {
b5ac8292 382 glDisable (aClipPlaneId);
383 aPtrPlane->isEnabled = GL_TRUE;
e276548b 384 }
385 else
386 {
b5ac8292 387 aPtrPlane->isEnabled = GL_FALSE;
e276548b 388 }
389 }
390
391 // Set OCCT state uniform variables
392ac980 392 const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager();
b5ac8292 393 if (!aManager->IsEmpty())
392ac980 394 {
b5ac8292 395 if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
396 {
397 aManager->UpdateLightSourceStateTo (&myLights);
398 myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
399 }
400
401 if (myProjectionState != myCamera->ProjectionState())
402 {
403 myProjectionState = myCamera->ProjectionState();
197ac94e 404 aManager->UpdateProjectionStateTo ((const Tmatrix3*)myCamera->ProjectionMatrixF().GetData());
b5ac8292 405 }
406
407 if (myModelViewState != myCamera->ModelViewState())
408 {
409 myModelViewState = myCamera->ModelViewState();
197ac94e 410 aManager->UpdateWorldViewStateTo ((const Tmatrix3*)myCamera->OrientationMatrixF().GetData());
b5ac8292 411 }
412
413 if (aManager->ModelWorldState().Index() == 0)
414 {
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 } };
419
420 aContext->ShaderManager()->UpdateModelWorldStateTo (&aModelWorldState);
421 }
e276548b 422 }
423
b5ac8292 424 // ====================================
425 // Step 2: Redraw background
426 // ====================================
e276548b 427
428 // Render background
b5ac8292 429 DrawBackground (theWorkspace);
2166f0fa
SK
430
431 // Switch off lighting by default
432 glDisable(GL_LIGHTING);
433
b5ac8292 434 // =================================
435 // Step 3: Draw underlayer
436 // =================================
437
438 RedrawLayer2d (thePrintContext, theCView, theCUnderLayer);
2166f0fa 439
b5ac8292 440 // =================================
441 // Step 4: Redraw main plane
442 // =================================
2166f0fa
SK
443
444 // Setup face culling
445 GLboolean isCullFace = GL_FALSE;
446 if ( myBackfacing )
447 {
448 isCullFace = glIsEnabled( GL_CULL_FACE );
449 if ( myBackfacing < 0 )
450 {
451 glEnable( GL_CULL_FACE );
452 glCullFace( GL_BACK );
453 }
b5ac8292 454 else
2166f0fa
SK
455 glDisable( GL_CULL_FACE );
456 }
457
b5ac8292 458 // if the view is scaled normal vectors are scaled to unit
459 // length for correct displaying of shaded objects
460 const gp_Pnt anAxialScale = myCamera->AxialScale();
461 if(anAxialScale.X() != 1.F ||
462 anAxialScale.Y() != 1.F ||
463 anAxialScale.Z() != 1.F)
2166f0fa 464 glEnable(GL_NORMALIZE);
3c3131a0 465 else if(glIsEnabled(GL_NORMALIZE))
2166f0fa
SK
466 glDisable(GL_NORMALIZE);
467
2166f0fa
SK
468 // Apply Fog
469 if ( myFog.IsOn )
470 {
b5ac8292 471 Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance();
472 if (myCamera->ZFar() < aFogFrontConverted)
2166f0fa 473 {
b5ac8292 474 aFogFrontConverted = myCamera->ZFar();
475 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
12381341 476 }
4fe9ad57 477
b5ac8292 478 Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance();
479 if (myCamera->ZFar() < aFogFrontConverted)
12381341 480 {
b5ac8292 481 aFogBackConverted = myCamera->ZFar();
482 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
12381341 483 }
b5ac8292 484
485 if (aFogFrontConverted > aFogBackConverted)
12381341 486 {
b5ac8292 487 myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance());
488 myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance());
489 }
490
491 glFogi(GL_FOG_MODE, GL_LINEAR);
492 glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted);
493 glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted);
494 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
495 glEnable(GL_FOG);
2166f0fa 496 }
b5ac8292 497 else
498 glDisable(GL_FOG);
2166f0fa
SK
499
500 // Apply InteriorShadingMethod
501 glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
502
b5ac8292 503 // Apply AntiAliasing
504 if (myAntiAliasing)
505 theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
506 else
507 theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
508
509 if (!aManager->IsEmpty())
2166f0fa 510 {
b5ac8292 511 aManager->UpdateClippingState();
512 }
2166f0fa 513
b5ac8292 514 // Redraw 3d scene
515 if (!myCamera->IsStereo() || !aContext->HasStereoBuffers())
516 {
517 // single-pass monographic rendering
197ac94e 518 const OpenGl_Matrix* aProj = (const OpenGl_Matrix*) &myCamera->ProjectionMatrixF();
b859a34d 519
197ac94e 520 const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
2166f0fa 521
b5ac8292 522 // redraw scene with normal orientation and projection
523 RedrawScene (thePrintContext, theWorkspace, aProj, aOrient);
524 }
525 else
526 {
527 // two stereographic passes
197ac94e 528 const OpenGl_Matrix* aLProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoLeftF();
529 const OpenGl_Matrix* aRProj = (const OpenGl_Matrix*) &myCamera->ProjectionStereoRightF();
530 const OpenGl_Matrix* aOrient = (const OpenGl_Matrix*) &myCamera->OrientationMatrixF();
2166f0fa 531
b5ac8292 532 // safely switch to left Eye buffer
533 aContext->SetDrawBufferLeft();
b859a34d 534
b5ac8292 535 // redraw left Eye
536 RedrawScene (thePrintContext, theWorkspace, aLProj, aOrient);
b859a34d 537
b5ac8292 538 // reset depth buffer of first rendering pass
539 if (theWorkspace->UseDepthTest())
4269bd1b 540 {
b5ac8292 541 glClear (GL_DEPTH_BUFFER_BIT);
2166f0fa 542 }
b5ac8292 543 // safely switch to right Eye buffer
544 aContext->SetDrawBufferRight();
30f0ad28 545
b5ac8292 546 // redraw right Eye
547 RedrawScene (thePrintContext, theWorkspace, aRProj, aOrient);
2166f0fa 548
b5ac8292 549 // switch back to monographic rendering
550 aContext->SetDrawBufferMono();
2166f0fa
SK
551 }
552
b5ac8292 553 // ===============================
554 // Step 5: Trihedron
555 // ===============================
2166f0fa 556
26395493 557 // Resetting GL parameters according to the default aspects
558 // in order to synchronize GL state with the graphic driver state
559 // before drawing auxiliary stuff (trihedrons, overlayer)
560 // and invoking optional callbacks
b5ac8292 561 theWorkspace->ResetAppliedAspect();
2166f0fa 562
b859a34d 563 aContext->ChangeClipping().RemoveAll();
2166f0fa 564
392ac980 565 if (!aManager->IsEmpty())
30f0ad28 566 {
392ac980 567 aManager->ResetMaterialStates();
568 aManager->RevertClippingState();
569
570 // We need to disable (unbind) all shaders programs to ensure
571 // that all objects without specified aspect will be drawn
572 // correctly (such as background)
573 OpenGl_ShaderProgram::Unbind (aContext);
30f0ad28 574 }
575
a174a3c5 576 // display global trihedron
577 if (myTrihedron != NULL)
578 {
b5ac8292 579 myTrihedron->Render (theWorkspace);
a174a3c5 580 }
581 if (myGraduatedTrihedron != NULL)
582 {
b5ac8292 583 myGraduatedTrihedron->Render (theWorkspace);
a174a3c5 584 }
2166f0fa 585
2166f0fa
SK
586 // Restore face culling
587 if ( myBackfacing )
588 {
589 if ( isCullFace )
590 {
591 glEnable ( GL_CULL_FACE );
592 glCullFace ( GL_BACK );
593 }
529afc1a 594 else
2166f0fa
SK
595 glDisable ( GL_CULL_FACE );
596 }
597
b5ac8292 598 // ===============================
599 // Step 6: Redraw overlay
600 // ===============================
601
529afc1a 602 const int aMode = 0;
b5ac8292 603 theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
2166f0fa 604
b5ac8292 605 RedrawLayer2d (thePrintContext, theCView, theCOverLayer);
2166f0fa 606
b5ac8292 607 theWorkspace->DisplayCallback (theCView, aMode);
608
609 // ===============================
610 // Step 7: Finalize
611 // ===============================
2166f0fa
SK
612
613 // Restore clipping planes
b5ac8292 614 aClipPlaneId = GL_CLIP_PLANE0;
615 aPtrPlane = aOldPlanes;
616
617 for (; aClipPlaneId < aClipLastId; aClipPlaneId++, aPtrPlane++)
2166f0fa 618 {
b5ac8292 619 glClipPlane (aClipPlaneId, aPtrPlane->Equation);
620 if (aPtrPlane->isEnabled)
621 glEnable (aClipPlaneId);
529afc1a 622 else
b5ac8292 623 glDisable (aClipPlaneId);
2166f0fa 624 }
b5ac8292 625
626 delete[] aOldPlanes;
2166f0fa
SK
627}
628
629/*----------------------------------------------------------------------*/
630
631//ExecuteViewDisplay
632void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
633{
59f45b7c 634 if ( myZLayers.NbStructures() <= 0 )
635 return;
2166f0fa
SK
636
637 glPushAttrib ( GL_DEPTH_BUFFER_BIT );
638
2166f0fa
SK
639 //TsmPushAttri(); /* save previous graphics context */
640
641 if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
642 {
643 const int antiAliasingMode = AWorkspace->GetDisplay()->AntiAliasingMode();
644
645 if ( !myAntiAliasing )
646 {
647 glDisable(GL_POINT_SMOOTH);
648 glDisable(GL_LINE_SMOOTH);
649 if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
650 glBlendFunc (GL_ONE, GL_ZERO);
651 glDisable (GL_BLEND);
652 }
653 else
654 {
655 glEnable(GL_POINT_SMOOTH);
656 glEnable(GL_LINE_SMOOTH);
657 if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
3c3131a0 658 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2166f0fa
SK
659 glEnable (GL_BLEND);
660 }
661 }
662
59f45b7c 663 myZLayers.Render (AWorkspace);
2166f0fa
SK
664
665 //TsmPopAttri(); /* restore previous graphics context; before update lights */
de75ed09 666 glPopAttrib();
2166f0fa
SK
667}
668
669/*----------------------------------------------------------------------*/
670
671//call_togl_redraw_layer2d
a174a3c5 672void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
a174a3c5 673 const Graphic3d_CView& ACView,
674 const Aspect_CLayer2d& ACLayer)
2166f0fa
SK
675{
676 if (&ACLayer == NULL
677 || ACLayer.ptrLayer == NULL
678 || ACLayer.ptrLayer->listIndex == 0) return;
679
529afc1a
K
680 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
681 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
2166f0fa 682
2166f0fa
SK
683 glMatrixMode( GL_MODELVIEW );
684 glPushMatrix ();
685 glLoadIdentity ();
686
687 glMatrixMode (GL_PROJECTION);
688 glPushMatrix ();
689 glLoadIdentity ();
690
691 if (!ACLayer.sizeDependent)
692 glViewport (0, 0, dispWidth, dispHeight);
693
694 float left = ACLayer.ortho[0];
695 float right = ACLayer.ortho[1];
696 float bottom = ACLayer.ortho[2];
697 float top = ACLayer.ortho[3];
698
699 int attach = ACLayer.attach;
700
701 float ratio;
702 if (!ACLayer.sizeDependent)
703 ratio = (float) dispWidth/dispHeight;
704 else
705 ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
706
707 float delta;
c9d4eb9d 708 if (ratio >= 1.0) {
2166f0fa
SK
709 delta = (float )((top - bottom)/2.0);
710 switch (attach) {
711 case 0: /* Aspect_TOC_BOTTOM_LEFT */
712 top = bottom + 2*delta/ratio;
713 break;
714 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
715 top = bottom + 2*delta/ratio;
716 break;
717 case 2: /* Aspect_TOC_TOP_LEFT */
718 bottom = top - 2*delta/ratio;
719 break;
720 case 3: /* Aspect_TOC_TOP_RIGHT */
721 bottom = top - 2*delta/ratio;
722 break;
723 }
724 }
c9d4eb9d 725 else {
2166f0fa
SK
726 delta = (float )((right - left)/2.0);
727 switch (attach) {
728 case 0: /* Aspect_TOC_BOTTOM_LEFT */
729 right = left + 2*delta*ratio;
730 break;
731 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
732 left = right - 2*delta*ratio;
733 break;
734 case 2: /* Aspect_TOC_TOP_LEFT */
735 right = left + 2*delta*ratio;
736 break;
737 case 3: /* Aspect_TOC_TOP_RIGHT */
738 left = right - 2*delta*ratio;
739 break;
740 }
741 }
742
a174a3c5 743#ifdef _WIN32
2166f0fa 744 // Check printer context that exists only for print operation
a174a3c5 745 if (!thePrintContext.IsNull())
2166f0fa
SK
746 {
747 // additional transformation matrix could be applied to
748 // render only those parts of viewport that will be
749 // passed to a printer as a current "frame" to provide
750 // tiling; scaling of graphics by matrix helps render a
751 // part of a view (frame) in same viewport, but with higher
752 // resolution
a174a3c5 753 thePrintContext->LoadProjTransformation();
2166f0fa
SK
754
755 // printing operation also assumes other viewport dimension
756 // to comply with transformation matrix or graphics scaling
757 // factors for tiling for layer redraw
758 GLsizei anViewportX = 0;
759 GLsizei anViewportY = 0;
a174a3c5 760 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
2166f0fa
SK
761 if (anViewportX != 0 && anViewportY != 0)
762 glViewport (0, 0, anViewportX, anViewportY);
763 }
3c3131a0 764#endif
2166f0fa
SK
765
766 glOrtho (left, right, bottom, top, -1.0, 1.0);
767
2166f0fa
SK
768 glPushAttrib (
769 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
770 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
c9d4eb9d 771
2166f0fa 772 glDisable (GL_DEPTH_TEST);
c9d4eb9d 773 glDisable (GL_TEXTURE_1D);
774 glDisable (GL_TEXTURE_2D);
775 glDisable (GL_LIGHTING);
776
777 // TODO: Obsolete code, the display list is always empty now, to be removed
2166f0fa
SK
778 glCallList (ACLayer.ptrLayer->listIndex);
779
780 //calling dynamic render of LayerItems
781 if ( ACLayer.ptrLayer->layerData )
782 {
30f0ad28 783 InitLayerProp (ACLayer.ptrLayer->listIndex);
2166f0fa 784 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
30f0ad28 785 InitLayerProp (0);
2166f0fa
SK
786 }
787
788 glPopAttrib ();
789
2166f0fa
SK
790 glMatrixMode (GL_PROJECTION);
791 glPopMatrix ();
792
793 glMatrixMode( GL_MODELVIEW );
794 glPopMatrix ();
795
2166f0fa
SK
796 if (!ACLayer.sizeDependent)
797 glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
798
799 glFlush ();
2166f0fa
SK
800}
801
802/*----------------------------------------------------------------------*/
803
804//call_togl_create_bg_texture
3c3131a0 805void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
806 const Aspect_FillMethod theFillStyle)
2166f0fa 807{
3c3131a0 808 if (myBgTexture.TexId != 0)
2166f0fa 809 {
3c3131a0 810 // delete existing texture
811 glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
2166f0fa
SK
812 myBgTexture.TexId = 0;
813 }
814
3c3131a0 815 // load image from file
816 Image_AlienPixMap anImageLoaded;
817 if (!anImageLoaded.Load (theFilePath))
818 {
819 return;
820 }
821
822 Image_PixMap anImage;
823 if (anImageLoaded.RowExtraBytes() == 0 &&
824 (anImageLoaded.Format() == Image_PixMap::ImgRGB
825 || anImageLoaded.Format() == Image_PixMap::ImgRGB32
826 || anImageLoaded.Format() == Image_PixMap::ImgRGBA))
2166f0fa 827 {
3c3131a0 828 anImage.InitWrapper (anImageLoaded.Format(), anImageLoaded.ChangeData(),
829 anImageLoaded.SizeX(), anImageLoaded.SizeY(), anImageLoaded.SizeRowBytes());
830 }
831 else
832 {
833 // convert image to RGB format
834 if (!anImage.InitTrash (Image_PixMap::ImgRGB, anImageLoaded.SizeX(), anImageLoaded.SizeY()))
835 {
836 return;
837 }
838
839 anImage.SetTopDown (false);
840 Image_PixMapData<Image_ColorRGB>& aDataNew = anImage.EditData<Image_ColorRGB>();
841 Quantity_Color aSrcColor;
842 for (Standard_Size aRow = 0; aRow < anImage.SizeY(); ++aRow)
843 {
844 for (Standard_Size aCol = 0; aCol < anImage.SizeX(); ++aCol)
2166f0fa 845 {
6a7d83c4 846 aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
3c3131a0 847 Image_ColorRGB& aColor = aDataNew.ChangeValue (aRow, aCol);
8263fcd3 848 aColor.r() = Standard_Byte(255.0 * aSrcColor.Red());
849 aColor.g() = Standard_Byte(255.0 * aSrcColor.Green());
850 aColor.b() = Standard_Byte(255.0 * aSrcColor.Blue());
2166f0fa 851 }
3c3131a0 852 }
853 anImageLoaded.Clear();
854 }
2166f0fa 855
3c3131a0 856 // create MipMapped texture
857 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
2166f0fa 858
3c3131a0 859 GLuint aTextureId = 0;
860 glGenTextures (1, &aTextureId);
861 glBindTexture (GL_TEXTURE_2D, aTextureId);
2166f0fa 862
3c3131a0 863 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
864 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
865 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
866 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
2166f0fa 867
3c3131a0 868 const GLenum aDataFormat = (anImage.Format() == Image_PixMap::ImgRGB) ? GL_RGB : GL_RGBA;
869 gluBuild2DMipmaps (GL_TEXTURE_2D, 3/*4*/,
870 GLint(anImage.SizeX()), GLint(anImage.SizeY()),
871 aDataFormat, GL_UNSIGNED_BYTE, anImage.Data());
2166f0fa 872
3c3131a0 873 myBgTexture.TexId = aTextureId;
874 myBgTexture.Width = (Standard_Integer )anImage.SizeX();
875 myBgTexture.Height = (Standard_Integer )anImage.SizeY();
876 myBgTexture.Style = theFillStyle;
2166f0fa
SK
877}
878
879/*----------------------------------------------------------------------*/
880
881//call_togl_set_bg_texture_style
882void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
883{
f8b2ed36 884 myBgTexture.Style = AFillStyle;
2166f0fa
SK
885}
886
887/*----------------------------------------------------------------------*/
888
889//call_togl_gradient_background
890void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
891 const Quantity_Color& AColor2,
892 const Aspect_GradientFillMethod AType)
893{
894 Standard_Real R,G,B;
895 AColor1.Values( R, G, B, Quantity_TOC_RGB );
896 myBgGradient.color1.rgb[0] = ( Tfloat )R;
897 myBgGradient.color1.rgb[1] = ( Tfloat )G;
898 myBgGradient.color1.rgb[2] = ( Tfloat )B;
899 myBgGradient.color1.rgb[3] = 0.F;
900
901 AColor2.Values( R, G, B, Quantity_TOC_RGB );
902 myBgGradient.color2.rgb[0] = ( Tfloat )R;
903 myBgGradient.color2.rgb[1] = ( Tfloat )G;
904 myBgGradient.color2.rgb[2] = ( Tfloat )B;
905 myBgGradient.color2.rgb[3] = 0.F;
906
907 myBgGradient.type = AType;
908}
909
910/*----------------------------------------------------------------------*/
911
912//call_togl_set_gradient_type
913void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
914{
f8b2ed36 915 myBgGradient.type = AType;
2166f0fa
SK
916}
917
59f45b7c 918//=======================================================================
919//function : AddZLayer
3c3131a0 920//purpose :
59f45b7c 921//=======================================================================
922
923void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
924{
925 myZLayers.AddLayer (theLayerId);
926}
927
928//=======================================================================
929//function : RemoveZLayer
3c3131a0 930//purpose :
59f45b7c 931//=======================================================================
932
933void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
934{
935 myZLayers.RemoveLayer (theLayerId);
936}
937
938//=======================================================================
939//function : DisplayStructure
3c3131a0 940//purpose :
59f45b7c 941//=======================================================================
942
943void OpenGl_View::DisplayStructure (const OpenGl_Structure *theStructure,
944 const Standard_Integer thePriority)
945{
946 Standard_Integer aZLayer = theStructure->GetZLayer ();
947 myZLayers.AddStructure (theStructure, aZLayer, thePriority);
948}
949
950//=======================================================================
679ecdee 951//function : DisplayImmediateStructure
952//purpose :
953//=======================================================================
954
955void OpenGl_View::DisplayImmediateStructure (const OpenGl_Structure* theStructure)
956{
957 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
958 anIter.More(); anIter.Next())
959 {
960 if (anIter.Value() == theStructure)
961 {
962 return;
963 }
964 }
965
966 myImmediateList.Append (theStructure);
967}
968
969//=======================================================================
59f45b7c 970//function : EraseStructure
3c3131a0 971//purpose :
59f45b7c 972//=======================================================================
973
974void OpenGl_View::EraseStructure (const OpenGl_Structure *theStructure)
975{
976 Standard_Integer aZLayer = theStructure->GetZLayer ();
977 myZLayers.RemoveStructure (theStructure, aZLayer);
978}
979
980//=======================================================================
679ecdee 981//function : EraseImmediateStructure
982//purpose :
983//=======================================================================
984
985void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure)
986{
987 for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList);
988 anIter.More(); anIter.Next())
989 {
990 if (anIter.Value() == theStructure)
991 {
992 myImmediateList.Remove (anIter);
993 return;
994 }
995 }
996}
997
998//=======================================================================
59f45b7c 999//function : ChangeZLayer
1000//purpose :
1001//=======================================================================
1002
1003void OpenGl_View::ChangeZLayer (const OpenGl_Structure *theStructure,
1004 const Standard_Integer theNewLayerId)
1005{
1006 Standard_Integer anOldLayer = theStructure->GetZLayer ();
1007 myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId);
1008}
b5ac8292 1009
1010//=======================================================================
1011//function : RedrawScene
1012//purpose :
1013//=======================================================================
1014
1015void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext,
1016 const Handle(OpenGl_Workspace)& theWorkspace,
1017 const OpenGl_Matrix* theProjection,
1018 const OpenGl_Matrix* theOrientation)
1019{
1020 const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
1021
1022 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
1023 {
1024 Handle(Graphic3d_ClipPlane) aPlaneBack;
1025 Handle(Graphic3d_ClipPlane) aPlaneFront;
1026
1027 if (myZClip.Back.IsOn)
1028 {
1029 Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1030 if (myCamera->ZFar() < aClipBackConverted)
1031 {
1032 aClipBackConverted = myCamera->ZFar();
1033 myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance());
1034 }
1035 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted);
1036 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
1037 }
1038
1039 if (myZClip.Front.IsOn)
1040 {
1041 Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance();
1042 if (myCamera->ZNear() > aClipFrontConverted)
1043 {
1044 aClipFrontConverted = myCamera->ZNear();
1045 myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance());
1046 }
1047 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted);
1048 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
1049 }
1050
1051 // do some "memory allocation"-wise optimization
1052 if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull())
1053 {
1054 Graphic3d_SequenceOfHClipPlane aSlicingPlanes;
1055 if (!aPlaneBack.IsNull())
1056 {
1057 aSlicingPlanes.Append (aPlaneBack);
1058 }
1059
1060 if (!aPlaneFront.IsNull())
1061 {
1062 aSlicingPlanes.Append (aPlaneFront);
1063 }
1064
1065 // add planes at loaded view matrix state
1066 aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace);
1067 }
1068 }
1069
1070 // Apply user clipping planes
1071 if (!myClipPlanes.IsEmpty())
1072 {
1073 Graphic3d_SequenceOfHClipPlane aUserPlanes;
1074 Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes);
1075 for (; aClippingIt.More(); aClippingIt.Next())
1076 {
1077 const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value();
1078 if (aClipPlane->IsOn())
1079 {
1080 aUserPlanes.Append (aClipPlane);
1081 }
1082 }
1083
1084 if (!aUserPlanes.IsEmpty())
1085 {
1086 // add planes at actual matrix state.
1087 aContext->ChangeClipping().AddWorld (aUserPlanes);
1088 }
1089
1090 if (!aContext->ShaderManager()->IsEmpty())
1091 {
1092 aContext->ShaderManager()->UpdateClippingState();
1093 }
1094 }
1095
1096 // Setup view projection
1097 glMatrixMode (GL_PROJECTION);
1098
1099#ifdef _WIN32
1100 // add printing scale/tiling transformation
1101 if (!thePrintContext.IsNull())
1102 {
1103 thePrintContext->LoadProjTransformation();
1104 }
1105 else
1106#endif
1107 glLoadIdentity();
1108
1109 glMultMatrixf ((const GLfloat*)theProjection);
1110
1111 if (!thePrintContext.IsNull())
1112 {
1113 // update shader uniform projection matrix with new data
1114 Tmatrix3 aResultProjection;
1115 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
1116 aContext->ShaderManager()->UpdateProjectionStateTo (&aResultProjection);
1117
1118 // force shader uniform restore on next frame
1119 myProjectionState = 0;
1120 }
1121
1122 // Setup view orientation
1123 theWorkspace->SetViewMatrix (theOrientation);
1124
1125 // Apply Lights
1126 {
1127 // setup lights
1128 Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0],
1129 THE_DEFAULT_AMBIENT[1],
1130 THE_DEFAULT_AMBIENT[2],
1131 THE_DEFAULT_AMBIENT[3]);
1132 GLenum aLightGlId = GL_LIGHT0;
1133 for (OpenGl_ListOfLight::Iterator aLightIt (myLights);
1134 aLightIt.More(); aLightIt.Next())
1135 {
1136 bind_light (aLightIt.Value(), aLightGlId, anAmbientColor);
1137 }
1138
1139 // apply accumulated ambient color
1140 anAmbientColor.a() = 1.0f;
1141 glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData());
1142
1143 if (aLightGlId != GL_LIGHT0)
1144 {
1145 glEnable (GL_LIGHTING);
1146 }
1147 // switch off unused lights
1148 for (; aLightGlId <= GL_LIGHT7; ++aLightGlId)
1149 {
1150 glDisable (aLightGlId);
1151 }
1152 }
1153
1154 // Clear status bitfields
1155 theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1156
1157 // Added PCT for handling of textures
1158 switch (mySurfaceDetail)
1159 {
1160 case Visual3d_TOD_NONE:
1161 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1162 theWorkspace->DisableTexture();
1163 // Render the view
1164 RenderStructs (theWorkspace);
1165 break;
1166
1167 case Visual3d_TOD_ENVIRONMENT:
1168 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1169 theWorkspace->EnableTexture (myTextureEnv);
1170 // Render the view
1171 RenderStructs (theWorkspace);
1172 theWorkspace->DisableTexture();
1173 break;
1174
1175 case Visual3d_TOD_ALL:
1176 // First pass
1177 theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1178 // Render the view
1179 RenderStructs (theWorkspace);
1180 theWorkspace->DisableTexture();
1181
1182 // Second pass
1183 if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1184 {
1185 theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1186 theWorkspace->EnableTexture (myTextureEnv);
1187
1188 // Remember OpenGl properties
1189 GLint aSaveBlendDst, aSaveBlendSrc;
1190 GLint aSaveZbuffFunc;
1191 GLboolean aSaveZbuffWrite;
1192 glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite);
1193 glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc);
1194 glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst);
1195 glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc);
1196 GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST);
1197 GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND);
1198
1199 // Change the properties for second rendering pass
1200 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1201 glEnable (GL_BLEND);
1202
1203 glDepthFunc (GL_EQUAL);
1204 glDepthMask (GL_FALSE);
1205 glEnable (GL_DEPTH_TEST);
1206
1207 theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1208
1209 // Render the view
1210 RenderStructs (theWorkspace);
1211 theWorkspace->DisableTexture();
1212
1213 // Restore properties back
1214 glBlendFunc (aSaveBlendSrc, aSaveBlendDst);
1215 if (!wasBlendEnabled)
1216 glDisable (GL_BLEND);
1217
1218 glDepthFunc (aSaveZbuffFunc);
1219 glDepthMask (aSaveZbuffWrite);
1220 if (!wasZbuffEnabled)
1221 glDisable (GL_DEPTH_FUNC);
1222 }
1223 break;
1224 }
1225}