Search
lxdream.org :: lxdream :: r805:b355f7b3ff2e
lxdream 0.9.1
released Jun 29
Download Now
changeset805:b355f7b3ff2e
parent804:567a684e1e7a
child806:6ef1ce4a9dbc
authornkeynes
dateThu Aug 07 23:53:17 2008 +0000 (11 years ago)
Add ability to bind a render buffer to a texture, with output going to the texture.
(RTT work in progress)
src/display.h
src/drivers/gl_fbo.c
src/drivers/video_glx.c
src/drivers/video_gtk.c
src/drivers/video_null.c
src/drivers/video_osx.c
src/pvr2/pvr2.c
1.1 --- a/src/display.h Thu Aug 07 23:50:52 2008 +0000
1.2 +++ b/src/display.h Thu Aug 07 23:53:17 2008 +0000
1.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.14
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 ID
1.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 to
1.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.24
1.25 /**
1.26 * Destroy the specified render buffer and release any associated
1.27 @@ -154,6 +159,12 @@
1.28 gboolean (*set_render_target)( render_buffer_t buffer );
1.29
1.30 /**
1.31 + * Complete rendering and clear the current rendering target. If the
1.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 +0000
2.2 +++ b/src/drivers/gl_fbo.c Thu Aug 07 23:53:17 2008 +0000
2.3 @@ -35,9 +35,10 @@
2.4 #define MAX_FRAMEBUFFERS 2
2.5 #define MAX_TEXTURES_PER_FB 16
2.6
2.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.26
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.55
2.56 +/**
2.57 + * Ensure the texture in the given render buffer is not attached to a
2.58 + * framebuffer (ie, so we can safely use it as a texture during the rendering
2.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.108
2.109 @@ -248,6 +277,13 @@
2.110 return TRUE;
2.111 }
2.112
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 window
2.122 * buffer.
3.1 --- a/src/drivers/video_glx.c Thu Aug 07 23:50:52 2008 +0000
3.2 +++ b/src/drivers/video_glx.c Thu Aug 07 23:53:17 2008 +0000
3.3 @@ -44,9 +44,10 @@
3.4
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.26
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.39
3.40 @@ -312,6 +315,18 @@
3.41 return TRUE;
3.42 }
3.43
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 window
3.58 * buffer.
4.1 --- a/src/drivers/video_gtk.c Thu Aug 07 23:50:52 2008 +0000
4.2 +++ b/src/drivers/video_gtk.c Thu Aug 07 23:53:17 2008 +0000
4.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.10
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 +0000
5.2 +++ b/src/drivers/video_null.c Thu Aug 07 23:53:17 2008 +0000
5.3 @@ -18,7 +18,7 @@
5.4
5.5 #include "display.h"
5.6
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.15
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 +0000
6.2 +++ b/src/drivers/video_osx.c Thu Aug 07 23:53:17 2008 +0000
6.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 };
6.11
6.12
7.1 --- a/src/pvr2/pvr2.c Thu Aug 07 23:50:52 2008 +0000
7.2 +++ b/src/pvr2/pvr2.c Thu Aug 07 23:53:17 2008 +0000
7.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 }
.