Mercurial > hg > Members > kono > Cerium
view TaskManager/Test/test_render/viewer.cpp @ 264:a59868d37093
merge 151 263
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 03 Jun 2009 23:57:38 +0900 |
parents | bbf774c57544 a802b19ab9ae |
children | d949e590da26 |
line wrap: on
line source
#include <SDL.h> #include "viewer.h" #include "viewer_types.h" #include "SceneGraph.h" #include "scene_graph_pack.h" #include "sys.h" #include "Func.h" #include "error.h" #include "TaskManager.h" #include "Keyboard.h" #include "Joystick.h" extern void post2runLoop(void *); extern void post2runDraw(void *); /* measure for FPS (Frame Per Second) */ int start_time; int this_time; int frames; extern SceneGraphPtr scene_graph; extern SceneGraphPtr scene_graph_viewer; /* Data Pack */ SceneGraphPack *sgpack; PolygonPack *ppack; SpanPackPtr spackList; SpanPackPtr *spackList_ptr; int spackList_length; int spackList_length_align; void *__texture; /** * Joystick があればそれを使い、 * 無ければキーボードを返す */ static Pad* create_controller(void) { if (SDL_NumJoysticks()) { SDL_Joystick *joy = SDL_JoystickOpen(0); if (!joy) { fprintf(stderr, "%s: failed to open joystick", __FUNCTION__); return new Keyboard; } else { printf("Use Joystick\n"); return new Joystick(joy); } } else { printf("Use Keyboard\n"); return new Keyboard; } } 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 create_snake_bg(void); void Viewer::run_init(char *xml, int sg_number) { HTaskPtr task_next; HTaskPtr task_init_tex; start_time = get_ticks(); this_time = 0; frames = 0; //scene_graph = SceneGraph::createFromXMLfile(xml); /** * これを実行すると、 * scene_graph にオリジナルの SceneGraph Object のリストが、 * scene_graph_viewer に描画用の SceneGraph が生成される */ //SceneGraph::createFromXMLfile(xml); //polygon->viewer = this; switch (sg_number) { case 0: case 1: create_cube_split(sg_number); break; case 2: create_snake_bg(); break; case 3: node_init(); break; default: node_init(); break; } scene_graph->controller = create_controller(); sgpack = (SceneGraphPack*)manager->malloc(sizeof(SceneGraphPack)); sgpack->init(); ppack = (PolygonPack*)manager->malloc(sizeof(PolygonPack)); spackList_length = (this->height + split_screen_h - 1) / split_screen_h; spackList = (SpanPack*)manager->malloc(sizeof(SpanPack)*spackList_length); // SPU に送る address list は 16 倍数でないといけない。 // spackList_length*sizeof(SpanPack*) が 16 倍数になるような // length_align を求めている。 spackList_length_align = (spackList_length + 3)&(~3); /* 各 SPU が持つ、SpanPack の address list */ spackList_ptr = (SpanPack**)manager->malloc(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 int tex_width = scene_graph->texture_image->w; int tex_height = scene_graph->texture_image->h; int tex_blocksize = tex_width*tex_height*4; __texture = (void*)manager->malloc(tex_blocksize); memcpy(__texture, scene_graph->texture_image->pixels, tex_blocksize); #if 0 uint32 *tex_src = (uint32*)scene_graph->texture_image->pixels; uint32 *tex_dest = (uint32*)manager->malloc(tex_blocksize); int tile_size = TEXTURE_SPLIT_PIXEL*TEXTURE_SPLIT_PIXEL; int tile_num = tex_width*tex_height/tile_size; tile_num = (tile_num + 15)&(~15); void **tex_addrList = (void**)manager->malloc(sizeof(void*)*tile_num); { int t = 0; for (int y = 0; y < tex_height; y += TEXTURE_SPLIT_PIXEL) { for (int x = 0; x < tex_width; x += TEXTURE_SPLIT_PIXEL) { for (int j = 0; j < TEXTURE_SPLIT_PIXEL; j++) { for (int i = 0; i < TEXTURE_SPLIT_PIXEL; i++) { tex_dest[t++] = tex_src[(x+i) + tex_width*(y+j)]; } } } } t = 0; for (int i = 0, t = 0; i < tex_width*tex_height; i += tile_size, t++) { tex_addrList[t] = (void*)&tex_dest[i]; } } for (int i = 0; i < spe_num; i++) { task_init_tex = manager->create_task(TASK_INIT_TEXTURE); task_init_tex->add_inData(tex_addrList, sizeof(void*)*tile_num); task_init_tex->add_param(tile_num); task_init_tex->set_cpu(SPE_ANY); task_next->wait_for(task_init_tex); task_init_tex->spawn(); } #endif 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 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 scene_graph->controller->check(); scene_graph_viewer->all_execute(width, height); #endif #if 0 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 task_create_pp = manager->create_task(TASK_CREATE_PP2); task_create_pp->add_param((uint32)scene_graph_viewer); 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 start_y = spack->info.y_top - split_screen_h + 1; //int end_y = spack->info.y_top; int rangey = (start_y + split_screen_h - 1 > this->height) ? this->height - start_y + 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)); } else { // Draw Background (現在は塗りつぶし) task_draw = manager->create_task(TASK_DRAW_BACK); <<<<<<< local task_draw->add_param(0xffffff); ======= //task_draw->add_param(0x00ffcc55); task_draw->add_param(0); //task_draw->add_param(st_rgb); >>>>>>> other } for (int k = 0; k < rangey; k++) { task_draw->add_outData( &pixels[(startx-1)+this->width*(k+start_y-1)], (endx - startx + 1)*sizeof(int)); } 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); } scene_graph->delete_data(); scene_graph->controller->close(); delete scene_graph; free(__texture); quit(); }