我的Vulkan渲染器在将纹理定向到3d模型时遇到问题。
特别是,我有一个工作版本,该版本加载了bmp图像,并与正常外观的苹果完美融合。然后,我决定使用PVRTexTool生成的纹理编写KTX解析器。我能够加载和映射纹理(验证中没有错误),但方向已关闭。
我曾尝试在导出之前以不同的方式旋转和翻转图像,但是看起来总是一样。任何猜测我在这里做错了吗?
从VK_FORMAT_R8G8B8A8_UNORM / GL_RGBA8UI PVRTexTool加载生成的KTX中加载:
从BMP加载:
PVRTexTool生成的KTX文件的唯一方向输出如下(我无法找到如何更改它的方法:]
KTXOrientation S=r,T=d,R=i
KTX specification描述以下有关方向的信息:
为了帮助编写图像处理工具和查看器,KTX文件中数据的方向可以在文件的键/值元数据。请注意,此元数据仅影响逻辑数据的解释,对像素映射没有影响在文件字节流中进行纹理坐标处理。推荐的钥匙用途是:
KTXorientation
建议查看和编辑工具至少支持以下值:S = r,T = dS = r,T = uS = r,T = d,R = iS = r,T = u,R = o
where
S indicates the direction of increasing S values T indicates the direction of increasing T values R indicates the direction of increasing R values r indicates increasing to the right l indicates increasing to the left d indicates increasing downwards u indicates increasing upwards o indicates increasing out from the screen (moving towards viewer) i indicates increasing in towards the screen (moving away from viewer)
KTX解析器的代码:
type Image_State (Data_Size : Int) is record
Mipmaps,
Faces,
Height,
Width,
Format : Int_Unsigned_C;
Data : Array_Byte (1..Data_Size);
end record;
type Ptr_Image_State is access all Image_State;
----------------
-- Load_Image --
----------------
procedure Load_Image (Path : Str; Image : in out Ptr_Image_State) is
-- https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
type KTX_Header_State is record
Id : Str_8 (1..12) := (others => NULL_CHAR_8);
Endianness,
Kind,
Kind_Size,
GL_Format,
Internal_Format,
Base_Format,
Width,
Height,
Depth,
Array_Length,
Faces,
Mipmaps,
Key_Value_Bytes : Int_Unsigned_C := 0;
end record with Pack;
Image_Size : Int_Unsigned_C;
Header : KTX_Header_State;
Data : Ada.Streams.Stream_IO.File_Type;
begin
Open (Data, In_File,
To_Str_8 (S (OS_Info.App_Path) & "Assets\Textures" & S & Path & ".ktx"));
-- Load the header and skip to the image data
KTX_Header_State'Read (Ada.Streams.Stream_IO.Stream (Data), Header);
Skip (Data, Int (Header.Key_Value_Bytes));
Int_Unsigned_C'Read (Ada.Streams.Stream_IO.Stream (Data), Image_Size);
-- Sanity check
Assert (Header.Id (2..7) = "KTX 11");
-- Map OpenGL format to Vulkan equivalent and fix up the mipmap count...
if Header.Mipmaps = 0 then Header.Mipmaps := 1; end if;
case Header.Internal_Format is
when 16#9137# => Header.Internal_Format := -- GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG
VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG;
when 16#9138# => Header.Internal_Format := -- GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG
VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG;
when 16#93F0# => Header.Internal_Format := -- GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG
VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG;
when 16#93F1# => Header.Internal_Format := -- GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG
VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG;
when 16#8D7C# => Header.Internal_Format := -- GL_RGBA8UI
VK_FORMAT_R8G8B8A8_UNORM;
when others => raise Unsupported_Compression_Format with Header.Internal_Format'Image;
end case;
-- Load the image in a single go - no reason for special loops...
Image := new Image_State (Int (Image_Size),
Header.Mipmaps,
Header.Faces,
Header.Width,
Header.Height,
Header.Internal_Format, others => <>);
Array_Byte'Read (Ada.Streams.Stream_IO.Stream (Data), Image.Data);
Close (Data);
end;
如果我没看错文档,那么KTXorientation键/值对将存储在您在代码中跳过的数据中
Skip (Data, Int (Header.Key_Value_Bytes));
第2.14节keyAndValue描述了该节的格式