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