00001
00002
00003
00004
00005
00006
00007
00008 #include "GPUQMCFramebuffer.h"
00009 #ifdef QMC_GPU
00010
00011 #define TEXTURE_INTERNAL_FORMAT GL_FLOAT_RGBA32_NV
00012 #define TEXTURE_TARGET GL_TEXTURE_RECTANGLE_NV
00013
00014 GPUQMCFramebuffer::GPUQMCFramebuffer()
00015 {
00016 w = 0; h = 0;
00017 }
00018
00019 GPUQMCFramebuffer::GPUQMCFramebuffer(int width, int height, int numFB, int numRT)
00020 {
00021 initialize(width,height,numFB, numRT);
00022 }
00023
00024 GPUQMCFramebuffer::~GPUQMCFramebuffer()
00025 {
00026 for(int i=0; i<getNumFB(); i++)
00027 {
00028 for(int j=0; j<getNumRT(); j++)
00029 {
00030 glDeleteTextures(1, &attachedTextures[i][j]);
00031 }
00032 glDeleteFramebuffersEXT(1,&theFrameBuffers[i]);
00033 }
00034 theFrameBuffers.clear();
00035 attachedTextures.clear();
00036 bufferAttachments.clear();
00037 }
00038
00039 void GPUQMCFramebuffer::operator=(GPUQMCFramebuffer & rhs)
00040 {
00041 initialize(rhs.w, rhs.h, rhs.getNumFB(), rhs.getNumRT());
00042 }
00043
00044 void GPUQMCFramebuffer::initialize(int width, int height, int numFB, int numRT)
00045 {
00046 w = width;
00047 h = height;
00048
00049 if(numRT < 1 || numRT > 4)
00050 cerr << "Error: number render targets must be between 1 and 4\n";
00051 if(width*height == 0)
00052 cerr << "Error: framebuffer must have non-zero dimensions\n";
00053
00054 theFrameBuffers.clear();
00055 attachedTextures.clear();
00056 bufferAttachments.clear();
00057 theFrameBuffers.resize(numFB);
00058 attachedTextures.resize(numFB);
00059 bufferAttachments.resize(numFB);
00060
00061 for(int i=0; i<getNumFB(); i++)
00062 {
00063 glGenFramebuffersEXT(1, &theFrameBuffers[i]);
00064 bufferAttachments[i] = new GLuint[4];
00065 }
00066
00067 for(int i=0; i<numRT; i++)
00068 addTexture();
00069
00070 checkFramebufferStatus();
00071 }
00072
00073 int GPUQMCFramebuffer::getWidth()
00074 {
00075 return w;
00076 }
00077
00078 int GPUQMCFramebuffer::getHeight()
00079 {
00080 return h;
00081 }
00082
00083 void GPUQMCFramebuffer::drawTo(int whichFB)
00084 {
00085 if(!testExistance(whichFB,0)) return;
00086
00087 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, theFrameBuffers[whichFB]);
00088
00089 if(getNumRT() == 1)
00090 {
00091 glDrawBuffer(bufferAttachments[whichFB][0]);
00092 }
00093 else
00094 {
00095 glDrawBuffers(getNumRT(), bufferAttachments[whichFB]);
00096 }
00097
00098 glViewport( 0, 0, getWidth(), getHeight());
00099 GET_GLERROR(0);
00100 }
00101
00102 void GPUQMCFramebuffer::readFrom(int whichFB, int whichRT)
00103 {
00104 if(!testExistance(whichFB,whichRT)) return;
00105 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, theFrameBuffers[whichFB]);
00106 glReadBuffer(bufferAttachments[whichFB][whichRT]);
00107 GET_GLERROR(0);
00108 }
00109
00110 void GPUQMCFramebuffer::cleanBuffer(int whichFB)
00111 {
00112 if(!testExistance(whichFB,0)) return;
00113 drawTo(whichFB);
00114 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00115 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00116 }
00117
00118 void GPUQMCFramebuffer::cleanAllBuffers()
00119 {
00120 for(int i=0; i<getNumFB(); i++)
00121 cleanBuffer(i);
00122 }
00123
00124 void GPUQMCFramebuffer::swapBuffers()
00125 {
00126 cerr << "Error: Function " << __FUNCTION__ << " is not implemented yet!\n";
00127 }
00128
00129 void GPUQMCFramebuffer::setupSwapBuffers(int first, int second)
00130 {
00131 cerr << "Error: Function " << __FUNCTION__ << " is not implemented yet!\n";
00132 }
00133
00134 GLuint GPUQMCFramebuffer::addTexture()
00135 {
00136 int numFB = getNumFB();
00137 int numRT = getNumRT();
00138
00139 if(numRT >= 4)
00140 {
00141 cerr << "ERROR: too many buffers requested\n";
00142 return 0;
00143 }
00144
00145 GLuint * newTextureIDs = new GLuint[numFB];
00146 glGenTextures(numFB, newTextureIDs);
00147
00148
00149 for(int i=0; i<numFB; i++)
00150 {
00151 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, theFrameBuffers[i]);
00152 glBindTexture(TEXTURE_TARGET, newTextureIDs[i]);
00153 glTexParameterf(TEXTURE_TARGET, GL_TEXTURE_WRAP_S, GL_CLAMP);
00154 glTexParameterf(TEXTURE_TARGET, GL_TEXTURE_WRAP_T, GL_CLAMP);
00155 glTexParameterf(TEXTURE_TARGET, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00156 glTexParameterf(TEXTURE_TARGET, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00157 glTexImage2D(TEXTURE_TARGET, 0, TEXTURE_INTERNAL_FORMAT,
00158 w, h, 0, GL_RGBA, GL_FLOAT, NULL);
00159
00160 bufferAttachments[i][numRT] = GL_COLOR_ATTACHMENT0_EXT + numRT;
00161
00162 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
00163 bufferAttachments[i][numRT], TEXTURE_TARGET, newTextureIDs[i], 0);
00164
00165 attachedTextures[i].push_back(newTextureIDs[i]);
00166 }
00167
00168 return 0;
00169 }
00170
00171 void GPUQMCFramebuffer::addTexture(GLuint newTexID)
00172 {
00173 cerr << "Error: Function " << __FUNCTION__ << " is not implemented yet!\n";
00174 }
00175
00176 void GPUQMCFramebuffer::removeTexture(int whichRT)
00177 {
00178 cerr << "Error: Function " << __FUNCTION__ << " is not implemented yet!\n";
00179 }
00180
00181 GLuint GPUQMCFramebuffer::getTextureID(int whichFB, int whichRT)
00182 {
00183 if(!testExistance(whichFB,whichRT)) return 0;
00184 return attachedTextures[whichFB][whichRT];
00185 }
00186
00187 int GPUQMCFramebuffer::getNumRT()
00188 {
00189 return (int)attachedTextures[0].size();
00190 }
00191
00192 int GPUQMCFramebuffer::getNumFB()
00193 {
00194 return (int)theFrameBuffers.size();
00195 }
00196
00197 bool GPUQMCFramebuffer::testExistance(int whichFB, int whichRT)
00198 {
00199 if(whichRT >= getNumRT() || whichRT < 0)
00200 {
00201 cerr << "ERROR: render target " << whichRT << " does not exist.\n";
00202 return false;
00203 }
00204
00205 if(whichFB >= getNumFB() || whichFB < 0)
00206 {
00207 cerr << "ERROR: framebuffer " << whichFB << " does not exist.\n";
00208 return false;
00209 }
00210 return true;
00211 }
00212
00213 void GPUQMCFramebuffer::checkFramebufferStatus()
00214 {
00215 GLenum status;
00216 status = (GLenum) glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00217 switch(status)
00218 {
00219 case GL_FRAMEBUFFER_COMPLETE_EXT:
00220 {
00221 break;
00222 }
00223 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00224 {
00225 printf("Unsupported framebuffer format\n");
00226 break;
00227 }
00228 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
00229 {
00230 printf("Framebuffer incomplete, missing attachment\n");
00231 break;
00232 }
00233 case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
00234 {
00235 printf("Framebuffer incomplete, duplicate attachment\n");
00236 break;
00237 }
00238 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00239 {
00240 printf("Framebuffer incomplete, attached images must have same dimensions\n");
00241 break;
00242 }
00243 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00244 {
00245 printf("Framebuffer incomplete, attached images must have same format\n");
00246 break;
00247 }
00248 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
00249 {
00250 printf("Framebuffer incomplete, missing draw buffer\n");
00251 break;
00252 }
00253 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
00254 {
00255 printf("Framebuffer incomplete, missing read buffer\n");
00256 break;
00257 }
00258 default:
00259 {
00260 cerr << "Error: Framebuffer screwed up for some odd reason...\n";
00261 exit(-1);
00262 }
00263 }
00264 }
00265
00266 #endif