Mercurial > hg > Game > Cerium
changeset 1404:0f8bee7eed3c draft
unify DrawSpan
author | sugi |
---|---|
date | Wed, 15 Feb 2012 17:45:24 +0900 |
parents | 95b114c66e14 |
children | aafad9d18a2c |
files | Renderer/Engine/SgChange.cc Renderer/Engine/SgChange.h Renderer/Engine/spe/DrawBack.cc Renderer/Engine/spe/DrawSpan.cc Renderer/Engine/spe/InitKey.cc Renderer/Engine/task/DrawSpan.cc Renderer/Engine/task/ExecMove.cc Renderer/Engine/task/ExecMove.h Renderer/Engine/task/SendKey.cc Renderer/Engine/task/SendKey.h Renderer/Engine/task/Switch.cc Renderer/Engine/task/Switch.h |
diffstat | 12 files changed, 353 insertions(+), 532 deletions(-) [+] |
line wrap: on
line diff
--- a/Renderer/Engine/SgChange.cc Wed Feb 15 16:52:00 2012 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -#include <SDL.h> -#include "SgChange.h" -#include "viewer_types.h" -#include "SceneGraph.h" -#include "SceneGraphRoot.h" -#include "scene_graph_pack.h" -#include "matrix_calc.h" -#include "Func.h" -#include "error.h" -#include "TaskManager.h" -#include <wchar.h> -#include "Pad.h" -#include "Application.h" -#include "lindaapi.h" - -static void post2runLoop(SchedTask *s, void *viewer, void *s1); -static void post2run(SchedTask *s, void *viewer, void *s1); -static void post2runDraw(SchedTask *s, void *viewer, void *s1); -static void post2rendering(SchedTask *s, void *viewer, void *s1); - -/* measure for FPS (Frame Per Second) */ -extern int start_time; -extern int this_time; -extern int frames; - -/* Data Pack sent to Other CPUs (ex. SPE) */ -extern RenderingData r[2]; - -void -SgChange::run_init() -{ - int width = viewer->width; - int height = viewer->height; - sgroot_A = new SceneGraphRoot(width, height, manager); - sgroot_A->tmanager = viewer->manager; - sgroot_B = new SceneGraphRoot(width, height, manager); - sgroot_B->tmanager = viewer->manager; -} - -HTaskPtr -SgChange::initLoop() -{ - return viewer->initLoop(); -} - -void -SgChange::mainLoop() -{ - HTaskPtr task_next = initLoop(); - - task_next->set_post(&post2run, (void *)this, 0); - task_next->spawn(); -} - - - -static void -post2run(SchedTask *s, void *sgchange_, void *arg) -{ - SgChange *sgchange = (SgChange*)sgchange_; - HTaskPtr task_next = sgchange->manager->create_task(Dummy); - sgchange->run_loop(task_next); - psx_sync_n(); -} - -static void -post2runLoop(SchedTask *s, void *sgchange_, void *arg) -{ - SgChange *sgchange = (SgChange*)sgchange_; - HTaskPtr task_next = sgchange->manager->create_task(Dummy); - sgchange->viewer->light_xyz_stock = sgchange->sgroot_A->getLightVector(); - sgchange->pass_draw_tree(); - sgchange->run_loop(task_next); - - psx_sync_n(); -} - - -void -SgChange::pass_draw_tree() -{ - sgroot_B->sg_draw_tree = sgroot_A->sg_exec_tree; -} - -void -SgChange::run_loop(HTaskPtr task_next) -{ - viewer->dev->clear_screen(); - - bool quit_flg; - quit_flg = viewer->quit_check(); - if (quit_flg == true) { - // this_time = viewer->get_ticks(); - viewer->run_finish(); - return; - } - - viewer->dev->clean_pixels(); - - for (int i = 1; i <= r[spi].spackList_length; i++) { - r[spi].spackList[i-1].reinit(i*split_screen_h); - } - - sgroot_A->updateControllerState(); - - HTaskPtr loop_task = manager->create_task(Dummy); - loop_task->set_post(post2runLoop, (void *)this, 0); - - HTaskPtr draw_task = manager->create_task(Dummy); - draw_task->set_post(post2rendering, (void *)this, 0); - - /* - application 側で sgroot に task を生成登録する - 引数を渡したりは後でやる。 - 登録された関数を実行して task を生成登録する。 - */ - sgroot_A->regist_execute(); - - //HTaskPtr move_task = manager->create_task(RunMove); - HTaskPtr move_task = manager->create_task(ExecMove); - move_task->set_param(0, (memaddr)this); - move_task->set_param(1, viewer->width); - move_task->set_param(2, viewer->height); - - /* - TTaskPtr move_finish = manager->create_task(Dummy); - loop_task->wait_for(move_finish); - move_finish は app の move_task の post_func で実行させてやる - */ - - /* - 描画終了確認用のダミータスク - 描画の最後で spwan させる - */ - HTaskPtr dummy_task = manager->create_task(Dummy); - - draw_finish = dummy_task; - - loop_task->wait_for(draw_finish); - // move_task に wait_for ではなく sgroot_A->move_exec_task に wait_for するべき - // どこかで move_exec_task->spawn() しないとな - loop_task->wait_for(sgroot_A->move_exec_task); - - //loop_task->wait_for(move_task); - - - draw_task->spawn(); - // この時点で app の task_id を知っていないとダメか - move_task->spawn(); - loop_task->spawn(); -} - -static void -post2rendering(SchedTask *s, void *sgchange_, void *arg) -{ - SgChange *sgchange = (SgChange *)sgchange_; - HTaskPtr task_next = sgchange->manager->create_task(Dummy); - sgchange->rendering(task_next); - -} - -void -SgChange::rendering(HTaskPtr task_next) -{ - viewer->rendering_pp(task_next, sgroot_B); - viewer->rendering_sp(task_next, sgroot_B); - - task_next->set_post(post2runDraw, (void*)this, 0); - task_next->spawn(); -} - - -static void -post2runDraw(SchedTask *s, void *sgchange_, void *arg) -{ - SgChange *sgchange = (SgChange *)sgchange_; - HTaskPtr task_next = sgchange->manager->create_task(Dummy); - sgchange->run_draw(task_next); -} - -void -SgChange::run_draw(HTaskPtr task_next) // 引数に post2runLoop を入れるようにする -{ - viewer->common_draw(task_next); - - this->draw_finish->wait_for(task_next); - task_next->spawn(); - this->draw_finish->spawn(); - - frames++; -} - -/* end */
--- a/Renderer/Engine/SgChange.h Wed Feb 15 16:52:00 2012 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -#ifndef INCLUDED_SG_CHANGE -#define INCLUDED_SG_CHANGE - -#include <SDL.h> - -#include "viewer_types.h" -#include "TaskManager.h" -#include "KeyStat.h" -#include "MainLoop.h" -#include "Application.h" -#include "SceneGraphRoot.h" -#include "viewer.h" - -class SceneGraphRoot; -class Application; - -class SgChange : public MainLoop { - -public: - - Viewer *viewer; - TaskManager *manager; - - SgChange(Viewer *v) { - viewer = v; - manager = v->manager; - } - - virtual ~SgChange() {} - - - SceneGraphRoot *sgroot_A; - SceneGraphRoot *sgroot_B; - - HTaskPtr draw_finish; - - void run_init(); - void run_loop(HTaskPtr task_next); - void run_move(HTaskPtr task_next); - void run_draw(HTaskPtr task_next); - void rendering(HTaskPtr task_next); - HTaskPtr initLoop(); - - void pass_draw_tree(); - void mainLoop(); - - void createFromXMLfile(const char *file) - { - sgroot_A->createFromXMLfile(manager, file); - } - - SceneGraph * createSceneGraph(int id) - { - return sgroot_A->createSceneGraph(id); - } - - SceneGraph * createSceneGraph(const char *id) - { - return sgroot_A->createSceneGraph(id); - } - - int getSgid(const char *id) - { - return sgroot_A->getSgid(id); - } - - SceneGraph * createSceneGraph() - { - return sgroot_A->createSceneGraph(); - } - - void setSceneData(SceneGraph *g) - { - sgroot_A->setSceneData(g); - } - - int getLast() - { - return sgroot_A->getLast(); - } -}; - -#endif -
--- a/Renderer/Engine/spe/DrawBack.cc Wed Feb 15 16:52:00 2012 +0900 +++ b/Renderer/Engine/spe/DrawBack.cc Wed Feb 15 17:45:24 2012 +0900 @@ -1,6 +1,3 @@ -// #define DEBUG -#include "error.h" - #include <stdlib.h> #include <string.h> #include "DrawBack.h" @@ -19,7 +16,6 @@ static int run(SchedTask *smanager, void *rbuf, void *wbuf) { - __debug_spe("DrawBack\n"); int rgb = (long)smanager->get_param(0); int rangex_start = (long)smanager->get_param(1); int rangex_end = (long)smanager->get_param(2);
--- a/Renderer/Engine/spe/DrawSpan.cc Wed Feb 15 16:52:00 2012 +0900 +++ b/Renderer/Engine/spe/DrawSpan.cc Wed Feb 15 17:45:24 2012 +0900 @@ -1,7 +1,7 @@ #include <stdlib.h> #include <string.h> +#include "DrawSpan.h" #include "polygon_pack.h" -#include "DrawSpan.h" #include "task_texture.h" #include "viewer_types.h" #include "Func.h" @@ -9,8 +9,11 @@ #include "SchedTask.h" #include "Tapestry.h" #include "SpanPack.h" +#include "matrix_calc.h" +#include <math.h> +#ifdef __SPU__ #include <spu_intrinsics.h> -#include <math.h> +#endif /* __SPU__ */ #if (__LITTLE_ENDIAN__) #define LITTLEENDIAN 1 @@ -18,7 +21,7 @@ #define LITTLEENDIAN 0 #endif -SchedDefineTask(DrawSpan); +SchedDefineTask1(DrawSpan, drawSpan); #define TEX_LOAD1 0 #define TEX_LOAD2 1 @@ -32,6 +35,21 @@ int doneWrite; } G, *Gptr; +/*double buffering するために、保持すべき状態*/ +typedef struct DrawParam { + + float tex_z; + int localx; + int tex_localx; + int tex_localy; + TilePtr tile; + float world_z; + int x; + int display; //他のオブジェクトの裏にいて表示するかしないかのflag + +} DrawParam, *DrawParamPtr; + + 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); @@ -52,11 +70,12 @@ 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, - SchedTask *smanager,int x, int y, float z, int world_x, int world_y, float world_z); +static int infinity_light_calc(int color,float normal_x, float normal_y, float normal_z, + SchedTask *smanager, int x, int y, float z, int world_x, int world_y, float world_z, + float diffuse_l, float diffuse_r, int rangex, int j); - +#ifdef __SPU__ static inline void normalize(vector float& v0, vector float& v1) { @@ -70,10 +89,14 @@ ret = spu_rsqrte(ret); v0 = spu_mul(v1,ret); } +#endif /* __SPU__ */ static inline float innerProduct1(vector float& v0, vector float& v1) { +#ifndef __SPU__ + return (v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2]); +#else /* __SPU__ */ vector float ret __attribute__((aligned(16))) = {0,0,0,0}; float inner; @@ -85,11 +108,10 @@ } return inner; +#endif /* __SPU__ */ } - - /** * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する * @@ -213,7 +235,8 @@ static void updateBuffer(Gptr g, float zpos, int rangex, int localx, int localy, int tex_x, int tex_y, float normal_x, float normal_y, float normal_z, TilePtr tile, - int world_x, int world_y, float world_z, SchedTask *smanager) + int world_x, int world_y, float world_z, SchedTask *smanager, + float diffuse_l, float diffuse_r, int j) { uint32 color = get_rgb(tex_x, tex_y, tile); @@ -226,14 +249,14 @@ //完全に透けているか判断 int flag = (alpha != 0); - int *light_sysswitch = (int*)smanager->global_get(LightSysSwitch); //smanager->printf("sys %d\n",light_sysswitch); if ( *light_sysswitch == 1 && flag) { color = infinity_light_calc(color,normal_x,normal_y,normal_z, smanager,localx,localy,zpos, - world_x,world_y,world_z); + world_x,world_y,world_z, + diffuse_l, diffuse_r, rangex, j); } g->zRow[localx + (rangex*localy)] = zpos*flag + g->zRow[localx + (rangex*localy)]*(1-flag); @@ -281,7 +304,7 @@ int tex_localy; memaddr tex_addr; - if (span->x < startx || endx < span->x) { + if (span->x < startx || endx < span->x || ! span->tex_addr) { return -1; } @@ -297,24 +320,18 @@ tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL; TilePtr tile = smanager->get_segment(tex_addr,g->tileList); - smanager->wait_segment(tile); + smanager->wait_segment(tile); updateBuffer(g, zpos, rangex, localx, localy, tex_localx, tex_localy, normal_x,normal_y,normal_z,tile, - span->x, span->y, zpos, smanager); + span->x, span->y, zpos, smanager, + span->diffuse_l, span->diffuse_r, 0); } 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 の描画 @@ -336,6 +353,60 @@ static int drawLine1(SchedTask *smanager, Gptr g, SpanPtr span, int startx, int endx, int wait_tag) { +#ifndef __SPU__ + + +#ifdef PIPE_TILE + + int cur = 0; + DrawParam param[2]; + + int rangex = endx - startx + 1; + + int js = (span->x < startx) ? startx - span->x : 0; + int je = (span->x + span->length_x > endx) ? endx - span->x : span->length_x; + + int localy = getLocalY(span->y-1); + + int ret = je+1; + int index = 1; + + + getDrawParam(smanager, g, span, localy, startx, endx, index, je, ¶m[cur]); + + //for (int j = je; j >= js; j--) { <-もとはこうで、一度先にtextureをloadしておくから、je-1にしてる + for (int j = je-1; j >= js; j--) { + + index += 1; + + getDrawParam(smanager, g, span, localy, startx, endx, index, j, ¶m[cur^1]); //次のループで使用するtexture + + if (param[cur].display) { + smanager->wait_segment(param[cur].tile); // 前でload命令を出しておいたtextureを待つ。 + + updateBuffer(g, param[cur].tex_z, rangex, param[cur].localx, localy, + param[cur].tex_localx, param[cur].tex_localy, + span->normal_x, span->normal_y, span->normal_z, param[cur].tile, + param[cur].x, span->y, param[cur].world_z, smanager); + } + + cur ^= 1; + + } +/* + if (param[cur].display) { + smanager->wait_segment(param[cur].tile); + + updateBuffer(g, param[cur].tex_z, rangex, param[cur].localx, localy, + param[cur].tex_localx, param[cur].tex_localy, + span->normal_x, span->normal_y, span->normal_z, param[cur].tile, + param[cur].x, span->y, param[cur].world_z, smanager); + + } +*/ + + +#endif /* ! __SPU__ */ int x = span->x; int rangex = endx - startx + 1; int x_len = span->length_x; @@ -344,12 +415,12 @@ float normal_y = span->normal_y; float normal_z = span->normal_z; + // startx は DrawSpanTask の描画担当範囲の左端のx座標 + // xは span の左端のx座標 int js = (x < startx) ? startx - x : 0; int je = (x + x_len > endx) ? endx - x : x_len; - /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */ - int tex_xpos, tex_ypos; // span の始点に対応する座標 (tex1, tey1) float tex1 = span->tex_x1; @@ -374,24 +445,48 @@ //for (int j = js; j <= je; j++) { for (int j = je; j >= js; j--) { + float tex_x, tex_y, tex_z; world_z -= z_inclination; - +#ifndef __SPU__ localx = getLocalX(x-1+j); + tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1); +#endif /* ! __SPU__ */ +#ifndef __SPU__ + if (tex_z < g->zRow[localx + (rangex*localy)]) { +#else /* __SPU__ */ + localx = getLocalX(x-1+j); +#endif /* __SPU__ */ + +#ifndef __SPU__ + float tex_x, tex_y; +#else /* __SPU__ */ tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1); +#endif /* __SPU__ */ - 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); - 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); + 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); +#ifndef __SPU__ + +#endif /* ! __SPU__ */ + 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; +#ifndef __SPU__ + /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */ + int tex_xpos, tex_ypos; + +#endif /* ! __SPU__ */ + tex_xpos = (int)((span->tex_width-1) * tex_x); + tex_ypos = (int)((span->tex_height-1) * tex_y); + +#ifdef __SPU__ if (tex_z < g->zRow[localx + (rangex*localy)]) { +#endif /* __SPU__ */ // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と // そのブロックのアドレス(MainMemory) memaddr tex_addr; @@ -410,22 +505,31 @@ updateBuffer(g, tex_z, rangex, localx, localy, tex_localx, tex_localy, normal_x, normal_y, normal_z, tile, - span->x+j, span->y, world_z, smanager); + span->x+j, span->y, world_z, smanager, + span->diffuse_l, span->diffuse_r, j); } } - return ret; } static int infinity_light_calc(int color,float normal_x, float normal_y, float normal_z, SchedTask *smanager, int x, int y, float z, - int world_x, int world_y, float world_z) - + int world_x, int world_y, float world_z, + float diffuse_l, float diffuse_r, int rangex, int j) { + unsigned char rgb[4]; +#ifndef __SPU__ + int light_rgb; + float normal_vector[4] = {normal_x,normal_y,normal_z,0}; + float light_vector[4]; + float *light_xyz = (float*)smanager->global_get(Light); +#endif /* ! __SPU__ */ - unsigned char rgb[4]; +#ifndef __SPU__ + normalize(normal_vector, normal_vector); +#endif /* __SPU__ */ // 引数で受け取った color の rgb 情報の抜き出し #if LITTLEENDIAN @@ -440,9 +544,21 @@ rgb[0] = (color & 0x000000ff); #endif +#ifndef __SPU__ + int tmp_rgb[3] = {0,0,0}; + int light_num = 4; + float inner_product = 0; +#endif /* ! __SPU__ */ +#ifndef __SPU__ + int *light_switch = (int*)smanager->global_get(LightSwitch); +#else /* __SPU__ */ vector float *light_xyz = (vector float*)smanager->global_get(Light); +#endif /* __SPU__ */ +#ifndef __SPU__ + for (int i = 0; i < light_num; i++) { +#else /* __SPU__ */ vector float v_rgb __attribute__((aligned(16))) = {(float)rgb[0],(float)rgb[1],(float)rgb[2],0}; vector float normal_vector __attribute__((aligned(16))) = {normal_x,normal_y,normal_z,0}; vector float light_vector __attribute__((aligned(16))) = {0,0,0,0}; @@ -451,43 +567,93 @@ {world_x, world_y, -world_z, 0}, {world_x, world_y, -world_z, 0}, {world_x, world_y, -world_z, 0}}; +#endif /* __SPU__ */ - +#ifndef __SPU__ + // 光源のスイッチが入ってたら + if (light_switch[i] == 1) { +#endif /* ! __SPU__ */ + +#ifndef __SPU__ + light_vector[0] = 0; + light_vector[1] = 0; + light_vector[2] = -1; + light_vector[3] = 0; +#else /* __SPU__ */ int light_rgb; float inner_product = 0.2; +#endif /* __SPU__ */ +#ifndef __SPU__ + normalize(light_vector, light_vector); +#else /* __SPU__ */ normalize(normal_vector, normal_vector); vector float vtmp_rgb __attribute__((aligned(16))) = {0,0,0,0}; int light_num = 4; int *light_switch = (int*)smanager->global_get(LightSwitch); - +#endif /* __SPU__ */ + +#ifndef __SPU__ + float tmp_inner_product = 0; +#else /* __SPU__ */ for (int i = 0; i < light_num; i++) { - +#endif /* __SPU__ */ + +#ifndef __SPU__ + // 法線ベクトルと光源ベクトルとの内積をとる + inner_product = innerProduct1(normal_vector,light_vector); +#else /* __SPU__ */ if (light_switch[i] == 1) { light_vector = spu_sub(v_world[i],light_xyz[i]); normalize(light_vector, light_vector); float tmp_inner_product = innerProduct1(normal_vector,light_vector); +#endif /* __SPU__ */ + + // 内積がマイナスの場合は色がない。 + if (inner_product < tmp_inner_product) { + inner_product = tmp_inner_product; + } + +#ifndef __SPU__ + // 内積を rgb にかけていく + + tmp_rgb[0] = (unsigned char)(rgb[0]*inner_product); + tmp_rgb[1] = (unsigned char)(rgb[1]*inner_product); + tmp_rgb[2] = (unsigned char)(rgb[2]*inner_product); - if (inner_product < tmp_inner_product) { - inner_product = tmp_inner_product; - } - +#else /* __SPU__ */ v_inner = spu_splats(inner_product); vtmp_rgb = spu_madd(v_rgb,v_inner,vtmp_rgb); +#endif /* __SPU__ */ } - } +#ifndef __SPU__ + //float diffuse = ( diffuse_r - diffuse_l ) / rangex * j + diffuse_l; + //tmp_rgb[0] = (unsigned char)(rgb[0]*diffuse); + //tmp_rgb[1] = (unsigned char)(rgb[1]*diffuse); + //tmp_rgb[2] = (unsigned char)(rgb[2]*diffuse); +#else /* __SPU__ */ vector unsigned int v_flag __attribute__((aligned(16))); vector float max_rgb __attribute__((aligned(16))) = (vector float)spu_splats((float)255.0f); +#endif /* __SPU__ */ + vector unsigned int last_rgb __attribute__((aligned(16))); +#ifndef __SPU__ + int rgb_flag[3]; + for (int i = 0; i < 3; i++) { + rgb_flag[i] = (tmp_rgb[i] > 255); + } + last_rgb[0] = tmp_rgb[0]*(1 - rgb_flag[0]) + 255*(rgb_flag[0]); + last_rgb[1] = tmp_rgb[1]*(1 - rgb_flag[1]) + 255*(rgb_flag[1]); + last_rgb[2] = tmp_rgb[2]*(1 - rgb_flag[2]) + 255*(rgb_flag[2]); +#else /* __SPU__ */ v_flag = spu_cmpgt(max_rgb,vtmp_rgb); vtmp_rgb = spu_sel(max_rgb,vtmp_rgb,v_flag); - - vector unsigned int last_rgb __attribute__((aligned(16))); last_rgb = spu_convtu(vtmp_rgb,0); +#endif /* __SPU__ */ //計算した rgb を light_rgb にまとめる。 @@ -502,10 +668,11 @@ static int -run(SchedTask *smanager, void *rbuf, void *wbuf) +drawSpan(SchedTask *smanager, void *rbuf, void *wbuf) { - if ((int)smanager->get_param(5) == 0) { + //get_param(5) is spack->info.size + if ((long)smanager->get_param(5) == 0) { int rangex_start = (long)smanager->get_param(2); int rangex_end = (long)smanager->get_param(3); @@ -575,13 +742,13 @@ span = &spack->span[t]; if (span->length_x != 1) { - drawLine1( - smanager, g, - span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]); + drawLine1( + smanager, g, + span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]); } else { - drawDot1( - smanager, g, - span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]); + drawDot1( + smanager, g, + span, rangex_start, rangex_end, tl_tag[tl_tag_flg1]); } next_span = span;
--- a/Renderer/Engine/spe/InitKey.cc Wed Feb 15 16:52:00 2012 +0900 +++ b/Renderer/Engine/spe/InitKey.cc Wed Feb 15 17:45:24 2012 +0900 @@ -3,7 +3,6 @@ #include "InitKey.h" #include "Func.h" #include "KeyStat.h" -#include "SchedTask.h" SchedDefineTask(InitKey); @@ -11,7 +10,7 @@ run(SchedTask *smanager, void *rbuf , void *wbuf) { - /*void *key = */ smanager->global_alloc(KEY_STATUS, sizeof(key_stat)); + smanager->global_alloc(KEY_STATUS, sizeof(key_stat)); return 0; }
--- a/Renderer/Engine/task/DrawSpan.cc Wed Feb 15 16:52:00 2012 +0900 +++ b/Renderer/Engine/task/DrawSpan.cc Wed Feb 15 17:45:24 2012 +0900 @@ -5,10 +5,15 @@ #include "task_texture.h" #include "viewer_types.h" #include "Func.h" +#include "matrix_calc.h" #include "SchedTask.h" #include "Tapestry.h" #include "SpanPack.h" #include "matrix_calc.h" +#include <math.h> +#ifdef __SPU__ +#include <spu_intrinsics.h> +#endif /* __SPU__ */ #if (__LITTLE_ENDIAN__) #define LITTLEENDIAN 1 @@ -65,20 +70,45 @@ 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 getDrawParam(SchedTask *smanager, Gptr g, SpanPtr span, int localy, int startx, int endx, int index, int j, DrawParamPtr param); - -static int infinity_light_calc(int color,float normal_x, float normal_y, - float normal_z, SchedTask *smanager, int x, int y, float z, - int world_x, int world_y, float world_z, +static int infinity_light_calc(int color,float normal_x, float normal_y, float normal_z, + SchedTask *smanager, int x, int y, float z, int world_x, int world_y, float world_z, float diffuse_l, float diffuse_r, int rangex, int j); +#ifdef __SPU__ +static inline void +normalize(vector float& v0, vector float& v1) +{ + float norm; + vector float ret __attribute__((aligned(16))) = {0,0,0,0}; + ret = spu_mul(v0,v1); + norm = (ret[0] + ret[1] + ret[2]); + + ret = (vector float)spu_splats(norm); + ret = spu_rsqrte(ret); + v0 = spu_mul(v1,ret); +} +#endif /* __SPU__ */ -static float -innerProduct1(float *v0, float *v1) +static inline float +innerProduct1(vector float& v0, vector float& v1) { +#ifndef __SPU__ return (v0[0]*v1[0] + v0[1]*v1[1] + v0[2]*v1[2]); +#else /* __SPU__ */ + + vector float ret __attribute__((aligned(16))) = {0,0,0,0}; + float inner; + ret = spu_mul(v0,v1); + + inner = (ret[0] + ret[1] + ret[2]); + if (inner < 0) { + inner = 0; + } + + return inner; +#endif /* __SPU__ */ } @@ -209,7 +239,7 @@ float diffuse_l, float diffuse_r, int j) { - int color = get_rgb(tex_x, tex_y, tile); + uint32 color = get_rgb(tex_x, tex_y, tile); /*下位4bitを抽出*/ #if LITTLEENDIAN int alpha = color & 0x000000ff; @@ -217,7 +247,6 @@ int alpha = color & 0xff000000; #endif - //完全に透けているか判断 int flag = (alpha != 0); int *light_sysswitch = (int*)smanager->global_get(LightSysSwitch); @@ -234,7 +263,6 @@ int *point = &g->linebuf[localy][localx]; *point = color*flag + *point *(1-flag); - } /** @@ -284,6 +312,7 @@ tex_ypos = (int)((span->tex_height-1) * tey); if (zpos < g->zRow[localx + (rangex*localy)]) { + if (!span->tex_addr) return -1; // broken case, I'd like to write some thing... tex_addr = getTile(tex_xpos, tex_ypos, span->tex_width, (memaddr)span->tex_addr); @@ -303,13 +332,6 @@ 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 の描画 @@ -331,6 +353,7 @@ static int drawLine1(SchedTask *smanager, Gptr g, SpanPtr span, int startx, int endx, int wait_tag) { +#ifndef __SPU__ #ifdef PIPE_TILE @@ -383,9 +406,7 @@ */ -#else - - +#endif /* ! __SPU__ */ int x = span->x; int rangex = endx - startx + 1; int x_len = span->length_x; @@ -400,6 +421,7 @@ int js = (x < startx) ? startx - x : 0; int je = (x + x_len > endx) ? endx - x : x_len; + // span の始点に対応する座標 (tex1, tey1) float tex1 = span->tex_x1; float tey1 = span->tex_y1; @@ -424,30 +446,47 @@ //for (int j = js; j <= je; j++) { for (int j = je; j >= js; j--) { - float tex_z; + float tex_x, tex_y, tex_z; world_z -= z_inclination; +#ifndef __SPU__ localx = getLocalX(x-1+j); tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1); +#endif /* ! __SPU__ */ +#ifndef __SPU__ if (tex_z < g->zRow[localx + (rangex*localy)]) { +#else /* __SPU__ */ + localx = getLocalX(x-1+j); +#endif /* __SPU__ */ +#ifndef __SPU__ float tex_x, tex_y; +#else /* __SPU__ */ + tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1); +#endif /* __SPU__ */ 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); +#ifndef __SPU__ +#endif /* ! __SPU__ */ 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; +#ifndef __SPU__ /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */ int tex_xpos, tex_ypos; +#endif /* ! __SPU__ */ tex_xpos = (int)((span->tex_width-1) * tex_x); tex_ypos = (int)((span->tex_height-1) * tex_y); +#ifdef __SPU__ + if (tex_z < g->zRow[localx + (rangex*localy)]) { +#endif /* __SPU__ */ // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と // そのブロックのアドレス(MainMemory) memaddr tex_addr; @@ -470,97 +509,27 @@ span->diffuse_l, span->diffuse_r, j); } } - - - -#endif - return ret; } -#if 0 -static int -getDrawParam(SchedTask *smanager, Gptr g, SpanPtr span, int localy, int startx, int endx, int index, int j, DrawParamPtr param) { - - int x = span->x; - int rangex = endx - startx + 1; - int x_len = span->length_x; - - /* span->x に対応する Texture の座標 (tex_xpos, tex_ypos) */ - int tex_xpos, tex_ypos; - - // span の始点に対応する座標 (tex1, tey1) - float tex1 = span->tex_x1; - float tey1 = span->tex_y1; - - // span の終点に対応する座標 (tex2, tey2) - float tex2 = span->tex_x2; - float tey2 = span->tex_y2; - - // span の始点、終点に対応する z 座標 - float zpos1 = span->start_z; - float zpos2 = span->end_z; - - //spanを右から左に見ていくうちに、zが下がるのか、上がっていくのか。 - float z_inclination = (zpos1 - zpos2) / x_len; - param->world_z = zpos2 + (z_inclination*index); - param->x = x + j; - param->tex_z = zpos1*(x_len-1-j)/(x_len-1) + zpos2*j/(x_len-1); - param->localx = getLocalX(x-1+j); - - - if (param->tex_z < g->zRow[param->localx + (rangex*localy)]) { - - float tex_x, tex_y; - - 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); - 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); - - // (tex_xpos, tex_ypos) の、Tile 内(上の図参照)での座標と - // そのブロックのアドレス(MainMemory) - memaddr tex_addr; - - if (!span->tex_addr) return -1; // broken case, I'd like to write some thing... - tex_addr = getTile(tex_xpos, tex_ypos, - span->tex_width, (memaddr)span->tex_addr); - - param->tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL; - param->tex_localy = tex_xpos % TEXTURE_SPLIT_PIXEL; - - param->tile = smanager->get_segment(tex_addr, g->tileList); - - param->display = 1; // z軸の一番まえだから表示されるよ - - return 1; // - } - - param->display = 0; //z軸の前に他のオブジェクトがあるので、計算しなくていい。 - - return 1; - -} -#endif static int infinity_light_calc(int color,float normal_x, float normal_y, float normal_z, SchedTask *smanager, int x, int y, float z, int world_x, int world_y, float world_z, float diffuse_l, float diffuse_r, int rangex, int j) - { unsigned char rgb[4]; +#ifndef __SPU__ int light_rgb; float normal_vector[4] = {normal_x,normal_y,normal_z,0}; float light_vector[4]; float *light_xyz = (float*)smanager->global_get(Light); +#endif /* ! __SPU__ */ +#ifndef __SPU__ normalize(normal_vector, normal_vector); +#endif /* __SPU__ */ // 引数で受け取った color の rgb 情報の抜き出し #if LITTLEENDIAN @@ -575,67 +544,126 @@ rgb[0] = (color & 0x000000ff); #endif +#ifndef __SPU__ int tmp_rgb[3] = {0,0,0}; int light_num = 4; float inner_product = 0; +#endif /* ! __SPU__ */ +#ifndef __SPU__ int *light_switch = (int*)smanager->global_get(LightSwitch); +#else /* __SPU__ */ + vector float *light_xyz = (vector float*)smanager->global_get(Light); +#endif /* __SPU__ */ +#ifndef __SPU__ for (int i = 0; i < light_num; i++) { +#else /* __SPU__ */ + vector float v_rgb __attribute__((aligned(16))) = {(float)rgb[0],(float)rgb[1],(float)rgb[2],0}; + vector float normal_vector __attribute__((aligned(16))) = {normal_x,normal_y,normal_z,0}; + vector float light_vector __attribute__((aligned(16))) = {0,0,0,0}; + vector float v_inner __attribute__((aligned(16))); + vector float v_world[4] __attribute__((aligned(16))) = {{world_x, world_y, -world_z, 0}, + {world_x, world_y, -world_z, 0}, + {world_x, world_y, -world_z, 0}, + {world_x, world_y, -world_z, 0}}; +#endif /* __SPU__ */ +#ifndef __SPU__ // 光源のスイッチが入ってたら if (light_switch[i] == 1) { +#endif /* ! __SPU__ */ +#ifndef __SPU__ light_vector[0] = 0; light_vector[1] = 0; light_vector[2] = -1; light_vector[3] = 0; +#else /* __SPU__ */ + int light_rgb; + float inner_product = 0.2; +#endif /* __SPU__ */ +#ifndef __SPU__ normalize(light_vector, light_vector); +#else /* __SPU__ */ + normalize(normal_vector, normal_vector); + + vector float vtmp_rgb __attribute__((aligned(16))) = {0,0,0,0}; + + int light_num = 4; + int *light_switch = (int*)smanager->global_get(LightSwitch); +#endif /* __SPU__ */ +#ifndef __SPU__ float tmp_inner_product = 0; +#else /* __SPU__ */ + for (int i = 0; i < light_num; i++) { +#endif /* __SPU__ */ +#ifndef __SPU__ // 法線ベクトルと光源ベクトルとの内積をとる inner_product = innerProduct1(normal_vector,light_vector); +#else /* __SPU__ */ + if (light_switch[i] == 1) { + light_vector = spu_sub(v_world[i],light_xyz[i]); + normalize(light_vector, light_vector); + float tmp_inner_product = innerProduct1(normal_vector,light_vector); +#endif /* __SPU__ */ // 内積がマイナスの場合は色がない。 if (inner_product < tmp_inner_product) { inner_product = tmp_inner_product; } +#ifndef __SPU__ // 内積を rgb にかけていく tmp_rgb[0] = (unsigned char)(rgb[0]*inner_product); tmp_rgb[1] = (unsigned char)(rgb[1]*inner_product); tmp_rgb[2] = (unsigned char)(rgb[2]*inner_product); +#else /* __SPU__ */ + v_inner = spu_splats(inner_product); + vtmp_rgb = spu_madd(v_rgb,v_inner,vtmp_rgb); +#endif /* __SPU__ */ } } +#ifndef __SPU__ //float diffuse = ( diffuse_r - diffuse_l ) / rangex * j + diffuse_l; //tmp_rgb[0] = (unsigned char)(rgb[0]*diffuse); //tmp_rgb[1] = (unsigned char)(rgb[1]*diffuse); //tmp_rgb[2] = (unsigned char)(rgb[2]*diffuse); +#else /* __SPU__ */ + vector unsigned int v_flag __attribute__((aligned(16))); + vector float max_rgb __attribute__((aligned(16))) = (vector float)spu_splats((float)255.0f); +#endif /* __SPU__ */ + vector unsigned int last_rgb __attribute__((aligned(16))); +#ifndef __SPU__ int rgb_flag[3]; for (int i = 0; i < 3; i++) { rgb_flag[i] = (tmp_rgb[i] > 255); } - - rgb[0] = tmp_rgb[0]*(1 - rgb_flag[0]) + 255*(rgb_flag[0]); - rgb[1] = tmp_rgb[1]*(1 - rgb_flag[1]) + 255*(rgb_flag[1]); - rgb[2] = tmp_rgb[2]*(1 - rgb_flag[2]) + 255*(rgb_flag[2]); + last_rgb[0] = tmp_rgb[0]*(1 - rgb_flag[0]) + 255*(rgb_flag[0]); + last_rgb[1] = tmp_rgb[1]*(1 - rgb_flag[1]) + 255*(rgb_flag[1]); + last_rgb[2] = tmp_rgb[2]*(1 - rgb_flag[2]) + 255*(rgb_flag[2]); +#else /* __SPU__ */ + v_flag = spu_cmpgt(max_rgb,vtmp_rgb); + vtmp_rgb = spu_sel(max_rgb,vtmp_rgb,v_flag); + last_rgb = spu_convtu(vtmp_rgb,0); +#endif /* __SPU__ */ //計算した rgb を light_rgb にまとめる。 #if LITTLEENDIAN - light_rgb = (rgb[0] << 24) + (rgb[1] << 16) + (rgb[2] << 8) + (rgb[3]); + light_rgb = (last_rgb[0] << 24) + (last_rgb[1] << 16) + (last_rgb[2] << 8) + (last_rgb[3]); #else - light_rgb = (rgb[3] << 24) + (rgb[2] << 16) + (rgb[1] << 8) + (rgb[0]); + light_rgb = (last_rgb[3] << 24) + (last_rgb[2] << 16) + (last_rgb[1] << 8) + (last_rgb[0]); #endif return light_rgb; - } @@ -663,7 +691,6 @@ } - G g0; Gptr g = &g0;
--- a/Renderer/Engine/task/ExecMove.cc Wed Feb 15 16:52:00 2012 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include "ExecMove.h" -#include "SgChange.h" -#include "SceneGraphRoot.h" - -SchedDefineTask(ExecMove); - -static int -run(SchedTask *smanager, void *rbuf , void *wbuf) -{ - SgChange *sgchange = (SgChange *)smanager->get_param(0); - //SceneGraphRoot *sgroot = (SceneGraphRoot *)smanager->get_param(0); - SceneGraphRoot *sgroot = sgchange->sgroot_A; - long screen_w = (long)smanager->get_param(1); - long screen_h = (long)smanager->get_param(2); - - //sgroot->updateControllerState(); - - SceneGraphPtr list = sgroot->sg_available_list; - sgroot->allRemove(sgroot->sg_remove_list); - - sgroot->sg_draw_tree = sgroot->sg_exec_tree; - sgroot->sg_remove_list = sgroot->sg_available_list; - - sgroot->sg_exec_tree = NULL; - sgroot->sg_available_list = NULL; - - sgroot->camera->move_execute(screen_w, screen_h); - sgroot->camera->update(screen_w, screen_h); - - sgroot->camera->children = NULL; - sgroot->camera->lastChild = NULL; - - list->move_execute(screen_w, screen_h); - - sgroot->list = list; - - return 0; -}
--- a/Renderer/Engine/task/ExecMove.h Wed Feb 15 16:52:00 2012 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -#ifndef INCLUDED_EXEC_MOVE -#define INCLUDED_EXEC_MOVE - -#include "SceneGraphRoot.h" -#include "SchedTask.h" - -#endif
--- a/Renderer/Engine/task/SendKey.cc Wed Feb 15 16:52:00 2012 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -#include "SendKey.h" -#include "TaskManager.h" - -SchedDefineTask(SendKey); - -static int -run(SchedTask *s,void *rbuf, void *wbuf) -{ - - - return 0; -}
--- a/Renderer/Engine/task/SendKey.h Wed Feb 15 16:52:00 2012 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -#ifndef INCLUDED_TASK_SEND_KEY -#define INCLUDED_TASK_SEND_KEY - -#include "SchedTask.h" - - -#endif
--- a/Renderer/Engine/task/Switch.cc Wed Feb 15 16:52:00 2012 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include "Switch.h" -#include "viewer_types.h" -#include "SceneGraphRoot.h" - -SchedDefineTask(Switch); - -static int -run(SchedTask *s,void *rbuf, void *wbuf) -{ -// 配列にする -// SceneGraphRootPtr tmp = sgroot; -// sgroot = sgroot_2; -// sgroot_2 = tmp; - - return 0; -}