# HG changeset patch # User nkeynes # Date 1203326503 0 # Node ID 162ee7614b6040b9cbd51b57c972d09d78dc0f9a # Parent 2ccf94f966fc37c7b6fcf03acf1263015d7ffe1c More render WIP - initial glrender.c --- a/src/Makefile.am Thu Feb 14 14:06:41 2008 +0000 +++ b/src/Makefile.am Mon Feb 18 09:21:43 2008 +0000 @@ -35,7 +35,7 @@ pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \ pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \ pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \ - pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h \ + pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c \ maple/maple.c maple/maple.h \ maple/controller.c maple/controller.h maple/kbd.c maple/mouse.c \ loader.c bootstrap.c util.c \ --- a/src/Makefile.in Thu Feb 14 14:06:41 2008 +0000 +++ b/src/Makefile.in Mon Feb 18 09:21:43 2008 +0000 @@ -236,7 +236,7 @@ pvr2/pvr2.c pvr2/pvr2.h pvr2/pvr2mem.c \ pvr2/tacore.c pvr2/render.c pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c \ pvr2/texcache.c pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \ - pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h \ + pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c \ maple/maple.c maple/maple.h \ maple/controller.c maple/controller.h maple/kbd.c maple/mouse.c \ loader.c bootstrap.c util.c \ @@ -295,7 +295,7 @@ pvr2/rendcore.c pvr2/rendbkg.c pvr2/rendsort.c pvr2/texcache.c \ pvr2/yuv.c pvr2/rendsave.c pvr2/scene.c pvr2/scene.h \ pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h \ - maple/maple.c maple/maple.h maple/controller.c \ + pvr2/glrender.c maple/maple.c maple/maple.h maple/controller.c \ maple/controller.h maple/kbd.c maple/mouse.c loader.c \ bootstrap.c util.c display.c display.h dckeysyms.h \ drivers/audio_null.c drivers/video_null.c drivers/video_gl.c \ @@ -353,13 +353,13 @@ rendcore.$(OBJEXT) rendbkg.$(OBJEXT) rendsort.$(OBJEXT) \ texcache.$(OBJEXT) yuv.$(OBJEXT) rendsave.$(OBJEXT) \ scene.$(OBJEXT) gl_sl.$(OBJEXT) gl_slsrc.$(OBJEXT) \ - glutil.$(OBJEXT) maple.$(OBJEXT) controller.$(OBJEXT) \ - kbd.$(OBJEXT) mouse.$(OBJEXT) loader.$(OBJEXT) \ - bootstrap.$(OBJEXT) util.$(OBJEXT) display.$(OBJEXT) \ - audio_null.$(OBJEXT) video_null.$(OBJEXT) video_gl.$(OBJEXT) \ - gl_fbo.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ - $(am__objects_3) $(am__objects_4) $(am__objects_5) \ - $(am__objects_6) $(am__objects_7) + glutil.$(OBJEXT) glrender.$(OBJEXT) maple.$(OBJEXT) \ + controller.$(OBJEXT) kbd.$(OBJEXT) mouse.$(OBJEXT) \ + loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \ + display.$(OBJEXT) audio_null.$(OBJEXT) video_null.$(OBJEXT) \ + video_gl.$(OBJEXT) gl_fbo.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) \ + $(am__objects_5) $(am__objects_6) $(am__objects_7) lxdream_OBJECTS = $(am_lxdream_OBJECTS) lxdream_DEPENDENCIES = lxdream_LDFLAGS = @@ -404,33 +404,33 @@ @AMDEP_TRUE@ ./$(DEPDIR)/gdrom.Po ./$(DEPDIR)/gdrom_menu.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/gendec.Po ./$(DEPDIR)/genglsl.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/gl_fbo.Po ./$(DEPDIR)/gl_sl.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gl_slsrc.Po ./$(DEPDIR)/glutil.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/gtkcb.Po ./$(DEPDIR)/gtkui.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/i386-dis.Po ./$(DEPDIR)/ide.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/insparse.Po ./$(DEPDIR)/intc.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/joy_linux.Po ./$(DEPDIR)/kbd.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/main_win.Po ./$(DEPDIR)/maple.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mmio_win.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/mmu.Po ./$(DEPDIR)/mouse.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/nrg.Po ./$(DEPDIR)/path_dlg.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/pvr2mem.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/rendbkg.Po ./$(DEPDIR)/rendcore.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/render.Po ./$(DEPDIR)/rendsave.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/rendsort.Po ./$(DEPDIR)/scene.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/sh4mem.Po ./$(DEPDIR)/sh4mmio.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/sh4stat.Po ./$(DEPDIR)/sh4trans.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/sh4x86.Po ./$(DEPDIR)/syscall.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/tacore.Po ./$(DEPDIR)/testsh4x86.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/testxlt.Po ./$(DEPDIR)/texcache.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/timer.Po ./$(DEPDIR)/util.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/video_gdk.Po ./$(DEPDIR)/video_gl.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/video_glx.Po ./$(DEPDIR)/video_gtk.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/video_null.Po ./$(DEPDIR)/watch.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/x86dasm.Po ./$(DEPDIR)/xltcache.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/yuv.Po +@AMDEP_TRUE@ ./$(DEPDIR)/gl_slsrc.Po ./$(DEPDIR)/glrender.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/glutil.Po ./$(DEPDIR)/gtkcb.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/gtkui.Po ./$(DEPDIR)/i386-dis.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ide.Po ./$(DEPDIR)/insparse.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/joy_linux.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/kbd.Po ./$(DEPDIR)/loader.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/main_win.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/mmio_win.Po ./$(DEPDIR)/mmu.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/mouse.Po ./$(DEPDIR)/nrg.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/path_dlg.Po ./$(DEPDIR)/pvr2.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/pvr2mem.Po ./$(DEPDIR)/rendbkg.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/rendcore.Po ./$(DEPDIR)/render.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/rendsave.Po ./$(DEPDIR)/rendsort.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/scene.Po ./$(DEPDIR)/scif.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/sh4.Po ./$(DEPDIR)/sh4core.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/sh4stat.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/sh4trans.Po ./$(DEPDIR)/sh4x86.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/tacore.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/testsh4x86.Po ./$(DEPDIR)/testxlt.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gdk.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/video_gl.Po ./$(DEPDIR)/video_glx.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/video_gtk.Po ./$(DEPDIR)/video_null.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/x86dasm.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/xltcache.Po ./$(DEPDIR)/yuv.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) @@ -541,6 +541,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_fbo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_sl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gl_slsrc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glrender.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glutil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkcb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gtkui.Po@am__quote@ @@ -1518,6 +1519,28 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o glutil.obj `if test -f 'pvr2/glutil.c'; then $(CYGPATH_W) 'pvr2/glutil.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/glutil.c'; fi` +glrender.o: pvr2/glrender.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT glrender.o -MD -MP -MF "$(DEPDIR)/glrender.Tpo" \ +@am__fastdepCC_TRUE@ -c -o glrender.o `test -f 'pvr2/glrender.c' || echo '$(srcdir)/'`pvr2/glrender.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/glrender.Tpo" "$(DEPDIR)/glrender.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/glrender.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/glrender.c' object='glrender.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/glrender.Po' tmpdepfile='$(DEPDIR)/glrender.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o glrender.o `test -f 'pvr2/glrender.c' || echo '$(srcdir)/'`pvr2/glrender.c + +glrender.obj: pvr2/glrender.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT glrender.obj -MD -MP -MF "$(DEPDIR)/glrender.Tpo" \ +@am__fastdepCC_TRUE@ -c -o glrender.obj `if test -f 'pvr2/glrender.c'; then $(CYGPATH_W) 'pvr2/glrender.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/glrender.c'; fi`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/glrender.Tpo" "$(DEPDIR)/glrender.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/glrender.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pvr2/glrender.c' object='glrender.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/glrender.Po' tmpdepfile='$(DEPDIR)/glrender.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o glrender.obj `if test -f 'pvr2/glrender.c'; then $(CYGPATH_W) 'pvr2/glrender.c'; else $(CYGPATH_W) '$(srcdir)/pvr2/glrender.c'; fi` + maple.o: maple/maple.c @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT maple.o -MD -MP -MF "$(DEPDIR)/maple.Tpo" \ @am__fastdepCC_TRUE@ -c -o maple.o `test -f 'maple/maple.c' || echo '$(srcdir)/'`maple/maple.c; \ --- a/src/drivers/video_gdk.c Thu Feb 14 14:06:41 2008 +0000 +++ b/src/drivers/video_gdk.c Mon Feb 18 09:21:43 2008 +0000 @@ -55,7 +55,7 @@ osmesa_context = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, 0 ); OSMesaMakeCurrent( osmesa_context, NULL, GL_UNSIGNED_BYTE, 640, 480 ); - texcache_gl_init(); + pvr2_setup_gl_context(); } int video_gdk_find_free() --- a/src/drivers/video_glx.c Thu Feb 14 14:06:41 2008 +0000 +++ b/src/drivers/video_glx.c Mon Feb 18 09:21:43 2008 +0000 @@ -177,7 +177,7 @@ } } - texcache_gl_init(); + pvr2_setup_gl_context(); video_x11_display = display; video_x11_window = window; --- a/src/pvr2/gl_slsrc.c Thu Feb 14 14:06:41 2008 +0000 +++ b/src/pvr2/gl_slsrc.c Mon Feb 18 09:21:43 2008 +0000 @@ -8,7 +8,6 @@ {\n\ gl_Position.xy = ftransform().xy;\n\ gl_Position.z = gl_Vertex.z;\n\ - gl_Position.w = 1;\n\ gl_FrontColor = gl_Color;\n\ gl_FrontSecondaryColor = gl_SecondaryColor;\n\ gl_TexCoord[0] = gl_MultiTexCoord0;\n\ --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pvr2/glrender.c Mon Feb 18 09:21:43 2008 +0000 @@ -0,0 +1,159 @@ +/** + * $Id$ + * + * Standard OpenGL rendering engine. + * + * Copyright (c) 2005 Nathan Keynes. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "display.h" +#include "pvr2/pvr2.h" +#include "pvr2/scene.h" + +/** + * Clip the tile bounds to the clipping plane. + * @return TRUE if the tile was not clipped completely. + */ +static gboolean clip_tile_bounds( uint32_t *tile, float *clip ) +{ + if( tile[0] < clip[0] ) tile[0] = clip[0]; + if( tile[1] > clip[1] ) tile[1] = clip[1]; + if( tile[2] < clip[2] ) tile[2] = clip[2]; + if( tile[3] > clip[3] ) tile[3] = clip[3]; + return tile[0] < tile[1] && tile[2] < tile[3]; +} + +/** + * Once-off call to setup the OpenGL context. + */ +void pvr2_setup_gl_context() +{ + texcache_gl_init(); // Allocate texture IDs + glShadeModel(GL_SMOOTH); + glCullFace( GL_BACK ); + glEnable( GL_BLEND ); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glEnableClientState( GL_COLOR_ARRAY ); + glEnableClientState( GL_VERTEX_ARRAY ); + glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + glEnableClientState( GL_SECONDARY_COLOR_ARRAY ); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClearDepth(0); + glClearStencil(0); +} + +static void gl_render_poly( struct polygon_struct *poly ) +{ + render_set_context( poly->context, RENDER_NORMAL ); + glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count ); +} + +static void gl_render_tilelist( pvraddr_t tile_entry ) +{ + uint32_t *tile_list = (uint32_t *)(video_base+tile_entry); + int strip_count; + struct polygon_struct *poly; + + while(1) { + uint32_t entry = *tile_list++; + switch( entry >> 28 ) { + case 0x0F: + return; // End-of-list + case 0x0E: + tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF)); + break; + case 0x08: + case 0x09: + case 0x0A: + case 0x0B: + strip_count = ((entry >> 25) & 0x0F)+1; + poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF]; + while( strip_count > 0 ) { + gl_render_poly( poly ); + poly = poly->next; + strip_count--; + } + break; + default: + poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF]; + gl_render_poly( poly ); + } + } +} + + +/** + * Render the currently defined scene in pvr2_scene + */ +void pvr2_scene_render( render_buffer_t buffer ) +{ + /* Scene setup */ + display_driver->set_render_target(buffer); + pvr2_check_palette_changed(); + + /* Setup view projection matrix */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + float nearz = pvr2_scene.bounds[4]; + float farz = pvr2_scene.bounds[5]; + if( nearz == farz ) { + farz*= 2.0; + } + glOrtho( 0, pvr2_scene.buffer_width, pvr2_scene.buffer_height, 0, + -nearz, -farz ); + + /* Clear the buffer (FIXME: May not want always want to do this) */ + glDisable( GL_SCISSOR_TEST ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); + + /* Setup vertex array pointers */ + glInterleavedArrays(GL_T2F_C4UB_V3F, sizeof(struct vertex_struct), pvr2_scene.vertex_array); + glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].offset_rgba ); + + uint32_t bgplane_mode = MMIO_READ(PVR2, RENDER_BGPLANE); + uint32_t *bgplane = pvr2_scene.pvr2_pbuf + (((bgplane_mode & 0x00FFFFFF)) >> 3) ; + render_backplane( bgplane, pvr2_scene.buffer_width, pvr2_scene.buffer_height, bgplane_mode ); + + glEnable( GL_SCISSOR_TEST ); + + /* Process the segment list */ + struct tile_segment *segment = pvr2_scene.segment_list; + do { + int tilex = SEGMENT_X(segment->control); + int tiley = SEGMENT_Y(segment->control); + + int tile_bounds[4] = { tilex << 5, (tilex+1)<<5, tiley<<5, (tiley+1)<<5 }; + if( !clip_tile_bounds(tile_bounds, pvr2_scene.bounds) ) { + continue; // fully clipped, skip tile + } + + /* Clip to the visible part of the tile */ + glScissor( tile_bounds[0], pvr2_scene.buffer_height-tile_bounds[3], + tile_bounds[1]-tile_bounds[0], tile_bounds[3] - tile_bounds[2] ); + if( IS_TILE_PTR(segment->opaque_ptr) ) { + gl_render_tilelist(segment->opaque_ptr); + } + if( IS_TILE_PTR(segment->trans_ptr) ) { + gl_render_tilelist(segment->trans_ptr); + } + if( IS_TILE_PTR(segment->punchout_ptr) ) { + gl_render_tilelist(segment->punchout_ptr); + } + } while( !IS_LAST_SEGMENT(segment++) ); + glDisable( GL_SCISSOR_TEST ); + +} --- a/src/pvr2/pvr2.c Thu Feb 14 14:06:41 2008 +0000 +++ b/src/pvr2/pvr2.c Mon Feb 18 09:21:43 2008 +0000 @@ -454,9 +454,10 @@ g_free( pvr2_state.save_next_render_filename ); pvr2_state.save_next_render_filename = NULL; } + pvr2_scene_read(); render_buffer_t buffer = pvr2_next_render_buffer(); if( buffer != NULL ) { - pvr2_render_scene( buffer ); + pvr2_scene_render( buffer ); } asic_event( EVENT_PVR_RENDER_DONE ); break; @@ -940,9 +941,9 @@ render_addr = (render_addr & 0x00FFFFFF) + PVR2_RAM_BASE; } - int width, height; + int width = pvr2_scene_buffer_width(); + int height = pvr2_scene_buffer_height(); int colour_format = pvr2_render_colour_format[render_mode&0x07]; - pvr2_render_getsize( &width, &height ); result = pvr2_alloc_render_buffer( render_addr, width, height ); /* Setup the buffer */ --- a/src/pvr2/render.c Thu Feb 14 14:06:41 2008 +0000 +++ b/src/pvr2/render.c Mon Feb 18 09:21:43 2008 +0000 @@ -106,7 +106,7 @@ glDisable( GL_SCISSOR_TEST ); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(0); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); glEnableClientState( GL_COLOR_ARRAY ); glEnableClientState( GL_VERTEX_ARRAY ); } --- a/src/pvr2/scene.c Thu Feb 14 14:06:41 2008 +0000 +++ b/src/pvr2/scene.c Mon Feb 18 09:21:43 2008 +0000 @@ -28,6 +28,11 @@ #define VBO_EXT_STRING "GL_ARB_vertex_buffer_object" #define PBO_EXT_STRING "GL_ARB_pixel_buffer_object" +static inline uint32_t bgra_to_rgba(uint32_t bgra) +{ + return (bgra&0xFF00FF00) | ((bgra&0x00FF0000)>>16) | ((bgra&0x000000FF)<<16); +} + struct pvr2_scene_struct pvr2_scene; static gboolean vbo_init = FALSE; @@ -53,6 +58,16 @@ } } +/** + * Clear the scene data structures in preparation for fresh data + */ +void pvr2_scene_reset() +{ + pvr2_scene.poly_count = 0; + pvr2_scene.vertex_count = 0; + memset( pvr2_scene.buf_to_poly_map, 0, BUF_POLY_MAP_SIZE ); +} + void pvr2_scene_shutdown() { if( vbo_supported ) { @@ -70,13 +85,19 @@ void *vertex_buffer_map() { + glGetError(); uint32_t size = pvr2_scene.vertex_count * sizeof(struct vertex_struct); if( vbo_supported ) { glBindBufferARB( GL_ARRAY_BUFFER_ARB, pvr2_scene.vbo_id ); - + assert( glGetError() == 0 ); if( size > pvr2_scene.vertex_array_size ) { glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB ); - assert( glGetError() == 0 ); + int status = glGetError(); + if( status != 0 ) { + fprintf( stderr, "Error %08X allocating vertex buffer\n", status ); + abort(); + } + pvr2_scene.vertex_array_size = size; } pvr2_scene.vertex_array = glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB ); assert(pvr2_scene.vertex_array != NULL ); @@ -98,7 +119,7 @@ } } -static struct polygon_struct *vertex_buffer_add_polygon( pvraddr_t poly_idx, int vertex_count, +static struct polygon_struct *scene_add_polygon( pvraddr_t poly_idx, int vertex_count, gboolean is_modified ) { int vert_mul = is_modified ? 2 : 1; @@ -114,6 +135,7 @@ poly->context = (uint32_t *)(video_base + MMIO_READ(PVR2,RENDER_POLYBASE) + (poly_idx<<2)); poly->vertex_count = vertex_count; poly->vertex_index = -1; + poly->next = NULL; pvr2_scene.buf_to_poly_map[poly_idx] = poly; pvr2_scene.vertex_count += (vertex_count * vert_mul); return poly; @@ -125,13 +147,16 @@ * volume) * @param vert Pointer to output vertex structure * @param poly1 First word of polygon context (needed to understand vertex) + * @param poly2 Second word of polygon context * @param pvr2_data Pointer to raw pvr2 vertex data (in VRAM) * @param modify_offset Offset in 32-bit words to the tex/color data. 0 for * the normal vertex, half the vertex length for the modified vertex. */ static void pvr2_decode_render_vertex( struct vertex_struct *vert, uint32_t poly1, - uint32_t *pvr2_data, int modify_offset ) + uint32_t poly2, uint32_t *pvr2_data, + int modify_offset ) { + gboolean force_alpha = !POLY2_ALPHA_ENABLE(poly2); union pvr2_data_type { uint32_t *ival; float *fval; @@ -161,10 +186,20 @@ vert->u = *data.fval++; vert->v = *data.fval++; } + if( POLY2_TEX_BLEND(poly2) == 1 ) { + force_alpha = TRUE; + } } - vert->rgba = *data.ival++; - if( POLY1_SPECULAR(poly1) ) { - vert->offset_rgba = *data.ival++; + if( force_alpha ) { + vert->rgba = bgra_to_rgba((*data.ival++) | 0xFF000000); + if( POLY1_SPECULAR(poly1) ) { + vert->offset_rgba = bgra_to_rgba((*data.ival++) | 0xFF000000); + } + } else { + vert->rgba = bgra_to_rgba(*data.ival++); + if( POLY1_SPECULAR(poly1) ) { + vert->offset_rgba = bgra_to_rgba(*data.ival++); + } } } @@ -172,7 +207,7 @@ * Compute texture, colour, and z values for a result point by interpolating from * a set of 3 input points. The result point must define its x,y. */ -static void vertex_buffer_compute_vertex( struct vertex_struct *result, +static void scene_compute_vertex( struct vertex_struct *result, struct vertex_struct *input, gboolean is_solid_shaded ) { @@ -236,7 +271,7 @@ } -static void vertex_buffer_add_vertexes( pvraddr_t poly_idx, int vertex_length, +static void scene_add_vertexes( pvraddr_t poly_idx, int vertex_length, gboolean is_modified ) { struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_idx]; @@ -248,9 +283,10 @@ if( poly->vertex_index == -1 ) { ptr += (is_modified ? 5 : 3 ); poly->vertex_index = pvr2_scene.vertex_index; + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count ); for( i=0; ivertex_count; i++ ) { - pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], ptr, 0 ); + pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[1], ptr, 0 ); ptr += vertex_length; } if( is_modified ) { @@ -258,14 +294,14 @@ ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5; poly->mod_vertex_index = pvr2_scene.vertex_index; for( i=0; ivertex_count; i++ ) { - pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], ptr, mod_offset ); + pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[3], ptr, mod_offset ); ptr += vertex_length; } } } } -static void vertex_buffer_add_quad_vertexes( pvraddr_t poly_idx, int vertex_length, +static void scene_add_quad_vertexes( pvraddr_t poly_idx, int vertex_length, gboolean is_modified ) { struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_idx]; @@ -283,11 +319,14 @@ ptr += (is_modified ? 5 : 3 ); poly->vertex_index = pvr2_scene.vertex_index; for( i=0; i<4; i++ ) { - pvr2_decode_render_vertex( &quad[i], context[0], ptr, 0 ); + pvr2_decode_render_vertex( &quad[i], context[0], context[1], ptr, 0 ); ptr += vertex_length; } - vertex_buffer_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) ); - memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(quad) ); + scene_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) ); + // Swap last two vertexes (quad arrangement => tri strip arrangement) + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(struct vertex_struct)*2 ); + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+2], &quad[3], sizeof(struct vertex_struct) ); + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+3], &quad[2], sizeof(struct vertex_struct) ); pvr2_scene.vertex_index += 4; if( is_modified ) { @@ -295,17 +334,19 @@ ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5; poly->mod_vertex_index = pvr2_scene.vertex_index; for( i=0; i<4; i++ ) { - pvr2_decode_render_vertex( &quad[4], context[0], ptr, mod_offset ); + pvr2_decode_render_vertex( &quad[4], context[0], context[3], ptr, mod_offset ); ptr += vertex_length; } - vertex_buffer_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) ); - memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(quad) ); + scene_compute_vertex( &quad[3], &quad[0], !POLY1_GOURAUD_SHADED(context[0]) ); + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(struct vertex_struct)*2 ); + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+2], &quad[3], sizeof(struct vertex_struct) ); + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+3], &quad[2], sizeof(struct vertex_struct) ); pvr2_scene.vertex_index += 4; } } } -static void vertex_buffer_extract_polygons( pvraddr_t tile_entry ) +static void scene_extract_polygons( pvraddr_t tile_entry ) { uint32_t *tile_list = (uint32_t *)(video_base+tile_entry); do { @@ -332,7 +373,7 @@ int i; struct polygon_struct *last_poly = NULL; for( i=0; inext == NULL ) { last_poly->next = poly; @@ -346,7 +387,7 @@ int i; struct polygon_struct *last_poly = NULL; for( i=0; inext == NULL ) { last_poly->next = poly; @@ -363,14 +404,14 @@ } } if( last != -1 ) { - vertex_buffer_add_polygon( polyaddr, last+3, is_modified ); + scene_add_polygon( polyaddr, last+3, is_modified ); } } } } while( 1 ); } -static void vertex_buffer_extract_vertexes( pvraddr_t tile_entry ) +static void scene_extract_vertexes( pvraddr_t tile_entry ) { uint32_t *tile_list = (uint32_t *)(video_base+tile_entry); do { @@ -396,7 +437,7 @@ int polygon_length = 3 * vertex_length + context_length; int i; for( i=0; i> 16) & 0x03FF) + 1; pvr2_scene.bounds[2] = MMIO_READ( PVR2, RENDER_VCLIP ) & 0x03FF; @@ -484,7 +534,7 @@ } for( i=0; i<5; i++ ) { if( (*segment & NO_POINTER) == 0 ) { - vertex_buffer_extract_polygons( *segment ); + scene_extract_polygons( *segment ); } segment++; } @@ -502,7 +552,7 @@ control = *segment++; for( i=0; i<5; i++ ) { if( (*segment & NO_POINTER) == 0 ) { - vertex_buffer_extract_vertexes( *segment ); + scene_extract_vertexes( *segment ); } segment++; } @@ -511,22 +561,3 @@ vertex_buffer_unmap(); } } - -/** - * Render the data in the scene structure. The GL target should already be setup. - * Note: thar be GL code here. - */ -void vertex_buffer_render() -{ - /* Scene setup */ - - glEnable( GL_SCISSOR_TEST ); - - /* Scene render */ - struct tile_segment *segment = pvr2_scene.segment_list; - do { - - - } while( !IS_LAST_SEGMENT(segment) ); - glDisable( GL_SCISSOR_TEST ); -} --- a/src/pvr2/scene.h Thu Feb 14 14:06:41 2008 +0000 +++ b/src/pvr2/scene.h Mon Feb 18 09:21:43 2008 +0000 @@ -28,9 +28,9 @@ } tile_sort_mode_t; struct vertex_struct { - float x,y,z; float u,v; uint32_t rgba; + float x,y,z; uint32_t offset_rgba; }; @@ -117,8 +117,7 @@ /** Pointer to the start of the tile segment list in PVR2 VRAM (32-bit) */ struct tile_segment *segment_list; - /** Map from PVR2 polygon address to an element of poly_array. Temporary, - * used only during poly buffer parsing */ + /** Map from PVR2 polygon address to an element of poly_array. */ struct polygon_struct **buf_to_poly_map; /** Pointer to the start of the raw polygon buffer in PVR2 VRAM (32-bit). * Also only used during parsing */ --- a/src/pvr2/vertex.glsl Thu Feb 14 14:06:41 2008 +0000 +++ b/src/pvr2/vertex.glsl Mon Feb 18 09:21:43 2008 +0000 @@ -4,7 +4,6 @@ { gl_Position.xy = ftransform().xy; gl_Position.z = gl_Vertex.z; - gl_Position.w = 1; gl_FrontColor = gl_Color; gl_FrontSecondaryColor = gl_SecondaryColor; gl_TexCoord[0] = gl_MultiTexCoord0;