1 // Created by: Kirill GAVRILOV
2 // Copyright (c) 2011-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <OpenGl_FrameBuffer.hxx>
16 #include <OpenGl_ArbFBO.hxx>
18 #include <Standard_Assert.hxx>
19 #include <TCollection_ExtendedString.hxx>
21 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer,OpenGl_Resource)
26 //! Determine data type from texture sized format.
27 static bool getDepthDataFormat (GLint theTextFormat,
28 GLenum& thePixelFormat,
31 switch (theTextFormat)
33 case GL_DEPTH24_STENCIL8:
35 thePixelFormat = GL_DEPTH_STENCIL;
36 theDataType = GL_UNSIGNED_INT_24_8;
39 case GL_DEPTH32F_STENCIL8:
41 thePixelFormat = GL_DEPTH_STENCIL;
42 theDataType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
45 case GL_DEPTH_COMPONENT16:
47 thePixelFormat = GL_DEPTH_COMPONENT;
48 theDataType = GL_UNSIGNED_SHORT;
51 case GL_DEPTH_COMPONENT24:
53 thePixelFormat = GL_DEPTH_COMPONENT;
54 theDataType = GL_UNSIGNED_INT;
57 case GL_DEPTH_COMPONENT32F:
59 thePixelFormat = GL_DEPTH_COMPONENT;
60 theDataType = GL_FLOAT;
67 //! Determine data type from texture sized format.
68 static bool getColorDataFormat (const Handle(OpenGl_Context)& theGlContext,
70 GLenum& thePixelFormat,
73 switch (theTextFormat)
77 thePixelFormat = GL_RGBA;
78 theDataType = GL_FLOAT;
83 thePixelFormat = GL_RED;
84 theDataType = GL_FLOAT;
89 thePixelFormat = GL_RGBA;
90 theDataType = GL_HALF_FLOAT;
91 if (theGlContext->hasHalfFloatBuffer == OpenGl_FeatureInExtensions)
93 #if defined(GL_ES_VERSION_2_0)
94 theDataType = GL_HALF_FLOAT_OES;
96 theDataType = GL_FLOAT;
103 thePixelFormat = GL_RED;
104 theDataType = GL_HALF_FLOAT;
105 if (theGlContext->hasHalfFloatBuffer == OpenGl_FeatureInExtensions)
107 #if defined(GL_ES_VERSION_2_0)
108 theDataType = GL_HALF_FLOAT_OES;
110 theDataType = GL_FLOAT;
118 thePixelFormat = GL_RGBA;
119 theDataType = GL_UNSIGNED_BYTE;
125 thePixelFormat = GL_RGB;
126 theDataType = GL_UNSIGNED_BYTE;
133 //! Checks whether two format arrays are equal or not.
134 static bool operator== (const OpenGl_ColorFormats& theFmt1,
135 const OpenGl_ColorFormats& theFmt2)
137 if (theFmt1.Length() != theFmt2.Length())
139 OpenGl_ColorFormats::Iterator anIt1 (theFmt1);
140 OpenGl_ColorFormats::Iterator anIt2 (theFmt1);
141 for (; anIt1.More(); anIt1.Next(), anIt2.Next())
143 if (anIt1.Value() != anIt2.Value())
150 // =======================================================================
151 // function : OpenGl_FrameBuffer
153 // =======================================================================
154 OpenGl_FrameBuffer::OpenGl_FrameBuffer()
160 myDepthFormat (GL_DEPTH24_STENCIL8),
161 myGlFBufferId (NO_FRAMEBUFFER),
162 myGlColorRBufferId (NO_RENDERBUFFER),
163 myGlDepthRBufferId (NO_RENDERBUFFER),
164 myIsOwnBuffer (false),
165 myDepthStencilTexture (new OpenGl_Texture())
167 myColorFormats.Append (GL_RGBA8);
168 myColorTextures.Append (new OpenGl_Texture());
171 // =======================================================================
172 // function : ~OpenGl_FrameBuffer
174 // =======================================================================
175 OpenGl_FrameBuffer::~OpenGl_FrameBuffer()
180 // =======================================================================
183 // =======================================================================
184 Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
185 const GLsizei theSizeX,
186 const GLsizei theSizeY,
187 const GLint theColorFormat,
188 const GLint theDepthFormat,
189 const GLsizei theNbSamples)
191 OpenGl_ColorFormats aColorFormats;
193 aColorFormats.Append (theColorFormat);
195 return Init (theGlContext, theSizeX, theSizeY, aColorFormats, theDepthFormat, theNbSamples);
198 // =======================================================================
201 // =======================================================================
202 Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
203 const GLsizei theSizeX,
204 const GLsizei theSizeY,
205 const OpenGl_ColorFormats& theColorFormats,
206 const Handle(OpenGl_Texture)& theDepthStencilTexture,
207 const GLsizei theNbSamples)
209 myColorFormats = theColorFormats;
211 OpenGl_TextureArray aTextures (myColorTextures);
212 if (!myColorTextures.IsEmpty())
214 for (OpenGl_TextureArray::Iterator aTextureIt (myColorTextures); aTextureIt.More(); aTextureIt.Next())
216 aTextureIt.Value()->Release (theGlContext.operator->());
218 myColorTextures.Clear();
220 for (Standard_Integer aLength = 0; aLength < myColorFormats.Length(); ++aLength)
222 myColorTextures.Append (aLength < aTextures.Length() ? aTextures.Value (aLength) : new OpenGl_Texture());
225 myDepthFormat = theDepthStencilTexture->GetFormat();
226 myNbSamples = theNbSamples;
227 if (theGlContext->arbFBO == NULL)
229 return Standard_False;
232 // clean up previous state
233 Release (theGlContext.operator->());
234 if (myColorFormats.IsEmpty()
235 && myDepthFormat == 0)
237 return Standard_False;
240 myDepthStencilTexture = theDepthStencilTexture;
241 myIsOwnDepth = false;
242 myIsOwnBuffer = true;
244 // setup viewport sizes as is
245 myVPSizeX = theSizeX;
246 myVPSizeY = theSizeY;
247 const Standard_Integer aSizeX = theSizeX > 0 ? theSizeX : 2;
248 const Standard_Integer aSizeY = theSizeY > 0 ? theSizeY : 2;
250 // Create the textures (will be used as color buffer and depth-stencil buffer)
251 if (theNbSamples != 0)
253 for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
255 const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
256 const GLint aColorFormat = myColorFormats (aColorBufferIdx);
257 if (aColorFormat != 0
258 && !aColorTexture->Init2DMultisample (theGlContext, theNbSamples,
259 aColorFormat, aSizeX, aSizeY))
261 Release (theGlContext.operator->());
262 return Standard_False;
268 for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
270 GLenum aPixelFormat = 0;
271 GLenum aDataType = 0;
272 const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
273 const GLint aColorFormat = myColorFormats (aColorBufferIdx);
274 if (aColorFormat != 0
275 && getColorDataFormat (theGlContext, aColorFormat, aPixelFormat, aDataType)
276 && !aColorTexture->Init (theGlContext, aColorFormat,
277 aPixelFormat, aDataType,
278 aSizeX, aSizeY, Graphic3d_TOT_2D))
280 Release (theGlContext.operator->());
281 return Standard_False;
286 // Build FBO and setup it as texture
287 theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
288 theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
290 for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
292 const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
293 if (aColorTexture->IsValid())
295 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + aColorBufferIdx,
296 aColorTexture->GetTarget(), aColorTexture->TextureId(), 0);
299 if (myDepthStencilTexture->IsValid())
301 #ifdef GL_DEPTH_STENCIL_ATTACHMENT
302 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
303 myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
305 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
306 myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
307 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
308 myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
311 if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
313 Release (theGlContext.operator->());
314 return Standard_False;
317 UnbindBuffer (theGlContext);
318 return Standard_True;
321 // =======================================================================
324 // =======================================================================
325 Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
326 const GLsizei theSizeX,
327 const GLsizei theSizeY,
328 const OpenGl_ColorFormats& theColorFormats,
329 const GLint theDepthFormat,
330 const GLsizei theNbSamples)
332 myColorFormats = theColorFormats;
334 OpenGl_TextureArray aTextures (myColorTextures);
335 if (!myColorTextures.IsEmpty())
337 for (OpenGl_TextureArray::Iterator aTextureIt (myColorTextures); aTextureIt.More(); aTextureIt.Next())
339 aTextureIt.Value()->Release (theGlContext.operator->());
341 myColorTextures.Clear();
343 for (Standard_Integer aLength = 0; aLength < myColorFormats.Length(); ++aLength)
345 myColorTextures.Append (aLength < aTextures.Length() ? aTextures.Value (aLength) : new OpenGl_Texture());
348 myDepthFormat = theDepthFormat;
349 myNbSamples = theNbSamples;
350 myInitVPSizeX = theSizeX;
351 myInitVPSizeY = theSizeY;
352 if (theGlContext->arbFBO == NULL)
354 return Standard_False;
357 // clean up previous state
358 Release (theGlContext.operator->());
359 if (myColorFormats.IsEmpty()
360 && myDepthFormat == 0)
362 return Standard_False;
365 myIsOwnBuffer = true;
368 // setup viewport sizes as is
369 myVPSizeX = theSizeX;
370 myVPSizeY = theSizeY;
371 const Standard_Integer aSizeX = theSizeX > 0 ? theSizeX : 2;
372 const Standard_Integer aSizeY = theSizeY > 0 ? theSizeY : 2;
373 bool hasStencilRB = false;
375 // Create the textures (will be used as color buffer and depth-stencil buffer)
376 if (theNbSamples != 0)
378 for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
380 const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
381 const GLint aColorFormat = myColorFormats (aColorBufferIdx);
382 if (aColorFormat != 0
383 && !aColorTexture->Init2DMultisample (theGlContext, theNbSamples, aColorFormat, aSizeX, aSizeY))
385 Release (theGlContext.operator->());
386 return Standard_False;
389 if (myDepthFormat != 0
390 && !myDepthStencilTexture->Init2DMultisample (theGlContext, theNbSamples, myDepthFormat, aSizeX, aSizeY))
392 Release (theGlContext.operator->());
393 return Standard_False;
398 GLenum aPixelFormat = 0;
399 GLenum aDataType = 0;
401 for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
403 const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
404 const GLint aColorFormat = myColorFormats (aColorBufferIdx);
405 if (aColorFormat != 0
406 && getColorDataFormat (theGlContext, aColorFormat, aPixelFormat, aDataType)
407 && !aColorTexture->Init (theGlContext, aColorFormat,
408 aPixelFormat, aDataType,
409 aSizeX, aSizeY, Graphic3d_TOT_2D))
411 Release (theGlContext.operator->());
412 return Standard_False;
416 // extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats
417 // instead of just trying to create such texture
418 if (myDepthFormat != 0
419 && getDepthDataFormat (myDepthFormat, aPixelFormat, aDataType)
420 && !myDepthStencilTexture->Init (theGlContext, myDepthFormat,
421 aPixelFormat, aDataType,
422 aSizeX, aSizeY, Graphic3d_TOT_2D))
424 TCollection_ExtendedString aMsg = TCollection_ExtendedString()
425 + "Warning! Depth textures are not supported by hardware!";
426 theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
427 GL_DEBUG_TYPE_PORTABILITY,
429 GL_DEBUG_SEVERITY_HIGH,
432 hasStencilRB = aPixelFormat == GL_DEPTH_STENCIL
433 && theGlContext->extPDS;
434 GLint aDepthStencilFormat = hasStencilRB
435 ? GL_DEPTH24_STENCIL8
436 : GL_DEPTH_COMPONENT16;
438 theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
439 theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
440 theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, aDepthStencilFormat, aSizeX, aSizeY);
441 theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
445 // Build FBO and setup it as texture
446 theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
447 theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
448 for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
450 const Handle(OpenGl_Texture)& aColorTexture = myColorTextures (aColorBufferIdx);
451 if (aColorTexture->IsValid())
453 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + aColorBufferIdx,
454 aColorTexture->GetTarget(), aColorTexture->TextureId(), 0);
457 if (myDepthStencilTexture->IsValid())
459 #ifdef GL_DEPTH_STENCIL_ATTACHMENT
460 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
461 myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
463 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
464 myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
465 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
466 myDepthStencilTexture->GetTarget(), myDepthStencilTexture->TextureId(), 0);
469 else if (myGlDepthRBufferId != NO_RENDERBUFFER)
471 #ifdef GL_DEPTH_STENCIL_ATTACHMENT
472 theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, hasStencilRB ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT,
473 GL_RENDERBUFFER, myGlDepthRBufferId);
475 theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
476 GL_RENDERBUFFER, myGlDepthRBufferId);
479 theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
480 GL_RENDERBUFFER, myGlDepthRBufferId);
484 if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
486 Release (theGlContext.operator->());
487 return Standard_False;
490 UnbindBuffer (theGlContext);
491 return Standard_True;
494 // =======================================================================
495 // function : InitLazy
497 // =======================================================================
498 Standard_Boolean OpenGl_FrameBuffer::InitLazy (const Handle(OpenGl_Context)& theGlContext,
499 const GLsizei theViewportSizeX,
500 const GLsizei theViewportSizeY,
501 const GLint theColorFormat,
502 const GLint theDepthFormat,
503 const GLsizei theNbSamples)
505 OpenGl_ColorFormats aColorFormats;
507 aColorFormats.Append (theColorFormat);
509 return InitLazy (theGlContext, theViewportSizeX, theViewportSizeY, aColorFormats, theDepthFormat, theNbSamples);
512 // =======================================================================
513 // function : InitLazy
515 // =======================================================================
516 Standard_Boolean OpenGl_FrameBuffer::InitLazy (const Handle(OpenGl_Context)& theGlContext,
517 const GLsizei theViewportSizeX,
518 const GLsizei theViewportSizeY,
519 const OpenGl_ColorFormats& theColorFormats,
520 const GLint theDepthFormat,
521 const GLsizei theNbSamples)
523 if (myVPSizeX == theViewportSizeX
524 && myVPSizeY == theViewportSizeY
525 && myColorFormats == theColorFormats
526 && myDepthFormat == theDepthFormat
527 && myNbSamples == theNbSamples)
532 return Init (theGlContext, theViewportSizeX, theViewportSizeY, theColorFormats, theDepthFormat, theNbSamples);
535 // =======================================================================
536 // function : InitWithRB
538 // =======================================================================
539 Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& theGlCtx,
540 const GLsizei theSizeX,
541 const GLsizei theSizeY,
542 const GLint theColorFormat,
543 const GLint theDepthFormat,
544 const GLuint theColorRBufferFromWindow)
546 myColorFormats.Clear();
547 myColorFormats.Append (theColorFormat);
548 if (!myColorTextures.IsEmpty())
550 Handle(OpenGl_Texture) aTexutre = myColorTextures.First();
551 for (OpenGl_TextureArray::Iterator aTextureIt (myColorTextures); aTextureIt.More(); aTextureIt.Next())
553 aTextureIt.Value()->Release (theGlCtx.operator->());
555 myColorTextures.Clear();
556 myColorTextures.Append (aTexutre);
559 myDepthFormat = theDepthFormat;
561 myInitVPSizeX = theSizeX;
562 myInitVPSizeY = theSizeY;
563 if (theGlCtx->arbFBO == NULL)
565 return Standard_False;
568 // clean up previous state
569 Release (theGlCtx.operator->());
571 myIsOwnBuffer = true;
574 // setup viewport sizes as is
575 myVPSizeX = theSizeX;
576 myVPSizeY = theSizeY;
577 const Standard_Integer aSizeX = theSizeX > 0 ? theSizeX : 2;
578 const Standard_Integer aSizeY = theSizeY > 0 ? theSizeY : 2;
580 // Create the render-buffers
581 if (theColorRBufferFromWindow != NO_RENDERBUFFER)
583 myGlColorRBufferId = theColorRBufferFromWindow;
585 else if (theColorFormat != 0)
587 theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlColorRBufferId);
588 theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlColorRBufferId);
589 theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, theColorFormat, aSizeX, aSizeY);
592 bool hasStencilRB = false;
593 if (myDepthFormat != 0)
595 GLenum aPixelFormat = 0;
596 GLenum aDataType = 0;
597 getDepthDataFormat (myDepthFormat, aPixelFormat, aDataType);
598 hasStencilRB = aPixelFormat == GL_DEPTH_STENCIL;
600 theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
601 theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
602 theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, myDepthFormat, aSizeX, aSizeY);
603 theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
607 theGlCtx->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
608 theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
609 theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
610 GL_RENDERBUFFER, myGlColorRBufferId);
611 if (myGlDepthRBufferId != NO_RENDERBUFFER)
613 #ifdef GL_DEPTH_STENCIL_ATTACHMENT
614 theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, hasStencilRB ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT,
615 GL_RENDERBUFFER, myGlDepthRBufferId);
617 theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
618 GL_RENDERBUFFER, myGlDepthRBufferId);
621 theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
622 GL_RENDERBUFFER, myGlDepthRBufferId);
626 if (theGlCtx->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
628 UnbindBuffer (theGlCtx);
629 Release (theGlCtx.operator->());
630 return Standard_False;
633 UnbindBuffer (theGlCtx);
634 return Standard_True;
637 // =======================================================================
638 // function : InitWrapper
640 // =======================================================================
641 Standard_Boolean OpenGl_FrameBuffer::InitWrapper (const Handle(OpenGl_Context)& theGlCtx)
644 if (theGlCtx->arbFBO == NULL)
646 return Standard_False;
649 // clean up previous state
650 Release (theGlCtx.operator->());
652 GLint anFbo = GLint(NO_FRAMEBUFFER);
653 ::glGetIntegerv (GL_FRAMEBUFFER_BINDING, &anFbo);
654 if (anFbo == GLint(NO_FRAMEBUFFER))
656 return Standard_False;
659 GLint aColorType = 0;
661 GLint aDepthType = 0;
663 theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &aColorType);
664 theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &aDepthType);
666 myGlFBufferId = GLuint(anFbo);
667 myIsOwnBuffer = false;
668 myIsOwnDepth = false;
669 if (aColorType == GL_RENDERBUFFER)
671 theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &aColorId);
672 myGlColorRBufferId = aColorId;
674 else if (aColorType != GL_NONE)
676 TCollection_ExtendedString aMsg = "OpenGl_FrameBuffer::InitWrapper(), color attachment of unsupported type has been skipped!";
677 theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
680 GL_DEBUG_SEVERITY_HIGH,
684 if (aDepthType == GL_RENDERBUFFER)
686 theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &aDepthId);
687 myGlDepthRBufferId = aDepthId;
689 else if (aDepthType != GL_NONE)
691 TCollection_ExtendedString aMsg = "OpenGl_FrameBuffer::InitWrapper(), depth attachment of unsupported type has been skipped!";
692 theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
695 GL_DEBUG_SEVERITY_HIGH,
699 // retrieve dimensions
700 GLuint aRBuffer = myGlColorRBufferId != NO_RENDERBUFFER ? myGlColorRBufferId : myGlDepthRBufferId;
701 if (aRBuffer != NO_RENDERBUFFER)
703 theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, aRBuffer);
704 theGlCtx->arbFBO->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &myVPSizeX);
705 theGlCtx->arbFBO->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &myVPSizeY);
706 theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
709 return aRBuffer != NO_RENDERBUFFER;
712 // =======================================================================
713 // function : Release
715 // =======================================================================
716 void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx)
718 if (isValidFrameBuffer())
720 // application can not handle this case by exception - this is bug in code
721 Standard_ASSERT_RETURN (theGlCtx != NULL,
722 "OpenGl_FrameBuffer destroyed without GL context! Possible GPU memory leakage...",);
723 if (theGlCtx->IsValid()
726 theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId);
727 if (myGlColorRBufferId != NO_RENDERBUFFER)
729 theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlColorRBufferId);
731 if (myGlDepthRBufferId != NO_RENDERBUFFER)
733 theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlDepthRBufferId);
736 myGlFBufferId = NO_FRAMEBUFFER;
737 myGlColorRBufferId = NO_RENDERBUFFER;
738 myGlDepthRBufferId = NO_RENDERBUFFER;
739 myIsOwnBuffer = false;
742 for (Standard_Integer aColorBufferIdx = 0; aColorBufferIdx < myColorTextures.Length(); ++aColorBufferIdx)
744 myColorTextures (aColorBufferIdx)->Release (theGlCtx);
749 myDepthStencilTexture->Release (theGlCtx);
750 myIsOwnDepth = false;
757 // =======================================================================
758 // function : SetupViewport
760 // =======================================================================
761 void OpenGl_FrameBuffer::SetupViewport (const Handle(OpenGl_Context)& theGlCtx)
763 const Standard_Integer aViewport[4] = { 0, 0, myVPSizeX, myVPSizeY };
764 theGlCtx->ResizeViewport (aViewport);
767 // =======================================================================
768 // function : ChangeViewport
770 // =======================================================================
771 void OpenGl_FrameBuffer::ChangeViewport (const GLsizei theVPSizeX,
772 const GLsizei theVPSizeY)
774 myVPSizeX = theVPSizeX;
775 myVPSizeY = theVPSizeY;
778 // =======================================================================
779 // function : BindBuffer
781 // =======================================================================
782 void OpenGl_FrameBuffer::BindBuffer (const Handle(OpenGl_Context)& theGlCtx)
784 theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
787 // =======================================================================
788 // function : BindDrawBuffer
790 // =======================================================================
791 void OpenGl_FrameBuffer::BindDrawBuffer (const Handle(OpenGl_Context)& theGlCtx)
793 theGlCtx->arbFBO->glBindFramebuffer (GL_DRAW_FRAMEBUFFER, myGlFBufferId);
796 // =======================================================================
797 // function : BindReadBuffer
799 // =======================================================================
800 void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx)
802 theGlCtx->arbFBO->glBindFramebuffer (GL_READ_FRAMEBUFFER, myGlFBufferId);
805 // =======================================================================
806 // function : UnbindBuffer
808 // =======================================================================
809 void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx)
811 if (!theGlCtx->DefaultFrameBuffer().IsNull()
812 && theGlCtx->DefaultFrameBuffer().operator->() != this)
814 theGlCtx->DefaultFrameBuffer()->BindBuffer (theGlCtx);
818 theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER);