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