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