diff TaskManager/Test/test_render/spe/DrawSpan.cpp @ 165:246881f0634b

fix
author gongo@localhost.localdomain
date Tue, 09 Dec 2008 11:15:37 +0900
parents 38cbb7aecc70
children e297ecaf2b4d
line wrap: on
line diff
--- a/TaskManager/Test/test_render/spe/DrawSpan.cpp	Mon Dec 08 21:28:59 2008 +0900
+++ b/TaskManager/Test/test_render/spe/DrawSpan.cpp	Tue Dec 09 11:15:37 2008 +0900
@@ -22,6 +22,65 @@
 
 static TileListPtr tileList;
 
+/**
+ * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
+ *
+ * +---+---+---+---+---+---+
+ * | 0 | 1 | 2 | 3 | 4 | 5 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |11 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |17 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |23 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |29 |
+ * +---+---+---+---+---+---+
+ * |   |   |   |   |   |35 |
+ * +---+---+---+---+---+---+
+ *
+ * 一辺を TEXTURE_SPLIT とする
+ * 各ブロックの数字がブロックIDとなる。
+ */
+
+/**
+ * テクスチャの座標から、
+ * テクスチャのどのブロックかを求める
+ *
+ * @param[in] tx X coordinates of texture
+ * @param[in] tx Y coordinates of texture
+ * @param[in] twidth  Width of texture
+ * @return block ID
+ */
+static inline int
+get_tex_block(int tx, int ty, int twidth)
+{
+     int blockX, blockY;
+
+     blockX = tx / TEXTURE_SPLIT_PIXEL;
+     blockY = ty / TEXTURE_SPLIT_PIXEL;
+
+     return blockX + (twidth/TEXTURE_SPLIT_PIXEL)*blockY;
+}
+
+/**
+ * block ID と、テクスチャの TOP address から
+ * (tx,ty) で使われるテクスチャの Tile addres を求める
+ *
+ * @param[in] tx X coordinates of texture
+ * @param[in] tx Y coordinates of texture
+ * @param[in] tw Width of texture
+ * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address
+ * @return block ID
+ */
+static inline uint32*
+getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
+{
+    int block = get_tex_block(tx, ty, tw);
+    return tex_addr_top + block*TEXTURE_BLOCK_SIZE;
+}
+
+
 static int
 hash(uint32 data)
 {
@@ -153,6 +212,8 @@
 	+ (blue & 0xff) + (alpha << 24);
 }
 
