Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-09-20 |
2 | // Created by: Sergey ZERCHANINOV | |
3 | // Copyright (c) 2011-2012 OPEN CASCADE SAS | |
4 | // | |
5 | // The content of this file is subject to the Open CASCADE Technology Public | |
6 | // License Version 6.5 (the "License"). You may not use the content of this file | |
7 | // except in compliance with the License. Please obtain a copy of the License | |
8 | // at http://www.opencascade.org and read it completely before using this file. | |
9 | // | |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
12 | // | |
13 | // The Original Code and all software distributed under the License is | |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
15 | // Initial Developer hereby disclaims all such warranties, including without | |
16 | // limitation, any warranties of merchantability, fitness for a particular | |
17 | // purpose or non-infringement. Please see the License for the specific terms | |
18 | // and conditions governing the rights and limitations under the License. | |
19 | ||
a577aaab | 20 | #include <OpenGl_GlCore15.hxx> |
5f8b738e | 21 | |
2166f0fa SK |
22 | #include <InterfaceGraphic.hxx> |
23 | ||
2166f0fa SK |
24 | #include <OpenGl_AspectLine.hxx> |
25 | #include <OpenGl_AspectFace.hxx> | |
26 | #include <OpenGl_AspectMarker.hxx> | |
27 | #include <OpenGl_AspectText.hxx> | |
bf75be98 | 28 | #include <OpenGl_Context.hxx> |
a174a3c5 | 29 | #include <OpenGl_FrameBuffer.hxx> |
bf75be98 | 30 | #include <OpenGl_Texture.hxx> |
a174a3c5 | 31 | #include <OpenGl_Workspace.hxx> |
2166f0fa | 32 | |
bf75be98 | 33 | #include <Graphic3d_TextureParams.hxx> |
2166f0fa | 34 | |
58655684 | 35 | #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) |
a174a3c5 | 36 | #include <OpenGl_AVIWriter.hxx> |
37 | #endif | |
38 | ||
2166f0fa SK |
39 | IMPLEMENT_STANDARD_HANDLE(OpenGl_Workspace,OpenGl_Window) |
40 | IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,OpenGl_Window) | |
41 | ||
42 | namespace | |
43 | { | |
44 | static const TEL_COLOUR myDefaultHighlightColor = { { 1.F, 1.F, 1.F, 1.F } }; | |
45 | ||
46 | static const OpenGl_AspectLine myDefaultAspectLine; | |
47 | static const OpenGl_AspectFace myDefaultAspectFace; | |
48 | static const OpenGl_AspectMarker myDefaultAspectMarker; | |
49 | static const OpenGl_AspectText myDefaultAspectText; | |
50 | ||
51 | static const OpenGl_TextParam myDefaultTextParam = | |
52 | { | |
53 | 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM | |
54 | }; | |
55 | ||
56 | static const OpenGl_Matrix myDefaultMatrix = | |
57 | { | |
58 | {{ 1.0F, 0.0F, 0.0F, 0.0F }, | |
59 | { 0.0F, 1.0F, 0.0F, 0.0F }, | |
60 | { 0.0F, 0.0F, 1.0F, 0.0F }, | |
61 | { 0.0F, 0.0F, 0.0F, 1.0F }} | |
62 | }; | |
bf75be98 | 63 | |
2166f0fa SK |
64 | }; |
65 | ||
66 | // ======================================================================= | |
67 | // function : OpenGl_Workspace | |
68 | // purpose : | |
69 | // ======================================================================= | |
70 | OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_Display)& theDisplay, | |
71 | const CALL_DEF_WINDOW& theCWindow, | |
5e27df78 | 72 | Aspect_RenderingContext theGContext, |
58655684 | 73 | const Handle(OpenGl_Caps)& theCaps, |
5e27df78 | 74 | const Handle(OpenGl_Context)& theShareCtx) |
58655684 | 75 | : OpenGl_Window (theDisplay, theCWindow, theGContext, theCaps, theShareCtx), |
a174a3c5 | 76 | NamedStatus (0), |
a174a3c5 | 77 | HighlightColor (&myDefaultHighlightColor), |
78 | // | |
2166f0fa SK |
79 | myIsTransientOpen (Standard_False), |
80 | myRetainMode (Standard_False), | |
a174a3c5 | 81 | myTransientDrawToFront (Standard_True), |
2166f0fa SK |
82 | myUseTransparency (Standard_False), |
83 | myUseZBuffer (Standard_False), | |
84 | myUseDepthTest (Standard_True), | |
85 | myUseGLLight (Standard_True), | |
86 | myBackBufferRestored (Standard_False), | |
87 | // | |
2166f0fa SK |
88 | AspectLine_set (&myDefaultAspectLine), |
89 | AspectLine_applied (NULL), | |
90 | AspectFace_set (&myDefaultAspectFace), | |
91 | AspectFace_applied (NULL), | |
92 | AspectMarker_set (&myDefaultAspectMarker), | |
93 | AspectMarker_applied (NULL), | |
94 | AspectText_set (&myDefaultAspectText), | |
95 | AspectText_applied (NULL), | |
96 | TextParam_set (&myDefaultTextParam), | |
97 | TextParam_applied (NULL), | |
98 | ViewMatrix_applied (&myDefaultMatrix), | |
99 | StructureMatrix_applied (&myDefaultMatrix), | |
100 | PolygonOffset_applied (NULL) | |
101 | { | |
102 | theDisplay->InitAttributes(); | |
103 | ||
104 | // General initialization of the context | |
105 | ||
106 | // Eviter d'avoir les faces mal orientees en noir. | |
107 | // Pourrait etre utiliser pour detecter les problemes d'orientation | |
bf75be98 | 108 | glLightModeli ((GLenum )GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); |
2166f0fa SK |
109 | |
110 | // Optimisation pour le Fog et l'antialiasing | |
111 | glHint (GL_FOG_HINT, GL_FASTEST); | |
112 | glHint (GL_POINT_SMOOTH_HINT, GL_FASTEST); | |
113 | glHint (GL_LINE_SMOOTH_HINT, GL_FASTEST); | |
114 | glHint (GL_POLYGON_SMOOTH_HINT, GL_FASTEST); | |
115 | ||
116 | // Polygon Offset | |
117 | EnablePolygonOffset(); | |
118 | } | |
119 | ||
1981cb22 | 120 | // ======================================================================= |
121 | // function : SetImmediateModeDrawToFront | |
122 | // purpose : | |
123 | // ======================================================================= | |
124 | Standard_Boolean OpenGl_Workspace::SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer) | |
125 | { | |
126 | const Standard_Boolean aPrevMode = myTransientDrawToFront; | |
127 | myTransientDrawToFront = theDrawToFrontBuffer; | |
128 | return aPrevMode; | |
129 | } | |
130 | ||
2166f0fa SK |
131 | // ======================================================================= |
132 | // function : ~OpenGl_Workspace | |
133 | // purpose : | |
134 | // ======================================================================= | |
135 | OpenGl_Workspace::~OpenGl_Workspace() | |
136 | { | |
137 | } | |
138 | ||
139 | // ======================================================================= | |
140 | // function : Activate | |
141 | // purpose : | |
142 | // ======================================================================= | |
143 | Standard_Boolean OpenGl_Workspace::Activate() | |
144 | { | |
145 | if (!OpenGl_Window::Activate()) | |
146 | return Standard_False; | |
147 | ||
2166f0fa SK |
148 | ViewMatrix_applied = &myDefaultMatrix; |
149 | StructureMatrix_applied = &myDefaultMatrix; | |
26395493 | 150 | |
151 | ResetAppliedAspect(); | |
152 | ||
153 | return Standard_True; | |
2166f0fa SK |
154 | } |
155 | ||
156 | // ======================================================================= | |
157 | // function : UseTransparency | |
158 | // purpose : call_togl_transparency | |
159 | // ======================================================================= | |
160 | void OpenGl_Workspace::UseTransparency (const Standard_Boolean theFlag) | |
161 | { | |
de75ed09 | 162 | myUseTransparency = theFlag; |
2166f0fa | 163 | } |
26395493 | 164 | |
165 | //======================================================================= | |
166 | //function : ResetAppliedAspect | |
167 | //purpose : Sets default values of GL parameters in accordance with default aspects | |
168 | //======================================================================= | |
169 | void OpenGl_Workspace::ResetAppliedAspect() | |
170 | { | |
bf75be98 | 171 | NamedStatus = !myTextureBound.IsNull() ? OPENGL_NS_TEXTURE : 0; |
26395493 | 172 | HighlightColor = &myDefaultHighlightColor; |
173 | AspectLine_set = &myDefaultAspectLine; | |
174 | AspectLine_applied = NULL; | |
175 | AspectFace_set = &myDefaultAspectFace; | |
176 | AspectFace_applied = NULL; | |
177 | AspectMarker_set = &myDefaultAspectMarker; | |
178 | AspectMarker_applied = NULL; | |
179 | AspectText_set = &myDefaultAspectText; | |
180 | AspectText_applied = NULL; | |
181 | TextParam_set = &myDefaultTextParam; | |
182 | TextParam_applied = NULL; | |
183 | PolygonOffset_applied = NULL; | |
184 | ||
185 | AspectLine(Standard_True); | |
186 | AspectFace(Standard_True); | |
187 | AspectMarker(Standard_True); | |
188 | AspectText(Standard_True); | |
189 | } | |
bf75be98 | 190 | |
191 | // ======================================================================= | |
192 | // function : DisableTexture | |
193 | // purpose : | |
194 | // ======================================================================= | |
195 | Handle(OpenGl_Texture) OpenGl_Workspace::DisableTexture() | |
196 | { | |
197 | if (myTextureBound.IsNull()) | |
198 | { | |
199 | return myTextureBound; | |
200 | } | |
201 | ||
202 | // reset texture matrix because some code may expect it is identity | |
203 | GLint aMatrixMode = GL_TEXTURE; | |
204 | glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); | |
205 | glMatrixMode (GL_TEXTURE); | |
206 | glLoadIdentity(); | |
207 | glMatrixMode (aMatrixMode); | |
208 | ||
209 | myTextureBound->Unbind (myGlContext); | |
210 | switch (myTextureBound->GetTarget()) | |
211 | { | |
212 | case GL_TEXTURE_1D: | |
213 | { | |
214 | if (myTextureBound->GetParams()->GenMode() != GL_NONE) | |
215 | { | |
216 | glDisable (GL_TEXTURE_GEN_S); | |
217 | } | |
218 | glDisable (GL_TEXTURE_1D); | |
219 | break; | |
220 | } | |
221 | case GL_TEXTURE_2D: | |
222 | { | |
223 | if (myTextureBound->GetParams()->GenMode() != GL_NONE) | |
224 | { | |
225 | glDisable (GL_TEXTURE_GEN_S); | |
226 | glDisable (GL_TEXTURE_GEN_T); | |
a577aaab | 227 | if (myTextureBound->GetParams()->GenMode() == Graphic3d_TOTM_SPRITE) |
228 | { | |
229 | glDisable (GL_POINT_SPRITE); | |
230 | } | |
bf75be98 | 231 | } |
232 | glDisable (GL_TEXTURE_2D); | |
233 | break; | |
234 | } | |
235 | default: break; | |
236 | } | |
237 | ||
238 | Handle(OpenGl_Texture) aPrevTexture = myTextureBound; | |
239 | myTextureBound.Nullify(); | |
240 | return aPrevTexture; | |
241 | } | |
242 | ||
243 | // ======================================================================= | |
244 | // function : setTextureParams | |
245 | // purpose : | |
246 | // ======================================================================= | |
247 | void OpenGl_Workspace::setTextureParams (Handle(OpenGl_Texture)& theTexture, | |
248 | const Handle(Graphic3d_TextureParams)& theParams) | |
249 | { | |
250 | const Handle(Graphic3d_TextureParams)& aParams = theParams.IsNull() ? theTexture->GetParams() : theParams; | |
251 | if (aParams.IsNull()) | |
252 | { | |
253 | return; | |
254 | } | |
255 | ||
256 | GLint aMatrixMode = GL_TEXTURE; | |
257 | glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode); | |
258 | ||
259 | // setup texture matrix | |
260 | glMatrixMode (GL_TEXTURE); | |
261 | glLoadIdentity(); | |
262 | const Graphic3d_Vec2& aScale = aParams->Scale(); | |
263 | const Graphic3d_Vec2& aTrans = aParams->Translation(); | |
264 | glScalef ( aScale.x(), aScale.y(), 1.0f); | |
265 | glTranslatef (-aTrans.x(), -aTrans.y(), 0.0f); | |
266 | glRotatef (-aParams->Rotation(), 0.0f, 0.0f, 1.0f); | |
267 | ||
268 | // setup generation of texture coordinates | |
269 | switch (aParams->GenMode()) | |
270 | { | |
271 | case Graphic3d_TOTM_OBJECT: | |
272 | { | |
273 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
274 | glTexGenfv (GL_S, GL_OBJECT_PLANE, aParams->GenPlaneS().GetData()); | |
275 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
276 | { | |
277 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
278 | glTexGenfv (GL_T, GL_OBJECT_PLANE, aParams->GenPlaneT().GetData()); | |
279 | } | |
280 | break; | |
281 | } | |
282 | case Graphic3d_TOTM_SPHERE: | |
283 | { | |
284 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); | |
285 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
286 | { | |
287 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); | |
288 | } | |
289 | break; | |
290 | } | |
291 | case Graphic3d_TOTM_EYE: | |
292 | { | |
293 | glMatrixMode (GL_MODELVIEW); | |
294 | glPushMatrix(); | |
295 | glLoadIdentity(); | |
296 | ||
297 | glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); | |
298 | glTexGenfv (GL_S, GL_EYE_PLANE, aParams->GenPlaneS().GetData()); | |
299 | ||
300 | if (theTexture->GetTarget() != GL_TEXTURE_1D) | |
301 | { | |
302 | glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); | |
303 | glTexGenfv (GL_T, GL_EYE_PLANE, aParams->GenPlaneT().GetData()); | |
304 | } | |
305 | glPopMatrix(); | |
306 | break; | |
307 | } | |
a577aaab | 308 | case Graphic3d_TOTM_SPRITE: |
309 | { | |
310 | if (GetGlContext()->core20 != NULL) | |
311 | { | |
312 | glEnable (GL_POINT_SPRITE); | |
313 | glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE); | |
314 | glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | |
315 | GetGlContext()->core15->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); | |
316 | } | |
317 | break; | |
318 | } | |
bf75be98 | 319 | case Graphic3d_TOTM_MANUAL: |
320 | default: break; | |
321 | } | |
322 | ||
323 | // setup lighting | |
a577aaab | 324 | if (aParams->GenMode() != Graphic3d_TOTM_SPRITE) |
325 | { | |
326 | glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aParams->IsModulate() ? GL_MODULATE : GL_DECAL); | |
327 | } | |
bf75be98 | 328 | |
329 | // setup texture filtering and wrapping | |
330 | //if (theTexture->GetParams() != theParams) | |
331 | const GLenum aFilter = (aParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR; | |
332 | const GLenum aWrapMode = aParams->IsRepeat() ? GL_REPEAT : GL_CLAMP; | |
333 | switch (theTexture->GetTarget()) | |
334 | { | |
335 | case GL_TEXTURE_1D: | |
336 | { | |
337 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter); | |
338 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter); | |
339 | glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode); | |
340 | break; | |
341 | } | |
342 | case GL_TEXTURE_2D: | |
343 | { | |
344 | GLenum aFilterMin = aFilter; | |
345 | if (theTexture->HasMipmaps()) | |
346 | { | |
347 | aFilterMin = GL_NEAREST_MIPMAP_NEAREST; | |
348 | if (aParams->Filter() == Graphic3d_TOTF_BILINEAR) | |
349 | { | |
350 | aFilterMin = GL_LINEAR_MIPMAP_NEAREST; | |
351 | } | |
352 | else if (aParams->Filter() == Graphic3d_TOTF_TRILINEAR) | |
353 | { | |
354 | aFilterMin = GL_LINEAR_MIPMAP_LINEAR; | |
355 | } | |
356 | ||
357 | if (myGlContext->extAnis) | |
358 | { | |
359 | // setup degree of anisotropy filter | |
360 | const GLint aMaxDegree = myGlContext->MaxDegreeOfAnisotropy(); | |
361 | switch (aParams->AnisoFilter()) | |
362 | { | |
363 | case Graphic3d_LOTA_QUALITY: | |
364 | { | |
365 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aMaxDegree); | |
366 | break; | |
367 | } | |
368 | case Graphic3d_LOTA_MIDDLE: | |
369 | { | |
370 | ||
371 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (aMaxDegree <= 4) ? 2 : (aMaxDegree / 2)); | |
372 | break; | |
373 | } | |
374 | case Graphic3d_LOTA_FAST: | |
375 | { | |
376 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2); | |
377 | break; | |
378 | } | |
379 | case Graphic3d_LOTA_OFF: | |
380 | default: | |
381 | { | |
382 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); | |
383 | break; | |
384 | } | |
385 | } | |
386 | } | |
387 | } | |
388 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin); | |
389 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter); | |
390 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode); | |
391 | glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode); | |
392 | break; | |
393 | } | |
394 | default: break; | |
395 | } | |
396 | ||
397 | switch (theTexture->GetTarget()) | |
398 | { | |
399 | case GL_TEXTURE_1D: | |
400 | { | |
401 | if (aParams->GenMode() != Graphic3d_TOTM_MANUAL) | |
402 | { | |
403 | glEnable (GL_TEXTURE_GEN_S); | |
404 | } | |
405 | glEnable (GL_TEXTURE_1D); | |
406 | break; | |
407 | } | |
408 | case GL_TEXTURE_2D: | |
409 | { | |
410 | if (aParams->GenMode() != Graphic3d_TOTM_MANUAL) | |
411 | { | |
412 | glEnable (GL_TEXTURE_GEN_S); | |
413 | glEnable (GL_TEXTURE_GEN_T); | |
414 | } | |
415 | glEnable (GL_TEXTURE_2D); | |
416 | break; | |
417 | } | |
418 | default: break; | |
419 | } | |
420 | ||
421 | glMatrixMode (aMatrixMode); // turn back active matrix | |
422 | theTexture->SetParams (aParams); | |
423 | } | |
424 | ||
425 | // ======================================================================= | |
426 | // function : EnableTexture | |
427 | // purpose : | |
428 | // ======================================================================= | |
429 | Handle(OpenGl_Texture) OpenGl_Workspace::EnableTexture (const Handle(OpenGl_Texture)& theTexture, | |
430 | const Handle(Graphic3d_TextureParams)& theParams) | |
431 | { | |
432 | if (theTexture.IsNull() || !theTexture->IsValid()) | |
433 | { | |
434 | return DisableTexture(); | |
435 | } | |
436 | ||
bca1d6e2 | 437 | if (myTextureBound == theTexture |
438 | && (theParams.IsNull() || theParams == theTexture->GetParams())) | |
bf75be98 | 439 | { |
bca1d6e2 | 440 | // already bound |
441 | return myTextureBound; | |
bf75be98 | 442 | } |
443 | ||
444 | Handle(OpenGl_Texture) aPrevTexture = DisableTexture(); | |
445 | myTextureBound = theTexture; | |
446 | myTextureBound->Bind (myGlContext); | |
447 | setTextureParams (myTextureBound, theParams); | |
448 | ||
449 | return aPrevTexture; | |
450 | } | |
a174a3c5 | 451 | |
452 | // ======================================================================= | |
453 | // function : Redraw | |
454 | // purpose : | |
455 | // ======================================================================= | |
456 | void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView, | |
457 | const Aspect_CLayer2d& theCUnderLayer, | |
458 | const Aspect_CLayer2d& theCOverLayer) | |
459 | { | |
460 | if (!Activate()) | |
461 | { | |
462 | return; | |
463 | } | |
464 | ||
465 | // release pending GL resources | |
466 | Handle(OpenGl_Context) aGlCtx = GetGlContext(); | |
467 | aGlCtx->ReleaseDelayed(); | |
468 | ||
469 | // cache render mode state | |
470 | GLint aRendMode = GL_RENDER; | |
471 | glGetIntegerv (GL_RENDER_MODE, &aRendMode); | |
472 | aGlCtx->SetFeedback (aRendMode == GL_FEEDBACK); | |
473 | ||
474 | Tint toSwap = (aRendMode == GL_RENDER); // swap buffers | |
475 | GLint aViewPortBack[4]; | |
476 | OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO; | |
477 | if (aFrameBuffer != NULL) | |
478 | { | |
479 | glGetIntegerv (GL_VIEWPORT, aViewPortBack); | |
480 | aFrameBuffer->SetupViewport(); | |
481 | aFrameBuffer->BindBuffer (aGlCtx); | |
482 | toSwap = 0; // no need to swap buffers | |
483 | } | |
484 | ||
485 | Redraw1 (theCView, theCUnderLayer, theCOverLayer, toSwap); | |
486 | if (aFrameBuffer == NULL || !myTransientDrawToFront) | |
487 | { | |
488 | RedrawImmediatMode(); | |
489 | } | |
490 | ||
491 | if (aFrameBuffer != NULL) | |
492 | { | |
493 | aFrameBuffer->UnbindBuffer (aGlCtx); | |
494 | // move back original viewport | |
495 | glViewport (aViewPortBack[0], aViewPortBack[1], aViewPortBack[2], aViewPortBack[3]); | |
496 | } | |
497 | ||
498 | #if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE) | |
499 | if (OpenGl_AVIWriter_AllowWriting (theCView.DefWindow.XWindow)) | |
500 | { | |
501 | GLint params[4]; | |
502 | glGetIntegerv (GL_VIEWPORT, params); | |
503 | int nWidth = params[2] & ~0x7; | |
504 | int nHeight = params[3] & ~0x7; | |
505 | ||
506 | const int nBitsPerPixel = 24; | |
507 | GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8]; | |
508 | ||
509 | glPixelStorei (GL_PACK_ALIGNMENT, 1); | |
510 | glReadPixels (0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData); | |
511 | OpenGl_AVIWriter_AVIWriter (aDumpData, nWidth, nHeight, nBitsPerPixel); | |
512 | delete[] aDumpData; | |
513 | } | |
514 | #endif | |
515 | ||
516 | // reset render mode state | |
517 | aGlCtx->SetFeedback (Standard_False); | |
518 | } |