comparison 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
comparison
equal deleted inserted replaced
162:99d512912eb6 165:246881f0634b
19 unsigned short PRIME[8] = { 19 unsigned short PRIME[8] = {
20 0x002, 0x065, 0x0c7, 0x133, 0x191, 0x1f3, 0x259, 0x2bd, 20 0x002, 0x065, 0x0c7, 0x133, 0x191, 0x1f3, 0x259, 0x2bd,
21 }; 21 };
22 22
23 static TileListPtr tileList; 23 static TileListPtr tileList;
24
25 /**
26 * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
27 *
28 * +---+---+---+---+---+---+
29 * | 0 | 1 | 2 | 3 | 4 | 5 |
30 * +---+---+---+---+---+---+
31 * | | | | | |11 |
32 * +---+---+---+---+---+---+
33 * | | | | | |17 |
34 * +---+---+---+---+---+---+
35 * | | | | | |23 |
36 * +---+---+---+---+---+---+
37 * | | | | | |29 |
38 * +---+---+---+---+---+---+
39 * | | | | | |35 |
40 * +---+---+---+---+---+---+
41 *
42 * 一辺を TEXTURE_SPLIT とする
43 * 各ブロックの数字がブロックIDとなる。
44 */
45
46 /**
47 * テクスチャの座標から、
48 * テクスチャのどのブロックかを求める
49 *
50 * @param[in] tx X coordinates of texture
51 * @param[in] tx Y coordinates of texture
52 * @param[in] twidth Width of texture
53 * @return block ID
54 */
55 static inline int
56 get_tex_block(int tx, int ty, int twidth)
57 {
58 int blockX, blockY;
59
60 blockX = tx / TEXTURE_SPLIT_PIXEL;
61 blockY = ty / TEXTURE_SPLIT_PIXEL;
62
63 return blockX + (twidth/TEXTURE_SPLIT_PIXEL)*blockY;
64 }
65
66 /**
67 * block ID と、テクスチャの TOP address から
68 * (tx,ty) で使われるテクスチャの Tile addres を求める
69 *
70 * @param[in] tx X coordinates of texture
71 * @param[in] tx Y coordinates of texture
72 * @param[in] tw Width of texture
73 * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address
74 * @return block ID
75 */
76 static inline uint32*
77 getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
78 {
79 int block = get_tex_block(tx, ty, tw);
80 return tex_addr_top + block*TEXTURE_BLOCK_SIZE;
81 }
82
24 83
25 static int 84 static int
26 hash(uint32 data) 85 hash(uint32 data)
27 { 86 {
28 int value = 0; 87 int value = 0;
151 210
152 return (red & 0xff) * 0x10000 + (green & 0xff) * 0x100 211 return (red & 0xff) * 0x10000 + (green & 0xff) * 0x100
153 + (blue & 0xff) + (alpha << 24); 212 + (blue & 0xff) + (alpha << 24);
154 } 213 }
155 214
215
216
156 int 217 int
157 DrawSpan::run(void *rbuf, void *wbuf) 218 DrawSpan::run(void *rbuf, void *wbuf)
158 { 219 {
159 SpanPack *sp = (SpanPack*)smanager->get_input(0); 220 SpanPack *sp = (SpanPack*)smanager->get_input(0);
160 SpanPack *next_sp = 221 SpanPack *next_sp =
161 (SpanPack*)smanager->allocate(sizeof(SpanPack)); 222 (SpanPack*)smanager->allocate(sizeof(SpanPack));
162 SpanPack *free_sp = next_sp; // next_sp の free() 用 223 SpanPack *free_sp = next_sp; // next_sp の free() 用
163 SpanPack *tmp_sp = NULL; 224 SpanPack *tmp_sp = NULL;
164 Span *span; 225 Span *span;
165 226
166 TileInfoListPtr tilist =
167 (TileInfoListPtr)smanager->allocate(sizeof(TileInfoList));
168 TileInfoListPtr next_tilist =
169 (TileInfoListPtr)smanager->allocate(sizeof(TileInfoList));
170
171 tileList = (TileListPtr)smanager->allocate(sizeof(TileList)); 227 tileList = (TileListPtr)smanager->allocate(sizeof(TileList));
172 tileList->init(); 228 tileList->init();
173 229
174 void *texture_image = global_get(TEXTURE_ID);
175 int rangex_start = get_param(0); // このタスクが担当する x の範囲の始点 230 int rangex_start = get_param(0); // このタスクが担当する x の範囲の始点
176 int rangex_end = get_param(1); // 終点 (start <= x <= end) 231 int rangex_end = get_param(1); // 終点 (start <= x <= end)
177 int rangey = get_param(2); // y の範囲 (render_y + rangey - 1) 232 int rangey = get_param(2); // y の範囲 (render_y + rangey - 1)
178 int rangex = rangex_end - rangex_start + 1; 233 int rangex = rangex_end - rangex_start + 1;
179 234
202 } 257 }
203 258
204 for (int t = 0; t < sp->info.size; t++) { 259 for (int t = 0; t < sp->info.size; t++) {
205 span = &sp->span[t]; 260 span = &sp->span[t];
206 261
207 smanager->dma_load(tilist, (uint32)span->tilelist,
208 sizeof(TileInfoList), TILE_INFO_LOAD);
209
210 Uint32 rgb = 0x00ff00; 262 Uint32 rgb = 0x00ff00;
263 float tex1 = span->tex_x1;
264 float tex2 = span->tex_x2;
265 float tey1 = span->tex_y1;
266 float tey2 = span->tex_y2;
267
211 int tex_xpos; 268 int tex_xpos;
212 int tex_ypos; 269 int tex_ypos;
213 int tex_zpos; 270 int tex_zpos;
271
272 int tex_localx;
273 int tex_localy;
274 uint32 *tex_addr;
275
214 int x = span->x; 276 int x = span->x;
215 int y = span->y; 277 int y = span->y;
216 int x_len = span->length_x; 278 int x_len = span->length_x;
217 float z = span->start_z; 279 float z = span->start_z;
218 float zpos = span->end_z; 280 float zpos = span->end_z;
219 281
220 // 座標が [0 .. split_screen_w-1] に入るように x,y を -1 282 // 座標が [0 .. split_screen_w-1] に入るように x,y を -1
221 int localx = getLocalX(x-1); 283 int localx = getLocalX(x-1);
222 int localy = getLocalY(y-1); 284 int localy = getLocalY(y-1);
223 285
224 smanager->dma_wait(TILE_INFO_LOAD);
225
226 if (x_len == 1) { 286 if (x_len == 1) {
227 if (x < rangex_start || rangex_end < x) { 287 if (x < rangex_start || rangex_end < x) {
228 continue; 288 continue;
229 } 289 }
230 290
231 tex_xpos = tilist->tileinfo[0].tix; 291 tex_xpos = (int)((span->tex_width-1) * tex1);
232 tex_ypos = tilist->tileinfo[0].tiy; 292 tex_ypos = (int)((span->tex_height-1) * tey1);
233 tex_zpos = (int)z; 293 tex_zpos = (int)z;
234 texture_image = tilist->tileinfo[0].tile;
235 294
236 if (zpos < zRow[localx + (rangex * localy)]) { 295 if (zpos < zRow[localx + (rangex * localy)]) {
237 rgb = get_rgb(tex_xpos, tex_ypos, texture_image); 296 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
297 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
298 tex_addr = getTile(tex_xpos, tex_ypos,
299 span->tex_width, span->tex_addr);
300
301 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
302
238 zRow[localx + (rangex * localy)] = zpos; 303 zRow[localx + (rangex * localy)] = zpos;
239 linebuf[localy][localx] = rgb; 304 linebuf[localy][localx] = rgb;
240 } 305 }
241 } else { 306 } else {
242 int js = (x < rangex_start) ? rangex_start - x : 0; 307 int js = (x < rangex_start) ? rangex_start - x : 0;
243 int je = (x + x_len > rangex_end) ? rangex_end - x : x_len; 308 int je = (x + x_len > rangex_end) ? rangex_end - x : x_len;
244 309 float tex_x, tex_y, tex_z;
245 if (js > je) continue; 310
246 311 for (int j = js; j <= je; j++) {
247 int cur_x = 0; 312 localx = getLocalX(x-1+j);
248 int max_x = je; 313
249 int len = 0; 314 tex_z = z*(x_len-1-j)/(x_len-1) + zpos*j/(x_len-1);
250 315
251 /** 316 tex_x = tex1*(x_len-1-j)/(x_len-1) + tex2*j/(x_len-1);
252 * Span は表示しない範囲([js..je]) の TileInfoList を 317 tex_y = tey1*(x_len-1-j)/(x_len-1) + tey2*j/(x_len-1);
253 * 持っているので、それは飛ばす
254 */
255 while (cur_x + MAX_TILE_LIST <= js) {
256 smanager->dma_load(next_tilist, (uint32)tilist->next,
257 sizeof(TileInfoList), TILE_INFO_LOAD);
258 smanager->dma_wait(TILE_INFO_LOAD);
259
260 TileInfoListPtr tmp = tilist;
261 tilist = next_tilist;
262 next_tilist = tmp;
263
264 cur_x += MAX_TILE_LIST;
265 }
266
267 cur_x = js;
268
269 while (cur_x <= max_x) {
270 /** 318 /**
271 * TileInfoList は 30 ずつで区切られてるので 319 * ・・・なんかかっこいい書き方ないかな
272 * cur_x が TileInfoList の途中から始まっても
273 * MAX_TILE_LIST に収まる様に
274 * (ex.)
275 * cur_x (=js) が 0 から始まった場合、
276 * cur_x = 0, len = 29
277 * cur_x (=js) が 15 から始まった場合、
278 * cur_x = 15, len = 14 になる
279 */ 320 */
280 int cur_x_diff = MAX_TILE_LIST - (cur_x % MAX_TILE_LIST); 321 if (tex_x > 1) tex_x = 1;
281 322 if (tex_x < 0) tex_x = 0;
282 if (cur_x + cur_x_diff - 1 < max_x) { 323 if (tex_y > 1) tex_y = 1;
283 smanager->dma_load(next_tilist, (uint32)tilist->next, 324 if (tex_y < 0) tex_y = 0;
284 sizeof(TileInfoList), 325 tex_xpos = (int)((span->tex_width-1) * tex_x);
285 TILE_INFO_LOAD); 326 tex_ypos = (int)((span->tex_height-1) * tex_y);
286 len = cur_x_diff - 1; 327
287 } else { 328 if (tex_z < zRow[localx + (rangex*localy)]) {
288 len = max_x - cur_x; 329 tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
330 tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
331 tex_addr = getTile(tex_xpos, tex_ypos,
332 span->tex_width, span->tex_addr);
333
334 rgb = get_rgb(tex_localx, tex_localy, tex_addr);
335
336 zRow[localx + (rangex*localy)] = tex_z;
337 linebuf[localy][localx] = rgb;
289 } 338 }
290
291 for (int j = cur_x; j <= cur_x + len; j++) {
292 TileInfoPtr tinfo = &tilist->tileinfo[j%MAX_TILE_LIST];
293 float tex_z
294 = z*(x_len-1-j)/(x_len-1) + zpos*j/(x_len-1);
295
296 localx = getLocalX(x-1+j);
297
298 tex_xpos = tinfo->tix;
299 tex_ypos = tinfo->tiy;
300 texture_image = tinfo->tile;
301
302 if (tex_z < zRow[localx + (rangex*localy)]) {
303 rgb = get_rgb(tex_xpos, tex_ypos, texture_image);
304 zRow[localx + (rangex*localy)] = tex_z;
305 linebuf[localy][localx] = rgb;
306 }
307 }
308
309 smanager->dma_wait(TILE_INFO_LOAD);
310
311 TileInfoListPtr tmp = tilist;
312 tilist = next_tilist;
313 next_tilist = tmp;
314
315 cur_x += cur_x_diff;
316 } 339 }
317 } 340 }
318 } 341 }
319 342
320 smanager->dma_wait(SPAN_PACK_LOAD); 343 smanager->dma_wait(SPAN_PACK_LOAD);
326 349
327 free(free_sp); 350 free(free_sp);
328 free(linebuf); 351 free(linebuf);
329 free(zRow); 352 free(zRow);
330 free(tileList); 353 free(tileList);
331 free(tilist);
332 free(next_tilist);
333 354
334 return 0; 355 return 0;
335 } 356 }