2019-05-19 13:02:35 +08:00
|
|
|
|
#include<hgl/graph/vulkan/VK.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKDevice.h>
|
|
|
|
|
#include<hgl/filesystem/FileSystem.h>
|
2019-05-20 17:52:23 +08:00
|
|
|
|
#include<hgl/LogInfo.h>
|
2019-05-19 13:02:35 +08:00
|
|
|
|
|
|
|
|
|
VK_NAMESPACE_BEGIN
|
|
|
|
|
namespace
|
|
|
|
|
{
|
|
|
|
|
#pragma pack(push,1)
|
|
|
|
|
struct TGAHeader
|
|
|
|
|
{
|
|
|
|
|
uint8 id;
|
|
|
|
|
uint8 color_map_type;
|
|
|
|
|
uint8 image_type; // 1 colormap image ,2 true-color,3 grayscale
|
|
|
|
|
|
|
|
|
|
uint16 color_map_first;
|
|
|
|
|
uint16 color_map_length;
|
|
|
|
|
uint8 color_map_size;
|
|
|
|
|
|
|
|
|
|
uint16 x_origin;
|
|
|
|
|
uint16 y_origin;
|
|
|
|
|
|
|
|
|
|
uint16 width;
|
|
|
|
|
uint16 height;
|
|
|
|
|
uint8 bit;
|
|
|
|
|
|
|
|
|
|
uint8 image_desc;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
union TGAImageDesc
|
|
|
|
|
{
|
|
|
|
|
//不要把此union放到上面的struct中,否则Visual C++会将此union编译成4字节。GCC无此问题
|
|
|
|
|
uint8 image_desc;
|
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
uint alpha_depth:4;
|
|
|
|
|
uint reserved:1;
|
|
|
|
|
uint direction:1; //0 lower-left,1 upper left
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
|
|
void RGB8to565(uint8 *data,uint size)
|
|
|
|
|
{
|
|
|
|
|
uint8 *src=data;
|
|
|
|
|
uint16 *target=(uint16 *)data;
|
|
|
|
|
|
|
|
|
|
for(uint i=0;i<size;i++)
|
|
|
|
|
{
|
|
|
|
|
*target=(((src[0])<<8)&0xF800)
|
|
|
|
|
|(((src[1])<<3)&0x7E0)
|
|
|
|
|
| ((src[2])>>3);
|
|
|
|
|
|
|
|
|
|
++target;
|
|
|
|
|
src+=3;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-20 17:52:23 +08:00
|
|
|
|
|
|
|
|
|
void SwapRow(uint8 *data,uint line_size,uint height)
|
|
|
|
|
{
|
|
|
|
|
uint8 *top=data;
|
|
|
|
|
uint8 *bottom=data+(height-1)*line_size;
|
|
|
|
|
uint8 *tmp=new uint8[line_size];
|
|
|
|
|
|
|
|
|
|
while(top<bottom)
|
|
|
|
|
{
|
|
|
|
|
memcpy(tmp,bottom,line_size);
|
|
|
|
|
memcpy(bottom,top,line_size);
|
|
|
|
|
memcpy(top,tmp,line_size);
|
|
|
|
|
|
|
|
|
|
top+=line_size;
|
|
|
|
|
bottom-=line_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete[] tmp;
|
|
|
|
|
}
|
2019-05-19 13:02:35 +08:00
|
|
|
|
}//namespace
|
|
|
|
|
|
|
|
|
|
Texture2D *LoadTGATexture(const OSString &filename,Device *device)
|
|
|
|
|
{
|
|
|
|
|
uint8 *data;
|
|
|
|
|
const int64 file_length=filesystem::LoadFileToMemory(filename,(void **)&data);
|
|
|
|
|
|
|
|
|
|
if(file_length<=0)
|
|
|
|
|
{
|
2019-05-20 17:52:23 +08:00
|
|
|
|
LOG_ERROR(OS_TEXT("[ERROR] open file<")+filename+OS_TEXT("> failed."));
|
2019-05-19 13:02:35 +08:00
|
|
|
|
return(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TGAHeader *header=(TGAHeader *)data;
|
2019-05-20 17:52:23 +08:00
|
|
|
|
TGAImageDesc image_desc;
|
|
|
|
|
uint8 *pixel_data=data+sizeof(TGAHeader);
|
|
|
|
|
|
|
|
|
|
image_desc.image_desc=header->image_desc;
|
2019-05-19 13:02:35 +08:00
|
|
|
|
|
|
|
|
|
VkFormat format;
|
2019-05-20 17:52:23 +08:00
|
|
|
|
uint line_size;
|
2019-05-19 13:02:35 +08:00
|
|
|
|
|
|
|
|
|
if(header->image_type==2)
|
|
|
|
|
{
|
|
|
|
|
if(header->bit==24)
|
|
|
|
|
{
|
2019-05-20 17:52:23 +08:00
|
|
|
|
RGB8to565(pixel_data,header->width*header->height);
|
2019-05-19 13:02:35 +08:00
|
|
|
|
|
2019-05-20 17:52:23 +08:00
|
|
|
|
format=FMT_BGR565;
|
|
|
|
|
line_size=header->width*2;
|
2019-05-19 13:02:35 +08:00
|
|
|
|
}
|
|
|
|
|
else if(header->bit==32)
|
|
|
|
|
{
|
|
|
|
|
format=FMT_RGBA8UN;
|
2019-05-20 17:52:23 +08:00
|
|
|
|
line_size=header->width*4;
|
2019-05-19 13:02:35 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(header->image_type==3&&header->bit==8)
|
|
|
|
|
{
|
|
|
|
|
format=FMT_R8UN;
|
2019-05-20 17:52:23 +08:00
|
|
|
|
line_size=header->width;
|
2019-05-19 13:02:35 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-05-20 17:52:23 +08:00
|
|
|
|
LOG_ERROR(OS_TEXT("[ERROR] Image format error,filename: ")+filename);
|
2019-05-19 13:02:35 +08:00
|
|
|
|
delete[] data;
|
|
|
|
|
return(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-20 17:52:23 +08:00
|
|
|
|
if(image_desc.direction==0)
|
|
|
|
|
SwapRow(pixel_data,line_size,header->height);
|
|
|
|
|
|
|
|
|
|
Texture2D *tex=device->CreateTexture2D(format,pixel_data,header->width,header->height,line_size*header->height);
|
2019-05-19 13:02:35 +08:00
|
|
|
|
|
|
|
|
|
if(tex)
|
|
|
|
|
{
|
2019-05-20 17:52:23 +08:00
|
|
|
|
LOG_INFO(OS_TEXT("load image file<")+filename+OS_TEXT(">:<")+OSString(header->width)+OS_TEXT("x")+OSString(header->height)+OS_TEXT("> to texture ok"));
|
2019-05-19 13:02:35 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-05-20 17:52:23 +08:00
|
|
|
|
LOG_ERROR(OS_TEXT("load image file<")+filename+OS_TEXT(">:<")+OSString(header->width)+OS_TEXT("x")+OSString(header->height)+OS_TEXT("> to texture failed."));
|
2019-05-19 13:02:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete[] data;
|
|
|
|
|
return(tex);
|
|
|
|
|
}
|
|
|
|
|
VK_NAMESPACE_END
|