TEXLoader::IoStatus TEXLoader::Save(const Texture& texture, bool compressed) { if (texture.GetColorMap(0) == 0) { return kStatusMissingColormapError; } // Calculate log2 of width and height. int width = 0; int height = 0; int log2_width = 0; int log2_height = 0; if (texture.IsCubeMap() == false) { width = texture.GetColorMap(0)->GetWidth(); height = texture.GetColorMap(0)->GetHeight(); } else { width = texture.GetCubeMapPosX(0)->GetWidth(); height = texture.GetCubeMapPosX(0)->GetHeight(); } while ((1 << log2_width) < width) { log2_width++; } while ((1 << log2_height) < height) { log2_height++; } // Prepare file header. FileHeader file_header; file_header.tex_magic_[0] = 'T'; file_header.tex_magic_[1] = 'T'; file_header.tex_magic_[2] = 'E'; file_header.tex_magic_[3] = 'X'; file_header.version_ = 1; file_header.data_offset_ = 16; // Size of file header. file_header.dimension_powers_ = (uint8)((log2_height << 4) | log2_width); file_header.compression_flag_ = compressed == true ? 1 : 0; file_header.map_flags_ = 0; if (texture.IsCubeMap() == false) { if (texture.GetAlphaMap(0) != 0 || texture.GetColorMap(0)->GetBitDepth() == Canvas::kBitdepth32Bit) file_header.map_flags_ |= kAlphaMap; if (texture.GetNormalMap(0) != 0) file_header.map_flags_ |= kNormalMap; if (texture.GetSpecularMap(0) != 0) file_header.map_flags_ |= kSpecularMap; } else { file_header.map_flags_ = kCubeMap; } // Write the file header. save_file_->WriteData(file_header.tex_magic_, 4); save_file_->Write(file_header.version_); save_file_->Write(file_header.data_offset_); save_file_->Write(file_header.dimension_powers_); save_file_->Write(file_header.compression_flag_); save_file_->Write(file_header.map_flags_); int num_levels = texture.GetNumMipMapLevels(); if (texture.IsCubeMap() == false) { int i; for (i = 0; i < num_levels; i++) { if (texture.GetColorMap(i)->GetBitDepth() != Canvas::kBitdepth24Bit) { Canvas temp(*texture.GetColorMap(i), true); temp.ConvertBitDepth(Canvas::kBitdepth24Bit); if (i < (num_levels - 2) && compressed == true) WriteJpeg(temp); else save_file_->WriteData(temp.GetBuffer(), temp.GetBufferByteSize()); } else { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetColorMap(i)); else save_file_->WriteData(texture.GetColorMap(i)->GetBuffer(), texture.GetColorMap(i)->GetBufferByteSize()); } } if (texture.GetAlphaMap(0) != 0) { for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetAlphaMap(i)); else save_file_->WriteData(texture.GetAlphaMap(i)->GetBuffer(), texture.GetAlphaMap(i)->GetBufferByteSize()); } } else if(texture.GetColorMap(0)->GetBitDepth() == Canvas::kBitdepth32Bit) { for (i = 0; i < texture.GetNumMipMapLevels(); i++) { Canvas alpha_map; texture.GetColorMap(i)->GetAlphaChannel(alpha_map); if (i < (num_levels - 2) && compressed == true) WriteJpeg(alpha_map); else save_file_->WriteData(alpha_map.GetBuffer(), alpha_map.GetBufferByteSize()); } } if (texture.GetNormalMap(0) != 0) { for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetNormalMap(i)); else save_file_->WriteData(texture.GetNormalMap(i)->GetBuffer(), texture.GetNormalMap(i)->GetBufferByteSize()); } } if (texture.GetSpecularMap(0) != 0) { for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetSpecularMap(i)); else save_file_->WriteData(texture.GetSpecularMap(i)->GetBuffer(), texture.GetSpecularMap(i)->GetBufferByteSize()); } } } else { int i; for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetCubeMapPosX(i)); else save_file_->WriteData(texture.GetCubeMapPosX(i)->GetBuffer(), texture.GetCubeMapPosX(i)->GetBufferByteSize()); } for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetCubeMapNegX(i)); else save_file_->WriteData(texture.GetCubeMapNegX(i)->GetBuffer(), texture.GetCubeMapNegX(i)->GetBufferByteSize()); } for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetCubeMapPosY(i)); else save_file_->WriteData(texture.GetCubeMapPosY(i)->GetBuffer(), texture.GetCubeMapPosY(i)->GetBufferByteSize()); } for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetCubeMapNegY(i)); else save_file_->WriteData(texture.GetCubeMapNegY(i)->GetBuffer(), texture.GetCubeMapNegY(i)->GetBufferByteSize()); } for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetCubeMapPosZ(i)); else save_file_->WriteData(texture.GetCubeMapPosZ(i)->GetBuffer(), texture.GetCubeMapPosZ(i)->GetBufferByteSize()); } for (i = 0; i < texture.GetNumMipMapLevels(); i++) { if (i < (num_levels - 2) && compressed == true) WriteJpeg(*texture.GetCubeMapNegZ(i)); else save_file_->WriteData(texture.GetCubeMapNegZ(i)->GetBuffer(), texture.GetCubeMapNegZ(i)->GetBufferByteSize()); } } save_file_->Close(); return kStatusSuccess; }