Пример #1
0
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;
}