//--------------------------------------------------------------------------------------
// File: DDSTextureLoader.cpp
//
// Function for loading a DDS texture and creating a Direct3D 11 runtime resource for it
//
// Note these functions are useful as a light-weight runtime loader for DDS files. For
// a full-featured DDS file reader, writer, and texture processing pipeline see
// the 'Texconv' sample and the 'DirectXTex' library.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// http://go.microsoft.com/fwlink/?LinkId=248926
// http://go.microsoft.com/fwlink/?LinkId=248929
//--------------------------------------------------------------------------------------
#include <pch.h>
#include <dxgiformat.h>
#include <assert.h>
#include <algorithm>
#include <memory>
#include "DDSTextureLoader.h"
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) && !defined(DXGI_1_2_FORMATS)
#define DXGI_1_2_FORMATS
#endif
#if defined(_DEBUG) || defined(PROFILE)
#pragma comment(lib,"dxguid.lib")
#endif
//--------------------------------------------------------------------------------------
// Macros
//--------------------------------------------------------------------------------------
#ifndef MAKEFOURCC
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \
((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
#endif /* defined(MAKEFOURCC) */
//--------------------------------------------------------------------------------------
// DDS file structure definitions
//
// See DDS.h in the 'Texconv' sample and the 'DirectXTex' library
//--------------------------------------------------------------------------------------
#pragma pack(push,1)
#define DDS_MAGIC 0x20534444 // "DDS "
struct DDS_PIXELFORMAT
{
uint32_t size;
uint32_t flags;
uint32_t fourCC;
uint32_t RGBBitCount;
uint32_t RBitMask;
uint32_t GBitMask;
uint32_t BBitMask;
uint32_t ABitMask;
};
#define DDS_FOURCC 0x00000004 // DDPF_FOURCC
#define DDS_RGB 0x00000040 // DDPF_RGB
#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS
#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE
#define DDS_LUMINANCEA 0x00020001 // DDPF_LUMINANCE | DDPF_ALPHAPIXELS
#define DDS_ALPHA 0x00000002 // DDPF_ALPHA
#define DDS_PAL8 0x00000020 // DDPF_PALETTEINDEXED8
#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT
#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT
#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH
#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH
#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE
#define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
#define DDS_WIDTH 0x00000004 // DDSD_WIDTH
#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE
#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP
#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX
#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX
#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX
#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY
#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY
#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ
#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ
#define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
#define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME
typedef struct
{
uint32_t size;
uint32_t flags;
uint32_t height;
uint32_t width;
uint32_t pitchOrLinearSize;
uint32_t depth; // only if DDS_HEADER_FLAGS_VOLUME is set in flags
uint32_t mipMapCount;
uint32_t reserved1[11];
DDS_PIXELFORMAT ddspf;
uint32_t caps;
uint32_t caps2;
uint32_t caps3;
uint32_t caps4;
uint32_t reserved2;
} DDS_HEADER;
typedef struct
{
DXGI_FORMAT dxgiFormat;
uint32_t resourceDimension;
uint32_t miscFlag; // see D3D11_RESOURCE_MISC_FLAG
uint32_t arraySize;
uint32_t reserved;
} DDS_HEADER_DXT10;
#pragma pack(pop)
//---------------------------------------------------------------------------------
struct handle_closer { void operator()(HANDLE h) { if (h) CloseHandle(h); } };
typedef public std::unique_ptr<void, handle_closer> ScopedHandle;
inline HANDLE safe_handle( HANDLE h ) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; }
//--------------------------------------------------------------------------------------
template<UINT TNameLength>
inline void SetDebugObjectName(_In_ ID3D11DeviceChild* resource, _In_ const char (&name)[TNameLength])
{
#if defined(_DEBUG) || defined(PROFILE)
resource->SetPrivateData(WKPDID_D3DDebugObjectName, TNameLength - 1, name);
#endif
}
//--------------------------------------------------------------------------------------
static HRESULT LoadTextureDataFromFile( _In_z_ const wchar_t* fileName,
std::unique_ptr<uint8_t[]>& ddsData,
DDS_HEADER** header,
uint8_t** bitData,
size_t* bitSize
)
{
if (!header || !bitData || !bitSize)
{
return E_POINTER;
}
// open the file
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
ScopedHandle hFile( safe_handle( CreateFile2( fileName,
GENERIC_READ,
FILE_SHARE_READ,
OPEN_EXISTING,
nullptr ) ) );
#else
ScopedHandle hFile( safe_handle( CreateFileW( fileName,
GENERIC_READ,
FILE_SHARE_READ,
nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
nullptr ) ) );
#endif
if ( !hFile )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
// Get the file size
LARGE_INTEGER FileSize = { 0 };
#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
FILE_STANDARD_INFO fileInfo;
if ( !GetFileInformationByHandleEx( hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo) ) )
{
return HRESULT_FROM_WIN32( GetLastError() );
}
FileSize = fileInfo.EndOfFile;
#else
GetFileSizeEx( hFile.get(), &FileSize );
#endif
// File is too big for 32-bit allocation, so reject read
if (FileSize.HighPart > 0)
{
return E_FAIL;
}
// Need at least enough data to fill the header and magic number to be a valid DDS
- 1
- 2
- 3
前往页