Search
lxdream.org :: lxdream/src/drivers/video_gl.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/video_gl.c
changeset 1076:18c164e8aec4
prev854:130928a3cdcb
next1222:a4545699a82b
author nkeynes
date Mon Aug 03 08:41:11 2009 +1000 (10 years ago)
permissions -rw-r--r--
last change Rearrange frame output slightly.
pvr2_display_frame renamed to pvr2_next_frame and changed to update the
frame data without displaying it.
pvr2_redraw_display renamed to pvr2_draw_frame, called internally after
pvr2_next_frame
Add swap_buffers() method to the display driver
Remove explicit glDrawBuffer() calls where they're referencing the window.
pvr2_draw_frame now gets to decide where to draw.
Add force_vsync flag to force double-buffering (not configurable yet)
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * Common GL code that doesn't depend on a specific implementation
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <sys/time.h>
    21 #include "display.h"
    22 #include "pvr2/pvr2.h"
    23 #include "drivers/video_gl.h"
    25 extern uint32_t video_width, video_height;
    27 /**
    28  * Reset the gl state to simple orthographic projection with 
    29  * texturing, alpha/depth/scissor/cull tests disabled.
    30  */
    31 void gl_reset_state()
    32 {
    33     glViewport( 0, 0, video_width, video_height );
    34     glMatrixMode(GL_PROJECTION);
    35     glLoadIdentity();
    36     glOrtho( 0, video_width, video_height, 0, 0, 65535 );
    37     glMatrixMode(GL_MODELVIEW);
    38     glLoadIdentity();
    39     glEnable( GL_BLEND );
    40     glDisable( GL_TEXTURE_2D );
    41     glDisable( GL_TEXTURE_RECTANGLE_ARB );
    42     glDisable( GL_ALPHA_TEST );
    43     glDisable( GL_DEPTH_TEST );
    44     glDisable( GL_SCISSOR_TEST );
    45     glDisable( GL_CULL_FACE );
    46 }
    48 void gl_display_render_buffer( render_buffer_t buffer )
    49 {
    50     gl_texture_window( buffer->width, buffer->height, buffer->buf_id, buffer->inverted );
    51 }
    53 /**
    54  * Convert window coordinates to dreamcast device coords (640x480) using the 
    55  * same viewable area as gl_texture_window.
    56  * If the coordinates are outside the viewable area, the result is -1,-1.
    57  */ 
    58 void gl_window_to_system_coords( int *x, int *y )
    59 {
    60     int x1=0,y1=0,x2=video_width,y2=video_height;
    62     int ah = video_width * 0.75;
    64     if( ah > video_height ) {
    65         int w = (video_height/0.75);
    66         x1 = (video_width - w)/2;
    67         x2 -= x1;
    68     } else if( ah < video_height ) {
    69         y1 = (video_height - ah)/2;
    70         y2 -= y1;
    71     }
    72     if( *x < x1 || *x >= x2 || *y < y1 || *y >= y2 ) {
    73         *x = -1;
    74         *y = -1;
    75     } else {
    76         *x = (*x - x1) * DISPLAY_WIDTH / (x2-x1);
    77         *y = (*y - y1) * DISPLAY_HEIGHT / (y2-y1);
    78     }
    79 }
    81 void gl_texture_window( int width, int height, int tex_id, gboolean inverted )
    82 {
    83     float top, bottom;
    84     if( inverted ) {
    85         top = ((float)height);
    86         bottom = 0;
    87     } else {
    88         top = 0;
    89         bottom = ((float)height);
    90     }
    92     /* Reset display parameters */
    93     gl_reset_state();
    94     glColor3f( 0,0,0 );    
    96     int x1=0,y1=0,x2=video_width,y2=video_height;
    98     int ah = video_width * 0.75;
   100     if( ah > video_height ) {
   101         int w = (video_height/0.75);
   102         x1 = (video_width - w)/2;
   103         x2 -= x1;
   105         glBegin( GL_QUADS );
   106         glVertex2f( 0, 0 );
   107         glVertex2f( x1, 0 );
   108         glVertex2f( x1, video_height );
   109         glVertex2f( 0, video_height);
   110         glVertex2f( x2, 0 );
   111         glVertex2f( video_width, 0 );
   112         glVertex2f( video_width, video_height );
   113         glVertex2f( x2, video_height);
   114         glEnd();
   115     } else if( ah < video_height ) {
   116         y1 = (video_height - ah)/2;
   117         y2 -= y1;
   118         glBegin( GL_QUADS );
   119         glVertex2f( 0, 0 );
   120         glVertex2f( video_width, 0 );
   121         glVertex2f( video_width, y1 );
   122         glVertex2f( 0, y1 );
   123         glVertex2f( 0, y2 );
   124         glVertex2f( video_width, y2 );
   125         glVertex2f( video_width, video_height );
   126         glVertex2f( 0, video_height );
   127         glEnd();
   128     }
   130     /* Render the textured rectangle */
   131     glEnable( GL_TEXTURE_RECTANGLE_ARB );
   132     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex_id );
   133     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
   134     glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   135     glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   136     glEnable( GL_BLEND );
   137     glBlendFunc( GL_ONE, GL_ZERO );
   138     glBegin( GL_QUADS );
   139     glTexCoord2f( 0, top );
   140     glVertex2f( x1, y1 );
   141     glTexCoord2f( ((float)width), top );
   142     glVertex2f( x2, y1 );
   143     glTexCoord2f( ((float)width), bottom );
   144     glVertex2f( x2, y2 );
   145     glTexCoord2f( 0, bottom );
   146     glVertex2f( x1, y2 );
   147     glEnd();
   148     glDisable( GL_TEXTURE_RECTANGLE_ARB );
   149     glFlush();
   150 }
   152 gboolean gl_load_frame_buffer( frame_buffer_t frame, int tex_id )
   153 {
   154     GLenum type = colour_formats[frame->colour_format].type;
   155     GLenum format = colour_formats[frame->colour_format].format;
   156     int bpp = colour_formats[frame->colour_format].bpp;
   157     int rowstride = (frame->rowstride / bpp) - frame->width;
   159     glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
   160     glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex_id );
   161     glTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, 0,0,
   162                      frame->width, frame->height, format, type, frame->data );
   163     return TRUE;
   164 }
   166 void gl_display_blank( uint32_t colour )
   167 {
   168     gl_reset_state();
   169     glColor3ub( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );
   170     glRecti(0,0, video_width, video_height );
   171     glFlush();
   172 }
   174 /**
   175  * Generic GL read_render_buffer. This function assumes that the caller
   176  * has already set the appropriate glReadBuffer(); in other words, unless
   177  * there's only one buffer this needs to be wrapped.
   178  */
   179 gboolean gl_read_render_buffer( unsigned char *target, render_buffer_t buffer, 
   180                                 int rowstride, int colour_format ) 
   181 {
   182     glFinish();
   183     GLenum type = colour_formats[colour_format].type;
   184     GLenum format = colour_formats[colour_format].format;
   185     // int line_size = buffer->width * colour_formats[colour_format].bpp;
   186     // int size = line_size * buffer->height;
   187     int glrowstride = (rowstride / colour_formats[colour_format].bpp) - buffer->width;
   188     glPixelStorei( GL_PACK_ROW_LENGTH, glrowstride );
   190     glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );
   191     return TRUE;
   192 }
.