filename | src/drivers/video_gdk.c |
changeset | 1236:d93175c36387 |
prev | 1066:ddffe9d2b332 |
author | nkeynes |
date | Fri Feb 24 21:17:47 2012 +1000 (11 years ago) |
permissions | -rw-r--r-- |
last change | Factor video_width/video_height out into video_gl.c Convert immediate-mode bits in video_gl.c into a structure for glDrawArray Move setOrtho into defineOrthoMatrix in glutil.c Rearrange various GL settings to keep a consistent state |
file | annotate | diff | log | raw |
nkeynes@635 | 1 | /** |
nkeynes@636 | 2 | * $Id$ |
nkeynes@635 | 3 | * |
nkeynes@635 | 4 | * The PC side of the video support (responsible for actually displaying / |
nkeynes@635 | 5 | * rendering frames) |
nkeynes@635 | 6 | * |
nkeynes@635 | 7 | * Copyright (c) 2005 Nathan Keynes. |
nkeynes@635 | 8 | * |
nkeynes@635 | 9 | * This program is free software; you can redistribute it and/or modify |
nkeynes@635 | 10 | * it under the terms of the GNU General Public License as published by |
nkeynes@635 | 11 | * the Free Software Foundation; either version 2 of the License, or |
nkeynes@635 | 12 | * (at your option) any later version. |
nkeynes@635 | 13 | * |
nkeynes@635 | 14 | * This program is distributed in the hope that it will be useful, |
nkeynes@635 | 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@635 | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@635 | 17 | * GNU General Public License for more details. |
nkeynes@635 | 18 | */ |
nkeynes@635 | 19 | #include <assert.h> |
nkeynes@635 | 20 | #include <stdlib.h> |
nkeynes@635 | 21 | #include <gdk/gdk.h> |
nkeynes@635 | 22 | #include <gdk-pixbuf/gdk-pixbuf.h> |
nkeynes@635 | 23 | #include <gtk/gtkwidget.h> |
nkeynes@661 | 24 | #include <GL/glu.h> |
nkeynes@635 | 25 | #include <GL/osmesa.h> |
nkeynes@635 | 26 | #include "lxdream.h" |
nkeynes@635 | 27 | #include "display.h" |
nkeynes@1236 | 28 | #include "video_gl.h" |
nkeynes@635 | 29 | |
nkeynes@635 | 30 | #define MAX_PIXBUF 16 |
nkeynes@635 | 31 | |
nkeynes@661 | 32 | extern GtkWidget *gtk_video_drawable; |
nkeynes@635 | 33 | |
nkeynes@635 | 34 | static render_buffer_t gdk_pixbuf_create_render_buffer( uint32_t width, uint32_t height ); |
nkeynes@635 | 35 | static void gdk_pixbuf_destroy_render_buffer( render_buffer_t buffer ); |
nkeynes@635 | 36 | static gboolean gdk_pixbuf_set_render_target( render_buffer_t buffer ); |
nkeynes@669 | 37 | static void gdk_pixbuf_display_render_buffer( render_buffer_t buffer ); |
nkeynes@635 | 38 | static void gdk_pixbuf_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer ); |
nkeynes@669 | 39 | static void gdk_pixbuf_display_blank( uint32_t colour ); |
nkeynes@635 | 40 | static gboolean gdk_pixbuf_read_render_buffer( unsigned char *target, render_buffer_t buffer, int rowstride, int format ); |
nkeynes@635 | 41 | |
nkeynes@635 | 42 | static void *pixbuf_array[MAX_PIXBUF]; |
nkeynes@635 | 43 | unsigned int pixbuf_max = 0; |
nkeynes@635 | 44 | OSMesaContext osmesa_context = NULL; |
nkeynes@635 | 45 | |
nkeynes@635 | 46 | void video_gdk_init_driver( display_driver_t driver ) |
nkeynes@635 | 47 | { |
nkeynes@635 | 48 | pixbuf_max = 0; |
nkeynes@635 | 49 | driver->create_render_buffer = gdk_pixbuf_create_render_buffer; |
nkeynes@635 | 50 | driver->destroy_render_buffer = gdk_pixbuf_destroy_render_buffer; |
nkeynes@635 | 51 | driver->set_render_target = gdk_pixbuf_set_render_target; |
nkeynes@635 | 52 | driver->display_render_buffer = gdk_pixbuf_display_render_buffer; |
nkeynes@635 | 53 | driver->load_frame_buffer = gdk_pixbuf_load_frame_buffer; |
nkeynes@635 | 54 | driver->display_blank = gdk_pixbuf_display_blank; |
nkeynes@635 | 55 | driver->read_render_buffer = gdk_pixbuf_read_render_buffer; |
nkeynes@635 | 56 | |
nkeynes@635 | 57 | osmesa_context = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, 0 ); |
nkeynes@635 | 58 | OSMesaMakeCurrent( osmesa_context, NULL, GL_UNSIGNED_BYTE, 640, 480 ); |
nkeynes@639 | 59 | pvr2_setup_gl_context(); |
nkeynes@635 | 60 | } |
nkeynes@635 | 61 | |
nkeynes@635 | 62 | int video_gdk_find_free() |
nkeynes@635 | 63 | { |
nkeynes@635 | 64 | unsigned int i; |
nkeynes@635 | 65 | for( i=0; i<pixbuf_max; i++ ) { |
nkeynes@736 | 66 | if( pixbuf_array[i] == NULL ) { |
nkeynes@736 | 67 | return i; |
nkeynes@736 | 68 | } |
nkeynes@635 | 69 | } |
nkeynes@635 | 70 | if( i < MAX_PIXBUF ) { |
nkeynes@736 | 71 | return pixbuf_max++; |
nkeynes@635 | 72 | } |
nkeynes@635 | 73 | return -1; |
nkeynes@635 | 74 | } |
nkeynes@635 | 75 | |
nkeynes@635 | 76 | void video_gdk_shutdown() |
nkeynes@635 | 77 | { |
nkeynes@635 | 78 | unsigned int i; |
nkeynes@635 | 79 | for( i=0; i<pixbuf_max; i++ ) { |
nkeynes@736 | 80 | if( pixbuf_array[i] != NULL ) { |
nkeynes@736 | 81 | g_free(pixbuf_array[i]); |
nkeynes@736 | 82 | pixbuf_array[i] = NULL; |
nkeynes@736 | 83 | } |
nkeynes@635 | 84 | } |
nkeynes@635 | 85 | pixbuf_max = 0; |
nkeynes@635 | 86 | OSMesaDestroyContext( osmesa_context ); |
nkeynes@635 | 87 | } |
nkeynes@635 | 88 | |
nkeynes@635 | 89 | |
nkeynes@635 | 90 | static render_buffer_t gdk_pixbuf_create_render_buffer( uint32_t width, uint32_t height ) |
nkeynes@635 | 91 | { |
nkeynes@635 | 92 | render_buffer_t buf = g_malloc0(sizeof(struct render_buffer)); |
nkeynes@635 | 93 | gboolean alpha = FALSE; |
nkeynes@635 | 94 | buf->width = width; |
nkeynes@635 | 95 | buf->height = height; |
nkeynes@635 | 96 | buf->buf_id = video_gdk_find_free(); |
nkeynes@635 | 97 | pixbuf_array[buf->buf_id] = g_malloc0( width * height * 4 ); |
nkeynes@635 | 98 | return buf; |
nkeynes@635 | 99 | } |
nkeynes@635 | 100 | |
nkeynes@635 | 101 | static void gdk_pixbuf_destroy_render_buffer( render_buffer_t buffer ) |
nkeynes@635 | 102 | { |
nkeynes@635 | 103 | g_free(pixbuf_array[buffer->buf_id] ); |
nkeynes@635 | 104 | pixbuf_array[buffer->buf_id] = NULL; |
nkeynes@635 | 105 | if( buffer->buf_id == (pixbuf_max-1) ) { |
nkeynes@736 | 106 | pixbuf_max--; |
nkeynes@635 | 107 | } |
nkeynes@635 | 108 | } |
nkeynes@635 | 109 | |
nkeynes@669 | 110 | static void gdk_pixbuf_display_render_buffer( render_buffer_t buffer ) |
nkeynes@635 | 111 | { |
nkeynes@635 | 112 | glFinish(); |
nkeynes@635 | 113 | |
nkeynes@635 | 114 | void *pb = pixbuf_array[buffer->buf_id]; |
nkeynes@661 | 115 | GdkGC *gc = gtk_video_drawable->style->fg_gc[GTK_STATE_NORMAL]; |
nkeynes@635 | 116 | GdkColor black = {0,0,0,0}; |
nkeynes@635 | 117 | |
nkeynes@635 | 118 | assert(gc); |
nkeynes@635 | 119 | |
nkeynes@635 | 120 | int x1=0,y1=0,x2=video_width,y2=video_height; |
nkeynes@635 | 121 | |
nkeynes@635 | 122 | int ah = video_width * 0.75; |
nkeynes@635 | 123 | |
nkeynes@635 | 124 | |
nkeynes@635 | 125 | if( ah > video_height ) { |
nkeynes@736 | 126 | int w = (video_height/0.75); |
nkeynes@736 | 127 | x1 = (video_width - w)/2; |
nkeynes@736 | 128 | x2 -= x1; |
nkeynes@736 | 129 | gdk_gc_set_foreground( gc, &black ); |
nkeynes@736 | 130 | gdk_gc_set_background( gc, &black ); |
nkeynes@736 | 131 | gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, x1, video_height ); |
nkeynes@736 | 132 | gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, x2, 0, video_width, video_height ); |
nkeynes@635 | 133 | } else if( ah < video_height ) { |
nkeynes@736 | 134 | y1 = (video_height - ah)/2; |
nkeynes@736 | 135 | y2 -= y1; |
nkeynes@736 | 136 | gdk_gc_set_foreground( gc, &black ); |
nkeynes@736 | 137 | gdk_gc_set_background( gc, &black ); |
nkeynes@736 | 138 | gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, video_width, y1 ); |
nkeynes@736 | 139 | gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, y2, video_width, video_height ); |
nkeynes@635 | 140 | } |
nkeynes@635 | 141 | int w = x2-x1; |
nkeynes@635 | 142 | int h = y2-y1; |
nkeynes@736 | 143 | |
nkeynes@635 | 144 | if( w != buffer->width || h != buffer->height ) { |
nkeynes@736 | 145 | gdk_draw_rgb_32_image( gtk_video_drawable->window, gc, x1, y1, buffer->width, buffer->height, GDK_RGB_DITHER_NONE, |
nkeynes@736 | 146 | pb, buffer->width*4 ); |
nkeynes@635 | 147 | } else { |
nkeynes@736 | 148 | gdk_draw_rgb_32_image( gtk_video_drawable->window, gc, x1, y1, buffer->width, buffer->height, GDK_RGB_DITHER_NONE, |
nkeynes@736 | 149 | pb, buffer->width*4 ); |
nkeynes@635 | 150 | } |
nkeynes@635 | 151 | } |
nkeynes@635 | 152 | |
nkeynes@669 | 153 | static void gdk_pixbuf_display_blank( uint32_t colour ) |
nkeynes@635 | 154 | { |
nkeynes@661 | 155 | GdkGC *gc = gtk_video_drawable->style->fg_gc[GTK_STATE_NORMAL]; |
nkeynes@635 | 156 | GdkColor col = { }; |
nkeynes@635 | 157 | |
nkeynes@635 | 158 | gdk_gc_set_foreground( gc, &col ); |
nkeynes@635 | 159 | gdk_gc_set_background( gc, &col ); |
nkeynes@661 | 160 | gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, video_width, video_height ); |
nkeynes@635 | 161 | } |
nkeynes@635 | 162 | |
nkeynes@635 | 163 | static gboolean gdk_pixbuf_set_render_target( render_buffer_t buffer ) |
nkeynes@635 | 164 | { |
nkeynes@635 | 165 | glFinish(); |
nkeynes@635 | 166 | void *pb = pixbuf_array[buffer->buf_id]; |
nkeynes@635 | 167 | OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE, |
nkeynes@736 | 168 | buffer->width, buffer->height ); |
nkeynes@635 | 169 | //OSMesaPixelStore( OSMESA_Y_UP, 0 ); |
nkeynes@635 | 170 | glViewport( 0, 0, buffer->width, buffer->height ); |
nkeynes@635 | 171 | glDrawBuffer(GL_FRONT); |
nkeynes@635 | 172 | return TRUE; |
nkeynes@635 | 173 | } |
nkeynes@635 | 174 | |
nkeynes@635 | 175 | static void gdk_pixbuf_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer ) |
nkeynes@635 | 176 | { |
nkeynes@635 | 177 | glFinish(); |
nkeynes@635 | 178 | void *pb = pixbuf_array[buffer->buf_id]; |
nkeynes@635 | 179 | OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE, |
nkeynes@736 | 180 | buffer->width, buffer->height ); |
nkeynes@635 | 181 | GLenum type = colour_formats[frame->colour_format].type; |
nkeynes@635 | 182 | GLenum format = colour_formats[frame->colour_format].format; |
nkeynes@635 | 183 | int bpp = colour_formats[frame->colour_format].bpp; |
nkeynes@635 | 184 | int rowstride = (frame->rowstride / bpp) - frame->width; |
nkeynes@736 | 185 | |
nkeynes@635 | 186 | gl_reset_state(); |
nkeynes@635 | 187 | glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride ); |
nkeynes@635 | 188 | glRasterPos2f(0.375, frame->height-0.375); |
nkeynes@635 | 189 | glPixelZoom( 1.0, 1.0 ); |
nkeynes@635 | 190 | glDrawPixels( frame->width, frame->height, format, type, frame->data ); |
nkeynes@635 | 191 | glFlush(); |
nkeynes@635 | 192 | } |
nkeynes@635 | 193 | |
nkeynes@635 | 194 | static gboolean gdk_pixbuf_read_render_buffer( unsigned char *target, render_buffer_t buffer, int rowstride, int format ) |
nkeynes@635 | 195 | { |
nkeynes@635 | 196 | glFinish(); |
nkeynes@635 | 197 | void *pb = pixbuf_array[buffer->buf_id]; |
nkeynes@635 | 198 | OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE, |
nkeynes@736 | 199 | buffer->width, buffer->height ); |
nkeynes@635 | 200 | glReadBuffer( GL_FRONT ); |
nkeynes@635 | 201 | return gl_read_render_buffer( target, buffer, rowstride, format ); |
nkeynes@635 | 202 | |
nkeynes@635 | 203 | } |
.