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