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