changeset 594:20166ecb1a78

add light
author yutaka@henri.cr.ie.u-ryukyu.ac.jp
date Wed, 04 Nov 2009 15:57:23 +0900
parents 6f741ab60749
children e0986347b103
files Renderer/Engine/spe/DrawSpan.cc Renderer/Engine/spe/DrawSpan.h
diffstat 2 files changed, 106 insertions(+), 149 deletions(-) [+]
line wrap: on
line diff
--- a/Renderer/Engine/spe/DrawSpan.cc	Tue Nov 03 21:08:47 2009 +0900
+++ b/Renderer/Engine/spe/DrawSpan.cc	Wed Nov 04 15:57:23 2009 +0900
@@ -1,14 +1,11 @@
-// #define DEBUG
-#include "error.h"
-
 #include <stdlib.h>
 #include <string.h>
-#include <spu_intrinsics.h>
 #include "DrawSpan.h"
 #include "polygon_pack.h"
 #include "texture.h"
 #include "viewer_types.h"
 #include "Func.h"
+#include "sys.h"
 #include "global_alloc.h"
 
 SchedDefineTask(DrawSpan);
@@ -29,34 +26,6 @@
     return 0;
 }
 
-
-inline vector float
-spu_re_nrm(vector float a)
-{
-    vector float unit = (vector float){1.0, 1.0, 1.0, 1.0};
-    vector float approximation;
-
-    approximation = spu_re(a);
-    return spu_madd(spu_nmsub(approximation, a, unit),
-                    approximation, approximation);
-}
-
-
-#if 0
-static vector signed int
-getLocalPositionVec(vector signed int d, signed int offset)
-{
-    return spu_and(d, spu_splats(offset-1));
-}
-
-static vector signed int
-getLocalXVec(vector signed int x)
-{
-    return getLocalPositionVec(x, split_screen_w);
-}
-#endif
-
-
 /**
  * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
  *
@@ -112,7 +81,7 @@
 getTile(int tx, int ty, int tw, memaddr tex_addr_top)
 {
     int block = getTexBlock(tx, ty, tw);
-    return tex_addr_top + block*TEXTURE_BLOCK_SIZE * sizeof(uint32);
+    return tex_addr_top + block * TEXTURE_BLOCK_SIZE * sizeof(uint32);
 }
 
 /**
@@ -148,13 +117,8 @@
     float *buf = (float*)smanager->allocate(sizeof(float)*width*height);
     float def = 65535.0f;
 
-    vector float init = spu_splats(0.0f);
-    vector float defi = spu_splats(def);
-
-    for (int i = 0; i < width*height; i += 4) {
-        vector float *out = (vector float *)&buf[i];
-
-        *out = spu_add(init, defi);
+    for (int i = 0; i < width*height; i++) {
+        buf[i] = def;
     }
 
     return buf;
@@ -168,58 +132,10 @@
     return data[(TEXTURE_SPLIT_PIXEL)*ty+tx];
 }
 
-#if 0
-/**
- * DrawSpan の再起動 (DrawSpanRenew 生成)
- *
- * @param[in] spack 現在処理している SpanPack
- * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で
- *                       どこまで進んでいるか
- */
-void
-DrawSpan::reboot(SpanPackPtr spack, int cur_span_x)
-{
-    DrawSpanArgPtr args =
-        (DrawSpanArgPtr)smanager->allocate(sizeof(DrawSpanArg));
-    TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2);
-
-    // 数が多いので構造体で渡す
-    args->display      = smanager->get_param(0);
-    args->screen_width = smanager->get_param(1);
-    args->rangex_start = smanager->get_param(2);
-    args->rangex_end   = smanager->get_param(3);
-    args->rangey       = smanager->get_param(4);
-    renew_task->add_param((int)args);
-
-    /**
-     * SpanPack は続きから開始するので、
-     * 現在の状態をコピーしておく。
-     * spack は rbuf から取得してる可能性があり
-     * rbuf はシステムが自動的に free() するため
-     * アドレスだけ渡すのはNG
-     */
-    SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
-    memcpy(curr, spack, sizeof(SpanPack));
-    renew_task->add_param((int)curr);
-    renew_task->add_param(cur_span_x);
-
-    // linebuf と zRow も引き継がせる
-    renew_task->add_param((int)linebuf);
-    renew_task->add_param((int)zRow);
-
-    /**
-     * 再起動したタスクを待つ
-     */
-    smanager->wait_task(renew_task);
-
-    // next_spack は free() するので wait する
-    smanager->dma_wait(SPAN_PACK_LOAD);
-}
-#endif
 
 static void
 writebuffer(SchedTask *smanager, Gptr g, unsigned int display, 
-        int buf_width, int height, int screen_width)
+	int buf_width, int height, int screen_width)
 {
     for (int i = 0; i < height; i++) {
         smanager->dma_store(&g->linebuf[i*buf_width],
@@ -242,13 +158,22 @@
  * @param tex_addr テクスチャのアドレス(MainMemory)
  */
 static void
-updateBuffer(Gptr g, float zpos, int rangex, int x, int y,
-                       int tex_x, int tex_y, TilePtr tile)
+updateBuffer(Gptr g, float zpos, int rangex, int x, int y, int tex_x, int tex_y,
+                       float normal_x, float normal_y, float normal_z, TilePtr tile)
 {
-    int rgb = get_rgb(tex_x, tex_y, tile);
+
 
-    g->zRow[x + (rangex*y)] = zpos;
-    g->linebuf[x + (rangex*y)] = rgb;
+    int color = get_rgb(tex_x, tex_y, tile);
+    /*下位4bitを抽出*/
+    int alpha = color & 0xF000;
+    /*完全に透けているか判断*/
+    int flag = (alpha != 0);
+
+    color = infinity_light_calc(color,normal_x,normal_y,normal_z);
+
+    g->zRow[x + (rangex*y)] = zpos*flag + g->zRow[x + (rangex*y)]*(1-flag);
+    g->linebuf[x + (rangex*y)] = color*flag + g->linebuf[x + (rangex*y)]*(1-flag);
+
 }
 
 /**
@@ -258,12 +183,16 @@
  * @param startx 描画開始範囲
  * @param endx 描画終了範囲
  */
-
 static int
 drawDot1(SchedTask *smanager, Gptr g, SpanPtr span, int startx, int endx, int wait_tag)
 {
     int rangex = endx - startx + 1;
 
+    float normal_x = span->normal_x;
+    float normal_y = span->normal_y;
+    float normal_z = span->normal_z;
+
+
     /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */
     int tex_xpos, tex_ypos;
 
@@ -299,16 +228,24 @@
         tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
         tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
 
-        TilePtr tile = smanager->get_segment(tex_addr,g->tileList);
-        smanager->wait_segment(tile);
+	TilePtr tile = smanager->get_segment(tex_addr,g->tileList);
+	smanager->wait_segment(tile);
 
         updateBuffer(g, zpos, rangex, localx, localy,
-                     tex_localx, tex_localy, tile);	
+                     tex_localx, tex_localy,
+                     normal_x,normal_y,normal_z,tile);
     }
 
     return -1;
 }
 
+#if 0
+static void
+drawDot2(SchedTask *smanager, SpanPtr span, int startx, int end, int js, int wait_tag)
+{
+    //printf("%d\n", js);
+}
+#endif
 
 /**
  * 長さが 1 より大きい Span の描画
@@ -334,6 +271,11 @@
     int rangex = endx - startx + 1;
     int x_len = span->length_x;
 
+    float normal_x = span->normal_x;
+    float normal_y = span->normal_y;
+    float normal_z = span->normal_z;
+
+
     int js = (x < startx) ? startx - x : 0;
     int je = (x + x_len > endx) ? endx - x : x_len;
 
@@ -385,41 +327,61 @@
                                span->tex_width, (memaddr)span->tex_addr);
             tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
             tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
-
 	    TilePtr tile = smanager->get_segment(tex_addr,g->tileList);
 	    smanager->wait_segment(tile);
 
             updateBuffer(g, tex_z, rangex, localx, localy,
-			 tex_localx, tex_localy, tile);
+                         tex_localx, tex_localy,
+                         normal_x, normal_y, normal_z, tile);
         }
     }
 
     return ret;
 }
 
-#if 1
-void
-fix_relocation(char **addr,int count)
+float
+innerProduct(float *v0, float *v1)
+{
+    return (v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2]);
+}
+
+static int
+infinity_light_calc(int color,float normal_x, float normal_y, float normal_z)
 {
-    unsigned int pc;
-    unsigned int label;
-    __asm__ __volatile__(
-"         brsl %0,____LLLL\n"
-"____LLLL:"
-"         ila  %1,____LLLL"
-        : "=r" (pc), "=r" (label));
-    int offset = pc-label;
-    int i;
-    for(i=0;i<count;i++) {
-	addr[i] += offset;
-    }
+    unsigned char rgb[4];
+    int light_rgb;
+    int flag;
+    float normal_vector[4] = {normal_x,normal_y,normal_z,0};
+    // 光のベクトル,きめうちしちゃった。どうにかする
+    float light_vector[4] = {0,0,-1,0};
+    float inner_product;
+
+    // 引数で受け取った color の rgb 情報の抜き出し
+    rgb[3] = (color & 0xff000000) >> 24;
+    rgb[2] = (color & 0x00ff0000) >> 16;
+    rgb[1] = (color & 0x0000ff00) >> 8;
+    rgb[0] = (color & 0x000000ff);
+
+    // 法線ベクトルと光源ベクトルとの内積をとる
+    inner_product = innerProduct(normal_vector,light_vector);
+    // 内積がマイナスの場合は色がない。
+    flag = (inner_product > 0);
+
+    // 内積を rgb にかけていく
+    rgb[0] = (unsigned char)(rgb[0]*inner_product*flag);
+    rgb[1] = (unsigned char)(rgb[1]*inner_product*flag);
+    rgb[2] = (unsigned char)(rgb[2]*inner_product*flag);
+
+    //計算した rgb を light_rgb にまとめる。
+    light_rgb = (rgb[3] << 24) + (rgb[2] << 16) + (rgb[1] << 8) + (rgb[0]);
+
+    return light_rgb;
 }
-#endif
+
 
 static int
 run(SchedTask *smanager, void *rbuf, void *wbuf)
 {
-    __debug_spe("DrawSpan\n");
     Gptr g = (Gptr)smanager->allocate(sizeof(G));
 
     SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0);
@@ -430,10 +392,9 @@
     Span nop_span;
     nop_span.length_x = 1;
 
-//    int (*drawFunc1[2])(SchedTask *, Gptr, SpanPtr, int, int, int) = {
-//        &drawDot1, &drawLine1
-//    };
-//    fix_relocation((void**)drawFunc1,2);
+    int (*drawFunc1[2])(SchedTask *, Gptr, SpanPtr, int, int, int) = {
+        &drawDot1, &drawLine1
+    };
 
     uint32 display   = smanager->get_param(0);
     int screen_width = smanager->get_param(1);
@@ -445,7 +406,6 @@
 
     // y の範囲
     int rangey = smanager->get_param(4);
-
     g->tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
 
     g->zRow = zRow_init(smanager, rangex, rangey);
@@ -465,7 +425,7 @@
          * 次の SpanPack の DMA 転送を行う
          */
         if (spack->next != NULL) {
-            smanager->dma_load(next_spack, (memaddr)spack->next,
+            smanager->dma_load(next_spack, (uint32)spack->next,
                                sizeof(SpanPack), SPAN_PACK_LOAD);
         } else {
             next_spack = NULL;
@@ -483,15 +443,10 @@
             /**
              * span の長さによって、drawLine か drawDot を選択している
              */
-	    if (span->length_x != 1) {
-		next_span_x
-		    = drawLine1( smanager, g,
-			span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]);
-	    } else {
-		next_span_x
-		    = drawDot1( smanager, g,
-			span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]);
-	    }
+            next_span_x
+                = (*drawFunc1[(span->length_x != 1)])(
+		    smanager, g,
+                    span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]);
             next_span = span;
 
             resume_span = next_span;
