Mercurial > hg > Game > Cerium
changeset 1049:91500a6c4def draft
non 2^n texture tapestry generation.
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 08 Dec 2010 13:06:18 +0900 |
parents | 5e62924bd7d9 |
children | 294bc9364bee |
files | Renderer/Engine/SceneGraph.cc Renderer/Engine/sys.h |
diffstat | 2 files changed, 36 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/Renderer/Engine/SceneGraph.cc Wed Dec 08 06:22:15 2010 +0900 +++ b/Renderer/Engine/SceneGraph.cc Wed Dec 08 13:06:18 2010 +0900 @@ -3,6 +3,7 @@ #include <SDL_opengl.h> #include <SDL_image.h> #include <libxml/parser.h> +#include <string.h> #include "SceneGraph.h" #include "xml.h" #include "sys.h" @@ -60,24 +61,38 @@ * @param[in] scale テクスチャの最大縮小率 (= 2^n) * @return (1) のアドレス */ + + +uint32 white[256] __attribute__((aligned(16))); + static uint32* -makeTapestry(TaskManager *manager, int tex_w, int tex_h, uint32 *tex_src, +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! + memset_pattern4(white,&pattern,256); + return white; + } - int t = 0; - int diff = TEXTURE_SPLIT_PIXEL; - int p_diff = 1; + uint32 t = 0; + uint32 diff = TEXTURE_SPLIT_PIXEL; + uint32 p_diff = 1; uint32 *tex_dest = (uint32*)manager->allocate(sizeof(int)*all_pixel_num); + uint32 alpha = SDL_BYTEORDER == SDL_LIL_ENDIAN? 0xff000000 : 0xff; /* OpenGL RGBA masks */ + while (scale_cnt) { - for (int y = 0; y < tex_h; y += diff) { - for (int x = 0; x < tex_w; x += diff) { - for (int j = 0; j < diff; j += p_diff) { - for (int i = 0; i < diff; i += p_diff) { - tex_dest[t++] - = tex_src[(x+i) + tex_w*(y+j)]; + // 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_h && y+j<=tex_w) ? tex_src[(x+i) + tex_w*(y+j)]: alpha; } } } @@ -496,20 +511,21 @@ * 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 */ - //if (tex_w!=power_of_two(tex_w)) nw = tex_w = power_of_two(tex_w)/2; - //if (tex_h!=power_of_two(tex_h)) nh = tex_h = power_of_two(tex_h)/2; - while (tex_w % TEXTURE_SPLIT_PIXEL == 0 && - tex_h % TEXTURE_SPLIT_PIXEL == 0) { - all_pixel_num += tex_w*tex_h; + 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; - // scale==0 means broken texture + scale >>= 1; // 必ず 1 以上になる tapestry = makeTapestry(manager, texture_image->w, texture_image->h, (uint32*)texture_image->pixels,
--- a/Renderer/Engine/sys.h Wed Dec 08 06:22:15 2010 +0900 +++ b/Renderer/Engine/sys.h Wed Dec 08 13:06:18 2010 +0900 @@ -23,5 +23,7 @@ void ApplyMatrix(float *v1, float *v2); void ScaleMatrix(float *m, float v); void ScaleMatrixXY(float *m, float sx,float sy); +static inline unsigned long align(unsigned long x,unsigned long alig) { return ((x+(alig-1))&~(alig-1)); } + #endif