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