@@ -536,3 +491,5 @@
 
     return 0;
 }
+
+/* end */
--- a/Renderer/Engine/spe/DrawSpan.h	Tue Nov 03 21:08:47 2009 +0900
+++ b/Renderer/Engine/spe/DrawSpan.h	Wed Nov 04 15:57:23 2009 +0900
@@ -5,34 +5,34 @@
 #include "Tapestry.h"
 #include "SpanPack.h"
 
-typedef struct g {
+typedef struct {
     int *linebuf;
     float *zRow;
     TileListPtr tileList;
     int doneWrite;
-} G, *Gptr ;
-
+} G, *Gptr; 
 
-static int run(SchedTask *smanager, void *rbuf, void *wbuf);
-
-static    int* linebuf_init(SchedTask *s, int width, int height, int rgb);
-static    float* zRow_init(SchedTask *s, int width, int height);
+static    int* linebuf_init(SchedTask *smanager, int width, int height, int rgb);
+static    float* zRow_init(SchedTask *smanager, int width, int height);
+// static    TilePtr set_rgb(memaddr addr, int wait_tag);
+// static    void set_rgbs(memaddr addr, uint32 *max_addr, int wait_tag);
 static    uint32 get_rgb(int tx, int ty, TilePtr tile);
+// static    TilePtr isAvailableTile(memaddr addr);
 static    memaddr getTile(int tx, int ty, int tw, memaddr tex_addr_top);
 static    int getTexBlock(int tx, int ty, int twidth);
