173 // GLenum type = TYPE; 174 // const GLvoid *pixels = NULL; 175 // glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); 176 // 177 // glDisable(TARGET); 178 // } 179 180 self->_width = width; 181 self->_height = height; 182 } 183 184 - (id)init 185 { 186 self = [super init]; 187 if (self != nil) 188 { 189 self->_width = 0; 190 self->_height = 0; 191 self->_texture = 0; 192 self->_fbo = 0; 193 194 [self _assertContext]; 195 if ([self _supportsFbo] == NO) 196 { 197 [super dealloc]; 198 self = nil; 199 } 200 } 201 return self; 202 } 203 204 - (void)dealloc 205 { 206 [self _assertContext]; 207 { 208 [self _destroyFbo]; 209 } 210 211 [super dealloc]; 212 } 213 214 - (GLuint)width 215 { 216 return self->_width; 217 } 218 219 - (GLuint)height 220 { 221 return self->_height; 222 } 223 224 - (void)bindForWidth:(GLuint)width andHeight:(GLuint)height 225 { 226 LOG(" GlassFrameBufferObject bindForWidth:%d andHeight:%d", width, height); 227 LOG(" context:%p", CGLGetCurrentContext()); 228 [self _assertContext]; 229 { 230 if ((width > 0) && (height > 0)) 231 { 232 [self _createFboIfNeededForWidth:width andHeight:height]; 233 } 234 } 235 LOG(" BOUND"); 236 LOG(" glGetError(): %d", glGetError()); 237 } 238 239 - (void)blitForWidth:(GLuint)width andHeight:(GLuint)height 240 { 241 LOG(" GlassFrameBufferObject blitForWidth:%d andHeight:%d [%p]", width, height, self); 242 if (self->_texture != 0) 243 { 244 glMatrixMode(GL_PROJECTION); 245 glLoadIdentity(); 246 glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f); 247 248 glMatrixMode(GL_MODELVIEW); 249 glLoadIdentity(); 250 251 glEnable(TARGET); 252 { 253 glActiveTextureARB(GL_TEXTURE0); 254 glBindTexture(TARGET, self->_texture); 255 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 256 { 257 glBegin(GL_QUADS); 258 { 277 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint*)&self->_fboToRestore); 278 [self _createFboIfNeededForWidth:other_fbo->_width andHeight:other_fbo->_height]; 279 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, self->_fbo); 280 glBindFramebuffer(GL_READ_FRAMEBUFFER, other_fbo->_fbo); 281 glBlitFramebuffer(0,0, other_fbo->_width, other_fbo->_height, 282 0,0, self->_width, self->_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); 283 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, self->_fboToRestore); 284 } 285 286 287 - (GLuint)texture 288 { 289 return self->_texture; 290 } 291 292 - (GLuint)fbo 293 { 294 return self->_fbo; 295 } 296 297 @end | 173 // GLenum type = TYPE; 174 // const GLvoid *pixels = NULL; 175 // glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); 176 // 177 // glDisable(TARGET); 178 // } 179 180 self->_width = width; 181 self->_height = height; 182 } 183 184 - (id)init 185 { 186 self = [super init]; 187 if (self != nil) 188 { 189 self->_width = 0; 190 self->_height = 0; 191 self->_texture = 0; 192 self->_fbo = 0; 193 self->_isSwPipe = NO; 194 195 [self _assertContext]; 196 if ([self _supportsFbo] == NO) 197 { 198 [super dealloc]; 199 self = nil; 200 } 201 } 202 return self; 203 } 204 205 - (void)dealloc 206 { 207 [self _assertContext]; 208 { 209 [self _destroyFbo]; 210 } 211 212 [super dealloc]; 213 } 214 215 - (GLuint)width 216 { 217 return self->_width; 218 } 219 220 - (GLuint)height 221 { 222 return self->_height; 223 } 224 225 - (void)bindForWidth:(GLuint)width andHeight:(GLuint)height 226 { 227 LOG(" GlassFrameBufferObject bindForWidth:%d andHeight:%d", width, height); 228 LOG(" context:%p", CGLGetCurrentContext()); 229 [self _assertContext]; 230 { 231 if ((width > 0) && (height > 0)) 232 { 233 if(self->_isSwPipe) 234 { 235 self->_fboToRestore = 0; // default to screen 236 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint*)&self->_fboToRestore); 237 LOG(" will need to restore to FBO: %d", self->_fboToRestore); 238 } 239 240 [self _createFboIfNeededForWidth:width andHeight:height]; 241 242 if (self->_isSwPipe && (self->_fbo != 0)) 243 { 244 GLuint framebufferToBind = self->_fbo; // our own FBO 245 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferToBind); 246 LOG(" bounded to FBO: %d", self->_fbo); 247 } 248 } 249 } 250 LOG(" BOUND"); 251 LOG(" glGetError(): %d", glGetError()); 252 } 253 254 - (void)unbind 255 { 256 if (self->_isSwPipe) 257 { 258 LOG(" GlassFrameBufferObject unbind"); 259 [self _assertContext]; 260 { 261 GLint framebufferCurrent = 0; 262 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &framebufferCurrent); 263 264 if ((GLuint)framebufferCurrent != self->_fbo) 265 { 266 fprintf(stderr, "ERROR: unexpected fbo is bound! Expected %d, but found %d\n", self->_fbo, framebufferCurrent); 267 } 268 269 if (![GlassApplication syncRenderingDisabled]) { 270 glFinish(); 271 } 272 GLuint framebufferToRevertTo = self->_fboToRestore; 273 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferToRevertTo); 274 LOG(" restored to FBO: %d", framebufferToRevertTo); 275 LOG(" glGetError(): %d", glGetError()); 276 } 277 } 278 } 279 280 - (void)blitForWidth:(GLuint)width andHeight:(GLuint)height 281 { 282 LOG(" GlassFrameBufferObject blitForWidth:%d andHeight:%d [%p]", width, height, self); 283 if (self->_texture != 0) 284 { 285 glMatrixMode(GL_PROJECTION); 286 glLoadIdentity(); 287 glOrtho(0.0f, width, height, 0.0f, -1.0f, 1.0f); 288 289 glMatrixMode(GL_MODELVIEW); 290 glLoadIdentity(); 291 292 glEnable(TARGET); 293 { 294 glActiveTextureARB(GL_TEXTURE0); 295 glBindTexture(TARGET, self->_texture); 296 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 297 { 298 glBegin(GL_QUADS); 299 { 318 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, (GLint*)&self->_fboToRestore); 319 [self _createFboIfNeededForWidth:other_fbo->_width andHeight:other_fbo->_height]; 320 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, self->_fbo); 321 glBindFramebuffer(GL_READ_FRAMEBUFFER, other_fbo->_fbo); 322 glBlitFramebuffer(0,0, other_fbo->_width, other_fbo->_height, 323 0,0, self->_width, self->_height, GL_COLOR_BUFFER_BIT, GL_LINEAR); 324 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, self->_fboToRestore); 325 } 326 327 328 - (GLuint)texture 329 { 330 return self->_texture; 331 } 332 333 - (GLuint)fbo 334 { 335 return self->_fbo; 336 } 337 338 - (void)setIsSwPipe:(BOOL)isSwPipe 339 { 340 self->_isSwPipe = isSwPipe; 341 } 342 343 @end |