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 1236:d93175c36387
prev1222:a4545699a82b
next1239:be3121267597
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
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 "pvr2/glutil.h"
    24 #include "drivers/video_gl.h"
    26 uint32_t video_width, video_height;
    27 struct video_vertex {
    28     float x,y;
    29     float u,v;
    30     float r,g,b;
    31 };
    33 static struct video_box_t {
    34     float viewMatrix[16];
    35     struct video_vertex gap1[4];
    36     struct video_vertex gap2[4];
    37     struct video_vertex video_view[4];
    38     struct video_vertex invert_view[4];
    39 } video_box;
    41 void gl_set_video_size( uint32_t width, uint32_t height )
    42 {
    43     video_width = width;
    44     video_height = height;
    46     int x1=0,y1=0,x2=video_width,y2=video_height;
    48     int ah = video_width * 0.75;
    50     if( ah > video_height ) {
    51         int w = (video_height/0.75);
    52         x1 = (video_width - w)/2;
    53         x2 -= x1;
    54         video_box.gap1[0].x = 0; video_box.gap1[0].y = 0;
    55         video_box.gap1[1].x = x1; video_box.gap1[1].y = 0;
    56         video_box.gap1[2].x = 0; video_box.gap1[2].y = video_height;
    57         video_box.gap1[3].x = x2; video_box.gap1[3].y = video_height;
    58         video_box.gap2[0].x = x2; video_box.gap2[0].y = 0;
    59         video_box.gap2[1].x = video_width; video_box.gap2[1].y = 0;
    60         video_box.gap2[2].x = x2; video_box.gap2[2].y = video_height;
    61         video_box.gap2[3].x = video_width; video_box.gap2[3].y = video_height;
    62     } else if( ah < video_height ) {
    63         y1 = (video_height - ah)/2;
    64         y2 -= y1;
    66         video_box.gap1[0].x = 0; video_box.gap1[0].y = 0;
    67         video_box.gap1[1].x = video_width; video_box.gap1[1].y = 0;
    68         video_box.gap1[2].x = 0; video_box.gap1[2].y = y1;
    69         video_box.gap1[3].x = video_width; video_box.gap1[3].y = y1;
    70         video_box.gap2[0].x = 0; video_box.gap2[0].y = y2;
    71         video_box.gap2[1].x = video_width; video_box.gap2[1].y = y2;
    72         video_box.gap2[2].x = 0; video_box.gap2[2].y = video_height;
    73         video_box.gap2[3].x = video_width; video_box.gap2[3].y = video_height;
    74     }
    76     video_box.video_view[0].x = x1; video_box.video_view[0].y = y1;
    77     video_box.video_view[0].u = 0; video_box.video_view[0].v = 0;
    78     video_box.video_view[1].x = x2; video_box.video_view[1].y = y1;
    79     video_box.video_view[1].u = 1; video_box.video_view[1].v = 0;
    80     video_box.video_view[2].x = x1; video_box.video_view[2].y = y2;
    81     video_box.video_view[2].u = 0; video_box.video_view[2].v = 1;
    82     video_box.video_view[3].x = x2; video_box.video_view[3].y = y2;
    83     video_box.video_view[3].u = 1; video_box.video_view[3].v = 1;
    85     memcpy( &video_box.invert_view, &video_box.video_view, sizeof(video_box.video_view) );
    86     video_box.invert_view[0].v = 1; video_box.invert_view[1].v = 1;
    87     video_box.invert_view[2].v = 0; video_box.invert_view[3].v = 0;
    89     defineOrthoMatrix(video_box.viewMatrix, video_width, video_height, 0, 65535);
    90 }
    92 /**
    93  * Setup the gl context for writes to the display output.
    94  */
    95 void gl_framebuffer_setup()
    96 {
    97     glLoadMatrixf(video_box.viewMatrix);
    98     glBlendFunc( GL_ONE, GL_ZERO );
    99     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
   100     glViewport( 0, 0, video_width, video_height );
   101     glVertexPointer(2, GL_FLOAT, sizeof(struct video_vertex), &video_box.gap1[0].x);
   102     glColorPointer(3, GL_FLOAT, sizeof(struct video_vertex), &video_box.gap1[0].r);
   103     glTexCoordPointer(2, GL_FLOAT, sizeof(struct video_vertex), &video_box.gap1[0].u);
   104     glEnableClientState( GL_VERTEX_ARRAY );
   105     glEnableClientState( GL_COLOR_ARRAY );
   106     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
   107 }
   109 void gl_display_render_buffer( render_buffer_t buffer )
   110 {
   111     gl_texture_window( buffer->width, buffer->height, buffer->buf_id, buffer->inverted );
   112 }
   114 /**
   115  * Convert window coordinates to dreamcast device coords (640x480) using the 
   116  * same viewable area as gl_texture_window.
   117  * If the coordinates are outside the viewable area, the result is -1,-1.
   118  */ 
   119 void gl_window_to_system_coords( int *x, int *y )
   120 {
   121     int x1=0,y1=0,x2=video_width,y2=video_height;
   123     int ah = video_width * 0.75;
   125     if( ah > video_height ) {
   126         int w = (video_height/0.75);
   127         x1 = (video_width - w)/2;
   128         x2 -= x1;
   129     } else if( ah < video_height ) {
   130         y1 = (video_height - ah)/2;
   131         y2 -= y1;
   132     }
   133     if( *x < x1 || *x >= x2 || *y < y1 || *y >= y2 ) {
   134         *x = -1;
   135         *y = -1;
   136     } else {
   137         *x = (*x - x1) * DISPLAY_WIDTH / (x2-x1);
   138         *y = (*y - y1) * DISPLAY_HEIGHT / (y2-y1);
   139     }
   140 }
   142 void gl_texture_window( int width, int height, int tex_id, gboolean inverted )
   143 {
   144     /* Reset display parameters */
   145     gl_framebuffer_setup();
   146     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   147     glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
   148     glEnable(GL_TEXTURE_2D);
   149     glBindTexture(GL_TEXTURE_2D,tex_id);
   150     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   151     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   152     glDrawArrays(GL_TRIANGLE_STRIP, inverted ? 12 : 8, 4);
   153     glDisable(GL_TEXTURE_2D);
   154     glFlush();
   155 }
   157 gboolean gl_load_frame_buffer( frame_buffer_t frame, int tex_id )
   158 {
   159     GLenum type = colour_formats[frame->colour_format].type;
   160     GLenum format = colour_formats[frame->colour_format].format;
   161     int bpp = colour_formats[frame->colour_format].bpp;
   162     int rowstride = (frame->rowstride / bpp) - frame->width;
   164     glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
   165     glBindTexture( GL_TEXTURE_2D, tex_id );
   166     glTexSubImage2D( GL_TEXTURE_2D, 0, 0,0,
   167                      frame->width, frame->height, format, type, frame->data );
   168     glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
   169     return TRUE;
   170 }
   172 void gl_display_blank( uint32_t colour )
   173 {
   174     /* Set the video_box background colour */
   175     video_box.video_view[0].r = ((float)(((colour >> 16) & 0xFF) + 1)) / 256.0;
   176     video_box.video_view[0].g = ((float)(((colour >> 8) & 0xFF) + 1)) / 256.0;
   177     video_box.video_view[0].b = ((float)((colour & 0xFF) + 1)) / 256.0;
   178     memcpy( &video_box.video_view[1].r, &video_box.video_view[0].r, sizeof(float)*3 );
   179     memcpy( &video_box.video_view[2].r, &video_box.video_view[0].r, sizeof(float)*3 );
   180     memcpy( &video_box.video_view[3].r, &video_box.video_view[0].r, sizeof(float)*3 );
   182     /* And render */
   183     gl_framebuffer_setup();
   184     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   185     glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
   186     glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
   187     glFlush();
   188 }
   190 /**
   191  * Generic GL read_render_buffer. This function assumes that the caller
   192  * has already set the appropriate glReadBuffer(); in other words, unless
   193  * there's only one buffer this needs to be wrapped.
   194  */
   195 gboolean gl_read_render_buffer( unsigned char *target, render_buffer_t buffer, 
   196                                 int rowstride, int colour_format ) 
   197 {
   198     glFinish();
   199     GLenum type = colour_formats[colour_format].type;
   200     GLenum format = colour_formats[colour_format].format;
   201     // int line_size = buffer->width * colour_formats[colour_format].bpp;
   202     // int size = line_size * buffer->height;
   203     int glrowstride = (rowstride / colour_formats[colour_format].bpp) - buffer->width;
   204     glPixelStorei( GL_PACK_ROW_LENGTH, glrowstride );
   205     glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );
   206     glPixelStorei( GL_PACK_ROW_LENGTH, 0 );
   207     return TRUE;
   208 }
.