00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "rTextureRenderTarget.h"
00029
00030
00031 #include "rScreen.h"
00032 #include "tException.h"
00033
00034 rTextureRenderTarget * rTextureRenderTarget::anchor = 0;
00035
00036
00037
00038
00039
00040
00045
00046
00048
00049
00050 void rTextureRenderTarget::Clear()
00051 {
00052 tASSERT( !IsTarget() );
00053
00054 texture_.Delete();
00055 depthBuffer_.Delete();
00056 frameBuffer_.Delete();
00057 }
00058
00059 rTextureRenderTarget::~rTextureRenderTarget()
00060 {
00061 if ( IsTarget() )
00062 {
00063 Pop();
00064 }
00065
00066 Clear();
00067 }
00068
00069 rTextureRenderTarget::rTextureRenderTarget( int width, int height )
00070 {
00071 #ifndef DEDICATED
00072 sr_CheckGLError();
00073
00074 width_ = width;
00075 height_ = height;
00076 previous = 0;
00077
00078 #ifdef GLEW_EXT_framebuffer_object
00079 if ( GLEW_EXT_framebuffer_object )
00080 {
00081 Push();
00082 sr_CheckGLError();
00083
00084
00085 glBindTexture( GL_TEXTURE_2D, texture_ );
00086 sr_CheckGLError();
00087
00088
00089 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
00090 sr_CheckGLError();
00091
00092 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00093 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00094 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00095 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00096
00097 glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texture_, 0 );
00098 sr_CheckGLError();
00099
00100 glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, depthBuffer_ );
00101 sr_CheckGLError();
00102
00103 glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, width, height );
00104 sr_CheckGLError();
00105
00106 glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer_ );
00107 sr_CheckGLError();
00108
00109 GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT);
00110 switch ( status )
00111 {
00112 case GL_FRAMEBUFFER_COMPLETE_EXT:
00113 break;
00114 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00115 throw rExceptionGLEW( "Unsupported frame buffer operation" );
00116 default:
00117 tASSERT( 0 );
00118 }
00119
00120 sr_CheckGLError();
00121
00122 Pop();
00123
00124 return;
00125 }
00126 #endif // GLEW_EXT_framebuffer_object
00127
00128 throw rExceptionGLEW( "frame buffer extension not supported" );
00129 #endif
00130 }
00131
00132 void rTextureRenderTarget::Push()
00133 {
00134 #ifndef DEDICATED
00135 previous = anchor;
00136 anchor = this;
00137
00138 #ifdef GLEW_EXT_framebuffer_object
00139 sr_CheckGLError();
00140
00141 glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, frameBuffer_ );
00142
00143 sr_CheckGLError();
00144 #endif
00145 #endif
00146 }
00147
00148 void rTextureRenderTarget::Pop()
00149 {
00150 #ifndef DEDICATED
00151 tASSERT( IsTarget() );
00152
00153 anchor = previous;
00154
00155 Restore();
00156 #endif
00157 }
00158
00159 void rTextureRenderTarget::Restore()
00160 {
00161 #ifdef GLEW_EXT_framebuffer_object
00162 sr_CheckGLError();
00163 glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, anchor ? anchor->frameBuffer_ : 0 );
00164 sr_CheckGLError();
00165 #endif
00166 }
00167
00168 void rTextureRenderTarget::OnSelect(bool)
00169 {
00170 #ifndef DEDICATED
00171 glBindTexture( GL_TEXTURE_2D, texture_ );
00172 #endif
00173 }