Skip to content

Commit dfec64b

Browse files
committed
implement DDS filer parser
1 parent a350d5f commit dfec64b

File tree

6 files changed

+370
-26
lines changed

6 files changed

+370
-26
lines changed

.vscode/launch.json

+12
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@
4444
"environment": [],
4545
"externalConsole": false
4646
},
47+
{
48+
"name": "(Windows) Launch Test",
49+
"type": "cppvsdbg",
50+
"request": "launch",
51+
"program": "${workspaceFolder}/build/Test/Debug/DdsParserTest.exe",
52+
"args": [
53+
],
54+
"stopAtEntry": false,
55+
"cwd": "${workspaceFolder}",
56+
"environment": [],
57+
"externalConsole": false
58+
},
4759
{
4860
"name": "(Windows) Launch Game",
4961
"type": "cppvsdbg",

Framework/Common/SceneObjectTexture.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "PNG.hpp"
66
#include "BMP.hpp"
77
#include "TGA.hpp"
8+
#include "DDS.hpp"
89
#include "AssetLoader.hpp"
910

1011
namespace My {
@@ -54,6 +55,11 @@ namespace My {
5455
TgaParser tga_parser;
5556
m_pImage = std::make_shared<Image>(tga_parser.Parse(buf));
5657
}
58+
else if (ext == ".dds")
59+
{
60+
DdsParser dds_parser;
61+
m_pImage = std::make_shared<Image>(dds_parser.Parse(buf));
62+
}
5763
}
5864
}
5965

Framework/Parser/DDS.hpp

