Mercurial > hg > Game > Cerium
view Renderer/Engine/SgChange.cc @ 725:3a97fdd53a8e draft
Light data load fix (general load routine)
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 19 Dec 2009 15:02:43 +0900 |
parents | 6e9e4726113e |
children | 92035a11633d |
line wrap: on
line source
#include <SDL.h> #include "SgChange.h" #include "viewer_types.h" #include "SceneGraph.h" #include "SceneGraphRoot.h" #include "scene_graph_pack.h" #include "sys.h" #include "Func.h" #include "error.h" #include "TaskManager.h" #include <wchar.h> #include "Pad.h" #include "Application.h" #include "lindaapi.h" #include "global_alloc.h" static void post2runLoop(SchedTask *s, void *viewer, void *s1); static void post2runDraw(SchedTask *s, void *viewer, void *s1); static void post2runMove(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 SceneGraphPack *sgpack; extern PolygonPack *ppack; extern SpanPackPtr spackList; extern SpanPackPtr *spackList_ptr; extern int spackList_length; extern int spackList_length_align; SgChange::SgChange(int b, int w, int h, int _num) { bpp = b; width = w; height = h; spe_num = _num; } int SgChange::get_ticks(void) { int time; time = SDL_GetTicks(); return time; } bool SgChange::quit_check(void) { SDL_Event event; while(SDL_PollEvent(&event)) { if (event.type==SDL_QUIT) { return true; } } Uint8 *keys=SDL_GetKeyState(NULL); if (keys[SDLK_q] == SDL_PRESSED) { return true; } return false; } void SgChange::quit(void) { SDL_Quit(); } void SgChange::swap_buffers(void) { SDL_GL_SwapBuffers(); } void SgChange::run_init(TaskManager *manager, Application *app) { this->manager = manager; start_time = get_ticks(); this_time = 0; frames = 0; // ココ! sgroot_A = new SceneGraphRoot(this->width, this->height); sgroot_A->tmanager = manager; sgroot_B = new SceneGraphRoot(this->width, this->height); sgroot_B->tmanager = manager; int size = sizeof(float)*4; light_xyz[0] = 0.0f; light_xyz[1] = 0.0f; light_xyz[2] = 0.0f; light_xyz[3] = 0.0f; HTaskPtr data_load; for(int i = 0; i < spe_num; i++) { data_load = manager->create_task(DataLoad); data_load->set_param(0, (memaddr)size); data_load->set_param(1, (memaddr)LOAD_ID); data_load->set_cpu((CPU_TYPE)((int)SPE_0 + i)); data_load->spawn(); } MainLoop *mainloop = app->init_only_sg(this, this->width, this->height); mainloop->mainLoop(); } HTaskPtr SgChange::initLoop() { HTaskPtr task_next; HTaskPtr task_tex; sgpack = (SceneGraphPack*)manager->allocate(sizeof(SceneGraphPack)); sgpack->init(); ppack = (PolygonPack*)manager->allocate(sizeof(PolygonPack)); spackList_length = (this->height + split_screen_h - 1) / split_screen_h; spackList = (SpanPack*)manager->allocate(sizeof(SpanPack)*spackList_length); spackList_length_align = (spackList_length + 3)&(~3); spackList_ptr = (SpanPack**)manager->allocate(sizeof(SpanPack*)*spackList_length_align); for (int i = 0; i < spackList_length; i++) { spackList_ptr[i] = &spackList[i]; } for (int i = 1; i <= spackList_length; i++) { spackList[i-1].init(i*split_screen_h); } task_next = manager->create_task(Dummy); for (int i = 0; i < spe_num; i++) { task_tex = manager->create_task(LoadTexture); task_tex->set_cpu((CPU_TYPE)((int)SPE_0 + i)); task_next->wait_for(task_tex); task_tex->spawn(); } return task_next; } void SgChange::mainLoop() { HTaskPtr task_next = initLoop(); task_next->set_post(&post2runLoop, (void *)this, 0); // set_post(function(this->run_loop()), NULL) task_next->spawn(); } static void post2runLoop(SchedTask *s, void *viewer_, void *arg) { SgChange *viewer = (SgChange*)viewer_; HTaskPtr task_next = viewer->manager->create_task(Dummy); viewer->run_loop(task_next); psx_sync_n(); } void SgChange::exchange_sgroot() { SceneGraphRoot *tmp; tmp = sgroot_A; sgroot_A = sgroot_B; sgroot_B = tmp; } void SgChange::run_loop(HTaskPtr task_next) { bool quit_flg; quit_flg = quit_check(); if (quit_flg == true) { this_time = get_ticks(); run_finish(); return; } clean_pixels(); for (int i = 1; i <= spackList_length; i++) { spackList[i-1].reinit(i*split_screen_h); } #if 0 exchange_sgroot(); light_xyz_stock = sgroot_A->getLightVector(); //printf("Sgroot = %x\n", sgroot_A); //task_next->set_post(&post2runLoop, (void *)this, 0); //task_next->spawn(); rendering(task_next); #else //exchange_sgroot(); sgroot_A->updateControllerState(); sgroot_A->allExecute(width, height); light_xyz_stock = sgroot_A->getLightVector(); 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); HTaskPtr move_task = manager->create_task(Dummy); move_task->set_post(post2runMove, (void *)this, 0); HTaskPtr dummy_task = manager->create_task(Dummy); this->dummy_task = dummy_task; loop_task->wait_for(dummy_task); loop_task->wait_for(move_task); move_task->spawn(); draw_task->spawn(); loop_task->spawn(); #endif } static void post2runMove(SchedTask *s, void *viewer_, void *arg) { SgChange *viewer = (SgChange *)viewer_; HTaskPtr task_next = viewer->manager->create_task(Dummy); viewer->run_move(task_next); } void SgChange::run_move(HTaskPtr task_next) { //sgroot_A->updateControllerState(); //sgroot_A->allExecute(width, height); } static void post2rendering(SchedTask *s, void *viewer_, void *arg) { SgChange *viewer = (SgChange *)viewer_; HTaskPtr task_next = viewer->manager->create_task(Dummy); viewer->run_draw(task_next); } void SgChange::rendering(HTaskPtr task_next) { common_rendering(task_next); task_next->set_post(post2runDraw, (void*)this, 0); task_next->spawn(); } void SgChange::common_rendering(HTaskPtr task_next) { HTaskPtr task_create_pp = manager->create_task(CreatePolygonFromSceneGraph); //task_create_pp->set_param(0, (memaddr)sgroot_B->getDrawSceneGraph()); task_create_pp->set_param(0, (memaddr)sgroot_A->getDrawSceneGraph()); task_create_pp->set_param(1, (memaddr)ppack); task_next->wait_for(task_create_pp); int range_base = spe_num; int range = (spackList_length + range_base - 1) / range_base; for (int i = 0; i < range_base; i++) { int index_start = range*i; int index_end = (index_start + range >= spackList_length) ? spackList_length : index_start + range; HTaskPtr task_create_sp = manager->create_task(CreateSpan); task_create_sp->set_param(0,index_start); task_create_sp->set_param(1,index_start*split_screen_h + 1); task_create_sp->set_param(2,index_end*split_screen_h); task_create_sp->add_inData(ppack, sizeof(PolygonPack)); task_create_sp->add_inData(spackList_ptr, sizeof(SpanPack*)*spackList_length_align); task_create_sp->add_inData(&spackList[index_start], sizeof(SpanPack)); task_next->wait_for(task_create_sp); task_create_sp->wait_for(task_create_pp); task_create_sp->set_cpu(SPE_ANY); task_create_sp->spawn(); } task_create_pp->spawn(); } static void post2runDraw(SchedTask *s, void *viewer_, void *arg) { SgChange *viewer = (SgChange *)viewer_; HTaskPtr task_next = viewer->manager->create_task(Dummy); viewer->run_draw(task_next); } void SgChange::run_draw(HTaskPtr task_next) // 引数に post2runLoop を入れるようにする { common_draw(task_next); #if 0 task_next->set_post(post2runLoop, (void*)this, 0); // set_post(function(this->run_loop()), NULL) task_next->spawn(); #else this->dummy_task->wait_for(task_next); task_next->spawn(); this->dummy_task->spawn(); #endif frames++; } void SgChange::common_draw(HTaskPtr task_next) { HTaskPtr task_draw; //Light info update HTaskPtr data_update; HTaskPtr data_update_wait; int size = sizeof(float)*4; light_xyz[0] = light_xyz_stock[0]; light_xyz[1] = light_xyz_stock[1]; light_xyz[2] = light_xyz_stock[2]; light_xyz[3] = light_xyz_stock[3]; data_update_wait = manager->create_task(DataUpdate); data_update_wait->add_inData(light_xyz, size); data_update_wait->set_param(0, size); data_update_wait->set_param(1, LOAD_ID); data_update_wait->set_cpu((CPU_TYPE)((int)SPE_0)); for (int i = 1; i < spe_num; i++) { data_update = manager->create_task(DataUpdate); data_update->add_inData(light_xyz, sizeof(float)*size); data_update->set_param(0, size); data_update->set_param(1, LOAD_ID); data_update->set_cpu((CPU_TYPE)((int)SPE_0 + i)); data_update_wait->wait_for(data_update); data_update->spawn(); } data_update_wait->spawn(); ppack->clear(); for (int i = 0; i < spackList_length; i++) { SpanPack *spack = &spackList[i]; int startx = 1; int endx = split_screen_w; int starty = spack->info.y_top - split_screen_h + 1; //int endy = spack->info.y_top; int rangey = (starty + split_screen_h - 1 > this->height) ? this->height - starty + 1 : split_screen_h; while (startx < this->width) { if (spack->info.size > 0) { // Draw SpanPack task_draw = manager->create_task(DrawSpan); task_draw->set_param(0, (memaddr)&pixels[(startx-1) + this->width*(starty-1)]); task_draw->set_param(1,this->width); task_draw->set_param(2,startx); task_draw->set_param(3,endx); task_draw->set_param(4,rangey); task_draw->add_inData(spack, sizeof(SpanPack)); for (int i = 0; i < rangey; i++) { task_draw->add_outData( &pixels[(startx-1) + this->width*(starty-1 + i) ], (endx-startx+1)*sizeof(int)); } } else { // 7.7.3 SL1 Data Cache Range Set to Zero コマンド // を使って、DMAでclearするべき... ということは、 // それもSPEでやる方が良い? memset(&pixels[(startx-1)+this->width*(starty-1)], 0, (this->width)*sizeof(int)*rangey); break; } task_draw->set_cpu(SPE_ANY); task_next->wait_for(task_draw); task_draw->wait_for(data_update_wait); task_draw->spawn(); startx += split_screen_w; endx += split_screen_w; if (endx > this->width) { endx = this->width; } } } } void SgChange::run_finish(void) { if (this_time != start_time) { printf("%f FPS\n", (((float)frames)/(this_time-start_time))*1000.0); } delete sgroot_A; //delete sgroot_B; quit(); } /* end */