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>
20 IMPLEMENT_STANDARD_HANDLE (OpenGl_FrameBuffer, OpenGl_Resource)
21 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_Resource)
23 static inline bool isOddNumber (const GLsizei theNumber)
25 return theNumber & 0x01;
28 static inline GLsizei getEvenNumber (const GLsizei theNumber)
30 return isOddNumber (theNumber) ? (theNumber + 1) : theNumber;
33 //! Notice - 0 is not power of two here
34 static inline bool isPowerOfTwo (const GLsizei theNumber)
36 return !(theNumber & (theNumber - 1));
39 // =======================================================================
40 // function : OpenGl_FrameBuffer
42 // =======================================================================
43 OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
46 myTextFormat (theTextureFormat),
47 myGlFBufferId (NO_FRAMEBUFFER),
48 myColorTexture (new OpenGl_Texture()),
49 myDepthStencilTexture (new OpenGl_Texture())
54 // =======================================================================
55 // function : ~OpenGl_FrameBuffer
57 // =======================================================================
58 OpenGl_FrameBuffer::~OpenGl_FrameBuffer()
63 // =======================================================================
66 // =======================================================================
67 Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlContext,
68 const GLsizei theViewportSizeX,
69 const GLsizei theViewportSizeY)
71 if (theGlContext->arbFBO == NULL)
73 return Standard_False;
76 // clean up previous state
77 Release (theGlContext.operator->());
79 // setup viewport sizes as is
80 myVPSizeX = theViewportSizeX;
81 myVPSizeY = theViewportSizeY;
83 // Create the textures (will be used as color buffer and depth-stencil buffer)
84 if (!initTrashTextures (theGlContext))
86 Release (theGlContext.operator->());
87 return Standard_False;
90 // Build FBO and setup it as texture
91 theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
92 theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
93 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
94 GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
95 #ifdef GL_DEPTH_STENCIL_ATTACHMENT
96 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
97 GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
99 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
100 GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
101 theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
102 GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
104 if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
106 Release (theGlContext.operator->());
107 return Standard_False;
110 UnbindBuffer (theGlContext);
111 return Standard_True;
114 // =======================================================================
115 // function : Release
117 // =======================================================================
118 void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx)
120 if (isValidFrameBuffer())
122 // application can not handle this case by exception - this is bug in code
123 Standard_ASSERT_RETURN (theGlCtx != NULL,
124 "OpenGl_FrameBuffer destroyed without GL context! Possible GPU memory leakage...",);
125 if (theGlCtx->IsValid())
127 theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId);
129 myGlFBufferId = NO_FRAMEBUFFER;
132 myColorTexture->Release (theGlCtx);
133 myDepthStencilTexture->Release (theGlCtx);
136 // =======================================================================
137 // function : initTrashTexture
139 // =======================================================================
140 Standard_Boolean OpenGl_FrameBuffer::initTrashTextures (const Handle(OpenGl_Context)& theGlContext)
142 return myColorTexture->Init (theGlContext, myTextFormat,
143 GL_RGBA, GL_UNSIGNED_BYTE,
144 myVPSizeX, myVPSizeY, Graphic3d_TOT_2D)
145 && myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
146 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
147 myVPSizeX, myVPSizeY, Graphic3d_TOT_2D);
150 // =======================================================================
151 // function : SetupViewport
153 // =======================================================================
154 void OpenGl_FrameBuffer::SetupViewport (const Handle(OpenGl_Context)& /*theGlCtx*/)
156 glViewport (0, 0, myVPSizeX, myVPSizeY);
159 // =======================================================================
160 // function : ChangeViewport
162 // =======================================================================
163 void OpenGl_FrameBuffer::ChangeViewport (const GLsizei theVPSizeX,
164 const GLsizei theVPSizeY)
166 myVPSizeX = theVPSizeX;
167 myVPSizeY = theVPSizeY;
170 // =======================================================================
171 // function : BindBuffer
173 // =======================================================================
174 void OpenGl_FrameBuffer::BindBuffer (const Handle(OpenGl_Context)& theGlCtx)
176 theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
179 // =======================================================================
180 // function : UnbindBuffer
182 // =======================================================================
183 void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx)
185 theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER);