Samples update
[occt.git] / src / OpenGl / OpenGl_View.cxx
CommitLineData
b311480e 1// Created on: 2011-09-20
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
e276548b 20
21#ifdef HAVE_CONFIG_H
22 #include <config.h>
23#endif
24
30f0ad28 25#include <NCollection_Mat4.hxx>
5f8b738e 26
bf75be98 27#include <OpenGl_Context.hxx>
2166f0fa 28#include <OpenGl_Display.hxx>
30f0ad28 29#include <OpenGl_GlCore11.hxx>
30#include <OpenGl_GraduatedTrihedron.hxx>
31#include <OpenGl_ShaderManager.hxx>
bf75be98 32#include <OpenGl_Texture.hxx>
2166f0fa 33#include <OpenGl_Trihedron.hxx>
2166f0fa 34#include <OpenGl_transform_persistence.hxx>
30f0ad28 35#include <OpenGl_View.hxx>
36#include <OpenGl_Workspace.hxx>
2166f0fa 37
bf75be98 38#include <Graphic3d_TextureEnv.hxx>
39
2166f0fa
SK
40IMPLEMENT_STANDARD_HANDLE(OpenGl_View,MMgt_TShared)
41IMPLEMENT_STANDARD_RTTIEXT(OpenGl_View,MMgt_TShared)
42
43/*----------------------------------------------------------------------*/
44
45static const OPENGL_BG_TEXTURE myDefaultBgTexture = { 0, 0, 0, Aspect_FM_CENTERED };
46static const OPENGL_BG_GRADIENT myDefaultBgGradient = { {{ 0.F, 0.F, 0.F, 1.F }}, {{ 0.F, 0.F, 0.F, 1.F }}, Aspect_GFM_NONE };
47static const Tmatrix3 myDefaultMatrix = { { 1.F, 0.F, 0.F, 0.F }, { 0.F, 1.F, 0.F, 0.F }, { 0.F, 0.F, 1.F, 0.F }, { 0.F, 0.F, 0.F, 1.F } };
48static const OPENGL_ZCLIP myDefaultZClip = { { Standard_True, 0.F }, { Standard_True, 1.F } };
49static const OPENGL_EXTRA_REP myDefaultExtra =
50{
51 //vrp
52 { 0.F, 0.F, 0.F },
53 //vpn
54 { 0.F, 0.F, 1.F },
55 //vup
56 { 0.F, 1.F, 0.F },
57 //map
58 {
59 //window
60 { 0.F, 0.F, 1.F, 1.F },
61 //viewport
62 { 0.F, 0.F, 0.F, 1.F, 1.F, 1.F },
63 //proj
64 TelParallel,
65 //prp
66 { 0.F, 0.F, 0.F },
67 //vpd
68 0.F,
69 //fpd
70 0.F,
71 //bpd
72 -1.F
73 },
74 //scaleFactors
75 { 1.F, 1.F, 1.F }
76};
77
78static const OPENGL_FOG myDefaultFog = { Standard_False, 0.F, 1.F, { { 0.F, 0.F, 0.F, 1.F } } };
79static const TEL_TRANSFORM_PERSISTENCE myDefaultTransPers = { 0, 0.F, 0.F, 0.F };
c34dba32 80static const GLdouble THE_IDENTITY_MATRIX[4][4] =
81{
82 {1.0, 0.0, 0.0, 0.0},
83 {0.0, 1.0, 0.0, 0.0},
84 {0.0, 0.0, 1.0, 0.0},
85 {0.0, 0.0, 0.0, 1.0}
86};
2166f0fa
SK
87
88/*----------------------------------------------------------------------*/
89
90OpenGl_View::OpenGl_View (const CALL_DEF_VIEWCONTEXT &AContext)
bf75be98 91: mySurfaceDetail(Visual3d_TOD_NONE),
2166f0fa
SK
92 myBackfacing(0),
93 myBgTexture(myDefaultBgTexture),
94 myBgGradient(myDefaultBgGradient),
95 //myOrientationMatrix(myDefaultMatrix),
96 //myMappingMatrix(myDefaultMatrix),
97 //shield_indicator = TOn,
98 //shield_colour = { { 0.F, 0.F, 0.F, 1.F } },
99 //border_indicator = TOff,
100 //border_colour = { { 0.F, 0.F, 0.F, 1.F } },
101 //active_status = TOn,
102 myZClip(myDefaultZClip),
103 myExtra(myDefaultExtra),
104 myFog(myDefaultFog),
2f6cb3ac 105 myTrihedron(NULL),
106 myGraduatedTrihedron(NULL),
2166f0fa
SK
107 myVisualization(AContext.Visualization),
108 myIntShadingMethod(TEL_SM_GOURAUD),
109 myAntiAliasing(Standard_False),
2166f0fa 110 myTransPers(&myDefaultTransPers),
30f0ad28 111 myIsTransPers(Standard_False),
112 myOrientationChanged (Standard_True),
113 myViewMappingChanged (Standard_True),
114 myLightSourcesChanged (Standard_True)
2166f0fa
SK
115{
116 // Initialize matrices
117 memcpy(myOrientationMatrix,myDefaultMatrix,sizeof(Tmatrix3));
118 memcpy(myMappingMatrix,myDefaultMatrix,sizeof(Tmatrix3));
119
120 // Shading method
121 switch (AContext.Model)
122 {
123 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
124 case 3 : /* VISUAL3D_TOM_VERTEX */
125 myIntShadingMethod = TEL_SM_GOURAUD;
126 break;
127 default :
128 myIntShadingMethod = TEL_SM_FLAT;
129 break;
130 }
e276548b 131
132#ifdef HAVE_OPENCL
133 myModificationState = 1; // initial state
134#endif
2166f0fa
SK
135}
136
137/*----------------------------------------------------------------------*/
138
139OpenGl_View::~OpenGl_View ()
140{
bf75be98 141 ReleaseGlResources (NULL); // ensure ReleaseGlResources() was called within valid context
142}
143
144void OpenGl_View::ReleaseGlResources (const Handle(OpenGl_Context)& theCtx)
145{
a174a3c5 146 OpenGl_Element::Destroy (theCtx, myTrihedron);
147 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
30f0ad28 148
bf75be98 149 if (!myTextureEnv.IsNull())
150 {
151 theCtx->DelayedRelease (myTextureEnv);
152 myTextureEnv.Nullify();
153 }
154 if (myBgTexture.TexId != 0)
155 {
156 glDeleteTextures (1, (GLuint*)&(myBgTexture.TexId));
157 myBgTexture.TexId = 0;
158 }
bf75be98 159}
2166f0fa 160
bf75be98 161void OpenGl_View::SetTextureEnv (const Handle(OpenGl_Context)& theCtx,
162 const Handle(Graphic3d_TextureEnv)& theTexture)
163{
164 if (!myTextureEnv.IsNull())
165 {
166 theCtx->DelayedRelease (myTextureEnv);
167 myTextureEnv.Nullify();
168 }
169
170 if (theTexture.IsNull())
171 {
172 return;
173 }
174
175 myTextureEnv = new OpenGl_Texture (theTexture->GetParams());
176 Handle(Image_PixMap) anImage = theTexture->GetImage();
e276548b 177 if (!anImage.IsNull())
da0e82aa 178 myTextureEnv->Init (theCtx, *anImage.operator->(), theTexture->Type());
e276548b 179
180#ifdef HAVE_OPENCL
181 myModificationState++;
182#endif
183}
184
185void OpenGl_View::SetSurfaceDetail (const Visual3d_TypeOfSurfaceDetail theMode)
186{
187 mySurfaceDetail = theMode;
188
189#ifdef HAVE_OPENCL
190 myModificationState++;
191#endif
2166f0fa
SK
192}
193
194/*----------------------------------------------------------------------*/
195
de75ed09 196void OpenGl_View::SetBackfacing (const Standard_Integer theMode)
2166f0fa 197{
de75ed09 198 myBackfacing = theMode;
2166f0fa
SK
199}
200
201/*----------------------------------------------------------------------*/
202
203//call_togl_setlight
204void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
205{
206 myLights.Clear();
207
208 const int nb_lights = AContext.NbActiveLight;
209
210 int i = 0;
211 const CALL_DEF_LIGHT *alight = &(AContext.ActiveLight[0]);
212 for ( ; i < nb_lights; i++, alight++ )
213 {
214 OpenGl_Light rep;
d20d815b 215 memset(&rep,0,sizeof(rep));
2166f0fa
SK
216
217 switch( alight->LightType )
218 {
219 case 0 : /* TOLS_AMBIENT */
220 rep.type = TLightAmbient;
221 rep.col.rgb[0] = alight->Color.r;
222 rep.col.rgb[1] = alight->Color.g;
223 rep.col.rgb[2] = alight->Color.b;
224 break;
225
226 case 1 : /* TOLS_DIRECTIONAL */
227 rep.type = TLightDirectional;
228 rep.col.rgb[0] = alight->Color.r;
229 rep.col.rgb[1] = alight->Color.g;
230 rep.col.rgb[2] = alight->Color.b;
231 rep.dir[0] = alight->Direction.x;
232 rep.dir[1] = alight->Direction.y;
233 rep.dir[2] = alight->Direction.z;
234 break;
235
236 case 2 : /* TOLS_POSITIONAL */
237 rep.type = TLightPositional;
238 rep.col.rgb[0] = alight->Color.r;
239 rep.col.rgb[1] = alight->Color.g;
240 rep.col.rgb[2] = alight->Color.b;
241 rep.pos[0] = alight->Position.x;
242 rep.pos[1] = alight->Position.y;
243 rep.pos[2] = alight->Position.z;
244 rep.atten[0] = alight->Attenuation[0];
245 rep.atten[1] = alight->Attenuation[1];
246 break;
247
248 case 3 : /* TOLS_SPOT */
249 rep.type = TLightSpot;
250 rep.col.rgb[0] = alight->Color.r;
251 rep.col.rgb[1] = alight->Color.g;
252 rep.col.rgb[2] = alight->Color.b;
253 rep.pos[0] = alight->Position.x;
254 rep.pos[1] = alight->Position.y;
255 rep.pos[2] = alight->Position.z;
256 rep.dir[0] = alight->Direction.x;
257 rep.dir[1] = alight->Direction.y;
258 rep.dir[2] = alight->Direction.z;
259 rep.shine = alight->Concentration;
260 rep.atten[0] = alight->Attenuation[0];
261 rep.atten[1] = alight->Attenuation[1];
262 rep.angle = alight->Angle;
263 break;
264 }
265
266 rep.HeadLight = alight->Headlight;
267
268 myLights.Append(rep);
269 }
30f0ad28 270
271 myLightSourcesChanged = Standard_True;
2166f0fa
SK
272}
273
274/*----------------------------------------------------------------------*/
275
2166f0fa
SK
276//call_togl_setvisualisation
277void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
278{
279 myVisualization = AContext.Visualization;
280 // Shading method
281 switch (AContext.Model)
282 {
283 case 1 : /* VISUAL3D_TOM_INTERP_COLOR */
284 case 3 : /* VISUAL3D_TOM_VERTEX */
285 myIntShadingMethod = TEL_SM_GOURAUD;
286 break;
287 default :
288 myIntShadingMethod = TEL_SM_FLAT;
289 break;
290 }
291}
292
293/*----------------------------------------------------------------------*/
294
295//call_togl_cliplimit
bf75be98 296void OpenGl_View::SetClipLimit (const Graphic3d_CView& theCView)
2166f0fa
SK
297{
298 myZClip.Back.Limit =
bf75be98 299 (theCView.Context.ZClipBackPlane - theCView.Mapping.BackPlaneDistance) /
300 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa 301 myZClip.Front.Limit =
bf75be98 302 (theCView.Context.ZClipFrontPlane - theCView.Mapping.BackPlaneDistance) /
303 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
304 if (myZClip.Back.Limit < 0.0f)
305 myZClip.Back.Limit = 0.0f;
306 if (myZClip.Front.Limit > 1.0f)
307 myZClip.Front.Limit = 1.0f;
308 if (myZClip.Back.Limit > myZClip.Front.Limit)
2166f0fa 309 {
bf75be98 310 myZClip.Back.Limit = 0.0f;
311 myZClip.Front.Limit = 1.0f;
2166f0fa
SK
312 }
313
bf75be98 314 myZClip.Back.IsOn = (theCView.Context.BackZClipping != 0);
315 myZClip.Front.IsOn = (theCView.Context.FrontZClipping != 0);
2166f0fa
SK
316}
317
318/*----------------------------------------------------------------------*/
319
320//call_togl_viewmapping
fd4a6963 321void OpenGl_View::SetMapping (const Handle(OpenGl_Display)& theGlDisplay,
322 const Graphic3d_CView& theCView)
2166f0fa 323{
bf75be98 324 const float ratio = theCView.DefWindow.dy / theCView.DefWindow.dx;
325 const float r_ratio = theCView.DefWindow.dx / theCView.DefWindow.dy;
2166f0fa
SK
326
327 TEL_VIEW_MAPPING Map;
328
bf75be98 329 Map.window.xmin = theCView.Mapping.WindowLimit.um;
330 Map.window.ymin = theCView.Mapping.WindowLimit.vm;
331 Map.window.xmax = theCView.Mapping.WindowLimit.uM;
332 Map.window.ymax = theCView.Mapping.WindowLimit.vM;
2166f0fa
SK
333
334 Map.viewport.xmin = 0.F;
335 Map.viewport.xmax = ( 1.F < r_ratio ? 1.F : r_ratio );
336 Map.viewport.ymin = 0.F;
337 Map.viewport.ymax = ( 1.F < ratio ? 1.F : ratio );
338 Map.viewport.zmin = 0.F;
339 Map.viewport.zmax = 1.F;
340
bf75be98 341 // projection type
342 switch (theCView.Mapping.Projection)
2166f0fa
SK
343 {
344 case 0 :
345 Map.proj = TelPerspective;
346 break;
347 case 1 :
348 Map.proj = TelParallel;
349 break;
350 }
351
bf75be98 352 // projection reference point
353 Map.prp[0] = theCView.Mapping.ProjectionReferencePoint.x;
354 Map.prp[1] = theCView.Mapping.ProjectionReferencePoint.y;
355 Map.prp[2] = theCView.Mapping.ProjectionReferencePoint.z;
fd4a6963 356 if (!theGlDisplay.IsNull() && !theGlDisplay->Walkthrough())
bf75be98 357 Map.prp[2] += theCView.Mapping.FrontPlaneDistance;
2166f0fa 358
bf75be98 359 // view plane distance
360 Map.vpd = theCView.Mapping.ViewPlaneDistance;
2166f0fa 361
bf75be98 362 // back plane distance
363 Map.bpd = theCView.Mapping.BackPlaneDistance;
2166f0fa 364
bf75be98 365 // front plane distance
366 Map.fpd = theCView.Mapping.FrontPlaneDistance;
2166f0fa
SK
367
368 Tint err_ind = 0;
369
bf75be98 370 // use user-defined matrix
371 if (theCView.Mapping.IsCustomMatrix)
2166f0fa
SK
372 {
373 int i, j;
374 for( i = 0; i < 4; i++ )
375 for( j = 0; j < 4; j++ )
bf75be98 376 myMappingMatrix[i][j] = theCView.Mapping.ProjectionMatrix[i][j];
2166f0fa 377 }
bf75be98 378 else
fd4a6963 379 TelEvalViewMappingMatrix (theGlDisplay, &Map, &err_ind, myMappingMatrix);
2166f0fa 380
bf75be98 381 if (!err_ind)
2166f0fa 382 myExtra.map = Map;
30f0ad28 383
384 myViewMappingChanged = Standard_True;
2166f0fa
SK
385}
386
387/*----------------------------------------------------------------------*/
388
389//call_togl_vieworientation
bf75be98 390void OpenGl_View::SetOrientation (const Graphic3d_CView& theCView)
2166f0fa
SK
391{
392 Tfloat Vrp[3];
393 Tfloat Vpn[3];
394 Tfloat Vup[3];
395 Tfloat ScaleFactors[3];
396
bf75be98 397 Vrp[0] = theCView.Orientation.ViewReferencePoint.x;
398 Vrp[1] = theCView.Orientation.ViewReferencePoint.y;
399 Vrp[2] = theCView.Orientation.ViewReferencePoint.z;
2166f0fa 400
bf75be98 401 Vpn[0] = theCView.Orientation.ViewReferencePlane.x;
402 Vpn[1] = theCView.Orientation.ViewReferencePlane.y;
403 Vpn[2] = theCView.Orientation.ViewReferencePlane.z;
2166f0fa 404
bf75be98 405 Vup[0] = theCView.Orientation.ViewReferenceUp.x;
406 Vup[1] = theCView.Orientation.ViewReferenceUp.y;
407 Vup[2] = theCView.Orientation.ViewReferenceUp.z;
2166f0fa 408
bf75be98 409 ScaleFactors[0] = theCView.Orientation.ViewScaleX;
410 ScaleFactors[1] = theCView.Orientation.ViewScaleY;
411 ScaleFactors[2] = theCView.Orientation.ViewScaleZ;
2166f0fa
SK
412
413 Tint err_ind = 0;
414
415 // use user-defined matrix
bf75be98 416 if (theCView.Orientation.IsCustomMatrix)
2166f0fa
SK
417 {
418 int i, j;
419 for( i = 0; i < 4; i++ )
420 for( j = 0; j < 4; j++ )
bf75be98 421 myOrientationMatrix[i][j] = theCView.Orientation.ModelViewMatrix[i][j];
2166f0fa
SK
422 }
423 else
bf75be98 424 {
425 TelEvalViewOrientationMatrix (Vrp, Vpn, Vup, ScaleFactors, &err_ind, myOrientationMatrix);
426 }
2166f0fa 427
bf75be98 428 if (!err_ind)
2166f0fa
SK
429 {
430 myExtra.vrp[0] = Vrp[0];
431 myExtra.vrp[1] = Vrp[1];
432 myExtra.vrp[2] = Vrp[2];
433
434 myExtra.vpn[0] = Vpn[0];
435 myExtra.vpn[1] = Vpn[1];
436 myExtra.vpn[2] = Vpn[2];
437
438 myExtra.vup[0] = Vup[0];
439 myExtra.vup[1] = Vup[1];
440 myExtra.vup[2] = Vup[2];
441
442 myExtra.scaleFactors[0] = ScaleFactors[0],
443 myExtra.scaleFactors[1] = ScaleFactors[1],
444 myExtra.scaleFactors[2] = ScaleFactors[2];
445 }
30f0ad28 446
447 myOrientationChanged = Standard_True;
2166f0fa
SK
448}
449
450/*----------------------------------------------------------------------*/
451
bf75be98 452void OpenGl_View::SetFog (const Graphic3d_CView& theCView,
453 const Standard_Boolean theFlag)
2166f0fa 454{
bf75be98 455 if (!theFlag)
2166f0fa
SK
456 {
457 myFog.IsOn = Standard_False;
458 }
459 else
460 {
461 myFog.IsOn = Standard_True;
462
463 myFog.Front =
bf75be98 464 (theCView.Context.DepthFrontPlane - theCView.Mapping.BackPlaneDistance) /
465 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa
SK
466
467 myFog.Back =
bf75be98 468 (theCView.Context.DepthBackPlane - theCView.Mapping.BackPlaneDistance) /
469 (theCView.Mapping.FrontPlaneDistance - theCView.Mapping.BackPlaneDistance);
2166f0fa
SK
470
471 if (myFog.Front < 0.F)
472 myFog.Front = 0.F;
473 else if (myFog.Front > 1.F)
474 myFog.Front = 1.F;
475
476 if (myFog.Back < 0.F)
477 myFog.Back = 0.F;
478 else if (myFog.Back > 1.F)
479 myFog.Back = 1.F;
480
481 if (myFog.Back > myFog.Front)
482 {
483 myFog.Front = 1.F;
484 myFog.Back = 0.F;
485 }
486
bf75be98 487 myFog.Color.rgb[0] = theCView.DefWindow.Background.r;
488 myFog.Color.rgb[1] = theCView.DefWindow.Background.g;
489 myFog.Color.rgb[2] = theCView.DefWindow.Background.b;
490 myFog.Color.rgb[3] = 1.0f;
2166f0fa
SK
491 }
492}
493
494/*----------------------------------------------------------------------*/
495
a174a3c5 496void OpenGl_View::TriedronDisplay (const Handle(OpenGl_Context)& theCtx,
497 const Aspect_TypeOfTriedronPosition thePosition,
498 const Quantity_NameOfColor theColor,
499 const Standard_Real theScale,
500 const Standard_Boolean theAsWireframe)
2166f0fa 501{
a174a3c5 502 OpenGl_Element::Destroy (theCtx, myTrihedron);
503 myTrihedron = new OpenGl_Trihedron (thePosition, theColor, theScale, theAsWireframe);
2166f0fa
SK
504}
505
506/*----------------------------------------------------------------------*/
507
a174a3c5 508void OpenGl_View::TriedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 509{
a174a3c5 510 OpenGl_Element::Destroy (theCtx, myTrihedron);
2166f0fa
SK
511}
512
513/*----------------------------------------------------------------------*/
514
a174a3c5 515void OpenGl_View::GraduatedTrihedronDisplay (const Handle(OpenGl_Context)& theCtx,
516 const Graphic3d_CGraduatedTrihedron& theData)
2166f0fa 517{
a174a3c5 518 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
519 myGraduatedTrihedron = new OpenGl_GraduatedTrihedron (theData);
2166f0fa
SK
520}
521
522/*----------------------------------------------------------------------*/
523
a174a3c5 524void OpenGl_View::GraduatedTrihedronErase (const Handle(OpenGl_Context)& theCtx)
2166f0fa 525{
a174a3c5 526 OpenGl_Element::Destroy (theCtx, myGraduatedTrihedron);
2166f0fa
SK
527}
528
529/*----------------------------------------------------------------------*/
530
531//transform_persistence_end
30f0ad28 532void OpenGl_View::EndTransformPersistence(const Handle(OpenGl_Context)& theCtx)
2166f0fa 533{
c34dba32 534 if (myIsTransPers)
2166f0fa 535 {
c34dba32 536 // restore matrix
2166f0fa 537 glMatrixMode (GL_PROJECTION);
c34dba32 538 glPopMatrix();
2166f0fa 539 glMatrixMode (GL_MODELVIEW);
c34dba32 540 glPopMatrix();
2166f0fa 541 myIsTransPers = Standard_False;
30f0ad28 542
543 // Note: the approach of accessing OpenGl matrices is used now since the matrix
544 // manipulation are made with help of OpenGl methods. This might be replaced by
545 // direct computation of matrices by OCC subroutines.
546 Tmatrix3 aResultWorldView;
547 glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
548
549 Tmatrix3 aResultProjection;
550 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
551
552 // Set OCCT state uniform variables
553 theCtx->ShaderManager()->RevertWorldViewStateTo (aResultWorldView);
554 theCtx->ShaderManager()->RevertProjectionStateTo (aResultProjection);
2166f0fa 555 }
bf75be98 556}
2166f0fa
SK
557
558/*----------------------------------------------------------------------*/
559
560//transform_persistence_begin
30f0ad28 561const TEL_TRANSFORM_PERSISTENCE* OpenGl_View::BeginTransformPersistence (const Handle(OpenGl_Context)& theCtx,
562 const TEL_TRANSFORM_PERSISTENCE* theTransPers)
2166f0fa 563{
c34dba32 564 const TEL_TRANSFORM_PERSISTENCE* aTransPersPrev = myTransPers;
565 myTransPers = theTransPers;
566 if (theTransPers->mode == 0)
2166f0fa 567 {
30f0ad28 568 EndTransformPersistence (theCtx);
c34dba32 569 return aTransPersPrev;
2166f0fa
SK
570 }
571
c34dba32 572 GLint aViewport[4];
573 GLdouble aModelMatrix[4][4];
574 GLdouble aProjMatrix[4][4];
575 glGetIntegerv (GL_VIEWPORT, aViewport);
576 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
577 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble *)aProjMatrix);
578 const GLdouble aViewportW = (GLdouble )aViewport[2];
579 const GLdouble aViewportH = (GLdouble )aViewport[3];
2166f0fa 580
c34dba32 581 if (myIsTransPers)
2166f0fa 582 {
c34dba32 583 // pop matrix stack - it will be overridden later
2166f0fa 584 glMatrixMode (GL_PROJECTION);
c34dba32 585 glPopMatrix();
2166f0fa 586 glMatrixMode (GL_MODELVIEW);
c34dba32 587 glPopMatrix();
2166f0fa
SK
588 }
589 else
c34dba32 590 {
2166f0fa 591 myIsTransPers = Standard_True;
c34dba32 592 }
2166f0fa 593
c34dba32 594 // push matrices into stack and reset them
595 glMatrixMode (GL_MODELVIEW);
2166f0fa
SK
596 glPushMatrix();
597 glLoadIdentity();
598
c34dba32 599 glMatrixMode (GL_PROJECTION);
2166f0fa
SK
600 glPushMatrix();
601 glLoadIdentity();
602
c34dba32 603 // get the window's (fixed) coordinates for theTransPers->point before matrixes modifications
604 GLdouble aWinX = 0.0, aWinY = 0.0, aWinZ = 0.0;
605 if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
2166f0fa 606 {
c34dba32 607 gluProject (theTransPers->pointX, theTransPers->pointY, theTransPers->pointZ,
608 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
609 &aWinX, &aWinY, &aWinZ);
2166f0fa
SK
610 }
611
c34dba32 612 // prevent zooming
613 if ((theTransPers->mode & TPF_ZOOM)
614 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 615 {
c34dba32 616 // compute fixed-zoom multiplier
617 // actually function works ugly with TelPerspective!
618 const GLdouble aDet2 = 0.002 / (aViewportW > aViewportH ? aProjMatrix[1][1] : aProjMatrix[0][0]);
619 aProjMatrix[0][0] *= aDet2;
620 aProjMatrix[1][1] *= aDet2;
621 aProjMatrix[2][2] *= aDet2;
2166f0fa
SK
622 }
623
c34dba32 624 // prevent translation - annulate translate matrix
625 if ((theTransPers->mode & TPF_PAN)
626 || (theTransPers->mode == TPF_TRIEDRON))
2166f0fa 627 {
c34dba32 628 aModelMatrix[3][0] = 0.0;
629 aModelMatrix[3][1] = 0.0;
630 aModelMatrix[3][2] = 0.0;
631 aProjMatrix [3][0] = 0.0;
632 aProjMatrix [3][1] = 0.0;
633 aProjMatrix [3][2] = 0.0;
2166f0fa 634 }
2166f0fa 635
c34dba32 636 // prevent scaling-on-axis
637 if (theTransPers->mode & TPF_ZOOM)
638 {
639 const double aScaleX = myExtra.scaleFactors[0];
640 const double aScaleY = myExtra.scaleFactors[1];
641 const double aScaleZ = myExtra.scaleFactors[2];
642 for (int i = 0; i < 3; ++i)
643 {
644 aModelMatrix[0][i] /= aScaleX;
645 aModelMatrix[1][i] /= aScaleY;
646 aModelMatrix[2][i] /= aScaleZ;
647 }
2166f0fa
SK
648 }
649
c34dba32 650 // prevent rotating - annulate rotate matrix
651 if (theTransPers->mode & TPF_ROTATE)
2166f0fa 652 {
c34dba32 653 aModelMatrix[0][0] = 1.0;
654 aModelMatrix[1][1] = 1.0;
655 aModelMatrix[2][2] = 1.0;
656
657 aModelMatrix[1][0] = 0.0;
658 aModelMatrix[2][0] = 0.0;
659 aModelMatrix[0][1] = 0.0;
660 aModelMatrix[2][1] = 0.0;
661 aModelMatrix[0][2] = 0.0;
662 aModelMatrix[1][2] = 0.0;
2166f0fa
SK
663 }
664
c34dba32 665 // load computed matrices
2166f0fa 666 glMatrixMode (GL_MODELVIEW);
c34dba32 667 glMultMatrixd ((GLdouble* )aModelMatrix);
2166f0fa
SK
668
669 glMatrixMode (GL_PROJECTION);
c34dba32 670 glMultMatrixd ((GLdouble* )aProjMatrix);
2166f0fa 671
c34dba32 672 if (theTransPers->mode == TPF_TRIEDRON)
2166f0fa 673 {
c34dba32 674 // move to the window corner
675 if (theTransPers->pointX != 0.0
676 && theTransPers->pointY != 0.0)
2166f0fa 677 {
c34dba32 678 GLdouble aW1, aH1, aW2, aH2, aDummy;
679 glMatrixMode (GL_PROJECTION);
680 gluUnProject ( 0.5 * aViewportW, 0.5 * aViewportH, 0.0,
681 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
682 &aW1, &aH1, &aDummy);
683 gluUnProject (-0.5 * aViewportW, -0.5 * aViewportH, 0.0,
684 (GLdouble* )THE_IDENTITY_MATRIX, (GLdouble* )aProjMatrix, aViewport,
685 &aW2, &aH2, &aDummy);
686 GLdouble aMoveX = 0.5 * (aW1 - aW2 - theTransPers->pointZ);
687 GLdouble aMoveY = 0.5 * (aH1 - aH2 - theTransPers->pointZ);
688 aMoveX = (theTransPers->pointX > 0.0) ? aMoveX : -aMoveX;
689 aMoveY = (theTransPers->pointY > 0.0) ? aMoveY : -aMoveY;
690 glTranslated (aMoveX, aMoveY, 0.0);
2166f0fa
SK
691 }
692 }
c34dba32 693 else if ((theTransPers->mode & TPF_PAN) != TPF_PAN)
694 {
695 // move to thePoint using saved win-coordinates ('marker-behaviour')
696 GLdouble aMoveX, aMoveY, aMoveZ;
697 glGetDoublev (GL_MODELVIEW_MATRIX, (GLdouble* )aModelMatrix);
698 glGetDoublev (GL_PROJECTION_MATRIX, (GLdouble* )aProjMatrix);
699 gluUnProject (aWinX, aWinY, aWinZ,
700 (GLdouble* )aModelMatrix, (GLdouble* )aProjMatrix, aViewport,
701 &aMoveX, &aMoveY, &aMoveZ);
2166f0fa 702
c34dba32 703 glMatrixMode (GL_MODELVIEW);
704 glTranslated (aMoveX, aMoveY, aMoveZ);
705 }
2166f0fa 706
30f0ad28 707 // Note: the approach of accessing OpenGl matrices is used now since the matrix
708 // manipulation are made with help of OpenGl methods. This might be replaced by
709 // direct computation of matrices by OCC subroutines.
710 Tmatrix3 aResultWorldView;
711 glGetFloatv (GL_MODELVIEW_MATRIX, *aResultWorldView);
712
713 Tmatrix3 aResultProjection;
714 glGetFloatv (GL_PROJECTION_MATRIX, *aResultProjection);
715
716 // Set OCCT state uniform variables
717 theCtx->ShaderManager()->UpdateWorldViewStateTo (aResultWorldView);
718 theCtx->ShaderManager()->UpdateProjectionStateTo (aResultProjection);
719
c34dba32 720 return aTransPersPrev;
721}