nkeynes@635: /** nkeynes@635: * $Id$ nkeynes@635: * nkeynes@635: * Common GL code that doesn't depend on a specific implementation nkeynes@635: * nkeynes@635: * Copyright (c) 2005 Nathan Keynes. nkeynes@635: * nkeynes@635: * This program is free software; you can redistribute it and/or modify nkeynes@635: * it under the terms of the GNU General Public License as published by nkeynes@635: * the Free Software Foundation; either version 2 of the License, or nkeynes@635: * (at your option) any later version. nkeynes@635: * nkeynes@635: * This program is distributed in the hope that it will be useful, nkeynes@635: * but WITHOUT ANY WARRANTY; without even the implied warranty of nkeynes@635: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nkeynes@635: * GNU General Public License for more details. nkeynes@635: */ nkeynes@635: nkeynes@635: #include nkeynes@635: nkeynes@635: #include "display.h" nkeynes@635: #include "pvr2/pvr2.h" nkeynes@635: #include "drivers/video_gl.h" nkeynes@635: nkeynes@635: extern uint32_t video_width, video_height; nkeynes@635: nkeynes@635: /** nkeynes@635: * Reset the gl state to simple orthographic projection with nkeynes@635: * texturing, alpha/depth/scissor/cull tests disabled. nkeynes@635: */ nkeynes@635: void gl_reset_state() nkeynes@635: { nkeynes@635: glViewport( 0, 0, video_width, video_height ); nkeynes@635: glMatrixMode(GL_PROJECTION); nkeynes@635: glLoadIdentity(); nkeynes@635: glOrtho( 0, video_width, video_height, 0, 0, 65535 ); nkeynes@635: glMatrixMode(GL_MODELVIEW); nkeynes@635: glLoadIdentity(); nkeynes@681: glEnable( GL_BLEND ); nkeynes@635: glDisable( GL_TEXTURE_2D ); nkeynes@681: glDisable( GL_TEXTURE_RECTANGLE_ARB ); nkeynes@635: glDisable( GL_ALPHA_TEST ); nkeynes@635: glDisable( GL_DEPTH_TEST ); nkeynes@635: glDisable( GL_SCISSOR_TEST ); nkeynes@635: glDisable( GL_CULL_FACE ); nkeynes@635: glDrawBuffer( GL_FRONT ); nkeynes@635: } nkeynes@635: nkeynes@635: void gl_display_render_buffer( render_buffer_t buffer ) nkeynes@635: { nkeynes@635: gl_texture_window( buffer->width, buffer->height, buffer->buf_id, buffer->inverted ); nkeynes@635: } nkeynes@635: nkeynes@635: void gl_texture_window( int width, int height, int tex_id, gboolean inverted ) nkeynes@635: { nkeynes@635: float top, bottom; nkeynes@635: if( inverted ) { nkeynes@635: top = ((float)height); nkeynes@635: bottom = 0; nkeynes@635: } else { nkeynes@635: top = 0; nkeynes@635: bottom = ((float)height); nkeynes@635: } nkeynes@635: nkeynes@635: /* Reset display parameters */ nkeynes@635: gl_reset_state(); nkeynes@635: glColor3f( 0,0,0 ); nkeynes@635: nkeynes@635: int x1=0,y1=0,x2=video_width,y2=video_height; nkeynes@635: nkeynes@635: int ah = video_width * 0.75; nkeynes@635: nkeynes@635: if( ah > video_height ) { nkeynes@635: int w = (video_height/0.75); nkeynes@635: x1 = (video_width - w)/2; nkeynes@635: x2 -= x1; nkeynes@635: nkeynes@635: glBegin( GL_QUADS ); nkeynes@635: glVertex2f( 0, 0 ); nkeynes@635: glVertex2f( x1, 0 ); nkeynes@635: glVertex2f( x1, video_height ); nkeynes@635: glVertex2f( 0, video_height); nkeynes@635: glVertex2f( x2, 0 ); nkeynes@635: glVertex2f( video_width, 0 ); nkeynes@635: glVertex2f( video_width, video_height ); nkeynes@635: glVertex2f( x2, video_height); nkeynes@635: glEnd(); nkeynes@635: } else if( ah < video_height ) { nkeynes@635: y1 = (video_height - ah)/2; nkeynes@635: y2 -= y1; nkeynes@635: glBegin( GL_QUADS ); nkeynes@635: glVertex2f( 0, 0 ); nkeynes@635: glVertex2f( video_width, 0 ); nkeynes@635: glVertex2f( video_width, y1 ); nkeynes@635: glVertex2f( 0, y1 ); nkeynes@635: glVertex2f( 0, y2 ); nkeynes@635: glVertex2f( video_width, y2 ); nkeynes@635: glVertex2f( video_width, video_height ); nkeynes@635: glVertex2f( 0, video_height ); nkeynes@635: glEnd(); nkeynes@635: } nkeynes@635: nkeynes@635: /* Render the textured rectangle */ nkeynes@635: glEnable( GL_TEXTURE_RECTANGLE_ARB ); nkeynes@635: glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex_id ); nkeynes@635: glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); nkeynes@635: glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); nkeynes@635: glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); nkeynes@635: glEnable( GL_BLEND ); nkeynes@635: glBlendFunc( GL_ONE, GL_ZERO ); nkeynes@635: glBegin( GL_QUADS ); nkeynes@635: glTexCoord2f( 0, top ); nkeynes@635: glVertex2f( x1, y1 ); nkeynes@635: glTexCoord2f( ((float)width), top ); nkeynes@635: glVertex2f( x2, y1 ); nkeynes@635: glTexCoord2f( ((float)width), bottom ); nkeynes@635: glVertex2f( x2, y2 ); nkeynes@635: glTexCoord2f( 0, bottom ); nkeynes@635: glVertex2f( x1, y2 ); nkeynes@635: glEnd(); nkeynes@635: glDisable( GL_TEXTURE_RECTANGLE_ARB ); nkeynes@635: glFlush(); nkeynes@635: } nkeynes@635: nkeynes@635: gboolean gl_load_frame_buffer( frame_buffer_t frame, int tex_id ) nkeynes@635: { nkeynes@635: GLenum type = colour_formats[frame->colour_format].type; nkeynes@635: GLenum format = colour_formats[frame->colour_format].format; nkeynes@635: int bpp = colour_formats[frame->colour_format].bpp; nkeynes@635: int rowstride = (frame->rowstride / bpp) - frame->width; nkeynes@635: nkeynes@635: glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride ); nkeynes@635: glBindTexture( GL_TEXTURE_RECTANGLE_ARB, tex_id ); nkeynes@635: glTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, 0,0, nkeynes@635: frame->width, frame->height, format, type, frame->data ); nkeynes@635: return TRUE; nkeynes@635: } nkeynes@635: nkeynes@669: void gl_display_blank( uint32_t colour ) nkeynes@635: { nkeynes@635: gl_reset_state(); nkeynes@635: glColor3ub( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF ); nkeynes@635: glRecti(0,0, video_width, video_height ); nkeynes@635: glFlush(); nkeynes@635: } nkeynes@635: nkeynes@635: /** nkeynes@635: * Generic GL read_render_buffer. This function assumes that the caller nkeynes@635: * has already set the appropriate glReadBuffer(); in other words, unless nkeynes@635: * there's only one buffer this needs to be wrapped. nkeynes@635: */ nkeynes@635: gboolean gl_read_render_buffer( unsigned char *target, render_buffer_t buffer, nkeynes@635: int rowstride, int colour_format ) nkeynes@635: { nkeynes@635: glFinish(); nkeynes@635: GLenum type = colour_formats[colour_format].type; nkeynes@635: GLenum format = colour_formats[colour_format].format; nkeynes@635: // int line_size = buffer->width * colour_formats[colour_format].bpp; nkeynes@635: // int size = line_size * buffer->height; nkeynes@635: int glrowstride = (rowstride / colour_formats[colour_format].bpp) - buffer->width; nkeynes@635: glPixelStorei( GL_PACK_ROW_LENGTH, glrowstride ); nkeynes@635: nkeynes@635: glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target ); nkeynes@635: return TRUE; nkeynes@635: }