0032508: Visualization - OpenGl_FrameBuffer::InitWrapper() should not fail on wrappin...
[occt.git] / src / OpenGl / OpenGl_FrameBuffer.cxx
1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2011-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <OpenGl_FrameBuffer.hxx>
16
17 #include <OpenGl_ArbFBO.hxx>
18 #include <OpenGl_Context.hxx>
19 #include <OpenGl_Texture.hxx>
20
21 #include <Standard_Assert.hxx>
22 #include <TCollection_ExtendedString.hxx>
23
24 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer,OpenGl_Resource)
25
26 namespace
27 {
28   //! Checks whether two format arrays are equal or not.
29   static bool operator== (const OpenGl_ColorFormats& theFmt1,
30                           const OpenGl_ColorFormats& theFmt2)
31   {
32     if (theFmt1.Length() != theFmt2.Length())
33       return false;
34     OpenGl_ColorFormats::Iterator anIt1 (theFmt1);
35     OpenGl_ColorFormats::Iterator anIt2 (theFmt1);
36     for (; anIt1.More(); anIt1.Next(), anIt2.Next())
37     {
38       if (anIt1.Value() != anIt2.Value())
39         return false;
40     }
41     return true;
42   }
43
44   //! Return TRUE if GL_DEPTH_STENCIL_ATTACHMENT can be used.
45   static bool hasDepthStencilAttach (const Handle(OpenGl_Context)& theCtx)
46   {
47   #ifdef __EMSCRIPTEN__
48     // supported since WebGL 2.0,
49     // while WebGL 1.0 + GL_WEBGL_depth_texture needs GL_DEPTH_STENCIL_ATTACHMENT
50     // and NOT separate GL_DEPTH_ATTACHMENT+GL_STENCIL_ATTACHMENT calls which is different to OpenGL ES 2.0 + extension
51     return theCtx->IsGlGreaterEqual (3, 0) || theCtx->extPDS;
52   #elif defined(GL_ES_VERSION_2_0)
53     // supported since OpenGL ES 3.0,
54     // while OpenGL ES 2.0 + GL_EXT_packed_depth_stencil needs separate GL_DEPTH_ATTACHMENT+GL_STENCIL_ATTACHMENT calls
55     return theCtx->IsGlGreaterEqual (3, 0);
56   #else
57     // available on desktop since OpenGL 3.0
58     // or OpenGL 2.0 + GL_ARB_framebuffer_object (GL_EXT_framebuffer_object is unsupported by OCCT)
59     (void )theCtx;
60     return true;
61   #endif
62   }
63 }
64
65 // =======================================================================
66 // function : OpenGl_FrameBuffer
67 // purpose  :
68 // =======================================================================
69 OpenGl_FrameBuffer::OpenGl_FrameBuffer()
70 : myInitVPSizeX (0),
71   myInitVPSizeY (0),
72   myVPSizeX (0),
73   myVPSizeY (0),
74   myNbSamples (0),
75   myDepthFormat (GL_DEPTH24_STENCIL8),
76   myGlFBufferId (NO_FRAMEBUFFER),
77   myGlColorRBufferId (NO_RENDERBUFFER),
78   myGlDepthRBufferId (NO_RENDERBUFFER),
79   myIsOwnBuffer (false),
80   myIsOwnColor  (false),
81   myIsOwnDepth  (false),
82   myDepthStencilTexture (new OpenGl_Texture())
83 {
84   myColorFormats.Append (GL_RGBA8);
85   myColorTextures.Append (new OpenGl_Texture());
86 }
87
88 // =======================================================================
89 // function : ~OpenGl_FrameBuffer
90 // purpose  :
91 // =======================================================================
92 OpenGl_FrameBuffer::~OpenGl_FrameBuffer()
93 {
94   Release (NULL);
95 }
96
97 // =======================================================================
98 // function : GetSizeX
99 // purpose  :
100 // =======================================================================
101 Standard_Integer OpenGl_FrameBuffer::GetSizeX() const
102 {
103   return !myColorTextures.IsEmpty() ? myColorTextures.First()->SizeX() : 0;
104 }
105
106 // =======================================================================
107 // function : GetSizeY
108 // purpose  :
109 // =======================================================================
110 Standard_Integer OpenGl_FrameBuffer::GetSizeY() const
111 {
112   return !myColorTextures.IsEmpty() ? myColorTextures.First()->SizeY() : 0;
113 }
114
115 // =======================================================================
116 // function : InitWrapper
117 // purpose  :
118 // =======================================================================
119 Standard_Boolean OpenGl_FrameBuffer::InitWrapper (const Handle(OpenGl_Context)& theGlContext,
120                                                   const NCollection_Sequence<Handle(OpenGl_Texture)>& theColorTextures,
121                                                   const Handle(OpenGl_Texture)& theDepthTexture)
122 {
123   Release (theGlContext.get());
124   if (theGlContext->arbFBO == NULL)
125   {
126     return false;
127   }
128
129   myColorFormats.Clear();
130   myColorTextures.Clear();
131   for (NCollection_Sequence<Handle(OpenGl_Texture)>::Iterator aColorIter (theColorTextures); aColorIter.More(); aColorIter.Next())
132   {
133     myColorTextures.Append (aColorIter.Value());
134   }
135   myDepthFormat = 0;
136   myDepthStencilTexture = theDepthTexture;
137   myNbSamples = theColorTextures.First()->NbSamples();
138
139   myIsOwnColor  = false;
140   myIsOwnDepth  = false;
141   myIsOwnBuffer = true;
142
143   myVPSizeX = theColorTextures.First()->SizeX();
144   myVPSizeY = theColorTextures.First()->SizeY();
145
146   theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
147   theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
148   for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
149   {
150     const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
151     if (aColorTexture->IsValid())
152     {
153       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + aColorBufferIdx,
154                                                     aColorTexture->GetTarget(), aColorTexture->TextureId(), 0);
155     }
156   }
157   if (!myDepthStencilTexture.IsNull()
158     && myDepthStencilTexture->IsValid())
159   {
160     if (hasDepthStencilAttach (theGlContext))
161     {
162       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
163                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
164     }
165     else
166     {
167       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
168                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
169       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
170                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
171     }
172   }
173   if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
174   {
175     Release (theGlContext.get());
176     return false;
177   }
178
179   UnbindBuffer (theGlContext);
180   return true;
181 }
182
183 // =======================================================================
184 // function : Init
185 // purpose  :
186 // =======================================================================
187 Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
188                                            const Graphic3d_Vec2i& theSize,
189                                            const Standard_Integer theColorFormat,
190                                            const Standard_Integer theDepthFormat,
191                                            const Standard_Integer theNbSamples)
192 {
193   OpenGl_ColorFormats aColorFormats;
194   if (theColorFormat != 0)
195   {
196     aColorFormats.Append (theColorFormat);
197   }
198   return Init (theGlContext, theSize, aColorFormats, theDepthFormat, theNbSamples);
199 }
200
201 // =======================================================================
202 // function : Init
203 // purpose  :
204 // =======================================================================
205 Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
206                                            const Graphic3d_Vec2i&        theSize,
207                                            const OpenGl_ColorFormats&    theColorFormats,
208                                            const Handle(OpenGl_Texture)& theDepthStencilTexture,
209                                            const Standard_Integer        theNbSamples)
210 {
211   myColorFormats = theColorFormats;
212
213   OpenGl_TextureArray aTextures (myColorTextures);
214   if (!myColorTextures.IsEmpty())
215   {
216     for (OpenGl_TextureArray::Iterator aTextureIt (myColorTextures); aTextureIt.More(); aTextureIt.Next())
217     {
218       aTextureIt.Value()->Release (theGlContext.operator->());
219     }
220     myColorTextures.Clear();
221   }
222   for (Standard_Integer aLength = 0; aLength < myColorFormats.Length(); ++aLength)
223   {
224     myColorTextures.Append (aLength < aTextures.Length() ? aTextures.Value (aLength) : new OpenGl_Texture());
225   }
226
227   myDepthFormat = theDepthStencilTexture->GetFormat();
228   myNbSamples   = theNbSamples;
229   if (theGlContext->arbFBO == NULL)
230   {
231     return Standard_False;
232   }
233
234   // clean up previous state
235   Release (theGlContext.operator->());
236   if (myColorFormats.IsEmpty()
237    && myDepthFormat == 0)
238   {
239     return Standard_False;
240   }
241
242   myDepthStencilTexture = theDepthStencilTexture;
243   myIsOwnColor  = true;
244   myIsOwnDepth  = false;
245   myIsOwnBuffer = true;
246
247   // setup viewport sizes as is
248   myVPSizeX = theSize.x();
249   myVPSizeY = theSize.y();
250   const Standard_Integer aSizeX = theSize.x() > 0 ? theSize.x() : 2;
251   const Standard_Integer aSizeY = theSize.y() > 0 ? theSize.y() : 2;
252
253   // Create the textures (will be used as color buffer and depth-stencil buffer)
254   if (theNbSamples != 0)
255   {
256     for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
257     {
258       const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
259       const GLint                   aColorFormat  = myColorFormats  (aColorBufferIdx);
260       if (aColorFormat == 0
261       || !aColorTexture->Init2DMultisample (theGlContext, theNbSamples,
262                                             aColorFormat, aSizeX, aSizeY))
263       {
264         Release (theGlContext.get());
265         return Standard_False;
266       }
267     }
268   }
269   else
270   {
271     for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
272     {
273       const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
274       const GLint                   aColorFormat  = myColorFormats  (aColorBufferIdx);
275       const OpenGl_TextureFormat aFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, aColorFormat);
276       if (!aFormat.IsValid()
277        || !aColorTexture->Init (theGlContext, aFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TOT_2D))
278       {
279         Release (theGlContext.get());
280         return Standard_False;
281       }
282     }
283   }
284
285   // Build FBO and setup it as texture
286   theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
287   theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
288
289   for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
290   {
291     const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
292     if (aColorTexture->IsValid())
293     {
294       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + aColorBufferIdx,
295                                                     aColorTexture->GetTarget(), aColorTexture->TextureId(), 0);
296     }
297   }
298   if (myDepthStencilTexture->IsValid())
299   {
300     if (hasDepthStencilAttach (theGlContext))
301     {
302       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
303                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
304     }
305     else
306     {
307       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
308                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
309       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
310                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
311     }
312   }
313   if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
314   {
315     Release (theGlContext.operator->());
316     return Standard_False;
317   }
318
319   UnbindBuffer (theGlContext);
320   return Standard_True;
321 }
322
323 // =======================================================================
324 // function : Init
325 // purpose  :
326 // =======================================================================
327 Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
328                                            const Graphic3d_Vec2i&        theSize,
329                                            const OpenGl_ColorFormats&    theColorFormats,
330                                            const Standard_Integer        theDepthFormat,
331                                            const Standard_Integer        theNbSamples)
332 {
333   myColorFormats = theColorFormats;
334
335   OpenGl_TextureArray aTextures (myColorTextures);
336   if (!myColorTextures.IsEmpty())
337   {
338     for (OpenGl_TextureArray::Iterator aTextureIt (myColorTextures); aTextureIt.More(); aTextureIt.Next())
339     {
340       aTextureIt.Value()->Release (theGlContext.operator->());
341     }
342     myColorTextures.Clear();
343   }
344   for (Standard_Integer aLength = 0; aLength < myColorFormats.Length(); ++aLength)
345   {
346     myColorTextures.Append (aLength < aTextures.Length() ? aTextures.Value (aLength) : new OpenGl_Texture());
347   }
348
349   myDepthFormat = theDepthFormat;
350   myNbSamples   = theNbSamples;
351   myInitVPSizeX = theSize.x();
352   myInitVPSizeY = theSize.y();
353   if (theGlContext->arbFBO == NULL)
354   {
355     return Standard_False;
356   }
357
358   // clean up previous state
359   Release (theGlContext.operator->());
360   if (myColorFormats.IsEmpty()
361    && myDepthFormat == 0)
362   {
363     return Standard_False;
364   }
365
366   myIsOwnColor  = true;
367   myIsOwnBuffer = true;
368   myIsOwnDepth  = true;
369
370   // setup viewport sizes as is
371   myVPSizeX = theSize.x();
372   myVPSizeY = theSize.y();
373   const Standard_Integer aSizeX = theSize.x() > 0 ? theSize.x() : 2;
374   const Standard_Integer aSizeY = theSize.y() > 0 ? theSize.y() : 2;
375   bool hasStencilRB = false;
376
377   // Create the textures (will be used as color buffer and depth-stencil buffer)
378   if (theNbSamples != 0)
379   {
380     for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
381     {
382       const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
383       const GLint                   aColorFormat  = myColorFormats  (aColorBufferIdx);
384       if (aColorFormat == 0
385       || !aColorTexture->Init2DMultisample (theGlContext, theNbSamples, aColorFormat, aSizeX, aSizeY))
386       {
387         Release (theGlContext.operator->());
388         return Standard_False;
389       }
390     }
391     if (myDepthFormat != 0
392     && !myDepthStencilTexture->Init2DMultisample (theGlContext, theNbSamples, myDepthFormat, aSizeX, aSizeY))
393     {
394       Release (theGlContext.operator->());
395       return Standard_False;
396     }
397   }
398   else
399   {
400     for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
401     {
402       const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
403       const GLint                   aColorFormat  = myColorFormats  (aColorBufferIdx);
404       const OpenGl_TextureFormat aFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, aColorFormat);
405       if (!aFormat.IsValid()
406        || !aColorTexture->Init (theGlContext, aFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TOT_2D))
407       {
408         Release (theGlContext.operator->());
409         return Standard_False;
410       }
411     }
412
413     // extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats
414     // instead of just trying to create such texture
415     const OpenGl_TextureFormat aDepthFormat = OpenGl_TextureFormat::FindSizedFormat (theGlContext, myDepthFormat);
416     if (aDepthFormat.IsValid()
417     && !myDepthStencilTexture->Init (theGlContext, aDepthFormat, Graphic3d_Vec2i (aSizeX, aSizeY), Graphic3d_TOT_2D))
418     {
419       theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
420                                  "Warning! Depth textures are not supported by hardware!");
421
422       hasStencilRB = aDepthFormat.PixelFormat() == GL_DEPTH_STENCIL
423                   && theGlContext->extPDS;
424       GLint aDepthStencilFormat = hasStencilRB
425                                 ? GL_DEPTH24_STENCIL8
426                                 : GL_DEPTH_COMPONENT16;
427
428       theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
429       theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
430       theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, aDepthStencilFormat, aSizeX, aSizeY);
431       theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
432     }
433   }
434
435   // Build FBO and setup it as texture
436   theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
437   theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
438   for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
439   {
440     const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
441     if (aColorTexture->IsValid())
442     {
443       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + aColorBufferIdx,
444                                                     aColorTexture->GetTarget(), aColorTexture->TextureId(), 0);
445     }
446   }
447
448   if (myDepthStencilTexture->IsValid())
449   {
450     if (hasDepthStencilAttach (theGlContext))
451     {
452       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
453                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
454     }
455     else
456     {
457       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
458                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
459       theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
460                                                     myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
461     }
462   }
463   else if (myGlDepthRBufferId != NO_RENDERBUFFER)
464   {
465     if (hasDepthStencilAttach (theGlContext) && hasStencilRB)
466     {
467       theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
468                                                        GL_RENDERBUFFER, myGlDepthRBufferId);
469     }
470     else
471     {
472       theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
473                                                        GL_RENDERBUFFER, myGlDepthRBufferId);
474       if (hasStencilRB)
475       {
476         theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
477                                                          GL_RENDERBUFFER, myGlDepthRBufferId);
478       }
479     }
480   }
481   if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
482   {
483     Release (theGlContext.operator->());
484     return Standard_False;
485   }
486
487   UnbindBuffer (theGlContext);
488   return Standard_True;
489 }
490
491 // =======================================================================
492 // function : InitLazy
493 // purpose  :
494 // =======================================================================
495 Standard_Boolean OpenGl_FrameBuffer::InitLazy (const Handle(OpenGl_Context)& theGlContext,
496                                                const Graphic3d_Vec2i& theViewportSize,
497                                                const Standard_Integer theColorFormat,
498                                                const Standard_Integer theDepthFormat,
499                                                const Standard_Integer theNbSamples)
500 {
501   OpenGl_ColorFormats aColorFormats;
502   aColorFormats.Append (theColorFormat);
503   return InitLazy (theGlContext, theViewportSize, aColorFormats, theDepthFormat, theNbSamples);
504 }
505
506 // =======================================================================
507 // function : InitLazy
508 // purpose  :
509 // =======================================================================
510 Standard_Boolean OpenGl_FrameBuffer::InitLazy (const Handle(OpenGl_Context)& theGlContext,
511                                                const Graphic3d_Vec2i&        theViewportSize,
512                                                const OpenGl_ColorFormats&    theColorFormats,
513                                                const Standard_Integer        theDepthFormat,
514                                                const Standard_Integer        theNbSamples)
515 {
516   if (myVPSizeX      == theViewportSize.x()
517    && myVPSizeY      == theViewportSize.y()
518    && myColorFormats == theColorFormats
519    && myDepthFormat  == theDepthFormat
520    && myNbSamples    == theNbSamples)
521   {
522     return IsValid();
523   }
524
525   return Init (theGlContext, theViewportSize, theColorFormats, theDepthFormat, theNbSamples);
526 }
527
528 // =======================================================================
529 // function : InitWithRB
530 // purpose  :
531 // =======================================================================
532 Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& theGlCtx,
533                                                  const Graphic3d_Vec2i& theSize,
534                                                  const Standard_Integer theColorFormat,
535                                                  const Standard_Integer theDepthFormat,
536                                                  const unsigned int     theColorRBufferFromWindow)
537 {
538   myColorFormats.Clear();
539   myColorFormats.Append (theColorFormat);
540   if (!myColorTextures.IsEmpty())
541   {
542     Handle(OpenGl_Texture) aTexutre = myColorTextures.First();
543     for (OpenGl_TextureArray::Iterator aTextureIt (myColorTextures); aTextureIt.More(); aTextureIt.Next())
544     {
545       aTextureIt.Value()->Release (theGlCtx.operator->());
546     }
547     myColorTextures.Clear();
548     myColorTextures.Append (aTexutre);
549   }
550
551   myDepthFormat = theDepthFormat;
552   myNbSamples   = 0;
553   myInitVPSizeX = theSize.x();
554   myInitVPSizeY = theSize.y();
555   if (theGlCtx->arbFBO == NULL)
556   {
557     return Standard_False;
558   }
559
560   // clean up previous state
561   Release (theGlCtx.operator->());
562
563   myIsOwnColor  = true;
564   myIsOwnBuffer = true;
565   myIsOwnDepth  = true;
566
567   // setup viewport sizes as is
568   myVPSizeX = theSize.x();
569   myVPSizeY = theSize.y();
570   const Standard_Integer aSizeX = theSize.x() > 0 ? theSize.x() : 2;
571   const Standard_Integer aSizeY = theSize.y() > 0 ? theSize.y() : 2;
572
573   // Create the render-buffers
574   if (theColorRBufferFromWindow != NO_RENDERBUFFER)
575   {
576     myGlColorRBufferId = theColorRBufferFromWindow;
577   }
578   else if (theColorFormat != 0)
579   {
580     theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlColorRBufferId);
581     theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlColorRBufferId);
582     theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, theColorFormat, aSizeX, aSizeY);
583   }
584
585   bool hasStencilRB = false;
586   if (myDepthFormat != 0)
587   {
588     const OpenGl_TextureFormat aDepthFormat = OpenGl_TextureFormat::FindSizedFormat (theGlCtx, myDepthFormat);
589     hasStencilRB = aDepthFormat.PixelFormat() == GL_DEPTH_STENCIL;
590
591     theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
592     theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
593     theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, myDepthFormat, aSizeX, aSizeY);
594     theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
595   }
596
597   // create FBO
598   theGlCtx->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
599   theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
600   theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
601                                                GL_RENDERBUFFER, myGlColorRBufferId);
602   if (myGlDepthRBufferId != NO_RENDERBUFFER)
603   {
604     if (hasDepthStencilAttach (theGlCtx) && hasStencilRB)
605     {
606       theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
607                                                    GL_RENDERBUFFER, myGlDepthRBufferId);
608     }
609     else
610     {
611       theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
612                                                    GL_RENDERBUFFER, myGlDepthRBufferId);
613       if (hasStencilRB)
614       {
615         theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
616                                                      GL_RENDERBUFFER, myGlDepthRBufferId);
617       }
618     }
619   }
620   if (theGlCtx->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
621   {
622     UnbindBuffer (theGlCtx);
623     Release (theGlCtx.operator->());
624     return Standard_False;
625   }
626
627   UnbindBuffer (theGlCtx);
628   return Standard_True;
629 }
630
631 // =======================================================================
632 // function : InitWrapper
633 // purpose  :
634 // =======================================================================
635 Standard_Boolean OpenGl_FrameBuffer::InitWrapper (const Handle(OpenGl_Context)& theGlCtx)
636 {
637   myNbSamples = 0;
638   if (theGlCtx->arbFBO == NULL)
639   {
640     return Standard_False;
641   }
642
643   // clean up previous state
644   Release (theGlCtx.operator->());
645
646   GLint anFbo = GLint(NO_FRAMEBUFFER);
647   theGlCtx->core11fwd->glGetIntegerv (GL_FRAMEBUFFER_BINDING, &anFbo);
648   if (anFbo == GLint(NO_FRAMEBUFFER))
649   {
650     return Standard_False;
651   }
652
653   GLint aColorType = 0;
654   GLint aColorId   = 0;
655   GLint aDepthType = 0;
656   GLint aDepthId   = 0;
657   theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &aColorType);
658   theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,  GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &aDepthType);
659
660   myGlFBufferId = GLuint(anFbo);
661   myIsOwnColor  = false;
662   myIsOwnBuffer = false;
663   myIsOwnDepth  = false;
664   if (aColorType == GL_RENDERBUFFER)
665   {
666     theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &aColorId);
667     myGlColorRBufferId = aColorId;
668   }
669   else if (aColorType == GL_TEXTURE)
670   {
671     // myColorTextures[0]->InitWrapper() - not implemented, just skip it
672   }
673   else if (aColorType != GL_NONE)
674   {
675     theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
676                            "OpenGl_FrameBuffer::InitWrapper(), color attachment of unsupported type has been skipped!");
677   }
678
679   if (aDepthType == GL_RENDERBUFFER)
680   {
681     theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,  GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &aDepthId);
682     myGlDepthRBufferId = aDepthId;
683   }
684   else if (aDepthType == GL_TEXTURE)
685   {
686     // myDepthStencilTexture->InitWrapper() - not implemented, just skip it
687   }
688   else if (aDepthType != GL_NONE)
689   {
690     theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
691                            "OpenGl_FrameBuffer::InitWrapper(), depth attachment of unsupported type has been skipped!");
692   }
693
694   // retrieve dimensions
695   GLuint aRBuffer = myGlColorRBufferId != NO_RENDERBUFFER ? myGlColorRBufferId : myGlDepthRBufferId;
696   if (aRBuffer != NO_RENDERBUFFER)
697   {
698     theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, aRBuffer);
699     theGlCtx->arbFBO->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH,  &myInitVPSizeX);
700     theGlCtx->arbFBO->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &myInitVPSizeY);
701     theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
702   }
703
704   GLint aViewport[4] = {};
705   theGlCtx->core11fwd->glGetIntegerv (GL_VIEWPORT, aViewport);
706   myVPSizeX = aViewport[2];
707   myVPSizeY = aViewport[3];
708   return Standard_True;
709 }
710
711 // =======================================================================
712 // function : Release
713 // purpose  :
714 // =======================================================================
715 void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx)
716 {
717   if (isValidFrameBuffer())
718   {
719     // application can not handle this case by exception - this is bug in code
720     Standard_ASSERT_RETURN (!myIsOwnBuffer || theGlCtx != NULL,
721       "OpenGl_FrameBuffer destroyed without GL context! Possible GPU memory leakage...",);
722     if (myIsOwnBuffer
723      && theGlCtx->IsValid())
724     {
725       theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId);
726       if (myGlColorRBufferId != NO_RENDERBUFFER)
727       {
728         theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlColorRBufferId);
729       }
730       if (myGlDepthRBufferId != NO_RENDERBUFFER)
731       {
732         theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlDepthRBufferId);
733       }
734     }
735     myGlFBufferId      = NO_FRAMEBUFFER;
736     myGlColorRBufferId = NO_RENDERBUFFER;
737     myGlDepthRBufferId = NO_RENDERBUFFER;
738     myIsOwnBuffer      = false;
739   }
740
741   if (myIsOwnColor)
742   {
743     for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
744     {
745       myColorTextures (aColorBufferIdx)->Release (theGlCtx);
746     }
747     myIsOwnColor = false;
748   }
749
750   if (myIsOwnDepth)
751   {
752     myDepthStencilTexture->Release (theGlCtx);
753     myIsOwnDepth = false;
754   }
755
756   myVPSizeX = 0;
757   myVPSizeY = 0;
758 }
759
760 // =======================================================================
761 // function : SetupViewport
762 // purpose  :
763 // =======================================================================
764 void OpenGl_FrameBuffer::SetupViewport (const Handle(OpenGl_Context)& theGlCtx)
765 {
766   const Standard_Integer aViewport[4] = { 0, 0, myVPSizeX, myVPSizeY };
767   theGlCtx->ResizeViewport (aViewport);
768 }
769
770 // =======================================================================
771 // function : ChangeViewport
772 // purpose  :
773 // =======================================================================
774 void OpenGl_FrameBuffer::ChangeViewport (const Standard_Integer theVPSizeX,
775                                          const Standard_Integer theVPSizeY)
776 {
777   myVPSizeX = theVPSizeX;
778   myVPSizeY = theVPSizeY;
779 }
780
781 // =======================================================================
782 // function : BindBuffer
783 // purpose  :
784 // =======================================================================
785 void OpenGl_FrameBuffer::BindBuffer (const Handle(OpenGl_Context)& theGlCtx)
786 {
787   theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
788   theGlCtx->SetFrameBufferSRGB (true);
789 }
790
791 // =======================================================================
792 // function : BindDrawBuffer
793 // purpose  :
794 // =======================================================================
795 void OpenGl_FrameBuffer::BindDrawBuffer (const Handle(OpenGl_Context)& theGlCtx)
796 {
797   theGlCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myGlFBufferId);
798   theGlCtx->SetFrameBufferSRGB (true);
799 }
800
801 // =======================================================================
802 // function : BindReadBuffer
803 // purpose  :
804 // =======================================================================
805 void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx)
806 {
807   theGlCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, myGlFBufferId);
808 }
809
810 // =======================================================================
811 // function : UnbindBuffer
812 // purpose  :
813 // =======================================================================
814 void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx)
815 {
816   if (!theGlCtx->DefaultFrameBuffer().IsNull()
817    &&  theGlCtx->DefaultFrameBuffer().operator->() != this)
818   {
819     theGlCtx->DefaultFrameBuffer()->BindBuffer (theGlCtx);
820   }
821   else
822   {
823     theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER);
824     theGlCtx->SetFrameBufferSRGB (false);
825   }
826 }
827
828 // =======================================================================
829 // function : getAligned
830 // purpose  :
831 // =======================================================================
832 inline Standard_Size getAligned (const Standard_Size theNumber,
833                                  const Standard_Size theAlignment)
834 {
835   return theNumber + theAlignment - 1 - (theNumber - 1) % theAlignment;
836 }
837
838 template<typename T>
839 inline void convertRowFromRgba (T* theRgbRow,
840                                 const Image_ColorRGBA* theRgbaRow,
841                                 const Standard_Size theWidth)
842 {
843   for (Standard_Size aCol = 0; aCol < theWidth; ++aCol)
844   {
845     const Image_ColorRGBA& anRgba = theRgbaRow[aCol];
846     T& anRgb = theRgbRow[aCol];
847     anRgb.r() = anRgba.r();
848     anRgb.g() = anRgba.g();
849     anRgb.b() = anRgba.b();
850   }
851 }
852
853 // =======================================================================
854 // function : BufferDump
855 // purpose  :
856 // =======================================================================
857 Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& theGlCtx,
858                                                  const Handle(OpenGl_FrameBuffer)& theFbo,
859                                                  Image_PixMap& theImage,
860                                                  Graphic3d_BufferType theBufferType)
861 {
862   if (theGlCtx.IsNull()
863    || theImage.IsEmpty())
864   {
865     return Standard_False;
866   }
867
868   GLenum aFormat = 0;
869   GLenum aType   = 0;
870   bool toSwapRgbaBgra = false;
871   bool toConvRgba2Rgb = false;
872   switch (theImage.Format())
873   {
874   #if !defined(GL_ES_VERSION_2_0)
875     case Image_Format_Gray:
876       aFormat = theBufferType == Graphic3d_BT_Depth ? GL_DEPTH_COMPONENT : GL_RED;
877       aType   = GL_UNSIGNED_BYTE;
878       break;
879     case Image_Format_GrayF:
880       aFormat = theBufferType == Graphic3d_BT_Depth ? GL_DEPTH_COMPONENT : GL_RED;
881       aType   = GL_FLOAT;
882       break;
883     case Image_Format_RGF:
884       aFormat = GL_RG;
885       aType   = GL_FLOAT;
886       break;
887     case Image_Format_RGB:
888       aFormat = GL_RGB;
889       aType   = GL_UNSIGNED_BYTE;
890       break;
891     case Image_Format_BGR:
892       aFormat = GL_BGR;
893       aType   = GL_UNSIGNED_BYTE;
894       break;
895     case Image_Format_BGRA:
896     case Image_Format_BGR32:
897       aFormat = GL_BGRA;
898       aType   = GL_UNSIGNED_BYTE;
899       break;
900     case Image_Format_BGRF:
901       aFormat = GL_BGR;
902       aType   = GL_FLOAT;
903       break;
904     case Image_Format_BGRAF:
905       aFormat = GL_BGRA;
906       aType   = GL_FLOAT;
907       break;
908   #else
909     case Image_Format_Gray:
910     case Image_Format_GrayF:
911     case Image_Format_BGRF:
912     case Image_Format_BGRAF:
913     case Image_Format_RGF:
914       return Standard_False;
915     case Image_Format_BGRA:
916     case Image_Format_BGR32:
917       aFormat = GL_RGBA;
918       aType   = GL_UNSIGNED_BYTE;
919       toSwapRgbaBgra = true;
920       break;
921     case Image_Format_BGR:
922     case Image_Format_RGB:
923       aFormat = GL_RGBA;
924       aType   = GL_UNSIGNED_BYTE;
925       toConvRgba2Rgb = true;
926       break;
927   #endif
928     case Image_Format_RGBA:
929     case Image_Format_RGB32:
930       aFormat = GL_RGBA;
931       aType   = GL_UNSIGNED_BYTE;
932       break;
933     case Image_Format_RGBF:
934       aFormat = GL_RGB;
935       aType   = GL_FLOAT;
936       break;
937     case Image_Format_RGBAF:
938       aFormat = GL_RGBA;
939       aType   = GL_FLOAT;
940       break;
941     case Image_Format_RGBAF_half:
942       aFormat = GL_RGBA;
943       aType   = GL_HALF_FLOAT;
944       break;
945     case Image_Format_Alpha:
946     case Image_Format_AlphaF:
947       return Standard_False; // GL_ALPHA is no more supported in core context
948     case Image_Format_RGF_half:
949     case Image_Format_UNKNOWN:
950       return Standard_False;
951   }
952
953   if (aFormat == 0)
954   {
955     return Standard_False;
956   }
957
958 #if !defined(GL_ES_VERSION_2_0)
959   GLint aReadBufferPrev = GL_BACK;
960   if (theBufferType == Graphic3d_BT_Depth
961    && aFormat != GL_DEPTH_COMPONENT)
962   {
963     return Standard_False;
964   }
965 #else
966   (void )theBufferType;
967 #endif
968
969   // bind FBO if used
970   if (!theFbo.IsNull() && theFbo->IsValid())
971   {
972     theFbo->BindBuffer (theGlCtx);
973   }
974   else
975   {
976   #if !defined(GL_ES_VERSION_2_0)
977     theGlCtx->core11fwd->glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
978     GLint aDrawBufferPrev = GL_BACK;
979     theGlCtx->core11fwd->glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
980     glReadBuffer (aDrawBufferPrev);
981   #endif
982   }
983
984   // setup alignment
985   const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
986   theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
987   bool isBatchCopy = !theImage.IsTopDown();
988
989   const GLint   anExtraBytes       = GLint(theImage.RowExtraBytes());
990   GLint         aPixelsWidth       = GLint(theImage.SizeRowBytes() / theImage.SizePixelBytes());
991   Standard_Size aSizeRowBytesEstim = getAligned (theImage.SizePixelBytes() * aPixelsWidth, anAligment);
992   if (anExtraBytes < anAligment)
993   {
994     aPixelsWidth = 0;
995   }
996   else if (aSizeRowBytesEstim != theImage.SizeRowBytes())
997   {
998     aPixelsWidth = 0;
999     isBatchCopy  = false;
1000   }
1001   if (theGlCtx->hasPackRowLength)
1002   {
1003     theGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
1004   }
1005   else if (aPixelsWidth != 0)
1006   {
1007     isBatchCopy = false;
1008   }
1009
1010   if (toConvRgba2Rgb)
1011   {
1012     const Standard_Size aRowSize = theImage.SizeX() * 4;
1013     NCollection_Buffer aRowBuffer (Image_PixMap::DefaultAllocator());
1014     if (!aRowBuffer.Allocate (aRowSize))
1015     {
1016       return Standard_False;
1017     }
1018
1019     for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1020     {
1021       // Image_PixMap rows indexation always starts from the upper corner
1022       // while order in memory depends on the flag and processed by ChangeRow() method
1023       theGlCtx->core11fwd->glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, aRowBuffer.ChangeData());
1024       const Image_ColorRGBA* aRowDataRgba = (const Image_ColorRGBA* )aRowBuffer.Data();
1025       if (theImage.Format() == Image_Format_BGR)
1026       {
1027         convertRowFromRgba ((Image_ColorBGR* )theImage.ChangeRow (aRow), aRowDataRgba, theImage.SizeX());
1028       }
1029       else
1030       {
1031         convertRowFromRgba ((Image_ColorRGB* )theImage.ChangeRow (aRow), aRowDataRgba, theImage.SizeX());
1032       }
1033     }
1034   }
1035   else if (!isBatchCopy)
1036   {
1037     // copy row by row
1038     for (Standard_Size aRow = 0; aRow < theImage.SizeY(); ++aRow)
1039     {
1040       // Image_PixMap rows indexation always starts from the upper corner
1041       // while order in memory depends on the flag and processed by ChangeRow() method
1042       theGlCtx->core11fwd->glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
1043     }
1044   }
1045   else
1046   {
1047     theGlCtx->core11fwd->glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
1048   }
1049   const bool hasErrors = theGlCtx->ResetErrors (true);
1050
1051   theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, 1);
1052   if (theGlCtx->hasPackRowLength)
1053   {
1054     theGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0);
1055   }
1056
1057   if (!theFbo.IsNull() && theFbo->IsValid())
1058   {
1059     theFbo->UnbindBuffer (theGlCtx);
1060   }
1061   else
1062   {
1063   #if !defined(GL_ES_VERSION_2_0)
1064     glReadBuffer (aReadBufferPrev);
1065   #endif
1066   }
1067
1068   if (toSwapRgbaBgra)
1069   {
1070     Image_PixMap::SwapRgbaBgra (theImage);
1071   }
1072
1073   return !hasErrors;
1074 }
1075
1076 // =======================================================================
1077 // function : EstimatedDataSize
1078 // purpose  :
1079 // =======================================================================
1080 Standard_Size OpenGl_FrameBuffer::EstimatedDataSize() const
1081 {
1082   if (!IsValid())
1083   {
1084     return 0;
1085   }
1086
1087   Standard_Size aSize = 0;
1088   for (OpenGl_TextureArray::Iterator aTextureIt (myColorTextures); aTextureIt.More(); aTextureIt.Next())
1089   {
1090     aSize += aTextureIt.Value()->EstimatedDataSize();
1091   }
1092   if (!myDepthStencilTexture.IsNull())
1093   {
1094     aSize += myDepthStencilTexture->EstimatedDataSize();
1095   }
1096   if (myGlColorRBufferId != NO_RENDERBUFFER
1097   && !myColorFormats.IsEmpty())
1098   {
1099     aSize += OpenGl_Texture::PixelSizeOfPixelFormat (myColorFormats.First()) * myInitVPSizeX * myInitVPSizeY;
1100   }
1101   if (myGlDepthRBufferId != NO_RENDERBUFFER)
1102   {
1103     aSize += OpenGl_Texture::PixelSizeOfPixelFormat (myDepthFormat) * myInitVPSizeX * myInitVPSizeY;
1104   }
1105   return aSize;
1106 }