llrendertarget.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llrendertarget.h"
00035 #include "llglimmediate.h"
00036 #include "llgl.h"
00037 
00038 
00039 BOOL LLRenderTarget::sUseFBO = FALSE;
00040 
00041 LLRenderTarget::LLRenderTarget() :
00042         mResX(0),
00043         mResY(0),
00044         mTex(0),
00045         mFBO(0),
00046         mDepth(0),
00047         mStencil(0),
00048         mUseDepth(FALSE),
00049         mRenderDepth(FALSE),
00050         mUsage(GL_TEXTURE_2D)
00051 {
00052 }
00053 
00054 LLRenderTarget::~LLRenderTarget()
00055 {
00056         release();
00057 }
00058 
00059 void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, U32 usage, BOOL use_fbo)
00060 {
00061         stop_glerror();
00062         mResX = resx;
00063         mResY = resy;
00064 
00065         mUsage = usage;
00066         mUseDepth = depth;
00067         release();
00068 
00069         glGenTextures(1, (GLuint *) &mTex);
00070         glBindTexture(mUsage, mTex);
00071         glTexImage2D(mUsage, 0, color_fmt, mResX, mResY, 0, color_fmt, GL_UNSIGNED_BYTE, NULL);
00072 
00073         glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00074         glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00075 
00076         if (mUsage != GL_TEXTURE_RECTANGLE_ARB)
00077         {
00078                 glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
00079                 glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
00080         }
00081         else
00082         {
00083                 // ATI doesn't support mirrored repeat for rectangular textures.
00084                 glTexParameteri(mUsage, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00085                 glTexParameteri(mUsage, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00086         }
00087 
00088         stop_glerror();
00089 
00090         if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject)
00091         {
00092 
00093                 if (depth)
00094                 {
00095                         stop_glerror();
00096                         allocateDepth();
00097                         stop_glerror();
00098                 }
00099 
00100                 glGenFramebuffersEXT(1, (GLuint *) &mFBO);
00101 
00102                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
00103 
00104                 if (mDepth)
00105                 {
00106                         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, mUsage, mDepth, 0);
00107                         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, mUsage, mDepth, 0);
00108                         stop_glerror();
00109                 }
00110 
00111                 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
00112                                                 mUsage, mTex, 0);
00113                 stop_glerror();
00114 
00115                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00116                 stop_glerror();
00117         }
00118 }
00119 
00120 void LLRenderTarget::allocateDepth()
00121 {
00122         glGenTextures(1, (GLuint *) &mDepth);
00123         glBindTexture(mUsage, mDepth);
00124         glTexParameteri(mUsage, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00125         glTexParameteri(mUsage, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00126         glTexImage2D(mUsage, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
00127 }
00128 
00129 void LLRenderTarget::release()
00130 {
00131         if (mFBO)
00132         {
00133                 glDeleteFramebuffersEXT(1, (GLuint *) &mFBO);
00134                 mFBO = 0;
00135         }
00136 
00137         if (mTex)
00138         {
00139                 glDeleteTextures(1, (GLuint *) &mTex);
00140                 mTex = 0;
00141         }
00142 
00143         if (mDepth)
00144         {
00145                 glDeleteTextures(1, (GLuint *) &mDepth);
00146                 mDepth = 0;
00147         }
00148 }
00149 
00150 void LLRenderTarget::bindTarget()
00151 {
00152         if (mFBO)
00153         {
00154                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
00155         }
00156 
00157         glViewport(0, 0, mResX, mResY);
00158 }
00159 
00160 // static
00161 void LLRenderTarget::unbindTarget()
00162 {
00163         if (gGLManager.mHasFramebufferObject)
00164         {
00165                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00166         }
00167 }
00168 
00169 void LLRenderTarget::clear()
00170 {
00171         U32 mask = GL_COLOR_BUFFER_BIT;
00172         if (mUseDepth)
00173         {
00174                 mask |= GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
00175         }
00176         if (mFBO)
00177         {
00178                 glClear(mask);
00179         }
00180         else
00181         {
00182                 LLGLEnable scissor(GL_SCISSOR_TEST);
00183                 glScissor(0, 0, mResX, mResY);
00184                 glClear(mask);
00185         }
00186 }
00187 
00188 void LLRenderTarget::bindTexture()
00189 {
00190         glBindTexture(mUsage, mTex);
00191 }
00192 
00193 void LLRenderTarget::bindDepth()
00194 {
00195         glBindTexture(mUsage, mDepth);
00196 }
00197 
00198 
00199 void LLRenderTarget::flush(BOOL fetch_depth)
00200 {
00201         gGL.flush();
00202         if (!mFBO)
00203         {
00204                 bindTexture();
00205                 glCopyTexSubImage2D(mUsage, 0, 0, 0, 0, 0, mResX, mResY);
00206 
00207                 if (fetch_depth)
00208                 {
00209                         if (!mDepth)
00210                         {
00211                                 allocateDepth();
00212                         }
00213 
00214                         bindDepth();
00215                         glCopyTexImage2D(mUsage, 0, GL_DEPTH24_STENCIL8_EXT, 0, 0, mResX, mResY, 0);
00216                 }
00217         }
00218         else
00219         {
00220                 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00221         }
00222 }
00223 
00224 BOOL LLRenderTarget::isComplete() const
00225 {
00226         return (mTex || mDepth) ? TRUE : FALSE;
00227 }
00228 
00229 void LLRenderTarget::getViewport(S32* viewport)
00230 {
00231         viewport[0] = 0;
00232         viewport[1] = 0;
00233         viewport[2] = mResX;
00234         viewport[3] = mResY;
00235 }
00236 

Generated on Fri May 16 08:32:49 2008 for SecondLife by  doxygen 1.5.5