0026885: Visualization - drop redundant aspects from structure level
[occt.git] / src / OpenGl / OpenGl_Workspace.cxx
CommitLineData
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
c357e426 16#include <OpenGl_Workspace.hxx>
5f8b738e 17
2166f0fa
SK
18#include <InterfaceGraphic.hxx>
19
c357e426 20#include <OpenGl_ArbFBO.hxx>
2166f0fa
SK
21#include <OpenGl_AspectLine.hxx>
22#include <OpenGl_AspectFace.hxx>
23#include <OpenGl_AspectMarker.hxx>
24#include <OpenGl_AspectText.hxx>
bf75be98 25#include <OpenGl_Context.hxx>
679ecdee 26#include <OpenGl_Element.hxx>
a174a3c5 27#include <OpenGl_FrameBuffer.hxx>
c357e426 28#include <OpenGl_GlCore15.hxx>
29#include <OpenGl_SceneGeometry.hxx>
679ecdee 30#include <OpenGl_Structure.hxx>
25ef750e 31#include <OpenGl_Sampler.hxx>
bf75be98 32#include <OpenGl_Texture.hxx>
e276548b 33#include <OpenGl_View.hxx>
c357e426 34#include <OpenGl_Window.hxx>
2166f0fa 35
bf75be98 36#include <Graphic3d_TextureParams.hxx>
825aa485 37#include <Graphic3d_TransformUtils.hxx>
2166f0fa 38
92efcf78 39IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,Standard_Transient)
40IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter,OpenGl_RenderFilter)
41
c357e426 42#ifdef HAVE_GL2PS
43 #include <gl2ps.h>
44 /* OCC22216 NOTE: linker dependency can be switched off by undefining macro.
45 Pragma comment for gl2ps.lib is defined only here. */
46 #ifdef _MSC_VER
47 #pragma comment( lib, "gl2ps.lib" )
48 #endif
a174a3c5 49#endif
50
2166f0fa
SK
51namespace
52{
0adbd30f 53 static const TEL_COLOUR THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } };
54 static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
2166f0fa
SK
55
56 static const OpenGl_AspectLine myDefaultAspectLine;
57 static const OpenGl_AspectFace myDefaultAspectFace;
58 static const OpenGl_AspectMarker myDefaultAspectMarker;
2831708b 59 static const OpenGl_AspectText myDefaultAspectText;
2166f0fa 60
2166f0fa
SK
61 static const OpenGl_Matrix myDefaultMatrix =
62 {
63 {{ 1.0F, 0.0F, 0.0F, 0.0F },
64 { 0.0F, 1.0F, 0.0F, 0.0F },
65 { 0.0F, 0.0F, 1.0F, 0.0F },
66 { 0.0F, 0.0F, 0.0F, 1.0F }}
67 };
bf75be98 68
a3f6f591 69}
2166f0fa
SK
70
71// =======================================================================
0adbd30f 72// function : Init
73// purpose :
74// =======================================================================
75void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp)
76{
77 // ambient component
78 if (theProp.color_mask & OPENGL_AMBIENT_MASK)
79 {
80 const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb;
81 Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb,
82 aSrcAmb[1] * theProp.amb,
83 aSrcAmb[2] * theProp.amb,
84 1.0f);
85 }
86 else
87 {
88 Ambient = THE_BLACK_COLOR;
89 }
90
91 // diffusion component
92 if (theProp.color_mask & OPENGL_DIFFUSE_MASK)
93 {
94 const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb;
95 Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff,
96 aSrcDif[1] * theProp.diff,
97 aSrcDif[2] * theProp.diff,
98 1.0f);
99 }
100 else
101 {
102 Diffuse = THE_BLACK_COLOR;
103 }
104
105 // specular component
106 if (theProp.color_mask & OPENGL_SPECULAR_MASK)
107 {
108 const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb;
109 Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec,
110 aSrcSpe[1] * theProp.spec,
111 aSrcSpe[2] * theProp.spec,
112 1.0f);
113 }
114 else
115 {
116 Specular = THE_BLACK_COLOR;
117 }
118
119 // emission component
120 if (theProp.color_mask & OPENGL_EMISSIVE_MASK)
121 {
122 const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb;
123 Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv,
124 aSrcEms[1] * theProp.emsv,
125 aSrcEms[2] * theProp.emsv,
126 1.0f);
127 }
128 else
129 {
130 Emission = THE_BLACK_COLOR;
131 }
132
133 ChangeShine() = theProp.shine;
134 ChangeTransparency() = theProp.trans;
135}
136
137// =======================================================================
2166f0fa
SK
138// function : OpenGl_Workspace
139// purpose :
140// =======================================================================
c357e426 141OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Window)& theWindow)
142: NamedStatus (0),
0adbd30f 143 HighlightColor (&THE_WHITE_COLOR),
c357e426 144 myView (theView),
145 myWindow (theWindow),
146 myGlContext (!theWindow.IsNull() ? theWindow->GetGlContext() : NULL),
eae454e3 147 myUseZBuffer (Standard_True),
148 myUseDepthWrite (Standard_True),
2166f0fa 149 myUseGLLight (Standard_True),
2166f0fa 150 //
2166f0fa
SK
151 AspectLine_set (&myDefaultAspectLine),
152 AspectLine_applied (NULL),
153 AspectFace_set (&myDefaultAspectFace),
154 AspectFace_applied (NULL),
155 AspectMarker_set (&myDefaultAspectMarker),
156 AspectMarker_applied (NULL),
2831708b 157 AspectText_set (&myDefaultAspectText),
158 AspectText_applied (NULL),
2166f0fa
SK
159 ViewMatrix_applied (&myDefaultMatrix),
160 StructureMatrix_applied (&myDefaultMatrix),
3b1817a9 161 myCullingMode (TelCullUndefined),
0f8c0fb8 162 myModelViewMatrix (myDefaultMatrix),
550f3b8b 163 PolygonOffset_applied (THE_DEFAULT_POFFSET)
2166f0fa 164{
c357e426 165 if (!myGlContext.IsNull() && myGlContext->MakeCurrent())
73192b37 166 {
c357e426 167 myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
2166f0fa 168
c357e426 169 if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs))
170 {
171 // share and register for release once the resource is no longer used
172 myLineAttribs = new OpenGl_LineAttributes();
173 myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs);
174 myLineAttribs->Init (myGlContext);
175 }
2166f0fa 176
c357e426 177 // General initialization of the context
4e1523ef 178
c357e426 179 #if !defined(GL_ES_VERSION_2_0)
180 if (myGlContext->core11 != NULL)
181 {
182 // Eviter d'avoir les faces mal orientees en noir.
183 // Pourrait etre utiliser pour detecter les problemes d'orientation
184 glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
2166f0fa 185
c357e426 186 // Optimisation pour le Fog et l'antialiasing
187 glHint (GL_FOG_HINT, GL_FASTEST);
188 glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST);
189 }
2166f0fa 190
c357e426 191 glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST);
192 glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
193 #endif
73192b37 194 }
f8ae3605 195
196 myDefaultCappingAlgoFilter = new OpenGl_CappingAlgoFilter();
197 myNoneCulling.ChangeCullingMode() = TelCullNone;
198 myNoneCulling.ChangeEdge() = 0;
199 myFrontCulling.ChangeCullingMode() = TelCullBack;
200 myFrontCulling.ChangeEdge() = 0;
2166f0fa
SK
201}
202
203// =======================================================================
204// function : ~OpenGl_Workspace
205// purpose :
206// =======================================================================
207OpenGl_Workspace::~OpenGl_Workspace()
208{
73192b37 209 if (!myLineAttribs.IsNull())
210 {
211 myLineAttribs.Nullify();
212 myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True);
213 }
2166f0fa
SK
214}
215
216// =======================================================================
217// function : Activate
218// purpose :
219// =======================================================================
220Standard_Boolean OpenGl_Workspace::Activate()
221{
c357e426 222 if (myWindow.IsNull() || !myWindow->Activate())
223 {
2166f0fa 224 return Standard_False;
c357e426 225 }
2166f0fa 226
2166f0fa
SK
227 ViewMatrix_applied = &myDefaultMatrix;
228 StructureMatrix_applied = &myDefaultMatrix;
26395493 229
230 ResetAppliedAspect();
231
232 return Standard_True;
2166f0fa
SK
233}
234
26395493 235//=======================================================================
236//function : ResetAppliedAspect
237//purpose : Sets default values of GL parameters in accordance with default aspects
238//=======================================================================
239void OpenGl_Workspace::ResetAppliedAspect()
240{
4e1523ef 241 myGlContext->BindDefaultVao();
242
bf75be98 243 NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0;
0adbd30f 244 HighlightColor = &THE_WHITE_COLOR;
26395493 245 AspectLine_set = &myDefaultAspectLine;
246 AspectLine_applied = NULL;
247 AspectFace_set = &myDefaultAspectFace;
248 AspectFace_applied = NULL;
249 AspectMarker_set = &myDefaultAspectMarker;
250 AspectMarker_applied = NULL;
2831708b 251 AspectText_set = &myDefaultAspectText;
252 AspectText_applied = NULL;
253
550f3b8b 254 PolygonOffset_applied = THE_DEFAULT_POFFSET;
3b1817a9 255 myCullingMode = TelCullUndefined;
26395493 256
257 AspectLine(Standard_True);
258 AspectFace(Standard_True);
259 AspectMarker(Standard_True);
260 AspectText(Standard_True);
ac116c22 261
262 myGlContext->SetTypeOfLine (myDefaultAspectLine.Type());
263 myGlContext->SetLineWidth (myDefaultAspectLine.Width());
26395493 264}
bf75be98 265
266// =======================================================================
267// function : DisableTexture
268// purpose :
269// =======================================================================
270Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture()
271{
272 if (myTextureBound.IsNull())
273 {
274 return myTextureBound;
275 }
276
e3414ada 277 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
278 if (!aSampler.IsNull())
279 {
280 aSampler->Unbind (*myGlContext);
281 }
282
ca3c13d1 283#if !defined(GL_ES_VERSION_2_0)
bf75be98 284 // reset texture matrix because some code may expect it is identity
4e1523ef 285 if (myGlContext->core11 != NULL)
286 {
287 GLint aMatrixMode = GL_TEXTURE;
288 glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
289 glMatrixMode (GL_TEXTURE);
290 glLoadIdentity();
291 glMatrixMode (aMatrixMode);
292 }
ca3c13d1 293#endif
bf75be98 294
295 myTextureBound->Unbind (myGlContext);
296 switch (myTextureBound->GetTarget())
297 {
ca3c13d1 298 #if !defined(GL_ES_VERSION_2_0)
bf75be98 299 case GL_TEXTURE_1D:
300 {
4e1523ef 301 if (myGlContext->core11 != NULL)
bf75be98 302 {
4e1523ef 303 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
304 {
305 glDisable (GL_TEXTURE_GEN_S);
306 }
307 glDisable (GL_TEXTURE_1D);
bf75be98 308 }
bf75be98 309 break;
310 }
ca3c13d1 311 #endif
bf75be98 312 case GL_TEXTURE_2D:
313 {
ca3c13d1 314 #if !defined(GL_ES_VERSION_2_0)
4e1523ef 315 if (myGlContext->core11 != NULL)
bf75be98 316 {
4e1523ef 317 if (myTextureBound->GetParams()->GenMode() != GL_NONE)
a577aaab 318 {
4e1523ef 319 glDisable (GL_TEXTURE_GEN_S);
320 glDisable (GL_TEXTURE_GEN_T);
321 if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE)
322 {
323 glDisable (GL_POINT_SPRITE);
324 }
a577aaab 325 }
4e1523ef 326 glDisable (GL_TEXTURE_2D);
bf75be98 327 }
05e2200b 328 #endif
bf75be98 329 break;
330 }
331 default: break;
332 }
333
334 Handle(OpenGl_Texture) aPrevTexture = myTextureBound;
335 myTextureBound.Nullify();
336 return aPrevTexture;
337}
338
339// =======================================================================
340// function : setTextureParams
341// purpose :
342// =======================================================================
343void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture,
344 const Handle(Graphic3d_TextureParams)& theParams)
345{
346 const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams;
347 if (aParams.IsNull())
348 {
349 return;
350 }
351
ca3c13d1 352#if !defined(GL_ES_VERSION_2_0)
4e1523ef 353 if (myGlContext->core11 != NULL)
354 {
4e1523ef 355 GLint anEnvMode = GL_MODULATE; // lighting mode
356 if (!aParams->IsModulate())
076ca35c 357 {
4e1523ef 358 anEnvMode = GL_DECAL;
359 if (theTexture->GetFormat() == GL_ALPHA
360 || theTexture->GetFormat() == GL_LUMINANCE)
361 {
362 anEnvMode = GL_REPLACE;
363 }
076ca35c 364 }
076ca35c 365
4e1523ef 366 // setup generation of texture coordinates
367 switch (aParams->GenMode())
bf75be98 368 {
4e1523ef 369 case Graphic3d_TOTM_OBJECT:
bf75be98 370 {
4e1523ef 371 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
372 glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData());
373 if (theTexture->GetTarget() != GL_TEXTURE_1D)
374 {
375 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
376 glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData());
377 }
378 break;
bf75be98 379 }
4e1523ef 380 case Graphic3d_TOTM_SPHERE:
bf75be98 381 {
4e1523ef 382 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
383 if (theTexture->GetTarget() != GL_TEXTURE_1D)
384 {
385 glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
386 }
387 break;
bf75be98 388 }
4e1523ef 389 case Graphic3d_TOTM_EYE:
390 {
391 myGlContext->WorldViewState.Push();
c827ea3a 392
4e1523ef 393 myGlContext->WorldViewState.SetIdentity();
394 myGlContext->ApplyWorldViewMatrix();
bf75be98 395
4e1523ef 396 glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
397 glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData());
bf75be98 398
4e1523ef 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 }
c827ea3a 404
4e1523ef 405 myGlContext->WorldViewState.Pop();
c827ea3a 406
4e1523ef 407 break;
408 }
409 case Graphic3d_TOTM_SPRITE:
a577aaab 410 {
c357e426 411 if (myGlContext->core20fwd != NULL)
4e1523ef 412 {
413 glEnable (GL_POINT_SPRITE);
414 glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
415 anEnvMode = GL_REPLACE;
c357e426 416 myGlContext->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
4e1523ef 417 }
418 break;
a577aaab 419 }
4e1523ef 420 case Graphic3d_TOTM_MANUAL:
421 default: break;
a577aaab 422 }
bf75be98 423
4e1523ef 424 // setup lighting
425 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode);
426 }
ca3c13d1 427#endif
bf75be98 428
25ef750e 429 // get active sampler object to override default texture parameters
430 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
431
bf75be98 432 // setup texture filtering and wrapping
433 //if (theTexture->GetParams() != theParams)
434 const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
ca3c13d1 435 const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp();
bf75be98 436 switch (theTexture->GetTarget())
437 {
ca3c13d1 438 #if !defined(GL_ES_VERSION_2_0)
bf75be98 439 case GL_TEXTURE_1D:
440 {
25ef750e 441 if (aSampler.IsNull() || !aSampler->IsValid())
442 {
443 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
444 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
445 glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
446 }
447 else
448 {
449 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
450 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter);
451 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
452 }
453
bf75be98 454 break;
455 }
ca3c13d1 456 #endif
bf75be98 457 case GL_TEXTURE_2D:
458 {
459 GLenum aFilterMin = aFilter;
460 if (theTexture->HasMipmaps())
461 {
462 aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
463 if (aParams->Filter() == Graphic3d_TOTF_BILINEAR)
464 {
465 aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
466 }
467 else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR)
468 {
469 aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
470 }
471
472 if (myGlContext->extAnis)
473 {
474 // setup degree of anisotropy filter
475 const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy();
25ef750e 476 GLint aDegree;
bf75be98 477 switch (aParams->AnisoFilter())
478 {
479 case Graphic3d_LOTA_QUALITY:
480 {
25ef750e 481 aDegree = aMaxDegree;
bf75be98 482 break;
483 }
484 case Graphic3d_LOTA_MIDDLE:
485 {
25ef750e 486 aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2);
bf75be98 487 break;
488 }
489 case Graphic3d_LOTA_FAST:
490 {
25ef750e 491 aDegree = 2;
bf75be98 492 break;
493 }
494 case Graphic3d_LOTA_OFF:
495 default:
496 {
25ef750e 497 aDegree = 1;
bf75be98 498 break;
499 }
500 }
25ef750e 501
502 if (aSampler.IsNull() || !aSampler->IsValid())
503 {
504 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
505 }
506 else
507 {
508 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree);
509 }
bf75be98 510 }
511 }
25ef750e 512
513 if (aSampler.IsNull() || !aSampler->IsValid())
514 {
515 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
516 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
517 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
518 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
519 }
520 else
521 {
522 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin);
523 aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter);
524 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode);
525 aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode);
526 }
527
bf75be98 528 break;
529 }
530 default: break;
531 }
532
533 switch (theTexture->GetTarget())
534 {
ca3c13d1 535 #if !defined(GL_ES_VERSION_2_0)
bf75be98 536 case GL_TEXTURE_1D:
537 {
4e1523ef 538 if (myGlContext->core11 != NULL)
bf75be98 539 {
4e1523ef 540 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
541 {
542 glEnable (GL_TEXTURE_GEN_S);
543 }
544 glEnable (GL_TEXTURE_1D);
bf75be98 545 }
bf75be98 546 break;
547 }
ca3c13d1 548 #endif
bf75be98 549 case GL_TEXTURE_2D:
550 {
ca3c13d1 551 #if !defined(GL_ES_VERSION_2_0)
4e1523ef 552 if (myGlContext->core11 != NULL)
bf75be98 553 {
4e1523ef 554 if (aParams->GenMode() != Graphic3d_TOTM_MANUAL)
555 {
556 glEnable (GL_TEXTURE_GEN_S);
557 glEnable (GL_TEXTURE_GEN_T);
558 }
559 glEnable (GL_TEXTURE_2D);
bf75be98 560 }
05e2200b 561 #endif
bf75be98 562 break;
563 }
564 default: break;
565 }
566
bf75be98 567 theTexture->SetParams (aParams);
568}
569
570// =======================================================================
571// function : EnableTexture
572// purpose :
573// =======================================================================
574Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture,
575 const Handle(Graphic3d_TextureParams)& theParams)
576{
577 if (theTexture.IsNull() || !theTexture->IsValid())
578 {
579 return DisableTexture();
580 }
581
bca1d6e2 582 if (myTextureBound == theTexture
583 && (theParams.IsNull() || theParams == theTexture->GetParams()))
bf75be98 584 {
bca1d6e2 585 // already bound
586 return myTextureBound;
bf75be98 587 }
588
589 Handle(OpenGl_Texture) aPrevTexture = DisableTexture();
590 myTextureBound = theTexture;
591 myTextureBound->Bind (myGlContext);
592 setTextureParams (myTextureBound, theParams);
593
25ef750e 594 // If custom sampler object is available it will be
595 // used for overriding default texture parameters
596 const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler();
597
598 if (!aSampler.IsNull() && aSampler->IsValid())
599 {
600 aSampler->Bind (*myGlContext);
601 }
602
bf75be98 603 return aPrevTexture;
604}
a174a3c5 605
606// =======================================================================
c357e426 607// function : TelUpdatePolygonOffsets
38a0206f 608// purpose :
609// =======================================================================
c357e426 610static void TelUpdatePolygonOffsets (const TEL_POFFSET_PARAM& theOffsetData)
38a0206f 611{
c357e426 612 if ((theOffsetData.mode & Aspect_POM_Fill) == Aspect_POM_Fill)
38a0206f 613 {
c357e426 614 glEnable (GL_POLYGON_OFFSET_FILL);
38a0206f 615 }
616 else
617 {
c357e426 618 glDisable (GL_POLYGON_OFFSET_FILL);
38a0206f 619 }
38a0206f 620
c357e426 621#if !defined(GL_ES_VERSION_2_0)
622 if ((theOffsetData.mode & Aspect_POM_Line) == Aspect_POM_Line)
62e1beed 623 {
c357e426 624 glEnable (GL_POLYGON_OFFSET_LINE);
62e1beed 625 }
626 else
627 {
c357e426 628 glDisable (GL_POLYGON_OFFSET_LINE);
62e1beed 629 }
c357e426 630
631 if ((theOffsetData.mode & Aspect_POM_Point) == Aspect_POM_Point)
632 {
633 glEnable (GL_POLYGON_OFFSET_POINT);
634 }
635 else
636 {
637 glDisable (GL_POLYGON_OFFSET_POINT);
638 }
639#endif
640
641 glPolygonOffset (theOffsetData.factor, theOffsetData.units);
62e1beed 642}
643
644// =======================================================================
c357e426 645// function : updateMaterial
38a0206f 646// purpose :
647// =======================================================================
c357e426 648void OpenGl_Workspace::updateMaterial (const int theFlag)
38a0206f 649{
c357e426 650 // Case of hidden line
651 if (AspectFace_set->InteriorStyle() == Aspect_IS_HIDDENLINE)
f978241f 652 {
c357e426 653 myAspectFaceHl = *AspectFace_set; // copy all values including line edge aspect
654 myAspectFaceHl.ChangeIntFront().matcol = myView->BackgroundColor();
655 myAspectFaceHl.ChangeIntFront().color_mask = 0;
656 myAspectFaceHl.ChangeIntFront().color_mask = 0;
657
658 AspectFace_set = &myAspectFaceHl;
659 return;
f978241f 660 }
38a0206f 661
c357e426 662 const OPENGL_SURF_PROP* aProps = &AspectFace_set->IntFront();
663 GLenum aFace = GL_FRONT_AND_BACK;
664 if (theFlag == TEL_BACK_MATERIAL)
38a0206f 665 {
c357e426 666 aFace = GL_BACK;
667 aProps = &AspectFace_set->IntBack();
38a0206f 668 }
c357e426 669 else if (AspectFace_set->DistinguishingMode() == TOn
670 && !(NamedStatus & OPENGL_NS_RESMAT))
38a0206f 671 {
c357e426 672 aFace = GL_FRONT;
38a0206f 673 }
38a0206f 674
c357e426 675 myMatTmp.Init (*aProps);
676
677 // handling transparency
678 if (NamedStatus & OPENGL_NS_2NDPASSDO)
38a0206f 679 {
c357e426 680 // second pass
681 myMatTmp.Diffuse.a() = aProps->env_reflexion;
682 }
683 else
684 {
685 if (aProps->env_reflexion != 0.0f)
38a0206f 686 {
c357e426 687 // if the material reflects the environment scene, the second pass is needed
688 NamedStatus |= OPENGL_NS_2NDPASSNEED;
38a0206f 689 }
38a0206f 690
c357e426 691 if (aProps->trans != 1.0f)
38a0206f 692 {
c357e426 693 // render transparent
694 myMatTmp.Diffuse.a() = aProps->trans;
695 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
696 glEnable (GL_BLEND);
697 if (myUseDepthWrite)
698 {
699 glDepthMask (GL_FALSE);
700 }
38a0206f 701 }
702 else
703 {
c357e426 704 // render opaque
705 if ((NamedStatus & OPENGL_NS_ANTIALIASING) == 0)
706 {
707 glBlendFunc (GL_ONE, GL_ZERO);
708 glDisable (GL_BLEND);
709 }
710 if (myUseDepthWrite)
711 {
712 glDepthMask (GL_TRUE);
713 }
38a0206f 714 }
715 }
c357e426 716
717 // do not update material properties in case of zero reflection mode,
718 // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
719 if (aProps->color_mask == 0)
38a0206f 720 {
c357e426 721 return;
722 }
38a0206f 723
c357e426 724 // reset material
725 if (NamedStatus & OPENGL_NS_RESMAT)
726 {
727 #if !defined(GL_ES_VERSION_2_0)
728 if (myGlContext->core11 != NULL)
729 {
730 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
731 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
732 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
733 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
734 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
735 }
736 #endif
38a0206f 737
c357e426 738 if (theFlag == TEL_FRONT_MATERIAL)
739 {
740 myMatFront = myMatTmp;
741 myMatBack = myMatTmp;
742 }
743 else
38a0206f 744 {
c357e426 745 myMatBack = myMatTmp;
746 }
38a0206f 747
c357e426 748 NamedStatus &= ~OPENGL_NS_RESMAT;
749 return;
750 }
38a0206f 751
c357e426 752 // reduce updates
753 OpenGl_Material& anOld = (theFlag == TEL_FRONT_MATERIAL)
754 ? myMatFront
755 : myMatBack;
756#if !defined(GL_ES_VERSION_2_0)
757 if (myGlContext->core11 != NULL)
758 {
759 if (myMatTmp.Ambient.r() != anOld.Ambient.r()
760 || myMatTmp.Ambient.g() != anOld.Ambient.g()
761 || myMatTmp.Ambient.b() != anOld.Ambient.b())
762 {
763 myGlContext->core11->glMaterialfv (aFace, GL_AMBIENT, myMatTmp.Ambient.GetData());
38a0206f 764 }
c357e426 765 if (myMatTmp.Diffuse.r() != anOld.Diffuse.r()
766 || myMatTmp.Diffuse.g() != anOld.Diffuse.g()
767 || myMatTmp.Diffuse.b() != anOld.Diffuse.b()
768 || fabs (myMatTmp.Diffuse.a() - anOld.Diffuse.a()) > 0.01f)
38a0206f 769 {
c357e426 770 myGlContext->core11->glMaterialfv (aFace, GL_DIFFUSE, myMatTmp.Diffuse.GetData());
771 }
772 if (myMatTmp.Specular.r() != anOld.Specular.r()
773 || myMatTmp.Specular.g() != anOld.Specular.g()
774 || myMatTmp.Specular.b() != anOld.Specular.b())
775 {
776 myGlContext->core11->glMaterialfv (aFace, GL_SPECULAR, myMatTmp.Specular.GetData());
777 }
778 if (myMatTmp.Emission.r() != anOld.Emission.r()
779 || myMatTmp.Emission.g() != anOld.Emission.g()
780 || myMatTmp.Emission.b() != anOld.Emission.b())
781 {
782 myGlContext->core11->glMaterialfv (aFace, GL_EMISSION, myMatTmp.Emission.GetData());
783 }
784 if (myMatTmp.Shine() != anOld.Shine())
785 {
786 myGlContext->core11->glMaterialf (aFace, GL_SHININESS, myMatTmp.Shine());
38a0206f 787 }
788 }
c357e426 789#endif
790 anOld = myMatTmp;
791 if (aFace == GL_FRONT_AND_BACK)
792 {
793 myMatBack = myMatTmp;
794 }
38a0206f 795}
796
797// =======================================================================
c357e426 798// function : SetAspectLine
38a0206f 799// purpose :
800// =======================================================================
c357e426 801const OpenGl_AspectLine * OpenGl_Workspace::SetAspectLine(const OpenGl_AspectLine *AnAspect)
38a0206f 802{
c357e426 803 const OpenGl_AspectLine *AspectLine_old = AspectLine_set;
804 AspectLine_set = AnAspect;
805 return AspectLine_old;
806}
38a0206f 807
c357e426 808// =======================================================================
809// function : SetAspectFace
810// purpose :
811// =======================================================================
812const OpenGl_AspectFace * OpenGl_Workspace::SetAspectFace(const OpenGl_AspectFace *AnAspect)
813{
814 const OpenGl_AspectFace *AspectFace_old = AspectFace_set;
815 AspectFace_set = AnAspect;
816 return AspectFace_old;
817}
38a0206f 818
c357e426 819// =======================================================================
820// function : SetAspectMarker
821// purpose :
822// =======================================================================
823const OpenGl_AspectMarker * OpenGl_Workspace::SetAspectMarker(const OpenGl_AspectMarker *AnAspect)
824{
825 const OpenGl_AspectMarker *AspectMarker_old = AspectMarker_set;
826 AspectMarker_set = AnAspect;
827 return AspectMarker_old;
828}
f978241f 829
c357e426 830// =======================================================================
831// function : SetAspectText
832// purpose :
833// =======================================================================
834const OpenGl_AspectText * OpenGl_Workspace::SetAspectText(const OpenGl_AspectText *AnAspect)
835{
836 const OpenGl_AspectText *AspectText_old = AspectText_set;
837 AspectText_set = AnAspect;
838 return AspectText_old;
839}
840
841// =======================================================================
842// function : AspectLine
843// purpose :
844// =======================================================================
845const OpenGl_AspectLine * OpenGl_Workspace::AspectLine(const Standard_Boolean theWithApply)
846{
847 if (theWithApply)
f978241f 848 {
c357e426 849 AspectLine_applied = AspectLine_set;
f978241f 850 }
851
c357e426 852 return AspectLine_set;
853}
38a0206f 854
c357e426 855// =======================================================================
856// function : AspectFace
857// purpose :
858// =======================================================================
859const OpenGl_AspectFace* OpenGl_Workspace::AspectFace (const Standard_Boolean theToApply)
860{
861 if (!theToApply)
862 {
863 return AspectFace_set;
864 }
38a0206f 865
c357e426 866 if (myView->BackfacingModel() == Graphic3d_TOBM_AUTOMATIC)
38a0206f 867 {
c357e426 868 // manage back face culling mode, disable culling when clipping is enabled
869 TelCullMode aCullingMode = (myGlContext->Clipping().IsClippingOrCappingOn()
870 || AspectFace_set->InteriorStyle() == Aspect_IS_HATCH)
871 ? TelCullNone
872 : (TelCullMode )AspectFace_set->CullingMode();
873 if (aCullingMode != TelCullNone
874 && !(NamedStatus & OPENGL_NS_2NDPASSDO))
f978241f 875 {
c357e426 876 // disable culling in case of translucent shading aspect
877 if (AspectFace_set->IntFront().trans != 1.0f)
f978241f 878 {
c357e426 879 aCullingMode = TelCullNone;
880 }
881 }
882 if (myCullingMode != aCullingMode)
883 {
884 myCullingMode = aCullingMode;
885 switch (myCullingMode)
886 {
887 case TelCullNone:
888 case TelCullUndefined:
f978241f 889 {
c357e426 890 glDisable (GL_CULL_FACE);
f978241f 891 break;
892 }
c357e426 893 case TelCullFront:
f978241f 894 {
c357e426 895 glCullFace (GL_FRONT);
896 glEnable (GL_CULL_FACE);
f978241f 897 break;
898 }
c357e426 899 case TelCullBack:
f978241f 900 {
c357e426 901 glCullFace (GL_BACK);
902 glEnable (GL_CULL_FACE);
f978241f 903 break;
904 }
905 }
f978241f 906 }
f978241f 907 }
908
c357e426 909 if (AspectFace_set == AspectFace_applied)
a2e4f780 910 {
c357e426 911 return AspectFace_set;
a2e4f780 912 }
913
c357e426 914#if !defined(GL_ES_VERSION_2_0)
915 const Aspect_InteriorStyle anIntstyle = AspectFace_set->InteriorStyle();
916 if (AspectFace_applied == NULL || AspectFace_applied->InteriorStyle() != anIntstyle)
b86bb3df 917 {
c357e426 918 switch (anIntstyle)
760c21c2 919 {
c357e426 920 case Aspect_IS_EMPTY:
921 case Aspect_IS_HOLLOW:
ee51a9fe 922 {
c357e426 923 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
924 break;
ee51a9fe 925 }
c357e426 926 case Aspect_IS_HATCH:
62e1beed 927 {
c357e426 928 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
929 myLineAttribs->SetTypeOfHatch (AspectFace_applied != NULL ? AspectFace_applied->Hatch() : TEL_HS_SOLID);
930 break;
62e1beed 931 }
c357e426 932 case Aspect_IS_SOLID:
933 case Aspect_IS_HIDDENLINE:
934 {
935 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
936 if (myGlContext->core11 != NULL)
937 {
938 glDisable (GL_POLYGON_STIPPLE);
939 }
940 break;
941 }
942 case Aspect_IS_POINT:
38a0206f 943 {
c357e426 944 glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
945 break;
38a0206f 946 }
38a0206f 947 }
91c60b57 948 }
e276548b 949
c357e426 950 if (anIntstyle == Aspect_IS_HATCH)
91c60b57 951 {
c357e426 952 const Tint hatchstyle = AspectFace_set->Hatch();
953 if (AspectFace_applied == NULL || AspectFace_applied->Hatch() != hatchstyle)
f978241f 954 {
c357e426 955 myLineAttribs->SetTypeOfHatch (hatchstyle);
38a0206f 956 }
c357e426 957 }
958#endif
38a0206f 959
c357e426 960 // Aspect_POM_None means: do not change current settings
961 if ((AspectFace_set->PolygonOffset().mode & Aspect_POM_None) != Aspect_POM_None)
962 {
963 if (PolygonOffset_applied.mode != AspectFace_set->PolygonOffset().mode
964 || PolygonOffset_applied.factor != AspectFace_set->PolygonOffset().factor
965 || PolygonOffset_applied.units != AspectFace_set->PolygonOffset().units)
38a0206f 966 {
c357e426 967 SetPolygonOffset (AspectFace_set->PolygonOffset().mode,
968 AspectFace_set->PolygonOffset().factor,
969 AspectFace_set->PolygonOffset().units);
38a0206f 970 }
971 }
c357e426 972
973 updateMaterial (TEL_FRONT_MATERIAL);
974 if (AspectFace_set->DistinguishingMode() == TOn)
a174a3c5 975 {
c357e426 976 updateMaterial (TEL_BACK_MATERIAL);
977 }
62e1beed 978
83da37b1 979 if (AspectFace_set->DoTextureMap())
c357e426 980 {
83da37b1 981 EnableTexture (AspectFace_set->TextureRes (myGlContext),
982 AspectFace_set->TextureParams());
983 }
984 else
985 {
986 if (!myEnvironmentTexture.IsNull())
38a0206f 987 {
83da37b1 988 EnableTexture (myEnvironmentTexture,
989 myEnvironmentTexture->GetParams());
38a0206f 990 }
c357e426 991 else
62e1beed 992 {
c357e426 993 DisableTexture();
62e1beed 994 }
a174a3c5 995 }
996
c357e426 997 AspectFace_applied = AspectFace_set;
998 return AspectFace_set;
999}
a174a3c5 1000
c357e426 1001//=======================================================================
1002//function : SetPolygonOffset
1003//purpose :
1004//=======================================================================
1005void OpenGl_Workspace::SetPolygonOffset (int theMode,
1006 Standard_ShortReal theFactor,
1007 Standard_ShortReal theUnits)
1008{
1009 PolygonOffset_applied.mode = theMode;
1010 PolygonOffset_applied.factor = theFactor;
1011 PolygonOffset_applied.units = theUnits;
a174a3c5 1012
c357e426 1013 TelUpdatePolygonOffsets (PolygonOffset_applied);
1014}
38a0206f 1015
c357e426 1016// =======================================================================
1017// function : AspectMarker
1018// purpose :
1019// =======================================================================
1020const OpenGl_AspectMarker* OpenGl_Workspace::AspectMarker (const Standard_Boolean theToApply)
1021{
1022 if (theToApply && (AspectMarker_set != AspectMarker_applied))
ee51a9fe 1023 {
c357e426 1024 if (!AspectMarker_applied || (AspectMarker_set->Scale() != AspectMarker_applied->Scale()))
ee51a9fe 1025 {
c357e426 1026 #if !defined(GL_ES_VERSION_2_0)
1027 glPointSize (AspectMarker_set->Scale());
1028 #ifdef HAVE_GL2PS
1029 gl2psPointSize (AspectMarker_set->Scale());
1030 #endif
1031 #endif
ee51a9fe 1032 }
c357e426 1033 AspectMarker_applied = AspectMarker_set;
ee51a9fe 1034 }
c357e426 1035 return AspectMarker_set;
a174a3c5 1036}
679ecdee 1037
1038// =======================================================================
c357e426 1039// function : AspectText
679ecdee 1040// purpose :
1041// =======================================================================
c357e426 1042const OpenGl_AspectText* OpenGl_Workspace::AspectText (const Standard_Boolean theWithApply)
679ecdee 1043{
c357e426 1044 if (theWithApply)
679ecdee 1045 {
c357e426 1046 AspectText_applied = AspectText_set;
38a0206f 1047 }
1048
c357e426 1049 return AspectText_set;
679ecdee 1050}
1051
1052// =======================================================================
c357e426 1053// function : Width
679ecdee 1054// purpose :
1055// =======================================================================
c357e426 1056Standard_Integer OpenGl_Workspace::Width() const
679ecdee 1057{
c357e426 1058 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Width() : 0;
1059}
679ecdee 1060
c357e426 1061// =======================================================================
1062// function : Height
1063// purpose :
1064// =======================================================================
1065Standard_Integer OpenGl_Workspace::Height() const
1066{
1067 return !myView->GlWindow().IsNull() ? myView->GlWindow()->Height() : 0;
1068}
679ecdee 1069
c357e426 1070// =======================================================================
1071// function : UseGLLight
1072// purpose :
1073// =======================================================================
1074Standard_Boolean OpenGl_Workspace::UseGLLight() const
1075{
1076 return myView->IsGLLightEnabled();
1077}
679ecdee 1078
c357e426 1079// =======================================================================
1080// function : AntiAliasingMode
1081// purpose :
1082// =======================================================================
1083Standard_Integer OpenGl_Workspace::AntiAliasingMode() const
1084{
1085 return myView->IsAntialiasingEnabled();
1086}
679ecdee 1087
c357e426 1088// =======================================================================
1089// function : IsCullingEnabled
1090// purpose :
1091// =======================================================================
1092Standard_Boolean OpenGl_Workspace::IsCullingEnabled() const
1093{
1094 return myView->IsCullingEnabled();
679ecdee 1095}
1096
1097// =======================================================================
c357e426 1098// function : FBOCreate
679ecdee 1099// purpose :
1100// =======================================================================
b128c892 1101Handle(OpenGl_FrameBuffer) OpenGl_Workspace::FBOCreate (const Standard_Integer theWidth,
1102 const Standard_Integer theHeight)
679ecdee 1103{
c357e426 1104 // activate OpenGL context
1105 if (!Activate())
b128c892 1106 return Handle(OpenGl_FrameBuffer)();
c357e426 1107
83da37b1 1108 DisableTexture();
1109
c357e426 1110 // create the FBO
1111 const Handle(OpenGl_Context)& aCtx = GetGlContext();
b128c892 1112 Handle(OpenGl_FrameBuffer) aFrameBuffer = new OpenGl_FrameBuffer();
3c4b62a4 1113 if (!aFrameBuffer->Init (aCtx, theWidth, theHeight, GL_RGBA8, GL_DEPTH24_STENCIL8, 0))
679ecdee 1114 {
c357e426 1115 aFrameBuffer->Release (aCtx.operator->());
b128c892 1116 return Handle(OpenGl_FrameBuffer)();
679ecdee 1117 }
b128c892 1118 return aFrameBuffer;
679ecdee 1119}
1120
1121// =======================================================================
c357e426 1122// function : FBORelease
679ecdee 1123// purpose :
1124// =======================================================================
b128c892 1125void OpenGl_Workspace::FBORelease (Handle(OpenGl_FrameBuffer)& theFbo)
679ecdee 1126{
c357e426 1127 // activate OpenGL context
1128 if (!Activate()
b128c892 1129 || theFbo.IsNull())
62e1beed 1130 {
62e1beed 1131 return;
1132 }
c357e426 1133
b128c892 1134 theFbo->Release (GetGlContext().operator->());
1135 theFbo.Nullify();
c357e426 1136}
62e1beed 1137
c357e426 1138inline bool getDataFormat (const Image_PixMap& theData,
1139 GLenum& thePixelFormat,
1140 GLenum& theDataType)
1141{
1142 thePixelFormat = GL_RGB;
1143 theDataType = GL_UNSIGNED_BYTE;
1144 switch (theData.Format())
38a0206f 1145 {
c357e426 1146 #if !defined(GL_ES_VERSION_2_0)
1147 case Image_PixMap::ImgGray:
1148 thePixelFormat = GL_DEPTH_COMPONENT;
1149 theDataType = GL_UNSIGNED_BYTE;
1150 return true;
1151 case Image_PixMap::ImgGrayF:
1152 thePixelFormat = GL_DEPTH_COMPONENT;
1153 theDataType = GL_FLOAT;
1154 return true;
1155 case Image_PixMap::ImgBGR:
1156 thePixelFormat = GL_BGR;
1157 theDataType = GL_UNSIGNED_BYTE;
1158 return true;
1159 case Image_PixMap::ImgBGRA:
1160 case Image_PixMap::ImgBGR32:
1161 thePixelFormat = GL_BGRA;
1162 theDataType = GL_UNSIGNED_BYTE;
1163 return true;
1164 case Image_PixMap::ImgBGRF:
1165 thePixelFormat = GL_BGR;
1166 theDataType = GL_FLOAT;
1167 return true;
1168 case Image_PixMap::ImgBGRAF:
1169 thePixelFormat = GL_BGRA;
1170 theDataType = GL_FLOAT;
1171 return true;
1172 #else
1173 case Image_PixMap::ImgGray:
1174 case Image_PixMap::ImgGrayF:
1175 case Image_PixMap::ImgBGR:
1176 case Image_PixMap::ImgBGRA:
1177 case Image_PixMap::ImgBGR32:
1178 case Image_PixMap::ImgBGRF:
1179 case Image_PixMap::ImgBGRAF:
1180 return false;
1181 #endif
1182 case Image_PixMap::ImgRGB:
1183 thePixelFormat = GL_RGB;
1184 theDataType = GL_UNSIGNED_BYTE;
1185 return true;
1186 case Image_PixMap::ImgRGBA:
1187 case Image_PixMap::ImgRGB32:
1188 thePixelFormat = GL_RGBA;
1189 theDataType = GL_UNSIGNED_BYTE;
1190 return true;
1191 case Image_PixMap::ImgRGBF:
1192 thePixelFormat = GL_RGB;
1193 theDataType = GL_FLOAT;
1194 return true;
1195 case Image_PixMap::ImgRGBAF:
1196 thePixelFormat = GL_RGBA;
1197 theDataType = GL_FLOAT;
1198 return true;
1199 case Image_PixMap::ImgAlpha:
1200 case Image_PixMap::ImgAlphaF:
1201 return false; // GL_ALPHA is no more supported in core context
1202 case Image_PixMap::ImgUNKNOWN:
1203 return false;
38a0206f 1204 }
c357e426 1205 return false;
1206}
38a0206f 1207
c357e426 1208// =======================================================================
1209// function : getAligned
1210// purpose :
1211// =======================================================================
1212inline Standard_Size getAligned (const Standard_Size theNumber,
1213 const Standard_Size theAlignment)
1214{
1215 return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
1216}
1217
1218// =======================================================================
1219// function : BufferDump
1220// purpose :
1221// =======================================================================
b128c892 1222Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)& theFbo,
1223 Image_PixMap& theImage,
1224 const Graphic3d_BufferType& theBufferType)
c357e426 1225{
1226 GLenum aFormat, aType;
1227 if (theImage.IsEmpty()
1228 || !getDataFormat (theImage, aFormat, aType)
1229 || !Activate())
38a0206f 1230 {
c357e426 1231 return Standard_False;
38a0206f 1232 }
c357e426 1233#if !defined(GL_ES_VERSION_2_0)
1234 GLint aReadBufferPrev = GL_BACK;
1235 if (theBufferType == Graphic3d_BT_Depth
1236 && aFormat != GL_DEPTH_COMPONENT)
38a0206f 1237 {
c357e426 1238 return Standard_False;
1239 }
20aeeb7b 1240#else
1241 (void )theBufferType;
c357e426 1242#endif
38a0206f 1243
c357e426 1244 // bind FBO if used
b128c892 1245 if (!theFbo.IsNull() && theFbo->IsValid())
c357e426 1246 {
b128c892 1247 theFbo->BindBuffer (GetGlContext());
38a0206f 1248 }
1249 else
a2e4f780 1250 {
38a0206f 1251 #if !defined(GL_ES_VERSION_2_0)
c357e426 1252 glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
1253 GLint aDrawBufferPrev = GL_BACK;
1254 glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
1255 glReadBuffer (aDrawBufferPrev);
38a0206f 1256 #endif
a2e4f780 1257 }
1258
c357e426 1259 // setup alignment
1260 const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
1261 glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
1262 bool isBatchCopy = !theImage.IsTopDown();
38a0206f 1263
c357e426 1264 const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
1265 GLint aPixelsWidth = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
1266 Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
1267 if (anExtraBytes < anAligment)
b86bb3df 1268 {
c357e426 1269 aPixelsWidth = 0;
ee51a9fe 1270 }
c357e426 1271 else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
ee51a9fe 1272 {
c357e426 1273 aPixelsWidth = 0;
1274 isBatchCopy = false;
ee51a9fe 1275 }
c357e426 1276#if !defined(GL_ES_VERSION_2_0)
1277 glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
1278#else
1279 if (aPixelsWidth != 0)
ee51a9fe 1280 {
c357e426 1281 isBatchCopy = false;
b86bb3df 1282 }
c357e426 1283#endif
1284
1285 if (!isBatchCopy)
679ecdee 1286 {
c357e426 1287 // copy row by row
1288 for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
679ecdee 1289 {
c357e426 1290 // Image_PixMap rows indexation always starts from the upper corner
1291 // while order in memory depends on the flag and processed by ChangeRow() method
1292 glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
679ecdee 1293 }
679ecdee 1294 }
1295 else
1296 {
c357e426 1297 glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
679ecdee 1298 }
a1954302 1299
c357e426 1300 glPixelStorei (GL_PACK_ALIGNMENT, 1);
eae454e3 1301#if !defined(GL_ES_VERSION_2_0)
c357e426 1302 glPixelStorei (GL_PACK_ROW_LENGTH, 0);
eae454e3 1303#endif
a1954302 1304
b128c892 1305 if (!theFbo.IsNull() && theFbo->IsValid())
c357e426 1306 {
b128c892 1307 theFbo->UnbindBuffer (GetGlContext());
c357e426 1308 }
1309 else
1310 {
1311 #if !defined(GL_ES_VERSION_2_0)
1312 glReadBuffer (aReadBufferPrev);
1313 #endif
1314 }
1315 return Standard_True;
679ecdee 1316}
91c60b57 1317
91c60b57 1318// =======================================================================
1319// function : CanRender
1320// purpose :
1321// =======================================================================
1322Standard_Boolean OpenGl_RaytraceFilter::CanRender (const OpenGl_Element* theElement)
1323{
1324 Standard_Boolean aPrevFilterResult = Standard_True;
1325 if (!myPrevRenderFilter.IsNull())
1326 {
1327 aPrevFilterResult = myPrevRenderFilter->CanRender (theElement);
1328 }
1329 return aPrevFilterResult &&
1330 !OpenGl_Raytrace::IsRaytracedElement (theElement);
1331}