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