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