+
+
 int
 DrawSpan::run(void *rbuf, void *wbuf)
 {
@@ -163,15 +224,9 @@
     SpanPack *tmp_sp = NULL;
     Span *span;
 
-    TileInfoListPtr tilist =
-	(TileInfoListPtr)smanager->allocate(sizeof(TileInfoList));
-    TileInfoListPtr next_tilist =
-	(TileInfoListPtr)smanager->allocate(sizeof(TileInfoList));
-
     tileList = (TileListPtr)smanager->allocate(sizeof(TileList));
     tileList->init();
 
-    void *texture_image = global_get(TEXTURE_ID);    
     int rangex_start  = get_param(0); // このタスクが担当する x の範囲の始点
     int rangex_end    = get_param(1); // 終点 (start <= x <= end)
     int rangey        = get_param(2); // y の範囲 (render_y + rangey - 1)
@@ -204,13 +259,20 @@
 	for (int t = 0; t < sp->info.size; t++) {	  
 	    span = &sp->span[t];
 
-	    smanager->dma_load(tilist, (uint32)span->tilelist,
-			       sizeof(TileInfoList), TILE_INFO_LOAD);
+	    Uint32 rgb = 0x00ff00;
+	    float tex1 = span->tex_x1;
+	    float tex2 = span->tex_x2;
+	    float tey1 = span->tex_y1;
+	    float tey2 = span->tex_y2;
 
-	    Uint32 rgb = 0x00ff00;
 	    int tex_xpos;
 	    int tex_ypos;
 	    int tex_zpos;
+
+	    int tex_localx;
+	    int tex_localy;
+	    uint32 *tex_addr;
+
 	    int x = span->x;
 	    int y = span->y;
 	    int x_len = span->length_x;
@@ -221,98 +283,59 @@
 	    int localx = getLocalX(x-1);
 	    int localy = getLocalY(y-1);
 
-	    smanager->dma_wait(TILE_INFO_LOAD);
-
 	    if (x_len == 1) {
 		if (x < rangex_start || rangex_end < x) {
 		    continue;
 		}
 
-		tex_xpos = tilist->tileinfo[0].tix;
-		tex_ypos = tilist->tileinfo[0].tiy;
+		tex_xpos = (int)((span->tex_width-1) * tex1);
+		tex_ypos = (int)((span->tex_height-1) * tey1);
 		tex_zpos = (int)z;
-		texture_image = tilist->tileinfo[0].tile;
 
 		if (zpos < zRow[localx + (rangex * localy)]) {
-		    rgb = get_rgb(tex_xpos, tex_ypos, texture_image);
+		    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+		    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+		    tex_addr = getTile(tex_xpos, tex_ypos,
+				       span->tex_width, span->tex_addr);
+
+		    rgb = get_rgb(tex_localx, tex_localy, tex_addr);
+
 		    zRow[localx + (rangex * localy)] = zpos;
 		    linebuf[localy][localx] = rgb;
 		}
 	    } else {
 		int js = (x < rangex_start) ? rangex_start - x : 0;
 		int je = (x + x_len > rangex_end) ? rangex_end - x : x_len;
-		
-		if (js > je) continue;
-
-		int cur_x = 0;
-		int max_x = je;
-		int len = 0;
+		float tex_x, tex_y, tex_z;
 
-		/**
-		 * Span は表示しない範囲([js..je]) の TileInfoList を
-		 * 持っているので、それは飛ばす
-		 */
-		while (cur_x + MAX_TILE_LIST <= js) {
-		    smanager->dma_load(next_tilist, (uint32)tilist->next,
-				       sizeof(TileInfoList), TILE_INFO_LOAD);
-		    smanager->dma_wait(TILE_INFO_LOAD);
+		for (int j = js; j <= je; j++) {
+		    localx = getLocalX(x-1+j);
 
-		    TileInfoListPtr tmp = tilist;
-		    tilist = next_tilist;
-		    next_tilist = tmp;
-
-		    cur_x += MAX_TILE_LIST;
-		}
-
-		cur_x = js;
+		    tex_z = z*(x_len-1-j)/(x_len-1) + zpos*j/(x_len-1);
 
-		while (cur_x <= max_x) {
+		    tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
+		    tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
 		    /**
-		     * TileInfoList は 30 ずつで区切られてるので
-		     * cur_x が TileInfoList の途中から始まっても
-		     * MAX_TILE_LIST に収まる様に
-		     * (ex.)
-		     *   cur_x (=js) が 0 から始まった場合、
-		     *     cur_x = 0, len = 29
-		     *   cur_x (=js) が 15 から始まった場合、
-		     *     cur_x = 15, len = 14 になる
+		     * ・・・なんかかっこいい書き方ないかな
 		     */
-		    int cur_x_diff = MAX_TILE_LIST - (cur_x % MAX_TILE_LIST);
-
-		    if (cur_x + cur_x_diff - 1 < max_x) {
-			smanager->dma_load(next_tilist, (uint32)tilist->next,
-					   sizeof(TileInfoList),
-					   TILE_INFO_LOAD);
-			len = cur_x_diff - 1;
-		    } else {
-			len = max_x - cur_x;
-		    }
-
-		    for (int j = cur_x; j <= cur_x + len; j++) {
-			TileInfoPtr tinfo = &tilist->tileinfo[j%MAX_TILE_LIST];
-			float tex_z
-			     = z*(x_len-1-j)/(x_len-1) + zpos*j/(x_len-1);
-
-			localx = getLocalX(x-1+j);
+		    if (tex_x > 1) tex_x = 1;
+		    if (tex_x < 0) tex_x = 0;
+		    if (tex_y > 1) tex_y = 1;
+		    if (tex_y < 0) tex_y = 0;
+		    tex_xpos = (int)((span->tex_width-1) * tex_x);
+		    tex_ypos = (int)((span->tex_height-1) * tex_y);
+		    
+		    if (tex_z < zRow[localx + (rangex*localy)]) {
+			tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
+			tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+			tex_addr = getTile(tex_xpos, tex_ypos,
+					   span->tex_width, span->tex_addr);
+			
+			rgb = get_rgb(tex_localx, tex_localy, tex_addr);
 
-			tex_xpos = tinfo->tix;
-			tex_ypos = tinfo->tiy;
-			texture_image = tinfo->tile;
-
-			if (tex_z < zRow[localx + (rangex*localy)]) {
-			    rgb = get_rgb(tex_xpos, tex_ypos, texture_image);
-			    zRow[localx + (rangex*localy)] = tex_z;
-			    linebuf[localy][localx] = rgb;
-			}
+			zRow[localx + (rangex*localy)] = tex_z;
+			linebuf[localy][localx] = rgb;
 		    }
-		    
-		    smanager->dma_wait(TILE_INFO_LOAD);
-		    
-		    TileInfoListPtr tmp = tilist;
-		    tilist = next_tilist;
-		    next_tilist = tmp;
-		    
-		    cur_x += cur_x_diff;
 		}
 	    }
 	}
@@ -328,8 +351,6 @@
     free(linebuf);
     free(zRow);
     free(tileList);
-    free(tilist);
-    free(next_tilist);
 
     return 0;
 }