改进TGATexture,文件加载直接进显存,减少一步内存分配
This commit is contained in:
parent
b9efaff10c
commit
a9e4ea026f
@ -1,6 +1,7 @@
|
|||||||
#include<hgl/graph/vulkan/VK.h>
|
#include<hgl/graph/vulkan/VK.h>
|
||||||
#include<hgl/graph/vulkan/VKDevice.h>
|
#include<hgl/graph/vulkan/VKDevice.h>
|
||||||
#include<hgl/filesystem/FileSystem.h>
|
#include<hgl/graph/vulkan/VKBuffer.h>
|
||||||
|
#include<hgl/io/FileInputStream.h>
|
||||||
#include<hgl/LogInfo.h>
|
#include<hgl/LogInfo.h>
|
||||||
|
|
||||||
VK_NAMESPACE_BEGIN
|
VK_NAMESPACE_BEGIN
|
||||||
@ -40,11 +41,8 @@ namespace
|
|||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
void RGB8to565(uint8 *data,uint size)
|
void RGB8to565(uint16 *target,uint8 *src,uint size)
|
||||||
{
|
{
|
||||||
uint8 *src=data;
|
|
||||||
uint16 *target=(uint16 *)data;
|
|
||||||
|
|
||||||
for(uint i=0;i<size;i++)
|
for(uint i=0;i<size;i++)
|
||||||
{
|
{
|
||||||
*target=((src[2]<<8)&0xF800)
|
*target=((src[2]<<8)&0xF800)
|
||||||
@ -78,69 +76,101 @@ namespace
|
|||||||
|
|
||||||
Texture2D *LoadTGATexture(const OSString &filename,Device *device)
|
Texture2D *LoadTGATexture(const OSString &filename,Device *device)
|
||||||
{
|
{
|
||||||
uint8 *data;
|
io::OpenFileInputStream fis(filename);
|
||||||
const int64 file_length=filesystem::LoadFileToMemory(filename,(void **)&data);
|
|
||||||
|
|
||||||
if(file_length<=0)
|
if(!fis)
|
||||||
{
|
{
|
||||||
LOG_ERROR(OS_TEXT("[ERROR] open file<")+filename+OS_TEXT("> failed."));
|
LOG_ERROR(OS_TEXT("[ERROR] open file<")+filename+OS_TEXT("> failed."));
|
||||||
return(nullptr);
|
return(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TGAHeader *header=(TGAHeader *)data;
|
const int64 file_length=fis->GetSize();
|
||||||
TGAImageDesc image_desc;
|
|
||||||
uint8 *pixel_data=data+sizeof(TGAHeader);
|
|
||||||
|
|
||||||
image_desc.image_desc=header->image_desc;
|
if(file_length<=sizeof(TGAHeader))
|
||||||
|
|
||||||
VkFormat format;
|
|
||||||
uint line_size;
|
|
||||||
|
|
||||||
if(header->image_type==2)
|
|
||||||
{
|
{
|
||||||
if(header->bit==24)
|
LOG_ERROR(OS_TEXT("[ERROR] file<")+filename+OS_TEXT("> length < sizeof(TGAHeader)."));
|
||||||
{
|
|
||||||
RGB8to565(pixel_data,header->width*header->height);
|
|
||||||
|
|
||||||
format=FMT_RGB565;
|
|
||||||
line_size=header->width*2;
|
|
||||||
}
|
|
||||||
else if(header->bit==32)
|
|
||||||
{
|
|
||||||
format=FMT_RGBA8UN;
|
|
||||||
line_size=header->width*4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(header->image_type==3&&header->bit==8)
|
|
||||||
{
|
|
||||||
format=FMT_R8UN;
|
|
||||||
line_size=header->width;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG_ERROR(OS_TEXT("[ERROR] Image format error,filename: ")+filename);
|
|
||||||
delete[] data;
|
|
||||||
return(nullptr);
|
return(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(image_desc.direction==0)
|
TGAHeader header;
|
||||||
SwapRow(pixel_data,line_size,header->height);
|
TGAImageDesc image_desc;
|
||||||
|
|
||||||
Texture2D *tex=device->CreateTexture2D(format,pixel_data,header->width,header->height,line_size*header->height);
|
if(fis->Read(&header,sizeof(TGAHeader))!=sizeof(TGAHeader))
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
const uint total_bytes=header.width*header.height*header.bit>>3;
|
||||||
|
|
||||||
|
if(file_length<sizeof(TGAHeader)+total_bytes)
|
||||||
|
{
|
||||||
|
LOG_ERROR(OS_TEXT("[ERROR] file<")+filename+OS_TEXT("> length error."));
|
||||||
|
return(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
image_desc.image_desc=header.image_desc;
|
||||||
|
|
||||||
|
VkFormat format=FMT_UNDEFINED;
|
||||||
|
|
||||||
|
if(header.image_type==2)
|
||||||
|
{
|
||||||
|
if(header.bit==24)format=FMT_RGB8UN;else
|
||||||
|
if(header.bit==32)format=FMT_RGBA8UN;
|
||||||
|
}
|
||||||
|
else if(header.image_type==3&&header.bit==8)
|
||||||
|
format=FMT_R8UN;
|
||||||
|
|
||||||
|
if(format==FMT_UNDEFINED)
|
||||||
|
{
|
||||||
|
LOG_ERROR(OS_TEXT("[ERROR] Image format error,filename: ")+filename);
|
||||||
|
return(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vulkan::Buffer *buf;
|
||||||
|
|
||||||
|
if(header.bit==24)
|
||||||
|
{
|
||||||
|
uint8 *pixel_data=new uint8[total_bytes];
|
||||||
|
|
||||||
|
fis->Read(pixel_data,total_bytes);
|
||||||
|
|
||||||
|
if(image_desc.direction==0)
|
||||||
|
SwapRow((uint8 *)pixel_data,header.width*header.bit/8,header.height);
|
||||||
|
|
||||||
|
buf=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,header.width*header.height*2);
|
||||||
|
RGB8to565((uint16 *)buf->Map(),pixel_data,header.width*header.height);
|
||||||
|
buf->Unmap();
|
||||||
|
|
||||||
|
format=FMT_RGB565;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vulkan::Buffer *buf=device->CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,total_bytes);
|
||||||
|
|
||||||
|
uint8 *pixel_data=(uint8 *)buf->Map();
|
||||||
|
|
||||||
|
fis->Read(pixel_data,total_bytes);
|
||||||
|
|
||||||
|
if(image_desc.direction==0)
|
||||||
|
SwapRow((uint8 *)pixel_data,header.width*header.bit/8,header.height);
|
||||||
|
|
||||||
|
buf->Unmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture2D *tex=device->CreateTexture2D(format,buf,header.width,header.height);
|
||||||
|
|
||||||
|
delete buf;
|
||||||
|
|
||||||
if(tex)
|
if(tex)
|
||||||
{
|
{
|
||||||
LOG_INFO(OS_TEXT("load image file<")+filename+OS_TEXT(">:<")+OSString(header->width)+OS_TEXT("x")+OSString(header->height)+OS_TEXT("> to texture ok"));
|
LOG_INFO(OS_TEXT("load image file<")+filename+OS_TEXT(">:<")+OSString(header.width)+OS_TEXT("x")+OSString(header.height)+OS_TEXT("> to texture ok"));
|
||||||
|
|
||||||
//下面代码用于测试修改纹理
|
//下面代码用于测试修改纹理
|
||||||
//device->ChangeTexture2D(tex,pixel_data,header->width/4,header->height/4,header->width/2,header->height/2,line_size*header->height/4);
|
//device->ChangeTexture2D(tex,pixel_data,header->width/4,header->height/4,header->width/2,header->height/2,line_size*header->height/4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_ERROR(OS_TEXT("load image file<")+filename+OS_TEXT(">:<")+OSString(header->width)+OS_TEXT("x")+OSString(header->height)+OS_TEXT("> to texture failed."));
|
LOG_ERROR(OS_TEXT("load image file<")+filename+OS_TEXT(">:<")+OSString(header.width)+OS_TEXT("x")+OSString(header.height)+OS_TEXT("> to texture failed."));
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] data;
|
|
||||||
return(tex);
|
return(tex);
|
||||||
}
|
}
|
||||||
VK_NAMESPACE_END
|
VK_NAMESPACE_END
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include<vulkan/vulkan.h>
|
#include<vulkan/vulkan.h>
|
||||||
|
|
||||||
|
#define FMT_UNDEFINED VK_FORMAT_UNDEFINED
|
||||||
|
|
||||||
#define FMT_RG4UN VK_FORMAT_R4G4_UNORM_PACK8
|
#define FMT_RG4UN VK_FORMAT_R4G4_UNORM_PACK8
|
||||||
#define FMT_RGBA4 VK_FORMAT_R4G4B4A4_UNORM_PACK16
|
#define FMT_RGBA4 VK_FORMAT_R4G4B4A4_UNORM_PACK16
|
||||||
#define FMT_BGRA4 VK_FORMAT_B4G4R4A4_UNORM_PACK16
|
#define FMT_BGRA4 VK_FORMAT_B4G4R4A4_UNORM_PACK16
|
||||||
|
@ -39,7 +39,7 @@ namespace hgl
|
|||||||
virtual int64 Tell()const; ///<取当前位置
|
virtual int64 Tell()const; ///<取当前位置
|
||||||
virtual int64 GetSize()const; ///<取得文件长度
|
virtual int64 GetSize()const; ///<取得文件长度
|
||||||
virtual bool Restart(); ///<复位访问指针
|
virtual bool Restart(); ///<复位访问指针
|
||||||
virtual int64 Seek(int64,SeekOrigin=SeekOrigin::Begin); ///<移动访问指针
|
virtual int64 Seek(int64,SeekOrigin=SeekOrigin::Begin); ///<移动访问指针
|
||||||
|
|
||||||
virtual int64 Available()const; ///<剩下的可以不受阻塞访问的字节数
|
virtual int64 Available()const; ///<剩下的可以不受阻塞访问的字节数
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user