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
00128 }
00129
00130 void VFramebufferObject::destroy()
00131 {
00132 if(m_FboHandle!= 0)
00133 {
00134 glDeleteFramebuffersEXT(1, &m_FboHandle);
00135 m_FboHandle = 0;
00136 glDeleteRenderbuffersEXT(1, &m_RenderBufferHandle);
00137 m_RenderBufferHandle = 0;
00138 }
00139 }
00140
00141 void VFramebufferObject::bind()
00142 {
00143 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FboHandle);
00144 glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
00145 glViewport(0, 0, m_Width, m_Height);
00146 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_TextureHandle, 0);
00147 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_RenderBufferHandle);
00148
00149 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
00150 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00151 checkFramebufferObjectStatus();
00152 }
00153
00154 void VFramebufferObject::unbind()
00155 {
00156 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
00157 glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0 );
00158 glPopAttrib();
00159 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00160 checkFramebufferObjectStatus();
00161 glDrawBuffer(GL_BACK);
00162
00163 }
00164
00165 void VFramebufferObject::saveImage(std::string filename)
00166 {
00167 if(!devIlInitialised)
00168 {
00169 devIlInitialised = initialiseDevIl();
00170 }
00171
00172 glEnable(GL_TEXTURE_2D);
00173 glBindTexture(GL_TEXTURE_2D, m_TextureHandle);
00174
00175 std::vector<unsigned char> imagedata;
00176
00177 imagedata.resize(m_Height * m_Width * 4);
00178 glPixelStoref(GL_UNPACK_ALIGNMENT, 1);
00179
00180 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &imagedata[0]);
00181
00182 const GLenum glError = glGetError();
00183
00184 if (glError != GL_NO_ERROR)
00185 std::cout << "OpenGL Error saving Image " << gluErrorString(glError) << std::endl;
00186
00187 ILuint ImageName;
00188 ilGenImages(1, &ImageName);
00189 ilBindImage(ImageName);
00190
00191 ilTexImage(m_Width, m_Height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, &imagedata[0]);
00192
00193 ilEnable(IL_FILE_OVERWRITE);
00194 ilSaveImage(filename.c_str());
00195 ILenum Error;
00196 Error = ilGetError();
00197
00198 if(Error != IL_NO_ERROR)
00199 std::cout << "DevIl Error saving IMage " << iluErrorString(Error) << std::endl;
00200
00201 ilDeleteImages(1, &ImageName);
00202
00203 glBindTexture(GL_TEXTURE_2D, 0);
00204 glDisable(GL_TEXTURE_2D);
00205 }
00206
00207 void VFramebufferObject::renderToFullScreen()
00208 {
00209 glActiveTextureARB(GL_TEXTURE0_ARB);
00210 glEnable(GL_TEXTURE_2D);
00211 glBindTexture(GL_TEXTURE_2D, this->getTextureHandle());
00212
00213 m_RenderToScreen.bind();
00214
00215 glUniform1i(m_RenderToScreen.getUniformLocation("mTexture"),0);
00216
00217 glBegin(GL_QUADS);
00218 glTexCoord2f(0.0f, 0.0f);
00219 glVertex3f(-1.0f, -1.0f, 0.0);
00220
00221 glTexCoord2f(0.0f, 1.0f);
00222 glVertex3f(-1.0f, 1.0f, 0.0);
00223
00224 glTexCoord2f(1.0f, 1.0f);
00225 glVertex3f(1.0f, 1.0f, 0.0);
00226
00227 glTexCoord2f(1.0f, 0.0f);
00228 glVertex3f(1.0f, -1.0f, 0.0);
00229 glEnd();
00230
00231 m_RenderToScreen.release();
00232
00233 glActiveTextureARB(GL_TEXTURE0_ARB);
00234 glBindTexture(GL_TEXTURE_2D, 0);
00235 glDisable(GL_TEXTURE_2D);
00236 }
00237
00238 void VFramebufferObject::renderToLowerLeftQuad()
00239 {
00240 glActiveTextureARB(GL_TEXTURE0_ARB);
00241 glEnable(GL_TEXTURE_2D);
00242 glBindTexture(GL_TEXTURE_2D, this->getTextureHandle());
00243
00244 m_RenderToScreen.bind();
00245
00246 glUniform1i(m_RenderToScreen.getUniformLocation("mTexture"),0);
00247
00248 glBegin(GL_QUADS);
00249 glTexCoord2f(0.0f, 0.0f);
00250 glVertex3f(-1.0f, -1.0f, -0.01f);
00251
00252 glTexCoord2f(0.0f, 1.0f);
00253 glVertex3f(-1.0f, -0.5f, -0.01f);
00254
00255 glTexCoord2f(1.0f, 1.0f);
00256 glVertex3f(-0.5f, -0.5f, -0.01f);
00257
00258 glTexCoord2f(1.0f, 0.0f);
00259 glVertex3f(-0.5f, -1.0f, -0.01f);
00260 glEnd();
00261
00262 m_RenderToScreen.release();
00263
00264 glActiveTextureARB(GL_TEXTURE0_ARB);
00265 glBindTexture(GL_TEXTURE_2D, 0);
00266 glDisable(GL_TEXTURE_2D);
00267 }
00268
00269 void VFramebufferObject::renderToLowerRightQuad()
00270 {
00271 glActiveTextureARB(GL_TEXTURE0_ARB);
00272 glEnable(GL_TEXTURE_2D);
00273 glBindTexture(GL_TEXTURE_2D, this->getTextureHandle());
00274
00275 m_RenderToScreen.bind();
00276
00277 glUniform1i(m_RenderToScreen.getUniformLocation("mTexture"),0);
00278
00279 glBegin(GL_QUADS);
00280 glTexCoord2f(0.0f, 0.0f);
00281 glVertex3f(0.5f, -1.0f, -0.01f);
00282
00283 glTexCoord2f(1.0f, 0.0f);
00284 glVertex3f(1.0f, -1.0f, -0.01f);
00285
00286 glTexCoord2f(1.0f, 1.0f);
00287 glVertex3f(1.0f, -0.5f, -0.01f);
00288
00289 glTexCoord2f(0.0f, 1.0f);
00290 glVertex3f(0.5f, -0.5f, -0.01f);
00291 glEnd();
00292
00293 m_RenderToScreen.release();
00294
00295 glActiveTextureARB(GL_TEXTURE0_ARB);
00296 glBindTexture(GL_TEXTURE_2D, 0);
00297 glDisable(GL_TEXTURE_2D);
00298 }