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