newly Loader code of Texture

This commit is contained in:
hyzboy 2021-12-13 21:03:41 +08:00
parent 926802619f
commit 9d0ae0a071
10 changed files with 391 additions and 304 deletions

2
CMCore

@ -1 +1 @@
Subproject commit 463eb1dd7eb84ba9e3ed2e4cb1180a7c10186a7d Subproject commit 1cefb338da8887ceaf800aecc9e1bc24dee63e8c

View File

@ -50,3 +50,4 @@ CreateProject(15.OffscreenRender OffscreenRender.cpp)
CreateProject(16.DeferredRenderMultiCmdBuffer DeferredRenderMultiCmdBuffer.cpp) CreateProject(16.DeferredRenderMultiCmdBuffer DeferredRenderMultiCmdBuffer.cpp)
#CreateProject(14.AutoMaterial auto_material.cpp) #CreateProject(14.AutoMaterial auto_material.cpp)
CreateProject(17.Cubemap Cubemap.cpp)

View File

@ -2,7 +2,7 @@
// 该示例使用TileData演示多个tile图片在一张纹理上 // 该示例使用TileData演示多个tile图片在一张纹理上
#include<hgl/type/StringList.h> #include<hgl/type/StringList.h>
#include<hgl/graph/TextureLoader.h> #include<hgl/graph/Bitmap2DLoader.h>
#include<hgl/graph/TileData.h> #include<hgl/graph/TileData.h>
#include"VulkanAppFramework.h" #include"VulkanAppFramework.h"

View 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
{
/**
* 2»Í¼¼ÓÔØ
*/
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

View File

@ -27,90 +27,124 @@ namespace hgl
constexpr uint32 CompressFormatCount=sizeof(CompressFormatList)/sizeof(VkFormat); constexpr uint32 CompressFormatCount=sizeof(CompressFormatList)/sizeof(VkFormat);
#pragma pack(push,1) #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 struct TexPixelFormat
{ {
char colors[4]; uint8 channels; //0: compress 1/2/3/4:normal
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;
union union
{ {
TexPixelFormat pixel_format; struct
uint16 compress_format; {
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: 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 *OnBegin(uint32)=0;
virtual void OnEnd()=0; virtual void OnEnd()=0;
virtual void OnError(){} virtual void OnError(){}
public: 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: public:
~Bitmap2DLoader(); Texture2DLoader():TextureLoader(VK_IMAGE_VIEW_TYPE_2D){}
virtual ~Texture2DLoader()=default;
void *OnBegin(uint32 total_bytes) override; };//class Texture2DLoader
void OnEnd() override {}
BitmapData *GetBitmap();
};//class Bitmap2DLoader
BitmapData *LoadBitmapFromFile(const OSString &filename);
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl
#endif//HGL_GRAPH_TEXTURE_LOADER_INCLUDE #endif//HGL_GRAPH_TEXTURE_LOADER_INCLUDE

View 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

View File

@ -1,7 +1,9 @@
set(SG_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph) set(SG_INCLUDE_PATH ${ROOT_INCLUDE_PATH}/hgl/graph)
SET(SG_TEXTURE_SOURCE ${SG_INCLUDE_PATH}/TextureLoader.h 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}) SOURCE_GROUP("Texture" FILES ${SG_TEXTURE_SOURCE})

View File

@ -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

View 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

View File

@ -8,96 +8,11 @@
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
namespace 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 class VkTexture2DLoader:public Texture2DLoader
{ {
protected: protected:
GPUDevice *device; GPUDevice *device;
VkFormat format;
GPUBuffer *buf; GPUBuffer *buf;
bool auto_mipmaps; bool auto_mipmaps;
@ -125,16 +40,6 @@ namespace
SAFE_CLEAR(buf); SAFE_CLEAR(buf);
SAFE_CLEAR(tex); 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)) if(!CheckVulkanFormat(format))
return(nullptr); return(nullptr);