+275
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
#pragma once
2+
#include <algorithm>
3+
#include "ImageParser.hpp"
4+
5+
namespace My {
6+
typedef enum DXGI_FORMAT {
7+
DXGI_FORMAT_UNKNOWN ,
8+
DXGI_FORMAT_R32G32B32A32_TYPELESS ,
9+
DXGI_FORMAT_R32G32B32A32_FLOAT ,
10+
DXGI_FORMAT_R32G32B32A32_UINT ,
11+
DXGI_FORMAT_R32G32B32A32_SINT ,
12+
DXGI_FORMAT_R32G32B32_TYPELESS ,
13+
DXGI_FORMAT_R32G32B32_FLOAT ,
14+
DXGI_FORMAT_R32G32B32_UINT ,
15+
DXGI_FORMAT_R32G32B32_SINT ,
16+
DXGI_FORMAT_R16G16B16A16_TYPELESS ,
17+
DXGI_FORMAT_R16G16B16A16_FLOAT ,
18+
DXGI_FORMAT_R16G16B16A16_UNORM ,
19+
DXGI_FORMAT_R16G16B16A16_UINT ,
20+
DXGI_FORMAT_R16G16B16A16_SNORM ,
21+
DXGI_FORMAT_R16G16B16A16_SINT ,
22+
DXGI_FORMAT_R32G32_TYPELESS ,
23+
DXGI_FORMAT_R32G32_FLOAT ,
24+
DXGI_FORMAT_R32G32_UINT ,
25+
DXGI_FORMAT_R32G32_SINT ,
26+
DXGI_FORMAT_R32G8X24_TYPELESS ,
27+
DXGI_FORMAT_D32_FLOAT_S8X24_UINT ,
28+
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS ,
29+
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT ,
30+
DXGI_FORMAT_R10G10B10A2_TYPELESS ,
31+
DXGI_FORMAT_R10G10B10A2_UNORM ,
32+
DXGI_FORMAT_R10G10B10A2_UINT ,
33+
DXGI_FORMAT_R11G11B10_FLOAT ,
34+
DXGI_FORMAT_R8G8B8A8_TYPELESS ,
35+
DXGI_FORMAT_R8G8B8A8_UNORM ,
36+
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB ,
37+
DXGI_FORMAT_R8G8B8A8_UINT ,
38+
DXGI_FORMAT_R8G8B8A8_SNORM ,
39+
DXGI_FORMAT_R8G8B8A8_SINT ,
40+
DXGI_FORMAT_R16G16_TYPELESS ,
41+
DXGI_FORMAT_R16G16_FLOAT ,
42+
DXGI_FORMAT_R16G16_UNORM ,
43+
DXGI_FORMAT_R16G16_UINT ,
44+
DXGI_FORMAT_R16G16_SNORM ,
45+
DXGI_FORMAT_R16G16_SINT ,
46+
DXGI_FORMAT_R32_TYPELESS ,
47+
DXGI_FORMAT_D32_FLOAT ,
48+
DXGI_FORMAT_R32_FLOAT ,
49+
DXGI_FORMAT_R32_UINT ,
50+
DXGI_FORMAT_R32_SINT ,
51+
DXGI_FORMAT_R24G8_TYPELESS ,
52+
DXGI_FORMAT_D24_UNORM_S8_UINT ,
53+
DXGI_FORMAT_R24_UNORM_X8_TYPELESS ,
54+
DXGI_FORMAT_X24_TYPELESS_G8_UINT ,
55+
DXGI_FORMAT_R8G8_TYPELESS ,
56+
DXGI_FORMAT_R8G8_UNORM ,
57+
DXGI_FORMAT_R8G8_UINT ,
58+
DXGI_FORMAT_R8G8_SNORM ,
59+
DXGI_FORMAT_R8G8_SINT ,
60+
DXGI_FORMAT_R16_TYPELESS ,
61+
DXGI_FORMAT_R16_FLOAT ,
62+
DXGI_FORMAT_D16_UNORM ,
63+
DXGI_FORMAT_R16_UNORM ,
64+
DXGI_FORMAT_R16_UINT ,
65+
DXGI_FORMAT_R16_SNORM ,
66+
DXGI_FORMAT_R16_SINT ,
67+
DXGI_FORMAT_R8_TYPELESS ,
68+
DXGI_FORMAT_R8_UNORM ,
69+
DXGI_FORMAT_R8_UINT ,
70+
DXGI_FORMAT_R8_SNORM ,
71+
DXGI_FORMAT_R8_SINT ,
72+
DXGI_FORMAT_A8_UNORM ,
73+
DXGI_FORMAT_R1_UNORM ,
74+
DXGI_FORMAT_R9G9B9E5_SHAREDEXP ,
75+
DXGI_FORMAT_R8G8_B8G8_UNORM ,
76+
DXGI_FORMAT_G8R8_G8B8_UNORM ,
77+
DXGI_FORMAT_BC1_TYPELESS ,
78+
DXGI_FORMAT_BC1_UNORM ,
79+
DXGI_FORMAT_BC1_UNORM_SRGB ,
80+
DXGI_FORMAT_BC2_TYPELESS ,
81+
DXGI_FORMAT_BC2_UNORM ,
82+
DXGI_FORMAT_BC2_UNORM_SRGB ,
83+
DXGI_FORMAT_BC3_TYPELESS ,
84+
DXGI_FORMAT_BC3_UNORM ,
85+
DXGI_FORMAT_BC3_UNORM_SRGB ,
86+
DXGI_FORMAT_BC4_TYPELESS ,
87+
DXGI_FORMAT_BC4_UNORM ,
88+
DXGI_FORMAT_BC4_SNORM ,
89+
DXGI_FORMAT_BC5_TYPELESS ,
90+
DXGI_FORMAT_BC5_UNORM ,
91+
DXGI_FORMAT_BC5_SNORM ,
92+
DXGI_FORMAT_B5G6R5_UNORM ,
93+
DXGI_FORMAT_B5G5R5A1_UNORM ,
94+
DXGI_FORMAT_B8G8R8A8_UNORM ,
95+
DXGI_FORMAT_B8G8R8X8_UNORM ,
96+
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ,
97+
DXGI_FORMAT_B8G8R8A8_TYPELESS ,
98+
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB ,
99+
DXGI_FORMAT_B8G8R8X8_TYPELESS ,
100+
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB ,
101+
DXGI_FORMAT_BC6H_TYPELESS ,
102+
DXGI_FORMAT_BC6H_UF16 ,
103+
DXGI_FORMAT_BC6H_SF16 ,
104+
DXGI_FORMAT_BC7_TYPELESS ,
105+
DXGI_FORMAT_BC7_UNORM ,
106+
DXGI_FORMAT_BC7_UNORM_SRGB ,
107+
DXGI_FORMAT_AYUV ,
108+
DXGI_FORMAT_Y410 ,
109+
DXGI_FORMAT_Y416 ,
110+
DXGI_FORMAT_NV12 ,
111+
DXGI_FORMAT_P010 ,
112+
DXGI_FORMAT_P016 ,
113+
DXGI_FORMAT_420_OPAQUE ,
114+
DXGI_FORMAT_YUY2 ,
115+
DXGI_FORMAT_Y210 ,
116+
DXGI_FORMAT_Y216 ,
117+
DXGI_FORMAT_NV11 ,
118+
DXGI_FORMAT_AI44 ,
119+
DXGI_FORMAT_IA44 ,
120+
DXGI_FORMAT_P8 ,
121+
DXGI_FORMAT_A8P8 ,
122+
DXGI_FORMAT_B4G4R4A4_UNORM ,
123+
DXGI_FORMAT_P208 ,
124+
DXGI_FORMAT_V208 ,
125+
DXGI_FORMAT_V408 ,
126+
DXGI_FORMAT_FORCE_UINT
127+
} DXGI_FORMAT;
128+
129+
typedef enum D3D10_RESOURCE_DIMENSION {
130+
D3D10_RESOURCE_DIMENSION_UNKNOWN ,
131+
D3D10_RESOURCE_DIMENSION_BUFFER ,
132+
D3D10_RESOURCE_DIMENSION_TEXTURE1D ,
133+
D3D10_RESOURCE_DIMENSION_TEXTURE2D ,
134+
D3D10_RESOURCE_DIMENSION_TEXTURE3D
135+
} D3D10_RESOURCE_DIMENSION;
136+
137+
typedef struct {
138+
uint32_t dwSize;
139+
uint32_t dwFlags;
140+
uint32_t dwFourCC;
141+
uint32_t dwRGBBitCount;
142+
uint32_t dwRBitMask;
143+
uint32_t dwGBitMask;
144+
uint32_t dwBBitMask;
145+
uint32_t dwABitMask;
146+
} DDS_PIXELFORMAT;
147+
148+
typedef struct {
149+
uint32_t dwSize;
150+
uint32_t dwFlags;
151+
uint32_t dwHeight;
152+
uint32_t dwWidth;
153+
uint32_t dwPitchOrLinearSize;
154+
uint32_t dwDepth;
155+
uint32_t dwMipMapCount;
156+
uint32_t dwReserved1[11];
157+
DDS_PIXELFORMAT ddspf;
158+
uint32_t dwCaps;
159+
uint32_t dwCaps2;
160+
uint32_t dwCaps3;
161+
uint32_t dwCaps4;
162+
uint32_t dwReserved2;
163+
} DDS_HEADER;
164+
165+
typedef struct {
166+
DXGI_FORMAT dxgiFormat;
167+
D3D10_RESOURCE_DIMENSION resourceDimension;
168+
uint32_t miscFlag;
169+
uint32_t arraySize;
170+
uint32_t miscFlag2;
171+
} DDS_HEADER_DXT10;
172+
173+
class DdsParser : implements ImageParser
174+
{
175+
public:
176+
virtual Image Parse(Buffer& buf)
177+
{
178+
Image img;
179+
uint8_t* pData = buf.GetData();
180+
181+
const uint32_t* pdwMagic = reinterpret_cast<const uint32_t*>(pData);
182+
pData += sizeof(uint32_t);
183+
assert(*pdwMagic == endian_net_unsigned_int("DDS "_u32));
184+
std::cerr << "The image is DDS format" << std::endl;
185+
186+
const DDS_HEADER* pHeader = reinterpret_cast<const DDS_HEADER*>(pData);
187+
pData += sizeof(DDS_HEADER);
188+
189+
assert(pHeader->dwSize == 124);
190+
img.Width = pHeader->dwWidth;
191+
img.Height = pHeader->dwHeight;
192+
img.pitch = pHeader->dwPitchOrLinearSize; //unreliable
193+
assert(pHeader->ddspf.dwSize == 32);
194+
195+
bool hasAlpha = false;
196+
bool isCompressed = false;
197+
if (pHeader->ddspf.dwFlags & 0x1 /* DDPF_ALPHAPIXELS */)
198+
{
199+
hasAlpha = true;
200+
std::cerr << "Alpha: YES" << std::endl;
201+
}
202+
else
203+
{
204+
std::cerr << "Alpha: NO" << std::endl;
205+
}
206+
207+
if (pHeader->ddspf.dwFlags & 0x4 /* DDPF_FOURCC */)
208+
{
209+
isCompressed = true;
210+
std::cerr << "Compressed: ";
211+
const uint32_t* pdwFourCC = &pHeader->ddspf.dwFourCC;
212+
const char* pCC = reinterpret_cast<const char*>(pdwFourCC);
213+
if (pCC[0] != 'D')
214+
{
215+
DXGI_FORMAT format = (DXGI_FORMAT) *pdwFourCC;
216+
}
217+
else
218+
{
219+
std::cerr << pCC[0] << pCC[1] << pCC[2] << pCC[3] << std::endl;
220+
221+
img.bitcount = 0;
222+
223+
if (*pdwFourCC == endian_net_unsigned_int("DXT1"_u32))
224+
{
225+
img.pitch = std::max(1u, ((img.Width + 3) / 4)) * 8;
226+
}
227+
if (*pdwFourCC == endian_net_unsigned_int("DXT2"_u32))
228+
{
229+
img.pitch = std::max(1u, ((img.Width + 3) / 4)) * 16;
230+
}
231+
if (*pdwFourCC == endian_net_unsigned_int("DXT3"_u32))
232+
{
233+
img.pitch = std::max(1u, ((img.Width + 3) / 4)) * 16;
234+
}
235+
if (*pdwFourCC == endian_net_unsigned_int("DXT4"_u32))
236+
{
237+
img.pitch = std::max(1u, ((img.Width + 3) / 4)) * 16;
238+
}
239+
if (*pdwFourCC == endian_net_unsigned_int("DXT5"_u32))
240+
{
241+
img.pitch = std::max(1u, ((img.Width + 3) / 4)) * 16;
242+
}
243+
if (*pdwFourCC == endian_net_unsigned_int("DX10"_u32))
244+
{
245+
const DDS_HEADER_DXT10* pHeaderDXT10 = reinterpret_cast<const DDS_HEADER_DXT10*>(pData);
246+
pData += sizeof(DDS_HEADER_DXT10);
247+
std::cerr << "DXGI_FORMAT: " << pHeaderDXT10->dxgiFormat << std::endl;
248+
}
249+
250+
img.data_size = img.pitch * img.Height / 8;
251+
}
252+
}
253+
else
254+
{
255+
if (!(pHeader->ddspf.dwFlags & 0x40 /* DDPF_RGB */))
256+
{
257+
std::cerr << "We only support RGB color space" << std::endl;
258+
assert(0);
259+
}
260+
261+
img.bitcount = pHeader->ddspf.dwRGBBitCount;
262+
img.pitch = (img.Width * img.bitcount + 7) / 8;
263+
img.data_size = img.pitch * img.Height;
264+
}
265+
266+
267+
assert(img.data_size <= buf.GetDataSize());
268+
269+
img.data = new uint8_t[img.data_size];
270+
memcpy(img.data, pData, img.data_size);
271+
272+
return img;
273+
}
274+
};
275+
}

0 commit comments

Comments
 (0)