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 | |
a577aaab | 16 | #include <OpenGl_GlCore15.hxx> |
b86bb3df | 17 | #include <OpenGl_ArbFBO.hxx> |
5f8b738e | 18 | |
2166f0fa SK |
19 | #include <InterfaceGraphic.hxx> |
20 | ||
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> |
679ecdee | 28 | #include <OpenGl_Structure.hxx> |
25ef750e | 29 | #include <OpenGl_Sampler.hxx> |
b86bb3df | 30 | #include <OpenGl_ShaderManager.hxx> |
bf75be98 | 31 | #include <OpenGl_Texture.hxx> |
c827ea3a | 32 | #include <OpenGl_Utils.hxx> |
e276548b | 33 | #include <OpenGl_View.hxx> |
a174a3c5 | 34 | #include <OpenGl_Workspace.hxx> |
2166f0fa | 35 | |
bf75be98 | 36 | #include <Graphic3d_TextureParams.hxx> |
2166f0fa | 37 | |
58655684 | 38 | #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) |
a174a3c5 | 39 | #include <OpenGl_AVIWriter.hxx> |
40 | #endif | |
41 | ||
2166f0fa SK |
42 | IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window) |
43 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window) | |
44 | ||
45 | namespace | |
46 | { | |
0adbd30f | 47 | static const TEL_COLOUR THE_WHITE_COLOR = { { 1.0f, 1.0f, 1.0f, 1.0f } }; |
48 | static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f); | |
2166f0fa SK |
49 | |
50 | static const OpenGl_AspectLine myDefaultAspectLine; | |
51 | static const OpenGl_AspectFace myDefaultAspectFace; | |
52 | static const OpenGl_AspectMarker myDefaultAspectMarker; | |
53 | static const OpenGl_AspectText myDefaultAspectText; | |
54 | ||
55 | static const OpenGl_TextParam myDefaultTextParam = | |
56 | { | |
57 | 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM | |
58 | }; | |
59 | ||
60 | static const OpenGl_Matrix myDefaultMatrix = | |
61 | { | |
62 | {{ 1.0F, 0.0F, 0.0F, 0.0F }, | |
63 | { 0.0F, 1.0F, 0.0F, 0.0F }, | |
64 | { 0.0F, 0.0F, 1.0F, 0.0F }, | |
65 | { 0.0F, 0.0F, 0.0F, 1.0F }} | |
66 | }; | |
bf75be98 | 67 | |
2166f0fa SK |
68 | }; |
69 | ||
0adbd30f | 70 | // ======================================================================= |
71 | // function : Init | |
72 | // purpose : | |
73 | // ======================================================================= | |
74 | void OpenGl_Material::Init (const OPENGL_SURF_PROP& theProp) | |
75 | { | |
76 | // ambient component | |
77 | if (theProp.color_mask & OPENGL_AMBIENT_MASK) | |
78 | { | |
79 | const float* aSrcAmb = theProp.isphysic ? theProp.ambcol.rgb : theProp.matcol.rgb; | |
80 | Ambient = OpenGl_Vec4 (aSrcAmb[0] * theProp.amb, | |
81 | aSrcAmb[1] * theProp.amb, | |
82 | aSrcAmb[2] * theProp.amb, | |
83 | 1.0f); | |
84 | } | |
85 | else | |
86 | { | |
87 | Ambient = THE_BLACK_COLOR; | |
88 | } | |
89 | ||
90 | // diffusion component | |
91 | if (theProp.color_mask & OPENGL_DIFFUSE_MASK) | |
92 | { | |
93 | const float* aSrcDif = theProp.isphysic ? theProp.difcol.rgb : theProp.matcol.rgb; | |
94 | Diffuse = OpenGl_Vec4 (aSrcDif[0] * theProp.diff, | |
95 | aSrcDif[1] * theProp.diff, | |
96 | aSrcDif[2] * theProp.diff, | |
97 | 1.0f); | |
98 | } | |
99 | else | |
100 | { | |
101 | Diffuse = THE_BLACK_COLOR; | |
102 | } | |
103 | ||
104 | // specular component | |
105 | if (theProp.color_mask & OPENGL_SPECULAR_MASK) | |
106 | { | |
107 | const float* aSrcSpe = theProp.isphysic ? theProp.speccol.rgb : THE_WHITE_COLOR.rgb; | |
108 | Specular = OpenGl_Vec4 (aSrcSpe[0] * theProp.spec, | |
109 | aSrcSpe[1] * theProp.spec, | |
110 | aSrcSpe[2] * theProp.spec, | |
111 | 1.0f); | |
112 | } | |
113 | else | |
114 | { | |
115 | Specular = THE_BLACK_COLOR; | |
116 | } | |
117 | ||
118 | // emission component | |
119 | if (theProp.color_mask & OPENGL_EMISSIVE_MASK) | |
120 | { | |
121 | const float* aSrcEms = theProp.isphysic ? theProp.emscol.rgb : theProp.matcol.rgb; | |
122 | Emission = OpenGl_Vec4 (aSrcEms[0] * theProp.emsv, | |
123 | aSrcEms[1] * theProp.emsv, | |
124 | aSrcEms[2] * theProp.emsv, | |
125 | 1.0f); | |
126 | } | |
127 | else | |
128 | { | |
129 | Emission = THE_BLACK_COLOR; | |
130 | } | |
131 | ||
132 | ChangeShine() = theProp.shine; | |
133 | ChangeTransparency() = theProp.trans; | |
134 | } | |
135 | ||
2166f0fa SK |
136 | // ======================================================================= |
137 | // function : OpenGl_Workspace | |
138 | // purpose : | |
139 | // ======================================================================= | |
25b97fac | 140 | OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDriver, |
2166f0fa | 141 | const CALL_DEF_WINDOW& theCWindow, |
5e27df78 | 142 | Aspect_RenderingContext theGContext, |
58655684 | 143 | const Handle(OpenGl_Caps)& theCaps, |
5e27df78 | 144 | const Handle(OpenGl_Context)& theShareCtx) |
25b97fac | 145 | : OpenGl_Window (theDriver, theCWindow, theGContext, theCaps, theShareCtx), |
a174a3c5 | 146 | NamedStatus (0), |
0adbd30f | 147 | HighlightColor (&THE_WHITE_COLOR), |
a174a3c5 | 148 | // |
fc73a202 | 149 | myComputeInitStatus (OpenGl_RT_NONE), |
150 | myIsRaytraceDataValid (Standard_False), | |
25ef750e | 151 | myIsRaytraceWarnTextures (Standard_False), |
fc73a202 | 152 | myViewModificationStatus (0), |
153 | myLayersModificationStatus (0), | |
154 | // | |
a89742cf | 155 | myRaytraceFilter (new OpenGl_RaytraceFilter()), |
156 | myToRedrawGL (Standard_True), | |
73192b37 | 157 | myAntiAliasingMode (3), |
a174a3c5 | 158 | myTransientDrawToFront (Standard_True), |
679ecdee | 159 | myBackBufferRestored (Standard_False), |
160 | myIsImmediateDrawn (Standard_False), | |
2166f0fa SK |
161 | myUseZBuffer (Standard_False), |
162 | myUseDepthTest (Standard_True), | |
163 | myUseGLLight (Standard_True), | |
b7cd4ba7 | 164 | myIsCullingEnabled (Standard_False), |
a89742cf | 165 | myFrameCounter (0), |
2166f0fa | 166 | // |
2166f0fa SK |
167 | AspectLine_set (&myDefaultAspectLine), |
168 | AspectLine_applied (NULL), | |
169 | AspectFace_set (&myDefaultAspectFace), | |
170 | AspectFace_applied (NULL), | |
171 | AspectMarker_set (&myDefaultAspectMarker), | |
172 | AspectMarker_applied (NULL), | |
173 | AspectText_set (&myDefaultAspectText), | |
174 | AspectText_applied (NULL), | |
175 | TextParam_set (&myDefaultTextParam), | |
176 | TextParam_applied (NULL), | |
177 | ViewMatrix_applied (&myDefaultMatrix), | |
178 | StructureMatrix_applied (&myDefaultMatrix), | |
3b1817a9 | 179 | myCullingMode (TelCullUndefined), |
0f8c0fb8 | 180 | myModelViewMatrix (myDefaultMatrix), |
550f3b8b | 181 | PolygonOffset_applied (THE_DEFAULT_POFFSET) |
2166f0fa | 182 | { |
73192b37 | 183 | myGlContext->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1); |
b86bb3df | 184 | myResultFBO = new OpenGl_FrameBuffer(); |
73192b37 | 185 | |
186 | if (!myGlContext->GetResource ("OpenGl_LineAttributes", myLineAttribs)) | |
187 | { | |
188 | // share and register for release once the resource is no longer used | |
189 | myLineAttribs = new OpenGl_LineAttributes(); | |
190 | myGlContext->ShareResource ("OpenGl_LineAttributes", myLineAttribs); | |
191 | myLineAttribs->Init (myGlContext); | |
192 | } | |
2166f0fa SK |
193 | |
194 | // General initialization of the context | |
195 | ||
ca3c13d1 | 196 | #if !defined(GL_ES_VERSION_2_0) |
2166f0fa SK |
197 | // Eviter d'avoir les faces mal orientees en noir. |
198 | // Pourrait etre utiliser pour detecter les problemes d'orientation | |
bf75be98 | 199 | glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); |
2166f0fa SK |
200 | |
201 | // Optimisation pour le Fog et l'antialiasing | |
202 | glHint (GL_FOG_HINT, GL_FASTEST); | |
203 | glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST); | |
204 | glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST); | |
205 | glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST); | |
ca3c13d1 | 206 | #endif |
2166f0fa | 207 | |
73192b37 | 208 | // AA mode |
209 | const char* anAaEnv = ::getenv ("CALL_OPENGL_ANTIALIASING_MODE"); | |
210 | if (anAaEnv != NULL) | |
211 | { | |
212 | int v; | |
213 | if (sscanf (anAaEnv, "%d", &v) > 0) myAntiAliasingMode = v; | |
214 | } | |
2166f0fa SK |
215 | } |
216 | ||
1981cb22 | 217 | // ======================================================================= |
218 | // function : SetImmediateModeDrawToFront | |
219 | // purpose : | |
220 | // ======================================================================= | |
221 | Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) | |
222 | { | |
223 | const Standard_Boolean aPrevMode = myTransientDrawToFront; | |
224 | myTransientDrawToFront = theDrawToFrontBuffer; | |
225 | return aPrevMode; | |
226 | } | |
227 | ||
2166f0fa SK |
228 | // ======================================================================= |
229 | // function : ~OpenGl_Workspace | |
230 | // purpose : | |
231 | // ======================================================================= | |
232 | OpenGl_Workspace::~OpenGl_Workspace() | |
233 | { | |
73192b37 | 234 | if (!myLineAttribs.IsNull()) |
235 | { | |
236 | myLineAttribs.Nullify(); | |
237 | myGlContext->ReleaseResource ("OpenGl_LineAttributes", Standard_True); | |
238 | } | |
239 | ||
b86bb3df | 240 | if (!myResultFBO.IsNull()) |
241 | { | |
242 | myResultFBO->Release (myGlContext.operator->()); | |
243 | myResultFBO.Nullify(); | |
244 | } | |
245 | if (myFullScreenQuad.IsValid()) | |
246 | { | |
247 | myFullScreenQuad.Release (myGlContext.operator->()); | |
248 | } | |
249 | ||
fc73a202 | 250 | ReleaseRaytraceResources(); |
2166f0fa SK |
251 | } |
252 | ||
253 | // ======================================================================= | |
254 | // function : Activate | |
255 | // purpose : | |
256 | // ======================================================================= | |
257 | Standard_Boolean OpenGl_Workspace::Activate() | |
258 | { | |
259 | if (!OpenGl_Window::Activate()) | |
260 | return Standard_False; | |
261 | ||
2166f0fa SK |
262 | ViewMatrix_applied = &myDefaultMatrix; |
263 | StructureMatrix_applied = &myDefaultMatrix; | |
26395493 | 264 | |
265 | ResetAppliedAspect(); | |
266 | ||
267 | return Standard_True; | |
2166f0fa SK |
268 | } |
269 | ||
26395493 | 270 | //======================================================================= |
271 | //function : ResetAppliedAspect | |
272 | //purpose : Sets default values of GL parameters in accordance with default aspects | |
273 | //======================================================================= | |
274 | void OpenGl_Workspace::ResetAppliedAspect() | |
275 | { | |
bf75be98 | 276 | NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0; |
0adbd30f | 277 | HighlightColor = &THE_WHITE_COLOR; |
26395493 | 278 | AspectLine_set = &myDefaultAspectLine; |
279 | AspectLine_applied = NULL; | |
280 | AspectFace_set = &myDefaultAspectFace; | |
281 | AspectFace_applied = NULL; | |
282 | AspectMarker_set = &myDefaultAspectMarker; | |
283 | AspectMarker_applied = NULL; | |
284 | AspectText_set = &myDefaultAspectText; | |
285 | AspectText_applied = NULL; | |
286 | TextParam_set = &myDefaultTextParam; | |
287 | TextParam_applied = NULL; | |
550f3b8b | 288 | PolygonOffset_applied = THE_DEFAULT_POFFSET; |
3b1817a9 | 289 | myCullingMode = TelCullUndefined; |
26395493 | 290 | |
291 | AspectLine(Standard_True); | |
292 | AspectFace(Standard_True); | |
293 | AspectMarker(Standard_True); | |
294 | AspectText(Standard_True); | |
295 | } | |
bf75be98 | 296 | |
297 | // ======================================================================= | |
298 | // function : DisableTexture | |
299 | // purpose : | |
300 | // ======================================================================= | |
301 | Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture() | |
302 | { | |
303 | if (myTextureBound.IsNull()) | |
304 | { | |
305 | return myTextureBound; | |
306 | } | |
307 | ||
e3414ada | 308 | const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler(); |
309 | if (!aSampler.IsNull()) | |
310 | { | |
311 | aSampler->Unbind (*myGlContext); | |
312 | } | |
313 | ||
ca3c13d1 | 314 | #if !defined(GL_ES_VERSION_2_0) |
bf75be98 | 315 | // reset texture matrix because some code may expect it is identity |
316 | GLint aMatrixMode = GL_TEXTURE; | |
317 | glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); | |
318 | glMatrixMode (GL_TEXTURE); | |
319 | glLoadIdentity(); | |
320 | glMatrixMode (aMatrixMode); | |
ca3c13d1 | 321 | #endif |
bf75be98 | 322 | |
323 | myTextureBound->Unbind (myGlContext); | |
324 | switch (myTextureBound->GetTarget()) | |
325 | { | |
ca3c13d1 | 326 | #if !defined(GL_ES_VERSION_2_0) |
bf75be98 | 327 | case GL_TEXTURE_1D: |
328 | { | |
ca3c13d1 | 329 | |
bf75be98 | 330 | if (myTextureBound->GetParams()->GenMode() != GL_NONE) |
331 | { | |
332 | glDisable (GL_TEXTURE_GEN_S); | |
333 | } | |
334 | glDisable (GL_TEXTURE_1D); | |
335 | break; | |
336 | } | |
ca3c13d1 | 337 | #endif |
bf75be98 | 338 | case GL_TEXTURE_2D: |
339 | { | |
ca3c13d1 | 340 | #if !defined(GL_ES_VERSION_2_0) |
bf75be98 | 341 | if (myTextureBound->GetParams()->GenMode() != GL_NONE) |
342 | { | |
343 | glDisable (GL_TEXTURE_GEN_S); | |
344 | glDisable (GL_TEXTURE_GEN_T); | |
a577aaab | 345 | if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE) |
346 | { | |
347 | glDisable (GL_POINT_SPRITE); | |
348 | } | |
bf75be98 | 349 | } |
350 | glDisable (GL_TEXTURE_2D); | |
05e2200b | 351 | #endif |
bf75be98 | 352 | break; |
353 | } | |
354 | default: break; | |
355 | } | |
356 | ||
357 | Handle(OpenGl_Texture) aPrevTexture = myTextureBound; | |
358 | myTextureBound.Nullify(); | |
359 | return aPrevTexture; | |
360 | } | |
361 | ||
362 | // ======================================================================= | |
363 | // function : setTextureParams | |
364 | // purpose : | |
365 | // ======================================================================= | |
366 | void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture, | |
367 | const Handle(Graphic3d_TextureParams)& theParams) | |
368 | { | |
369 | const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams; | |
370 | if (aParams.IsNull()) | |
371 | { | |
372 | return; | |
373 | } | |
374 | ||
ca3c13d1 | 375 | #if !defined(GL_ES_VERSION_2_0) |
bf75be98 | 376 | GLint aMatrixMode = GL_TEXTURE; |
377 | glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); | |
378 | ||
379 | // setup texture matrix | |
380 | glMatrixMode (GL_TEXTURE); | |
c827ea3a | 381 | OpenGl_Mat4 aTextureMat; |
bf75be98 | 382 | const Graphic3d_Vec2& aScale = aParams->Scale(); |
383 | const Graphic3d_Vec2& aTrans = aParams->Translation(); | |
c827ea3a | 384 | OpenGl_Utils::Scale (aTextureMat, aScale.x(), aScale.y(), 1.0f); |
385 | OpenGl_Utils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f); | |
386 | OpenGl_Utils::Rotate (aTextureMat, -aParams->Rotation(), 0.0f, 0.0f, 1.0f); | |
387 | glLoadMatrixf (aTextureMat); | |
bf75be98 | 388 | |
076ca35c | 389 | GLint anEnvMode = GL_MODULATE; // lighting mode |
390 | if (!aParams->IsModulate()) | |
391 | { | |
392 | anEnvMode = GL_DECAL; | |
393 | if (theTexture->GetFormat() == GL_ALPHA | |
394 | || theTexture->GetFormat() == GL_LUMINANCE) | |
395 | { | |
396 | anEnvMode = GL_REPLACE; | |
397 | } | |
398 | } | |
399 | ||
bf75be98 | 400 | // setup generation of texture coordinates |
401 | switch (aParams->GenMode()) | |
402 | { | |
403 | case Graphic3d_TOTM_OBJECT: | |
404 | { | |
405 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
406 | glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData()); | |
407 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
408 | { | |
409 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
410 | glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData()); | |
411 | } | |
412 | break; | |
413 | } | |
414 | case Graphic3d_TOTM_SPHERE: | |
415 | { | |
416 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); | |
417 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
418 | { | |
419 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); | |
420 | } | |
421 | break; | |
422 | } | |
423 | case Graphic3d_TOTM_EYE: | |
424 | { | |
c827ea3a | 425 | myGlContext->WorldViewState.Push(); |
426 | ||
427 | myGlContext->WorldViewState.SetIdentity(); | |
428 | myGlContext->ApplyWorldViewMatrix(); | |
bf75be98 | 429 | |
430 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); | |
431 | glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData()); | |
432 | ||
433 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
434 | { | |
435 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); | |
436 | glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData()); | |
437 | } | |
c827ea3a | 438 | |
439 | myGlContext->WorldViewState.Pop(); | |
440 | ||
bf75be98 | 441 | break; |
442 | } | |
a577aaab | 443 | case Graphic3d_TOTM_SPRITE: |
444 | { | |
445 | if (GetGlContext()->core20 != NULL) | |
446 | { | |
447 | glEnable (GL_POINT_SPRITE); | |
448 | glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); | |
076ca35c | 449 | anEnvMode = GL_REPLACE; |
a577aaab | 450 | GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); |
451 | } | |
452 | break; | |
453 | } | |
bf75be98 | 454 | case Graphic3d_TOTM_MANUAL: |
455 | default: break; | |
456 | } | |
457 | ||
458 | // setup lighting | |
076ca35c | 459 | glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, anEnvMode); |
ca3c13d1 | 460 | #endif |
bf75be98 | 461 | |
25ef750e | 462 | // get active sampler object to override default texture parameters |
463 | const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler(); | |
464 | ||
bf75be98 | 465 | // setup texture filtering and wrapping |
466 | //if (theTexture->GetParams() != theParams) | |
467 | const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR; | |
ca3c13d1 | 468 | const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : myGlContext->TextureWrapClamp(); |
bf75be98 | 469 | switch (theTexture->GetTarget()) |
470 | { | |
ca3c13d1 | 471 | #if !defined(GL_ES_VERSION_2_0) |
bf75be98 | 472 | case GL_TEXTURE_1D: |
473 | { | |
25ef750e | 474 | if (aSampler.IsNull() || !aSampler->IsValid()) |
475 | { | |
476 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter); | |
477 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter); | |
478 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode); | |
479 | } | |
480 | else | |
481 | { | |
482 | aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter); | |
483 | aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilter); | |
484 | aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode); | |
485 | } | |
486 | ||
bf75be98 | 487 | break; |
488 | } | |
ca3c13d1 | 489 | #endif |
bf75be98 | 490 | case GL_TEXTURE_2D: |
491 | { | |
492 | GLenum aFilterMin = aFilter; | |
493 | if (theTexture->HasMipmaps()) | |
494 | { | |
495 | aFilterMin = GL_NEAREST_MIPMAP_NEAREST; | |
496 | if (aParams->Filter() == Graphic3d_TOTF_BILINEAR) | |
497 | { | |
498 | aFilterMin = GL_LINEAR_MIPMAP_NEAREST; | |
499 | } | |
500 | else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR) | |
501 | { | |
502 | aFilterMin = GL_LINEAR_MIPMAP_LINEAR; | |
503 | } | |
504 | ||
505 | if (myGlContext->extAnis) | |
506 | { | |
507 | // setup degree of anisotropy filter | |
508 | const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy(); | |
25ef750e | 509 | GLint aDegree; |
bf75be98 | 510 | switch (aParams->AnisoFilter()) |
511 | { | |
512 | case Graphic3d_LOTA_QUALITY: | |
513 | { | |
25ef750e | 514 | aDegree = aMaxDegree; |
bf75be98 | 515 | break; |
516 | } | |
517 | case Graphic3d_LOTA_MIDDLE: | |
518 | { | |
25ef750e | 519 | aDegree = (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2); |
bf75be98 | 520 | break; |
521 | } | |
522 | case Graphic3d_LOTA_FAST: | |
523 | { | |
25ef750e | 524 | aDegree = 2; |
bf75be98 | 525 | break; |
526 | } | |
527 | case Graphic3d_LOTA_OFF: | |
528 | default: | |
529 | { | |
25ef750e | 530 | aDegree = 1; |
bf75be98 | 531 | break; |
532 | } | |
533 | } | |
25ef750e | 534 | |
535 | if (aSampler.IsNull() || !aSampler->IsValid()) | |
536 | { | |
537 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree); | |
538 | } | |
539 | else | |
540 | { | |
541 | aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAX_ANISOTROPY_EXT, aDegree); | |
542 | } | |
bf75be98 | 543 | } |
544 | } | |
25ef750e | 545 | |
546 | if (aSampler.IsNull() || !aSampler->IsValid()) | |
547 | { | |
548 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin); | |
549 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter); | |
550 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode); | |
551 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode); | |
552 | } | |
553 | else | |
554 | { | |
555 | aSampler->SetParameter (*myGlContext, GL_TEXTURE_MIN_FILTER, aFilterMin); | |
556 | aSampler->SetParameter (*myGlContext, GL_TEXTURE_MAG_FILTER, aFilter); | |
557 | aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_S, aWrapMode); | |
558 | aSampler->SetParameter (*myGlContext, GL_TEXTURE_WRAP_T, aWrapMode); | |
559 | } | |
560 | ||
bf75be98 | 561 | break; |
562 | } | |
563 | default: break; | |
564 | } | |
565 | ||
566 | switch (theTexture->GetTarget()) | |
567 | { | |
ca3c13d1 | 568 | #if !defined(GL_ES_VERSION_2_0) |
bf75be98 | 569 | case GL_TEXTURE_1D: |
570 | { | |
571 | if (aParams->GenMode() != Graphic3d_TOTM_MANUAL) | |
572 | { | |
573 | glEnable (GL_TEXTURE_GEN_S); | |
574 | } | |
575 | glEnable (GL_TEXTURE_1D); | |
576 | break; | |
577 | } | |
ca3c13d1 | 578 | #endif |
bf75be98 | 579 | case GL_TEXTURE_2D: |
580 | { | |
ca3c13d1 | 581 | #if !defined(GL_ES_VERSION_2_0) |
bf75be98 | 582 | if (aParams->GenMode() != Graphic3d_TOTM_MANUAL) |
583 | { | |
584 | glEnable (GL_TEXTURE_GEN_S); | |
585 | glEnable (GL_TEXTURE_GEN_T); | |
586 | } | |
587 | glEnable (GL_TEXTURE_2D); | |
05e2200b | 588 | #endif |
bf75be98 | 589 | break; |
590 | } | |
591 | default: break; | |
592 | } | |
593 | ||
ca3c13d1 | 594 | #if !defined(GL_ES_VERSION_2_0) |
bf75be98 | 595 | glMatrixMode (aMatrixMode); // turn back active matrix |
ca3c13d1 | 596 | #endif |
bf75be98 | 597 | theTexture->SetParams (aParams); |
598 | } | |
599 | ||
600 | // ======================================================================= | |
601 | // function : EnableTexture | |
602 | // purpose : | |
603 | // ======================================================================= | |
604 | Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture, | |
605 | const Handle(Graphic3d_TextureParams)& theParams) | |
606 | { | |
607 | if (theTexture.IsNull() || !theTexture->IsValid()) | |
608 | { | |
609 | return DisableTexture(); | |
610 | } | |
611 | ||
bca1d6e2 | 612 | if (myTextureBound == theTexture |
613 | && (theParams.IsNull() || theParams == theTexture->GetParams())) | |
bf75be98 | 614 | { |
bca1d6e2 | 615 | // already bound |
616 | return myTextureBound; | |
bf75be98 | 617 | } |
618 | ||
619 | Handle(OpenGl_Texture) aPrevTexture = DisableTexture(); | |
620 | myTextureBound = theTexture; | |
621 | myTextureBound->Bind (myGlContext); | |
622 | setTextureParams (myTextureBound, theParams); | |
623 | ||
25ef750e | 624 | // If custom sampler object is available it will be |
625 | // used for overriding default texture parameters | |
626 | const Handle(OpenGl_Sampler)& aSampler = myGlContext->TextureSampler(); | |
627 | ||
628 | if (!aSampler.IsNull() && aSampler->IsValid()) | |
629 | { | |
630 | aSampler->Bind (*myGlContext); | |
631 | } | |
632 | ||
bf75be98 | 633 | return aPrevTexture; |
634 | } | |
a174a3c5 | 635 | |
636 | // ======================================================================= | |
637 | // function : Redraw | |
638 | // purpose : | |
639 | // ======================================================================= | |
640 | void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView, | |
641 | const Aspect_CLayer2d& theCUnderLayer, | |
642 | const Aspect_CLayer2d& theCOverLayer) | |
643 | { | |
644 | if (!Activate()) | |
645 | { | |
646 | return; | |
647 | } | |
648 | ||
a89742cf | 649 | ++myFrameCounter; |
b7cd4ba7 | 650 | myIsCullingEnabled = theCView.IsCullingEnabled; |
651 | ||
a174a3c5 | 652 | // release pending GL resources |
653 | Handle(OpenGl_Context) aGlCtx = GetGlContext(); | |
654 | aGlCtx->ReleaseDelayed(); | |
655 | ||
b5ac8292 | 656 | // fetch OpenGl context state |
657 | aGlCtx->FetchState(); | |
a174a3c5 | 658 | |
25b97fac | 659 | Tint toSwap = (aGlCtx->IsRender() && !aGlCtx->caps->buffersNoSwap) ? 1 : 0; // swap buffers |
a174a3c5 | 660 | OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO; |
661 | if (aFrameBuffer != NULL) | |
662 | { | |
fd4a6963 | 663 | aFrameBuffer->SetupViewport (aGlCtx); |
a174a3c5 | 664 | toSwap = 0; // no need to swap buffers |
665 | } | |
e3573bb9 | 666 | else |
667 | { | |
668 | aGlCtx->core11fwd->glViewport (0, 0, myWidth, myHeight); | |
669 | } | |
a174a3c5 | 670 | |
b86bb3df | 671 | Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth; |
672 | Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight; | |
673 | ||
674 | if (myResultFBO->GetVPSizeX() != aSizeX | |
675 | || myResultFBO->GetVPSizeY() != aSizeY) | |
676 | { | |
677 | myResultFBO->Init (aGlCtx, aSizeX, aSizeY); | |
678 | } | |
679 | if (myResultFBO->IsValid()) | |
680 | { | |
681 | myResultFBO->SetupViewport (aGlCtx); | |
682 | } | |
683 | ||
684 | const Standard_Boolean isImmediate = myView->HasImmediateStructures() | |
685 | || myResultFBO->IsValid(); | |
686 | ||
a89742cf | 687 | myToRedrawGL = Standard_True; |
688 | if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING | |
689 | && myComputeInitStatus != OpenGl_RT_FAIL) | |
e276548b | 690 | { |
a89742cf | 691 | if (UpdateRaytraceGeometry (OpenGl_GUM_CHECK) && myIsRaytraceDataValid) |
692 | { | |
693 | myToRedrawGL = Standard_False; | |
694 | ||
695 | // Only non-raytracable structures should be rendered in OpenGL mode. | |
696 | Handle(OpenGl_RenderFilter) aRenderFilter = GetRenderFilter(); | |
697 | myRaytraceFilter->SetPrevRenderFilter (aRenderFilter); | |
698 | SetRenderFilter (myRaytraceFilter); | |
699 | ||
a89742cf | 700 | if (myOpenGlFBO.IsNull()) |
701 | { | |
702 | myOpenGlFBO = new OpenGl_FrameBuffer(); | |
703 | } | |
704 | if (myOpenGlFBO->GetVPSizeX() != aSizeX | |
705 | || myOpenGlFBO->GetVPSizeY() != aSizeY) | |
706 | { | |
707 | myOpenGlFBO->Init (aGlCtx, aSizeX, aSizeY); | |
708 | } | |
709 | ||
710 | // OverLayer and UnderLayer shouldn't be drawn by OpenGL. | |
711 | // They will be drawn during ray-tracing. | |
712 | Aspect_CLayer2d anEmptyCLayer; | |
713 | anEmptyCLayer.ptrLayer = NULL; | |
714 | ||
715 | myOpenGlFBO->BindBuffer (aGlCtx); | |
716 | redraw1 (theCView, anEmptyCLayer, anEmptyCLayer, 0); | |
717 | myOpenGlFBO->UnbindBuffer (aGlCtx); | |
718 | ||
a89742cf | 719 | Raytrace (theCView, aSizeX, aSizeY, isImmediate ? 0 : toSwap, |
b86bb3df | 720 | theCOverLayer, theCUnderLayer, |
721 | myResultFBO->IsValid() ? myResultFBO.operator->() : aFrameBuffer); | |
a89742cf | 722 | |
723 | if (isImmediate) | |
724 | { | |
b86bb3df | 725 | RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True, aFrameBuffer); |
a89742cf | 726 | } |
727 | ||
728 | SetRenderFilter (aRenderFilter); | |
729 | ||
730 | theCView.WasRedrawnGL = Standard_False; | |
731 | } | |
732 | } | |
733 | ||
734 | if (myToRedrawGL) | |
735 | { | |
736 | // draw entire frame using normal OpenGL pipeline | |
b86bb3df | 737 | if (myResultFBO->IsValid()) |
738 | { | |
739 | myResultFBO->BindBuffer (aGlCtx); | |
740 | } | |
741 | else if (aFrameBuffer != NULL) | |
a89742cf | 742 | { |
743 | aFrameBuffer->BindBuffer (aGlCtx); | |
744 | } | |
745 | ||
679ecdee | 746 | redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap); |
747 | if (isImmediate) | |
e276548b | 748 | { |
b86bb3df | 749 | RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True, aFrameBuffer); |
e276548b | 750 | } |
751 | ||
752 | theCView.WasRedrawnGL = Standard_True; | |
e276548b | 753 | } |
a174a3c5 | 754 | |
755 | if (aFrameBuffer != NULL) | |
756 | { | |
757 | aFrameBuffer->UnbindBuffer (aGlCtx); | |
758 | // move back original viewport | |
e3573bb9 | 759 | aGlCtx->core11fwd->glViewport (0, 0, myWidth, myHeight); |
a174a3c5 | 760 | } |
761 | ||
679ecdee | 762 | #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) |
a174a3c5 | 763 | if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow)) |
764 | { | |
765 | GLint params[4]; | |
766 | glGetIntegerv (GL_VIEWPORT, params); | |
767 | int nWidth = params[2] & ~0x7; | |
768 | int nHeight = params[3] & ~0x7; | |
769 | ||
770 | const int nBitsPerPixel = 24; | |
771 | GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8]; | |
772 | ||
773 | glPixelStorei (GL_PACK_ALIGNMENT, 1); | |
774 | glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData); | |
775 | OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel); | |
776 | delete[] aDumpData; | |
777 | } | |
778 | #endif | |
779 | ||
780 | // reset render mode state | |
b5ac8292 | 781 | aGlCtx->FetchState(); |
a174a3c5 | 782 | } |
679ecdee | 783 | |
784 | // ======================================================================= | |
785 | // function : redraw1 | |
786 | // purpose : | |
787 | // ======================================================================= | |
788 | void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView, | |
789 | const Aspect_CLayer2d& theCUnderLayer, | |
790 | const Aspect_CLayer2d& theCOverLayer, | |
791 | const int theToSwap) | |
792 | { | |
73192b37 | 793 | if (myView.IsNull()) |
679ecdee | 794 | { |
795 | return; | |
796 | } | |
797 | ||
798 | // request reset of material | |
799 | NamedStatus |= OPENGL_NS_RESMAT; | |
800 | ||
679ecdee | 801 | GLbitfield toClear = GL_COLOR_BUFFER_BIT; |
802 | if (myUseZBuffer) | |
803 | { | |
804 | glDepthFunc (GL_LEQUAL); | |
805 | glDepthMask (GL_TRUE); | |
806 | if (myUseDepthTest) | |
807 | { | |
808 | glEnable (GL_DEPTH_TEST); | |
809 | } | |
810 | else | |
811 | { | |
812 | glDisable (GL_DEPTH_TEST); | |
813 | } | |
814 | ||
ca3c13d1 | 815 | #if !defined(GL_ES_VERSION_2_0) |
679ecdee | 816 | glClearDepth (1.0); |
ca3c13d1 | 817 | #else |
818 | glClearDepthf (1.0f); | |
819 | #endif | |
679ecdee | 820 | toClear |= GL_DEPTH_BUFFER_BIT; |
821 | } | |
822 | else | |
823 | { | |
824 | glDisable (GL_DEPTH_TEST); | |
825 | } | |
826 | ||
a89742cf | 827 | if (!ToRedrawGL()) |
679ecdee | 828 | { |
a89742cf | 829 | // set background to black |
830 | glClearColor (0.0f, 0.0f, 0.0f, 0.0f); | |
831 | toClear |= GL_DEPTH_BUFFER_BIT; // | |
679ecdee | 832 | } |
833 | else | |
834 | { | |
a89742cf | 835 | if (NamedStatus & OPENGL_NS_WHITEBACK) |
836 | { | |
837 | // set background to white | |
838 | glClearColor (1.0f, 1.0f, 1.0f, 1.0f); | |
839 | toClear |= GL_DEPTH_BUFFER_BIT; | |
840 | } | |
841 | else | |
842 | { | |
843 | glClearColor (myBgColor.rgb[0], myBgColor.rgb[1], myBgColor.rgb[2], 0.0f); | |
844 | } | |
679ecdee | 845 | } |
846 | glClear (toClear); | |
847 | ||
848 | Handle(OpenGl_Workspace) aWS (this); | |
a1954302 | 849 | myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer, Standard_False); |
679ecdee | 850 | |
851 | // swap the buffers | |
852 | if (theToSwap) | |
853 | { | |
854 | GetGlContext()->SwapBuffers(); | |
855 | myBackBufferRestored = Standard_False; | |
856 | myIsImmediateDrawn = Standard_False; | |
857 | } | |
858 | else | |
859 | { | |
a89742cf | 860 | glFlush(); // |
861 | myBackBufferRestored = Standard_True;// | |
862 | myIsImmediateDrawn = Standard_False;// | |
679ecdee | 863 | } |
864 | } | |
865 | ||
866 | // ======================================================================= | |
867 | // function : copyBackToFront | |
868 | // purpose : | |
869 | // ======================================================================= | |
870 | void OpenGl_Workspace::copyBackToFront() | |
871 | { | |
ca3c13d1 | 872 | #if !defined(GL_ES_VERSION_2_0) |
ca3c13d1 | 873 | |
c827ea3a | 874 | OpenGl_Mat4 aProjectMat; |
875 | OpenGl_Utils::Ortho2D<Standard_ShortReal> (aProjectMat, | |
876 | 0.f, static_cast<GLfloat> (myWidth), 0.f, static_cast<GLfloat> (myHeight)); | |
877 | ||
878 | myGlContext->WorldViewState.Push(); | |
879 | myGlContext->ProjectionState.Push(); | |
880 | ||
881 | myGlContext->WorldViewState.SetIdentity(); | |
882 | myGlContext->ProjectionState.SetCurrent (aProjectMat); | |
883 | ||
884 | myGlContext->ApplyProjectionMatrix(); | |
885 | myGlContext->ApplyWorldViewMatrix(); | |
679ecdee | 886 | |
887 | DisableFeatures(); | |
888 | ||
889 | glDrawBuffer (GL_FRONT); | |
890 | glReadBuffer (GL_BACK); | |
891 | ||
892 | glRasterPos2i (0, 0); | |
893 | glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_COLOR); | |
a1954302 | 894 | //glCopyPixels (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH); |
679ecdee | 895 | |
896 | EnableFeatures(); | |
897 | ||
c827ea3a | 898 | myGlContext->WorldViewState.Pop(); |
899 | myGlContext->ProjectionState.Pop(); | |
900 | myGlContext->ApplyProjectionMatrix(); | |
679ecdee | 901 | glDrawBuffer (GL_BACK); |
902 | ||
ca3c13d1 | 903 | #endif |
679ecdee | 904 | myIsImmediateDrawn = Standard_False; |
905 | } | |
906 | ||
907 | // ======================================================================= | |
908 | // function : DisplayCallback | |
909 | // purpose : | |
910 | // ======================================================================= | |
911 | void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView, | |
912 | Standard_Integer theReason) | |
913 | { | |
914 | if (theCView.GDisplayCB == NULL) | |
915 | { | |
916 | return; | |
917 | } | |
918 | ||
919 | Aspect_GraphicCallbackStruct aCallData; | |
920 | aCallData.reason = theReason; | |
921 | aCallData.glContext = GetGlContext(); | |
922 | aCallData.wsID = theCView.WsId; | |
923 | aCallData.viewID = theCView.ViewId; | |
924 | theCView.GDisplayCB (theCView.DefWindow.XWindow, theCView.GClientData, &aCallData); | |
925 | } | |
926 | ||
927 | // ======================================================================= | |
928 | // function : RedrawImmediate | |
929 | // purpose : | |
930 | // ======================================================================= | |
931 | void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView, | |
932 | const Aspect_CLayer2d& theCUnderLayer, | |
933 | const Aspect_CLayer2d& theCOverLayer, | |
b86bb3df | 934 | const Standard_Boolean theToForce, |
935 | OpenGl_FrameBuffer* theTargetFBO) | |
679ecdee | 936 | { |
937 | if (!Activate()) | |
938 | { | |
939 | return; | |
940 | } | |
941 | ||
942 | GLboolean isDoubleBuffer = GL_FALSE; | |
ca3c13d1 | 943 | #if !defined(GL_ES_VERSION_2_0) |
679ecdee | 944 | glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer); |
ca3c13d1 | 945 | #endif |
b86bb3df | 946 | if (!myView->HasImmediateStructures() |
947 | && !myResultFBO->IsValid()) | |
679ecdee | 948 | { |
949 | if (theToForce | |
950 | || !myIsImmediateDrawn) | |
951 | { | |
952 | myIsImmediateDrawn = Standard_False; | |
953 | return; | |
954 | } | |
955 | ||
956 | if (myBackBufferRestored | |
957 | && isDoubleBuffer) | |
958 | { | |
959 | copyBackToFront(); | |
65812bd0 | 960 | glFlush(); |
679ecdee | 961 | } |
962 | else | |
963 | { | |
964 | Redraw (theCView, theCUnderLayer, theCOverLayer); | |
965 | } | |
966 | return; | |
967 | } | |
968 | ||
b86bb3df | 969 | if (myResultFBO->IsValid() |
970 | && myGlContext->IsRender()) | |
971 | { | |
972 | if (!myBackBufferRestored) | |
973 | { | |
974 | Redraw (theCView, theCUnderLayer, theCOverLayer); | |
975 | return; | |
976 | } | |
977 | ||
978 | // clear destination before blitting | |
979 | if (theTargetFBO != NULL) | |
980 | { | |
981 | theTargetFBO->BindBuffer (myGlContext); | |
982 | } | |
983 | else | |
984 | { | |
985 | myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
986 | } | |
987 | #if !defined(GL_ES_VERSION_2_0) | |
988 | myGlContext->core20fwd->glClearDepth (1.0); | |
989 | #else | |
990 | myGlContext->core20fwd->glClearDepthf (1.0f); | |
991 | #endif | |
992 | myGlContext->core20fwd->glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | |
993 | ||
994 | /*#if !defined(GL_ES_VERSION_2_0) | |
995 | if (myGlContext->arbFBOBlit != NULL) | |
996 | { | |
997 | myResultFBO->BindReadBuffer (myGlContext); | |
998 | if (theTargetFBO != NULL) | |
999 | { | |
1000 | theTargetFBO->BindDrawBuffer (myGlContext); | |
1001 | } | |
1002 | else | |
1003 | { | |
1004 | myGlContext->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
1005 | } | |
1006 | // we don't copy stencil buffer here... does it matter for performance? | |
1007 | myGlContext->arbFBOBlit->glBlitFramebuffer (0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(), | |
1008 | 0, 0, myResultFBO->GetVPSizeX(), myResultFBO->GetVPSizeY(), | |
1009 | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); | |
1010 | ||
1011 | if (theTargetFBO != NULL) | |
1012 | { | |
1013 | theTargetFBO->BindBuffer (myGlContext); | |
1014 | } | |
1015 | else | |
1016 | { | |
1017 | myGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER); | |
1018 | } | |
1019 | } | |
1020 | else | |
1021 | #endif*/ | |
1022 | { | |
1023 | myGlContext->core20fwd->glDepthFunc (GL_ALWAYS); | |
1024 | myGlContext->core20fwd->glDepthMask (GL_TRUE); | |
1025 | myGlContext->core20fwd->glEnable (GL_DEPTH_TEST); | |
1026 | ||
1027 | DisableTexture(); | |
1028 | if (!myFullScreenQuad.IsValid()) | |
1029 | { | |
1030 | OpenGl_Vec4 aQuad[4] = | |
1031 | { | |
1032 | OpenGl_Vec4( 1.0f, -1.0f, 1.0f, 0.0f), | |
1033 | OpenGl_Vec4( 1.0f, 1.0f, 1.0f, 1.0f), | |
1034 | OpenGl_Vec4(-1.0f, -1.0f, 0.0f, 0.0f), | |
1035 | OpenGl_Vec4(-1.0f, 1.0f, 0.0f, 1.0f) | |
1036 | }; | |
1037 | myFullScreenQuad.Init (myGlContext, 4, 4, aQuad[0].GetData()); | |
1038 | } | |
1039 | ||
1040 | const Handle(OpenGl_ShaderManager)& aManager = myGlContext->ShaderManager(); | |
1041 | if (myFullScreenQuad.IsValid() | |
1042 | && aManager->BindFboBlitProgram()) | |
1043 | { | |
1044 | myResultFBO->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0); | |
1045 | myResultFBO->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1); | |
1046 | myFullScreenQuad.BindVertexAttrib (myGlContext, 0); | |
1047 | ||
1048 | myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4); | |
1049 | ||
1050 | myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0); | |
1051 | myResultFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1); | |
1052 | myResultFBO->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0); | |
1053 | } | |
1054 | } | |
1055 | } | |
1056 | else if (isDoubleBuffer && myTransientDrawToFront) | |
679ecdee | 1057 | { |
1058 | if (!myBackBufferRestored) | |
1059 | { | |
1060 | Redraw (theCView, theCUnderLayer, theCOverLayer); | |
1061 | return; | |
1062 | } | |
1063 | copyBackToFront(); | |
1064 | MakeFrontBufCurrent(); | |
1065 | } | |
1066 | else | |
1067 | { | |
1068 | myBackBufferRestored = Standard_False; | |
1069 | } | |
1070 | myIsImmediateDrawn = Standard_True; | |
1071 | ||
679ecdee | 1072 | Handle(OpenGl_Workspace) aWS (this); |
a1954302 | 1073 | |
1074 | if (myUseZBuffer) | |
1075 | { | |
1076 | glDepthFunc (GL_LEQUAL); | |
1077 | glDepthMask (GL_TRUE); | |
1078 | if (myUseDepthTest) | |
1079 | { | |
1080 | glEnable (GL_DEPTH_TEST); | |
1081 | } | |
1082 | else | |
1083 | { | |
1084 | glDisable (GL_DEPTH_TEST); | |
1085 | } | |
1086 | ||
1087 | #if !defined(GL_ES_VERSION_2_0) | |
1088 | glClearDepth (1.0); | |
1089 | #else | |
1090 | glClearDepthf (1.0f); | |
1091 | #endif | |
1092 | } | |
1093 | else | |
1094 | { | |
1095 | glDisable (GL_DEPTH_TEST); | |
1096 | } | |
1097 | ||
1098 | myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer, Standard_True); | |
1099 | if (!myView->ImmediateStructures().IsEmpty()) | |
1100 | { | |
1101 | glDisable (GL_DEPTH_TEST); | |
1102 | } | |
679ecdee | 1103 | for (OpenGl_SequenceOfStructure::Iterator anIter (myView->ImmediateStructures()); |
1104 | anIter.More(); anIter.Next()) | |
1105 | { | |
1106 | const OpenGl_Structure* aStructure = anIter.Value(); | |
a1954302 | 1107 | if (!aStructure->IsVisible()) |
1108 | { | |
1109 | continue; | |
1110 | } | |
1111 | ||
679ecdee | 1112 | aStructure->Render (aWS); |
1113 | } | |
1114 | ||
b86bb3df | 1115 | if (myResultFBO->IsValid()) |
1116 | { | |
1117 | if (theTargetFBO == NULL | |
1118 | && myGlContext->IsRender() | |
1119 | && !myGlContext->caps->buffersNoSwap) | |
1120 | { | |
1121 | myGlContext->SwapBuffers(); | |
1122 | } | |
1123 | } | |
1124 | else if (isDoubleBuffer && myTransientDrawToFront) | |
679ecdee | 1125 | { |
1126 | glFlush(); | |
1127 | MakeBackBufCurrent(); | |
1128 | } | |
1129 | } |