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