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