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