revision 805:b355f7b3ff2e
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 805:b355f7b3ff2e |
parent | 804:567a684e1e7a |
child | 806:6ef1ce4a9dbc |
author | nkeynes |
date | Thu Aug 07 23:53:17 2008 +0000 (15 years ago) |
Add ability to bind a render buffer to a texture, with output going to the texture.
(RTT work in progress)
(RTT work in progress)
1.1 --- a/src/display.h Thu Aug 07 23:50:52 2008 +00001.2 +++ b/src/display.h Thu Aug 07 23:53:17 2008 +00001.3 @@ -74,6 +74,8 @@1.4 uint32_t size; /* Size of buffer in bytes, must be width*height*bpp */1.5 gboolean inverted;/* True if the buffer is upside down */1.6 uint32_t scale;1.7 + GLuint tex_id; /* texture bound to render buffer, if any (0 = none).1.8 + * The render buffer does not own the texture */1.9 unsigned int buf_id; /* driver-specific buffer id, if applicable */1.10 gboolean flushed; /* True if the buffer has been flushed to vram */1.11 };1.12 @@ -138,9 +140,12 @@1.13 gchar *(*get_keysym_for_keycode)( uint16_t keycode );1.15 /**1.16 - * Create a render target with the given width and height.1.17 + * Create a render target with the given width and height. If a texture ID1.18 + * is supplied (non-zero), the render buffer writes its output to that texture.1.19 + * @param tex_id 0 or a valid GL texture name which must have been initialized to1.20 + * the correct dimensions.1.21 */1.22 - render_buffer_t (*create_render_buffer)( uint32_t width, uint32_t height );1.23 + render_buffer_t (*create_render_buffer)( uint32_t width, uint32_t height, GLuint tex_id );1.25 /**1.26 * Destroy the specified render buffer and release any associated1.27 @@ -154,6 +159,12 @@1.28 gboolean (*set_render_target)( render_buffer_t buffer );1.30 /**1.31 + * Complete rendering and clear the current rendering target. If the1.32 + * buffer has a bound texture, it will be updated if necessary.1.33 + */1.34 + void (*finish_render)( render_buffer_t buffer );1.35 +1.36 + /**1.37 * Load the supplied frame buffer into the given render buffer.1.38 * Included here to allow driver-specific optimizations.1.39 */
2.1 --- a/src/drivers/gl_fbo.c Thu Aug 07 23:50:52 2008 +00002.2 +++ b/src/drivers/gl_fbo.c Thu Aug 07 23:53:17 2008 +00002.3 @@ -35,9 +35,10 @@2.4 #define MAX_FRAMEBUFFERS 22.5 #define MAX_TEXTURES_PER_FB 162.7 -static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height );2.8 +static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height, GLuint tex_id );2.9 static void gl_fbo_destroy_render_buffer( render_buffer_t buffer );2.10 static gboolean gl_fbo_set_render_target( render_buffer_t buffer );2.11 +static void gl_fbo_finish_render( render_buffer_t buffer );2.12 static void gl_fbo_display_render_buffer( render_buffer_t buffer );2.13 static void gl_fbo_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer );2.14 static void gl_fbo_display_blank( uint32_t colour );2.15 @@ -95,6 +96,7 @@2.16 driver->create_render_buffer = gl_fbo_create_render_buffer;2.17 driver->destroy_render_buffer = gl_fbo_destroy_render_buffer;2.18 driver->set_render_target = gl_fbo_set_render_target;2.19 + driver->finish_render = gl_fbo_finish_render;2.20 driver->display_render_buffer = gl_fbo_display_render_buffer;2.21 driver->load_frame_buffer = gl_fbo_load_frame_buffer;2.22 driver->display_blank = gl_fbo_display_blank;2.23 @@ -199,40 +201,67 @@2.24 return ATTACHMENT_POINT(attach);2.25 }2.27 -static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height )2.28 +static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height, GLuint tex_id )2.29 {2.30 - GLuint tex;2.31 render_buffer_t buffer = calloc( sizeof(struct render_buffer), 1 );2.32 buffer->width = width;2.33 buffer->height = height;2.34 - glGenTextures( 1, &tex );2.35 - buffer->buf_id = tex;2.36 - glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex );2.37 + buffer->tex_id = tex_id;2.38 + if( tex_id == 0 ) {2.39 + GLuint tex;2.40 + glGenTextures( 1, &tex );2.41 + buffer->buf_id = tex;2.42 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex );2.43 + glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );2.44 + } else {2.45 + buffer->buf_id = tex_id;2.46 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex_id );2.47 + }2.48 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP );2.49 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP );2.50 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST );2.51 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST );2.52 - glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );2.53 return buffer;2.54 }2.56 +/**2.57 + * Ensure the texture in the given render buffer is not attached to a2.58 + * framebuffer (ie, so we can safely use it as a texture during the rendering2.59 + * cycle, or before deletion).2.60 + */2.61 +static void gl_fbo_detach_render_buffer( render_buffer_t buffer )2.62 +{2.63 + int i,j;2.64 + for( i=0; i<MAX_FRAMEBUFFERS; i++ ) {2.65 + if( fbo[i].width == buffer->width && fbo[i].height == buffer->height ) {2.66 + for( j=0; j<gl_fbo_max_attachments; j++ ) {2.67 + if( fbo[i].tex_ids[j] == buffer->buf_id ) {2.68 + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo[i].fb_id);2.69 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ATTACHMENT_POINT(j),2.70 + GL_TEXTURE_RECTANGLE_ARB, GL_NONE, 0 );2.71 + fbo[i].tex_ids[j] = -1;2.72 + return;2.73 + }2.74 + }2.75 + break;2.76 + }2.77 + }2.78 +}2.79 +2.80 static void gl_fbo_destroy_render_buffer( render_buffer_t buffer )2.81 {2.82 int i,j;2.83 - GLuint tex = buffer->buf_id;2.84 - for( i=0; i<MAX_FRAMEBUFFERS; i++ ) {2.85 - for( j=0; j < MAX_TEXTURES_PER_FB; j++ ) {2.86 - if( fbo[i].tex_ids[j] == buffer->buf_id ) {2.87 - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo[i].fb_id);2.88 - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ATTACHMENT_POINT(j),2.89 - GL_TEXTURE_RECTANGLE_ARB, GL_NONE, 0 );2.90 - fbo[i].tex_ids[j] = -1;2.91 - }2.92 - }2.93 +2.94 + gl_fbo_detach_render_buffer( buffer );2.95 +2.96 + if( buffer->buf_id != buffer->tex_id ) {2.97 + // If tex_id was set at buffer creation, we don't own the texture.2.98 + // Otherwise, delete it now.2.99 + GLuint tex = buffer->buf_id;2.100 + glDeleteTextures( 1, &tex );2.101 }2.102 -2.103 - glDeleteTextures( 1, &tex );2.104 buffer->buf_id = 0;2.105 + buffer->tex_id = 0;2.106 free( buffer );2.107 }2.109 @@ -248,6 +277,13 @@2.110 return TRUE;2.111 }2.113 +static void gl_fbo_finish_render( render_buffer_t buffer )2.114 +{2.115 + glFinish();2.116 + glGetError();2.117 + gl_fbo_detach_render_buffer(buffer);2.118 +}2.119 +2.120 /**2.121 * Render the texture holding the given buffer to the front window2.122 * buffer.
3.1 --- a/src/drivers/video_glx.c Thu Aug 07 23:50:52 2008 +00003.2 +++ b/src/drivers/video_glx.c Thu Aug 07 23:53:17 2008 +00003.3 @@ -44,9 +44,10 @@3.5 /* Prototypes for pbuffer support methods */3.6 static void glx_pbuffer_init( display_driver_t driver );3.7 -static render_buffer_t glx_pbuffer_create_render_buffer( uint32_t width, uint32_t height );3.8 +static render_buffer_t glx_pbuffer_create_render_buffer( uint32_t width, uint32_t height, GLuint tex_id );3.9 static void glx_pbuffer_destroy_render_buffer( render_buffer_t buffer );3.10 static gboolean glx_pbuffer_set_render_target( render_buffer_t buffer );3.11 +static void glx_pbuffer_finish_render( render_buffer_t buffer );3.12 static void glx_pbuffer_display_render_buffer( render_buffer_t buffer );3.13 static void glx_pbuffer_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer );3.14 static void glx_pbuffer_display_blank( uint32_t colour );3.15 @@ -265,6 +266,7 @@3.16 driver->create_render_buffer = glx_pbuffer_create_render_buffer;3.17 driver->destroy_render_buffer = glx_pbuffer_destroy_render_buffer;3.18 driver->set_render_target = glx_pbuffer_set_render_target;3.19 + driver->finish_render = glx_pbuffer_finish_render;3.20 driver->display_render_buffer = glx_pbuffer_display_render_buffer;3.21 driver->load_frame_buffer = glx_pbuffer_load_frame_buffer;3.22 driver->display_blank = glx_pbuffer_display_blank;3.23 @@ -276,7 +278,7 @@3.24 glDeleteTextures( 1, &glx_pbuffer_texture );3.25 }3.27 -static render_buffer_t glx_pbuffer_create_render_buffer( uint32_t width, uint32_t height )3.28 +static render_buffer_t glx_pbuffer_create_render_buffer( uint32_t width, uint32_t height, GLuint tex_id )3.29 {3.30 int attribs[] = { GLX_PBUFFER_WIDTH, width, GLX_PBUFFER_HEIGHT, height,3.31 GLX_PRESERVED_CONTENTS, True, 0 };3.32 @@ -289,6 +291,7 @@3.33 buffer->width = width;3.34 buffer->height = height;3.35 buffer->buf_id = pb;3.36 + buffer->tex_id = tex_id;3.37 return buffer;3.38 }3.40 @@ -312,6 +315,18 @@3.41 return TRUE;3.42 }3.44 +static void glx_pbuffer_finish_render( render_buffer_t buffer )3.45 +{3.46 + glFinish();3.47 + if( buffer->tex_id != 0 ) {3.48 + // The pbuffer should already be the current context, but just in case...3.49 + glXMakeContextCurrent( video_x11_display, (GLXPbuffer)buffer->buf_id, (GLXPbuffer)buffer->buf_id, glx_context );3.50 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, buffer->tex_id );3.51 + glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, buffer->width, buffer->height, 0 );3.52 + }3.53 +}3.54 +3.55 +3.56 /**3.57 * Render the texture holding the given buffer to the front window3.58 * buffer.
4.1 --- a/src/drivers/video_gtk.c Thu Aug 07 23:50:52 2008 +00004.2 +++ b/src/drivers/video_gtk.c Thu Aug 07 23:53:17 2008 +00004.3 @@ -135,7 +135,7 @@4.4 video_gtk_resolve_keysym,4.5 video_gtk_keycode_to_dckeysym,4.6 video_gtk_keycode_to_keysym,4.7 - NULL, NULL, NULL, NULL, NULL,4.8 + NULL, NULL, NULL, NULL, NULL, NULL,4.9 video_gtk_display_blank, NULL };4.11 gboolean video_gtk_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data )
5.1 --- a/src/drivers/video_null.c Thu Aug 07 23:50:52 2008 +00005.2 +++ b/src/drivers/video_null.c Thu Aug 07 23:53:17 2008 +00005.3 @@ -18,7 +18,7 @@5.5 #include "display.h"5.7 -static render_buffer_t video_null_create_render_buffer( uint32_t hres, uint32_t vres )5.8 +static render_buffer_t video_null_create_render_buffer( uint32_t hres, uint32_t vres, GLuint tex_id )5.9 {5.10 return NULL;5.11 }5.12 @@ -32,6 +32,10 @@5.13 return TRUE;5.14 }5.16 +static void video_null_finish_render( render_buffer_t buffer )5.17 +{5.18 +}5.19 +5.20 static void video_null_display_render_buffer( render_buffer_t buffer )5.21 {5.22 }5.23 @@ -64,6 +68,7 @@5.24 video_null_create_render_buffer,5.25 video_null_destroy_render_buffer,5.26 video_null_set_render_target,5.27 + video_null_finish_render,5.28 video_null_load_frame_buffer,5.29 video_null_display_render_buffer,5.30 video_null_display_blank,
6.1 --- a/src/drivers/video_osx.c Thu Aug 07 23:50:52 2008 +00006.2 +++ b/src/drivers/video_osx.c Thu Aug 07 23:53:17 2008 +00006.3 @@ -47,7 +47,8 @@6.4 video_osx_resolve_keysym,6.5 video_osx_keycode_to_dckeysym,6.6 video_osx_keycode_to_keysym,6.7 - NULL, NULL, NULL, NULL, NULL,6.8 + NULL, NULL, NULL, NULL, NULL,6.9 + NULL,6.10 video_osx_display_blank, NULL };
7.1 --- a/src/pvr2/pvr2.c Thu Aug 07 23:50:52 2008 +00007.2 +++ b/src/pvr2/pvr2.c Thu Aug 07 23:53:17 2008 +00007.3 @@ -917,14 +917,14 @@7.4 }7.5 if( result->width != width || result->height != height ) {7.6 display_driver->destroy_render_buffer(render_buffers[i]);7.7 - result = display_driver->create_render_buffer(width,height);7.8 + result = display_driver->create_render_buffer(width,height,0);7.9 render_buffers[i] = result;7.10 }7.11 break;7.12 }7.13 }7.14 } else {7.15 - result = display_driver->create_render_buffer(width,height);7.16 + result = display_driver->create_render_buffer(width,height,0);7.17 if( result != NULL ) {7.18 render_buffers[render_buffer_count++] = result;7.19 }
.