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