Mercurial > hg > Members > kono > Cerium
view TaskManager/Test/test_render/viewer.cpp @ 222:5ffee529dc59
fix
author | gongo@localhost.localdomain |
---|---|
date | Tue, 10 Feb 2009 13:09:52 +0900 |
parents | d61fded0729e |
children | 401b55a4a4dd |
line wrap: on
line source
#include <SDL.h> #include "viewer.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" extern void post2runLoop(void *); extern void post2runDraw(void *); /* measure for FPS (Frame Per Second) */ int start_time; int this_time; int frames; SceneGraphRootPtr sgroot; /* Data Pack sent to Other CPUs (ex. SPE) */ SceneGraphPack *sgpack; PolygonPack *ppack; SpanPackPtr spackList; SpanPackPtr *spackList_ptr; int spackList_length; int spackList_length_align; /** * */ Viewer::Viewer(int b, int w, int h, int _num) { bpp = b; width = w; height = h; spe_num = _num; } int Viewer::get_ticks() { int time; time = SDL_GetTicks(); return time; } bool Viewer::quit_check() { 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 Viewer::quit() { SDL_Quit(); } void Viewer::swap_buffers() { SDL_GL_SwapBuffers(); } extern void node_init(void); extern void create_cube_split(int); extern void panel_init(int); extern void universe_init(void); extern void ieshoot_init(void); extern void ball_bound_init(int, int); extern void lcube_init(int, int); extern void direction_init(void); extern void init_position(int, int); extern void vacuum_init(int w, int h); void Viewer::run_init(const char *xml, int sg_number) { HTaskPtr task_next; HTaskPtr task_tex; start_time = get_ticks(); this_time = 0; frames = 0; sgroot = new SceneGraphRoot(this->width, this->height); //sgroot->createFromXMLFile(xml); switch (sg_number) { case 0: case 1: create_cube_split(sg_number); break; case 2: case 3: case 4: panel_init(sg_number); break; case 5: universe_init(); break; case 6: ieshoot_init(); break; case 7: ball_bound_init(this->width, this->height); break; case 8: lcube_init(this->width, this->height); break; case 9: direction_init(); break; case 10: init_position(this->width, this->height); break; case 11: vacuum_init(this->width, this->height); break; default: node_init(); break; } 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); /** * SPU に送る address list は 16 バイト倍数でないといけない。 * spackList_length*sizeof(SpanPack*) が 16 バイト倍数になるような * length_align を求めている。はみ出した部分は使われない * (ex) spackList_length が 13 の場合 * spackList_length_align = 16; * 実際に送るデータは64バイトになるのでOK * 14,15,16 の部分は何も入らない。 */ spackList_length_align = (spackList_length + 3)&(~3); /* 各 SPU が持つ、SpanPack の address list */ 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(TASK_DUMMY); task_next->set_post(&post2runLoop, NULL); #if 0 // 諸事情で、今は SceneGraphPack を作らずに // そのまま SceneGraph でやっています HTaskPtr task_sgp; task_sgp = manager->create_task(TASK_CREATE_SGP); task_sgp->add_param((uint32)scene_graph); task_sgp->add_param((uint32)sgpack); task_next->wait_for(task_sgp); task_sgp->spawn(); #endif for (int i = 0; i < spe_num; i++) { task_tex = manager->create_task(TASK_INIT_TEXTURE); /* ここはもう少しわかりやすい使い方がいいかもしれぬ。こんなもん? */ task_tex->set_cpu((CPU_TYPE)((int)SPE_0 + i)); task_next->wait_for(task_tex); task_tex->spawn(); } task_next->spawn(); } void Viewer::run_loop(void) { HTaskPtr task_create_pp = NULL; HTaskPtr task_create_sp = NULL; 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); } task_next = manager->create_task(TASK_DUMMY); task_next->set_post(post2runDraw, NULL); #if 0 // SceneGraphPack の update HTaskPtr task_update_sgp = NULL; task_update_sgp = manager->create_task(TASK_UPDATE_SGP); task_update_sgp->add_inData(sgpack, sizeof(SceneGraphPack)); task_update_sgp->add_outData(sgpack, sizeof(SceneGraphPack)); task_update_sgp->add_param(width); task_update_sgp->add_param(height); task_next->wait_for(task_update_sgp); task_update_sgp->spawn(); #else sgroot->updateControllerState(); sgroot->allExecute(width, height); //sgroot->checkRemove(); #endif #if 0 // SceneGraphPack(配列) -> PolygonPack task_create_pp = manager->create_task(TASK_CREATE_PP); task_create_pp->add_inData(sgpack, sizeof(SceneGraphPack)); task_create_pp->add_param((uint32)ppack); #else // SceneGraph(木構造) -> PolygonPack task_create_pp = manager->create_task(TASK_CREATE_PP2); task_create_pp->add_param((uint32)sgroot->getDrawSceneGraph()); task_create_pp->add_param((uint32)ppack); #endif 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; task_create_sp = manager->create_task(TASK_CREATE_SPAN); 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_create_sp->add_param(index_start); /** * ex. screen_height が 480, spenum が 6 の場合、各SPEのy担当範囲 * [ 1.. 80] [ 81..160] [161..240] * [241..320] [321..400] [401..480] * * ex. screen_height が 1080, spenum が 5 の場合、 * [ 1..216] [217..432] [433..648] * [649..864] [865..1080] */ task_create_sp->add_param(index_start*split_screen_h + 1); task_create_sp->add_param(index_end*split_screen_h); 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(); task_next->spawn(); } void Viewer::run_draw(void) { HTaskPtr task_next; HTaskPtr task_draw; task_next = manager->create_task(TASK_DUMMY); task_next->set_post(post2runLoop, NULL); 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(TASK_DRAW_SPAN); task_draw->add_inData(spack, sizeof(SpanPack)); task_draw->add_param( (uint32)&pixels[(startx-1) + this->width*(starty-1)]); task_draw->add_param(this->width); } else { #if 0 //break; // Draw Background (現在は塗りつぶし) task_draw = manager->create_task(TASK_DRAW_BACK); task_draw->add_param(0xffffffff); for (int k = 0; k < rangey; k++) { task_draw->add_outData( &pixels[(startx-1)+this->width*(k+starty-1)], (endx - startx + 1)*sizeof(int)); } #else memset(&pixels[(startx-1)+this->width*(starty-1)], 0, (this->width)*sizeof(int)*rangey); //wmemset((wchar_t*)&pixels[(startx-1)+this->width*(starty-1)], //0xFFFFFFFF, (this->width)*sizeof(int)*rangey/sizeof(wchar_t)); break; #endif } task_draw->add_param(startx); task_draw->add_param(endx); task_draw->add_param(rangey); task_draw->set_cpu(SPE_ANY); task_next->wait_for(task_draw); task_draw->spawn(); startx += split_screen_w; endx += split_screen_w; if (endx > this->width) { endx = this->width; } } } task_next->spawn(); frames++; } void Viewer::run_finish(void) { if (this_time != start_time) { printf("%f FPS\n", (((float)frames)/(this_time-start_time))*1000.0); } delete sgroot; quit(); }