0023006: Improvement to debug memory leaks and insufficient memory growths.
[occt.git] / src / OpenGl / OpenGl_Workspace_3.cxx
CommitLineData
2166f0fa
SK
1// File: OpenGl_Workspace_3.cxx
2// Created: 20 September 2011
3// Author: Sergey ZERCHANINOV
4// Copyright: OPEN CASCADE 2011
5
6#define BUC60863 /*GG_100401 After any view update, made identical
7// the front and back buffer to avoid ghost drawing.
8// Minimize flicking.
9*/
10
11#define IMP150501 /*GG_150501 CADPAK_V2 Enable/Disable Zbuffer
12NOTE that the previous and unused "double-buffer"
13arg is changed to "zbuffer" and enable/disable
14to use the OpenGl zbuffer capabilities during immediat
15drawing
16*/
17
18#define IMP260601 /*GG Enable correct backing store between 2 different views.
19*/
20
21/*----------------------------------------------------------------------*/
22
23#define RIC120302 /* GG Enable to use the application display
24// callback at end of traversal
25*/
26
27/*
28* Includes
29*/
30#include <math.h>
31#include <stdio.h>
32
33#ifdef HAVE_GL2PS
34 #include <gl2ps.h>
35#endif
36
37#include <OpenGl_Context.hxx>
38#include <OpenGl_telem_util.hxx>
39#include <OpenGl_AspectLine.hxx>
40#include <OpenGl_Structure.hxx>
41
42/*----------------------------------------------------------------------*/
43/*
44* Prototypes Private functions
45*/
46
47static void call_util_transform_pt (float *x, float *y, float *z);
48static void call_util_transpose_mat (float tmat[16], float mat[4][4]);
49
50/*----------------------------------------------------------------------*/
51/*
52* Variables statiques
53*/
54
55static int openglNumberOfPoints = 0;
56
57static int myImmediateMatIsIdentity = 1;
58
59static int partial = -1; /* -1 init, 0 complete, 1 partielle */
60
61static float xm, ym, zm, XM, YM, ZM;
62
63static float myImmediateMat[4][4] = {
64 {1., 0., 0., 0.},
65 {0., 1., 0., 0.},
66 {0., 0., 1., 0.},
67 {0., 0., 0., 1.},
68};
69
70/*----------------------------------------------------------------------*/
71/* Mode Ajout */
72/*----------------------------------------------------------------------*/
73
74//call_togl_begin_ajout_mode
75Standard_Boolean OpenGl_Workspace::BeginAddMode ()
76{
77 if (!Activate())
78 return Standard_False;
79
80 NamedStatus |= OPENGL_NS_ADD;
81
82 MakeFrontAndBackBufCurrent();
83
84 //TsmPushAttri();
85
86 return Standard_True;
87}
88
89/*----------------------------------------------------------------------*/
90
91//call_togl_end_ajout_mode
92void OpenGl_Workspace::EndAddMode ()
93{
94 if (NamedStatus & OPENGL_NS_ADD)
95 {
96 OpenGl_Workspace::MakeBackBufCurrent();
97
98 // Clear add mode flag
99 NamedStatus &= ~OPENGL_NS_ADD;
100 }
101
102 myImmediateMatIsIdentity = 1;
103
104 /* FMN necessaire pour l'affichage sur WNT */
105 glFlush();
106
107 //TsmPopAttri();
108}
109
110/*----------------------------------------------------------------------*/
111/* Mode Transient */
112/*----------------------------------------------------------------------*/
113
114//call_togl_clear_immediat_mode
115void OpenGl_Workspace::ClearImmediatMode (const Graphic3d_CView& ACView, const Standard_Boolean AFlush)
116{
117 if ( myIsTransientOpen )
118 EndImmediatMode();
119
120 if (!Activate()) return;
121
122 if ( !myBackBufferRestored )
123 {
124 EraseAnimation();
125
126 Redraw1(ACView,*((CALL_DEF_LAYER *)ACView.ptrUnderLayer),*((CALL_DEF_LAYER *)ACView.ptrOverLayer),AFlush);
127
128 // After a redraw,
129 // Made the back identical to the front buffer.
130 // Always perform full copy (partial update optimization is useless on mordern hardware)!
131 if (myRetainMode)
132 CopyBuffers (ACView.ViewId, 1 /* GL_FRONT -> GL_BACK */, xm, ym, zm, XM, YM, ZM, 0);
133
134 myBackBufferRestored = Standard_True;
135 }
136 else if ( partial >= 0 )
137 {
138 // Restore pixels from the back buffer.
139 // Always perform full copy (partial update optimization is useless on mordern hardware)!
140 CopyBuffers (ACView.ViewId, 0 /* GL_BACK -> GL_FRONT */, xm, ym, zm, XM, YM, ZM, 0);
141 }
142
143 if (myTransientList)
144 {
145 /* Clear current list contents */
146 glNewList( (GLuint) myTransientList, GL_COMPILE_AND_EXECUTE);
147 glEndList();
148 }
149 partial = -1;
150 XM = YM = ZM = (float ) shortrealfirst ();
151 xm = ym = zm = (float ) shortreallast ();
152}
153
154/*----------------------------------------------------------------------*/
155
156//call_togl_redraw_immediat_mode
157void OpenGl_Workspace::RedrawImmediatMode ()
158{
159 if (myRetainMode)
160 {
161 if (myTransientList)
162 {
163 MakeFrontBufCurrent();
164 glDisable(GL_LIGHTING);
165 glCallList((GLuint) myTransientList);
166 /* FMN necessaire pour l'affichage sur WNT */
167 glFlush();
168 MakeBackBufCurrent();
169 }
170 }
171}
172
173/*----------------------------------------------------------------------*/
174
175//call_togl_begin_immediat_mode
176Standard_Boolean OpenGl_Workspace::BeginImmediatMode (const Graphic3d_CView& ACView, const Standard_Boolean UseDepthTest, const Standard_Boolean RetainMode)
177{
178 if (!Activate())
179 return Standard_False;
180
181 OpenGl_Workspace::ClearImmediatMode(ACView,1);
182
183 NamedStatus |= OPENGL_NS_IMMEDIATE;
184 myRetainMode = RetainMode;
185
186 MakeFrontBufCurrent();
187
188 //TsmPushAttri();
189
190 if ( myRetainMode )
191 {
192 GLuint listid = (GLuint) myTransientList;
193 if (!listid)
194 listid = glGenLists(1);
195 if (!listid) return Standard_False;
196
197 glNewList(listid, GL_COMPILE_AND_EXECUTE);
198 myTransientList = listid;
199 myIsTransientOpen = Standard_True;
200 }
201
202 if ( UseDepthTest )
203 glEnable(GL_DEPTH_TEST);
204 else
205 glDisable(GL_DEPTH_TEST);
206
207 return Standard_True;
208}
209
210/*----------------------------------------------------------------------*/
211
212//call_togl_end_immediat_mode
213void OpenGl_Workspace::EndImmediatMode ()
214{
215 if (NamedStatus & OPENGL_NS_IMMEDIATE)
216 {
217 if (myIsTransientOpen)
218 {
219 glEndList();
220 myIsTransientOpen = Standard_False;
221 }
222 MakeBackBufCurrent();
223
224 // Clear immediate mode flag
225 NamedStatus &= ~OPENGL_NS_IMMEDIATE;
226 }
227
228 // Ajout CAL : pour voir quelque chose avant le prochain begin_immediat_mode
229 glFinish ();
230
231 myImmediateMatIsIdentity = 1;
232
233 //TsmPopAttri();
234}
235
236/*----------------------------------------------------------------------*/
237
238//call_togl_transform
239void OpenGl_Workspace::Transform (const TColStd_Array2OfReal& AMatrix, const Graphic3d_TypeOfComposition AType)
240{
241 //call_togl_transform in OpenGl_togl_begin_immediat_mode.cxx
242 const Standard_Integer lr = AMatrix.LowerRow ();
243 const Standard_Integer lc = AMatrix.LowerCol ();
244
245 Standard_Integer i, j;
246 if ((AType == Graphic3d_TOC_REPLACE) || myImmediateMatIsIdentity)
247 {
248 for (i=0; i<4; i++)
249 for (j=0; j<4; j++)
250 myImmediateMat[i][j] = float (AMatrix (i+lr, j+lc));
251 }
252 else
253 {
254 float theMatrix[4][4];
255 for (i=0; i<4; i++)
256 for (j=0; j<4; j++)
257 theMatrix[i][j] = float (AMatrix (i+lr, j+lc));
258
259 TelMultiplymat3 (myImmediateMat, myImmediateMat, theMatrix);
260 }
261
262 myImmediateMatIsIdentity = 1;
263 for (i = 0; i < 4; i++)
264 for (j = 0; j < 4; j++)
265 if (myImmediateMat[i][j] != (i == j? 1. : 0.))
266 {
267 myImmediateMatIsIdentity = 0;
268 return;
269 }
270}
271
272/*----------------------------------------------------------------------*/
273
274//call_togl_begin_polyline
275void OpenGl_Workspace::BeginPolyline ()
276{
277 if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
278 {
279 openglNumberOfPoints = 0;
280 glDisable(GL_LIGHTING);
281 glBegin(GL_LINE_STRIP);
282 }
283}
284
285/*----------------------------------------------------------------------*/
286
287//call_togl_end_polyline
288void OpenGl_Workspace::EndPolyline ()
289{
290 if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
291 glEnd();
292}
293
294/*----------------------------------------------------------------------*/
295
296//call_togl_draw
297void OpenGl_Workspace::Draw (const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z)
298{
299 if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
300 {
301 openglNumberOfPoints++;
302 float x = X, y = Y, z = Z;
303 if (!myImmediateMatIsIdentity)
304 call_util_transform_pt (&x, &y, &z);
305 if (x > XM) XM = x;
306 if (y > YM) YM = y;
307 if (z > ZM) ZM = z;
308 if (x < xm) xm = x;
309 if (y < ym) ym = y;
310 if (z < zm) zm = z;
311 glVertex3f (x, y, z);
312 partial = 1;
313 }
314}
315
316/*----------------------------------------------------------------------*/
317
318//call_togl_move
319void OpenGl_Workspace::Move (const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Z)
320{
321 if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
322 {
323 if (openglNumberOfPoints != 0)
324 {
325 OpenGl_Workspace::EndPolyline();
326 OpenGl_Workspace::BeginPolyline();
327 }
328 OpenGl_Workspace::Draw(X,Y,Z);
329 }
330}
331
332/*----------------------------------------------------------------------*/
333
334//call_togl_set_linecolor
335void OpenGl_Workspace::SetLineColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
336{
337 if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
338 {
339 GLfloat color[3];
340 color[0] = R;
341 color[1] = G;
342 color[2] = B;
343 glColor3fv(color);
344 }
345}
346
347/*----------------------------------------------------------------------*/
348
349//call_togl_set_linetype
350void OpenGl_Workspace::SetLineType (const Standard_Integer Type)
351{
352 if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
353 {
354 myDisplay->SetTypeOfLine((Aspect_TypeOfLine)Type);
355 }
356}
357
358/*----------------------------------------------------------------------*/
359
360//call_togl_set_linewidth
361void OpenGl_Workspace::SetLineWidth (const Standard_ShortReal Width)
362{
363 if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
364 {
365 glLineWidth( (GLfloat)Width );
366#ifdef HAVE_GL2PS
367 gl2psLineWidth( (GLfloat)Width );
368#endif
369 }
370}
371
372/*----------------------------------------------------------------------*/
373
374//call_togl_draw_structure
375void OpenGl_Workspace::DrawStructure (const OpenGl_Structure *AStructure)
376{
377 if (NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE))
378 {
379 float mat16[16];
380 GLint mode1;
381
382 //TsmPushAttri();
383
384 /* mise en place de la matrice de transformation du trace transient */
385 if (!myImmediateMatIsIdentity)
386 {
387 call_util_transpose_mat (mat16, myImmediateMat);
388 glGetIntegerv (GL_MATRIX_MODE, &mode1);
389 glMatrixMode (GL_MODELVIEW);
390 glPushMatrix ();
391 glScalef (1.F, 1.F, 1.F);
392 glMultMatrixf (mat16);
393 }
394
395 // Render structure
396 Handle(OpenGl_Workspace) aWS(this);
397 AStructure->Render(aWS);
398
399 //TsmPopAttri();
400
401 if (!myImmediateMatIsIdentity)
402 {
403 glPopMatrix ();
404 glMatrixMode (mode1);
405 }
406 }
407}
408
409/*----------------------------------------------------------------------*/
410
411//call_togl_set_minmax
412void OpenGl_Workspace::SetMinMax (const Standard_ShortReal X1, const Standard_ShortReal Y1, const Standard_ShortReal Z1, const Standard_ShortReal X2, const Standard_ShortReal Y2, const Standard_ShortReal Z2)
413{
414 if ((X1 > shortreallast ()) || (Y1 > shortreallast ()) || (Z1 > shortreallast ()) ||
415 (X2 > shortreallast ()) || (Y2 > shortreallast ()) || (Z2 > shortreallast ()) ||
416 (X1 < shortrealfirst ()) || (Y1 < shortrealfirst ()) || (Z1 < shortrealfirst ()) ||
417 (X2 < shortrealfirst ()) || (Y2 < shortrealfirst ()) || (Z2 < shortrealfirst ()))
418 {
419 XM = YM = ZM = (float ) shortreallast ();
420 xm = ym = zm = (float ) shortrealfirst ();
421 partial = 0;
422 }
423 else
424 {
425 float x1=X1,y1=Y1,z1=Z1,x2=X2,y2=Y2,z2=Z2;
426 if (!myImmediateMatIsIdentity)
427 {
428 call_util_transform_pt (&x1, &y1, &z1);
429 call_util_transform_pt (&x2, &y2, &z2);
430 }
431 if (x1 > XM) XM = x1;
432 if (x1 < xm) xm = x1;
433 if (y1 > YM) YM = y1;
434 if (y1 < ym) ym = y1;
435 if (z1 > ZM) ZM = z1;
436 if (z1 < zm) zm = z1;
437
438 if (x2 > XM) XM = x2;
439 if (x2 < xm) xm = x2;
440 if (y2 > YM) YM = y2;
441 if (y2 < ym) ym = y2;
442 if (z2 > ZM) ZM = z2;
443 if (z2 < zm) zm = z2;
444 if (partial != 0) partial = 1;
445 }
446}
447
448/*----------------------------------------------------------------------*/
449/*
450* Private functions
451*/
452
453/*----------------------------------------------------------------------*/
454/*
455Transform the point pt
456*/
457static void call_util_transform_pt ( float *x, float *y, float *z )
458{
459 float tpt[4], pt[4];
460 pt[0] = *x, pt[1] = *y, pt[2] = *z, pt[3] = 1.0;
461
462 int i, j;
463 for (i = 0; i < 4; i++)
464 {
465 float sum = 0.;
466 for (j = 0; j < 4; j++)
467 sum += myImmediateMat[i][j] * pt[j];
468 tpt[i] = sum;
469 }
470
471 *x = tpt[0], *y = tpt[1], *z = tpt[2];
472}
473
474/*----------------------------------------------------------------------*/
475/*
476void call_util_transpose_mat (tmat, mat)
477float tmat[16];
478float mat[4][4];
479
480Transpose mat and returns tmat.
481*/
482
483static void call_util_transpose_mat (float tmat[16], float mat[4][4])
484{
485 int i, j;
486
487 for (i=0; i<4; i++)
488 for (j=0; j<4; j++)
489 tmat[j*4+i] = mat[i][j];
490}