Search
lxdream.org :: lxdream :: r443:1163eb5c0590
lxdream 0.9.1
released Jun 29
Download Now
changeset443:1163eb5c0590
parent442:c0dcf22c8e08
child444:74c38d57eb11
authornkeynes
dateSat Oct 13 04:01:02 2007 +0000 (16 years ago)
Add ability to track the last displayed buffer, and handle expose/resize
events appropriately
src/drivers/gl_common.c
src/drivers/gl_common.h
src/drivers/gl_fbo.c
src/drivers/video_gtk.c
1.1 --- a/src/drivers/gl_common.c Sat Oct 13 04:00:23 2007 +0000
1.2 +++ b/src/drivers/gl_common.c Sat Oct 13 04:01:02 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: gl_common.c,v 1.3 2007-10-08 11:49:35 nkeynes Exp $
1.6 + * $Id: gl_common.c,v 1.4 2007-10-13 04:01:02 nkeynes Exp $
1.7 *
1.8 * Common GL code that doesn't depend on a specific implementation
1.9 *
1.10 @@ -16,11 +16,20 @@
1.11 * GNU General Public License for more details.
1.12 */
1.13
1.14 +#include <sys/time.h>
1.15 +
1.16 #include <GL/gl.h>
1.17 #include "dream.h"
1.18 #include "drivers/gl_common.h"
1.19
1.20 extern uint32_t video_width, video_height;
1.21 +static GLuint frame_last_texid = 0, fbuf_id = 0;
1.22 +static uint32_t frame_width = 0;
1.23 +static uint32_t frame_height = 0;
1.24 +static uint32_t frame_colour = 0;
1.25 +static gboolean frame_inverted = FALSE;
1.26 +
1.27 +
1.28
1.29 char *required_extensions[] = { "GL_EXT_framebuffer_object", NULL };
1.30
1.31 @@ -71,55 +80,76 @@
1.32 return isOK;
1.33 }
1.34
1.35 -
1.36 -gboolean gl_display_frame_buffer( frame_buffer_t frame )
1.37 +void gl_frame_buffer_to_tex_rectangle( frame_buffer_t frame, GLuint texid )
1.38 {
1.39 GLenum type = colour_formats[frame->colour_format].type;
1.40 GLenum format = colour_formats[frame->colour_format].format;
1.41 int bpp = colour_formats[frame->colour_format].bpp;
1.42 + int rowstride = (frame->rowstride / bpp) - frame->width;
1.43 +
1.44 + glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
1.45 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texid );
1.46 + glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
1.47 + frame->width, frame->height, 0, format, type, frame->data );
1.48 +}
1.49
1.50 +void gl_display_tex_rectangle( GLuint texid, uint32_t tex_width, uint32_t tex_height, gboolean invert )
1.51 +{
1.52 + float top, bottom;
1.53 + if( invert ) {
1.54 + top = ((float)tex_height) - 0.5;
1.55 + bottom = 0.5;
1.56 + } else {
1.57 + top = 0.5;
1.58 + bottom = ((float)tex_height) - 0.5;
1.59 + }
1.60 +
1.61 + /* Reset display parameters */
1.62 glViewport( 0, 0, video_width, video_height );
1.63 glMatrixMode(GL_PROJECTION);
1.64 glLoadIdentity();
1.65 glOrtho( 0, video_width, video_height, 0, 0, -65535 );
1.66 glMatrixMode(GL_MODELVIEW);
1.67 glLoadIdentity();
1.68 -
1.69 - /* Disable everything */
1.70 glDisable( GL_TEXTURE_2D );
1.71 glDisable( GL_ALPHA_TEST );
1.72 glDisable( GL_DEPTH_TEST );
1.73 glDisable( GL_SCISSOR_TEST );
1.74 glDisable( GL_CULL_FACE );
1.75
1.76 - float scale = ((float)video_height) / frame->height;
1.77 - int rowstride = (frame->rowstride / bpp) - frame->width;
1.78 -
1.79 -
1.80 - /*
1.81 - glGenTextures( 1, &texid );
1.82 - glBindTexture( GL_TEXTURE_2D, texid );
1.83 - glTexImage2D( GL_TEXTURE_2D, 0, colour_formats[frame->colour_format].int_format,
1.84 - frame->width, frame->height, 0, format, type, frame->data );
1.85 + /* Render the textured rectangle */
1.86 + glEnable( GL_TEXTURE_RECTANGLE_ARB );
1.87 + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texid );
1.88 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
1.89 + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1.90 + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1.91 + glEnable( GL_BLEND );
1.92 + glBlendFunc( GL_ONE, GL_ZERO );
1.93 glBegin( GL_QUADS );
1.94 - glTexCoord2i( 0, 1.0 );
1.95 + glTexCoord2f( 0.5, top );
1.96 glVertex2f( 0.0, 0.0 );
1.97 - glTexCoord2i( 1.0, 1.0 );
1.98 - glVertex2f( frame->width, 0.0 );
1.99 - glTexCoord2i( 1.0, 0.0 );
1.100 - glVertex2f( frame->width, frame->height );
1.101 - glTexCoord2i( 0, 0.0 );
1.102 - glVertex2f( 0.0, frame->height );
1.103 + glTexCoord2f( ((float)tex_width)-0.5, top );
1.104 + glVertex2f( video_width, 0.0 );
1.105 + glTexCoord2f( ((float)tex_width)-0.5, bottom );
1.106 + glVertex2f( video_width, video_height );
1.107 + glTexCoord2f( 0.5, bottom );
1.108 + glVertex2f( 0.0, video_height );
1.109 glEnd();
1.110 - glDeleteTextures( 1, &texid );
1.111 - */
1.112 - glRasterPos2i( 0, 0 );
1.113 - glPixelZoom( 1.0f, -scale );
1.114 - glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
1.115 - glDrawPixels( frame->width, frame->height, format, type,
1.116 - frame->data );
1.117 -
1.118 + glDisable( GL_TEXTURE_RECTANGLE_ARB );
1.119 glFlush();
1.120 + frame_last_texid = texid;
1.121 + frame_width = tex_width;
1.122 + frame_height = tex_height;
1.123 + frame_inverted = invert;
1.124 +}
1.125 +
1.126 +gboolean gl_display_frame_buffer( frame_buffer_t frame )
1.127 +{
1.128 + if( fbuf_id == 0 ) {
1.129 + glGenTextures( 1, &fbuf_id );
1.130 + }
1.131 + gl_frame_buffer_to_tex_rectangle( frame, fbuf_id );
1.132 + gl_display_tex_rectangle( fbuf_id, frame->width, frame->height, FALSE );
1.133 return TRUE;
1.134 }
1.135
1.136 @@ -134,9 +164,20 @@
1.137 glColor3b( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );
1.138 glRecti(0,0, video_width, video_height );
1.139 glFlush();
1.140 + frame_colour = colour;
1.141 + frame_last_texid = 0;
1.142 return TRUE;
1.143 }
1.144
1.145 +void gl_redisplay_last()
1.146 +{
1.147 + if( frame_last_texid == 0 ) {
1.148 + gl_display_blank( frame_colour );
1.149 + } else {
1.150 + gl_display_tex_rectangle( frame_last_texid, frame_width, frame_height, frame_inverted );
1.151 + }
1.152 +}
1.153 +
1.154 /**
1.155 * Generic GL read_render_buffer. This function assumes that the caller
1.156 * has already set the appropriate glReadBuffer(); in other words, unless
2.1 --- a/src/drivers/gl_common.h Sat Oct 13 04:00:23 2007 +0000
2.2 +++ b/src/drivers/gl_common.h Sat Oct 13 04:01:02 2007 +0000
2.3 @@ -1,5 +1,5 @@
2.4 /**
2.5 - * $Id: gl_common.h,v 1.3 2007-10-08 11:49:35 nkeynes Exp $
2.6 + * $Id: gl_common.h,v 1.4 2007-10-13 04:01:02 nkeynes Exp $
2.7 *
2.8 * Parent for all X11 display drivers.
2.9 *
2.10 @@ -40,6 +40,20 @@
2.11 */
2.12 gboolean gl_display_blank( uint32_t colour );
2.13
2.14 +/**
2.15 + * Copy the frame buffer contents to the specified texture id
2.16 + */
2.17 +void gl_frame_buffer_to_tex_rectangle( frame_buffer_t frame, GLuint texid );
2.18 +
2.19 +/**
2.20 + * Write a rectangular texture (GL_TEXTURE_RECTANGLE_ARB) to the display frame
2.21 + */
2.22 +void gl_display_tex_rectangle( GLuint texid, uint32_t texwidth, uint32_t texheight, gboolean invert );
2.23 +
2.24 +/**
2.25 + * Redisplay the last frame.
2.26 + */
2.27 +void gl_redisplay_last();
2.28
2.29 /**
2.30 * Generic GL read_render_buffer. This function assumes that the caller
3.1 --- a/src/drivers/gl_fbo.c Sat Oct 13 04:00:23 2007 +0000
3.2 +++ b/src/drivers/gl_fbo.c Sat Oct 13 04:01:02 2007 +0000
3.3 @@ -1,5 +1,5 @@
3.4 /**
3.5 - * $Id: gl_fbo.c,v 1.4 2007-10-11 11:08:36 nkeynes Exp $
3.6 + * $Id: gl_fbo.c,v 1.5 2007-10-13 04:01:02 nkeynes Exp $
3.7 *
3.8 * GL framebuffer-based driver shell. This requires the EXT_framebuffer_object
3.9 * extension, but is much nicer/faster/etc than pbuffers when it's available.
3.10 @@ -245,14 +245,16 @@
3.11 {
3.12 glFinish();
3.13 glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // real window
3.14 + glDrawBuffer( GL_FRONT );
3.15 + glReadBuffer( GL_FRONT );
3.16 + gl_display_tex_rectangle( buffer->buf_id, buffer->width, buffer->height, TRUE );
3.17 + /*
3.18 glViewport( 0, 0, video_width, video_height );
3.19 glEnable( GL_TEXTURE_RECTANGLE_ARB );
3.20 glBindTexture( GL_TEXTURE_RECTANGLE_ARB, buffer->buf_id );
3.21 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
3.22 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
3.23 glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
3.24 - glDrawBuffer( GL_FRONT );
3.25 - glReadBuffer( GL_FRONT );
3.26 glDisable( GL_ALPHA_TEST );
3.27 glDisable( GL_DEPTH_TEST );
3.28 glDisable( GL_SCISSOR_TEST );
3.29 @@ -278,6 +280,7 @@
3.30 glEnd();
3.31 glDisable( GL_TEXTURE_RECTANGLE_ARB );
3.32 glFlush();
3.33 + */
3.34 return TRUE;
3.35 }
3.36
4.1 --- a/src/drivers/video_gtk.c Sat Oct 13 04:00:23 2007 +0000
4.2 +++ b/src/drivers/video_gtk.c Sat Oct 13 04:01:02 2007 +0000
4.3 @@ -1,5 +1,5 @@
4.4 /**
4.5 - * $Id: video_gtk.c,v 1.14 2007-10-11 08:20:38 nkeynes Exp $
4.6 + * $Id: video_gtk.c,v 1.15 2007-10-13 04:01:02 nkeynes Exp $
4.7 *
4.8 * The PC side of the video support (responsible for actually displaying /
4.9 * rendering frames)
4.10 @@ -64,24 +64,20 @@
4.11
4.12 gboolean video_gtk_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data )
4.13 {
4.14 - /* redisplay last frame */
4.15 + gl_redisplay_last();
4.16 + return TRUE;
4.17 }
4.18
4.19 gboolean video_gtk_resize_callback(GtkWidget *widget, GdkEventConfigure *event, gpointer data )
4.20 {
4.21 video_width = event->width;
4.22 video_height = event->height;
4.23 + gl_redisplay_last();
4.24 + return TRUE;
4.25 }
4.26
4.27 gboolean video_gtk_init()
4.28 {
4.29 - /*
4.30 - video_win = GTK_WINDOW(gtk_window_new( GTK_WINDOW_TOPLEVEL ));
4.31 - gtk_window_set_title( video_win, APP_NAME " - Emulation Window" );
4.32 - gtk_window_set_policy( video_win, FALSE, FALSE, FALSE );
4.33 - gtk_window_set_default_size( video_win, video_width, video_height );
4.34 - */
4.35 -
4.36 video_win = gtk_gui_get_renderarea();
4.37
4.38 g_signal_connect( video_win, "key_press_event",
4.39 @@ -95,6 +91,7 @@
4.40 gtk_widget_add_events( video_win,
4.41 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
4.42 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK );
4.43 + gtk_widget_set_double_buffered( video_win, FALSE );
4.44 video_width = video_win->allocation.width;
4.45 video_height = video_win->allocation.height;
4.46 return video_glx_init( gdk_x11_display_get_xdisplay( gtk_widget_get_display(GTK_WIDGET(video_win))),
.