Search
lxdream.org :: lxdream/src/pvr2/glrender.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/glrender.c
changeset 639:162ee7614b60
next645:a7392098299c
author nkeynes
date Mon Feb 18 09:21:43 2008 +0000 (12 years ago)
branchlxdream-render
permissions -rw-r--r--
last change More render WIP - initial glrender.c
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * Standard OpenGL rendering engine. 
     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 "display.h"
    20 #include "pvr2/pvr2.h"
    21 #include "pvr2/scene.h"
    23 /**
    24  * Clip the tile bounds to the clipping plane. 
    25  * @return TRUE if the tile was not clipped completely.
    26  */
    27 static gboolean clip_tile_bounds( uint32_t *tile, float *clip )
    28 {
    29     if( tile[0] < clip[0] ) tile[0] = clip[0];
    30     if( tile[1] > clip[1] ) tile[1] = clip[1];
    31     if( tile[2] < clip[2] ) tile[2] = clip[2];
    32     if( tile[3] > clip[3] ) tile[3] = clip[3];
    33     return tile[0] < tile[1] && tile[2] < tile[3];
    34 }
    36 /**
    37  * Once-off call to setup the OpenGL context.
    38  */
    39 void pvr2_setup_gl_context()
    40 {
    41     texcache_gl_init(); // Allocate texture IDs
    42     glShadeModel(GL_SMOOTH);
    43     glCullFace( GL_BACK );
    44     glEnable( GL_BLEND );
    45     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    46     glMatrixMode(GL_MODELVIEW);
    47     glLoadIdentity();
    49     glEnableClientState( GL_COLOR_ARRAY );
    50     glEnableClientState( GL_VERTEX_ARRAY );
    51     glEnableClientState( GL_TEXTURE_COORD_ARRAY );
    52     glEnableClientState( GL_SECONDARY_COLOR_ARRAY );
    54     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    55     glClearDepth(0);
    56     glClearStencil(0);
    57 }
    59 static void gl_render_poly( struct polygon_struct *poly )
    60 {
    61     render_set_context( poly->context, RENDER_NORMAL );
    62     glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
    63 }
    65 static void gl_render_tilelist( pvraddr_t tile_entry )
    66 {
    67     uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
    68     int strip_count;
    69     struct polygon_struct *poly;
    71     while(1) {
    72 	uint32_t entry = *tile_list++;
    73 	switch( entry >> 28 ) {
    74 	case 0x0F:
    75 	    return; // End-of-list
    76 	case 0x0E:
    77 	    tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));
    78 	    break;
    79 	case 0x08:
    80 	case 0x09:
    81 	case 0x0A:
    82 	case 0x0B:
    83 	    strip_count = ((entry >> 25) & 0x0F)+1;
    84 	    poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
    85 	    while( strip_count > 0 ) {
    86 		gl_render_poly( poly );
    87 		poly = poly->next;
    88 		strip_count--;
    89 	    }
    90 	    break;
    91 	default:
    92 	    poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
    93 	    gl_render_poly( poly );
    94 	}
    95     }	    
    96 }
    99 /**
   100  * Render the currently defined scene in pvr2_scene
   101  */
   102 void pvr2_scene_render( render_buffer_t buffer )
   103 {
   104     /* Scene setup */
   105     display_driver->set_render_target(buffer);
   106     pvr2_check_palette_changed();
   108     /* Setup view projection matrix */
   109     glMatrixMode(GL_PROJECTION);
   110     glLoadIdentity();
   111     float nearz = pvr2_scene.bounds[4];
   112     float farz = pvr2_scene.bounds[5];
   113     if( nearz == farz ) {
   114 	farz*= 2.0;
   115     }
   116     glOrtho( 0, pvr2_scene.buffer_width, pvr2_scene.buffer_height, 0, 
   117 	     -nearz, -farz );
   119     /* Clear the buffer (FIXME: May not want always want to do this) */
   120     glDisable( GL_SCISSOR_TEST );
   121     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
   123     /* Setup vertex array pointers */
   124     glInterleavedArrays(GL_T2F_C4UB_V3F, sizeof(struct vertex_struct), pvr2_scene.vertex_array);
   125     glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].offset_rgba );
   127     uint32_t bgplane_mode = MMIO_READ(PVR2, RENDER_BGPLANE);
   128     uint32_t *bgplane = pvr2_scene.pvr2_pbuf + (((bgplane_mode & 0x00FFFFFF)) >> 3) ;
   129     render_backplane( bgplane, pvr2_scene.buffer_width, pvr2_scene.buffer_height, bgplane_mode );
   131     glEnable( GL_SCISSOR_TEST );
   133     /* Process the segment list */
   134     struct tile_segment *segment = pvr2_scene.segment_list;
   135     do {
   136 	int tilex = SEGMENT_X(segment->control);
   137 	int tiley = SEGMENT_Y(segment->control);
   139 	int tile_bounds[4] = { tilex << 5, (tilex+1)<<5, tiley<<5, (tiley+1)<<5 };
   140 	if( !clip_tile_bounds(tile_bounds, pvr2_scene.bounds) ) {
   141 	    continue; // fully clipped, skip tile
   142 	}
   144 	/* Clip to the visible part of the tile */
   145 	glScissor( tile_bounds[0], pvr2_scene.buffer_height-tile_bounds[3], 
   146 		   tile_bounds[1]-tile_bounds[0], tile_bounds[3] - tile_bounds[2] );
   147 	if( IS_TILE_PTR(segment->opaque_ptr) ) {
   148 	    gl_render_tilelist(segment->opaque_ptr);
   149 	}
   150 	if( IS_TILE_PTR(segment->trans_ptr) ) {
   151 	    gl_render_tilelist(segment->trans_ptr);
   152 	}
   153 	if( IS_TILE_PTR(segment->punchout_ptr) ) {
   154 	    gl_render_tilelist(segment->punchout_ptr);
   155 	}
   156     } while( !IS_LAST_SEGMENT(segment++) );
   157     glDisable( GL_SCISSOR_TEST );
   159 }
.