Mercurial > hg > Game > Cerium
changeset 1205:b8adf4e95e96 draft
add createStringFont()
line wrap: on
line diff
--- a/Renderer/Engine/Makefile.macosx Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/Makefile.macosx Thu Jul 21 18:56:08 2011 +0900 @@ -13,8 +13,8 @@ LIBS += -lFifoManager -CFLAGS += `sdl-config --cflags` `xml2-config --cflags` -Drestrict=__restrict__ -LIBS += `sdl-config --libs` `xml2-config --libs` -lSDL_image -Wl,-framework,OpenGL +CFLAGS += `sdl-config --cflags` `xml2-config --cflags` `freetype-config --cflags` -Drestrict=__restrict__ +LIBS += `sdl-config --libs` `xml2-config --libs` `freetype-config --libs` -lSDL_image -Wl,-framework,OpenGL .SUFFIXES: .cc .o
--- a/Renderer/Engine/SceneGraph.cc Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/SceneGraph.cc Thu Jul 21 18:56:08 2011 +0900 @@ -11,6 +11,8 @@ #include "texture.h" #include "TaskManager.h" #include "polygon_pack.h" +#include <ft2build.h> +#include <freetype/freetype.h> using namespace std; @@ -219,6 +221,199 @@ } +SceneGraph::SceneGraph(TaskManager *manager,char *font,int pixels,Uint32 color,char *string_name) { + + init(); + + this->matrix = (float*)manager->allocate(sizeof(float)*16); + this->real_matrix = (float*)manager->allocate(sizeof(float)*16); + this->texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); + texture_info->texture_id = -1; + + //size : 頂点の数かな + size = 6; + parent_name = NULL; + name = string_name; + for (int i = 0; i < 16; i++) { + matrix[i] = 0; + real_matrix[i] = 0; + } + + if (size % 3 != 0) { + printf("vertex size is error. size %% 3 = %lld\n", size % 3); + } + + if (size > 0) { + pp_num = (size/3 + MAX_SIZE_TRIANGLE - 1) / MAX_SIZE_TRIANGLE; + pp = (PolygonPack*)manager->allocate(sizeof(PolygonPack)*pp_num); + } else { + pp_num = 0; + pp = NULL; + } + + create_font_data(manager, font, pixels, color, string_name); + + finalize = &SceneGraph::finalize_original; +} + +void +SceneGraph::create_font_data(TaskManager *manager,char *font ,int pixels, Uint32 color, char *string_name) +{ + //font_coordinate(pixels/2,pixels); + font_normal(); + font_model(); + //font_texture(); + + get_font_image(manager, font, pixels, color, string_name); +} + +void +SceneGraph::get_font_image(TaskManager *manager,char *font ,int pixels ,Uint32 color, char *string_name) +{ + int tex_id; + if (texture_hash.hash_regist(string_name, tex_id)) { + SDL_Surface *texture_image = load_font_image(font,pixels,color,string_name); + if(!texture_image){ + printf("Can't load image %s\n",string_name); + exit(0); + } + texture_info->texture_id = makeTapestries(manager, texture_image,tex_id); + printf("%d\n",texture_info->texture_id); + tex_id = texture_info->texture_id; + + } else { + texture_info->texture_id = tex_id; + } + + texture_info->t_w = list[tex_id].t_w; + texture_info->t_h = list[tex_id].t_h; + texture_info->pixels_orig = list[tex_id].pixels_orig; + texture_info->pixels = list[tex_id].pixels; + texture_info->scale_max = list[tex_id].scale_max; + texture_info->texture_image = list[tex_id].texture_image; +} + +SDL_Surface* +SceneGraph::load_font_image(char *font ,int pixel,Uint32 color , char *string_name) +{ + //printf("laod_font_iamge"); + FT_Library library; + FT_Error err; + err = FT_Init_FreeType(&library); + if(err){ + exit(1); + } + FT_Face face; + err = FT_New_Face(library,font,0,&face);//font:フォントファイルのパス + if(err){ + exit(1); + } + + err = FT_Set_Pixel_Sizes(face,pixel,pixel); + if(err){ + exit(1); + } + + u_int32_t changecode[256] = {0}; + + conv(string_name+5,strlen(string_name+5),changecode); + + unsigned int characode = changecode[0]; + + err = FT_Load_Char(face,characode,0); + if(err){ + exit(1); + } + + err = FT_Render_Glyph(face->glyph,FT_RENDER_MODE_MONO); + if(err){ + exit(1); + } + + FT_Bitmap *bm = &face->glyph->bitmap; + + //baseline計算 y_ppem(nominal height) - bitmap_top(topからのbaseline) + float baseline = face->size->metrics.y_ppem - face->glyph->bitmap_top; + + float row = 1; + float width = 1; + + font_coordinate(baseline,face->glyph->bitmap.rows,face->glyph->bitmap.width); + this->seq = face->glyph->bitmap.width; + font_texture(row,width); + + int index = 0; + Uint32 *pixels = (Uint32*)malloc(bm->rows*bm->pitch*8*4); + + for (int row = 0; row < bm->rows; row ++) { + for (int col = 0; col < bm->pitch; col ++) { + int c = bm->buffer[bm->pitch * row + col]; + for (int bit = 7; bit >= 0; bit --) { + + if (((c >> bit) & 1) == 0) { + //printf(" "); + pixels[index++] = 0x0000000; + } else { + //printf("##"); + //pixels[index++] = 0x00ffffff; + pixels[index++] = color; + + } + + } + } + + } + + SDL_Surface *texture_image = SDL_CreateRGBSurfaceFrom(pixels, bm->pitch*8, bm->rows, + 32, bm->pitch*8*4, redMask, + greenMask, blueMask, alphaMask); + + + + if (!texture_image) { + printf("error\n"); + return 0; + } + SDL_Surface *tmpImage + = SDL_CreateRGBSurface(SDL_HWSURFACE, texture_image->w, + texture_image->h, 32, redMask, + greenMask, blueMask, alphaMask); + + + SDL_Surface *converted; + converted = SDL_ConvertSurface(texture_image, tmpImage->format, + SDL_HWSURFACE); + if (converted != NULL) { + SDL_FreeSurface(texture_image); + texture_image = converted; + } + + return texture_image; +} + +void +SceneGraph::conv(char *str, int length, u_int32_t *out) { + int oindex = 0; + int i = 0; + while (i < length) { + out[oindex] = str[i++] & 0xff; + int len = 0; + u_int32_t mask; + for (mask = 0x80; out[oindex] & mask; mask >>= 1) { + out[oindex] -= mask; + len++; + } + int j; + for (j = 1; j < len; j++) + out[oindex] = (out[oindex] << 6) | (str[i++] & 0x3f); + oindex++; + } +} + +/*文字のSceneGraphを生成する*/ + + void SceneGraph::init() {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Engine/SceneGraph.cc~ Thu Jul 21 18:56:08 2011 +0900 @@ -0,0 +1,1100 @@ +#include <iostream> +#include <SDL.h> +#include <SDL_opengl.h> +#include <SDL_image.h> +#include <libxml/parser.h> +#include <string.h> +#include "SceneGraph.h" +#include "xml.h" +#include "matrix_calc.h" +#include "TextureHash.h" +#include "texture.h" +#include "TaskManager.h" +#include "polygon_pack.h" +#include <ft2build.h> +#include <freetype/freetype.h> + +using namespace std; + +SceneGraphPtr scene_graph = NULL; +SceneGraphPtr scene_graph_viewer = NULL; + +static TextureHash texture_hash; +texture_list list[TABLE_SIZE]; + +extern int decode(char *cont, FILE *outfile); + +static void +no_move(SceneGraphPtr self, void *sgroot_, int screen_w, int screen_h) {} + +static void +no_collision(SceneGraphPtr self, void *sgroot_, int screen_w, int screen_h, + SceneGraphPtr tree) {} + +/** + * 事前に計算したテクスチャの最大縮小率 scale まで、 + * テクスチャを 1/2 縮小していく。 + * このとき、テクスチャは TEXTURE_SPLIT_PIXELx2 のブロック (Tile) で分割し、 + * これらを連続したメモリ領域に格納していく。 + * 以下の (1), (2), (3) を Tapestry と呼ぶ + * + * 例 scale = 4 の場合 + * + * Tapestry(1) 1/1 + * +---+---+---+---+ + * | 0 | 1 | 2 | 3 | + * +---+---+---+---+ + * | 4 | 5 | 6 | 7 | (2) 1/2 + * +---+---+---+---+ +---+---+ + * | 8 | 9 | 10| 11| | 16| 17| (3) 1/4 + * +---+---+---+---+ +---+---+ +---+ + * | 12| 13| 14| 15| | 18| 19| | 20| + * +---+---+---+---+ +---+---+ +---| + * + * (1) (2) (3) + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * | * | * | 14| 15| 16| 17| 18| 19| 20| + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * + * @param[in] tex_w Width of orignal texture + * @param[in] tex_h Height of orignal texture + * @param[in] tex_src Original texture + * @param[in] all_pixel_num Tapestry の合計 pixel 数 + * @param[in] scale テクスチャの最大縮小率 (= 2^n) + * @return (1) のアドレス + */ + + +uint32 white[256] __attribute__((aligned(16))); + +static uint32* +makeTapestry(TaskManager *manager, uint32 tex_w, uint32 tex_h, uint32 *tex_src, + int all_pixel_num, int scale_cnt) +{ + if (tex_w==0 && tex_h==0) { + // non texture case + uint32 pattern = SDL_BYTEORDER == SDL_LIL_ENDIAN? 0x00ffffff : 0xffffff00; /* OpenGL RGBA masks */ + if (white[0]!=pattern) { // dumb! +#if 1 + for(int i=0;i<256;i++) + white[i] = pattern; +#else + memset_pattern4(white,&pattern,256); +#endif + } + return white; + } + + uint32 t = 0; + uint32 diff = TEXTURE_SPLIT_PIXEL; + uint32 p_diff = 1; + + uint32 *tex_dest = (uint32*)manager->allocate(sizeof(int)*all_pixel_num); + // uint32 *tex_src_max = (uint32*)( tex_src + tex_h*tex_w); + + // uint32 alpha = SDL_BYTEORDER == SDL_LIL_ENDIAN? 0xff000000 : 0xff; /* OpenGL RGBA masks */ + uint32 alpha = tex_src[0]; + + while (scale_cnt) { + // we should use average, except clear one + for (uint32 y = 0; y < align(tex_h,diff); y += diff) { + for (uint32 x = 0; x < align(tex_w,diff); x += diff) { + for (uint32 j = 0; j < diff; j += p_diff) { + for (uint32 i = 0; i < diff; i += p_diff) { + tex_dest[t++] = + (x+i<tex_w && y+j<tex_h) ? tex_src[(x+i) + tex_w*(y+j)]: alpha; + } + } + } + } + + diff <<= 1; p_diff <<= 1; + scale_cnt >>= 1; + } + + return tex_dest; +} + + +/** + * 何の情報も持ってない SceneGraph の生成 + * 今のところ、とりあえず木構造の繋がりに使うぐらい + */ +SceneGraph::SceneGraph(TaskManager *manager) +{ + + init(); + + matrix = (float*)manager->allocate(sizeof(float)*16); + real_matrix = (float*)manager->allocate(sizeof(float)*16); + texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); + + texture_info->texture_id = -1; + + for (int i = 0; i < 16; i++) { + matrix[i] = 0; + real_matrix[i] = 0; + } + + + finalize = &SceneGraph::finalize_copy; + + this->name = "NULLPO"; + +} + +/** + * orig のコピーとして SceneGraph を生成する + */ +SceneGraph::SceneGraph( TaskManager *manager, SceneGraphPtr orig) +{ + + init(); + + memcpy(this, orig, sizeof(SceneGraph)); + + matrix = (float*)manager->allocate(sizeof(float)*16); + real_matrix = (float*)manager->allocate(sizeof(float)*16); + texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); + + for (int i = 0; i < 16; i++) { + matrix[i] = orig->matrix[i]; + real_matrix[i] = orig->real_matrix[i]; + } + + memcpy(texture_info, orig->texture_info, sizeof(texture_list)); + + // コピーしない + //flag_remove = 0; + //flag_drawable = 1; + next = NULL; + prev = NULL; + last = NULL; + + parent = NULL; + brother = NULL; + children = NULL; + lastChild = NULL; + + finalize = &SceneGraph::finalize_copy; + + frame = 0; +} + + +/* construct polygon from xmlNode. */ +SceneGraph::SceneGraph(TaskManager *manager, xmlNodePtr surface) +{ + + init(); + + matrix = (float*)manager->allocate(sizeof(float)*16); + real_matrix = (float*)manager->allocate(sizeof(float)*16); + texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); + texture_info->texture_id = -1; + + //size : 頂点の数かな + size = atoi((char *)xmlGetProp(surface,(xmlChar *)"size")); + name = (char *)xmlGetProp(surface,(xmlChar *)"name"); + parent_name = (char *)xmlGetProp(surface,(xmlChar *)"parent"); + + for (int i = 0; i < 16; i++) { + matrix[i] = 0; + real_matrix[i] = 0; + } + + if (size % 3 != 0) { + printf("vertex size is error. size %% 3 = %lld\n", size % 3); + } + + if (size > 0) { + pp_num = (size/3 + MAX_SIZE_TRIANGLE - 1) / MAX_SIZE_TRIANGLE; + pp = (PolygonPack*)manager->allocate(sizeof(PolygonPack)*pp_num); + } else { + pp_num = 0; + pp = NULL; + } + + get_data(manager, surface->children); + + finalize = &SceneGraph::finalize_original; + +} + +SceneGraph::SceneGraph(TaskManager *manager,char *font,int pixels,Uint32 color,char *string_name) { + + init(); + + this->matrix = (float*)manager->allocate(sizeof(float)*16); + this->real_matrix = (float*)manager->allocate(sizeof(float)*16); + this->texture_info = (texture_list*)manager->allocate(sizeof(texture_list)); + texture_info->texture_id = -1; + + //size : 頂点の数かな + size = 6; + parent_name = NULL; + name = string_name; + for (int i = 0; i < 16; i++) { + matrix[i] = 0; + real_matrix[i] = 0; + } + + if (size % 3 != 0) { + printf("vertex size is error. size %% 3 = %lld\n", size % 3); + } + + if (size > 0) { + pp_num = (size/3 + MAX_SIZE_TRIANGLE - 1) / MAX_SIZE_TRIANGLE; + pp = (PolygonPack*)manager->allocate(sizeof(PolygonPack)*pp_num); + } else { + pp_num = 0; + pp = NULL; + } + + create_font_data(manager, font, pixels, color, string_name); + + finalize = &SceneGraph::finalize_original; +} + +void +SceneGraph::create_font_data(TaskManager *manager,char *font ,int pixels, Uint32 color, char *string_name) +{ + //font_coordinate(pixels/2,pixels); + font_normal(); + font_model(); + //font_texture(); + + get_font_image(manager, font, pixels, color, string_name); +} + +void +SceneGraph::get_font_image(TaskManager *manager,char *font ,int pixels ,Uint32 color, char *string_name) +{ + int tex_id; + if (!texture_hash.hash_regist(string_name, tex_id)) { + SDL_Surface *texture_image = load_font_image(font,pixels,color,string_name); + if(!texture_image){ + printf("Can't load image %s\n",string_name); + exit(0); + } + texture_info->texture_id = makeTapestries(manager, texture_image,tex_id); + printf("%d\n",texture_info->texture_id); + tex_id = texture_info->texture_id; + + } else { + texture_info->texture_id = tex_id; + } + + texture_info->t_w = list[tex_id].t_w; + texture_info->t_h = list[tex_id].t_h; + texture_info->pixels_orig = list[tex_id].pixels_orig; + texture_info->pixels = list[tex_id].pixels; + texture_info->scale_max = list[tex_id].scale_max; + texture_info->texture_image = list[tex_id].texture_image; +} + +SDL_Surface* +SceneGraph::load_font_image(char *font ,int pixel,Uint32 color , char *string_name) +{ + FT_Library library; + FT_Error err; + err = FT_Init_FreeType(&library); + if(err){ + exit(1); + } + FT_Face face; + err = FT_New_Face(library,font,0,&face);//font:フォントファイルのパス + if(err){ + exit(1); + } + + err = FT_Set_Pixel_Sizes(face,pixel,pixel); + if(err){ + exit(1); + } + + u_int32_t changecode[256] = {0}; + + conv(string_name+5,strlen(string_name+5),changecode); + + unsigned int characode = changecode[0]; + + err = FT_Load_Char(face,characode,0); + if(err){ + exit(1); + } + + err = FT_Render_Glyph(face->glyph,FT_RENDER_MODE_MONO); + if(err){ + exit(1); + } + + FT_Bitmap *bm = &face->glyph->bitmap; + + //baseline計算 y_ppem(nominal height) - bitmap_top(topからのbaseline) + float baseline = face->size->metrics.y_ppem - face->glyph->bitmap_top; + + float row = 1; + float width = 1; + + font_coordinate(baseline,face->glyph->bitmap.rows,face->glyph->bitmap.width); + this->seq = face->glyph->bitmap.width; + font_texture(row,width); + + int index = 0; + Uint32 *pixels = (Uint32*)malloc(bm->rows*bm->pitch*8*4); + + for (int row = 0; row < bm->rows; row ++) { + for (int col = 0; col < bm->pitch; col ++) { + int c = bm->buffer[bm->pitch * row + col]; + for (int bit = 7; bit >= 0; bit --) { + + if (((c >> bit) & 1) == 0) { + //printf(" "); + pixels[index++] = 0x0000000; + } else { + //printf("##"); + //pixels[index++] = 0x00ffffff; + pixels[index++] = color; + + } + + } + } + + } + + SDL_Surface *texture_image = SDL_CreateRGBSurfaceFrom(pixels, bm->pitch*8, bm->rows, + 32, bm->pitch*8*4, redMask, + greenMask, blueMask, alphaMask); + + + + if (!texture_image) { + printf("error\n"); + return 0; + } + SDL_Surface *tmpImage + = SDL_CreateRGBSurface(SDL_HWSURFACE, texture_image->w, + texture_image->h, 32, redMask, + greenMask, blueMask, alphaMask); + + + SDL_Surface *converted; + converted = SDL_ConvertSurface(texture_image, tmpImage->format, + SDL_HWSURFACE); + if (converted != NULL) { + SDL_FreeSurface(texture_image); + texture_image = converted; + } + + return texture_image; +} + +void +SceneGraph::conv(char *str, int length, u_int32_t *out) { + int oindex = 0; + int i = 0; + while (i < length) { + out[oindex] = str[i++] & 0xff; + int len = 0; + u_int32_t mask; + for (mask = 0x80; out[oindex] & mask; mask >>= 1) { + out[oindex] -= mask; + len++; + } + int j; + for (j = 1; j < len; j++) + out[oindex] = (out[oindex] << 6) | (str[i++] & 0x3f); + oindex++; + } +} + +/*文字のSceneGraphを生成する*/ + + +void +SceneGraph::init() +{ + next = NULL; + prev = NULL; + last = NULL; + + parent = NULL; + brother = NULL; + children = NULL; + lastChild = NULL; + + stack_xyz[0] = 0.0f; + stack_xyz[2] = 0.0f; + stack_xyz[1] = 0.0f; + stack_angle[0] = 0.0f; + stack_angle[1] = 0.0f; + stack_angle[2] = 0.0f; + + size = 0; + pp_num = 0; + + //data = NULL; + + move = no_move; + collision = no_collision; + + flag_remove = 0; + flag_drawable = 1; + sgid = -1; + gid = -1; + + frame = 0; +} + +SceneGraph::~SceneGraph() +{ + (this->*finalize)(); +} + +/** + * xml ファイルから生成されたオリジナル SceneGraph なので + * polygon data を削除 + */ +void +SceneGraph::finalize_original() +{ + //delete [] data; + + free(pp); + free(matrix); + free(real_matrix); + free(texture_info); + +} + +/** + * SceneGraph ID から生成された、コピー SceneGraph なので + * polygon data は削除しない。オリジナルの方で削除する。 + */ +void +SceneGraph::finalize_copy() +{ + + free(matrix); + free(real_matrix); + free(texture_info); +} + + +/** + * add Children + * 親の登録と、brother のリストへ加える + * + * @param child new child + */ +SceneGraphPtr +SceneGraph::addChild(SceneGraphPtr child) +{ + /* childrenのリストの最後に加える (brother として)*/ + if (this->lastChild != NULL) { + SceneGraphPtr last = this->lastChild; + last->brother = child; + //child->parent = this; + //return child; + } + + this->lastChild = child; + + if (this->children == NULL) { + this->children = child; + } + + child->parent = this; + + return child; +} + + +/** + * add Brother + * addChild() でも brother の操作をしないといけないので、そっちに回す + * + * @param bro new Brother + */ +SceneGraphPtr +SceneGraph::addBrother(SceneGraphPtr bro) +{ + if (this->parent) { + parent->addChild(bro); + } else { + fprintf(stderr, "error : SceneGraph::%s : %s doesn't have parent\n", + __FUNCTION__, this->name); + } + + return bro; +} + +/* thisの子や子孫にnameのものが存在すればそいつを返す なければNULL. */ +SceneGraphPtr +SceneGraph::searchSceneGraph(const char *name) +{ + SceneGraphPtr tmp; + SceneGraphPtr result; + + /* 本人か */ + if( 0==strcmp(this->name, name) ) return this; + + /* 子供から再帰的に探す */ + for(tmp = this->children; tmp; tmp = tmp->next) { + if ((result=tmp->searchSceneGraph(name)) != NULL) + return result; + } + + /* 無かったら NULL. */ + return NULL; +} + +void +SceneGraph::tree_check() +{ + SceneGraphPtr t = this; + + while(t) + { + cout << "my_name : " << t->name << endl; + if(t->children != NULL) + { + cout << "--move children : " << t->children->name << endl; + t = t->children; + } + else if(t->brother != NULL) + { + cout << "--move brother : " << t->brother->name << endl; + t = t->brother; + } + else + { + while(t) + { + if(t->brother != NULL) + { + cout << "--move brother : " << t->brother->name << endl; + t = t->brother; + break; + } + else + { + if(t->parent) + { + cout << "--move parent : " << t->parent->name << endl; + } + t = t->parent; + } + } + } + } +} + + +void +SceneGraph::print_member() +{ + cout << "size = " << size << endl; + cout << "name = " << name << endl; + cout << "parent_name = " << parent_name << endl; + + if (parent != NULL) { + cout << "parent->name = " << parent->name << endl; + } + + if (children != NULL) { + cout << "children->name = " << children->name << endl; + } +} + + +/* + * surface nodeからポリゴンの情報を読み出す 再帰しない + */ +void +SceneGraph::get_data(TaskManager *manager, xmlNodePtr cur) +{ + //char *image_name; + + for(;cur;cur=cur->next) + { + if(!xmlStrcmp(cur->name,(xmlChar*)"coordinate")) + { + char *cont = (char *)xmlNodeGetContent(cur); + pickup_coordinate(cont); + } + else if(!xmlStrcmp(cur->name,(xmlChar*)"normal")) + { + char *cont = (char *)xmlNodeGetContent(cur); + pickup_normal(cont); + } + else if(!xmlStrcmp(cur->name,(xmlChar*)"model")) + { + char *cont = (char *)xmlNodeGetContent(cur); + pickup_model(cont); + } + else if(!xmlStrcmp(cur->name,(xmlChar*)"texture")) + { + char *cont = (char *)xmlNodeGetContent(cur); + pickup_texture(cont); + } + else if(!xmlStrcmp(cur->name,(xmlChar*)"imageflag")) + { + int id; + char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name"); + texture_hash.hash_regist(filename, id); + } + else if(!xmlStrcmp(cur->name,(xmlChar*)"image")) + { + get_image(manager, cur); + } + } +} + +static int +is_bmp(char *name) { + int bmp = 0; + + while(*name) { + if (bmp==0 && *name=='.') bmp = 1; + else if (bmp==1 && (*name=='b' || *name=='B')) bmp = 2; + else if (bmp==2 && (*name=='m' || *name=='M')) bmp = 3; + else if (bmp==3 && (*name=='p' || *name=='P')) bmp = 4; + else bmp = 0; + name++; + } + return bmp==4; +} + +#if (__LITTLE_ENDIAN__) +#define LITTLEENDIAN 1 +#else +#define LITTLEENDIAN 0 +#endif + +static void +make_black_alpha(SDL_Surface *texture_image) +{ + int tex_w = texture_image->w; + int tex_h = texture_image->h; +#if LITTLEENDIAN + uint32 alpha = 0x000000ff; +#else + uint32 alpha = 0xff000000; +#endif + + uint32 *pixels = (uint32*)texture_image->pixels; + int i; + for(i=0;i<tex_w*tex_h;i++) { + uint32 pixel = pixels[i] & ~alpha; + if (pixel==0) { + pixels[i] = 0; + } + } +} + +SDL_Surface* +SceneGraph::load_decode_image(char *file_name, char *image_name, xmlNodePtr cur) +{ + int fd = mkstemp(image_name); + FILE *outfile = fdopen(fd, "wb"); + + if (NULL == outfile) { + cout << "error open file\n"; + return 0; + } + + char *cont = (char *)xmlNodeGetContent(cur); + //decode(cont, image_name); + decode(cont, outfile); + fclose(outfile); + + int alpha_black = is_bmp(file_name); + + +/** + * image を 32bit(RGBA) に変換する + */ + SDL_Surface *texture_image = IMG_Load(image_name); + if (!texture_image) return 0; + SDL_Surface *tmpImage + = SDL_CreateRGBSurface(SDL_HWSURFACE, texture_image->w, + texture_image->h, 32, redMask, + greenMask, blueMask, alphaMask); + + //= SDL_CreateRGBSurface(SDL_HWSURFACE, 0, + // 0, 32, redMask, + // greenMask, blueMask, alphaMask); + SDL_Surface *converted; + converted = SDL_ConvertSurface(texture_image, tmpImage->format, + SDL_HWSURFACE); + + //SDL_SetAlpha(converted, 0, 0); + + if (converted != NULL) { + SDL_FreeSurface(texture_image); + texture_image = converted; + } + + if (alpha_black) { + make_black_alpha(texture_image); + } + + // this->gl_tex = SDL_GL_LoadTexture(texture_image); + return texture_image; +} + +int +SceneGraph::makeTapestries(TaskManager *manager, SDL_Surface *texture_image, int id) { + uint32 *tapestry; + int scale = 1; + int tex_w = texture_image->w; + int tex_h = texture_image->h; + int all_pixel_num = 0; + int nw = tex_w; + int nh = tex_h; + + /** + * テクスチャの w or h が 8 pixel で分割できる間、 + * 1/2 の縮小画像を作る。 + * ここでは、最大の scale (1/scale) を見つける + * + * (ex) + * (128,128) => 64,64 : 32,32: 16,16 : 8,8 + * scale = 16 + * (128, 64) => 64,32 : 32,16: 16,8 + * scale = 8 + * 8 pixcel align してない場合は、透明に 8 pixcel に拡張する + * (200, 57) => 200,64 : 100,32 : 56,16: 32,8 (16,1 : 8,1 まで落すべき? 32byte) + * scale = 32 + */ + + do { + tex_w = align(tex_w,8); + tex_h = align(tex_h,8); + all_pixel_num += tex_w * tex_h; + tex_w >>= 1; /* tex_w /= 2 */ + tex_h >>= 1; + scale <<= 1; /* scale *= 2 */ + } while( tex_w >8 || tex_h > 8 ); + + scale >>= 1; // 必ず 1 以上になる + + tapestry = makeTapestry(manager, texture_image->w, texture_image->h, + (uint32*)texture_image->pixels, + all_pixel_num, scale); + + list[id].t_w = nw; + list[id].t_h = nh; + list[id].pixels_orig = (Uint32*)texture_image->pixels; + list[id].pixels = tapestry; + list[id].scale_max = scale; + list[id].texture_image = texture_image; + + return id; + } + +void +SceneGraph::get_image(TaskManager *manager, xmlNodePtr cur) +{ + char image_name[20] = "/tmp/image_XXXXXX"; + char *filename = (char *)xmlGetProp(cur, (xmlChar *)"name"); + + if (filename == NULL || filename[0] == 0) { + return; + } + + /** + * image_name を既に Load していれば何もしない + */ + int tex_id; + if (texture_hash.sg_hash_regist(filename, tex_id) == -1) { + + SDL_Surface *texture_image = load_decode_image(filename, image_name, cur); + if (texture_image==0) { + printf("Can't load image %s\n",filename); + exit(0); + } + texture_info->texture_id = makeTapestries(manager, texture_image, tex_id); + tex_id = texture_info->texture_id; + + if (unlink(image_name)) { + cout << "unlink error\n"; + } + } else { + /** + * 以前に Load されている Texture を共用 + */ + texture_info->texture_id = tex_id; + } + + // こんなことすると list[] のいみあるのかなーと + // 微妙に思う、自分で書き換えた感想 by gongo + texture_info->t_w = list[tex_id].t_w; + texture_info->t_h = list[tex_id].t_h;; + texture_info->pixels_orig = list[tex_id].pixels_orig; + texture_info->pixels = list[tex_id].pixels; + texture_info->scale_max = list[tex_id].scale_max; + texture_info->texture_image = list[tex_id].texture_image; + +} + + +void +SceneGraph::delete_data() +{ + SceneGraphPtr n = this->next, m; + + //n = this; + //delete [] n->data; + + if (next) { + while (n) { + m = n->next; + delete n; + n = m; + } + } +} + +/* move_func 実行 sgroot 渡す */ +void +SceneGraph::move_execute(int w, int h) +{ + (*move)(this, this->sgroot, w, h); +} + +void +SceneGraph::collision_check(int w, int h, SceneGraphPtr tree) +{ + (*collision)(this, this->sgroot, w, h, tree); +} + +void +SceneGraph::create_sg_execute() +{ + (*create_sg)(this->sgroot, property, update_property); +} + +void +SceneGraph::set_move_collision(move_func new_move) +{ + this->move = new_move; +} + +void +SceneGraph::set_move_collision(collision_func new_collision) +{ + this->collision = new_collision; +} + +void +SceneGraph::set_move_collision(move_func new_move, + collision_func new_collision) +{ + this->move = new_move; + this->collision = new_collision; +} + + +void +SceneGraph::set_move_collision(move_func new_move, + collision_func new_collision, void *sgroot_) +{ + this->move = new_move; + this->collision = new_collision; + // add + this->sgroot = sgroot_; +} + +void +SceneGraph::set_move_collision(move_func new_move, + collision_func new_collision, create_sg_func new_create_sg) +{ + this->move = new_move; + this->collision = new_collision; + this->create_sg = new_create_sg; +} + +void +SceneGraph::add_next(SceneGraphPtr next) +{ + /* next のリストの最後に加える */ + if (this->next != NULL) { + SceneGraphPtr tmp = this->last; + tmp->next = next; + } else { + this->next = next; + } + + this->last = next; +} + +/** + * SceneGraph の clone + * @return clone SceneGraph + */ +SceneGraphPtr +SceneGraph::clone(TaskManager *manager) { + + SceneGraphPtr p = new SceneGraph(manager, this); + + + return p; +} + +/** + * SceneGraph の clone + * 予め allocate されてる領域への placement new を行う + * + * @param buf clone 領域 + * @return clone SceneGraph + */ + +SceneGraphPtr +SceneGraph::clone(TaskManager *manager, void *buf) { + SceneGraphPtr p = new(buf) SceneGraph(manager, this); + return p; +} + +void +SceneGraph::remove() +{ + this->flag_remove = 1; +} + +/** + * tree から node を削除する + * + * @param tree SceneGraphTree + * @return node削除後の SceneGraphTree + */ +SceneGraphPtr +SceneGraph::realRemoveFromTree(SceneGraphPtr tree) +{ + SceneGraphPtr node = this; + SceneGraphPtr parent = node->parent; + SceneGraphPtr ret = tree; + + if (parent) { + SceneGraphPtr brother = parent->children; + SceneGraphPtr p, p1 = NULL; + + p = brother; + if (p) { + if (p == node) { + parent->children = NULL; + parent->lastChild = NULL; + } else { + p1 = p->brother; + + while (p1 && p1 != node) { + p1 = p1->brother; + p = p->brother; + } + + if (p1) { + p->brother = p1->brother; + + // node が最後尾なら、lastChild を変更 + if (parent->lastChild == p1) { + parent->lastChild = p; + } + } else { + // Can't find remove node + } + } + } + } else { + // 親が居ない = tree root なので + // NULL を返す + ret = NULL; + } + + return ret; +} + +/** + * list から node を削除する + * + * @param list SceneGraphList + * @return node削除後の SceneGraphList + */ +SceneGraphPtr +SceneGraph::realRemoveFromList(SceneGraphPtr list) +{ + SceneGraphPtr node = this; + SceneGraphPtr prev = node->prev; + SceneGraphPtr next = node->next; + SceneGraphPtr ret = list; + + if (prev) { + prev->next = next; + } else { + ret = next; + } + + if (next) { + next->prev = prev; + } + + return ret; +} + +int +SceneGraph::isRemoved() +{ + return flag_remove; +} + +/** + * 平行移動 + * + * @param x Ttranslate in the x direction + * @param y Ttranslate in the y direction + * @param z Ttranslate in the z direction + */ +void +SceneGraph::translate(float x, float y, float z) +{ + this->xyz[0] = x; + this->xyz[1] = y; + this->xyz[2] = z; +} + +/** + * x 軸方向への平行移動 + * + * @param x Ttranslate in the x direction + */ +void +SceneGraph::translateX(float x) +{ + this->xyz[0] = x; +} + +/** + * y 軸方向への平行移動 + * + * @param y Ttranslate in the y direction + */ +void +SceneGraph::translateY(float y) +{ + this->xyz[1] = y; +} + +/** + * z 軸方向への平行移動 + * + * @param z Ttranslate in the z direction + */ +void +SceneGraph::translateZ(float z) +{ + this->xyz[2] = z; +} + +/* end */
--- a/Renderer/Engine/SceneGraph.h Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/SceneGraph.h Thu Jul 21 18:56:08 2011 +0900 @@ -21,6 +21,8 @@ SceneGraph(TaskManager *manager); SceneGraph(TaskManager *manager, xmlNodePtr surface); SceneGraph(TaskManager *manager, SceneGraphPtr orig); + SceneGraph(TaskManager *manager, char* string_name, int pixels, Uint32 len , char* obj_name); + ~SceneGraph(void); // add @@ -74,6 +76,13 @@ move_func move; collision_func collision; create_sg_func create_sg; + + // フォントデータ + void create_font_data(TaskManager *manager,char *font, int pixels,Uint32 color, char *filename); + void get_font_image(TaskManager *manager,char *font, int pixels,Uint32 color, char *name); + void createFont(TaskManager *manager); + void conv(char *str, int length, u_int32_t *out); + SDL_Surface* load_font_image(char *font, int pixels,Uint32 color, char *string_name); // desutroctor で呼ばれる void (SceneGraph::*finalize)(void);
--- a/Renderer/Engine/SceneGraphRoot.cc Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/SceneGraphRoot.cc Thu Jul 21 18:56:08 2011 +0900 @@ -139,6 +139,63 @@ cnt++; } +/*文字列の生成*/ +void +SceneGraphRoot::createStringFont(TaskManager *manager, SceneGraphPtr root, + char *string,int pixels,int screen_w, + int screen_h,Uint32 color) +{ + SceneGraphPtr text; + float width_shift = 0; + int i; + int length = strlen(string); + for (i = 0; i < length;) { + int len = 0; + unsigned char initial = string[i]; + while (1) { + unsigned char mask = 0x80; + if (mask & initial) { + len++; + } else { + if (len == 0) len++; + break; + } + initial <<= 1; + } + char *obj_name; + float scale[] = {1,1,1}; + sgroot->createFont(manager,"/Library/Fonts/Osaka.ttf", pixels, color, &string[i], len, &obj_name); + text = sgroot->createSceneGraph(obj_name); + text->xyz[0] = screen_w/2 + width_shift -100; + text->xyz[1] = screen_h/2; + text->xyz[2] = -100; + width_shift += text->seq; + root->addChild(text); + get_matrix_scale(text->matrix, text->angle, text->xyz, scale, root->matrix); + get_matrix(text->real_matrix, text->angle, text->xyz, root->real_matrix); + i += len; + } +} + +void +SceneGraphRoot::createFont(TaskManager *manager,char *font, int pixels, + Uint32 color,char *string_name, int len, + char **obj_name) +{ + *obj_name = (char *)malloc(sizeof(char) * 12); + char sname[] = "char:"; + memcpy(*obj_name, sname, 5); + memcpy(*obj_name + 5, string_name, len); + (*obj_name)[5+len] = '\0'; + printf("%d",sgid_hash.get_sgid(*obj_name)); + if (sgid_hash.get_sgid(*obj_name) != -1) { + return; + } + SceneGraphPtr tmp = new SceneGraph(manager, font, pixels, color, + *obj_name); + registSceneGraph(tmp); +} + /* XMLファイルからポリゴンを作成 */ void SceneGraphRoot::createFromXMLfile(TaskManager *manager, const char *xmlfile)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Engine/SceneGraphRoot.cc~ Thu Jul 21 18:56:08 2011 +0900 @@ -0,0 +1,799 @@ +#include <SDL.h> +#include <SDL_image.h> +#include <libxml/parser.h> +#include "SceneGraphRoot.h" +#include "xml.h" +#include "matrix_calc.h" +#include "TextureHash.h" +#include "texture.h" +#include "Application.h" + +static int cnt = 0; +static const int SGLIST_LENGTH = 138; +static int sg_src_size = SGLIST_LENGTH ; +static int sg_src_id = -1; +static SceneGraphPtr *sg_src; + +static TextureHash sgid_hash; + +SceneGraphRoot *sgroot; + +SceneGraphRoot::SceneGraphRoot(float w, float h, TaskManager *manager) +{ + + sgroot = this; + sgroot->tmanager = manager; + + // SGLIST_LENGTH 決め打ちかぁ、動的生成にする場合上限決めておいた方がいいのかな + // + sg_src = (SceneGraphPtr*) malloc(sizeof(SceneGraphPtr)*SGLIST_LENGTH); + + camera = new Camera(w, h, this, sgroot->tmanager); + + iterator = new SceneGraphIterator; + controller = create_controller(); + + sg_exec_tree = NULL; + sg_draw_tree = NULL; + sg_available_list = NULL; + sg_remove_list = NULL; + + + screen_w = (int)w; + screen_h = (int)h; + int light_num = 4; + light_sysswitch = 0; + + for (int i = 0; i < light_num; i++) { + light[i] = new SceneGraph(sgroot->tmanager); + light[i]->xyz[0] = 0; + light[i]->xyz[1] = 0; + light[i]->xyz[2] = 0; + + light_switch[i] = 0; + + } + + move_finish_flag = 0; + + gtask_array = NULL; + + // TODO + // 今はとりあえず camera を Root にしています + // 今はそれすらもしてません + //sg_exec_tree = camera; +} + +SceneGraphRoot::~SceneGraphRoot() +{ + SceneGraphPtr p = sg_available_list; + + while (p) { + SceneGraphPtr tmp = p->next; + delete p; + p = tmp; + cnt--; + } + + p = sg_remove_list; + + while (p) { + SceneGraphPtr tmp = p->next; + delete p; + p = tmp; + cnt--; + } + + free(sg_src); + delete camera; + int light_num = 4; + for (int i = 0; i < light_num; i++) { + delete light[i]; + } + delete iterator; + delete controller; + + if (gtask_array != NULL) { + delete gtask_array; + } +} + +/** + * xml ファイルから生成された SceneGraph を sg_src に登録する。 + * + * @param sg SceneGraph created by xmlfile + */ +void +SceneGraphRoot::registSceneGraph(SceneGraphPtr sg) +{ + int dup; + if ((dup = getSgid(sg->name))>=0) { // while... + sg_src[dup]->name = ""; + // we should remove this. but some one may use it... + } + if (sg_src_id+1> sg_src_size) { + sg_src_size *= 2; + sg_src = (SceneGraphPtr*)realloc(sg_src, sg_src_size*sizeof(SceneGraphPtr)); + } + sg->sgid = ++sg_src_id; + sg_src[sg->sgid] = sg; + sgid_hash.sg_hash_regist((const char*)sg->name, sg->sgid); +} + + +void +SceneGraphRoot::addNext(SceneGraphPtr sg) +{ + SceneGraphPtr last = sg_available_list; + + if (!last) { + sg_available_list = sg; + } else { + while (last->next) { + last = last->next; + } + last->next = sg; + sg->prev = last; + } + + cnt++; +} + +/*文字列の生成*/ +void +SceneGraphRoot::createStringFont(TaskManager *manager, SceneGraphPtr root, + char *string,int pixels,int screen_w, + int screen_h,Uint32 color) +{ + SceneGraphPtr text; + float width_shift = 0; + int i; + int length = strlen(string); + for (i = 0; i < length;) { + int len = 0; + unsigned char initial = string[i]; + while (1) { + unsigned char mask = 0x80; + if (mask & initial) { + len++; + } else { + if (len == 0) len++; + break; + } + initial <<= 1; + } + char *obj_name; + sgroot->createFont(manager,"/Library/Fonts/Osaka.ttf", pixels, color, &string[i], len, &obj_name); + text = sgroot->createSceneGraph(obj_name); + text->xyz[0] = screen_w / 2 + width_shift -100; + text->xyz[1] = screen_h/2 ; + text->xyz[2] = -100; + width_shift += text->seq; + root->addChild(text); + i += len; + } +} + +void +SceneGraphRoot::createFont(TaskManager *manager,char *font, int pixels, + Uint32 color,char *string_name, int len, + char **obj_name) +{ + *obj_name = (char *)malloc(sizeof(char) * 12); + char sname[] = "char:"; + memcpy(*obj_name, sname, 5); + memcpy(*obj_name + 5, string_name, len); + (*obj_name)[5+len] = '\0'; + printf("%d",sgid_hash.get_sgid(*obj_name)); + if (sgid_hash.get_sgid(*obj_name) != -1) { + return; + } + SceneGraphPtr tmp = new SceneGraph(manager, font, pixels, color, + *obj_name); + registSceneGraph(tmp); +} + +/* XMLファイルからポリゴンを作成 */ +void +SceneGraphRoot::createFromXMLfile(TaskManager *manager, const char *xmlfile) +{ + xmlDocPtr doc; + xmlNodePtr cur; + SceneGraphPtr tmp; + + /* パース DOM生成 */ + doc = xmlParseFile(xmlfile); + cur = xmlDocGetRootElement(doc); + + /* ?? */ + xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D"); + + /* XMLのノードを一つずつ解析 */ + for (cur=cur->children; cur; cur=cur->next) { + /* 扱うのはsurfaceオンリー */ + if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) { + continue; + } + + /* ポリゴン(SceneGraph)生成 */ + tmp = new SceneGraph(manager, cur); + registSceneGraph(tmp); + } + xmlFreeDoc(doc); +} + +void +SceneGraphRoot::createFromXMLmemory(TaskManager *manager, SceneGraph *node, char *data, int len) +{ + xmlDocPtr doc; + xmlNodePtr cur; + + // size は取れるはず、テスト用に mmap したデータを使う + /* パース DOM生成 */ + + doc = xmlParseMemory(data, len); + cur = xmlDocGetRootElement(doc); + + /* ?? */ + xmlStrcmp(cur->name,(xmlChar*)"OBJECT-3D"); + + /* XMLのノードを一つずつ解析 */ + for (cur=cur->children; cur; cur=cur->next) { + /* 扱うのはsurfaceオンリー */ + if (xmlStrcmp(cur->name,(xmlChar*)"surface") != 0) { + continue; + } + /* ポリゴン(SceneGraph)生成 */ + SceneGraphPtr original = new SceneGraph(manager, cur); + registSceneGraph(original); + SceneGraphPtr clone = createSceneGraph(original->sgid); + node->addChild(clone); + } + xmlFreeDoc(doc); +} + +SceneGraphPtr +SceneGraphRoot::createSceneGraph(int id) +{ + SceneGraphPtr src; + SceneGraphPtr p; + + if (id < 0 || id > sg_src_size) { + printf("error: createSceneGraph(int id): id not found.\n"); + return NULL; + } + + /* オリジナルの SceneGraph */ + src = sg_src[id]; + + /* ユーザーにはオリジナルの clone を返す */ + p = src->clone(this->tmanager); + + /* move, collision に sgroot を渡したいのでここで sgroot を渡しておく*/ + p->sgroot = (void *)this; + + addNext(p); + + return p; +} + + + + +SceneGraphPtr +SceneGraphRoot::createSceneGraph(const char *name) +{ + SceneGraphPtr src; + SceneGraphPtr p; + + int id = getSgid(name); + if (id < 0) { + printf("error: createSceneGraph(name): name object not found.\n"); + return NULL; + } + + /* オリジナルの SceneGraph */ + src = sg_src[id]; + + /* ユーザーにはオリジナルの clone を返す */ + p = src->clone(this->tmanager); + + /* move, collision に sgroot を渡したいのでここで sgroot を渡しておく*/ + p->sgroot = (void *)this; + + addNext(p); + + return p; +} + +int +SceneGraphRoot::getSgid(const char *name) +{ + return sgid_hash.get_sgid(name); +} + +int +SceneGraphRoot::getLast() +{ + if (sg_src_id>=0) + return sg_src[sg_src_id]->sgid; + return -1; +} + +/** + * 何も表示しない、move,collision もしない SceneGraph を生成 + * いずれ、Transform3D 的なものに回す予定 + */ +SceneGraphPtr +SceneGraphRoot::createSceneGraph() +{ + SceneGraphPtr p = new SceneGraph(sgroot->tmanager); + + /* move, collision に sgroot を渡したいのでここで sgroot を渡しておく*/ + p->sgroot = (void *)this; + + addNext(p); + p->flag_drawable = 0; + + return p; +} + + +void +SceneGraphRoot::lightCalc() +{ + int light_num = 4; + for (int i = 0; i < light_num; i++) { + + get_matrix(light[i]->matrix, light[i]->angle, light[i]->xyz, camera->matrix); + + light_vector[i*4] = 0.0f; + light_vector[i*4+1] = 0.0f; + light_vector[i*4+2] = 0.0f; + light_vector[i*4+3] = 1.0f; + + ApplyMatrix(&light_vector[i*4], light[i]->matrix); + + light_vector[i*4] /= light_vector[i*4+2]; + light_vector[i*4+1] /= light_vector[i*4+2]; + + /*SIMD演算のため*/ + light_vector[i*4+2] *= -1; + light_vector[i*4+3] *= -1; + + } +} + +void +SceneGraphRoot::flip() +{ + // 前フレームで描画した SceneGraph は削除 + allRemove(sg_remove_list); + + // 前フレームに作られた SceneGraph は描画用に移行 + // 現フレームでの操作は以下の tree,list には適用されない + sg_draw_tree = sg_exec_tree; + sg_remove_list = sg_available_list; + + // 現フレームで新しく SceneGraph がコピーされるので初期化 + sg_exec_tree = NULL; + sg_available_list = NULL; +} + +void +SceneGraphRoot::allExecute(int screen_w, int screen_h) +{ + SceneGraphPtr list = sg_available_list; + + flip(); + + camera->move_execute(screen_w, screen_h); + camera->update(screen_w, screen_h); + + camera->children = NULL; + camera->lastChild = NULL; + + /*まずは全部動作させる*/ + while (list) { + + list->move_execute(screen_w, screen_h); + list->collision_check(screen_w, screen_h, list); + + list->frame++; + list = list->next; + } + + lightCalc(); + + if(sg_exec_tree != NULL) { + return; + } + + copyTree(sg_draw_tree, camera); + + // 現在、allExecute が終わった時点では + // camera->children が User SceneGraph の root になる + + /** + * NULL じゃなかったら、setSceneData が呼ばれてるから + * そっちを次の Scene にする + */ + + sg_exec_tree = camera->children; +} + +void +SceneGraphRoot::copyTree(SceneGraphPtr t, SceneGraphPtr cur_parent) +{ + // SceneGraphPtr t = sg_draw_tree; + + /*removeのflagをもとにtreeを形成*/ + while (t) { + SceneGraphPtr c = NULL; + if (!t->isRemoved()) { + c = t->clone(this->tmanager); + addNext(c); + cur_parent->addChild(c); + c->frame = t->frame; + /*親の回転、座標から、子の回転、座標を算出*/ + get_matrix(c->matrix, c->angle, c->xyz, cur_parent->matrix); + /*法線用の行列。Cameraの行列を抜いている(Cameraのコンストラクタで、単位行列にしている)*/ + get_matrix(c->real_matrix, c->angle, c->xyz, cur_parent->real_matrix); + //get_matrix(c->real_matrix, c->angle, c->xyz, camera->real_matrix); + + } + + if (t->children != NULL && c != NULL) { + cur_parent = c; + t = t->children; + } else if (t->brother != NULL) { + t = t->brother; + } else { + while (t) { + if (t->brother != NULL) { + t = t->brother; + break; + } else { + if (t->parent == NULL) { + t = NULL; + break; + } else { + cur_parent = cur_parent->parent; + t = t->parent; + } + } + } + } + } + +} + + +/* + ExecMove task の post func として呼んでやる +*/ +void +SceneGraphRoot::move_finish() +{ + list->collision_check(screen_w, screen_h, list); + + list->frame++; + //list = list->next; + + int light_num = 4; + for (int i = 0; i < light_num; i++) { + + get_matrix(light[i]->matrix, light[i]->angle, light[i]->xyz, camera->matrix); + + light_vector[i*4] = 0.0f; + light_vector[i*4+1] = 0.0f; + light_vector[i*4+2] = 0.0f; + light_vector[i*4+3] = 1.0f; + + ApplyMatrix(&light_vector[i*4], light[i]->matrix); + + light_vector[i*4] /= light_vector[i*4+2]; + light_vector[i*4+1] /= light_vector[i*4+2]; + + light_vector[i*4+2] *= -1; + light_vector[i*4+3] *= -1; + } + + //sgchange->viewer->light_xyz_stock = getLightVector(); +} + + +void +SceneGraphRoot::appTaskRegist(regist_func new_register) +{ + this->regist = new_register; +} + +void +SceneGraphRoot::regist_execute() +{ + (*regist)(this); +} + +void +SceneGraphRoot::allRemove(SceneGraphPtr list) +{ + SceneGraphPtr p = list; + + while (p) { + SceneGraphPtr p1 = p->next; + delete p; + p = p1; + cnt--; + } +} + +void +SceneGraphRoot::checkRemove() +{ + SceneGraphPtr p = sg_available_list; + SceneGraphPtr p1; + + while (p) { + p1 = p->next; + if (p->isRemoved()) { + sg_exec_tree = p->realRemoveFromTree(sg_exec_tree); + sg_available_list = p->realRemoveFromList(sg_available_list); + } + delete p; + p = p1; + } +} + +SceneGraphPtr +SceneGraphRoot::getExecuteSceneGraph() +{ + return sg_exec_tree; +} + + +void +printSceneGraph(SceneGraphPtr t) +{ + while (t) { + if (!t->isRemoved()) { + if (t->name) printf("name: %s ",t->name); + printf("x=%g y=%g z=%g\n",t->xyz[0],t->xyz[1],t->xyz[2]); + } + if (t->children != NULL) { + t = t->children; + } else if (t->brother != NULL) { + t = t->brother; + } else { + while (t) { + if (t->brother != NULL) { + t = t->brother; + break; + } else { + if (t->parent == NULL) { + t = NULL; + break; + } else { + t = t->parent; + } + } + } + } + } +} + +SceneGraphPtr +SceneGraphRoot::getDrawSceneGraph() +{ + return sg_draw_tree; +} + +void +SceneGraphRoot::updateControllerState() +{ + controller->check(); +} + +void +SceneGraphRoot::setSceneData(SceneGraphPtr sg) +{ + sg_exec_tree = sg; +} + +Pad* +SceneGraphRoot::getController() +{ + return controller; +} + +SceneGraphIteratorPtr +SceneGraphRoot::getIterator() +{ + iterator->set(sg_remove_list); + return iterator; +} + +SceneGraphIteratorPtr +SceneGraphRoot::getIterator(SceneGraphPtr list) +{ + iterator->set(list); + return iterator; +} + +CameraPtr +SceneGraphRoot::getCamera() +{ + return camera; +} + + +SceneGraphPtr +SceneGraphRoot::getLight(int id) +{ + + return light[id]; + +} + + +float* +SceneGraphRoot::getLightVector() +{ + return light_vector; +} + +int* +SceneGraphRoot::getLightSwitch() +{ + return light_switch; +} + +int +SceneGraphRoot::getLightSysSwitch() +{ + return light_sysswitch; +} + +void +SceneGraphRoot::OnLightSwitch(int id) +{ + light_switch[id] = 1; +} + +void +SceneGraphRoot::OffLightSwitch(int id) +{ + light_switch[id] = 0; +} + +void +SceneGraphRoot::OnLightSysSwitch() +{ + + light_sysswitch = 1; + +} + +void +SceneGraphRoot::OffLightSysSwitch() +{ + + light_sysswitch = 0; + +} + +void +SceneGraphRoot::task_array_init(int id, int task_num, int param, int inData_num, int outData_num) +{ + gtask_array = new GTaskArray; + gtask_array->init(id, task_num, param, inData_num, outData_num); +} + +void +SceneGraphRoot::create_task_array() +{ + gtask_array->create_task_array(this->tmanager); +} + +void +SceneGraphRoot::task_array_finish() +{ + gtask_array->finish(); +} + +void +SceneGraphRoot::set_gtask_array(int id, void *property, int size, PostFunction post_func) +{ + gtask_array->next_task_array(id); + + gtask_array->game_task->set_inData(0, property, size); + gtask_array->game_task->set_outData(0, property, size); + +} + +void +SceneGraphRoot::set_gtask_array(int id, void *property, void *pad, int size, PostFunction post_func) +{ + gtask_array->next_task_array(id); + + gtask_array->game_task->set_inData(0, property, size); + gtask_array->game_task->set_inData(1, pad, sizeof(Pad)); + gtask_array->game_task->set_outData(0, property, size); + +} + +void +SceneGraphRoot::set_game_task(int id, void *property, int size) +{ + HTask *task = sgroot->tmanager->create_task(id); + task->set_cpu(SPE_ANY); + task->add_inData(property, size); + task->add_outData(property, size); + task->spawn(); +} + +void +SceneGraphRoot::set_game_task(int id, void *property, void *pad, int size) +{ + HTask *task = sgroot->tmanager->create_task(id); + task->set_cpu(SPE_ANY); + task->add_inData(property, size); + task->add_inData(pad, sizeof(Pad)); + task->add_outData(property, size); + task->spawn(); +} + + +void +main_task_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) +{ + int size = node->property_size; + void *e = node->propertyptr; + int move = node->move_id; + SceneGraphRoot *sgroottmp = (SceneGraphRoot*)sgroot_; +/* + ObjPropertyPtr property = (ObjPropertyPtr)node->propertyptr; + node->xyz[0] = property->x; + node->xyz[1] = property->y; +*/ + sgroottmp->set_game_task(move, (void*)e, size); +} + +void +pad_task_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) +{ + int size = node->property_size; + void *e = node->propertyptr; + int move = node->move_id; + SceneGraphRoot *sgroottmp = (SceneGraphRoot*)sgroot_; + void *pad = (void*)sgroottmp->getController(); + +/* + ObjPropertyPtr property = (ObjPropertyPtr)node->propertyptr; + property->root = node; + node->xyz[0] = property->x; + node->xyz[1] = property->y; +*/ + + sgroottmp->set_game_task(move, (void*)e, pad, size); +} + +void +SceneGraphRoot::set_move_task(SceneGraphPtr node, int move, void *property, int size) +{ + node->move = main_task_move; + node->move_id = move; + node->propertyptr = property; + node->property_size = size; +} + +void +SceneGraphRoot::set_pad_task(SceneGraphPtr node, int move, void *property, int size) +{ + node->move = pad_task_move; + node->move_id = move; + node->propertyptr = property; + node->property_size = size; +} + +/* end */
--- a/Renderer/Engine/SceneGraphRoot.h Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/SceneGraphRoot.h Thu Jul 21 18:56:08 2011 +0900 @@ -88,6 +88,8 @@ * Functions */ /* User API */ + void createStringFont(TaskManager *manager, SceneGraphPtr root,char *string, int pixeles, int screen_w,int screen_h, Uint32 color); + void createFont(TaskManager *manager,char *font,int pixels,Uint32 color,char *filename, int len, char **obj_name); void createFromXMLfile(TaskManager *manager, const char *); void createFromXMLmemory(TaskManager *manager, SceneGraph * node, char *data, int len); SceneGraphPtr createSceneGraph(int id);
--- a/Renderer/Engine/TextureHash.cc Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/TextureHash.cc Thu Jul 21 18:56:08 2011 +0900 @@ -24,7 +24,7 @@ } int -TextureHash::hash_function(const char *key) +TextureHash::hash_function(const unsigned char *key) { //float value = 0.0; int value = 0; @@ -39,7 +39,7 @@ int TextureHash::hash_regist(const char* key, int &id) { - int hash = hash_function(key); + int hash = hash_function((const unsigned char*)key); for (int i = 0; ; i++) { if (table[hash].tx_id == -1) { table[hash].key = (char*)key; @@ -58,7 +58,7 @@ int TextureHash::sg_hash_regist(const char* key, int &id) { - int hash = hash_function(key); + int hash = hash_function((const unsigned char*)key); for (int i = 0; ; i++) { if (table[hash].tx_id == -1) { @@ -78,7 +78,7 @@ TextureHash::get_sgid(const char* key) { - int hash = hash_function(key); + int hash = hash_function((const unsigned char*)key); for (int i = 0; ; i++) { if (table[hash].tx_id == -1) { return -1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Engine/TextureHash.cc~ Thu Jul 21 18:56:08 2011 +0900 @@ -0,0 +1,92 @@ +#include <string.h> +#include <stdlib.h> +#include "TextureHash.h" + +TextureHash::TextureHash(void) +{ + id_count = 0; + int size = sizeof(hashtable)*TABLE_SIZE; +#if defined(__SPU__) || ! defined(HAS_POSIX_MEMALIGN) + table = (hashtable*)malloc(size); +#else + posix_memalign((void**)&table, 16, size); +#endif + + for (int i = 0; i < TABLE_SIZE; i++) { + table[i].tx_id = -1; + table[i].key = NULL; + } +} + +TextureHash::~TextureHash(void) +{ + free(table); +} + +int +TextureHash::hash_function(const char *key) +{ + //float value = 0.0; + int value = 0; + + for (int i = 0; key[i]; i++) { + value += key[i]*(i+1)*17+1; + } + + return value%TABLE_SIZE; +} + +int +TextureHash::hash_regist(const char* key, int &id) +{ + int hash = hash_function(key); + for (int i = 0; ; i++) { + if (table[hash].tx_id == -1) { + table[hash].key = (char*)key; + id = id_count++; + return -1; + + } else if (strcmp(key, table[hash].key) == 0 + && table[hash].tx_id != -1){ + id = table[hash].tx_id; + return 1; + } + hash = ((37*hash)^(11*i)) % TABLE_SIZE; + } +} + +int +TextureHash::sg_hash_regist(const char* key, int &id) +{ + int hash = hash_function(key); + + for (int i = 0; ; i++) { + if (table[hash].tx_id == -1) { + table[hash].key = (char*)key; + table[hash].tx_id = id; + return -1; + + } else if (strcmp(key, table[hash].key) == 0 + && table[hash].tx_id != -1){ + return table[hash].tx_id; + } + hash = ((37*hash)^(11*i)) % TABLE_SIZE; + } +} + +int +TextureHash::get_sgid(const char* key) +{ + + int hash = hash_function(key); + for (int i = 0; ; i++) { + if (table[hash].tx_id == -1) { + return -1; + + } else if (strcmp(key, table[hash].key) == 0 + && table[hash].tx_id != -1){ + return table[hash].tx_id; + } + hash = ((37*hash)^(11*i)) % TABLE_SIZE; + } +}
--- a/Renderer/Engine/TextureHash.h Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/TextureHash.h Thu Jul 21 18:56:08 2011 +0900 @@ -15,7 +15,7 @@ TextureHash(void); ~TextureHash(void); - int hash_function(const char* image_name); + int hash_function(const unsigned char* image_name); int hash_regist(const char* image_name, int &tx_id); int sg_hash_regist(const char* image_name, int &tx_id); int get_sgid(const char* key);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Engine/TextureHash.h~ Thu Jul 21 18:56:08 2011 +0900 @@ -0,0 +1,25 @@ +#ifndef INCLUDED_TEXTURE_HASH +#define INCLUDED_TEXTURE_HASH + +const int TABLE_SIZE = 9192; //8192 + 1000 + +struct hashtable{ + int tx_id; + char* key; +}; + +class TextureHash { +public: + int id_count; + hashtable *table; + + TextureHash(void); + ~TextureHash(void); + int hash_function(const char* image_name); + int hash_regist(const char* image_name, int &tx_id); + int sg_hash_regist(const char* image_name, int &tx_id); + int get_sgid(const char* key); + void remove(int id) { table[id].tx_id = -1; } +}; + +#endif
--- a/Renderer/Engine/polygon.cc Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/polygon.cc Thu Jul 21 18:56:08 2011 +0900 @@ -246,3 +246,127 @@ //cout << SDL_MapRGB(pf, red, green, blue) << endl; return SDL_MapRGB(pf, red, green, blue); } + +void Polygon::font_coordinate(int baseline, int row,int width) +{ + + //int count = size / 3; + + for (int i = 0; i < pp_num; i++) { + + TrianglePackPtr tri = pp[i].tri; + // TrianglePack の size のチェック + int tri_size = 2; + pp[i].info.size = tri_size; + + for (int j = 0; j < tri_size; j++) { + + tri[j].ver1.x = 0.0 ; + tri[j].ver1.y = 0.0 + baseline; + //tri[j].ver1.y = 0.0; + tri[j].ver1.z = 0.0; + + if(j < 1) + { + tri[j].ver2.x = 0.0 ; + tri[j].ver2.y = row +baseline; + //tri[j].ver2.y = row; + tri[j].ver2.z = 0.0; + }else{ + tri[j].ver2.x = width ; + tri[j].ver2.y = 0.0 +baseline; + //tri[j].ver2.y = 0.0; + tri[j].ver2.z = 0.0; + } + tri[j].ver3.x = width ; + tri[j].ver3.y =row +baseline; + //tri[j].ver3.y =row; + tri[j].ver3.z = 0.0; + + } + + } +} + +void Polygon::font_normal() +{ + + //テスト用 + float polygon_point[2][9] = { {0,0,1, 0,0,1, 0,0,1}, + {0,0,1, 0,0,1, 0,0,1} }; + + //int count = size / 3; + + for (int i = 0; i < pp_num; i++) { + + TrianglePackPtr tri = pp[i].tri; + // TrianglePack の size のチェック + int tri_size = 2; + pp[i].info.size = tri_size; + + for (int j = 0; j < tri_size; j++) { + + tri[j].normal1.x = polygon_point[j][0]; + tri[j].normal1.y = polygon_point[j][1]; + tri[j].normal1.z = polygon_point[j][2]; + + tri[j].normal2.x = polygon_point[j][3]; + tri[j].normal2.y = polygon_point[j][4]; + tri[j].normal2.z = polygon_point[j][5]; + + tri[j].normal3.x = polygon_point[j][6]; + tri[j].normal3.y = polygon_point[j][7]; + tri[j].normal3.z = polygon_point[j][8]; + + } + + } + +} + +void Polygon::font_model() +{ + //テスト用 + float polygon_point[3] = {0,0,0}; + + c_xyz[0] = polygon_point[0]; + c_xyz[1] = polygon_point[1]; + c_xyz[2] = polygon_point[2]; + +} + + +void Polygon::font_texture(float row,float width) +{ + float texture_point[2][7] = { {0,0, 0,1, 1,1}, + {0,0, 1,0, 1,1} }; + + for (int i = 0; i < pp_num; i++) { + + TrianglePackPtr tri = pp[i].tri; + // TrianglePack の size のチェック + int tri_size = 2; + pp[i].info.size = tri_size; + + for (int j = 0; j < tri_size; j++) { + + tri[j].ver1.tex_x = texture_point[j][0]; + tri[j].ver1.tex_y = texture_point[j][1]; + + tri[j].ver2.tex_x = texture_point[j][2]; + tri[j].ver2.tex_y = texture_point[j][3]; + + tri[j].ver3.tex_x = texture_point[j][4]; + tri[j].ver3.tex_y = texture_point[j][5]; + + + } + + + } + + /*if (count != 0) { + printf("miss pickup_texture size. diff size = %d\n", count); + }*/ + +}
--- a/Renderer/Engine/polygon.h Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/polygon.h Thu Jul 21 18:56:08 2011 +0900 @@ -62,6 +62,11 @@ void pickup_normal(char *cont); void pickup_model(char *cont); void pickup_texture(char *cont); + + void font_coordinate(int baseline, int row, int width); + void font_texture(float row,float width); + void font_normal(); + void font_model(); }; #endif
--- a/Renderer/Engine/viewer.h Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Engine/viewer.h Thu Jul 21 18:56:08 2011 +0900 @@ -108,6 +108,14 @@ // void setSceneData(SceneGraph *g); virtual void mainLoop(); + void createStringFont(SceneGraphPtr root, char *string, int pixels, int screen_w, int screen_h, Uint32 color) + { + sgroot -> createStringFont(manager, root, string, pixels, screen_w, screen_h, color); + } + void createFont(char *font,int pixels,Uint32 color, char *filename, int len, char **obj_name) + { + sgroot -> createFont(manager,font,pixels,color,filename, len, obj_name); + } void task_array_init(int id, int task_num, int param, int inData_num, int outData_num) { sgroot->task_array_init(id, task_num, param, inData_num, outData_num);
--- a/Renderer/Test/Makefile.macosx Thu Jul 14 00:27:19 2011 +0900 +++ b/Renderer/Test/Makefile.macosx Thu Jul 21 18:56:08 2011 +0900 @@ -2,8 +2,8 @@ LIBS += -lCerium -lFifoManager -CFLAGS += `sdl-config --cflags` `xml2-config --cflags` $(INCLUDE) -LIBS += `sdl-config --libs` `xml2-config --libs` -lSDL_image -Wl,-framework,OpenGL +CFLAGS += `sdl-config --cflags` `xml2-config --cflags` `freetype-config --cflags` $(INCLUDE) +LIBS += `sdl-config --libs` `xml2-config --libs` `freetype-config --libs` -lSDL_image -Wl,-framework,OpenGL .SUFFIXES: .proto .pb.o .pb.cc .cc .o .xml .xml.h .xml.cc .PRECIOUS: %.pb.cc @@ -13,10 +13,14 @@ %.pb.cc: $(PROTODIR)/%.proto $(PROTO) $(PROTOFLAGS) $< -ALL = ball_bound boss1_action direction gaplant ieshoot node panel universe untitled vacuum property_test send_linda dynamic writer chain_old SgRootChange viewer aquarium network init_aquarium test_linda +ALL = print_string ball_bound boss1_action direction gaplant ieshoot node panel universe untitled vacuum property_test send_linda dynamic writer chain_old SgRootChange viewer aquarium network init_aquarium test_linda all: $(ALL) +STR_OBJ = print_string.o +print_string : $(STR_OBJ) + $(CC) $(CFLAGS) -o $@ $? $(LIBS) + BALL_BOUND_OBJ = ball_bound.o ball_bound : $(BALL_BOUND_OBJ) $(CC) $(CFLAGS) -o $@ $? $(LIBS)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Test/print_string.cc Thu Jul 21 18:56:08 2011 +0900 @@ -0,0 +1,57 @@ +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include "SceneGraphRoot.h" +#include "MainLoop.h" +#include "print_string.h" + +MainLoopPtr +print_string::init(Viewer *sgroot, int screen_w, int screen_h) +{ + SceneGraphPtr root; + + //SceneGraphPtr test[10]; + char *print_message = "aあ区"; + SceneGraphPtr light = sgroot->getLight(0); + sgroot->OnLightSwitch(0); + light->xyz[0] = screen_w / 2; + light->xyz[1] = screen_h / 2; + light->xyz[2] = -100; + + root = sgroot->createSceneGraph(); + + //display_string(sgroot,root,print_message,80,screen_w,screen_h,0x00ff00ff); + sgroot->createStringFont(root,print_message,80,700,300,0x00ff00ff); + sgroot->setSceneData(root); + + return sgroot; +} + + +extern Application * +application() { + return new print_string(); +} + +const char *usr_help_str = "Usage: ./test_nogl [OPTION]\n"; + +extern int init(TaskManager *manager, int argc, char *argv[]); +extern void task_initialize(); +static void TMend(TaskManager *manager); + +int +TMmain(TaskManager *manager, int argc, char *argv[]) +{ + task_initialize(); + manager->set_TMend(TMend); + return init(manager, argc, argv); + +} + +void +TMend(TaskManager *manager) +{ + printf("test_nogl end\n"); +} + +/* end */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Test/print_string.cc~ Thu Jul 21 18:56:08 2011 +0900 @@ -0,0 +1,57 @@ +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include "SceneGraphRoot.h" +#include "MainLoop.h" +#include "print_string.h" + +MainLoopPtr +print_string::init(Viewer *sgroot, int screen_w, int screen_h) +{ + SceneGraphPtr root; + + //SceneGraphPtr test[10]; + char *print_message = "aあ区"; + SceneGraphPtr light = sgroot->getLight(0); + sgroot->OnLightSwitch(0); + light->xyz[0] = screen_w / 2; + light->xyz[1] = screen_h / 2; + light->xyz[2] = -100; + + root = sgroot->createSceneGraph(); + + //display_string(sgroot,root,print_message,80,screen_w,screen_h,0x00ff00ff); + sgroot->createStringFont(root,print_message,80,screen_w,screen_h,0x00ff00ff); + sgroot->setSceneData(root); + + return sgroot; +} + + +extern Application * +application() { + return new print_string(); +} + +const char *usr_help_str = "Usage: ./test_nogl [OPTION]\n"; + +extern int init(TaskManager *manager, int argc, char *argv[]); +extern void task_initialize(); +static void TMend(TaskManager *manager); + +int +TMmain(TaskManager *manager, int argc, char *argv[]) +{ + task_initialize(); + manager->set_TMend(TMend); + return init(manager, argc, argv); + +} + +void +TMend(TaskManager *manager) +{ + printf("test_nogl end\n"); +} + +/* end */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Renderer/Test/print_string.h Thu Jul 21 18:56:08 2011 +0900 @@ -0,0 +1,10 @@ +#include <math.h> +#include <stdlib.h> +#include "SceneGraphRoot.h" +#include "Application.h" +#include "MainLoop.h" + +class print_string : public Application { + + MainLoopPtr init(Viewer *viewer, int screen_w, int screen_h); +};