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(16.DeferredRenderMultiCmdBuffer DeferredRenderMultiCmdBuffer.cpp)
|
||||||
#CreateProject(14.AutoMaterial auto_material.cpp)
|
#CreateProject(14.AutoMaterial auto_material.cpp)
|
||||||
|
|
||||||
|
CreateProject(17.Cubemap Cubemap.cpp)
|
@ -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"
|
||||||
|
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);
|
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
|
||||||
|
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_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})
|
||||||
|
|
||||||
|
@ -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
|
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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user