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