[qfusion-cvs-commits] SF.net SVN: l33t:[813] trunk/qfusion/source/ref_gl/r_framebuffer.c
Brought to you by:
digiman
|
From: qfusion s. c. <l33...@li...> - 2009-02-07 22:22:16
|
Revision: 813
http://l33t.svn.sourceforge.net/l33t/?rev=813&view=rev
Author: digiman
Date: 2009-02-07 21:48:37 +0000 (Sat, 07 Feb 2009)
Log Message:
-----------
Added Paths:
-----------
trunk/qfusion/source/ref_gl/r_framebuffer.c
Added: trunk/qfusion/source/ref_gl/r_framebuffer.c
===================================================================
--- trunk/qfusion/source/ref_gl/r_framebuffer.c (rev 0)
+++ trunk/qfusion/source/ref_gl/r_framebuffer.c 2009-02-07 21:48:37 UTC (rev 813)
@@ -0,0 +1,270 @@
+/*
+Copyright (C) 2008 Victor Luchits
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+// r_framebuffer.c - Framebuffer Objects support
+
+#include "r_local.h"
+
+#define MAX_FRAMEBUFFER_OBJECTS 1024
+
+typedef struct
+{
+ int objectID;
+ int renderBufferAttachment;
+ image_t *textureAttachment;
+} r_fbo_t;
+
+static qboolean r_frambuffer_objects_initialized;
+static int r_bound_framebuffer_object;
+static int r_num_framebuffer_objects;
+static r_fbo_t r_framebuffer_objects[MAX_FRAMEBUFFER_OBJECTS];
+
+/*
+================
+R_InitFBObjects
+================
+*/
+void R_InitFBObjects( void )
+{
+ if( !glConfig.ext.framebuffer_object )
+ return;
+
+ r_num_framebuffer_objects = 0;
+ memset( r_framebuffer_objects, 0, sizeof( r_framebuffer_objects ) );
+
+ qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+ r_bound_framebuffer_object = 0;
+
+ r_frambuffer_objects_initialized = qtrue;
+}
+
+/*
+================
+R_DeleteFBObject
+
+Delete framebuffer object along with attached render buffer
+================
+*/
+static void R_DeleteFBObject( r_fbo_t *fbo )
+{
+ GLuint t;
+
+ if( fbo->renderBufferAttachment )
+ {
+ t = fbo->renderBufferAttachment;
+ qglDeleteRenderbuffersEXT( 1, &t );
+ fbo->renderBufferAttachment = 0;
+ }
+
+ if( fbo->objectID )
+ {
+ t = fbo->objectID;
+ qglDeleteFramebuffersEXT( 1, &t );
+ fbo->objectID = 0;
+ }
+}
+
+/*
+================
+R_RegisterFBObject
+================
+*/
+int R_RegisterFBObject( void )
+{
+ int i;
+ GLuint fbID;
+ r_fbo_t *fbo;
+
+ if( !r_frambuffer_objects_initialized )
+ return 0;
+ if( r_num_framebuffer_objects == MAX_FRAMEBUFFER_OBJECTS )
+ {
+ Com_Printf( S_COLOR_YELLOW "R_RegisterFBObject: framebuffer objects limit exceeded\n" );
+ return 0;
+ }
+
+ qglGenFramebuffersEXT( 1, &fbID );
+
+ i = r_num_framebuffer_objects++;
+ fbo = r_framebuffer_objects + i;
+ memset( fbo, 0, sizeof( *fbo ) );
+ fbo->objectID = fbID;
+
+ return i+1;
+}
+
+/*
+================
+R_ActiveFBObject
+================
+*/
+int R_ActiveFBObject( void )
+{
+ return r_bound_framebuffer_object;
+}
+
+/*
+================
+R_UseFBObject
+================
+*/
+qboolean R_UseFBObject( int object )
+{
+ qboolean status;
+
+ if( !object )
+ {
+ if( r_frambuffer_objects_initialized )
+ qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+ r_bound_framebuffer_object = 0;
+
+ return r_frambuffer_objects_initialized;
+ }
+
+ assert( object > 0 && object <= r_num_framebuffer_objects );
+
+ qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, r_framebuffer_objects[object-1].objectID );
+ r_bound_framebuffer_object = object;
+
+ status = R_CheckFBObjectStatus ();
+
+ return status;
+}
+
+/*
+================
+R_AttachTextureToFBOject
+================
+*/
+qboolean R_AttachTextureToFBOject( int object, image_t *texture, qboolean depthOnly )
+{
+ r_fbo_t *fbo;
+ qboolean status;
+
+ if( !object )
+ return qfalse;
+ if( !r_frambuffer_objects_initialized )
+ return qfalse;
+
+ assert( object > 0 && object <= r_num_framebuffer_objects );
+ assert( texture );
+
+ fbo = r_framebuffer_objects + object - 1;
+
+ qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo->objectID );
+
+ if( depthOnly )
+ {
+ // Set up depth_tex for render-to-texture
+ qglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texture->texnum, 0 );
+
+ // inform the driver we do not wish to render to the color buffer
+ qglDrawBuffer( GL_NONE );
+ qglReadBuffer( GL_NONE );
+ }
+ else
+ {
+ // initialize depth renderbuffer
+ if( !fbo->renderBufferAttachment )
+ {
+ GLuint rbID;
+ qglGenRenderbuffersEXT( 1, &rbID );
+ fbo->renderBufferAttachment = rbID;
+ }
+
+ // setup 24bit depth buffer for render-to-texture
+ qglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, fbo->renderBufferAttachment );
+ qglRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,
+ texture->upload_width, texture->upload_height );
+ qglBindRenderbufferEXT( GL_RENDERBUFFER_EXT, 0 );
+
+ // attach depth renderbuffer
+ qglFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT, fbo->renderBufferAttachment );
+
+ // attach texture
+ qglFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ (texture->upload_depth != 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D), texture->texnum, 0 );
+ fbo->textureAttachment = texture;
+ }
+
+ status = R_CheckFBObjectStatus ();
+
+ if( r_bound_framebuffer_object )
+ qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, r_framebuffer_objects[r_bound_framebuffer_object-1].objectID );
+ else
+ qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+
+ return status;
+}
+
+/*
+================
+R_CheckFBObjectStatus
+
+Boolean, returns qfalse in case of error
+================
+*/
+qboolean R_CheckFBObjectStatus( void )
+{
+ GLenum status;
+
+ if( !r_frambuffer_objects_initialized )
+ return qfalse;
+
+ status = qglCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
+ switch( status )
+ {
+ case GL_FRAMEBUFFER_COMPLETE_EXT:
+ return qtrue;
+ case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+ return qfalse;
+ default:
+ // programming error; will fail on all hardware
+ assert( 0 );
+ }
+
+ return qfalse;
+}
+
+/*
+================
+R_ShutdownFBObjects
+
+Delete all registered framebuffer and render buffer objects, clear memory
+================
+*/
+void R_ShutdownFBObjects( void )
+{
+ int i;
+
+ if( !r_frambuffer_objects_initialized )
+ return;
+
+ for( i = 0; i < r_num_framebuffer_objects; i++ )
+ R_DeleteFBObject( r_framebuffer_objects + i );
+
+ qglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
+ r_bound_framebuffer_object = 0;
+
+ r_frambuffer_objects_initialized = qfalse;
+ r_num_framebuffer_objects = 0;
+ memset( r_framebuffer_objects, 0, sizeof( r_framebuffer_objects ) );
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|