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 | |
e276548b | 16 | #ifdef HAVE_CONFIG_H |
17 | #include <config.h> | |
18 | #endif | |
19 | ||
a577aaab | 20 | #include <OpenGl_GlCore15.hxx> |
5f8b738e | 21 | |
2166f0fa SK |
22 | #include <InterfaceGraphic.hxx> |
23 | ||
2166f0fa SK |
24 | #include <OpenGl_AspectLine.hxx> |
25 | #include <OpenGl_AspectFace.hxx> | |
26 | #include <OpenGl_AspectMarker.hxx> | |
27 | #include <OpenGl_AspectText.hxx> | |
bf75be98 | 28 | #include <OpenGl_Context.hxx> |
679ecdee | 29 | #include <OpenGl_Element.hxx> |
a174a3c5 | 30 | #include <OpenGl_FrameBuffer.hxx> |
679ecdee | 31 | #include <OpenGl_Structure.hxx> |
bf75be98 | 32 | #include <OpenGl_Texture.hxx> |
e276548b | 33 | #include <OpenGl_View.hxx> |
a174a3c5 | 34 | #include <OpenGl_Workspace.hxx> |
2166f0fa | 35 | |
bf75be98 | 36 | #include <Graphic3d_TextureParams.hxx> |
2166f0fa | 37 | |
58655684 | 38 | #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) |
a174a3c5 | 39 | #include <OpenGl_AVIWriter.hxx> |
40 | #endif | |
41 | ||
2166f0fa SK |
42 | IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window) |
43 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window) | |
44 | ||
45 | namespace | |
46 | { | |
0adbd30f | 47 | static const TEL_COLOUR THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } }; |
48 | static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f); | |
2166f0fa SK |
49 | |
50 | static const OpenGl_AspectLine myDefaultAspectLine; | |
51 | static const OpenGl_AspectFace myDefaultAspectFace; | |
52 | static const OpenGl_AspectMarker myDefaultAspectMarker; | |
53 | static const OpenGl_AspectText myDefaultAspectText; | |
54 | ||
55 | static const OpenGl_TextParam myDefaultTextParam = | |
56 | { | |
57 | 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM | |
58 | }; | |
59 | ||
60 | static const OpenGl_Matrix myDefaultMatrix = | |
61 | { | |
62 | {{ 1.0F, 0.0F, 0.0F, 0.0F }, | |
63 | { 0.0F, 1.0F, 0.0F, 0.0F }, | |
64 | { 0.0F, 0.0F, 1.0F, 0.0F }, | |
65 | { 0.0F, 0.0F, 0.0F, 1.0F }} | |
66 | }; | |
bf75be98 | 67 | |
2166f0fa SK |
68 | }; |
69 | ||
0adbd30f | 70 | // ======================================================================= |
71 | // function : Init | |
72 | // purpose : | |
73 | // ======================================================================= | |
74 | void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp) | |
75 | { | |
76 | // ambient component | |
77 | if (theProp.color_mask & OPENGL_AMBIENT_MASK) | |
78 | { | |
79 | const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb; | |
80 | Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb, | |
81 | aSrcAmb[1] * theProp.amb, | |
82 | aSrcAmb[2] * theProp.amb, | |
83 | 1.0f); | |
84 | } | |
85 | else | |
86 | { | |
87 | Ambient = THE_BLACK_COLOR; | |
88 | } | |
89 | ||
90 | // diffusion component | |
91 | if (theProp.color_mask & OPENGL_DIFFUSE_MASK) | |
92 | { | |
93 | const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb; | |
94 | Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff, | |
95 | aSrcDif[1] * theProp.diff, | |
96 | aSrcDif[2] * theProp.diff, | |
97 | 1.0f); | |
98 | } | |
99 | else | |
100 | { | |
101 | Diffuse = THE_BLACK_COLOR; | |
102 | } | |
103 | ||
104 | // specular component | |
105 | if (theProp.color_mask & OPENGL_SPECULAR_MASK) | |
106 | { | |
107 | const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb; | |
108 | Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec, | |
109 | aSrcSpe[1] * theProp.spec, | |
110 | aSrcSpe[2] * theProp.spec, | |
111 | 1.0f); | |
112 | } | |
113 | else | |
114 | { | |
115 | Specular = THE_BLACK_COLOR; | |
116 | } | |
117 | ||
118 | // emission component | |
119 | if (theProp.color_mask & OPENGL_EMISSIVE_MASK) | |
120 | { | |
121 | const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb; | |
122 | Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv, | |
123 | aSrcEms[1] * theProp.emsv, | |
124 | aSrcEms[2] * theProp.emsv, | |
125 | 1.0f); | |
126 | } | |
127 | else | |
128 | { | |
129 | Emission = THE_BLACK_COLOR; | |
130 | } | |
131 | ||
132 | ChangeShine() = theProp.shine; | |
133 | ChangeTransparency() = theProp.trans; | |
134 | } | |
135 | ||
2166f0fa SK |
136 | // ======================================================================= |
137 | // function : OpenGl_Workspace | |
138 | // purpose : | |
139 | // ======================================================================= | |
73192b37 | 140 | OpenGl_Workspace::OpenGl_Workspace (const Handle(Aspect_DisplayConnection)& theDisplayConnection, |
2166f0fa | 141 | const CALL_DEF_WINDOW& theCWindow, |
5e27df78 | 142 | Aspect_RenderingContext theGContext, |
58655684 | 143 | const Handle(OpenGl_Caps)& theCaps, |
5e27df78 | 144 | const Handle(OpenGl_Context)& theShareCtx) |
73192b37 | 145 | : OpenGl_Window (theDisplayConnection, theCWindow, theGContext, theCaps, theShareCtx), |
a174a3c5 | 146 | NamedStatus (0), |
0adbd30f | 147 | HighlightColor (&THE_WHITE_COLOR), |
a174a3c5 | 148 | // |
fc73a202 | 149 | myComputeInitStatus (OpenGl_RT_NONE), |
150 | myIsRaytraceDataValid (Standard_False), | |
151 | myTraversalStackSize (THE_DEFAULT_STACK_SIZE), | |
152 | myViewModificationStatus (0), | |
153 | myLayersModificationStatus (0), | |
154 | // | |
73192b37 | 155 | myAntiAliasingMode (3), |
a174a3c5 | 156 | myTransientDrawToFront (Standard_True), |
679ecdee | 157 | myBackBufferRestored (Standard_False), |
158 | myIsImmediateDrawn (Standard_False), | |
2166f0fa SK |
159 | myUseTransparency (Standard_False), |
160 | myUseZBuffer (Standard_False), | |
161 | myUseDepthTest (Standard_True), | |
162 | myUseGLLight (Standard_True), | |
2166f0fa | 163 | // |
2166f0fa SK |
164 | AspectLine_set (&myDefaultAspectLine), |
165 | AspectLine_applied (NULL), | |
166 | AspectFace_set (&myDefaultAspectFace), | |
167 | AspectFace_applied (NULL), | |
168 | AspectMarker_set (&myDefaultAspectMarker), | |
169 | AspectMarker_applied (NULL), | |
170 | AspectText_set (&myDefaultAspectText), | |
171 | AspectText_applied (NULL), | |
172 | TextParam_set (&myDefaultTextParam), | |
173 | TextParam_applied (NULL), | |
174 | ViewMatrix_applied (&myDefaultMatrix), | |
175 | StructureMatrix_applied (&myDefaultMatrix), | |
3b1817a9 | 176 | myCullingMode (TelCullUndefined), |
0f8c0fb8 | 177 | myModelViewMatrix (myDefaultMatrix), |
550f3b8b | 178 | PolygonOffset_applied (THE_DEFAULT_POFFSET) |
2166f0fa | 179 | { |
73192b37 | 180 | myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1); |
181 | ||
182 | if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs)) | |
183 | { | |
184 | // share and register for release once the resource is no longer used | |
185 | myLineAttribs = new OpenGl_LineAttributes(); | |
186 | myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs); | |
187 | myLineAttribs->Init (myGlContext); | |
188 | } | |
2166f0fa SK |
189 | |
190 | // General initialization of the context | |
191 | ||
192 | // Eviter d'avoir les faces mal orientees en noir. | |
193 | // Pourrait etre utiliser pour detecter les problemes d'orientation | |
bf75be98 | 194 | glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); |
2166f0fa SK |
195 | |
196 | // Optimisation pour le Fog et l'antialiasing | |
197 | glHint (GL_FOG_HINT, GL_FASTEST); | |
198 | glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST); | |
199 | glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST); | |
200 | glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST); | |
201 | ||
73192b37 | 202 | // AA mode |
203 | const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE"); | |
204 | if (anAaEnv != NULL) | |
205 | { | |
206 | int v; | |
207 | if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasingMode = v; | |
208 | } | |
2166f0fa SK |
209 | } |
210 | ||
1981cb22 | 211 | // ======================================================================= |
212 | // function : SetImmediateModeDrawToFront | |
213 | // purpose : | |
214 | // ======================================================================= | |
215 | Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) | |
216 | { | |
217 | const Standard_Boolean aPrevMode = myTransientDrawToFront; | |
218 | myTransientDrawToFront = theDrawToFrontBuffer; | |
219 | return aPrevMode; | |
220 | } | |
221 | ||
2166f0fa SK |
222 | // ======================================================================= |
223 | // function : ~OpenGl_Workspace | |
224 | // purpose : | |
225 | // ======================================================================= | |
226 | OpenGl_Workspace::~OpenGl_Workspace() | |
227 | { | |
73192b37 | 228 | if (!myLineAttribs.IsNull()) |
229 | { | |
230 | myLineAttribs.Nullify(); | |
231 | myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True); | |
232 | } | |
233 | ||
fc73a202 | 234 | ReleaseRaytraceResources(); |
2166f0fa SK |
235 | } |
236 | ||
237 | // ======================================================================= | |
238 | // function : Activate | |
239 | // purpose : | |
240 | // ======================================================================= | |
241 | Standard_Boolean OpenGl_Workspace::Activate() | |
242 | { | |
243 | if (!OpenGl_Window::Activate()) | |
244 | return Standard_False; | |
245 | ||
2166f0fa SK |
246 | ViewMatrix_applied = &myDefaultMatrix; |
247 | StructureMatrix_applied = &myDefaultMatrix; | |
26395493 | 248 | |
249 | ResetAppliedAspect(); | |
250 | ||
251 | return Standard_True; | |
2166f0fa SK |
252 | } |
253 | ||
254 | // ======================================================================= | |
255 | // function : UseTransparency | |
256 | // purpose : call_togl_transparency | |
257 | // ======================================================================= | |
258 | void OpenGl_Workspace::UseTransparency (const Standard_Boolean theFlag) | |
259 | { | |
de75ed09 | 260 | myUseTransparency = theFlag; |
2166f0fa | 261 | } |
26395493 | 262 | |
263 | //======================================================================= | |
264 | //function : ResetAppliedAspect | |
265 | //purpose : Sets default values of GL parameters in accordance with default aspects | |
266 | //======================================================================= | |
267 | void OpenGl_Workspace::ResetAppliedAspect() | |
268 | { | |
bf75be98 | 269 | NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0; |
0adbd30f | 270 | HighlightColor = &THE_WHITE_COLOR; |
26395493 | 271 | AspectLine_set = &myDefaultAspectLine; |
272 | AspectLine_applied = NULL; | |
273 | AspectFace_set = &myDefaultAspectFace; | |
274 | AspectFace_applied = NULL; | |
275 | AspectMarker_set = &myDefaultAspectMarker; | |
276 | AspectMarker_applied = NULL; | |
277 | AspectText_set = &myDefaultAspectText; | |
278 | AspectText_applied = NULL; | |
279 | TextParam_set = &myDefaultTextParam; | |
280 | TextParam_applied = NULL; | |
550f3b8b | 281 | PolygonOffset_applied = THE_DEFAULT_POFFSET; |
3b1817a9 | 282 | myCullingMode = TelCullUndefined; |
26395493 | 283 | |
284 | AspectLine(Standard_True); | |
285 | AspectFace(Standard_True); | |
286 | AspectMarker(Standard_True); | |
287 | AspectText(Standard_True); | |
288 | } | |
bf75be98 | 289 | |
290 | // ======================================================================= | |
291 | // function : DisableTexture | |
292 | // purpose : | |
293 | // ======================================================================= | |
294 | Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture() | |
295 | { | |
296 | if (myTextureBound.IsNull()) | |
297 | { | |
298 | return myTextureBound; | |
299 | } | |
300 | ||
301 | // reset texture matrix because some code may expect it is identity | |
302 | GLint aMatrixMode = GL_TEXTURE; | |
303 | glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); | |
304 | glMatrixMode (GL_TEXTURE); | |
305 | glLoadIdentity(); | |
306 | glMatrixMode (aMatrixMode); | |
307 | ||
308 | myTextureBound->Unbind (myGlContext); | |
309 | switch (myTextureBound->GetTarget()) | |
310 | { | |
311 | case GL_TEXTURE_1D: | |
312 | { | |
313 | if (myTextureBound->GetParams()->GenMode() != GL_NONE) | |
314 | { | |
315 | glDisable (GL_TEXTURE_GEN_S); | |
316 | } | |
317 | glDisable (GL_TEXTURE_1D); | |
318 | break; | |
319 | } | |
320 | case GL_TEXTURE_2D: | |
321 | { | |
322 | if (myTextureBound->GetParams()->GenMode() != GL_NONE) | |
323 | { | |
324 | glDisable (GL_TEXTURE_GEN_S); | |
325 | glDisable (GL_TEXTURE_GEN_T); | |
a577aaab | 326 | if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE) |
327 | { | |
328 | glDisable (GL_POINT_SPRITE); | |
329 | } | |
bf75be98 | 330 | } |
331 | glDisable (GL_TEXTURE_2D); | |
332 | break; | |
333 | } | |
334 | default: break; | |
335 | } | |
336 | ||
337 | Handle(OpenGl_Texture) aPrevTexture = myTextureBound; | |
338 | myTextureBound.Nullify(); | |
339 | return aPrevTexture; | |
340 | } | |
341 | ||
342 | // ======================================================================= | |
343 | // function : setTextureParams | |
344 | // purpose : | |
345 | // ======================================================================= | |
346 | void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture, | |
347 | const Handle(Graphic3d_TextureParams)& theParams) | |
348 | { | |
349 | const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams; | |
350 | if (aParams.IsNull()) | |
351 | { | |
352 | return; | |
353 | } | |
354 | ||
355 | GLint aMatrixMode = GL_TEXTURE; | |
356 | glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); | |
357 | ||
358 | // setup texture matrix | |
359 | glMatrixMode (GL_TEXTURE); | |
360 | glLoadIdentity(); | |
361 | const Graphic3d_Vec2& aScale = aParams->Scale(); | |
362 | const Graphic3d_Vec2& aTrans = aParams->Translation(); | |
363 | glScalef ( aScale.x(), aScale.y(), 1.0f); | |
364 | glTranslatef (-aTrans.x(), -aTrans.y(), 0.0f); | |
365 | glRotatef (-aParams->Rotation(), 0.0f, 0.0f, 1.0f); | |
366 | ||
367 | // setup generation of texture coordinates | |
368 | switch (aParams->GenMode()) | |
369 | { | |
370 | case Graphic3d_TOTM_OBJECT: | |
371 | { | |
372 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
373 | glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData()); | |
374 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
375 | { | |
376 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
377 | glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData()); | |
378 | } | |
379 | break; | |
380 | } | |
381 | case Graphic3d_TOTM_SPHERE: | |
382 | { | |
383 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); | |
384 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
385 | { | |
386 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); | |
387 | } | |
388 | break; | |
389 | } | |
390 | case Graphic3d_TOTM_EYE: | |
391 | { | |
392 | glMatrixMode (GL_MODELVIEW); | |
393 | glPushMatrix(); | |
394 | glLoadIdentity(); | |
395 | ||
396 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); | |
397 | glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData()); | |
398 | ||
399 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
400 | { | |
401 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); | |
402 | glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData()); | |
403 | } | |
404 | glPopMatrix(); | |
405 | break; | |
406 | } | |
a577aaab | 407 | case Graphic3d_TOTM_SPRITE: |
408 | { | |
409 | if (GetGlContext()->core20 != NULL) | |
410 | { | |
411 | glEnable (GL_POINT_SPRITE); | |
412 | glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); | |
413 | glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | |
414 | GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); | |
415 | } | |
416 | break; | |
417 | } | |
bf75be98 | 418 | case Graphic3d_TOTM_MANUAL: |
419 | default: break; | |
420 | } | |
421 | ||
422 | // setup lighting | |
a577aaab | 423 | if (aParams->GenMode() != Graphic3d_TOTM_SPRITE) |
424 | { | |
425 | glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aParams->IsModulate() ? GL_MODULATE : GL_DECAL); | |
426 | } | |
bf75be98 | 427 | |
428 | // setup texture filtering and wrapping | |
429 | //if (theTexture->GetParams() != theParams) | |
430 | const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR; | |
431 | const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : GL_CLAMP; | |
432 | switch (theTexture->GetTarget()) | |
433 | { | |
434 | case GL_TEXTURE_1D: | |
435 | { | |
436 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter); | |
437 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter); | |
438 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode); | |
439 | break; | |
440 | } | |
441 | case GL_TEXTURE_2D: | |
442 | { | |
443 | GLenum aFilterMin = aFilter; | |
444 | if (theTexture->HasMipmaps()) | |
445 | { | |
446 | aFilterMin = GL_NEAREST_MIPMAP_NEAREST; | |
447 | if (aParams->Filter() == Graphic3d_TOTF_BILINEAR) | |
448 | { | |
449 | aFilterMin = GL_LINEAR_MIPMAP_NEAREST; | |
450 | } | |
451 | else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR) | |
452 | { | |
453 | aFilterMin = GL_LINEAR_MIPMAP_LINEAR; | |
454 | } | |
455 | ||
456 | if (myGlContext->extAnis) | |
457 | { | |
458 | // setup degree of anisotropy filter | |
459 | const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy(); | |
460 | switch (aParams->AnisoFilter()) | |
461 | { | |
462 | case Graphic3d_LOTA_QUALITY: | |
463 | { | |
464 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aMaxDegree); | |
465 | break; | |
466 | } | |
467 | case Graphic3d_LOTA_MIDDLE: | |
468 | { | |
469 | ||
470 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2)); | |
471 | break; | |
472 | } | |
473 | case Graphic3d_LOTA_FAST: | |
474 | { | |
475 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2); | |
476 | break; | |
477 | } | |
478 | case Graphic3d_LOTA_OFF: | |
479 | default: | |
480 | { | |
481 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); | |
482 | break; | |
483 | } | |
484 | } | |
485 | } | |
486 | } | |
487 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin); | |
488 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter); | |
489 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode); | |
490 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode); | |
491 | break; | |
492 | } | |
493 | default: break; | |
494 | } | |
495 | ||
496 | switch (theTexture->GetTarget()) | |
497 | { | |
498 | case GL_TEXTURE_1D: | |
499 | { | |
500 | if (aParams->GenMode() != Graphic3d_TOTM_MANUAL) | |
501 | { | |
502 | glEnable (GL_TEXTURE_GEN_S); | |
503 | } | |
504 | glEnable (GL_TEXTURE_1D); | |
505 | break; | |
506 | } | |
507 | case GL_TEXTURE_2D: | |
508 | { | |
509 | if (aParams->GenMode() != Graphic3d_TOTM_MANUAL) | |
510 | { | |
511 | glEnable (GL_TEXTURE_GEN_S); | |
512 | glEnable (GL_TEXTURE_GEN_T); | |
513 | } | |
514 | glEnable (GL_TEXTURE_2D); | |
515 | break; | |
516 | } | |
517 | default: break; | |
518 | } | |
519 | ||
520 | glMatrixMode (aMatrixMode); // turn back active matrix | |
521 | theTexture->SetParams (aParams); | |
522 | } | |
523 | ||
524 | // ======================================================================= | |
525 | // function : EnableTexture | |
526 | // purpose : | |
527 | // ======================================================================= | |
528 | Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture, | |
529 | const Handle(Graphic3d_TextureParams)& theParams) | |
530 | { | |
531 | if (theTexture.IsNull() || !theTexture->IsValid()) | |
532 | { | |
533 | return DisableTexture(); | |
534 | } | |
535 | ||
bca1d6e2 | 536 | if (myTextureBound == theTexture |
537 | && (theParams.IsNull() || theParams == theTexture->GetParams())) | |
bf75be98 | 538 | { |
bca1d6e2 | 539 | // already bound |
540 | return myTextureBound; | |
bf75be98 | 541 | } |
542 | ||
543 | Handle(OpenGl_Texture) aPrevTexture = DisableTexture(); | |
544 | myTextureBound = theTexture; | |
545 | myTextureBound->Bind (myGlContext); | |
546 | setTextureParams (myTextureBound, theParams); | |
547 | ||
548 | return aPrevTexture; | |
549 | } | |
a174a3c5 | 550 | |
551 | // ======================================================================= | |
552 | // function : Redraw | |
553 | // purpose : | |
554 | // ======================================================================= | |
555 | void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView, | |
556 | const Aspect_CLayer2d& theCUnderLayer, | |
557 | const Aspect_CLayer2d& theCOverLayer) | |
558 | { | |
559 | if (!Activate()) | |
560 | { | |
561 | return; | |
562 | } | |
563 | ||
564 | // release pending GL resources | |
565 | Handle(OpenGl_Context) aGlCtx = GetGlContext(); | |
566 | aGlCtx->ReleaseDelayed(); | |
567 | ||
b5ac8292 | 568 | // fetch OpenGl context state |
569 | aGlCtx->FetchState(); | |
a174a3c5 | 570 | |
b5ac8292 | 571 | Tint toSwap = (aGlCtx->IsRender()); // swap buffers |
a174a3c5 | 572 | GLint aViewPortBack[4]; |
573 | OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO; | |
574 | if (aFrameBuffer != NULL) | |
575 | { | |
576 | glGetIntegerv (GL_VIEWPORT, aViewPortBack); | |
fd4a6963 | 577 | aFrameBuffer->SetupViewport (aGlCtx); |
578 | aFrameBuffer->BindBuffer (aGlCtx); | |
a174a3c5 | 579 | toSwap = 0; // no need to swap buffers |
580 | } | |
581 | ||
fc73a202 | 582 | if (!theCView.IsRaytracing || myComputeInitStatus == OpenGl_RT_FAIL) |
e276548b | 583 | { |
679ecdee | 584 | const Standard_Boolean isImmediate = !myView->ImmediateStructures().IsEmpty(); |
585 | redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap); | |
586 | if (isImmediate) | |
e276548b | 587 | { |
679ecdee | 588 | RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True); |
e276548b | 589 | } |
590 | ||
591 | theCView.WasRedrawnGL = Standard_True; | |
e276548b | 592 | } |
593 | else | |
a174a3c5 | 594 | { |
e276548b | 595 | int aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth; |
596 | int aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight; | |
597 | ||
fc73a202 | 598 | Raytrace (theCView, aSizeX, aSizeY, toSwap, aFrameBuffer); |
e276548b | 599 | |
600 | theCView.WasRedrawnGL = Standard_False; | |
a174a3c5 | 601 | } |
602 | ||
603 | if (aFrameBuffer != NULL) | |
604 | { | |
605 | aFrameBuffer->UnbindBuffer (aGlCtx); | |
606 | // move back original viewport | |
607 | glViewport (aViewPortBack[0], aViewPortBack[1], aViewPortBack[2], aViewPortBack[3]); | |
608 | } | |
609 | ||
679ecdee | 610 | #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) |
a174a3c5 | 611 | if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow)) |
612 | { | |
613 | GLint params[4]; | |
614 | glGetIntegerv (GL_VIEWPORT, params); | |
615 | int nWidth = params[2] & ~0x7; | |
616 | int nHeight = params[3] & ~0x7; | |
617 | ||
618 | const int nBitsPerPixel = 24; | |
619 | GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8]; | |
620 | ||
621 | glPixelStorei (GL_PACK_ALIGNMENT, 1); | |
622 | glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData); | |
623 | OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel); | |
624 | delete[] aDumpData; | |
625 | } | |
626 | #endif | |
627 | ||
628 | // reset render mode state | |
b5ac8292 | 629 | aGlCtx->FetchState(); |
a174a3c5 | 630 | } |
679ecdee | 631 | |
632 | // ======================================================================= | |
633 | // function : redraw1 | |
634 | // purpose : | |
635 | // ======================================================================= | |
636 | void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView, | |
637 | const Aspect_CLayer2d& theCUnderLayer, | |
638 | const Aspect_CLayer2d& theCOverLayer, | |
639 | const int theToSwap) | |
640 | { | |
73192b37 | 641 | if (myView.IsNull()) |
679ecdee | 642 | { |
643 | return; | |
644 | } | |
645 | ||
646 | // request reset of material | |
647 | NamedStatus |= OPENGL_NS_RESMAT; | |
648 | ||
679ecdee | 649 | GLbitfield toClear = GL_COLOR_BUFFER_BIT; |
650 | if (myUseZBuffer) | |
651 | { | |
652 | glDepthFunc (GL_LEQUAL); | |
653 | glDepthMask (GL_TRUE); | |
654 | if (myUseDepthTest) | |
655 | { | |
656 | glEnable (GL_DEPTH_TEST); | |
657 | } | |
658 | else | |
659 | { | |
660 | glDisable (GL_DEPTH_TEST); | |
661 | } | |
662 | ||
663 | glClearDepth (1.0); | |
664 | toClear |= GL_DEPTH_BUFFER_BIT; | |
665 | } | |
666 | else | |
667 | { | |
668 | glDisable (GL_DEPTH_TEST); | |
669 | } | |
670 | ||
671 | if (NamedStatus & OPENGL_NS_WHITEBACK) | |
672 | { | |
673 | // set background to white | |
674 | glClearColor (1.0f, 1.0f, 1.0f, 1.0f); | |
675 | toClear |= GL_DEPTH_BUFFER_BIT; | |
676 | } | |
677 | else | |
678 | { | |
679 | glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f); | |
680 | } | |
681 | glClear (toClear); | |
682 | ||
683 | Handle(OpenGl_Workspace) aWS (this); | |
684 | myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer); | |
685 | ||
686 | // swap the buffers | |
687 | if (theToSwap) | |
688 | { | |
689 | GetGlContext()->SwapBuffers(); | |
690 | myBackBufferRestored = Standard_False; | |
691 | myIsImmediateDrawn = Standard_False; | |
692 | } | |
693 | else | |
694 | { | |
695 | glFlush(); | |
696 | myBackBufferRestored = Standard_True; | |
697 | myIsImmediateDrawn = Standard_False; | |
698 | } | |
699 | } | |
700 | ||
701 | // ======================================================================= | |
702 | // function : copyBackToFront | |
703 | // purpose : | |
704 | // ======================================================================= | |
705 | void OpenGl_Workspace::copyBackToFront() | |
706 | { | |
707 | glMatrixMode (GL_PROJECTION); | |
708 | glPushMatrix(); | |
709 | glLoadIdentity(); | |
710 | gluOrtho2D (0.0, (GLdouble )myWidth, 0.0, (GLdouble )myHeight); | |
711 | glMatrixMode (GL_MODELVIEW); | |
712 | glPushMatrix(); | |
713 | glLoadIdentity(); | |
714 | ||
715 | DisableFeatures(); | |
716 | ||
717 | glDrawBuffer (GL_FRONT); | |
718 | glReadBuffer (GL_BACK); | |
719 | ||
720 | glRasterPos2i (0, 0); | |
721 | glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR); | |
722 | ||
723 | EnableFeatures(); | |
724 | ||
725 | glMatrixMode (GL_PROJECTION); | |
726 | glPopMatrix(); | |
727 | glMatrixMode (GL_MODELVIEW); | |
728 | glPopMatrix(); | |
729 | ||
730 | glDrawBuffer (GL_BACK); | |
731 | ||
732 | myIsImmediateDrawn = Standard_False; | |
733 | } | |
734 | ||
735 | // ======================================================================= | |
736 | // function : DisplayCallback | |
737 | // purpose : | |
738 | // ======================================================================= | |
739 | void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView, | |
740 | Standard_Integer theReason) | |
741 | { | |
742 | if (theCView.GDisplayCB == NULL) | |
743 | { | |
744 | return; | |
745 | } | |
746 | ||
747 | Aspect_GraphicCallbackStruct aCallData; | |
748 | aCallData.reason = theReason; | |
749 | aCallData.glContext = GetGlContext(); | |
750 | aCallData.wsID = theCView.WsId; | |
751 | aCallData.viewID = theCView.ViewId; | |
752 | theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData); | |
753 | } | |
754 | ||
755 | // ======================================================================= | |
756 | // function : RedrawImmediate | |
757 | // purpose : | |
758 | // ======================================================================= | |
759 | void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView, | |
760 | const Aspect_CLayer2d& theCUnderLayer, | |
761 | const Aspect_CLayer2d& theCOverLayer, | |
762 | const Standard_Boolean theToForce) | |
763 | { | |
764 | if (!Activate()) | |
765 | { | |
766 | return; | |
767 | } | |
768 | ||
769 | GLboolean isDoubleBuffer = GL_FALSE; | |
770 | glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer); | |
771 | if (myView->ImmediateStructures().IsEmpty()) | |
772 | { | |
773 | if (theToForce | |
774 | || !myIsImmediateDrawn) | |
775 | { | |
776 | myIsImmediateDrawn = Standard_False; | |
777 | return; | |
778 | } | |
779 | ||
780 | if (myBackBufferRestored | |
781 | && isDoubleBuffer) | |
782 | { | |
783 | copyBackToFront(); | |
65812bd0 | 784 | glFlush(); |
679ecdee | 785 | } |
786 | else | |
787 | { | |
788 | Redraw (theCView, theCUnderLayer, theCOverLayer); | |
789 | } | |
790 | return; | |
791 | } | |
792 | ||
793 | if (isDoubleBuffer && myTransientDrawToFront) | |
794 | { | |
795 | if (!myBackBufferRestored) | |
796 | { | |
797 | Redraw (theCView, theCUnderLayer, theCOverLayer); | |
798 | return; | |
799 | } | |
800 | copyBackToFront(); | |
801 | MakeFrontBufCurrent(); | |
802 | } | |
803 | else | |
804 | { | |
805 | myBackBufferRestored = Standard_False; | |
806 | } | |
807 | myIsImmediateDrawn = Standard_True; | |
808 | ||
809 | NamedStatus |= OPENGL_NS_IMMEDIATE; | |
810 | ///glDisable (GL_LIGHTING); | |
811 | glDisable (GL_DEPTH_TEST); | |
812 | ||
813 | Handle(OpenGl_Workspace) aWS (this); | |
814 | for (OpenGl_SequenceOfStructure::Iterator anIter (myView->ImmediateStructures()); | |
815 | anIter.More(); anIter.Next()) | |
816 | { | |
817 | const OpenGl_Structure* aStructure = anIter.Value(); | |
818 | aStructure->Render (aWS); | |
819 | } | |
820 | ||
821 | NamedStatus &= ~OPENGL_NS_IMMEDIATE; | |
822 | ||
823 | if (isDoubleBuffer && myTransientDrawToFront) | |
824 | { | |
825 | glFlush(); | |
826 | MakeBackBufCurrent(); | |
827 | } | |
828 | } |