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