Search
lxdream.org :: lxdream/src/drivers/gl_fbo.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/gl_fbo.c
changeset 805:b355f7b3ff2e
prev798:eb5c0d1863cd
next857:3d8944884eaa
author nkeynes
date Thu Aug 07 23:53:17 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Add ability to bind a render buffer to a texture, with output going to the texture.
(RTT work in progress)
file annotate diff log raw
1.1 --- a/src/drivers/gl_fbo.c Sun Aug 03 02:55:27 2008 +0000
1.2 +++ b/src/drivers/gl_fbo.c Thu Aug 07 23:53:17 2008 +0000
1.3 @@ -35,9 +35,10 @@
1.4 #define MAX_FRAMEBUFFERS 2
1.5 #define MAX_TEXTURES_PER_FB 16
1.6
1.7 -static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height );
1.8 +static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height, GLuint tex_id );
1.9 static void gl_fbo_destroy_render_buffer( render_buffer_t buffer );
1.10 static gboolean gl_fbo_set_render_target( render_buffer_t buffer );
1.11 +static void gl_fbo_finish_render( render_buffer_t buffer );
1.12 static void gl_fbo_display_render_buffer( render_buffer_t buffer );
1.13 static void gl_fbo_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer );
1.14 static void gl_fbo_display_blank( uint32_t colour );
1.15 @@ -95,6 +96,7 @@
1.16 driver->create_render_buffer = gl_fbo_create_render_buffer;
1.17 driver->destroy_render_buffer = gl_fbo_destroy_render_buffer;
1.18 driver->set_render_target = gl_fbo_set_render_target;
1.19 + driver->finish_render = gl_fbo_finish_render;
1.20 driver->display_render_buffer = gl_fbo_display_render_buffer;
1.21 driver->load_frame_buffer = gl_fbo_load_frame_buffer;
1.22 driver->display_blank = gl_fbo_display_blank;
1.23 @@ -199,40 +201,67 @@
1.24 return ATTACHMENT_POINT(attach);
1.25 }
1.26
1.27 -static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height )
1.28 +static render_buffer_t gl_fbo_create_render_buffer( uint32_t width, uint32_t height, GLuint tex_id )
1.29 {
1.30 - GLuint tex;
1.31 render_buffer_t buffer = calloc( sizeof(struct render_buffer), 1 );
1.32 buffer->width = width;
1.33 buffer->height = height;
1.34 - glGenTextures( 1, &tex );
1.35 - buffer->buf_id = tex;
1.36 - glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex );
1.37 + buffer->tex_id = tex_id;
1.38 + if( tex_id == 0 ) {
1.39 + GLuint tex;
1.40 + glGenTextures( 1, &tex );
1.41 + buffer->buf_id = tex;
1.42 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex );
1.43 + glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
1.44 + } else {
1.45 + buffer->buf_id = tex_id;
1.46 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex_id );
1.47 + }
1.48 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP );
1.49 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP );
1.50 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
1.51 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
1.52 - glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
1.53 return buffer;
1.54 }
1.55
1.56 +/**
1.57 + * Ensure the texture in the given render buffer is not attached to a
1.58 + * framebuffer (ie, so we can safely use it as a texture during the rendering
1.59 + * cycle, or before deletion).
1.60 + */
1.61 +static void gl_fbo_detach_render_buffer( render_buffer_t buffer )
1.62 +{
1.63 + int i,j;
1.64 + for( i=0; i<MAX_FRAMEBUFFERS; i++ ) {
1.65 + if( fbo[i].width == buffer->width && fbo[i].height == buffer->height ) {
1.66 + for( j=0; j<gl_fbo_max_attachments; j++ ) {
1.67 + if( fbo[i].tex_ids[j] == buffer->buf_id ) {
1.68 + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo[i].fb_id);
1.69 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ATTACHMENT_POINT(j),
1.70 + GL_TEXTURE_RECTANGLE_ARB, GL_NONE, 0 );
1.71 + fbo[i].tex_ids[j] = -1;
1.72 + return;
1.73 + }
1.74 + }
1.75 + break;
1.76 + }
1.77 + }
1.78 +}
1.79 +
1.80 static void gl_fbo_destroy_render_buffer( render_buffer_t buffer )
1.81 {
1.82 int i,j;
1.83 - GLuint tex = buffer->buf_id;
1.84 - for( i=0; i<MAX_FRAMEBUFFERS; i++ ) {
1.85 - for( j=0; j < MAX_TEXTURES_PER_FB; j++ ) {
1.86 - if( fbo[i].tex_ids[j] == buffer->buf_id ) {
1.87 - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo[i].fb_id);
1.88 - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, ATTACHMENT_POINT(j),
1.89 - GL_TEXTURE_RECTANGLE_ARB, GL_NONE, 0 );
1.90 - fbo[i].tex_ids[j] = -1;
1.91 - }
1.92 - }
1.93 +
1.94 + gl_fbo_detach_render_buffer( buffer );
1.95 +
1.96 + if( buffer->buf_id != buffer->tex_id ) {
1.97 + // If tex_id was set at buffer creation, we don't own the texture.
1.98 + // Otherwise, delete it now.
1.99 + GLuint tex = buffer->buf_id;
1.100 + glDeleteTextures( 1, &tex );
1.101 }
1.102 -
1.103 - glDeleteTextures( 1, &tex );
1.104 buffer->buf_id = 0;
1.105 + buffer->tex_id = 0;
1.106 free( buffer );
1.107 }
1.108
1.109 @@ -248,6 +277,13 @@
1.110 return TRUE;
1.111 }
1.112
1.113 +static void gl_fbo_finish_render( render_buffer_t buffer )
1.114 +{
1.115 + glFinish();
1.116 + glGetError();
1.117 + gl_fbo_detach_render_buffer(buffer);
1.118 +}
1.119 +
1.120 /**
1.121 * Render the texture holding the given buffer to the front window
1.122 * buffer.
.