00001 #include "VFramebufferObject.h"
00002 #include "glew.h"
00003 #include "IL/il.h"
00004 #include "IL/ilu.h"
00005 #include "IL/ilut.h"
00006 #include <vector>
00007
00008 bool VFramebufferObject::m_ProgramLoaded = false;
00009
00010 VProgram VFramebufferObject::m_RenderToScreen;
00011
00012 VFramebufferObject::VFramebufferObject(int width, int height, unsigned int texturetype) :
00013 m_FboHandle(0), m_TextureHandle(0), m_RenderBufferHandle(0), m_TextureType(texturetype)
00014 {
00015 if (!GLEW_ARB_texture_non_power_of_two)
00016 {
00017 m_Width = getNextPowerOfTwo(width);
00018 m_Height = getNextPowerOfTwo(height);
00019 }
00020 else
00021 {
00022 m_Width = width;
00023 m_Height = height;
00024 }
00025 }
00026
00027 void VFramebufferObject::checkFramebufferObjectStatus()
00028 {
00029 int error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00030 if (!(error == GL_FRAMEBUFFER_COMPLETE_EXT))
00031 {
00032 std::cout << "FBO Error" << gluErrorString(error) << std::endl;;
00033 }
00034 }
00035
00036 bool VFramebufferObject::devIlInitialised = false;
00037
00038 bool VFramebufferObject::initialiseDevIl()
00039 {
00040 ilInit();
00041 iluInit();
00042 ilutInit();
00043 ilutRenderer(ILUT_OPENGL);
00044 if ((ilGetInteger(IL_VERSION_NUM) < IL_VERSION) ||
00045 (iluGetInteger(ILU_VERSION_NUM) < ILU_VERSION) ||
00046 (ilutGetInteger(ILUT_VERSION_NUM) < ILUT_VERSION))
00047 {
00048 std::cout << "devil not working" << std::endl;
00049 return false;
00050 }
00051 return true;
00052 }
00053
00054 VProgram * VFramebufferObject::getRenderToScreenProgram()
00055 {
00056 if(!m_ProgramLoaded)
00057 {
00058 m_RenderToScreen = VProgram(VVertexShader("shader/rendertoscreen_vertex.glsl"), VFragmentShader("shader/rendertoscreen_fragment.glsl"));
00059 m_ProgramLoaded = true;
00060 }
00061
00062 return &m_RenderToScreen;
00063 }
00064
00065
00066 void VFramebufferObject::init()
00067 {
00068 int mMaxColorTargets;
00069 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &mMaxColorTargets);
00070
00071
00072
00073 glGenTextures(1, &m_TextureHandle);
00074 glBindTexture(GL_TEXTURE_2D, m_TextureHandle);
00075
00076 unsigned int format;
00077 if(m_TextureType == GL_RGBA16F_ARB)
00078 {
00079 if (!GLEW_ARB_texture_float)
00080 {
00081 m_TextureType = GL_RGBA;
00082 format = GL_UNSIGNED_SHORT;
00083 }
00084 else
00085 {
00086 format = GL_FLOAT;
00087 }
00088 }
00089 else
00090 {
00091 format = GL_UNSIGNED_BYTE;
00092 }
00093
00094 glTexImage2D(GL_TEXTURE_2D, 0, m_TextureType, m_Width, m_Height, 0, GL_RGBA, format, 0);
00095
00096
00097 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00098 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00099 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00101
00102
00103 glGenRenderbuffersEXT(1, &m_RenderBufferHandle);
00104 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_RenderBufferHandle);
00105 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_Width, m_Height);
00106
00107
00108 glGenFramebuffersEXT(1, &m_FboHandle);
00109 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FboHandle);
00110 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_TextureHandle, 0);
00111 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_RenderBufferHandle);
00112
00113 checkFramebufferObjectStatus();
00114
00115 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
00116 glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0 );
00117 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00118 glDrawBuffer(GL_BACK);
00119 checkFramebufferObjectStatus();
00120
00121 if(!m_ProgramLoaded)
00122 {
00123 m_RenderToScreen = VProgram(VVertexShader("shader/rendertoscreen_vertex.glsl"), VFragmentShader("shader/rendertoscreen_fragment.glsl"));
00124 m_ProgramLoaded = true;
00125 }
00126
00127 bind();
00128 unbind();
00129
00130 }
00131
00132 void VFramebufferObject::destroy()
00133 {
00134 if(m_FboHandle!= 0)
00135 {
00136 glDeleteFramebuffersEXT(1, &m_FboHandle);
00137 m_FboHandle = 0;
00138 glDeleteRenderbuffersEXT(1, &m_RenderBufferHandle);
00139 m_RenderBufferHandle = 0;
00140
00141 glDeleteTextures(1, &m_TextureHandle);
00142 m_TextureHandle = 0;
00143 }
00144 }
00145
00146 void VFramebufferObject::bind()
00147 {
00148 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FboHandle);
00149 glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
00150 glViewport(0, 0, m_Width, m_Height);
00151
00152 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_TextureHandle, 0);
00153 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_RenderBufferHandle);
00154
00155 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
00156 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00157 checkFramebufferObjectStatus();
00158 }
00159
00160
00161 void VFramebufferObject::bindWithoutClear()
00162 {
00163 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FboHandle);
00164 glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
00165 glViewport(0, 0, m_Width, m_Height);
00166 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_TextureHandle, 0);
00167 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_RenderBufferHandle);
00168
00169 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
00170 checkFramebufferObjectStatus();
00171 }
00172
00173 void VFramebufferObject::unbind()
00174 {
00175 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
00176 glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0 );
00177 glPopAttrib();
00178 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00179 checkFramebufferObjectStatus();
00180 glDrawBuffer(GL_BACK);
00181
00182 }
00183
00184 void VFramebufferObject::saveImage(std::string filename)
00185 {
00186 if(!devIlInitialised)
00187 {
00188 devIlInitialised = initialiseDevIl();
00189 }
00190
00191 glEnable(GL_TEXTURE_2D);
00192 glBindTexture(GL_TEXTURE_2D, m_TextureHandle);
00193
00194 std::vector<unsigned char> imagedata;
00195
00196 imagedata.resize(m_Height * m_Width * 4);
00197 glPixelStoref(GL_UNPACK_ALIGNMENT, 1);
00198
00199 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &imagedata[0]);
00200
00201 const GLenum glError = glGetError();
00202
00203 if (glError != GL_NO_ERROR)
00204 std::cout << "OpenGL Error saving Image " << gluErrorString(glError) << std::endl;
00205
00206 ILuint ImageName;
00207 ilGenImages(1, &ImageName);
00208 ilBindImage(ImageName);
00209
00210 ilTexImage(m_Width, m_Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, &imagedata[0]);
00211
00212 ilEnable(IL_FILE_OVERWRITE);
00213 ilSaveImage(filename.c_str());
00214 ILenum Error;
00215 Error = ilGetError();
00216
00217 if(Error != IL_NO_ERROR)
00218 std::cout << "DevIl Error saving IMage " << iluErrorString(Error) << std::endl;
00219
00220 ilDeleteImages(1, &ImageName);
00221
00222 glBindTexture(GL_TEXTURE_2D, 0);
00223 glDisable(GL_TEXTURE_2D);
00224 }
00225
00226 void VFramebufferObject::renderToFullScreen()
00227 {
00228 glActiveTextureARB(GL_TEXTURE0_ARB);
00229 glEnable(GL_TEXTURE_2D);
00230 glBindTexture(GL_TEXTURE_2D, this->getTextureHandle());
00231
00232 m_RenderToScreen.bind();
00233
00234 glUniform1i(m_RenderToScreen.getUniformLocation("mTexture"),0);
00235
00236 glBegin(GL_QUADS);
00237 glTexCoord2f(0.0f, 0.0f);
00238 glVertex3f(-1.0f, -1.0f, 0.0);
00239
00240 glTexCoord2f(0.0f, 1.0f);
00241 glVertex3f(-1.0f, 1.0f, 0.0);
00242
00243 glTexCoord2f(1.0f, 1.0f);
00244 glVertex3f(1.0f, 1.0f, 0.0);
00245
00246 glTexCoord2f(1.0f, 0.0f);
00247 glVertex3f(1.0f, -1.0f, 0.0);
00248 glEnd();
00249
00250 m_RenderToScreen.release();
00251
00252 glActiveTextureARB(GL_TEXTURE0_ARB);
00253 glBindTexture(GL_TEXTURE_2D, 0);
00254 glDisable(GL_TEXTURE_2D);
00255 }
00256
00257 void VFramebufferObject::renderToLowerLeftQuad()
00258 {
00259 glActiveTextureARB(GL_TEXTURE0_ARB);
00260 glEnable(GL_TEXTURE_2D);
00261 glBindTexture(GL_TEXTURE_2D, this->getTextureHandle());
00262
00263 m_RenderToScreen.bind();
00264
00265 glUniform1i(m_RenderToScreen.getUniformLocation("mTexture"),0);
00266
00267 glBegin(GL_QUADS);
00268 glTexCoord2f(0.0f, 0.0f);
00269 glVertex3f(-1.0f, -1.0f, -0.01f);
00270
00271 glTexCoord2f(0.0f, 1.0f);
00272 glVertex3f(-1.0f, -0.5f, -0.01f);
00273
00274 glTexCoord2f(1.0f, 1.0f);
00275 glVertex3f(-0.5f, -0.5f, -0.01f);
00276
00277 glTexCoord2f(1.0f, 0.0f);
00278 glVertex3f(-0.5f, -1.0f, -0.01f);
00279 glEnd();
00280
00281 m_RenderToScreen.release();
00282
00283 glActiveTextureARB(GL_TEXTURE0_ARB);
00284 glBindTexture(GL_TEXTURE_2D, 0);
00285 glDisable(GL_TEXTURE_2D);
00286 }
00287
00288 void VFramebufferObject::renderToLowerRightQuad()
00289 {
00290 glActiveTextureARB(GL_TEXTURE0_ARB);
00291 glEnable(GL_TEXTURE_2D);
00292 glBindTexture(GL_TEXTURE_2D, this->getTextureHandle());
00293
00294 m_RenderToScreen.bind();
00295
00296 glUniform1i(m_RenderToScreen.getUniformLocation("mTexture"),0);
00297
00298 glBegin(GL_QUADS);
00299 glTexCoord2f(0.0f, 0.0f);
00300 glVertex3f(0.5f, -1.0f, -0.01f);
00301
00302 glTexCoord2f(1.0f, 0.0f);
00303 glVertex3f(1.0f, -1.0f, -0.01f);
00304
00305 glTexCoord2f(1.0f, 1.0f);
00306 glVertex3f(1.0f, -0.5f, -0.01f);
00307
00308 glTexCoord2f(0.0f, 1.0f);
00309 glVertex3f(0.5f, -0.5f, -0.01f);
00310 glEnd();
00311
00312 m_RenderToScreen.release();
00313
00314 glActiveTextureARB(GL_TEXTURE0_ARB);
00315 glBindTexture(GL_TEXTURE_2D, 0);
00316 glDisable(GL_TEXTURE_2D);
00317 }