1 #include <OpenGl_FrameBuffer.hxx>
8 #define glGetProcAddress( x ) glXGetProcAddress( (const GLubyte*) x )
10 #define glGetProcAddress( x ) wglGetProcAddress( x )
13 static inline bool isOddNumber (const GLsizei theNumber)
15 return theNumber & 0x01;
18 static inline GLsizei getEvenNumber (const GLsizei theNumber)
20 return isOddNumber (theNumber) ? (theNumber + 1) : theNumber;
23 //! Notice - 0 is not power of two here
24 static inline bool isPowerOfTwo (const GLsizei theNumber)
26 return !(theNumber & (theNumber - 1));
29 static inline GLsizei getPowerOfTwo (const GLsizei theNumber,
30 const GLsizei theThreshold)
32 for (GLsizei p2 = 2; p2 <= theThreshold; p2 <<= 1)
42 Standard_Boolean OpenGl_FrameBuffer::AreFBOFunctionsValid()
44 return glGenFramebuffersEXT != NULL
45 && glDeleteFramebuffersEXT != NULL
46 && glBindFramebufferEXT != NULL
47 && glFramebufferTexture2DEXT != NULL
48 && glCheckFramebufferStatusEXT != NULL
49 && glGenRenderbuffersEXT != NULL
50 && glBindRenderbufferEXT != NULL
51 && glDeleteRenderbuffersEXT != NULL
52 && glRenderbufferStorageEXT != NULL
53 && glFramebufferRenderbufferEXT != NULL;
56 Standard_Boolean OpenGl_FrameBuffer::InitFBOFunctions()
58 if (AreFBOFunctionsValid())
62 if (CheckExtension ((char *)"GL_EXT_framebuffer_object", (const char *)glGetString (GL_EXTENSIONS)))
64 glGenFramebuffersEXT = (glGenFramebuffersEXT_t) glGetProcAddress ("glGenFramebuffersEXT");
65 glDeleteFramebuffersEXT = (glDeleteFramebuffersEXT_t) glGetProcAddress ("glDeleteFramebuffersEXT");
66 glBindFramebufferEXT = (glBindFramebufferEXT_t) glGetProcAddress ("glBindFramebufferEXT");
67 glFramebufferTexture2DEXT = (glFramebufferTexture2DEXT_t) glGetProcAddress ("glFramebufferTexture2DEXT");
68 glCheckFramebufferStatusEXT = (glCheckFramebufferStatusEXT_t) glGetProcAddress ("glCheckFramebufferStatusEXT");
69 glGenRenderbuffersEXT = (glGenRenderbuffersEXT_t) glGetProcAddress ("glGenRenderbuffersEXT");
70 glDeleteRenderbuffersEXT = (glDeleteRenderbuffersEXT_t) glGetProcAddress ("glDeleteRenderbuffersEXT");
71 glBindRenderbufferEXT = (glBindRenderbufferEXT_t) glGetProcAddress ("glBindRenderbufferEXT");
72 glRenderbufferStorageEXT = (glRenderbufferStorageEXT_t) glGetProcAddress ("glRenderbufferStorageEXT");
73 glFramebufferRenderbufferEXT = (glFramebufferRenderbufferEXT_t)glGetProcAddress ("glFramebufferRenderbufferEXT");
74 return AreFBOFunctionsValid();
76 return Standard_False;
79 OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
84 myTextFormat (theTextureFormat),
85 myGlTextureId (NO_TEXTURE),
86 myGlFBufferId (NO_FRAMEBUFFER),
87 myGlDepthRBId (NO_RENDERBUFFER),
88 glGenFramebuffersEXT (NULL),
89 glDeleteFramebuffersEXT (NULL),
90 glBindFramebufferEXT (NULL),
91 glFramebufferTexture2DEXT (NULL),
92 glCheckFramebufferStatusEXT (NULL),
93 glGenRenderbuffersEXT (NULL),
94 glDeleteRenderbuffersEXT (NULL),
95 glBindRenderbufferEXT (NULL),
96 glRenderbufferStorageEXT (NULL),
97 glFramebufferRenderbufferEXT (NULL)
102 Standard_Boolean OpenGl_FrameBuffer::Init (GLsizei theViewportSizeX,
103 GLsizei theViewportSizeY,
104 GLboolean toForcePowerOfTwo)
106 if (!InitFBOFunctions())
109 std::cerr << "OpenGl_FrameBuffer, FBO extension not supported!\n";
111 return Standard_False;
114 // clean up previous state
117 // upscale width/height if numbers are odd
118 if (toForcePowerOfTwo)
120 GLint aMaxTexDim = 2048;
121 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aMaxTexDim);
122 mySizeX = getPowerOfTwo (theViewportSizeX, aMaxTexDim);
123 mySizeY = getPowerOfTwo (theViewportSizeY, aMaxTexDim);
127 mySizeX = getEvenNumber (theViewportSizeX);
128 mySizeY = getEvenNumber (theViewportSizeY);
131 // setup viewport sizes as is
132 myVPSizeX = theViewportSizeX;
133 myVPSizeY = theViewportSizeY;
135 // Create the texture (will be used as color buffer)
136 if (!InitTrashTexture())
138 if (!isPowerOfTwo (mySizeX) || !isPowerOfTwo (mySizeY))
140 return Init (theViewportSizeX, theViewportSizeY, GL_TRUE);
143 return Standard_False;
146 // Create RenderBuffer (will be used as depth buffer)
147 glGenRenderbuffersEXT (1, &myGlDepthRBId);
148 glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, myGlDepthRBId);
149 glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mySizeX, mySizeY);
151 // Build FBO and setup it as texture
152 glGenFramebuffersEXT (1, &myGlFBufferId);
153 glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, myGlFBufferId);
154 glEnable (GL_TEXTURE_2D);
155 glBindTexture (GL_TEXTURE_2D, myGlTextureId);
156 glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, myGlTextureId, 0);
157 glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, myGlFBufferId);
158 if (glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
160 if (!isPowerOfTwo (mySizeX) || !isPowerOfTwo (mySizeY))
162 return Init (theViewportSizeX, theViewportSizeY, GL_TRUE);
165 return Standard_False;
170 glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, NO_RENDERBUFFER);
173 std::cerr << "OpenGl_FrameBuffer, created FBO " << mySizeX << "x" << mySizeY
174 << " for viewport " << theViewportSizeX << "x" << theViewportSizeY << "\n";
176 return Standard_True;
179 void OpenGl_FrameBuffer::Release()
181 if (IsValidDepthBuffer())
183 glDeleteRenderbuffersEXT (1, &myGlDepthRBId);
184 myGlDepthRBId = NO_RENDERBUFFER;
186 if (IsValidTexture())
188 glDeleteTextures (1, &myGlTextureId);
189 myGlTextureId = NO_TEXTURE;
191 mySizeX = mySizeY = myVPSizeX = myVPSizeY = 0;
192 if (IsValidFrameBuffer())
194 glDeleteFramebuffersEXT (1, &myGlFBufferId);
195 myGlFBufferId = NO_FRAMEBUFFER;
199 Standard_Boolean OpenGl_FrameBuffer::IsProxySuccess() const
201 // use proxy to check texture could be created or not
202 glTexImage2D (GL_PROXY_TEXTURE_2D,
203 0, // LOD number: 0 - base image level; n is the nth mipmap reduction image
204 myTextFormat, // internalformat
206 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
207 GLint aTestParamX (0), aTestParamY (0);
208 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestParamX);
209 glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestParamY);
210 return aTestParamX != 0 && aTestParamY != 0;
213 Standard_Boolean OpenGl_FrameBuffer::InitTrashTexture()
215 // Check texture size is fit dimension maximum
216 GLint aMaxTexDim = 2048;
217 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &aMaxTexDim);
218 if (mySizeX > aMaxTexDim || mySizeY > aMaxTexDim)
220 return Standard_False;
224 glEnable (GL_TEXTURE_2D);
225 if (!IsValidTexture())
227 glGenTextures (1, &myGlTextureId); // Create The Texture
229 glBindTexture (GL_TEXTURE_2D, myGlTextureId);
231 // texture interpolation parameters - could be overridden later
232 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
233 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
235 if (!IsProxySuccess())
238 return Standard_False;
241 glTexImage2D (GL_TEXTURE_2D,
242 0, // LOD number: 0 - base image level; n is the nth mipmap reduction image
243 myTextFormat, // internalformat
245 GL_RGBA, GL_UNSIGNED_BYTE, NULL); // NULL pointer supported from OpenGL 1.1
246 return Standard_True;