Mercurial > hg > Game > Cerium
view old/simple_render/viewer.cpp @ 1032:373576eb10ba draft
merge
author | Yutaka_Kinjyo |
---|---|
date | Tue, 16 Nov 2010 14:59:28 +0900 |
parents | 3bc98f6d31ff |
children |
line wrap: on
line source
#include <iostream> #include <SDL.h> #include "polygon.h" #include "viewer.h" #include "sys.h" #include "SpuSpan.h" #include "Func.h" #include "error.h" #include "fb.h" using namespace std; int Viewer::width; int Viewer::height; int Viewer::bpp; int Viewer::spe_num; #define redMask 0x00ff0000 #define greenMask 0x0000ff00 #define blueMask 0x000000ff #define alphaMask 0 extern int create_sgp(Polygon *sg, SceneGraphPack *sgp); #if 0 #define MEMORY_ALLOCATION(dest, align, size) \ posix_memalign((void**)(dest), (align), (size)) //void posix_memalign(void** dest, size_t align, size_t size){ //*dest = malloc(size); //} #else #define MEMORY_ALLOCATION(dest, align, size) \ *((void**)dest) = malloc((size)) #endif Viewer::Viewer(int b, int w, int h) { bpp = b; width = w; height = h; spe_num = 1; } Viewer::Viewer(int b, int w, int h, int _num) { bpp = b; width = w; height = h; spe_num = _num; } unsigned int fbdev_addr; void Viewer::sdl_init() { if (SDL_Init( SDL_INIT_VIDEO ) < 0) { fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError()); exit( 1 ); } #ifndef _DEBUG screen = SDL_SetVideoMode( width, height, bpp, SDL_HWSURFACE); if (screen == NULL) { fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError()); SDL_Quit(); exit(1); } fbdev_addr = (uint32)screen->pixels; #else fbdev_addr = get_fbdev_addr(); if (fbdev_addr == 0) { fbdev_addr = (unsigned int)(new Uint32[width*height*32/8]); } screen = SDL_CreateRGBSurfaceFrom((void*)fbdev_addr, width, height, 32, width*4, redMask, greenMask, blueMask, alphaMask); #endif } int Viewer::get_ticks() { int time; time = SDL_GetTicks(); return time; } bool Viewer::quit_check() { bool quit = false; SDL_Event event; while(SDL_PollEvent(&event)) { if(event.type==SDL_QUIT) { quit = true; return quit; } } return quit; } void Viewer::quit() { SDL_Quit(); } void Viewer::swap_buffers() { SDL_GL_SwapBuffers(); } void Viewer::write_pixel(int x, int y,float z, Uint32 rgb) { x += width/2; y += height/2; if (z < zRow[x][y]) { if (x < width && x > 0 && y > 0 && y < height) { zRow[x][y] = z; y = height - y; pixels[width*y + x] = rgb; } } } void Viewer::write_line(float x1, float y1, float x2, float y2, Uint32 rgb) { if (x1 > x2) { float x=0; float y=0; x=x1; y=y1; x1 = x2; y1 = y2; x2 = x; y2 = y; } float s = y1; if ((int)x1 == (int)x2) { if (y1 > y2) { float y=0; y = y1; y1 = y2; y2 = y; } for (float i=y1; i<y2; i++) { //write_pixel((int)x1,(int)i); write_pixel((int)x1,(int)i,0,rgb); } } else { float t = (y2 - y1)/(x2 - x1); if (t < -1) { float f = 0; for (float i=x1; i<x2; i++) { for (float a=(int)t; a<0; a++) { write_pixel((int)i,(int)s,0,rgb); s--; } f += t-(int)t; if (f <= -1) { write_pixel((int)i,(int)s,0,rgb); f = 0; s--; } } } else if (t <= 1) { for(float i=x1; i<x2; i++) { //write_pixel((int)i,(int)s); write_pixel((int)i,(int)s,0,rgb); s += t; } } else { float f = 0; for (float i=x1; i<x2; i++) { for (float a=0; a<(int)t; a++) { write_pixel((int)i,(int)s,0,rgb); s++; } f += t-(int)t; if (f >= 1) { write_pixel((int)i,(int)s,0,rgb); f = 0; s++; } } } } } void Viewer::write_triangle(float x1, float y1, float x2, float y2, float x3, float y3, Uint32 rgb) { write_line(x1,y1,x2,y2,rgb); write_line(x2,y2,x3,y3,rgb); write_line(x3,y3,x1,y1,rgb); } void Viewer::clean_pixels() { #if 0 for(int i=0; i<width*height; i++) { pixels[i] = 0x00; } #else bzero(pixels, sizeof(int)*width*height); #endif } void Viewer::graph_line() { int xl = width*height/2; int yl = width/2; for(int i=0; i<width; i++) { for(int t=0; t<height; t+=20) { pixels[width*t+i] = 0x5a; } pixels[xl +i] = 0xff; } for(int i=0; i<height; i++) { for(int t=0; t<width; t+=20) { pixels[i*width+t] = 0x5a; } pixels[i*width+yl] = 0xff; } } int start_time; int this_time; int frames; SDL_Surface *bitmap; SDL_PixelFormat *pixelFormat; Uint32 background; Polygon *polygon; SceneGraphPack *sgp; PolygonPack *pp; SpuSpan *ssl; //SpanPack send_pack[6][10] __attribute__((aligned(16))); SpanPack send_pack[SPE_NUM_MAX][MAX_SIZE_SPAN_PACK] __attribute__((aligned(16))); void *__texture; void Viewer::run_init(char *xml) { HTaskPtr task; start_time = get_ticks(); this_time = 0; frames = 0; pixelFormat = screen->format; background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); //polygon = new Polygon; //polygon->set_data(xml); polygon = Polygon::createFromXMLfile(xml); polygon->viewer = this; // TaskManager 側で // allocate API を作っておいた方がいい。 // もしくは configure ?微妙か //posix_memalign((void**)&sgp, 16, sizeof(SceneGraphPack)); //posix_memalign((void**)&pp, 16, sizeof(PolygonPack)); //posix_memalign((void**)&ssl, 16, sizeof(SpuSpan)); //sgp = new SceneGraphPack; //pp = new PolygonPack; //ssl = new SpuSpan; MEMORY_ALLOCATION( &sgp, 16, sizeof(SceneGraphPack)); MEMORY_ALLOCATION( &pp, 16, sizeof(PolygonPack)); MEMORY_ALLOCATION( &ssl, 16, sizeof(SpuSpan)); create_sgp(polygon, sgp); sgp->ssl = ssl; //pixels = new Uint32[width*height]; pixels = (Uint32*)fbdev_addr; //fbdev_addr = (Uint32)pixels; //graph_line(); bitmap = SDL_CreateRGBSurfaceFrom((void *)pixels, width, height, 32, width*4, redMask, greenMask, blueMask, alphaMask); task = manager->create_task(VIEWER_RUN_LOOP, 0, 0, 0, NULL); task->spawn(); //posix_memalign((void**)&__texture, 16, 128*128*3); //__texture = malloc(128*128*3); MEMORY_ALLOCATION( &__texture, 16, 128*128*3); memcpy(__texture, polygon->texture_image->pixels, 128*128*3); HTaskPtr task_init_tex; for (int i = 0; i < spe_num; i++) { task_init_tex = manager->create_task(TASK_INIT_TEXTURE, 0, (uint32)__texture, 0, NULL); //task_init_tex->set_cpu(CPU_SPE); task_init_tex->set_cpu((CPU_TYPE)(i + SPE_0)); task_init_tex->spawn(); } } void Viewer::run_loop(void) { HTaskPtr task_update_sgp = NULL; HTaskPtr task_create_pp = NULL; HTaskPtr task_create_sp = NULL; HTaskPtr task_finish = NULL; HTaskPtr task; bool quit_flg; quit_flg = quit_check(); SDL_BlitSurface(bitmap, NULL, screen, NULL); SDL_UpdateRect(screen, 0, 0, 0, 0); if (quit_flg == true) { this_time = get_ticks(); task_finish = manager->create_task(VIEWER_RUN_FINISH, 0, 0, 0, NULL); task_finish->spawn(); return; } // clean_pixels や zRow_init は、 // spe で fb に draw する時は必要ない。 // ppe 側で draw する時にだけ呼ぶべき。 //clean_pixels(); //zRow_init(); // これ自身、一つのタスクとして回す方がよいか //graph_line(); task_update_sgp = manager->create_task(TASK_UPDATE_SGP, sizeof(SceneGraphPack), (uint32)sgp, (uint32)sgp, NULL); task_create_pp = manager->create_task(TASK_CREATE_PP, sizeof(SceneGraphPack), (uint32)sgp, (uint32)pp, NULL); task_create_sp = manager->create_task(TASK_CREATE_SPAN, sizeof(PolygonPack), (uint32)pp, 0, NULL); task = manager->create_task(VIEWER_RUN_DRAW, 0, 0, 0, NULL); task->wait_for(task_update_sgp); task->wait_for(task_create_pp); task->wait_for(task_create_sp); task_create_sp->wait_for(task_create_pp); //task_update_sgp->set_cpu(CPU_SPE); //task_create_pp->set_cpu(CPU_SPE); task_update_sgp->spawn(); task_create_pp->spawn(); task_create_sp->spawn(); task->spawn(); } /** * 本当はタスクとして TestDraw を選ぶ */ //#define DRAW_POLYGON #define DRAW_SPANPACK //#define DRAW_SPUSPAN void Viewer::run_draw(void) { HTaskPtr task_loop; HTaskPtr task_draw; task_loop = manager->create_task(VIEWER_RUN_LOOP, 0, 0, 0, NULL); #if 1 for (int j = 0; j < SPE_NUM_MAX; j++) { for (int i = 0; i < MAX_SIZE_SPAN_PACK; i++) { if (ssl->list[j].packs[i].info.size == 0) continue; // memcpy はもちろんだめ。だけど。。。 // SPUSPAN->ss は配列で、各要素がアライメントとれてないと駄目。 #if 1 memcpy(&send_pack[j][i], &ssl->list[j].packs[i], sizeof(SpanPack)); task_draw = manager->create_task(TASK_DRAW, sizeof(SpanPack), (uint32)&send_pack[j][i], fbdev_addr, NULL); #else task_draw = manager->create_task(TASK_DRAW, sizeof(SpanPack), (uint32)&ssl->list[j].packs[i], fbdev_addr, NULL); #endif //task_draw->set_cpu(CPU_SPE); // もう少し良い選び方があってもいいはずだ // てか ANY にすればいいんじゃね task_draw->set_cpu((CPU_TYPE)(((i+j)%spe_num) + SPE_0)); //task_draw->set_cpu(CPU_PPE); task_loop->wait_for(task_draw); task_draw->spawn(); } } #endif task_loop->spawn(); frames++; return; #ifdef DRAW_POLYGON //polygon->draw(pp); // test draw of PolygonPack polygon->draw(sgp); // test draw of PolygonPack #else # ifdef DRAW_SPANPACK // test draw of SpanPack for (int j = 0; j < SPE_NUM_MAX; j++) { for (int i = 0; i < MAX_SIZE_SPAN_PACK; i++) { if (ssl->list[j].packs[i].info.size < 1) continue; polygon->draw(&ssl->list[j].packs[i]); } } # else polygon->draw(&ssl->ss[0]); polygon->draw(&ssl->ss[1]); polygon->draw(&ssl->ss[2]); polygon->draw(&ssl->ss[3]); polygon->draw(&ssl->ss[4]); polygon->draw(&ssl->ss[5]); # endif #endif SDL_BlitSurface(bitmap, NULL, screen, NULL); SDL_UpdateRect(screen, 0, 0, 0, 0); } void Viewer::run_finish(void) { if (this_time != start_time) { cout<< (((float)frames)/(this_time-start_time))*1000.0 << " FPS\n"; } SDL_FreeSurface(bitmap); //delete [] pixels; polygon->delete_data(); delete polygon; free(__texture); quit(); } void Viewer::zRow_init() { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { zRow[i][j] = 65535; } } }