newly Loader code of Texture
This commit is contained in:
parent
926802619f
commit
9d0ae0a071
2
CMCore
2
CMCore
@ -1 +1 @@
|
||||
Subproject commit 463eb1dd7eb84ba9e3ed2e4cb1180a7c10186a7d
|
||||
Subproject commit 1cefb338da8887ceaf800aecc9e1bc24dee63e8c
|
@ -50,3 +50,4 @@ CreateProject(15.OffscreenRender OffscreenRender.cpp)
|
||||
CreateProject(16.DeferredRenderMultiCmdBuffer DeferredRenderMultiCmdBuffer.cpp)
|
||||
#CreateProject(14.AutoMaterial auto_material.cpp)
|
||||
|
||||
CreateProject(17.Cubemap Cubemap.cpp)
|
@ -2,7 +2,7 @@
|
||||
// 该示例使用TileData,演示多个tile图片在一张纹理上
|
||||
|
||||
#include<hgl/type/StringList.h>
|
||||
#include<hgl/graph/TextureLoader.h>
|
||||
#include<hgl/graph/Bitmap2DLoader.h>
|
||||
#include<hgl/graph/TileData.h>
|
||||
|
||||
#include"VulkanAppFramework.h"
|
||||
|
32
inc/hgl/graph/Bitmap2DLoader.h
Normal file
32
inc/hgl/graph/Bitmap2DLoader.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef HGL_GRAPH_BITMAP2D_LOADER_INCLUDE
|
||||
#define HGL_GRAPH_BITMAP2D_LOADER_INCLUDE
|
||||
|
||||
#include<hgl/graph/TextureLoader.h>
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
/**
|
||||
* 2Dλͼ¼ÓÔØ
|
||||
*/
|
||||
class Bitmap2DLoader:public Texture2DLoader
|
||||
{
|
||||
protected:
|
||||
|
||||
BitmapData *bmp=nullptr;
|
||||
|
||||
public:
|
||||
|
||||
using Texture2DLoader::Texture2DLoader;
|
||||
~Bitmap2DLoader();
|
||||
|
||||
void *OnBegin(uint32 total_bytes) override;
|
||||
void OnEnd() override {}
|
||||
|
||||
BitmapData *GetBitmap();
|
||||
};//class Bitmap2DLoader
|
||||
|
||||
BitmapData *LoadBitmapFromFile(const OSString &filename);
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
#endif//HGL_GRAPH_BITMAP2D_LOADER_INCLUDE
|
@ -27,90 +27,124 @@ namespace hgl
|
||||
constexpr uint32 CompressFormatCount=sizeof(CompressFormatList)/sizeof(VkFormat);
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct Tex2DFileHeader
|
||||
{
|
||||
uint8 id[6]; ///<Tex2D\x1A
|
||||
uint8 version; ///<必须为3
|
||||
uint8 mipmaps;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint8 channels;
|
||||
|
||||
public:
|
||||
|
||||
const uint pixel_count()const{return width*height;}
|
||||
};//struct Tex2DFileHeader
|
||||
|
||||
struct TexPixelFormat
|
||||
{
|
||||
char colors[4];
|
||||
uint8 bits[4];
|
||||
uint8 datatype;
|
||||
|
||||
public:
|
||||
|
||||
const uint pixel_bits()const{return bits[0]+bits[1]+bits[2]+bits[3];}
|
||||
const uint pixel_bytes()const{return pixel_bits()>>3;}
|
||||
};//struct TexPixelFormat
|
||||
#pragma pack(pop)
|
||||
|
||||
/**
|
||||
* 2D纹理加载器
|
||||
*/
|
||||
class Texture2DLoader
|
||||
{
|
||||
protected:
|
||||
|
||||
Tex2DFileHeader file_header;
|
||||
uint8 channels; //0: compress 1/2/3/4:normal
|
||||
|
||||
union
|
||||
{
|
||||
TexPixelFormat pixel_format;
|
||||
uint16 compress_format;
|
||||
struct
|
||||
{
|
||||
char colors[4];
|
||||
uint8 bits[4];
|
||||
uint8 datatype;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
uint16 compress_format;
|
||||
};
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
const uint pixel_bits()const
|
||||
{
|
||||
return channels ?bits[0]+bits[1]+bits[2]+bits[3]
|
||||
:CompressFormatBits[compress_format];
|
||||
}
|
||||
};//struct TexPixelFormat
|
||||
|
||||
constexpr uint TexPixelFormatLength=sizeof(TexPixelFormat);
|
||||
|
||||
struct alignas(8) TextureFileHeader
|
||||
{
|
||||
uint8 id_str[8]; ///<Texture\x1A
|
||||
uint8 version; ///<必须为0
|
||||
uint8 type; ///<贴图类型,等同于VkImageViewType
|
||||
|
||||
union
|
||||
{
|
||||
uint32 length; ///<长(1D纹理用)
|
||||
uint32 width; ///<宽(2D/Cube纹理用)
|
||||
};
|
||||
|
||||
uint32 height; ///<高(2D/3D/Cube纹理用)
|
||||
|
||||
union
|
||||
{
|
||||
uint32 depth; ///<深度(3D纹理用)
|
||||
uint32 layers; ///<层数(Arrays纹理用)
|
||||
};
|
||||
|
||||
TexPixelFormat pixel_format; ///<象素格式
|
||||
uint8 mipmaps; ///<mipmaps
|
||||
};
|
||||
|
||||
constexpr uint TextureFileHeaderLength=sizeof(TextureFileHeader); //GPUBuffer内需要64位8字节对齐,如果此值不对齐,请想办法填0
|
||||
#pragma pack(pop)
|
||||
|
||||
const uint32 ComputeMipmapBytes(uint32 length,uint32 bytes);
|
||||
const uint32 ComputeMipmapBytes(uint32 width,uint32 height,uint32 bytes);
|
||||
const uint32 ComputeMipmapBytes(uint32 width,uint32 height,uint32 depth,uint32 bytes);
|
||||
|
||||
class TextureLoader
|
||||
{
|
||||
protected:
|
||||
|
||||
VkImageViewType type;
|
||||
|
||||
TextureFileHeader file_header;
|
||||
|
||||
VkFormat format;
|
||||
|
||||
uint32 mipmap_zero_total_bytes; ///< 0 级mipmaps单个图象的总字节数
|
||||
uint32 total_bytes; ///<总字节数
|
||||
|
||||
protected:
|
||||
|
||||
uint32 mipmap_zero_total_bytes;
|
||||
virtual uint32 GetPixelsCount()const=0;
|
||||
virtual uint32 GetImageCount()const=0; ///<每个级别的图象数量
|
||||
virtual uint32 GetTotalBytes()const=0; ///<计算总字节数
|
||||
|
||||
protected:
|
||||
|
||||
uint32 ComputeTotalBytes();
|
||||
|
||||
virtual void *OnBegin(uint32)=0;
|
||||
virtual void OnEnd()=0;
|
||||
virtual void OnError(){}
|
||||
|
||||
public:
|
||||
|
||||
const Tex2DFileHeader *GetFileHeader()const{return &file_header;}
|
||||
TextureLoader(const VkImageViewType &ivt){type=ivt;}
|
||||
|
||||
public:
|
||||
virtual bool Load(io::InputStream *);
|
||||
bool Load(const OSString &filename);
|
||||
};//class TextureLoader
|
||||
|
||||
virtual ~Texture2DLoader()=default;
|
||||
|
||||
bool Load(io::InputStream *is);
|
||||
bool Load(const OSString &filename);
|
||||
};//class Texture2DLoader
|
||||
|
||||
/**
|
||||
* 2D位图加载
|
||||
* 2D纹理加载器
|
||||
*/
|
||||
class Bitmap2DLoader:public Texture2DLoader
|
||||
class Texture2DLoader:public TextureLoader
|
||||
{
|
||||
protected:
|
||||
protected: // override functions
|
||||
|
||||
BitmapData *bmp=nullptr;
|
||||
uint32 GetPixelsCount()const override{return file_header.width*file_header.height;}
|
||||
uint32 GetImageCount()const override{return 1;}
|
||||
uint32 GetTotalBytes()const override
|
||||
{
|
||||
if(file_header.mipmaps<=1)
|
||||
return mipmap_zero_total_bytes;
|
||||
else
|
||||
return ComputeMipmapBytes( file_header.width,
|
||||
file_header.height,
|
||||
mipmap_zero_total_bytes);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
~Bitmap2DLoader();
|
||||
|
||||
void *OnBegin(uint32 total_bytes) override;
|
||||
void OnEnd() override {}
|
||||
|
||||
BitmapData *GetBitmap();
|
||||
};//class Bitmap2DLoader
|
||||
|
||||
BitmapData *LoadBitmapFromFile(const OSString &filename);
|
||||
Texture2DLoader():TextureLoader(VK_IMAGE_VIEW_TYPE_2D){}
|
||||
virtual ~Texture2DLoader()=default;
|
||||
};//class Texture2DLoader
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
||||
#endif//HGL_GRAPH_TEXTURE_LOADER_INCLUDE
|
||||
|
44
src/SceneGraph/Bitmap2DLoader.cpp
Normal file
44
src/SceneGraph/Bitmap2DLoader.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include<hgl/graph/Bitmap2DLoader.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
Bitmap2DLoader::~Bitmap2DLoader()
|
||||
{
|
||||
SAFE_CLEAR(bmp);
|
||||
}
|
||||
|
||||
void *Bitmap2DLoader::OnBegin(uint32 total_bytes)
|
||||
{
|
||||
SAFE_CLEAR(bmp);
|
||||
|
||||
bmp=new BitmapData;
|
||||
|
||||
bmp->width =file_header.width;
|
||||
bmp->height =file_header.height;
|
||||
bmp->total_bytes=total_bytes;
|
||||
|
||||
bmp->data=new char[total_bytes];
|
||||
|
||||
return bmp->data;
|
||||
}
|
||||
|
||||
BitmapData *Bitmap2DLoader::GetBitmap()
|
||||
{
|
||||
BitmapData *result=bmp;
|
||||
bmp=nullptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
BitmapData *LoadBitmapFromFile(const OSString &filename)
|
||||
{
|
||||
Bitmap2DLoader loader;
|
||||
|
||||
if(!loader.Load(filename))
|
||||
return(nullptr);
|
||||
|
||||
return loader.GetBitmap();
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
@ -1,7 +1,9 @@
|
||||
set(SG_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph)
|
||||
|
||||
SET(SG_TEXTURE_SOURCE ${SG_INCLUDE_PATH}/TextureLoader.h
|
||||
Texture2DLoader.cpp)
|
||||
${SG_INCLUDE_PATH}/Bitmap2DLoader.h
|
||||
TextureLoader.cpp
|
||||
Bitmap2DLoader.cpp)
|
||||
|
||||
SOURCE_GROUP("Texture" FILES ${SG_TEXTURE_SOURCE})
|
||||
|
||||
|
@ -1,147 +0,0 @@
|
||||
#include<hgl/graph/TextureLoader.h>
|
||||
#include<hgl/graph/Bitmap.h>
|
||||
#include<hgl/io/FileInputStream.h>
|
||||
#include<hgl/log/LogInfo.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
uint32 Texture2DLoader::ComputeTotalBytes()
|
||||
{
|
||||
uint32 pixel_bits;
|
||||
uint32 bytes;
|
||||
|
||||
if(file_header.channels==0)
|
||||
{
|
||||
if(compress_format<0||compress_format>=CompressFormatCount)
|
||||
return(0);
|
||||
|
||||
pixel_bits=CompressFormatBits[compress_format];
|
||||
}
|
||||
else
|
||||
{
|
||||
pixel_bits=pixel_format.pixel_bits();
|
||||
}
|
||||
|
||||
bytes=(pixel_bits*file_header.pixel_count())>>3;
|
||||
|
||||
mipmap_zero_total_bytes=bytes;
|
||||
|
||||
if(file_header.mipmaps<=1)
|
||||
return bytes;
|
||||
|
||||
uint32 total=0;
|
||||
|
||||
uint32 w=file_header.width;
|
||||
uint32 h=file_header.height;
|
||||
|
||||
while(w>=1&&h>=1)
|
||||
{
|
||||
if(bytes<8)
|
||||
total+=8;
|
||||
else
|
||||
total+=bytes;
|
||||
|
||||
if(w==1&&h==1)break;
|
||||
|
||||
if(w>1){w>>=1;bytes>>=1;}
|
||||
if(h>1){h>>=1;bytes>>=1;}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
bool Texture2DLoader::Load(io::InputStream *is)
|
||||
{
|
||||
if(!is)return(false);
|
||||
|
||||
if(is->Read(&file_header,sizeof(Tex2DFileHeader))!=sizeof(Tex2DFileHeader))
|
||||
return(false);
|
||||
|
||||
if(file_header.version!=3)
|
||||
return(false);
|
||||
|
||||
if(file_header.channels==0) //压缩格式
|
||||
{
|
||||
if(is->Read(&compress_format,sizeof(uint16))!=sizeof(uint16))
|
||||
return(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is->Read(&pixel_format,sizeof(TexPixelFormat))!=sizeof(TexPixelFormat))
|
||||
return(false);
|
||||
}
|
||||
|
||||
const uint32 total_bytes=ComputeTotalBytes();
|
||||
|
||||
if(is->Available()<total_bytes)
|
||||
return(false);
|
||||
|
||||
void *ptr=OnBegin(total_bytes);
|
||||
|
||||
if(!ptr)
|
||||
return(false);
|
||||
|
||||
if(is->Read(ptr,total_bytes)!=total_bytes)
|
||||
OnError();
|
||||
|
||||
OnEnd();
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool Texture2DLoader::Load(const OSString &filename)
|
||||
{
|
||||
io::OpenFileInputStream fis(filename);
|
||||
|
||||
if(!fis)
|
||||
{
|
||||
LOG_ERROR(OS_TEXT("[ERROR] open texture file<")+filename+OS_TEXT("> failed."));
|
||||
return(false);
|
||||
}
|
||||
|
||||
return this->Load(&fis);
|
||||
}
|
||||
}//namespace graph
|
||||
|
||||
namespace graph
|
||||
{
|
||||
Bitmap2DLoader::~Bitmap2DLoader()
|
||||
{
|
||||
SAFE_CLEAR(bmp);
|
||||
}
|
||||
|
||||
void *Bitmap2DLoader::OnBegin(uint32 total_bytes)
|
||||
{
|
||||
SAFE_CLEAR(bmp);
|
||||
|
||||
bmp=new BitmapData;
|
||||
|
||||
bmp->width =file_header.width;
|
||||
bmp->height =file_header.height;
|
||||
bmp->total_bytes=total_bytes;
|
||||
|
||||
bmp->data=new char[total_bytes];
|
||||
|
||||
return bmp->data;
|
||||
}
|
||||
|
||||
BitmapData *Bitmap2DLoader::GetBitmap()
|
||||
{
|
||||
BitmapData *result=bmp;
|
||||
bmp=nullptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
BitmapData *LoadBitmapFromFile(const OSString &filename)
|
||||
{
|
||||
Bitmap2DLoader loader;
|
||||
|
||||
if(!loader.Load(filename))
|
||||
return(nullptr);
|
||||
|
||||
return loader.GetBitmap();
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
216
src/SceneGraph/TextureLoader.cpp
Normal file
216
src/SceneGraph/TextureLoader.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
#include<hgl/graph/TextureLoader.h>
|
||||
#include<hgl/io/FileInputStream.h>
|
||||
#include<hgl/log/LogInfo.h>
|
||||
|
||||
namespace hgl
|
||||
{
|
||||
namespace graph
|
||||
{
|
||||
const uint32 ComputeMipmapBytes(uint32 length,uint32 bytes)
|
||||
{
|
||||
uint32 total=0;
|
||||
|
||||
while(length>=1)
|
||||
{
|
||||
if(bytes<8)
|
||||
total+=8;
|
||||
else
|
||||
total+=bytes;
|
||||
|
||||
if(length==1)break;
|
||||
|
||||
if(length>1){length>>=1;bytes>>=1;}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
const uint32 ComputeMipmapBytes(uint32 width,uint32 height,uint32 bytes)
|
||||
{
|
||||
uint32 total=0;
|
||||
|
||||
while(width>=1&&height>=1)
|
||||
{
|
||||
if(bytes<8)
|
||||
total+=8;
|
||||
else
|
||||
total+=bytes;
|
||||
|
||||
if(width==1&&height==1)break;
|
||||
|
||||
if(width >1){width >>=1;bytes>>=1;}
|
||||
if(height>1){height>>=1;bytes>>=1;}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
const uint32 ComputeMipmapBytes(uint32 width,uint32 height,uint32 depth,uint32 bytes)
|
||||
{
|
||||
uint32 total=0;
|
||||
|
||||
while(width>=1&&height>=1&&depth>=1)
|
||||
{
|
||||
if(bytes<8)
|
||||
total+=8;
|
||||
else
|
||||
total+=bytes;
|
||||
|
||||
if(width==1&&height==1&&depth==1)break;
|
||||
|
||||
if(depth >1){depth >>=1;bytes>>=1;}
|
||||
if(width >1){width >>=1;bytes>>=1;}
|
||||
if(height>1){height>>=1;bytes>>=1;}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
struct VulkanTexturePixelFormat
|
||||
{
|
||||
VkFormat format;
|
||||
|
||||
uint8 channels; //颜色通道数
|
||||
char colors[4];
|
||||
uint8 bits[4];
|
||||
VulkanDataType type;
|
||||
};//
|
||||
|
||||
constexpr VulkanTexturePixelFormat pf_list[]=
|
||||
{
|
||||
{ PF_RGBA4, 4,{'R','G','B','A'},{ 4, 4, 4, 4},VulkanDataType::UNORM}, //Android 部分不支持
|
||||
{ PF_BGRA4, 4,{'B','G','R','A'},{ 4, 4, 4, 4},VulkanDataType::UNORM}, //ios不支持这个
|
||||
{UPF_RGB565, 3,{'R','G','B', 0 },{ 5, 6, 5, 0},VulkanDataType::UNORM},
|
||||
{UPF_A1RGB5, 4,{'A','R','G','B'},{ 1, 5, 5, 5},VulkanDataType::UNORM},
|
||||
{UPF_R8, 1,{'R', 0 , 0 , 0 },{ 8, 0, 0, 0},VulkanDataType::UNORM},
|
||||
{UPF_RG8, 2,{'R','G', 0 , 0 },{ 8, 8, 0, 0},VulkanDataType::UNORM},
|
||||
{UPF_RGBA8, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::UNORM},
|
||||
{UPF_RGBA8S, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::SNORM},
|
||||
{UPF_RGBA8U, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::UINT},
|
||||
{UPF_RGBA8I, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::SINT},
|
||||
{UPF_ABGR8, 4,{'A','B','G','R'},{ 8, 8, 8, 8},VulkanDataType::UNORM},
|
||||
{UPF_A2BGR10, 4,{'A','B','G','R'},{ 2,10,10,10},VulkanDataType::UNORM},
|
||||
{UPF_R16, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::UNORM},
|
||||
{UPF_R16U, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::UINT},
|
||||
{UPF_R16I, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::SINT},
|
||||
{UPF_R16F, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::SFLOAT},
|
||||
{UPF_RG16, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::UNORM},
|
||||
{UPF_RG16U, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::UINT},
|
||||
{UPF_RG16I, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::SINT},
|
||||
{UPF_RG16F, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::SFLOAT},
|
||||
{ PF_RGBA16UN, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::UNORM},
|
||||
{ PF_RGBA16SN, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SNORM},
|
||||
{UPF_RGBA16U, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::UINT},
|
||||
{UPF_RGBA16I, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SINT},
|
||||
{UPF_RGBA16F, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SFLOAT},
|
||||
{UPF_R32U, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::UINT},
|
||||
{UPF_R32I, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::SINT},
|
||||
{UPF_R32F, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::SFLOAT},
|
||||
{UPF_RG32U, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::UINT},
|
||||
{UPF_RG32I, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::SINT},
|
||||
{UPF_RG32F, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::SFLOAT},
|
||||
{ PF_RGB32U, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::UINT},
|
||||
{ PF_RGB32I, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::SINT},
|
||||
{ PF_RGB32F, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::SFLOAT},
|
||||
{UPF_RGBA32U, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::UINT},
|
||||
{UPF_RGBA32I, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::SINT},
|
||||
{UPF_RGBA32F, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::SFLOAT},
|
||||
{UPF_B10GR11UF, 3,{'B','G','R', 0 },{10,11,11, 0},VulkanDataType::UFLOAT}
|
||||
};
|
||||
|
||||
constexpr uint VulkanTexturePixelFormatCount=sizeof(pf_list)/sizeof(VulkanTexturePixelFormat);
|
||||
|
||||
const VkFormat GetVulkanFormat(const TexPixelFormat &tpf)
|
||||
{
|
||||
const VulkanTexturePixelFormat *pf=pf_list;
|
||||
|
||||
for(uint i=0;i<VulkanTexturePixelFormatCount;i++,++pf)
|
||||
{
|
||||
if(tpf.channels!=pf->channels)continue;
|
||||
if(tpf.datatype!=(uint8)pf->type)continue;
|
||||
|
||||
if(tpf.colors[0]!=pf->colors[0])continue;
|
||||
if(tpf.colors[1]!=pf->colors[1])continue;
|
||||
if(tpf.colors[2]!=pf->colors[2])continue;
|
||||
if(tpf.colors[3]!=pf->colors[3])continue;
|
||||
|
||||
if(tpf.bits[0]!=pf->bits[0])continue;
|
||||
if(tpf.bits[1]!=pf->bits[1])continue;
|
||||
if(tpf.bits[2]!=pf->bits[2])continue;
|
||||
if(tpf.bits[3]!=pf->bits[3])continue;
|
||||
|
||||
return pf->format;
|
||||
}
|
||||
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
bool TextureLoader::Load(io::InputStream *is)
|
||||
{
|
||||
if(!is)return(false);
|
||||
|
||||
if(is->Read(&file_header,sizeof(TextureFileHeader))!=sizeof(TextureFileHeader))
|
||||
return(false);
|
||||
|
||||
constexpr char TEXTURE_FILE_HEADER[]="Texture\x1A";
|
||||
constexpr uint TEXTURE_FILE_HEADER_LENGTH=sizeof(TEXTURE_FILE_HEADER)-1;
|
||||
|
||||
if(memcmp(&file_header.id_str,TEXTURE_FILE_HEADER,TEXTURE_FILE_HEADER_LENGTH))
|
||||
return(false);
|
||||
|
||||
if(file_header.version!=0)
|
||||
return(false);
|
||||
|
||||
if(file_header.type!=type)
|
||||
return(false);
|
||||
|
||||
if(file_header.pixel_format.channels==0)
|
||||
{
|
||||
if(file_header.pixel_format.compress_format<0
|
||||
||file_header.pixel_format.compress_format>=CompressFormatCount)
|
||||
return(nullptr);
|
||||
|
||||
format=CompressFormatList[file_header.pixel_format.compress_format];
|
||||
}
|
||||
else
|
||||
{
|
||||
format=GetVulkanFormat(file_header.pixel_format);
|
||||
}
|
||||
|
||||
//计算0级mipmap图像的字节数
|
||||
mipmap_zero_total_bytes=(GetPixelsCount()*file_header.pixel_format.pixel_bits())>>3;
|
||||
|
||||
total_bytes=GetTotalBytes();
|
||||
|
||||
const uint32 file_left_bytes=is->Available();
|
||||
|
||||
if(file_left_bytes<total_bytes)
|
||||
return(false);
|
||||
|
||||
void *ptr=OnBegin(total_bytes);
|
||||
|
||||
if(!ptr)
|
||||
return(false);
|
||||
|
||||
if(is->Read(ptr,total_bytes)!=total_bytes)
|
||||
OnError();
|
||||
|
||||
OnEnd();
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool TextureLoader::Load(const OSString &filename)
|
||||
{
|
||||
io::OpenFileInputStream fis(filename);
|
||||
|
||||
if(!fis)
|
||||
{
|
||||
LOG_ERROR(OS_TEXT("[ERROR] open texture file<")+filename+OS_TEXT("> failed."));
|
||||
return(false);
|
||||
}
|
||||
|
||||
return this->Load(&fis);
|
||||
}
|
||||
}//namespace graph
|
||||
}//namespace hgl
|
@ -8,96 +8,11 @@
|
||||
VK_NAMESPACE_BEGIN
|
||||
namespace
|
||||
{
|
||||
struct PixelFormat
|
||||
{
|
||||
VkFormat format;
|
||||
|
||||
uint8 channels; //颜色通道数
|
||||
char colors[4];
|
||||
uint8 bits[4];
|
||||
VulkanDataType type;
|
||||
|
||||
public:
|
||||
|
||||
const uint GetPixelBytes()const{return (bits[0]+bits[1]+bits[2]+bits[3])>>3;} ///<获取单个象素所需字节数
|
||||
};//
|
||||
|
||||
constexpr PixelFormat pf_list[]=
|
||||
{
|
||||
{ PF_RGBA4, 4,{'R','G','B','A'},{ 4, 4, 4, 4},VulkanDataType::UNORM}, //Android 部分不支持
|
||||
{ PF_BGRA4, 4,{'B','G','R','A'},{ 4, 4, 4, 4},VulkanDataType::UNORM}, //ios不支持这个
|
||||
{UPF_RGB565, 3,{'R','G','B', 0 },{ 5, 6, 5, 0},VulkanDataType::UNORM},
|
||||
{UPF_A1RGB5, 4,{'A','R','G','B'},{ 1, 5, 5, 5},VulkanDataType::UNORM},
|
||||
{UPF_R8, 1,{'R', 0 , 0 , 0 },{ 8, 0, 0, 0},VulkanDataType::UNORM},
|
||||
{UPF_RG8, 2,{'R','G', 0 , 0 },{ 8, 8, 0, 0},VulkanDataType::UNORM},
|
||||
{UPF_RGBA8, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::UNORM},
|
||||
{UPF_RGBA8S, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::SNORM},
|
||||
{UPF_RGBA8U, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::UINT},
|
||||
{UPF_RGBA8I, 4,{'R','G','B','A'},{ 8, 8, 8, 8},VulkanDataType::SINT},
|
||||
{UPF_ABGR8, 4,{'A','B','G','R'},{ 8, 8, 8, 8},VulkanDataType::UNORM},
|
||||
{UPF_A2BGR10, 4,{'A','B','G','R'},{ 2,10,10,10},VulkanDataType::UNORM},
|
||||
{UPF_R16, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::UNORM},
|
||||
{UPF_R16U, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::UINT},
|
||||
{UPF_R16I, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::SINT},
|
||||
{UPF_R16F, 1,{'R', 0 , 0 , 0 },{16, 0, 0, 0},VulkanDataType::SFLOAT},
|
||||
{UPF_RG16, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::UNORM},
|
||||
{UPF_RG16U, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::UINT},
|
||||
{UPF_RG16I, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::SINT},
|
||||
{UPF_RG16F, 2,{'R','G', 0 , 0 },{16,16, 0, 0},VulkanDataType::SFLOAT},
|
||||
{ PF_RGBA16UN, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::UNORM},
|
||||
{ PF_RGBA16SN, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SNORM},
|
||||
{UPF_RGBA16U, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::UINT},
|
||||
{UPF_RGBA16I, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SINT},
|
||||
{UPF_RGBA16F, 4,{'R','G','B','A'},{16,16,16,16},VulkanDataType::SFLOAT},
|
||||
{UPF_R32U, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::UINT},
|
||||
{UPF_R32I, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::SINT},
|
||||
{UPF_R32F, 1,{'R', 0 , 0 , 0 },{32, 0, 0, 0},VulkanDataType::SFLOAT},
|
||||
{UPF_RG32U, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::UINT},
|
||||
{UPF_RG32I, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::SINT},
|
||||
{UPF_RG32F, 2,{'R','G', 0 , 0 },{32,32, 0, 0},VulkanDataType::SFLOAT},
|
||||
{ PF_RGB32U, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::UINT},
|
||||
{ PF_RGB32I, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::SINT},
|
||||
{ PF_RGB32F, 3,{'R','G','B', 0 },{32,32,32, 0},VulkanDataType::SFLOAT},
|
||||
{UPF_RGBA32U, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::UINT},
|
||||
{UPF_RGBA32I, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::SINT},
|
||||
{UPF_RGBA32F, 4,{'R','G','B','A'},{32,32,32,32},VulkanDataType::SFLOAT},
|
||||
{UPF_B10GR11UF, 3,{'B','G','R', 0 },{10,11,11, 0},VulkanDataType::UFLOAT}
|
||||
};
|
||||
|
||||
constexpr uint PixelFormatCount=sizeof(pf_list)/sizeof(PixelFormat);
|
||||
|
||||
const VkFormat GetVulkanFormat(const int channels,const TexPixelFormat &tpf)
|
||||
{
|
||||
const PixelFormat *pf=pf_list;
|
||||
|
||||
for(uint i=0;i<PixelFormatCount;i++,++pf)
|
||||
{
|
||||
if(channels!=pf->channels)continue;
|
||||
if(tpf.datatype!=(uint8)pf->type)continue;
|
||||
|
||||
if(tpf.colors[0]!=pf->colors[0])continue;
|
||||
if(tpf.colors[1]!=pf->colors[1])continue;
|
||||
if(tpf.colors[2]!=pf->colors[2])continue;
|
||||
if(tpf.colors[3]!=pf->colors[3])continue;
|
||||
|
||||
if(tpf.bits[0]!=pf->bits[0])continue;
|
||||
if(tpf.bits[1]!=pf->bits[1])continue;
|
||||
if(tpf.bits[2]!=pf->bits[2])continue;
|
||||
if(tpf.bits[3]!=pf->bits[3])continue;
|
||||
|
||||
return pf->format;
|
||||
}
|
||||
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
class VkTexture2DLoader:public Texture2DLoader
|
||||
{
|
||||
protected:
|
||||
|
||||
GPUDevice *device;
|
||||
|
||||
VkFormat format;
|
||||
GPUBuffer *buf;
|
||||
|
||||
bool auto_mipmaps;
|
||||
@ -125,16 +40,6 @@ namespace
|
||||
SAFE_CLEAR(buf);
|
||||
SAFE_CLEAR(tex);
|
||||
|
||||
if(file_header.channels==0)
|
||||
{
|
||||
if(compress_format<0||compress_format>=CompressFormatCount)
|
||||
return(nullptr);
|
||||
|
||||
format=CompressFormatList[compress_format];
|
||||
}
|
||||
else
|
||||
format=GetVulkanFormat(file_header.channels,pixel_format);
|
||||
|
||||
if(!CheckVulkanFormat(format))
|
||||
return(nullptr);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user