static void _load_part_pvr(struct dtex_import_stream* is, struct dtex_cf_node* node) { struct dtex_rect* dst_pos = &node->dst_rect; assert(IS_4TIMES(dst_pos->xmin) && IS_4TIMES(dst_pos->ymin)); if (!node->dst_tex->ud) { node->dst_tex->ud = dtex_pvr_init_blank(node->dst_tex->tex->width); } int w, h; _load_pvr_header(is, &w, &h); assert(IS_POT(w) && IS_POT(h) && w == dst_pos->xmax - dst_pos->xmin && h == dst_pos->ymax - dst_pos->ymin); int grid_x = dst_pos->xmin >> 2, grid_y = dst_pos->ymin >> 2; int grid_w = w >> 2, grid_h = h >> 2; const uint8_t* src_data = (const uint8_t*)(is->stream); uint8_t* dst_data = (uint8_t*)(node->dst_tex->ud); for (int y = 0; y < grid_h; ++y) { for (int x = 0; x < grid_w; ++x) { int idx_src = dtex_pvr_get_morton_number(x, y); int idx_dst = dtex_pvr_get_morton_number(grid_x + x, grid_y + y); assert(idx_dst < node->dst_tex->tex->width * node->dst_tex->tex->height / 16); int64_t* src = (int64_t*)src_data + idx_src; int64_t* dst = (int64_t*)dst_data + idx_dst; memcpy(dst, src, sizeof(int64_t)); } } }
static void _load_part_etc2(struct dtex_import_stream* is, struct dtex_cf_node* node) { struct dtex_rect* dst_pos = &node->dst_rect; assert(IS_4TIMES(dst_pos->xmin) && IS_4TIMES(dst_pos->ymin)); if (!node->dst_tex->ud) { node->dst_tex->ud = dtex_etc2_init_blank(node->dst_tex->tex->width); } int w, h; _load_etc2_header(is, &w, &h); assert(IS_POT(w) && IS_POT(h) && w == dst_pos->xmax - dst_pos->xmin && h == dst_pos->ymax - dst_pos->ymin); int grid_x = dst_pos->xmin >> 2, grid_y = dst_pos->ymin >> 2; int grid_w = w >> 2, grid_h = h >> 2; const uint8_t* src_data = (const uint8_t*)(is->stream); uint8_t* dst_data = (uint8_t*)(node->dst_tex->ud); const int grid_sz = sizeof(uint8_t) * 8 * 2; const int large_grid_w = node->dst_tex->tex->width >> 2; for (int y = 0; y < grid_h; ++y) { for (int x = 0; x < grid_w; ++x) { int idx_src = x + grid_w * y; int idx_dst = grid_x + x + large_grid_w * (grid_y + y); assert(idx_dst < node->dst_tex->tex->width * node->dst_tex->tex->height / 16); memcpy(dst_data + idx_dst * grid_sz, src_data + idx_src * grid_sz, grid_sz); } } }
const char * texture_load(int id, int pixel_format, int pixel_width, int pixel_height, void *data) { if (id >= MAX_TEXTURE) { return "Too many texture"; } struct texture * tex = &POOL.tex[id]; if (id >= POOL.count) { POOL.count = id + 1; } tex->width = pixel_width; tex->height = pixel_height; tex->invw = 1.0f / (float)pixel_width; tex->invh = 1.0f / (float)pixel_height; if (tex->id == 0) { glGenTextures(1, &tex->id); } if (data == NULL) { // empty texture return NULL; } if ((pixel_format == Texture2DPixelFormat_RGBA8888) || ( IS_POT(pixel_width) && IS_POT(pixel_height))) { glPixelStorei(GL_UNPACK_ALIGNMENT,4); } else { glPixelStorei(GL_UNPACK_ALIGNMENT,1); } glActiveTexture(GL_TEXTURE0); shader_texture(tex->id); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); switch(pixel_format) { case Texture2DPixelFormat_RGBA8888: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); break; case Texture2DPixelFormat_RGB888: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); break; case Texture2DPixelFormat_RGBA4444: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data); break; case Texture2DPixelFormat_RGB565: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data); break; case Texture2DPixelFormat_A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, (GLsizei)pixel_width, (GLsizei)pixel_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); break; default: glDeleteTextures(1,&tex->id); tex->id = 0; return "Invalid pixel format"; } return NULL; }