-static    void writebuffer(SchedTask *s, Gptr g, unsigned int display, int width, int height,
-		     int screen_width);
+static    void writebuffer(SchedTask *smanager, Gptr g, unsigned int display, 
+	    int width, int height, int screen_width);
 static    void updateBuffer(Gptr g, float zpos, int rangex, int x, int y,
-		      int tex_x, int tex_y, TilePtr tile);
+                      int tex_x, int tex_y, float normal_x, float nomral_x, float normal_z, TilePtr tile);
+
 
-#if 0
-static    void reboot(SpanPackPtr spack, int cur_span_x);
-#endif
+// static    void reboot(SpanPackPtr spack, int cur_span_x);
 
-static    int drawDot1(SchedTask *s, Gptr g, SpanPtr span, int startx, int endx, int wait_tag);
-//static    void drawDot2(SpanPtr span, int startx, int endx, int js, int wait_tag);
-static    int drawLine1(SchedTask *s, Gptr g, SpanPtr span, int startx, int endx, int wait_tag);
-//static    void drawLine2(SpanPtr span, int startx, int endx, int js, int wait_tag);
+static    int drawDot1(SchedTask *smanager, Gptr g, SpanPtr span, int startx, int endx, int wait_tag);
+//static    void drawDot2(SchedTask *smanager, SpanPtr span, int startx, int endx, int js, int wait_tag);
+static    int drawLine1(SchedTask *smanager, Gptr g, SpanPtr span, int startx, int endx, int wait_tag);
+// static    void drawLine2(SchedTask *smanager, SpanPtr span, int startx, int endx, int js, int wait_tag);
+static    int infinity_light_calc(int color,float normal_x, float normal_y, float normal_z);
 
 typedef struct {
     uint32 display;