Commit | Line | Data |
---|---|---|
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 | |
0b0320e7 | 22 | #include <Graphic3d_TextureParams.hxx> |
23 | #include <Graphic3d_Texture2Dmanual.hxx> | |
3c3131a0 | 24 | #include <Image_AlienPixMap.hxx> |
2166f0fa SK |
25 | #include <Visual3d_Layer.hxx> |
26 | ||
30f0ad28 | 27 | #include <NCollection_Mat4.hxx> |
28 | ||
2166f0fa | 29 | #include <OpenGl_AspectLine.hxx> |
30f0ad28 | 30 | #include <OpenGl_Context.hxx> |
30f0ad28 | 31 | #include <OpenGl_Matrix.hxx> |
2166f0fa SK |
32 | #include <OpenGl_Workspace.hxx> |
33 | #include <OpenGl_View.hxx> | |
34 | #include <OpenGl_Trihedron.hxx> | |
35 | #include <OpenGl_GraduatedTrihedron.hxx> | |
0b0320e7 | 36 | #include <OpenGl_PrimitiveArray.hxx> |
2166f0fa | 37 | #include <OpenGl_PrinterContext.hxx> |
30f0ad28 | 38 | #include <OpenGl_ShaderManager.hxx> |
39 | #include <OpenGl_ShaderProgram.hxx> | |
59f45b7c | 40 | #include <OpenGl_Structure.hxx> |
2166f0fa | 41 | |
2166f0fa SK |
42 | #define EPSI 0.0001 |
43 | ||
12381341 | 44 | namespace |
45 | { | |
46 | ||
47 | static const GLfloat THE_DEFAULT_AMBIENT[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; | |
48 | static const GLfloat THE_DEFAULT_SPOT_DIR[3] = { 0.0f, 0.0f, -1.0f }; | |
49 | static const GLfloat THE_DEFAULT_SPOT_EXPONENT = 0.0f; | |
50 | static const GLfloat THE_DEFAULT_SPOT_CUTOFF = 180.0f; | |
51 | ||
52 | }; | |
2166f0fa | 53 | |
30f0ad28 | 54 | extern void InitLayerProp (const int theListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx |
2166f0fa SK |
55 | |
56 | /*----------------------------------------------------------------------*/ | |
57 | ||
58 | struct OPENGL_CLIP_PLANE | |
59 | { | |
60 | GLboolean isEnabled; | |
61 | GLdouble Equation[4]; | |
1c35b92f | 62 | DEFINE_STANDARD_ALLOC |
2166f0fa SK |
63 | }; |
64 | ||
65 | /*----------------------------------------------------------------------*/ | |
66 | /* | |
67 | * Fonctions privees | |
68 | */ | |
69 | ||
ca3c13d1 | 70 | #if !defined(GL_ES_VERSION_2_0) |
2166f0fa SK |
71 | /*-----------------------------------------------------------------*/ |
72 | /* | |
73 | * Set des lumieres | |
74 | */ | |
c827ea3a | 75 | static void bindLight (const OpenGl_Light& theLight, |
76 | GLenum& theLightGlId, | |
77 | Graphic3d_Vec4& theAmbientColor, | |
78 | const Handle(OpenGl_Workspace)& theWorkspace) | |
2166f0fa SK |
79 | { |
80 | // Only 8 lights in OpenGL... | |
12381341 | 81 | if (theLightGlId > GL_LIGHT7) |
2166f0fa | 82 | { |
12381341 | 83 | return; |
2166f0fa SK |
84 | } |
85 | ||
12381341 | 86 | if (theLight.Type == Visual3d_TOLS_AMBIENT) |
2166f0fa | 87 | { |
4fe9ad57 | 88 | // add RGBA intensity of the ambient light |
89 | theAmbientColor += theLight.Color; | |
12381341 | 90 | return; |
91 | } | |
2166f0fa | 92 | |
c827ea3a | 93 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); |
94 | ||
12381341 | 95 | // the light is a headlight? |
12381341 | 96 | if (theLight.IsHeadlight) |
97 | { | |
c827ea3a | 98 | |
99 | aContext->WorldViewState.Push(); | |
100 | aContext->WorldViewState.SetIdentity(); | |
101 | ||
102 | aContext->ApplyWorldViewMatrix(); | |
2166f0fa SK |
103 | } |
104 | ||
12381341 | 105 | // setup light type |
106 | switch (theLight.Type) | |
3c3131a0 | 107 | { |
12381341 | 108 | case Visual3d_TOLS_DIRECTIONAL: |
109 | { | |
110 | // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one | |
111 | const OpenGl_Vec4 anInfDir = -theLight.Direction; | |
112 | ||
113 | // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE. | |
114 | glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); | |
115 | glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); | |
116 | glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); | |
117 | glLightfv (theLightGlId, GL_POSITION, anInfDir.GetData()); | |
118 | glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR); | |
119 | glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT); | |
120 | glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF); | |
121 | break; | |
122 | } | |
123 | case Visual3d_TOLS_POSITIONAL: | |
124 | { | |
125 | // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE | |
126 | glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); | |
127 | glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); | |
128 | glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); | |
129 | glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData()); | |
130 | glLightfv (theLightGlId, GL_SPOT_DIRECTION, THE_DEFAULT_SPOT_DIR); | |
131 | glLightf (theLightGlId, GL_SPOT_EXPONENT, THE_DEFAULT_SPOT_EXPONENT); | |
132 | glLightf (theLightGlId, GL_SPOT_CUTOFF, THE_DEFAULT_SPOT_CUTOFF); | |
133 | glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation()); | |
134 | glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation()); | |
135 | glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0); | |
136 | break; | |
137 | } | |
138 | case Visual3d_TOLS_SPOT: | |
139 | { | |
140 | glLightfv (theLightGlId, GL_AMBIENT, THE_DEFAULT_AMBIENT); | |
141 | glLightfv (theLightGlId, GL_DIFFUSE, theLight.Color.GetData()); | |
142 | glLightfv (theLightGlId, GL_SPECULAR, theLight.Color.GetData()); | |
143 | glLightfv (theLightGlId, GL_POSITION, theLight.Position.GetData()); | |
144 | glLightfv (theLightGlId, GL_SPOT_DIRECTION, theLight.Direction.GetData()); | |
145 | glLightf (theLightGlId, GL_SPOT_EXPONENT, theLight.Concentration() * 128.0f); | |
146 | glLightf (theLightGlId, GL_SPOT_CUTOFF, (theLight.Angle() * 180.0f) / GLfloat(M_PI)); | |
147 | glLightf (theLightGlId, GL_CONSTANT_ATTENUATION, theLight.ConstAttenuation()); | |
148 | glLightf (theLightGlId, GL_LINEAR_ATTENUATION, theLight.LinearAttenuation()); | |
149 | glLightf (theLightGlId, GL_QUADRATIC_ATTENUATION, 0.0f); | |
150 | break; | |
151 | } | |
2166f0fa SK |
152 | } |
153 | ||
12381341 | 154 | // restore matrix in case of headlight |
155 | if (theLight.IsHeadlight) | |
2166f0fa | 156 | { |
c827ea3a | 157 | aContext->WorldViewState.Pop(); |
2166f0fa | 158 | } |
12381341 | 159 | |
160 | glEnable (theLightGlId++); | |
2166f0fa | 161 | } |
ca3c13d1 | 162 | #endif |
2166f0fa | 163 | |
2166f0fa SK |
164 | /*----------------------------------------------------------------------*/ |
165 | ||
0b0320e7 | 166 | void OpenGl_View::DrawBackground (const Handle(OpenGl_Workspace)& theWorkspace) |
2166f0fa | 167 | { |
0b0320e7 | 168 | const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext(); |
2166f0fa | 169 | |
0b0320e7 | 170 | if ((theWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) != 0 // no background |
171 | || (!myBgTextureArray->IsDefined() // no texture | |
172 | && !myBgGradientArray->IsDefined())) // no gradient | |
173 | { | |
174 | return; | |
175 | } | |
2166f0fa | 176 | |
0b0320e7 | 177 | aCtx->core11fwd->glDisable (GL_DEPTH_TEST); |
c827ea3a | 178 | |
0b0320e7 | 179 | aCtx->WorldViewState.Push(); |
180 | aCtx->ProjectionState.Push(); | |
181 | aCtx->WorldViewState.SetIdentity(); | |
182 | aCtx->ProjectionState.SetIdentity(); | |
183 | aCtx->ApplyProjectionMatrix(); | |
184 | aCtx->ApplyWorldViewMatrix(); | |
c827ea3a | 185 | |
0b0320e7 | 186 | // Drawing background gradient if: |
187 | // - gradient fill type is not Aspect_GFM_NONE and | |
188 | // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode | |
189 | if (myBgGradientArray->IsDefined() | |
190 | && (!myBgTextureArray->IsDefined() | |
191 | || myBgTextureArray->TextureFillMethod() == Aspect_FM_CENTERED | |
192 | || myBgTextureArray->TextureFillMethod() == Aspect_FM_NONE)) | |
193 | { | |
194 | #if !defined(GL_ES_VERSION_2_0) | |
195 | GLint aShadingModelOld = GL_SMOOTH; | |
196 | if (aCtx->core11 != NULL) | |
197 | { | |
198 | aCtx->core11fwd->glDisable (GL_LIGHTING); | |
199 | aCtx->core11fwd->glGetIntegerv (GL_SHADE_MODEL, &aShadingModelOld); | |
200 | aCtx->core11->glShadeModel (GL_SMOOTH); | |
201 | } | |
202 | #endif | |
c827ea3a | 203 | |
0b0320e7 | 204 | if (myBgGradientArray->IsDataChanged()) |
205 | { | |
206 | myBgGradientArray->Init (theWorkspace); | |
207 | } | |
2166f0fa | 208 | |
0b0320e7 | 209 | myBgGradientArray->Render (theWorkspace); |
2166f0fa | 210 | |
0b0320e7 | 211 | #if !defined(GL_ES_VERSION_2_0) |
212 | if (aCtx->core11 != NULL) | |
2166f0fa | 213 | { |
0b0320e7 | 214 | aCtx->core11->glShadeModel (aShadingModelOld); |
215 | } | |
216 | #endif | |
217 | } | |
2166f0fa | 218 | |
0b0320e7 | 219 | // Drawing background image if it is defined |
220 | // (texture is defined and fill type is not Aspect_FM_NONE) | |
221 | if (myBgTextureArray->IsDefined() | |
222 | && myTextureParams->DoTextureMap()) | |
223 | { | |
224 | aCtx->core11fwd->glDisable (GL_BLEND); | |
2166f0fa | 225 | |
0b0320e7 | 226 | const OpenGl_AspectFace* anOldAspectFace = theWorkspace->SetAspectFace (myTextureParams); |
2166f0fa | 227 | |
0b0320e7 | 228 | if (myBgTextureArray->IsDataChanged() |
229 | || myBgTextureArray->IsViewSizeChanged (theWorkspace)) | |
f8b2ed36 | 230 | { |
0b0320e7 | 231 | myBgTextureArray->Init (theWorkspace); |
f8b2ed36 | 232 | } |
2166f0fa | 233 | |
0b0320e7 | 234 | myBgTextureArray->Render (theWorkspace); |
c827ea3a | 235 | |
0b0320e7 | 236 | // restore aspects |
237 | theWorkspace->SetAspectFace (anOldAspectFace); | |
238 | } | |
2166f0fa | 239 | |
0b0320e7 | 240 | aCtx->WorldViewState.Pop(); |
241 | aCtx->ProjectionState.Pop(); | |
242 | aCtx->ApplyProjectionMatrix(); | |
2166f0fa | 243 | |
0b0320e7 | 244 | if (theWorkspace->UseZBuffer()) |
245 | { | |
246 | aCtx->core11fwd->glEnable (GL_DEPTH_TEST); | |
2166f0fa | 247 | } |
e276548b | 248 | } |
249 | ||
250 | /*----------------------------------------------------------------------*/ | |
251 | ||
252 | //call_func_redraw_all_structs_proc | |
253 | void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext, | |
a1954302 | 254 | const Handle(OpenGl_Workspace)& theWorkspace, |
255 | const Graphic3d_CView& theCView, | |
256 | const Aspect_CLayer2d& theCUnderLayer, | |
257 | const Aspect_CLayer2d& theCOverLayer, | |
258 | const Standard_Boolean theToDrawImmediate) | |
e276548b | 259 | { |
b5ac8292 | 260 | // ================================== |
261 | // Step 1: Prepare for redraw | |
262 | // ================================== | |
263 | ||
264 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); | |
265 | ||
ca3c13d1 | 266 | #if !defined(GL_ES_VERSION_2_0) |
8625ef7e | 267 | // store and disable current clipping planes |
268 | const Standard_Integer aMaxPlanes = aContext->MaxClipPlanes(); | |
269 | NCollection_Array1<OPENGL_CLIP_PLANE> aOldPlanes (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + aMaxPlanes - 1); | |
270 | if (aContext->core11 != NULL) | |
e276548b | 271 | { |
8625ef7e | 272 | for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId) |
e276548b | 273 | { |
8625ef7e | 274 | OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId); |
275 | aContext->core11->glGetClipPlane (aClipPlaneId, aPlane.Equation); | |
276 | if (aPlane.isEnabled) | |
277 | { | |
278 | aContext->core11fwd->glDisable (aClipPlaneId); | |
279 | aPlane.isEnabled = GL_TRUE; | |
280 | } | |
281 | else | |
282 | { | |
283 | aPlane.isEnabled = GL_FALSE; | |
284 | } | |
e276548b | 285 | } |
286 | } | |
ca3c13d1 | 287 | #endif |
e276548b | 288 | |
c827ea3a | 289 | // Update states of OpenGl_BVHTreeSelector (frustum culling algorithm). |
b7cd4ba7 | 290 | Standard_Boolean isProjectionMatUpdateNeeded = Standard_False; |
291 | Standard_Boolean isOrientationMatUpdateNeeded = Standard_False; | |
292 | if (myBVHSelector.ProjectionState() != myCamera->ProjectionState()) | |
293 | { | |
294 | isProjectionMatUpdateNeeded = Standard_True; | |
295 | myBVHSelector.ChangeProjectionState() = myCamera->ProjectionState(); | |
296 | } | |
297 | if (myBVHSelector.ModelViewState() != myCamera->ModelViewState()) | |
298 | { | |
299 | isOrientationMatUpdateNeeded = Standard_True; | |
300 | myBVHSelector.ChangeModelViewState() = myCamera->ModelViewState(); | |
301 | } | |
302 | ||
c827ea3a | 303 | if (isProjectionMatUpdateNeeded |
304 | || isOrientationMatUpdateNeeded) | |
305 | { | |
306 | myBVHSelector.SetViewVolume (myCamera); | |
307 | } | |
308 | ||
8625ef7e | 309 | const Handle(OpenGl_ShaderManager) aManager = aContext->ShaderManager(); |
310 | const Standard_Boolean isSameView = aManager->IsSameView (this); // force camera state update when needed | |
256f9ac0 | 311 | if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState) |
392ac980 | 312 | { |
256f9ac0 | 313 | aManager->UpdateLightSourceStateTo (&myLights); |
314 | myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()); | |
315 | } | |
b5ac8292 | 316 | |
256f9ac0 | 317 | if (myProjectionState != myCamera->ProjectionState() |
318 | || !isSameView) | |
319 | { | |
320 | myProjectionState = myCamera->ProjectionState(); | |
c827ea3a | 321 | aContext->ProjectionState.SetCurrent (myCamera->ProjectionMatrixF()); |
322 | aContext->ApplyProjectionMatrix(); | |
256f9ac0 | 323 | } |
b5ac8292 | 324 | |
256f9ac0 | 325 | if (myModelViewState != myCamera->ModelViewState() |
326 | || !isSameView) | |
327 | { | |
328 | myModelViewState = myCamera->ModelViewState(); | |
c827ea3a | 329 | aContext->WorldViewState.SetCurrent (myCamera->OrientationMatrixF()); |
330 | aContext->ApplyWorldViewMatrix(); | |
256f9ac0 | 331 | } |
b5ac8292 | 332 | |
256f9ac0 | 333 | if (aManager->ModelWorldState().Index() == 0) |
334 | { | |
c827ea3a | 335 | aContext->ShaderManager()->UpdateModelWorldStateTo (OpenGl_Mat4()); |
b7cd4ba7 | 336 | } |
337 | ||
b5ac8292 | 338 | // ==================================== |
339 | // Step 2: Redraw background | |
340 | // ==================================== | |
e276548b | 341 | |
342 | // Render background | |
a1954302 | 343 | if (theWorkspace->ToRedrawGL() |
344 | && !theToDrawImmediate) | |
a89742cf | 345 | { |
0b0320e7 | 346 | DrawBackground (theWorkspace); |
a89742cf | 347 | } |
2166f0fa | 348 | |
ca3c13d1 | 349 | #if !defined(GL_ES_VERSION_2_0) |
2166f0fa SK |
350 | // Switch off lighting by default |
351 | glDisable(GL_LIGHTING); | |
ca3c13d1 | 352 | #endif |
2166f0fa | 353 | |
b5ac8292 | 354 | // ================================= |
355 | // Step 3: Draw underlayer | |
356 | // ================================= | |
a1954302 | 357 | if (!theToDrawImmediate) |
358 | { | |
359 | RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCUnderLayer); | |
360 | } | |
2166f0fa | 361 | |
b5ac8292 | 362 | // ================================= |
363 | // Step 4: Redraw main plane | |
364 | // ================================= | |
2166f0fa SK |
365 | |
366 | // Setup face culling | |
367 | GLboolean isCullFace = GL_FALSE; | |
368 | if ( myBackfacing ) | |
369 | { | |
370 | isCullFace = glIsEnabled( GL_CULL_FACE ); | |
371 | if ( myBackfacing < 0 ) | |
372 | { | |
373 | glEnable( GL_CULL_FACE ); | |
374 | glCullFace( GL_BACK ); | |
375 | } | |
b5ac8292 | 376 | else |
2166f0fa SK |
377 | glDisable( GL_CULL_FACE ); |
378 | } | |
379 | ||
ca3c13d1 | 380 | #if !defined(GL_ES_VERSION_2_0) |
b5ac8292 | 381 | // if the view is scaled normal vectors are scaled to unit |
382 | // length for correct displaying of shaded objects | |
383 | const gp_Pnt anAxialScale = myCamera->AxialScale(); | |
7d9e854b | 384 | if (anAxialScale.X() != 1.F || |
385 | anAxialScale.Y() != 1.F || | |
386 | anAxialScale.Z() != 1.F) | |
387 | { | |
388 | aContext->SetGlNormalizeEnabled (Standard_True); | |
389 | } | |
390 | else | |
391 | { | |
392 | aContext->SetGlNormalizeEnabled (Standard_False); | |
393 | } | |
2166f0fa | 394 | |
2166f0fa SK |
395 | // Apply Fog |
396 | if ( myFog.IsOn ) | |
397 | { | |
b5ac8292 | 398 | Standard_Real aFogFrontConverted = (Standard_Real )myFog.Front + myCamera->Distance(); |
399 | if (myCamera->ZFar() < aFogFrontConverted) | |
2166f0fa | 400 | { |
b5ac8292 | 401 | aFogFrontConverted = myCamera->ZFar(); |
402 | myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance()); | |
12381341 | 403 | } |
4fe9ad57 | 404 | |
b5ac8292 | 405 | Standard_Real aFogBackConverted = (Standard_Real )myFog.Back + myCamera->Distance(); |
406 | if (myCamera->ZFar() < aFogFrontConverted) | |
12381341 | 407 | { |
b5ac8292 | 408 | aFogBackConverted = myCamera->ZFar(); |
409 | myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance()); | |
12381341 | 410 | } |
b5ac8292 | 411 | |
412 | if (aFogFrontConverted > aFogBackConverted) | |
12381341 | 413 | { |
b5ac8292 | 414 | myFog.Front = (Standard_ShortReal )(aFogFrontConverted - myCamera->Distance()); |
415 | myFog.Back = (Standard_ShortReal )(aFogBackConverted - myCamera->Distance()); | |
ca3c13d1 | 416 | } |
b5ac8292 | 417 | |
418 | glFogi(GL_FOG_MODE, GL_LINEAR); | |
419 | glFogf(GL_FOG_START, (Standard_ShortReal )aFogFrontConverted); | |
420 | glFogf(GL_FOG_END, (Standard_ShortReal )aFogBackConverted); | |
421 | glFogfv(GL_FOG_COLOR, myFog.Color.rgb); | |
422 | glEnable(GL_FOG); | |
2166f0fa | 423 | } |
b5ac8292 | 424 | else |
425 | glDisable(GL_FOG); | |
2166f0fa SK |
426 | |
427 | // Apply InteriorShadingMethod | |
8625ef7e | 428 | aContext->core11->glShadeModel (myShadingModel == Visual3d_TOM_FACET |
429 | || myShadingModel == Visual3d_TOM_NONE ? GL_FLAT : GL_SMOOTH); | |
ca3c13d1 | 430 | #endif |
2166f0fa | 431 | |
8625ef7e | 432 | aManager->SetShadingModel (myShadingModel); |
433 | ||
b5ac8292 | 434 | // Apply AntiAliasing |
435 | if (myAntiAliasing) | |
436 | theWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING; | |
437 | else | |
438 | theWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING; | |
439 | ||
440 | if (!aManager->IsEmpty()) | |
2166f0fa | 441 | { |
b5ac8292 | 442 | aManager->UpdateClippingState(); |
443 | } | |
2166f0fa | 444 | |
b5ac8292 | 445 | // Redraw 3d scene |
446 | if (!myCamera->IsStereo() || !aContext->HasStereoBuffers()) | |
447 | { | |
448 | // single-pass monographic rendering | |
b5ac8292 | 449 | // redraw scene with normal orientation and projection |
a1954302 | 450 | RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate); |
b5ac8292 | 451 | } |
452 | else | |
453 | { | |
454 | // two stereographic passes | |
2166f0fa | 455 | |
b5ac8292 | 456 | // safely switch to left Eye buffer |
457 | aContext->SetDrawBufferLeft(); | |
b859a34d | 458 | |
c827ea3a | 459 | aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoLeftF()); |
460 | aContext->ApplyProjectionMatrix(); | |
461 | ||
b5ac8292 | 462 | // redraw left Eye |
a1954302 | 463 | RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate); |
b859a34d | 464 | |
b5ac8292 | 465 | // reset depth buffer of first rendering pass |
466 | if (theWorkspace->UseDepthTest()) | |
4269bd1b | 467 | { |
b5ac8292 | 468 | glClear (GL_DEPTH_BUFFER_BIT); |
2166f0fa | 469 | } |
b5ac8292 | 470 | // safely switch to right Eye buffer |
471 | aContext->SetDrawBufferRight(); | |
ca3c13d1 | 472 | |
c827ea3a | 473 | aContext->ProjectionState.SetCurrent (myCamera->ProjectionStereoRightF()); |
474 | aContext->ApplyProjectionMatrix(); | |
475 | ||
b5ac8292 | 476 | // redraw right Eye |
a1954302 | 477 | RedrawScene (thePrintContext, theWorkspace, theToDrawImmediate); |
2166f0fa | 478 | |
b5ac8292 | 479 | // switch back to monographic rendering |
480 | aContext->SetDrawBufferMono(); | |
2166f0fa SK |
481 | } |
482 | ||
b5ac8292 | 483 | // =============================== |
484 | // Step 5: Trihedron | |
485 | // =============================== | |
2166f0fa | 486 | |
26395493 | 487 | // Resetting GL parameters according to the default aspects |
488 | // in order to synchronize GL state with the graphic driver state | |
489 | // before drawing auxiliary stuff (trihedrons, overlayer) | |
490 | // and invoking optional callbacks | |
b5ac8292 | 491 | theWorkspace->ResetAppliedAspect(); |
2166f0fa | 492 | |
b859a34d | 493 | aContext->ChangeClipping().RemoveAll(); |
2166f0fa | 494 | |
392ac980 | 495 | if (!aManager->IsEmpty()) |
30f0ad28 | 496 | { |
392ac980 | 497 | aManager->ResetMaterialStates(); |
498 | aManager->RevertClippingState(); | |
499 | ||
500 | // We need to disable (unbind) all shaders programs to ensure | |
501 | // that all objects without specified aspect will be drawn | |
502 | // correctly (such as background) | |
7d3e64ef | 503 | aContext->BindProgram (NULL); |
30f0ad28 | 504 | } |
505 | ||
a89742cf | 506 | // Render trihedron |
a1954302 | 507 | if (theWorkspace->ToRedrawGL() |
508 | && !theToDrawImmediate) | |
a174a3c5 | 509 | { |
a89742cf | 510 | RedrawTrihedron (theWorkspace); |
2166f0fa | 511 | |
a89742cf | 512 | // Restore face culling |
513 | if ( myBackfacing ) | |
2166f0fa | 514 | { |
a89742cf | 515 | if ( isCullFace ) |
516 | { | |
517 | glEnable ( GL_CULL_FACE ); | |
518 | glCullFace ( GL_BACK ); | |
519 | } | |
520 | else | |
521 | glDisable ( GL_CULL_FACE ); | |
2166f0fa | 522 | } |
2166f0fa SK |
523 | } |
524 | ||
b5ac8292 | 525 | // =============================== |
526 | // Step 6: Redraw overlay | |
527 | // =============================== | |
a1954302 | 528 | if (!theToDrawImmediate) |
529 | { | |
530 | const int aMode = 0; | |
531 | theWorkspace->DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY)); | |
b5ac8292 | 532 | |
a1954302 | 533 | RedrawLayer2d (thePrintContext, theWorkspace, theCView, theCOverLayer); |
2166f0fa | 534 | |
a1954302 | 535 | theWorkspace->DisplayCallback (theCView, aMode); |
536 | } | |
b5ac8292 | 537 | |
538 | // =============================== | |
539 | // Step 7: Finalize | |
540 | // =============================== | |
2166f0fa | 541 | |
ca3c13d1 | 542 | #if !defined(GL_ES_VERSION_2_0) |
8625ef7e | 543 | // restore clipping planes |
544 | if (aContext->core11 != NULL) | |
2166f0fa | 545 | { |
8625ef7e | 546 | for (Standard_Integer aClipPlaneId = aOldPlanes.Lower(); aClipPlaneId <= aOldPlanes.Upper(); ++aClipPlaneId) |
547 | { | |
548 | const OPENGL_CLIP_PLANE& aPlane = aOldPlanes.ChangeValue (aClipPlaneId); | |
549 | aContext->core11->glClipPlane (aClipPlaneId, aPlane.Equation); | |
550 | if (aPlane.isEnabled) | |
551 | aContext->core11fwd->glEnable (aClipPlaneId); | |
552 | else | |
553 | aContext->core11fwd->glDisable (aClipPlaneId); | |
554 | } | |
2166f0fa | 555 | } |
ca3c13d1 | 556 | #endif |
e6804ff7 | 557 | |
558 | // ============================================================== | |
559 | // Step 8: Keep shader manager informed about last View | |
560 | // ============================================================== | |
561 | ||
562 | if (!aManager.IsNull()) | |
563 | { | |
564 | aManager->SetLastView (this); | |
565 | } | |
2166f0fa SK |
566 | } |
567 | ||
b7cd4ba7 | 568 | // ======================================================================= |
569 | // function : InvalidateBVHData | |
570 | // purpose : | |
571 | // ======================================================================= | |
a1954302 | 572 | void OpenGl_View::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId) |
b7cd4ba7 | 573 | { |
574 | myZLayers.InvalidateBVHData (theLayerId); | |
575 | } | |
576 | ||
2166f0fa SK |
577 | /*----------------------------------------------------------------------*/ |
578 | ||
579 | //ExecuteViewDisplay | |
a1954302 | 580 | void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace)& AWorkspace, |
581 | const Standard_Boolean theToDrawImmediate) | |
2166f0fa | 582 | { |
59f45b7c | 583 | if ( myZLayers.NbStructures() <= 0 ) |
584 | return; | |
2166f0fa | 585 | |
ca3c13d1 | 586 | #if !defined(GL_ES_VERSION_2_0) |
2166f0fa | 587 | glPushAttrib ( GL_DEPTH_BUFFER_BIT ); |
ca3c13d1 | 588 | #endif |
2166f0fa | 589 | |
2166f0fa SK |
590 | //TsmPushAttri(); /* save previous graphics context */ |
591 | ||
592 | if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 ) | |
593 | { | |
ca3c13d1 | 594 | #if !defined(GL_ES_VERSION_2_0) |
73192b37 | 595 | const int antiAliasingMode = AWorkspace->AntiAliasingMode(); |
ca3c13d1 | 596 | #endif |
2166f0fa SK |
597 | |
598 | if ( !myAntiAliasing ) | |
599 | { | |
ca3c13d1 | 600 | #if !defined(GL_ES_VERSION_2_0) |
2166f0fa SK |
601 | glDisable(GL_POINT_SMOOTH); |
602 | glDisable(GL_LINE_SMOOTH); | |
603 | if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH); | |
ca3c13d1 | 604 | #endif |
2166f0fa SK |
605 | glBlendFunc (GL_ONE, GL_ZERO); |
606 | glDisable (GL_BLEND); | |
607 | } | |
608 | else | |
609 | { | |
ca3c13d1 | 610 | #if !defined(GL_ES_VERSION_2_0) |
2166f0fa SK |
611 | glEnable(GL_POINT_SMOOTH); |
612 | glEnable(GL_LINE_SMOOTH); | |
613 | if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH); | |
ca3c13d1 | 614 | #endif |
3c3131a0 | 615 | glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
2166f0fa SK |
616 | glEnable (GL_BLEND); |
617 | } | |
618 | } | |
619 | ||
a1954302 | 620 | myZLayers.Render (AWorkspace, theToDrawImmediate); |
2166f0fa | 621 | |
ca3c13d1 | 622 | #if !defined(GL_ES_VERSION_2_0) |
2166f0fa | 623 | //TsmPopAttri(); /* restore previous graphics context; before update lights */ |
de75ed09 | 624 | glPopAttrib(); |
ca3c13d1 | 625 | #endif |
2166f0fa SK |
626 | } |
627 | ||
628 | /*----------------------------------------------------------------------*/ | |
629 | ||
630 | //call_togl_redraw_layer2d | |
a174a3c5 | 631 | void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext, |
c827ea3a | 632 | const Handle(OpenGl_Workspace)& theWorkspace, |
93e572ca | 633 | const Graphic3d_CView& /*ACView*/, |
a174a3c5 | 634 | const Aspect_CLayer2d& ACLayer) |
2166f0fa | 635 | { |
ca3c13d1 | 636 | #if !defined(GL_ES_VERSION_2_0) |
2166f0fa SK |
637 | if (&ACLayer == NULL |
638 | || ACLayer.ptrLayer == NULL | |
639 | || ACLayer.ptrLayer->listIndex == 0) return; | |
640 | ||
c827ea3a | 641 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); |
642 | ||
529afc1a K |
643 | GLsizei dispWidth = (GLsizei )ACLayer.viewport[0]; |
644 | GLsizei dispHeight = (GLsizei )ACLayer.viewport[1]; | |
2166f0fa | 645 | |
c827ea3a | 646 | aContext->WorldViewState.Push(); |
647 | aContext->ProjectionState.Push(); | |
2166f0fa | 648 | |
c827ea3a | 649 | aContext->WorldViewState.SetIdentity(); |
650 | aContext->ProjectionState.SetIdentity(); | |
651 | ||
652 | aContext->ApplyWorldViewMatrix(); | |
653 | aContext->ApplyProjectionMatrix(); | |
2166f0fa SK |
654 | |
655 | if (!ACLayer.sizeDependent) | |
e3573bb9 | 656 | aContext->core11fwd->glViewport (0, 0, dispWidth, dispHeight); |
2166f0fa SK |
657 | |
658 | float left = ACLayer.ortho[0]; | |
659 | float right = ACLayer.ortho[1]; | |
660 | float bottom = ACLayer.ortho[2]; | |
661 | float top = ACLayer.ortho[3]; | |
662 | ||
663 | int attach = ACLayer.attach; | |
664 | ||
e3573bb9 | 665 | const float ratio = !ACLayer.sizeDependent |
666 | ? float(dispWidth) / float(dispHeight) | |
667 | : float(theWorkspace->Width()) / float(theWorkspace->Height()); | |
2166f0fa SK |
668 | |
669 | float delta; | |
c9d4eb9d | 670 | if (ratio >= 1.0) { |
2166f0fa SK |
671 | delta = (float )((top - bottom)/2.0); |
672 | switch (attach) { | |
673 | case 0: /* Aspect_TOC_BOTTOM_LEFT */ | |
674 | top = bottom + 2*delta/ratio; | |
675 | break; | |
676 | case 1: /* Aspect_TOC_BOTTOM_RIGHT */ | |
677 | top = bottom + 2*delta/ratio; | |
678 | break; | |
679 | case 2: /* Aspect_TOC_TOP_LEFT */ | |
680 | bottom = top - 2*delta/ratio; | |
681 | break; | |
682 | case 3: /* Aspect_TOC_TOP_RIGHT */ | |
683 | bottom = top - 2*delta/ratio; | |
684 | break; | |
685 | } | |
686 | } | |
c9d4eb9d | 687 | else { |
2166f0fa SK |
688 | delta = (float )((right - left)/2.0); |
689 | switch (attach) { | |
690 | case 0: /* Aspect_TOC_BOTTOM_LEFT */ | |
691 | right = left + 2*delta*ratio; | |
692 | break; | |
693 | case 1: /* Aspect_TOC_BOTTOM_RIGHT */ | |
694 | left = right - 2*delta*ratio; | |
695 | break; | |
696 | case 2: /* Aspect_TOC_TOP_LEFT */ | |
697 | right = left + 2*delta*ratio; | |
698 | break; | |
699 | case 3: /* Aspect_TOC_TOP_RIGHT */ | |
700 | left = right - 2*delta*ratio; | |
701 | break; | |
702 | } | |
703 | } | |
704 | ||
a174a3c5 | 705 | #ifdef _WIN32 |
2166f0fa | 706 | // Check printer context that exists only for print operation |
a174a3c5 | 707 | if (!thePrintContext.IsNull()) |
2166f0fa SK |
708 | { |
709 | // additional transformation matrix could be applied to | |
710 | // render only those parts of viewport that will be | |
711 | // passed to a printer as a current "frame" to provide | |
712 | // tiling; scaling of graphics by matrix helps render a | |
713 | // part of a view (frame) in same viewport, but with higher | |
714 | // resolution | |
c827ea3a | 715 | |
716 | // set printing scale/tiling transformation | |
717 | aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation()); | |
718 | aContext->ApplyProjectionMatrix(); | |
2166f0fa SK |
719 | |
720 | // printing operation also assumes other viewport dimension | |
721 | // to comply with transformation matrix or graphics scaling | |
722 | // factors for tiling for layer redraw | |
723 | GLsizei anViewportX = 0; | |
724 | GLsizei anViewportY = 0; | |
a174a3c5 | 725 | thePrintContext->GetLayerViewport (anViewportX, anViewportY); |
2166f0fa | 726 | if (anViewportX != 0 && anViewportY != 0) |
e3573bb9 | 727 | aContext->core11fwd->glViewport (0, 0, anViewportX, anViewportY); |
2166f0fa | 728 | } |
3c3131a0 | 729 | #endif |
2166f0fa SK |
730 | |
731 | glOrtho (left, right, bottom, top, -1.0, 1.0); | |
732 | ||
2166f0fa SK |
733 | glPushAttrib ( |
734 | GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT | | |
735 | GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT ); | |
c9d4eb9d | 736 | |
2166f0fa | 737 | glDisable (GL_DEPTH_TEST); |
c9d4eb9d | 738 | glDisable (GL_TEXTURE_1D); |
739 | glDisable (GL_TEXTURE_2D); | |
740 | glDisable (GL_LIGHTING); | |
741 | ||
742 | // TODO: Obsolete code, the display list is always empty now, to be removed | |
2166f0fa SK |
743 | glCallList (ACLayer.ptrLayer->listIndex); |
744 | ||
745 | //calling dynamic render of LayerItems | |
746 | if ( ACLayer.ptrLayer->layerData ) | |
747 | { | |
30f0ad28 | 748 | InitLayerProp (ACLayer.ptrLayer->listIndex); |
2166f0fa | 749 | ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems(); |
30f0ad28 | 750 | InitLayerProp (0); |
2166f0fa SK |
751 | } |
752 | ||
753 | glPopAttrib (); | |
754 | ||
c827ea3a | 755 | aContext->WorldViewState.Pop(); |
756 | aContext->ProjectionState.Pop(); | |
2166f0fa | 757 | |
c827ea3a | 758 | aContext->ApplyProjectionMatrix(); |
759 | aContext->ApplyWorldViewMatrix(); | |
2166f0fa | 760 | |
2166f0fa | 761 | if (!ACLayer.sizeDependent) |
e3573bb9 | 762 | aContext->core11fwd->glViewport (0, 0, theWorkspace->Width(), theWorkspace->Height()); |
2166f0fa SK |
763 | |
764 | glFlush (); | |
ca3c13d1 | 765 | #endif |
2166f0fa SK |
766 | } |
767 | ||
768 | /*----------------------------------------------------------------------*/ | |
769 | ||
a89742cf | 770 | void OpenGl_View::RedrawTrihedron (const Handle(OpenGl_Workspace) &theWorkspace) |
771 | { | |
772 | // display global trihedron | |
773 | if (myTrihedron != NULL) | |
774 | { | |
775 | myTrihedron->Render (theWorkspace); | |
776 | } | |
777 | if (myGraduatedTrihedron != NULL) | |
778 | { | |
779 | myGraduatedTrihedron->Render (theWorkspace); | |
780 | } | |
781 | } | |
782 | ||
783 | /*----------------------------------------------------------------------*/ | |
784 | ||
2166f0fa | 785 | //call_togl_create_bg_texture |
3c3131a0 | 786 | void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath, |
787 | const Aspect_FillMethod theFillStyle) | |
2166f0fa | 788 | { |
0b0320e7 | 789 | // Prepare aspect for texture storage |
790 | Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d(); | |
791 | Handle(Graphic3d_Texture2Dmanual) aTextureMap = new Graphic3d_Texture2Dmanual (TCollection_AsciiString (theFilePath)); | |
792 | aTextureMap->EnableRepeat(); | |
793 | aTextureMap->DisableModulate(); | |
794 | aTextureMap->GetParams()->SetGenMode (Graphic3d_TOTM_MANUAL, | |
795 | Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f), | |
796 | Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 0.0f)); | |
797 | anAspect->SetTextureMap (aTextureMap); | |
798 | anAspect->SetInteriorStyle (Aspect_IS_SOLID); | |
799 | // Enable texture mapping | |
800 | if (aTextureMap->IsDone()) | |
801 | { | |
802 | anAspect->SetTextureMapOn(); | |
3c3131a0 | 803 | } |
804 | else | |
805 | { | |
0b0320e7 | 806 | anAspect->SetTextureMapOff(); |
807 | return; | |
3c3131a0 | 808 | |
3c3131a0 | 809 | } |
2166f0fa | 810 | |
0b0320e7 | 811 | // Set texture parameters |
812 | myTextureParams->SetAspect (anAspect); | |
2166f0fa | 813 | |
0b0320e7 | 814 | myBgTextureArray->SetTextureParameters (theFillStyle); |
2166f0fa SK |
815 | } |
816 | ||
817 | /*----------------------------------------------------------------------*/ | |
818 | ||
819 | //call_togl_set_bg_texture_style | |
0b0320e7 | 820 | void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod theFillStyle) |
2166f0fa | 821 | { |
0b0320e7 | 822 | myBgTextureArray->SetTextureFillMethod (theFillStyle); |
2166f0fa SK |
823 | } |
824 | ||
825 | /*----------------------------------------------------------------------*/ | |
826 | ||
827 | //call_togl_gradient_background | |
0b0320e7 | 828 | void OpenGl_View::SetBackgroundGradient (const Quantity_Color& theColor1, |
829 | const Quantity_Color& theColor2, | |
830 | const Aspect_GradientFillMethod theType) | |
2166f0fa | 831 | { |
0b0320e7 | 832 | myBgGradientArray->SetGradientParameters (theColor1, theColor2, theType); |
2166f0fa SK |
833 | } |
834 | ||
835 | /*----------------------------------------------------------------------*/ | |
836 | ||
837 | //call_togl_set_gradient_type | |
0b0320e7 | 838 | void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod theType) |
2166f0fa | 839 | { |
0b0320e7 | 840 | myBgGradientArray->SetGradientFillMethod (theType); |
2166f0fa SK |
841 | } |
842 | ||
59f45b7c | 843 | //======================================================================= |
844 | //function : AddZLayer | |
3c3131a0 | 845 | //purpose : |
59f45b7c | 846 | //======================================================================= |
847 | ||
a1954302 | 848 | void OpenGl_View::AddZLayer (const Graphic3d_ZLayerId theLayerId) |
59f45b7c | 849 | { |
850 | myZLayers.AddLayer (theLayerId); | |
851 | } | |
852 | ||
853 | //======================================================================= | |
854 | //function : RemoveZLayer | |
3c3131a0 | 855 | //purpose : |
59f45b7c | 856 | //======================================================================= |
857 | ||
a1954302 | 858 | void OpenGl_View::RemoveZLayer (const Graphic3d_ZLayerId theLayerId) |
59f45b7c | 859 | { |
860 | myZLayers.RemoveLayer (theLayerId); | |
861 | } | |
862 | ||
863 | //======================================================================= | |
864 | //function : DisplayStructure | |
3c3131a0 | 865 | //purpose : |
59f45b7c | 866 | //======================================================================= |
867 | ||
a1954302 | 868 | void OpenGl_View::DisplayStructure (const Handle(Graphic3d_Structure)& theStructure, |
869 | const Standard_Integer thePriority) | |
59f45b7c | 870 | { |
a1954302 | 871 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->()); |
872 | const Graphic3d_ZLayerId aZLayer = aStruct->ZLayer(); | |
873 | myZLayers.AddStructure (aStruct, aZLayer, thePriority); | |
59f45b7c | 874 | } |
875 | ||
679ecdee | 876 | //======================================================================= |
877 | //function : DisplayImmediateStructure | |
878 | //purpose : | |
879 | //======================================================================= | |
880 | ||
a1954302 | 881 | void OpenGl_View::DisplayImmediateStructure (const Handle(Graphic3d_Structure)& theStructure) |
679ecdee | 882 | { |
a1954302 | 883 | const OpenGl_Structure* aStruct = reinterpret_cast<const OpenGl_Structure*> (theStructure->CStructure().operator->()); |
679ecdee | 884 | for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList); |
885 | anIter.More(); anIter.Next()) | |
886 | { | |
a1954302 | 887 | if (anIter.Value() == aStruct) |
679ecdee | 888 | { |
889 | return; | |
890 | } | |
891 | } | |
892 | ||
a1954302 | 893 | myImmediateList.Append (aStruct); |
679ecdee | 894 | } |
895 | ||
59f45b7c | 896 | //======================================================================= |
897 | //function : EraseStructure | |
3c3131a0 | 898 | //purpose : |
59f45b7c | 899 | //======================================================================= |
900 | ||
a1954302 | 901 | void OpenGl_View::EraseStructure (const Handle(Graphic3d_Structure)& theStructure) |
59f45b7c | 902 | { |
a1954302 | 903 | myZLayers.RemoveStructure (theStructure); |
59f45b7c | 904 | } |
905 | ||
906 | //======================================================================= | |
679ecdee | 907 | //function : EraseImmediateStructure |
908 | //purpose : | |
909 | //======================================================================= | |
910 | ||
911 | void OpenGl_View::EraseImmediateStructure (const OpenGl_Structure* theStructure) | |
912 | { | |
913 | for (OpenGl_SequenceOfStructure::Iterator anIter (myImmediateList); | |
914 | anIter.More(); anIter.Next()) | |
915 | { | |
916 | if (anIter.Value() == theStructure) | |
917 | { | |
918 | myImmediateList.Remove (anIter); | |
919 | return; | |
920 | } | |
921 | } | |
922 | } | |
923 | ||
924 | //======================================================================= | |
59f45b7c | 925 | //function : ChangeZLayer |
926 | //purpose : | |
927 | //======================================================================= | |
928 | ||
a1954302 | 929 | void OpenGl_View::ChangeZLayer (const OpenGl_Structure* theStructure, |
930 | const Graphic3d_ZLayerId theNewLayerId) | |
59f45b7c | 931 | { |
a1954302 | 932 | const Graphic3d_ZLayerId anOldLayer = theStructure->ZLayer(); |
59f45b7c | 933 | myZLayers.ChangeLayer (theStructure, anOldLayer, theNewLayerId); |
934 | } | |
b5ac8292 | 935 | |
c5751993 | 936 | //======================================================================= |
937 | //function : SetZLayerSettings | |
938 | //purpose : | |
939 | //======================================================================= | |
a1954302 | 940 | void OpenGl_View::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId, |
941 | const Graphic3d_ZLayerSettings& theSettings) | |
c5751993 | 942 | { |
a1954302 | 943 | myZLayers.SetLayerSettings (theLayerId, theSettings); |
c5751993 | 944 | } |
945 | ||
b7cd4ba7 | 946 | //======================================================================= |
947 | //function : ChangePriority | |
948 | //purpose : | |
949 | //======================================================================= | |
950 | void OpenGl_View::ChangePriority (const OpenGl_Structure *theStructure, | |
951 | const Standard_Integer theNewPriority) | |
952 | { | |
a1954302 | 953 | const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer(); |
b7cd4ba7 | 954 | myZLayers.ChangePriority (theStructure, aLayerId, theNewPriority); |
955 | } | |
c5751993 | 956 | |
b5ac8292 | 957 | //======================================================================= |
958 | //function : RedrawScene | |
959 | //purpose : | |
960 | //======================================================================= | |
961 | ||
962 | void OpenGl_View::RedrawScene (const Handle(OpenGl_PrinterContext)& thePrintContext, | |
a1954302 | 963 | const Handle(OpenGl_Workspace)& theWorkspace, |
964 | const Standard_Boolean theToDrawImmediate) | |
b5ac8292 | 965 | { |
966 | const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); | |
967 | ||
968 | if (myZClip.Back.IsOn || myZClip.Front.IsOn) | |
969 | { | |
970 | Handle(Graphic3d_ClipPlane) aPlaneBack; | |
971 | Handle(Graphic3d_ClipPlane) aPlaneFront; | |
972 | ||
973 | if (myZClip.Back.IsOn) | |
974 | { | |
975 | Standard_Real aClipBackConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance(); | |
976 | if (myCamera->ZFar() < aClipBackConverted) | |
977 | { | |
978 | aClipBackConverted = myCamera->ZFar(); | |
979 | myZClip.Back.Limit = (Standard_ShortReal )(aClipBackConverted - myCamera->Distance()); | |
980 | } | |
981 | const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, (Standard_ShortReal )aClipBackConverted); | |
982 | aPlaneBack = new Graphic3d_ClipPlane (aBackEquation); | |
983 | } | |
984 | ||
985 | if (myZClip.Front.IsOn) | |
986 | { | |
987 | Standard_Real aClipFrontConverted = (Standard_Real )myZClip.Front.Limit + myCamera->Distance(); | |
988 | if (myCamera->ZNear() > aClipFrontConverted) | |
989 | { | |
990 | aClipFrontConverted = myCamera->ZNear(); | |
991 | myZClip.Front.Limit = (Standard_ShortReal )(aClipFrontConverted - myCamera->Distance()); | |
992 | } | |
993 | const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, (Standard_ShortReal )-aClipFrontConverted); | |
994 | aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation); | |
995 | } | |
996 | ||
cddbf6a9 | 997 | // Specify slicing planes with identity transformation |
b5ac8292 | 998 | if (!aPlaneBack.IsNull() || !aPlaneFront.IsNull()) |
999 | { | |
1000 | Graphic3d_SequenceOfHClipPlane aSlicingPlanes; | |
1001 | if (!aPlaneBack.IsNull()) | |
1002 | { | |
1003 | aSlicingPlanes.Append (aPlaneBack); | |
1004 | } | |
1005 | ||
1006 | if (!aPlaneFront.IsNull()) | |
1007 | { | |
1008 | aSlicingPlanes.Append (aPlaneFront); | |
1009 | } | |
1010 | ||
1011 | // add planes at loaded view matrix state | |
1012 | aContext->ChangeClipping().AddView (aSlicingPlanes, theWorkspace); | |
1013 | } | |
1014 | } | |
1015 | ||
b5ac8292 | 1016 | #ifdef _WIN32 |
c827ea3a | 1017 | // set printing scale/tiling transformation |
b5ac8292 | 1018 | if (!thePrintContext.IsNull()) |
1019 | { | |
c827ea3a | 1020 | aContext->ProjectionState.Push(); |
1021 | aContext->ProjectionState.SetCurrent (thePrintContext->ProjTransformation() * aContext->ProjectionState.Current()); | |
1022 | aContext->ApplyProjectionMatrix(); | |
b5ac8292 | 1023 | } |
ca3c13d1 | 1024 | #endif |
b5ac8292 | 1025 | |
cddbf6a9 | 1026 | // Specify clipping planes in view transformation space |
1027 | if (!myClipPlanes.IsEmpty()) | |
1028 | { | |
1029 | Graphic3d_SequenceOfHClipPlane aUserPlanes; | |
1030 | Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes); | |
1031 | for (; aClippingIt.More(); aClippingIt.Next()) | |
1032 | { | |
1033 | const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value(); | |
1034 | if (aClipPlane->IsOn()) | |
1035 | { | |
1036 | aUserPlanes.Append (aClipPlane); | |
1037 | } | |
1038 | } | |
1039 | ||
1040 | if (!aUserPlanes.IsEmpty()) | |
1041 | { | |
1042 | aContext->ChangeClipping().AddWorld (aUserPlanes); | |
1043 | } | |
1044 | ||
1045 | if (!aContext->ShaderManager()->IsEmpty()) | |
1046 | { | |
1047 | aContext->ShaderManager()->UpdateClippingState(); | |
1048 | } | |
1049 | } | |
1050 | ||
ca3c13d1 | 1051 | #if !defined(GL_ES_VERSION_2_0) |
b5ac8292 | 1052 | // Apply Lights |
1053 | { | |
1054 | // setup lights | |
1055 | Graphic3d_Vec4 anAmbientColor (THE_DEFAULT_AMBIENT[0], | |
1056 | THE_DEFAULT_AMBIENT[1], | |
1057 | THE_DEFAULT_AMBIENT[2], | |
1058 | THE_DEFAULT_AMBIENT[3]); | |
1059 | GLenum aLightGlId = GL_LIGHT0; | |
1060 | for (OpenGl_ListOfLight::Iterator aLightIt (myLights); | |
1061 | aLightIt.More(); aLightIt.Next()) | |
1062 | { | |
c827ea3a | 1063 | bindLight (aLightIt.Value(), aLightGlId, anAmbientColor, theWorkspace); |
b5ac8292 | 1064 | } |
1065 | ||
1066 | // apply accumulated ambient color | |
1067 | anAmbientColor.a() = 1.0f; | |
1068 | glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbientColor.GetData()); | |
1069 | ||
1070 | if (aLightGlId != GL_LIGHT0) | |
1071 | { | |
1072 | glEnable (GL_LIGHTING); | |
1073 | } | |
1074 | // switch off unused lights | |
1075 | for (; aLightGlId <= GL_LIGHT7; ++aLightGlId) | |
1076 | { | |
1077 | glDisable (aLightGlId); | |
1078 | } | |
1079 | } | |
ca3c13d1 | 1080 | #endif |
b5ac8292 | 1081 | |
1082 | // Clear status bitfields | |
1083 | theWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO); | |
1084 | ||
1085 | // Added PCT for handling of textures | |
1086 | switch (mySurfaceDetail) | |
1087 | { | |
1088 | case Visual3d_TOD_NONE: | |
1089 | theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX; | |
1090 | theWorkspace->DisableTexture(); | |
1091 | // Render the view | |
a1954302 | 1092 | RenderStructs (theWorkspace, theToDrawImmediate); |
b5ac8292 | 1093 | break; |
1094 | ||
1095 | case Visual3d_TOD_ENVIRONMENT: | |
1096 | theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX; | |
1097 | theWorkspace->EnableTexture (myTextureEnv); | |
1098 | // Render the view | |
a1954302 | 1099 | RenderStructs (theWorkspace, theToDrawImmediate); |
b5ac8292 | 1100 | theWorkspace->DisableTexture(); |
1101 | break; | |
1102 | ||
1103 | case Visual3d_TOD_ALL: | |
1104 | // First pass | |
1105 | theWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX; | |
1106 | // Render the view | |
a1954302 | 1107 | RenderStructs (theWorkspace, theToDrawImmediate); |
b5ac8292 | 1108 | theWorkspace->DisableTexture(); |
1109 | ||
1110 | // Second pass | |
1111 | if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) | |
1112 | { | |
1113 | theWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO; | |
1114 | theWorkspace->EnableTexture (myTextureEnv); | |
1115 | ||
1116 | // Remember OpenGl properties | |
ca3c13d1 | 1117 | GLint aSaveBlendDst = GL_ONE_MINUS_SRC_ALPHA, aSaveBlendSrc = GL_SRC_ALPHA; |
b5ac8292 | 1118 | GLint aSaveZbuffFunc; |
1119 | GLboolean aSaveZbuffWrite; | |
1120 | glGetBooleanv (GL_DEPTH_WRITEMASK, &aSaveZbuffWrite); | |
1121 | glGetIntegerv (GL_DEPTH_FUNC, &aSaveZbuffFunc); | |
ca3c13d1 | 1122 | #if !defined(GL_ES_VERSION_2_0) |
b5ac8292 | 1123 | glGetIntegerv (GL_BLEND_DST, &aSaveBlendDst); |
1124 | glGetIntegerv (GL_BLEND_SRC, &aSaveBlendSrc); | |
ca3c13d1 | 1125 | #endif |
b5ac8292 | 1126 | GLboolean wasZbuffEnabled = glIsEnabled (GL_DEPTH_TEST); |
1127 | GLboolean wasBlendEnabled = glIsEnabled (GL_BLEND); | |
1128 | ||
1129 | // Change the properties for second rendering pass | |
1130 | glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
1131 | glEnable (GL_BLEND); | |
1132 | ||
1133 | glDepthFunc (GL_EQUAL); | |
1134 | glDepthMask (GL_FALSE); | |
1135 | glEnable (GL_DEPTH_TEST); | |
1136 | ||
1137 | theWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX; | |
1138 | ||
1139 | // Render the view | |
a1954302 | 1140 | RenderStructs (theWorkspace, theToDrawImmediate); |
b5ac8292 | 1141 | theWorkspace->DisableTexture(); |
1142 | ||
1143 | // Restore properties back | |
1144 | glBlendFunc (aSaveBlendSrc, aSaveBlendDst); | |
1145 | if (!wasBlendEnabled) | |
1146 | glDisable (GL_BLEND); | |
1147 | ||
1148 | glDepthFunc (aSaveZbuffFunc); | |
1149 | glDepthMask (aSaveZbuffWrite); | |
1150 | if (!wasZbuffEnabled) | |
1151 | glDisable (GL_DEPTH_FUNC); | |
1152 | } | |
1153 | break; | |
1154 | } | |
c827ea3a | 1155 | |
1156 | // Apply restored view matrix. | |
1157 | aContext->ApplyWorldViewMatrix(); | |
1158 | ||
1159 | #ifdef _WIN32 | |
1160 | // set printing scale/tiling transformation | |
1161 | if (!thePrintContext.IsNull()) | |
1162 | { | |
1163 | aContext->ProjectionState.Pop(); | |
1164 | aContext->ApplyProjectionMatrix(); | |
1165 | } | |
1166 | #endif | |
1167 | ||
b5ac8292 | 1168 | } |