changeset 1205:b8adf4e95e96 draft

add createStringFont()
author Takao YONAMINE <e095763@ie.u-ryukyu.ac.jp>
date Thu, 21 Jul 2011 18:56:08 +0900
parents 726098b89619
children a8ab91f49cac
files Renderer/Engine/Makefile.macosx Renderer/Engine/SceneGraph.cc Renderer/Engine/SceneGraph.cc~ Renderer/Engine/SceneGraph.h Renderer/Engine/SceneGraphRoot.cc Renderer/Engine/SceneGraphRoot.cc~ Renderer/Engine/SceneGraphRoot.h Renderer/Engine/TextureHash.cc Renderer/Engine/TextureHash.cc~ Renderer/Engine/TextureHash.h Renderer/Engine/TextureHash.h~ Renderer/Engine/polygon.cc Renderer/Engine/polygon.h Renderer/Engine/viewer.h Renderer/Test/Makefile.macosx Renderer/Test/SgRootChange Renderer/Test/ball_bound Renderer/Test/boss1_action Renderer/Test/chain_old Renderer/Test/direction Renderer/Test/dynamic Renderer/Test/gaplant Renderer/Test/ieshoot Renderer/Test/node Renderer/Test/panel Renderer/Test/print_string Renderer/Test/print_string.cc Renderer/Test/print_string.cc~ Renderer/Test/print_string.h Renderer/Test/property_test Renderer/Test/send_linda Renderer/Test/universe Renderer/Test/untitled Renderer/Test/vacuum Renderer/Test/viewer Renderer/Test/writer
diffstat 36 files changed, 2554 insertions(+), 10 deletions(-) [+]
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)
Binary file Renderer/Test/SgRootChange has changed
Binary file Renderer/Test/ball_bound has changed
Binary file Renderer/Test/boss1_action has changed
Binary file Renderer/Test/chain_old has changed
Binary file Renderer/Test/direction has changed
Binary file Renderer/Test/dynamic has changed
Binary file Renderer/Test/gaplant has changed
Binary file Renderer/Test/ieshoot has changed
Binary file Renderer/Test/node has changed
Binary file Renderer/Test/panel has changed
Binary file Renderer/Test/print_string has changed
--- /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);
+};
Binary file Renderer/Test/property_test has changed
Binary file Renderer/Test/send_linda has changed
Binary file Renderer/Test/universe has changed
Binary file Renderer/Test/untitled has changed
Binary file Renderer/Test/vacuum has changed
Binary file Renderer/Test/viewer has changed
Binary file Renderer/Test/writer has changed