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