summaryrefslogtreecommitdiffstats
path: root/Projects/Asteroids/src
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2017-05-20 20:20:23 +0000
committerEgor Yusov <egor.yusov@gmail.com>2017-05-20 20:20:23 +0000
commitcdd751dc2f5bf0851c795587aab4fd547e95b6a8 (patch)
treec20f440a9a092ec8f655e38f30cab522a4933f93 /Projects/Asteroids/src
parentUpdated submodules (diff)
downloadDiligentEngine-cdd751dc2f5bf0851c795587aab4fd547e95b6a8.tar.gz
DiligentEngine-cdd751dc2f5bf0851c795587aab4fd547e95b6a8.zip
Added asteroids sample
Diffstat (limited to 'Projects/Asteroids/src')
-rw-r--r--Projects/Asteroids/src/DDSTextureLoader.cpp1103
-rw-r--r--Projects/Asteroids/src/DDSTextureLoader.h18
-rw-r--r--Projects/Asteroids/src/WinWrapper.cpp616
-rw-r--r--Projects/Asteroids/src/asteroid_ps.hlsl50
-rw-r--r--Projects/Asteroids/src/asteroid_ps_d3d11.hlsl56
-rw-r--r--Projects/Asteroids/src/asteroid_vs.hlsl36
-rw-r--r--Projects/Asteroids/src/asteroids_DE.cpp870
-rw-r--r--Projects/Asteroids/src/asteroids_DE.h123
-rw-r--r--Projects/Asteroids/src/asteroids_d3d11.cpp594
-rw-r--r--Projects/Asteroids/src/asteroids_d3d11.h108
-rw-r--r--Projects/Asteroids/src/asteroids_d3d12.cpp938
-rw-r--r--Projects/Asteroids/src/asteroids_d3d12.h182
-rw-r--r--Projects/Asteroids/src/asteroids_d3d12.icobin0 -> 2998 bytes
-rw-r--r--Projects/Asteroids/src/camera.cpp170
-rw-r--r--Projects/Asteroids/src/camera.h62
-rw-r--r--Projects/Asteroids/src/common.hlsl45
-rw-r--r--Projects/Asteroids/src/common_defines.h6
-rw-r--r--Projects/Asteroids/src/dds.h145
-rw-r--r--Projects/Asteroids/src/descriptor.h165
-rw-r--r--Projects/Asteroids/src/font.h98
-rw-r--r--Projects/Asteroids/src/font_ps.hlsl12
-rw-r--r--Projects/Asteroids/src/gui.h149
-rw-r--r--Projects/Asteroids/src/intel_clear_bd_50_usascii.inl920
-rw-r--r--Projects/Asteroids/src/mesh.cpp352
-rw-r--r--Projects/Asteroids/src/mesh.h74
-rw-r--r--Projects/Asteroids/src/noise.h57
-rw-r--r--Projects/Asteroids/src/settings.h92
-rw-r--r--Projects/Asteroids/src/simplexnoise1234.c499
-rw-r--r--Projects/Asteroids/src/simplexnoise1234.h70
-rw-r--r--Projects/Asteroids/src/simulation.cpp250
-rw-r--r--Projects/Asteroids/src/simulation.h90
-rw-r--r--Projects/Asteroids/src/skybox_ps.hlsl16
-rw-r--r--Projects/Asteroids/src/skybox_vs.hlsl20
-rw-r--r--Projects/Asteroids/src/sprite.h36
-rw-r--r--Projects/Asteroids/src/sprite_ps.hlsl11
-rw-r--r--Projects/Asteroids/src/sprite_vs.hlsl14
-rw-r--r--Projects/Asteroids/src/stb_font_consolas_bold_50_usascii.inl1195
-rw-r--r--Projects/Asteroids/src/subset_d3d12.h50
-rw-r--r--Projects/Asteroids/src/texture.cpp285
-rw-r--r--Projects/Asteroids/src/texture.h46
-rw-r--r--Projects/Asteroids/src/upload_heap.h60
-rw-r--r--Projects/Asteroids/src/util.h79
42 files changed, 9762 insertions, 0 deletions
diff --git a/Projects/Asteroids/src/DDSTextureLoader.cpp b/Projects/Asteroids/src/DDSTextureLoader.cpp
new file mode 100644
index 0000000..97e1064
--- /dev/null
+++ b/Projects/Asteroids/src/DDSTextureLoader.cpp
@@ -0,0 +1,1103 @@
+//--------------------------------------------------------------------------------------
+// File: DDSTextureLoader.cpp
+//
+// Functions for loading a DDS texture without using D3DX
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//--------------------------------------------------------------------------------------
+//#include "DXUT.h"
+#include "DDSTextureLoader.h"
+#include <d3d9.h> // For D3DFMT stuff
+
+#include <assert.h>
+#include <algorithm>
+using std::max;
+using std::min;
+
+#define SAFE_DELETE_ARRAY(a) if(a) { delete[] a; a=nullptr; }
+#define SAFE_RELEASE(a) if(a) { a->Release(); a=nullptr; }
+
+
+// From DXUT
+//--------------------------------------------------------------------------------------
+// Helper functions to create SRGB formats from typeless formats and vice versa
+//--------------------------------------------------------------------------------------
+DXGI_FORMAT MAKE_SRGB( _In_ DXGI_FORMAT format )
+{
+ switch( format )
+ {
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ return DXGI_FORMAT_BC1_UNORM_SRGB;
+
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ return DXGI_FORMAT_BC2_UNORM_SRGB;
+
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ return DXGI_FORMAT_BC3_UNORM_SRGB;
+
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
+
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
+
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ return DXGI_FORMAT_BC7_UNORM_SRGB;
+ };
+
+ return format;
+}
+
+
+//--------------------------------------------------------------------------------------
+HRESULT LoadTextureDataFromFile( __in_z const WCHAR* szFileName, BYTE** ppHeapData,
+ DDS_HEADER** ppHeader,
+ BYTE** ppBitData, UINT* pBitSize )
+{
+ // open the file
+ HANDLE hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+ FILE_FLAG_SEQUENTIAL_SCAN, NULL );
+ if( INVALID_HANDLE_VALUE == hFile )
+ return HRESULT_FROM_WIN32( GetLastError() );
+
+ // Get the file size
+ LARGE_INTEGER FileSize = {0};
+ GetFileSizeEx( hFile, &FileSize );
+
+ // File is too big for 32-bit allocation, so reject read
+ if( FileSize.HighPart > 0 )
+ {
+ CloseHandle( hFile );
+ return E_FAIL;
+ }
+
+ // Need at least enough data to fill the header and magic number to be a valid DDS
+ if( FileSize.LowPart < (sizeof(DDS_HEADER)+sizeof(DWORD)) )
+ {
+ CloseHandle( hFile );
+ return E_FAIL;
+ }
+
+ // create enough space for the file data
+ *ppHeapData = new BYTE[ FileSize.LowPart ];
+ if( !( *ppHeapData ) )
+ {
+ CloseHandle( hFile );
+ return E_OUTOFMEMORY;
+ }
+
+ // read the data in
+ DWORD BytesRead = 0;
+ if( !ReadFile( hFile, *ppHeapData, FileSize.LowPart, &BytesRead, NULL ) )
+ {
+ CloseHandle( hFile );
+ SAFE_DELETE_ARRAY( *ppHeapData );
+ return HRESULT_FROM_WIN32( GetLastError() );
+ }
+
+ if( BytesRead < FileSize.LowPart )
+ {
+ CloseHandle( hFile );
+ SAFE_DELETE_ARRAY( *ppHeapData );
+ return E_FAIL;
+ }
+
+ // DDS files always start with the same magic number ("DDS ")
+ DWORD dwMagicNumber = *( DWORD* )( *ppHeapData );
+ if( dwMagicNumber != DDS_MAGIC )
+ {
+ CloseHandle( hFile );
+ SAFE_DELETE_ARRAY( *ppHeapData );
+ return E_FAIL;
+ }
+
+ DDS_HEADER* pHeader = reinterpret_cast<DDS_HEADER*>( *ppHeapData + sizeof( DWORD ) );
+
+ // Verify header to validate DDS file
+ if( pHeader->dwSize != sizeof(DDS_HEADER)
+ || pHeader->ddspf.dwSize != sizeof(DDS_PIXELFORMAT) )
+ {
+ CloseHandle( hFile );
+ SAFE_DELETE_ARRAY( *ppHeapData );
+ return E_FAIL;
+ }
+
+ // Check for DX10 extension
+ bool bDXT10Header = false;
+ if ( (pHeader->ddspf.dwFlags & DDS_FOURCC)
+ && (MAKEFOURCC( 'D', 'X', '1', '0' ) == pHeader->ddspf.dwFourCC) )
+ {
+ // Must be long enough for both headers and magic value
+ if( FileSize.LowPart < (sizeof(DDS_HEADER)+sizeof(DWORD)+sizeof(DDS_HEADER_DXT10)) )
+ {
+ CloseHandle( hFile );
+ SAFE_DELETE_ARRAY( *ppHeapData );
+ return E_FAIL;
+ }
+
+ bDXT10Header = true;
+ }
+
+ // setup the pointers in the process request
+ *ppHeader = pHeader;
+ INT offset = sizeof( DWORD ) + sizeof( DDS_HEADER )
+ + (bDXT10Header ? sizeof( DDS_HEADER_DXT10 ) : 0);
+ *ppBitData = *ppHeapData + offset;
+ *pBitSize = FileSize.LowPart - offset;
+
+ CloseHandle( hFile );
+
+ return S_OK;
+}
+
+
+static UINT BitsPerPixel( DXGI_FORMAT fmt )
+{
+ switch( fmt )
+ {
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ return 128;
+
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ case DXGI_FORMAT_R32G32B32_UINT:
+ case DXGI_FORMAT_R32G32B32_SINT:
+ return 96;
+
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ case DXGI_FORMAT_R32G32_FLOAT:
+ case DXGI_FORMAT_R32G32_UINT:
+ case DXGI_FORMAT_R32G32_SINT:
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ return 64;
+
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ case DXGI_FORMAT_R16G16_FLOAT:
+ case DXGI_FORMAT_R16G16_UNORM:
+ case DXGI_FORMAT_R16G16_UINT:
+ case DXGI_FORMAT_R16G16_SNORM:
+ case DXGI_FORMAT_R16G16_SINT:
+ case DXGI_FORMAT_R32_TYPELESS:
+ case DXGI_FORMAT_D32_FLOAT:
+ case DXGI_FORMAT_R32_FLOAT:
+ case DXGI_FORMAT_R32_UINT:
+ case DXGI_FORMAT_R32_SINT:
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ return 32;
+
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ case DXGI_FORMAT_R8G8_UNORM:
+ case DXGI_FORMAT_R8G8_UINT:
+ case DXGI_FORMAT_R8G8_SNORM:
+ case DXGI_FORMAT_R8G8_SINT:
+ case DXGI_FORMAT_R16_TYPELESS:
+ case DXGI_FORMAT_R16_FLOAT:
+ case DXGI_FORMAT_D16_UNORM:
+ case DXGI_FORMAT_R16_UNORM:
+ case DXGI_FORMAT_R16_UINT:
+ case DXGI_FORMAT_R16_SNORM:
+ case DXGI_FORMAT_R16_SINT:
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ return 16;
+
+ case DXGI_FORMAT_R8_TYPELESS:
+ case DXGI_FORMAT_R8_UNORM:
+ case DXGI_FORMAT_R8_UINT:
+ case DXGI_FORMAT_R8_SNORM:
+ case DXGI_FORMAT_R8_SINT:
+ case DXGI_FORMAT_A8_UNORM:
+ return 8;
+
+ case DXGI_FORMAT_R1_UNORM:
+ return 1;
+
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC4_SNORM:
+ return 4;
+
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC5_SNORM:
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC6H_SF16:
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ return 8;
+
+ default:
+ return 0;
+ }
+}
+
+
+static void GetSurfaceInfo( UINT width, UINT height, DXGI_FORMAT fmt, UINT* pNumBytes, UINT* pRowBytes, UINT* pNumRows )
+{
+ UINT numBytes = 0;
+ UINT rowBytes = 0;
+ UINT numRows = 0;
+
+ bool bc = false;
+ bool packed = false;
+ UINT bcnumBytesPerBlock = 0;
+ switch (fmt)
+ {
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC4_SNORM:
+ bc=true;
+ bcnumBytesPerBlock = 8;
+ break;
+
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC5_SNORM:
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC6H_SF16:
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ bc = true;
+ bcnumBytesPerBlock = 16;
+ break;
+
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ packed = true;
+ break;
+ }
+
+ if( bc )
+ {
+ int numBlocksWide = 0;
+ if( width > 0 )
+ numBlocksWide = max( 1U, (width + 3) / 4 );
+ int numBlocksHigh = 0;
+ if( height > 0 )
+ numBlocksHigh = max( 1U, (height + 3) / 4 );
+ rowBytes = numBlocksWide * bcnumBytesPerBlock;
+ numRows = numBlocksHigh;
+ }
+ else if ( packed )
+ {
+ rowBytes = ( ( width + 1 ) >> 1 ) * 4;
+ numRows = height;
+ }
+ else
+ {
+ UINT bpp = BitsPerPixel( fmt );
+ rowBytes = ( width * bpp + 7 ) / 8; // round up to nearest byte
+ numRows = height;
+ }
+
+ numBytes = rowBytes * numRows;
+ if( pNumBytes != NULL )
+ *pNumBytes = numBytes;
+ if( pRowBytes != NULL )
+ *pRowBytes = rowBytes;
+ if( pNumRows != NULL )
+ *pNumRows = numRows;
+}
+
+
+//--------------------------------------------------------------------------------------
+#define ISBITMASK( r,g,b,a ) ( ddpf.dwRBitMask == r && ddpf.dwGBitMask == g && ddpf.dwBBitMask == b && ddpf.dwABitMask == a )
+
+//--------------------------------------------------------------------------------------
+static D3DFORMAT GetD3D9Format( const DDS_PIXELFORMAT& ddpf )
+{
+ if( ddpf.dwFlags & DDS_RGB )
+ {
+ switch (ddpf.dwRGBBitCount)
+ {
+ case 32:
+ if( ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0xff000000) )
+ return D3DFMT_A8R8G8B8;
+ if( ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0x00000000) )
+ return D3DFMT_X8R8G8B8;
+ if( ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0xff000000) )
+ return D3DFMT_A8B8G8R8;
+ if( ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0x00000000) )
+ return D3DFMT_X8B8G8R8;
+
+ // Note that many common DDS reader/writers (including D3DX) swap the
+ // the RED/BLUE masks for 10:10:10:2 formats. We assumme
+ // below that the 'incorrect' header mask is being used
+
+ // For 'correct' writers this should be 0x3ff00000,0x000ffc00,0x000003ff for BGR data
+ if( ISBITMASK(0x000003ff,0x000ffc00,0x3ff00000,0xc0000000) )
+ return D3DFMT_A2R10G10B10;
+
+ // For 'correct' writers this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data
+ if( ISBITMASK(0x3ff00000,0x000ffc00,0x000003ff,0xc0000000) )
+ return D3DFMT_A2B10G10R10;
+
+ if( ISBITMASK(0x0000ffff,0xffff0000,0x00000000,0x00000000) )
+ return D3DFMT_G16R16;
+ if( ISBITMASK(0xffffffff,0x00000000,0x00000000,0x00000000) )
+ return D3DFMT_R32F; // D3DX writes this out as a FourCC of 114
+ break;
+
+ case 24:
+ if( ISBITMASK(0x00ff0000,0x0000ff00,0x000000ff,0x00000000) )
+ return D3DFMT_R8G8B8;
+ break;
+
+ case 16:
+ if( ISBITMASK(0x0000f800,0x000007e0,0x0000001f,0x00000000) )
+ return D3DFMT_R5G6B5;
+ if( ISBITMASK(0x00007c00,0x000003e0,0x0000001f,0x00008000) )
+ return D3DFMT_A1R5G5B5;
+ if( ISBITMASK(0x00007c00,0x000003e0,0x0000001f,0x00000000) )
+ return D3DFMT_X1R5G5B5;
+ if( ISBITMASK(0x00000f00,0x000000f0,0x0000000f,0x0000f000) )
+ return D3DFMT_A4R4G4B4;
+ if( ISBITMASK(0x00000f00,0x000000f0,0x0000000f,0x00000000) )
+ return D3DFMT_X4R4G4B4;
+
+ // 3:3:2, 3:3:2:8, and paletted texture formats are typically not supported on modern video cards
+ break;
+ }
+ }
+ else if( ddpf.dwFlags & DDS_LUMINANCE )
+ {
+ if( 8 == ddpf.dwRGBBitCount )
+ {
+ if( ISBITMASK(0x0000000f,0x00000000,0x00000000,0x000000f0) )
+ return D3DFMT_A4L4;
+ if( ISBITMASK(0x000000ff,0x00000000,0x00000000,0x00000000) )
+ return D3DFMT_L8;
+ }
+
+ if( 16 == ddpf.dwRGBBitCount )
+ {
+ if( ISBITMASK(0x0000ffff,0x00000000,0x00000000,0x00000000) )
+ return D3DFMT_L16;
+ if( ISBITMASK(0x000000ff,0x00000000,0x00000000,0x0000ff00) )
+ return D3DFMT_A8L8;
+ }
+ }
+ else if( ddpf.dwFlags & DDS_ALPHA )
+ {
+ if( 8 == ddpf.dwRGBBitCount )
+ {
+ return D3DFMT_A8;
+ }
+ }
+ else if( ddpf.dwFlags & DDS_FOURCC )
+ {
+ if( MAKEFOURCC( 'D', 'X', 'T', '1' ) == ddpf.dwFourCC )
+ return D3DFMT_DXT1;
+ if( MAKEFOURCC( 'D', 'X', 'T', '2' ) == ddpf.dwFourCC )
+ return D3DFMT_DXT2;
+ if( MAKEFOURCC( 'D', 'X', 'T', '3' ) == ddpf.dwFourCC )
+ return D3DFMT_DXT3;
+ if( MAKEFOURCC( 'D', 'X', 'T', '4' ) == ddpf.dwFourCC )
+ return D3DFMT_DXT4;
+ if( MAKEFOURCC( 'D', 'X', 'T', '5' ) == ddpf.dwFourCC )
+ return D3DFMT_DXT5;
+
+ if( MAKEFOURCC( 'R', 'G', 'B', 'G' ) == ddpf.dwFourCC )
+ return D3DFMT_R8G8_B8G8;
+ if( MAKEFOURCC( 'G', 'R', 'G', 'B' ) == ddpf.dwFourCC )
+ return D3DFMT_G8R8_G8B8;
+
+ if( MAKEFOURCC( 'U', 'Y', 'V', 'Y' ) == ddpf.dwFourCC )
+ return D3DFMT_UYVY;
+ if( MAKEFOURCC( 'Y', 'U', 'Y', '2' ) == ddpf.dwFourCC )
+ return D3DFMT_YUY2;
+
+ // Check for D3DFORMAT enums being set here
+ switch( ddpf.dwFourCC )
+ {
+ case D3DFMT_A16B16G16R16:
+ case D3DFMT_Q16W16V16U16:
+ case D3DFMT_R16F:
+ case D3DFMT_G16R16F:
+ case D3DFMT_A16B16G16R16F:
+ case D3DFMT_R32F:
+ case D3DFMT_G32R32F:
+ case D3DFMT_A32B32G32R32F:
+ case D3DFMT_CxV8U8:
+ return (D3DFORMAT)ddpf.dwFourCC;
+ }
+ }
+
+ return D3DFMT_UNKNOWN;
+}
+
+//--------------------------------------------------------------------------------------
+DXGI_FORMAT GetDXGIFormat( const DDS_PIXELFORMAT& ddpf )
+{
+ if( ddpf.dwFlags & DDS_RGB )
+ {
+ switch (ddpf.dwRGBBitCount)
+ {
+ case 32:
+ // DXGI_FORMAT_B8G8R8A8_UNORM_SRGB & DXGI_FORMAT_B8G8R8X8_UNORM_SRGB should be
+ // written using the DX10 extended header instead since these formats require
+ // DXGI 1.1
+ //
+ // This code will use the fallback to swizzle BGR to RGB in memory for standard
+ // DDS files which works on 10 and 10.1 devices with WDDM 1.0 drivers
+ //
+ // NOTE: We don't use DXGI_FORMAT_B8G8R8X8_UNORM or DXGI_FORMAT_B8G8R8X8_UNORM
+ // here because they were defined for DXGI 1.0 but were not required for D3D10/10.1
+
+ if( ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0xff000000) )
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+
+ // No D3DFMT_X8B8G8R8 in DXGI. We'll deal with it in a swizzle case to ensure
+ // alpha channel is 255 (don't care formats could contain garbage)
+
+ // Note that many common DDS reader/writers (including D3DX) swap the
+ // the RED/BLUE masks for 10:10:10:2 formats. We assumme
+ // below that the 'backwards' header mask is being used since it is most
+ // likely written by D3DX. The more robust solution is to use the 'DX10'
+ // header extension and specify the DXGI_FORMAT_R10G10B10A2_UNORM format directly
+
+ // For 'correct' writers, this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data
+ if( ISBITMASK(0x3ff00000,0x000ffc00,0x000003ff,0xc0000000) )
+ return DXGI_FORMAT_R10G10B10A2_UNORM;
+
+ if( ISBITMASK(0x0000ffff,0xffff0000,0x00000000,0x00000000) )
+ return DXGI_FORMAT_R16G16_UNORM;
+
+ if( ISBITMASK(0xffffffff,0x00000000,0x00000000,0x00000000) )
+ // Only 32-bit color channel format in D3D9 was R32F
+ return DXGI_FORMAT_R32_FLOAT; // D3DX writes this out as a FourCC of 114
+ break;
+
+ case 24:
+ // No 24bpp DXGI formats
+ break;
+
+ case 16:
+ // 5:5:5 & 5:6:5 formats are defined for DXGI, but are deprecated for D3D10, 10.0, and 11
+
+ // No 4bpp, 3:3:2, 3:3:2:8, or paletted DXGI formats
+ break;
+ }
+ }
+ else if( ddpf.dwFlags & DDS_LUMINANCE )
+ {
+ if( 8 == ddpf.dwRGBBitCount )
+ {
+ if( ISBITMASK(0x000000ff,0x00000000,0x00000000,0x00000000) )
+ return DXGI_FORMAT_R8_UNORM; // D3DX10/11 writes this out as DX10 extension
+
+ // No 4bpp DXGI formats
+ }
+
+ if( 16 == ddpf.dwRGBBitCount )
+ {
+ if( ISBITMASK(0x0000ffff,0x00000000,0x00000000,0x00000000) )
+ return DXGI_FORMAT_R16_UNORM; // D3DX10/11 writes this out as DX10 extension
+ if( ISBITMASK(0x000000ff,0x00000000,0x00000000,0x0000ff00) )
+ return DXGI_FORMAT_R8G8_UNORM; // D3DX10/11 writes this out as DX10 extension
+ }
+ }
+ else if( ddpf.dwFlags & DDS_ALPHA )
+ {
+ if( 8 == ddpf.dwRGBBitCount )
+ {
+ return DXGI_FORMAT_A8_UNORM;
+ }
+ }
+ else if( ddpf.dwFlags & DDS_FOURCC )
+ {
+ if( MAKEFOURCC( 'D', 'X', 'T', '1' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC1_UNORM;
+ if( MAKEFOURCC( 'D', 'X', 'T', '3' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC2_UNORM;
+ if( MAKEFOURCC( 'D', 'X', 'T', '5' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC3_UNORM;
+
+ // While pre-mulitplied alpha isn't directly supported by the DXGI formats,
+ // they are basically the same as these BC formats so they can be mapped
+ if( MAKEFOURCC( 'D', 'X', 'T', '2' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC2_UNORM;
+ if( MAKEFOURCC( 'D', 'X', 'T', '4' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC3_UNORM;
+
+ if( MAKEFOURCC( 'A', 'T', 'I', '1' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC4_UNORM;
+ if( MAKEFOURCC( 'B', 'C', '4', 'U' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC4_UNORM;
+ if( MAKEFOURCC( 'B', 'C', '4', 'S' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC4_SNORM;
+
+ if( MAKEFOURCC( 'A', 'T', 'I', '2' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC5_UNORM;
+ if( MAKEFOURCC( 'B', 'C', '5', 'U' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC5_UNORM;
+ if( MAKEFOURCC( 'B', 'C', '5', 'S' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_BC5_SNORM;
+
+ if( MAKEFOURCC( 'R', 'G', 'B', 'G' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_R8G8_B8G8_UNORM;
+ if( MAKEFOURCC( 'G', 'R', 'G', 'B' ) == ddpf.dwFourCC )
+ return DXGI_FORMAT_G8R8_G8B8_UNORM;
+
+ // Check for D3DFORMAT enums being set here
+ switch( ddpf.dwFourCC )
+ {
+ case D3DFMT_A16B16G16R16: // 36
+ return DXGI_FORMAT_R16G16B16A16_UNORM;
+
+ case D3DFMT_Q16W16V16U16: // 110
+ return DXGI_FORMAT_R16G16B16A16_SNORM;
+
+ case D3DFMT_R16F: // 111
+ return DXGI_FORMAT_R16_FLOAT;
+
+ case D3DFMT_G16R16F: // 112
+ return DXGI_FORMAT_R16G16_FLOAT;
+
+ case D3DFMT_A16B16G16R16F: // 113
+ return DXGI_FORMAT_R16G16B16A16_FLOAT;
+
+ case D3DFMT_R32F: // 114
+ return DXGI_FORMAT_R32_FLOAT;
+
+ case D3DFMT_G32R32F: // 115
+ return DXGI_FORMAT_R32G32_FLOAT;
+
+ case D3DFMT_A32B32G32R32F: // 116
+ return DXGI_FORMAT_R32G32B32A32_FLOAT;
+ }
+ }
+
+ return DXGI_FORMAT_UNKNOWN;
+}
+
+
+//--------------------------------------------------------------------------------------
+static HRESULT CreateTextureFromDDS( ID3D11Device* pDev, DDS_HEADER* pHeader, __inout_bcount(BitSize) BYTE* pBitData,
+ UINT BitSize, __out ID3D11ShaderResourceView** ppSRV, bool bSRGB )
+{
+ HRESULT hr = S_OK;
+
+ UINT iWidth = pHeader->dwWidth;
+ UINT iHeight = pHeader->dwHeight;
+ UINT iDepth = pHeader->dwDepth;
+
+ UINT resDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
+ UINT arraySize = 1;
+ DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
+ bool isCubeMap = false;
+
+ UINT iMipCount = pHeader->dwMipMapCount;
+ if( 0 == iMipCount )
+ iMipCount = 1;
+
+ bool swaprgb = false;
+ bool seta = false;
+
+ if ((pHeader->ddspf.dwFlags & DDS_FOURCC)
+ && (MAKEFOURCC( 'D', 'X', '1', '0' ) == pHeader->ddspf.dwFourCC ) )
+ {
+ DDS_HEADER_DXT10* d3d10ext = (DDS_HEADER_DXT10*)( (char*)pHeader + sizeof(DDS_HEADER) );
+
+ arraySize = d3d10ext->arraySize;
+ if ( arraySize == 0 )
+ return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
+
+ if ( BitsPerPixel( d3d10ext->dxgiFormat ) == 0 )
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+ format = d3d10ext->dxgiFormat;
+
+ switch ( d3d10ext->resourceDimension )
+ {
+ case DDS_DIMENSION_TEXTURE1D:
+ // D3DX writes 1D textures with a fixed Height of 1
+ if ( (pHeader->dwFlags & DDS_HEIGHT) && iHeight != 1 )
+ return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
+ iHeight = iDepth = 1;
+ break;
+
+ case DDS_DIMENSION_TEXTURE2D:
+ if ( d3d10ext->miscFlag & DDS_RESOURCE_MISC_TEXTURECUBE )
+ {
+ arraySize *= 6;
+ isCubeMap = true;
+ }
+ iDepth = 1;
+ break;
+
+ case DDS_DIMENSION_TEXTURE3D:
+ if ( !(pHeader->dwFlags & DDS_HEADER_FLAGS_VOLUME) )
+ return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
+
+ if ( arraySize > 1 )
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+ break;
+
+ default:
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+ }
+
+ resDim = d3d10ext->resourceDimension;
+ }
+ else
+ {
+ format = GetDXGIFormat( pHeader->ddspf );
+
+ if ( pHeader->dwFlags & DDS_HEADER_FLAGS_VOLUME )
+ {
+ resDim = DDS_DIMENSION_TEXTURE3D;
+ }
+ else
+ {
+ if ( pHeader->dwCaps2 & DDS_CUBEMAP )
+ {
+ // We require all six faces to be defined
+ if ( (pHeader->dwCaps2 & DDS_CUBEMAP_ALLFACES ) != DDS_CUBEMAP_ALLFACES )
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+ arraySize = 6;
+ isCubeMap = true;
+ }
+
+ iDepth = 1;
+ resDim = DDS_DIMENSION_TEXTURE2D;
+
+ // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
+ }
+
+ if ( format == DXGI_FORMAT_UNKNOWN )
+ {
+ D3DFORMAT fmt = GetD3D9Format( pHeader->ddspf );
+
+ switch( fmt )
+ {
+ case D3DFMT_X8R8G8B8:
+ format = DXGI_FORMAT_B8G8R8A8_UNORM; // NOTE: DXGI1.1 requirement is fine here
+ seta = true;
+ break;
+
+ case D3DFMT_A8R8G8B8:
+ format = DXGI_FORMAT_B8G8R8A8_UNORM; // NOTE: DXGI1.1 requirement is fine here
+ break;
+
+ case D3DFMT_X8B8G8R8:
+ format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ seta = true;
+ break;
+
+ case D3DFMT_A2R10G10B10:
+ format = DXGI_FORMAT_R10G10B10A2_UNORM;
+ swaprgb = TRUE;
+ break;
+
+ // Would need temp memory to expand other formats (24bpp, 4bpp, 16-bit (5:6:5, 5:5:5, 5:5:5:1), 3:3:2, 3:3:2:8)
+
+ default:
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+ }
+ }
+
+ assert( BitsPerPixel( format ) != 0 );
+ }
+
+ // Bound sizes
+ if ( iMipCount > D3D11_REQ_MIP_LEVELS )
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+
+ switch ( resDim )
+ {
+ case DDS_DIMENSION_TEXTURE1D:
+ if ( (arraySize > D3D11_REQ_TEXTURE1D_ARRAY_AXIS_DIMENSION)
+ || (iWidth > D3D11_REQ_TEXTURE1D_U_DIMENSION) )
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+ break;
+
+ case DDS_DIMENSION_TEXTURE2D:
+ if ( isCubeMap )
+ {
+ // This is the right bound because we set arraySize to (NumCubes*6) above
+ if ( (arraySize > D3D11_REQ_TEXTURECUBE_DIMENSION)
+ || (iWidth > D3D11_REQ_TEXTURECUBE_DIMENSION)
+ || (iHeight > D3D11_REQ_TEXTURECUBE_DIMENSION))
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+ }
+ else if ( (arraySize > D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION)
+ || (iWidth > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION)
+ || (iHeight > D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION))
+ {
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+ }
+ break;
+
+ case DDS_DIMENSION_TEXTURE3D:
+ if ( (arraySize > 1)
+ || (iWidth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
+ || (iHeight > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION)
+ || (iDepth > D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION) )
+ return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
+ break;
+ }
+
+
+ if ( bSRGB )
+ format = MAKE_SRGB( format );
+
+ // Create the texture
+ D3D11_SUBRESOURCE_DATA* pInitData = new D3D11_SUBRESOURCE_DATA[ iMipCount * arraySize ];
+ if( !pInitData )
+ return E_OUTOFMEMORY;
+
+ UINT NumBytes = 0;
+ UINT RowBytes = 0;
+ UINT NumRows = 0;
+ BYTE* pSrcBits = pBitData;
+ const BYTE *pEndBits = pBitData + BitSize;
+
+ UINT index = 0;
+ for( UINT j = 0; j < arraySize; j++ )
+ {
+ UINT w = iWidth;
+ UINT h = iHeight;
+ UINT d = iDepth;
+ for( UINT i = 0; i < iMipCount; i++ )
+ {
+ GetSurfaceInfo( w, h, format, &NumBytes, &RowBytes, &NumRows );
+
+ pInitData[index].pSysMem = ( void* )pSrcBits;
+ pInitData[index].SysMemPitch = RowBytes;
+ pInitData[index].SysMemSlicePitch = NumBytes;
+ ++index;
+
+ if ( pSrcBits + (NumBytes*d) > pEndBits )
+ {
+ SAFE_DELETE_ARRAY( pInitData );
+ return HRESULT_FROM_WIN32( ERROR_HANDLE_EOF );
+ }
+
+ if ( swaprgb || seta )
+ {
+ switch( format )
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ BYTE *sptr = pSrcBits;
+ for ( UINT slice = 0; slice < d; ++slice )
+ {
+ BYTE *rptr = sptr;
+ for ( UINT row = 0; row < NumRows; ++row )
+ {
+ BYTE *ptr = rptr;
+ for( UINT x = 0; x < w; ++x, ptr += 4 )
+ {
+ if ( ptr + 4 <= pEndBits )
+ {
+ if ( swaprgb )
+ {
+ BYTE a = ptr[0];
+ ptr[0] = ptr[2];
+ ptr[2] = a;
+ }
+ if ( seta )
+ ptr[3] = 255;
+ }
+ }
+ rptr += RowBytes;
+ }
+ sptr += NumBytes;
+ }
+ }
+ break;
+
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ {
+ BYTE *sptr = pSrcBits;
+ for ( UINT slice = 0; slice < d; ++slice )
+ {
+ const BYTE *rptr = sptr;
+ for ( UINT row = 0; row < NumRows; ++row )
+ {
+ DWORD *ptr = (DWORD*)rptr;
+ for( UINT x = 0; x < w; ++x, ++ptr )
+ {
+ if ( ptr + 1 <= (DWORD*)pEndBits )
+ {
+ DWORD t = *ptr;
+ DWORD u = (t & 0x3ff00000) >> 20;
+ DWORD v = (t & 0x000003ff) << 20;
+ *ptr = ( t & ~0x3ff003ff ) | u | v;
+ }
+ }
+ rptr += RowBytes;
+ }
+ sptr += NumBytes;
+ }
+ }
+ break;
+ }
+ }
+
+ pSrcBits += NumBytes * d;
+
+ w = w >> 1;
+ h = h >> 1;
+ d = d >> 1;
+ if( w == 0 )
+ w = 1;
+ if( h == 0 )
+ h = 1;
+ if( d == 0 )
+ d = 1;
+ }
+ }
+
+ switch ( resDim )
+ {
+ case DDS_DIMENSION_TEXTURE1D:
+ {
+ D3D11_TEXTURE1D_DESC desc;
+ desc.Width = iWidth;
+ desc.MipLevels = iMipCount;
+ desc.ArraySize = arraySize;
+ desc.Format = format;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ ID3D11Texture1D* pTex = NULL;
+ hr = pDev->CreateTexture1D( &desc, pInitData, &pTex );
+ if( SUCCEEDED( hr ) && pTex )
+ {
+#if defined(DEBUG) || defined(PROFILE)
+ pTex->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof("DDSTextureLoader")-1, "DDSTextureLoader" );
+#endif
+ D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
+ memset( &SRVDesc, 0, sizeof( SRVDesc ) );
+ SRVDesc.Format = format;
+
+ if ( arraySize > 1 )
+ {
+ SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1DARRAY;
+ SRVDesc.Texture1DArray.MipLevels = desc.MipLevels;
+ SRVDesc.Texture1DArray.ArraySize = arraySize;
+ }
+ else
+ {
+ SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE1D;
+ SRVDesc.Texture1D.MipLevels = desc.MipLevels;
+ }
+
+ hr = pDev->CreateShaderResourceView( pTex, &SRVDesc, ppSRV );
+ SAFE_RELEASE( pTex );
+ }
+ }
+ break;
+
+ case DDS_DIMENSION_TEXTURE2D:
+ {
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = iWidth;
+ desc.Height = iHeight;
+ desc.MipLevels = iMipCount;
+ desc.ArraySize = arraySize;
+ desc.Format = format;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = (isCubeMap) ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0;
+
+ ID3D11Texture2D* pTex = NULL;
+ hr = pDev->CreateTexture2D( &desc, pInitData, &pTex );
+ if( SUCCEEDED( hr ) && pTex )
+ {
+#if defined(DEBUG) || defined(PROFILE)
+ pTex->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof("DDSTextureLoader")-1, "DDSTextureLoader" );
+#endif
+ D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
+ memset( &SRVDesc, 0, sizeof( SRVDesc ) );
+ SRVDesc.Format = format;
+
+ if ( isCubeMap )
+ {
+ if ( arraySize > 6 )
+ {
+ SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBEARRAY;
+ SRVDesc.TextureCubeArray.MipLevels = desc.MipLevels;
+
+ // Earlier we set arraySize to (NumCubes * 6)
+ SRVDesc.TextureCubeArray.NumCubes = arraySize / 6;
+ }
+ else
+ {
+ SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURECUBE;
+ SRVDesc.TextureCube.MipLevels = desc.MipLevels;
+ }
+ }
+ else if ( arraySize > 1 )
+ {
+ SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2DARRAY;
+ SRVDesc.Texture2DArray.MipLevels = desc.MipLevels;
+ SRVDesc.Texture2DArray.ArraySize = arraySize;
+ }
+ else
+ {
+ SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D;
+ SRVDesc.Texture2D.MipLevels = desc.MipLevels;
+ }
+
+ hr = pDev->CreateShaderResourceView( pTex, &SRVDesc, ppSRV );
+ SAFE_RELEASE( pTex );
+ }
+ }
+ break;
+
+ case DDS_DIMENSION_TEXTURE3D:
+ {
+ D3D11_TEXTURE3D_DESC desc;
+ desc.Width = iWidth;
+ desc.Height = iHeight;
+ desc.Depth = iDepth;
+ desc.MipLevels = iMipCount;
+ desc.Format = format;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ ID3D11Texture3D* pTex = NULL;
+ hr = pDev->CreateTexture3D( &desc, pInitData, &pTex );
+ if( SUCCEEDED( hr ) && pTex )
+ {
+#if defined(DEBUG) || defined(PROFILE)
+ pTex->SetPrivateData( WKPDID_D3DDebugObjectName, sizeof("DDSTextureLoader")-1, "DDSTextureLoader" );
+#endif
+ D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
+ memset( &SRVDesc, 0, sizeof( SRVDesc ) );
+ SRVDesc.Format = format;
+ SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE3D;
+ SRVDesc.Texture3D.MipLevels = desc.MipLevels;
+
+ hr = pDev->CreateShaderResourceView( pTex, &SRVDesc, ppSRV );
+ SAFE_RELEASE( pTex );
+ }
+ }
+ break;
+ }
+
+ SAFE_DELETE_ARRAY( pInitData );
+
+ return hr;
+}
+
+
+//--------------------------------------------------------------------------------------
+HRESULT CreateDDSTextureFromFile( __in ID3D11Device* pDev, __in_z const WCHAR* szFileName, __out_opt ID3D11ShaderResourceView** ppSRV, bool sRGB )
+{
+ if ( !pDev || !szFileName || !ppSRV )
+ return E_INVALIDARG;
+
+ BYTE* pHeapData = NULL;
+ DDS_HEADER* pHeader = NULL;
+ BYTE* pBitData = NULL;
+ UINT BitSize = 0;
+
+ HRESULT hr = LoadTextureDataFromFile( szFileName, &pHeapData, &pHeader, &pBitData, &BitSize );
+ if(FAILED(hr))
+ {
+ SAFE_DELETE_ARRAY( pHeapData );
+ return hr;
+ }
+
+ hr = CreateTextureFromDDS( pDev, pHeader, pBitData, BitSize, ppSRV, sRGB );
+ SAFE_DELETE_ARRAY( pHeapData );
+
+#if defined(DEBUG) || defined(PROFILE)
+ if ( *ppSRV )
+ {
+ CHAR strFileA[MAX_PATH];
+ WideCharToMultiByte( CP_ACP, 0, szFileName, -1, strFileA, MAX_PATH, NULL, FALSE );
+ CHAR* pstrName = strrchr( strFileA, '\\' );
+ if( pstrName == NULL )
+ pstrName = strFileA;
+ else
+ pstrName++;
+
+ (*ppSRV)->SetPrivateData( WKPDID_D3DDebugObjectName, lstrlenA(pstrName), pstrName );
+ }
+#endif
+
+ return hr;
+}
diff --git a/Projects/Asteroids/src/DDSTextureLoader.h b/Projects/Asteroids/src/DDSTextureLoader.h
new file mode 100644
index 0000000..5bca4c6
--- /dev/null
+++ b/Projects/Asteroids/src/DDSTextureLoader.h
@@ -0,0 +1,18 @@
+//--------------------------------------------------------------------------------------
+// File: DDSTextureLoader.h
+//
+// Functions for loading a DDS texture without using D3DX
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//--------------------------------------------------------------------------------------
+
+#include "DDS.h"
+#include <d3d11.h>
+
+HRESULT CreateDDSTextureFromFile( __in ID3D11Device* pDev, __in_z const WCHAR* szFileName, __out_opt ID3D11ShaderResourceView** ppSRV, bool sRGB = false );
+
+// INTEL: Exposed this from the internals so we can load the data into D3D12, etc.
+DXGI_FORMAT GetDXGIFormat( const DDS_PIXELFORMAT& ddpf );
+HRESULT LoadTextureDataFromFile(__in_z const WCHAR* szFileName, BYTE** ppHeapData,
+ DDS_HEADER** ppHeader,
+ BYTE** ppBitData, UINT* pBitSize);
diff --git a/Projects/Asteroids/src/WinWrapper.cpp b/Projects/Asteroids/src/WinWrapper.cpp
new file mode 100644
index 0000000..ffb0f6d
--- /dev/null
+++ b/Projects/Asteroids/src/WinWrapper.cpp
@@ -0,0 +1,616 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#define WIN32_LEAN_AND_MEAN
+#include <sdkddkver.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <shellapi.h> // must be after windows.h
+#include <ShellScalingApi.h>
+#include <interactioncontext.h>
+#include <mmsystem.h>
+#include <map>
+#include <vector>
+#include <iostream>
+
+#include "asteroids_d3d11.h"
+#include "asteroids_d3d12.h"
+#include "asteroids_DE.h"
+#include "camera.h"
+#include "gui.h"
+
+using namespace DirectX;
+
+namespace {
+
+// Global demo state
+Settings gSettings;
+OrbitCamera gCamera;
+
+IDXGIFactory2* gDXGIFactory = nullptr;
+
+AsteroidsD3D11::Asteroids* gWorkloadD3D11 = nullptr;
+AsteroidsD3D12::Asteroids* gWorkloadD3D12 = nullptr;
+AsteroidsDE::Asteroids* gWorkloadDE = nullptr;
+bool gd3d11Available = false;
+bool gd3d12Available = false;
+Settings::RenderMode gLastFrameRenderMode = static_cast<Settings::RenderMode>(-1);
+
+GUI gGUI;
+GUIText* gFPSControl;
+
+enum
+{
+ basicStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE,
+ windowedStyle = basicStyle | WS_OVERLAPPEDWINDOW,
+ fullscreenStyle = basicStyle
+};
+
+bool CheckDll(char const* dllName)
+{
+ auto hModule = LoadLibrary(dllName);
+ if (hModule == NULL) {
+ return false;
+ }
+ FreeLibrary(hModule);
+ return true;
+}
+
+
+UINT SetupDPI()
+{
+ // Just do system DPI awareness for now for simplicity... scale the 3D content
+ SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE);
+
+ UINT dpiX = 0, dpiY;
+ POINT pt = {1, 1};
+ auto hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
+ if (SUCCEEDED(GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
+ return dpiX;
+ } else {
+ return 96; // default
+ }
+}
+
+
+void ResetCameraView()
+{
+ auto center = XMVectorSet(0.0f, -0.4f*SIM_DISC_RADIUS, 0.0f, 0.0f);
+ auto radius = SIM_ORBIT_RADIUS + SIM_DISC_RADIUS + 10.f;
+ auto minRadius = SIM_ORBIT_RADIUS - 3.0f * SIM_DISC_RADIUS;
+ auto maxRadius = SIM_ORBIT_RADIUS + 3.0f * SIM_DISC_RADIUS;
+ auto longAngle = 4.50f;
+ auto latAngle = 1.45f;
+ gCamera.View(center, radius, minRadius, maxRadius, longAngle, latAngle);
+}
+
+void ToggleFullscreen(HWND hWnd)
+{
+ static WINDOWPLACEMENT prevPlacement = { sizeof(prevPlacement) };
+ DWORD dwStyle = (DWORD)GetWindowLongPtr(hWnd, GWL_STYLE);
+ if ((dwStyle & windowedStyle) == windowedStyle)
+ {
+ MONITORINFO mi = { sizeof(mi) };
+ if (GetWindowPlacement(hWnd, &prevPlacement) &&
+ GetMonitorInfo(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), &mi))
+ {
+ SetWindowLong(hWnd, GWL_STYLE, fullscreenStyle);
+ SetWindowPos(hWnd, HWND_TOP,
+ mi.rcMonitor.left, mi.rcMonitor.top,
+ mi.rcMonitor.right - mi.rcMonitor.left,
+ mi.rcMonitor.bottom - mi.rcMonitor.top,
+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+ }
+ } else {
+ SetWindowLong(hWnd, GWL_STYLE, windowedStyle);
+ SetWindowPlacement(hWnd, &prevPlacement);
+ SetWindowPos(hWnd, NULL, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+ }
+}
+
+
+} // namespace
+
+
+
+LRESULT CALLBACK WindowProc(
+ HWND hWnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch (message) {
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+
+ case WM_SIZE: {
+ UINT ww = LOWORD(lParam);
+ UINT wh = HIWORD(lParam);
+
+ // Ignore resizing to minimized
+ if (ww == 0 || wh == 0) return 0;
+
+ gSettings.windowWidth = (int)ww;
+ gSettings.windowHeight = (int)wh;
+ gSettings.renderWidth = (UINT)(double(gSettings.windowWidth) * gSettings.renderScale);
+ gSettings.renderHeight = (UINT)(double(gSettings.windowHeight) * gSettings.renderScale);
+
+ // Update camera projection
+ float aspect = (float)gSettings.renderWidth / (float)gSettings.renderHeight;
+ gCamera.Projection(XM_PIDIV2 * 0.8f * 3 / 2, aspect);
+
+ // Resize currently active swap chain
+ switch (gSettings.mode)
+ {
+ case Settings::RenderMode::NativeD3D11:
+ if(gWorkloadD3D11)
+ gWorkloadD3D11->ResizeSwapChain(gDXGIFactory, hWnd, gSettings.renderWidth, gSettings.renderHeight);
+ break;
+
+ case Settings::RenderMode::NativeD3D12:
+ if(gWorkloadD3D12)
+ gWorkloadD3D12->ResizeSwapChain(gDXGIFactory, hWnd, gSettings.renderWidth, gSettings.renderHeight);
+ break;
+
+ case Settings::RenderMode::DiligentD3D11:
+ case Settings::RenderMode::DiligentD3D12:
+ case Settings::RenderMode::DiligentGL:
+ if(gWorkloadDE)
+ gWorkloadDE->ResizeSwapChain(hWnd, gSettings.renderWidth, gSettings.renderHeight);
+ break;
+ }
+
+ return 0;
+ }
+
+ case WM_KEYDOWN:
+ if (lParam & (1 << 30)) {
+ // Ignore repeats
+ return 0;
+ }
+ switch (wParam) {
+ case VK_SPACE:
+ gSettings.animate = !gSettings.animate;
+ std::cout << "Animate: " << gSettings.animate << std::endl;
+ return 0;
+
+ /* Disabled for demo setup */
+ case 'V':
+ gSettings.vsync = !gSettings.vsync;
+ std::cout << "Vsync: " << gSettings.vsync << std::endl;
+ return 0;
+ case 'M':
+ gSettings.multithreadedRendering = !gSettings.multithreadedRendering;
+ std::cout << "Multithreaded Rendering: " << gSettings.multithreadedRendering << std::endl;
+ return 0;
+ case 'I':
+ gSettings.executeIndirect = !gSettings.executeIndirect;
+ std::cout << "ExecuteIndirect Rendering: " << gSettings.executeIndirect << std::endl;
+ return 0;
+ case 'S':
+ gSettings.submitRendering = !gSettings.submitRendering;
+ std::cout << "Submit Rendering: " << gSettings.submitRendering << std::endl;
+ return 0;
+
+ case VK_ADD:
+ case VK_OEM_PLUS:
+ gSettings.numThreads = std::min(gSettings.numThreads+1, 16);
+ gLastFrameRenderMode = static_cast<Settings::RenderMode>(-1);
+ return 0;
+ case VK_SUBTRACT:
+ case VK_OEM_MINUS:
+ gSettings.numThreads = std::max(gSettings.numThreads-1, 2);
+ gLastFrameRenderMode = static_cast<Settings::RenderMode>(-1);
+ return 0;
+
+ case '1': gSettings.mode = gd3d11Available ? Settings::RenderMode::NativeD3D11 : gSettings.mode; return 0;
+ case '2': gSettings.mode = gd3d12Available ? Settings::RenderMode::NativeD3D12 : gSettings.mode; return 0;
+ case '3': gSettings.mode = gd3d11Available ? Settings::RenderMode::DiligentD3D11 : gSettings.mode; return 0;
+ case '4': gSettings.mode = gd3d12Available ? Settings::RenderMode::DiligentD3D12 : gSettings.mode; return 0;
+ case '5': gSettings.mode = Settings::RenderMode::DiligentGL; return 0;
+
+ case VK_ESCAPE:
+ SendMessage(hWnd, WM_CLOSE, 0, 0);
+ return 0;
+ } // Switch on key code
+ return 0;
+
+ case WM_SYSKEYDOWN:
+ if (lParam & (1 << 30)) {
+ // Ignore repeats
+ return 0;
+ }
+ switch (wParam) {
+ case VK_RETURN:
+ ToggleFullscreen(hWnd);
+ break;
+ }
+ return 0;
+
+ case WM_MOUSEWHEEL: {
+ auto delta = GET_WHEEL_DELTA_WPARAM(wParam);
+ gCamera.ZoomRadius(-0.07f * delta);
+ return 0;
+ }
+
+ case WM_POINTERDOWN:
+ case WM_POINTERUPDATE:
+ case WM_POINTERUP: {
+ auto pointerId = GET_POINTERID_WPARAM(wParam);
+ POINTER_INFO pointerInfo;
+ if (GetPointerInfo(pointerId, &pointerInfo)) {
+ if (message == WM_POINTERDOWN) {
+ // Compute pointer position in render units
+ POINT p = pointerInfo.ptPixelLocation;
+ ScreenToClient(hWnd, &p);
+ RECT clientRect;
+ GetClientRect(hWnd, &clientRect);
+ p.x = p.x * gSettings.renderWidth / (clientRect.right - clientRect.left);
+ p.y = p.y * gSettings.renderHeight / (clientRect.bottom - clientRect.top);
+
+ auto guiControl = gGUI.HitTest(p.x, p.y);
+ if (guiControl == gFPSControl) {
+ gSettings.lockFrameRate = !gSettings.lockFrameRate;
+ } else { // Camera manipulation
+ gCamera.AddPointer(pointerId);
+ }
+ }
+
+ // Otherwise send it to the camera controls
+ gCamera.ProcessPointerFrames(pointerId, &pointerInfo);
+ if (message == WM_POINTERUP) gCamera.RemovePointer(pointerId);
+ }
+ return 0;
+ }
+
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+}
+
+int InitWorkload(HWND hWnd, AsteroidsSimulation &asteroids)
+{
+ delete gWorkloadD3D11;
+ gWorkloadD3D11 = nullptr;
+ delete gWorkloadD3D12;
+ gWorkloadD3D12 = nullptr;
+ delete gWorkloadDE;
+ gWorkloadDE = nullptr;
+ switch (gSettings.mode)
+ {
+ case Settings::RenderMode::NativeD3D11:
+ if (gd3d11Available) {
+ gWorkloadD3D11 = new AsteroidsD3D11::Asteroids(&asteroids, &gGUI, gSettings.warp);
+ }
+
+ gWorkloadD3D11->ResizeSwapChain(gDXGIFactory, hWnd, gSettings.renderWidth, gSettings.renderHeight);
+ break;
+
+ case Settings::RenderMode::NativeD3D12:
+ if (gd3d12Available) {
+ // If requested, enumerate the warp adapter
+ // TODO: Allow picking from multiple hardware adapters
+ IDXGIAdapter1* adapter = nullptr;
+
+ if (gSettings.warp) {
+ IDXGIFactory4* DXGIFactory4 = nullptr;
+ if (FAILED(gDXGIFactory->QueryInterface(&DXGIFactory4))) {
+ fprintf(stderr, "error: WARP requires IDXGIFactory4 interface which is not present on this system!\n");
+ return -1;
+ }
+
+ auto hr = DXGIFactory4->EnumWarpAdapter(IID_PPV_ARGS(&adapter));
+ DXGIFactory4->Release();
+
+ if (FAILED(hr)) {
+ fprintf(stderr, "error: WARP adapter not present on this system!\n");
+ return -1;
+ }
+ }
+
+ gWorkloadD3D12 = new AsteroidsD3D12::Asteroids(&asteroids, &gGUI, gSettings.numThreads, adapter);
+ }
+
+ gWorkloadD3D12->ResizeSwapChain(gDXGIFactory, hWnd, gSettings.renderWidth, gSettings.renderHeight);
+ break;
+
+ case Settings::RenderMode::DiligentD3D11:
+ gWorkloadDE = new AsteroidsDE::Asteroids(gSettings.numThreads, &asteroids, &gGUI, hWnd, Diligent::DeviceType::D3D11);
+ break;
+
+ case Settings::RenderMode::DiligentD3D12:
+ gWorkloadDE = new AsteroidsDE::Asteroids(gSettings.numThreads, &asteroids, &gGUI, hWnd, Diligent::DeviceType::D3D12);
+ break;
+
+ case Settings::RenderMode::DiligentGL:
+ gWorkloadDE = new AsteroidsDE::Asteroids(gSettings.numThreads, &asteroids, &gGUI, hWnd, Diligent::DeviceType::OpenGL);
+ break;
+ }
+
+ return 0;
+}
+
+int main(int argc, char** argv)
+{
+#if defined(_DEBUG) || defined(DEBUG)
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+#endif
+
+ gd3d11Available = CheckDll("d3d11.dll");
+ gd3d12Available = CheckDll("d3d12.dll");
+
+ // Must be done before any windowing-system-like things or else virtualization will kick in
+ auto dpi = SetupDPI();
+ // By default render at the lower resolution and scale up based on system settings
+ gSettings.renderScale = 96.0 / double(dpi);
+
+ // Scale default window size based on dpi
+ gSettings.windowWidth *= dpi / 96;
+ gSettings.windowHeight *= dpi / 96;
+
+ for (int a = 1; a < argc; ++a) {
+ if (_stricmp(argv[a], "-close_after") == 0 && a + 1 < argc) {
+ gSettings.closeAfterSeconds = atof(argv[++a]);
+ } else if (_stricmp(argv[a], "-nod3d11") == 0) {
+ gd3d11Available = false;
+ } else if (_stricmp(argv[a], "-warp") == 0) {
+ gSettings.warp = true;
+ } else if (_stricmp(argv[a], "-nod3d12") == 0) {
+ gd3d12Available = false;
+ } else if (_stricmp(argv[a], "-indirect") == 0) {
+ gSettings.executeIndirect = true;
+ } else if (_stricmp(argv[a], "-fullscreen") == 0) {
+ gSettings.windowed = false;
+ } else if (_stricmp(argv[a], "-window") == 0 && a + 2 < argc) {
+ gSettings.windowWidth = atoi(argv[++a]);
+ gSettings.windowHeight = atoi(argv[++a]);
+ } else if (_stricmp(argv[a], "-render_scale") == 0 && a + 1 < argc) {
+ gSettings.renderScale = atof(argv[++a]);
+ } else if (_stricmp(argv[a], "-locked_fps") == 0 && a + 1 < argc) {
+ gSettings.lockedFrameRate = atoi(argv[++a]);
+ } else if (_stricmp(argv[a], "-threads") == 0 && a + 1 < argc) {
+ gSettings.numThreads = atoi(argv[++a]);
+ } else {
+ fprintf(stderr, "error: unrecognized argument '%s'\n", argv[a]);
+ fprintf(stderr, "usage: asteroids_d3d12 [options]\n");
+ fprintf(stderr, "options:\n");
+ fprintf(stderr, " -close_after [seconds]\n");
+ fprintf(stderr, " -nod3d11\n");
+ fprintf(stderr, " -nod3d12\n");
+ fprintf(stderr, " -fullscreen\n");
+ fprintf(stderr, " -window [width] [height]\n");
+ fprintf(stderr, " -render_scale [scale]\n");
+ fprintf(stderr, " -locked_fps [fps]\n");
+ fprintf(stderr, " -warp\n");
+ return -1;
+ }
+ }
+
+ if (gSettings.numThreads == 0)
+ {
+ gSettings.numThreads = std::max(std::thread::hardware_concurrency()-1, 2u);
+ }
+
+ //if (!d3d11Available && !d3d12Available) {
+ // fprintf(stderr, "error: neither D3D11 nor D3D12 available.\n");
+ // return -1;
+ //}
+
+ // DXGI Factory
+ ThrowIfFailed(CreateDXGIFactory2(0, IID_PPV_ARGS(&gDXGIFactory)));
+
+ // Setup GUI
+ gFPSControl = gGUI.AddText(150, 10);
+
+ ResetCameraView();
+ // Camera projection set up in WM_SIZE
+
+ AsteroidsSimulation asteroids(1337, NUM_ASTEROIDS, NUM_UNIQUE_MESHES, MESH_MAX_SUBDIV_LEVELS, NUM_UNIQUE_TEXTURES);
+
+
+ gSettings.mode = Settings::RenderMode::DiligentD3D12;
+
+
+ // init window class
+ WNDCLASSEX windowClass;
+ ZeroMemory(&windowClass, sizeof(WNDCLASSEX));
+ windowClass.cbSize = sizeof(WNDCLASSEX);
+ windowClass.style = CS_HREDRAW | CS_VREDRAW;
+ windowClass.lpfnWndProc = WindowProc;
+ windowClass.hInstance = GetModuleHandle(NULL);
+ windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ windowClass.lpszClassName = "AsteroidsD3D12WindowClass";
+ RegisterClassEx(&windowClass);
+
+ RECT windowRect = { 0, 0, gSettings.windowWidth, gSettings.windowHeight };
+ AdjustWindowRect(&windowRect, windowedStyle, FALSE);
+
+ // create the window and store a handle to it
+ auto hWnd = CreateWindowEx(
+ WS_EX_APPWINDOW,
+ "AsteroidsD3D12WindowClass",
+ "Asteroids",
+ windowedStyle,
+ 0, // CW_USE_DEFAULT
+ 0, // CW_USE_DEFAULT
+ windowRect.right - windowRect.left,
+ windowRect.bottom - windowRect.top,
+ NULL,
+ NULL,
+ windowClass.hInstance,
+ NULL);
+
+ if (!gSettings.windowed) {
+ ToggleFullscreen(hWnd);
+ }
+
+ SetForegroundWindow(hWnd);
+
+ // Initialize performance counters
+ UINT64 perfCounterFreq = 0;
+ UINT64 lastPerfCount = 0;
+ QueryPerformanceFrequency((LARGE_INTEGER*)&perfCounterFreq);
+ QueryPerformanceCounter((LARGE_INTEGER*)&lastPerfCount);
+
+ // main loop
+ double elapsedTime = 0.0;
+ double frameTime = 0.0;
+ int lastMouseX = 0;
+ int lastMouseY = 0;
+ POINTER_INFO pointerInfo = {};
+
+ timeBeginPeriod(1);
+ EnableMouseInPointer(TRUE);
+
+ float filteredUpdateTime = 0.0f;
+ float filteredRenderTime = 0.0f;
+ float filteredFrameTime = 0.0f;
+ for (;;)
+ {
+ MSG msg = {};
+ while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ if (msg.message == WM_QUIT) {
+ // Cleanup
+ delete gWorkloadD3D11;
+ delete gWorkloadD3D12;
+ delete gWorkloadDE;
+ SafeRelease(&gDXGIFactory);
+ timeEndPeriod(1);
+ EnableMouseInPointer(FALSE);
+ return (int)msg.wParam;
+ };
+
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ // If we swap to a new API we need to recreate swap chains
+ if (gLastFrameRenderMode != gSettings.mode) {
+ InitWorkload(hWnd, asteroids);
+ gLastFrameRenderMode = gSettings.mode;
+ }
+
+ // Still need to process inertia even when no interaction is happening
+ gCamera.ProcessInertia();
+
+ // In D3D12 we'll wait on the GPU before taking the timestamp (more consistent)
+ if (gSettings.mode == Settings::RenderMode::NativeD3D12) {
+ gWorkloadD3D12->WaitForReadyToRender();
+ }
+
+ // Get time delta
+ UINT64 count;
+ QueryPerformanceCounter((LARGE_INTEGER*)&count);
+ auto rawFrameTime = (double)(count - lastPerfCount) / perfCounterFreq;
+ elapsedTime += rawFrameTime;
+ lastPerfCount = count;
+
+ // Maintaining absolute time sync is not important in this demo so we can err on the "smoother" side
+ double alpha = 0.2f;
+ frameTime = alpha * rawFrameTime + (1.0f - alpha) * frameTime;
+
+ // Update GUI
+ {
+ const char *ModeStr = nullptr;
+ float updateTime = 0;
+ float renderTime = 0;
+ switch (gSettings.mode)
+ {
+ case Settings::RenderMode::NativeD3D11:
+ ModeStr = "Native D3D11";
+ gWorkloadD3D11->GetPerfCounters(updateTime, renderTime);
+ break;
+
+ case Settings::RenderMode::NativeD3D12:
+ ModeStr = "Native D3D12";
+ gWorkloadD3D12->GetPerfCounters(updateTime, renderTime);
+ break;
+
+ case Settings::RenderMode::DiligentD3D11:
+ ModeStr = "Diligent D3D11";
+ gWorkloadDE->GetPerfCounters(updateTime, renderTime);
+ break;
+
+ case Settings::RenderMode::DiligentD3D12:
+ ModeStr = "Diligent D3D12";
+ gWorkloadDE->GetPerfCounters(updateTime, renderTime);
+ break;
+
+ case Settings::RenderMode::DiligentGL:
+ ModeStr = "Diligent GL";
+ gWorkloadDE->GetPerfCounters(updateTime, renderTime);
+ break;
+ }
+ float filterScale = 0.05f;
+ filteredUpdateTime = filteredUpdateTime * (1.f - filterScale) + filterScale * updateTime;
+ filteredRenderTime = filteredRenderTime * (1.f - filterScale) + filterScale * renderTime;
+ filteredFrameTime = filteredFrameTime * (1.f - filterScale) + filterScale * (float)frameTime;
+
+ char buffer[256];
+ sprintf(buffer, "Asteroids %s (%dt) - %4.2f ms (%4.2f ms / %4.2f ms)", ModeStr, gSettings.multithreadedRendering ? gSettings.numThreads : 1,
+ 1000.f * filteredFrameTime, 1000.f * filteredUpdateTime, 1000.f * filteredRenderTime);
+
+ SetWindowText(hWnd, buffer);
+
+ if (gSettings.lockFrameRate) {
+ sprintf(buffer, "(Locked)");
+ } else {
+ sprintf(buffer, "%.0f fps", 1.0f / filteredFrameTime);
+ }
+ gFPSControl->Text(buffer);
+ }
+
+ switch (gSettings.mode)
+ {
+ case Settings::RenderMode::NativeD3D11:
+ if(gWorkloadD3D11)
+ gWorkloadD3D11->Render((float)frameTime, gCamera, gSettings);
+ break;
+
+ case Settings::RenderMode::NativeD3D12:
+ if(gWorkloadD3D12)
+ gWorkloadD3D12->Render((float)frameTime, gCamera, gSettings);
+ break;
+
+ case Settings::RenderMode::DiligentD3D11:
+ case Settings::RenderMode::DiligentD3D12:
+ case Settings::RenderMode::DiligentGL:
+ if(gWorkloadDE)
+ gWorkloadDE->Render((float)frameTime, gCamera, gSettings);
+ break;
+ }
+
+ if (gSettings.lockFrameRate) {
+
+ UINT64 afterRenderCount;
+ QueryPerformanceCounter((LARGE_INTEGER*)&afterRenderCount);
+ double renderTime = (double)(afterRenderCount - count) / perfCounterFreq;
+
+ double targetRenderTime = 1.0 / double(gSettings.lockedFrameRate);
+ double deltaMs = (targetRenderTime - renderTime) * 1000.0;
+ if (deltaMs > 1.0) {
+ Sleep((DWORD)deltaMs);
+ }
+
+ }
+
+ // All done?
+ if (gSettings.closeAfterSeconds > 0.0 && elapsedTime > gSettings.closeAfterSeconds) {
+ SendMessage(hWnd, WM_CLOSE, 0, 0);
+ break;
+ }
+ }
+
+ // Shouldn't get here
+ return 1;
+}
diff --git a/Projects/Asteroids/src/asteroid_ps.hlsl b/Projects/Asteroids/src/asteroid_ps.hlsl
new file mode 100644
index 0000000..c645486
--- /dev/null
+++ b/Projects/Asteroids/src/asteroid_ps.hlsl
@@ -0,0 +1,50 @@
+#include "asteroid_vs.hlsl"
+#include "common_defines.h"
+
+// Apparently tools don't like unbounded/bindless texture arrays, so use the real constant for now
+Texture2DArray<float4> Tex[NUM_UNIQUE_TEXTURES] : register(t0);
+sampler Sampler : register(s0);
+
+float4 asteroid_ps(in float4 position : SV_Position,
+ in VSOut vs_output) : SV_Target
+{
+ // Tweaking
+ float3 lightPos = float3(0.5, -0.25, -1);
+ bool applyNoise = true;
+ bool applyLight = true;
+ bool applyCoverage = true;
+
+ float3 normal = normalize(vs_output.normalWorld);
+
+ // Triplanar projection
+ float3 blendWeights = abs(normalize(vs_output.positionModel));
+ float3 uvw = vs_output.positionModel * 0.5f + 0.5f;
+ // Tighten up the blending zone
+ blendWeights = saturate((blendWeights - 0.2f) * 7.0f);
+ blendWeights /= (blendWeights.x + blendWeights.y + blendWeights.z).xxx;
+
+ float3 coords1 = float3(uvw.yz, 0);
+ float3 coords2 = float3(uvw.zx, 1);
+ float3 coords3 = float3(uvw.xy, 2);
+
+ // TODO: Should really branch out zero'd weight ones, but FXC is being a pain
+ // and forward substituting the above and then refusing to compile "divergent"
+ // coordinates...
+ float3 detailTex = 0.0f;
+ detailTex += blendWeights.x * Tex[mTextureIndex].Sample(Sampler, coords1).xyz;
+ detailTex += blendWeights.y * Tex[mTextureIndex].Sample(Sampler, coords2).xyz;
+ detailTex += blendWeights.z * Tex[mTextureIndex].Sample(Sampler, coords3).xyz;
+
+ float wrap = 0.0f;
+ float wrap_diffuse = saturate((dot(normal, normalize(lightPos)) + wrap) / (1.0f + wrap));
+ float light = 3.0f * wrap_diffuse + 0.06f;
+
+ // Approximate partial coverage on distant asteroids (by fading them out)
+ float coverage = saturate(position.z * 4000.0f);
+
+ float3 color = vs_output.albedo;
+ [flatten] if (applyNoise) color = color * (2.0f * detailTex);
+ [flatten] if (applyLight) color = color * light;
+ [flatten] if (applyCoverage) color = color * coverage;
+ return float4(color, 1.0f);
+}
diff --git a/Projects/Asteroids/src/asteroid_ps_d3d11.hlsl b/Projects/Asteroids/src/asteroid_ps_d3d11.hlsl
new file mode 100644
index 0000000..69ebc33
--- /dev/null
+++ b/Projects/Asteroids/src/asteroid_ps_d3d11.hlsl
@@ -0,0 +1,56 @@
+#include "common_defines.h"
+
+struct VSOut
+{
+ float3 positionModel : POSITIONMODEL;
+ float3 normalWorld : NORMAL;
+ float3 albedo : ALBEDO; // Alternatively, can pass just "ao" to PS and read cbuffer in PS
+};
+
+Texture2DArray<float4> Tex;// : register(t0);
+SamplerState Tex_sampler;// : register(s0);
+
+void asteroid_ps_d3d11(in float4 position : SV_Position,
+ in VSOut vs_output,
+ out float4 color : SV_Target)
+{
+ // Tweaking
+ float3 lightPos = float3(0.5, -0.25, -1);
+ bool applyNoise = true;
+ bool applyLight = true;
+ bool applyCoverage = true;
+
+ float3 normal = normalize(vs_output.normalWorld);
+
+ // Triplanar projection
+ float3 blendWeights = abs(normalize(vs_output.positionModel));
+ float3 uvw = vs_output.positionModel * 0.5f + 0.5f;
+ // Tighten up the blending zone
+ blendWeights = saturate((blendWeights - 0.2f) * 7.0f);
+ blendWeights /= (blendWeights.x + blendWeights.y + blendWeights.z).xxx;
+
+ float3 coords1 = float3(uvw.yz, 0);
+ float3 coords2 = float3(uvw.zx, 1);
+ float3 coords3 = float3(uvw.xy, 2);
+
+ // TODO: Should really branch out zero'd weight ones, but FXC is being a pain
+ // and forward substituting the above and then refusing to compile "divergent"
+ // coordinates...
+ float3 detailTex = float3(0.0, 0.0, 0.0);
+ detailTex += blendWeights.x * Tex.Sample(Tex_sampler, coords1).xyz;
+ detailTex += blendWeights.y * Tex.Sample(Tex_sampler, coords2).xyz;
+ detailTex += blendWeights.z * Tex.Sample(Tex_sampler, coords3).xyz;
+
+ float wrap = 0.0f;
+ float wrap_diffuse = saturate((dot(normal, normalize(lightPos)) + wrap) / (1.0f + wrap));
+ float light = 3.0f * wrap_diffuse + 0.06f;
+
+ // Approximate partial coverage on distant asteroids (by fading them out)
+ float coverage = saturate(position.z * 4000.0f);
+
+ color.rgb = vs_output.albedo.rgb;
+ [flatten] if (applyNoise) color.rgb = color.rgb * (2.0f * detailTex);
+ [flatten] if (applyLight) color.rgb = color.rgb * light;
+ [flatten] if (applyCoverage) color.rgb = color.rgb * coverage;
+ color.a = 1.0;
+}
diff --git a/Projects/Asteroids/src/asteroid_vs.hlsl b/Projects/Asteroids/src/asteroid_vs.hlsl
new file mode 100644
index 0000000..772137c
--- /dev/null
+++ b/Projects/Asteroids/src/asteroid_vs.hlsl
@@ -0,0 +1,36 @@
+cbuffer DrawConstantBuffer// : register(b0)
+{
+ float4x4 mWorld;
+ float4x4 mViewProjection;
+ float4 mSurfaceColor;
+ float4 mDeepColor;
+ uint mTextureIndex;
+};
+
+struct VSOut
+{
+ float3 positionModel : POSITIONMODEL;
+ float3 normalWorld : NORMAL;
+ float3 albedo : ALBEDO; // Alternatively, can pass just "ao" to PS and read cbuffer in PS
+};
+
+float linstep(float min, float max, float s)
+{
+ return saturate((s - min) / (max - min));
+}
+
+
+void asteroid_vs(in float3 in_pos : ATTRIB0,
+ in float3 in_normal : ATTRIB1,
+ out float4 position : SV_Position,
+ out VSOut vs_output)
+{
+ float3 positionWorld = mul(mWorld, float4(in_pos, 1.0f)).xyz;
+ position = mul(mViewProjection, float4(positionWorld, 1.0f));
+
+ vs_output.positionModel = in_pos;
+ vs_output.normalWorld = mul(mWorld, float4(in_normal, 0.0f)).xyz; // No non-uniform scaling
+
+ float depth = linstep(0.5f, 0.7f, length(in_pos.xyz));
+ vs_output.albedo = lerp(mDeepColor.xyz, mSurfaceColor.xyz, depth);
+}
diff --git a/Projects/Asteroids/src/asteroids_DE.cpp b/Projects/Asteroids/src/asteroids_DE.cpp
new file mode 100644
index 0000000..0cb3ddf
--- /dev/null
+++ b/Projects/Asteroids/src/asteroids_DE.cpp
@@ -0,0 +1,870 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#include <directxmath.h>
+#include <math.h>
+
+#include <iostream>
+#include <algorithm>
+#include <vector>
+#include <future>
+#include <limits>
+#include <random>
+#include <locale>
+#include <codecvt>
+
+#include "asteroids_DE.h"
+#include "RenderDeviceFactoryD3D11.h"
+#include "RenderDeviceFactoryD3D12.h"
+#include "RenderDeviceFactoryOpenGL.h"
+#include "BasicShaderSourceStreamFactory.h"
+#include "MapHelper.h"
+
+#include "util.h"
+#include "mesh.h"
+#include "noise.h"
+#include "texture.h"
+#include "StringTools.h"
+#include "TextureUtilities.h"
+
+using namespace Diligent;
+
+namespace Diligent
+{
+#ifdef ENGINE_DLL
+ CreateDeviceAndContextsD3D11Type CreateDeviceAndContextsD3D11 = nullptr;
+ CreateSwapChainD3D11Type CreateSwapChainD3D11 = nullptr;
+
+ CreateDeviceAndContextsD3D12Type CreateDeviceAndContextsD3D12 = nullptr;
+ CreateSwapChainD3D12Type CreateSwapChainD3D12 = nullptr;
+
+ CreateDeviceAndSwapChainGLType CreateDeviceAndSwapChainGL = nullptr;
+#endif
+}
+
+namespace AsteroidsDE {
+
+
+// Create Direct3D device and swap chain
+void Asteroids::InitDevice(HWND hWnd, DeviceType DevType)
+{
+ EngineCreationAttribs EngineCreationAttribs;
+ EngineCreationAttribs.strShaderCachePath = "bin\\tmp\\ShaderCache";
+ SwapChainDesc SwapChainDesc;
+ SwapChainDesc.SamplesCount = 1;
+ SwapChainDesc.BufferCount = NUM_SWAP_CHAIN_BUFFERS;
+ SwapChainDesc.ColorBufferFormat = TEX_FORMAT_RGBA8_UNORM_SRGB;
+ SwapChainDesc.DepthBufferFormat = TEX_FORMAT_D32_FLOAT;
+ SwapChainDesc.DefaultDepthValue = 0.f;
+ switch (DevType)
+ {
+ case DeviceType::D3D12:
+ case DeviceType::D3D11:
+ {
+ std::vector<IDeviceContext*> ppContexts(mNumSubsets);
+ if(DevType == DeviceType::D3D11)
+ {
+ EngineD3D11Attribs DeviceAttribs;
+ DeviceAttribs.DebugFlags = (Uint32)EngineD3D11DebugFlags::VerifyCommittedShaderResources |
+ (Uint32)EngineD3D11DebugFlags::VerifyCommittedResourceRelevance;
+
+#ifdef ENGINE_DLL
+ if(!CreateDeviceAndContextsD3D11 || !CreateSwapChainD3D11)
+ LoadGraphicsEngineD3D11(CreateDeviceAndContextsD3D11, CreateSwapChainD3D11);
+#endif
+ CreateDeviceAndContextsD3D11( DeviceAttribs, &mDevice, ppContexts.data(), mNumSubsets-1 );
+ CreateSwapChainD3D11( mDevice, ppContexts[0], SwapChainDesc, hWnd, &mSwapChain );
+ }
+ else
+ {
+ EngineD3D12Attribs Attribs;
+ Attribs.GPUDescriptorHeapDynamicSize[0] = 65536*4;
+ Attribs.GPUDescriptorHeapSize[0] = 65536*4;
+#ifndef _DEBUG
+ Attribs.DynamicDescriptorAllocationChunkSize[0] = 4*2048;
+#endif
+#ifdef ENGINE_DLL
+ if(!CreateDeviceAndContextsD3D12 || !CreateSwapChainD3D12)
+ LoadGraphicsEngineD3D12(CreateDeviceAndContextsD3D12, CreateSwapChainD3D12);
+#endif
+ CreateDeviceAndContextsD3D12( Attribs, &mDevice, ppContexts.data(), mNumSubsets-1 );
+ CreateSwapChainD3D12( mDevice, ppContexts[0], SwapChainDesc, hWnd, &mSwapChain );
+ }
+
+ mDeviceCtxt.Attach(ppContexts[0]);
+ mDeferredCtxt.resize(mNumSubsets-1);
+ for(size_t ctx=0; ctx < mNumSubsets-1; ++ctx)
+ mDeferredCtxt[ctx].Attach(ppContexts[1+ctx]);
+ }
+ break;
+
+ case DeviceType::OpenGL:
+#ifdef ENGINE_DLL
+ if(!CreateDeviceAndSwapChainGL)
+ LoadGraphicsEngineOpenGL(CreateDeviceAndSwapChainGL);
+#endif
+ CreateDeviceAndSwapChainGL(
+ EngineCreationAttribs, &mDevice, &mDeviceCtxt, SwapChainDesc, hWnd, &mSwapChain );
+ break;
+
+ default:
+ LOG_ERROR_AND_THROW("Unknown device type");
+ break;
+ }
+}
+
+Asteroids::Asteroids(UINT NumThreads, AsteroidsSimulation* asteroids, GUI* gui, HWND hWnd, Diligent::DeviceType DevType)
+ : mAsteroids(asteroids)
+ , mGUI(gui)
+{
+ QueryPerformanceFrequency((LARGE_INTEGER*)&mPerfCounterFreq);
+
+ mNumSubsets = std::max(NumThreads,1u);
+ mNumSubsets = std::min(NumThreads,32u);
+
+ InitDevice(hWnd, DevType);
+
+ mCmdLists.resize(mDeferredCtxt.size());
+ mWorkerThreads.resize(mNumSubsets-1);
+ for(auto &thread : mWorkerThreads)
+ {
+ thread = std::thread(WorkerThreadFunc, this, (Uint32)(&thread-mWorkerThreads.data()) );
+ }
+
+ const char *spriteFile = nullptr;
+ switch(DevType)
+ {
+ case DeviceType::D3D11: spriteFile = "DiligentD3D11.dds"; break;
+ case DeviceType::D3D12: spriteFile = "DiligentD3D12.dds"; break;
+ case DeviceType::OpenGL: spriteFile = "DiligentGL.dds"; break;
+ }
+ mSprite.reset( new GUISprite(5, 10, 140, 50, spriteFile) );
+
+ BasicShaderSourceStreamFactory BasicSSSFactory({"src"});
+
+ mBackBufferWidth = mSwapChain->GetDesc().Width;
+ mBackBufferHeight = mSwapChain->GetDesc().Height;
+ // Create draw constant buffer
+ {
+ BufferDesc desc;
+ desc.Name = "draw constant buffer (dynamic)";
+ desc.Usage = USAGE_DYNAMIC;
+ desc.uiSizeInBytes = (Uint32) sizeof(DrawConstantBuffer);
+ desc.BindFlags = BIND_UNIFORM_BUFFER;
+ desc.CPUAccessFlags = CPU_ACCESS_WRITE;
+ mDevice->CreateBuffer(desc, BufferData(), &mDrawConstantBuffer);
+ }
+
+ // create pipeline state
+ {
+ PipelineStateDesc PSODesc;
+ LayoutElement inputDesc[] = {
+ LayoutElement( 0, 0, 3, VT_FLOAT32),
+ LayoutElement( 1, 0, 3, VT_FLOAT32)
+ };
+
+ PSODesc.GraphicsPipeline.InputLayout.LayoutElements = inputDesc;
+ PSODesc.GraphicsPipeline.InputLayout.NumElements = _countof(inputDesc);
+
+ PSODesc.GraphicsPipeline.DepthStencilDesc.DepthFunc = COMPARISON_FUNC_GREATER_EQUAL;
+
+ RefCntAutoPtr<IShader> vs, ps;
+ {
+ ShaderCreationAttribs attribs;
+ attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC;
+ attribs.Desc.ShaderType = SHADER_TYPE_VERTEX;
+ attribs.Desc.Name = "Asteroids VS";
+ attribs.EntryPoint = "asteroid_vs";
+ attribs.FilePath = "asteroid_vs.hlsl";
+ attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
+ attribs.pShaderSourceStreamFactory = &BasicSSSFactory;
+ mDevice->CreateShader(attribs, &vs);
+ vs->GetShaderVariable("DrawConstantBuffer")->Set(mDrawConstantBuffer);
+ }
+
+ {
+ ShaderCreationAttribs attribs;
+ attribs.Desc.DefaultVariableType = m_BindingMode == BindingMode::Dynamic ? SHADER_VARIABLE_TYPE_DYNAMIC : SHADER_VARIABLE_TYPE_MUTABLE;
+ attribs.Desc.ShaderType = SHADER_TYPE_PIXEL;
+ attribs.Desc.Name = "Asteroids PS";
+ attribs.EntryPoint = "asteroid_ps_d3d11";
+ attribs.FilePath = "asteroid_ps_d3d11.hlsl";
+ attribs.pShaderSourceStreamFactory = &BasicSSSFactory;
+ attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
+
+ StaticSamplerDesc samDesc;
+ samDesc.Desc.MagFilter = FILTER_TYPE_ANISOTROPIC;
+ samDesc.Desc.MinFilter = FILTER_TYPE_ANISOTROPIC;
+ samDesc.Desc.MipFilter = FILTER_TYPE_ANISOTROPIC;
+ samDesc.Desc.AddressU = TEXTURE_ADDRESS_WRAP;
+ samDesc.Desc.AddressV = TEXTURE_ADDRESS_WRAP;
+ samDesc.Desc.AddressW = TEXTURE_ADDRESS_WRAP;
+ samDesc.Desc.MinLOD = -D3D11_FLOAT32_MAX;
+ samDesc.Desc.MaxLOD = D3D11_FLOAT32_MAX;
+ samDesc.Desc.MipLODBias = 0.0f;
+ samDesc.Desc.MaxAnisotropy = TEXTURE_ANISO;
+ samDesc.Desc.ComparisonFunc = COMPARISON_FUNC_NEVER;
+ samDesc.TextureName = "Tex";
+ attribs.Desc.StaticSamplers = &samDesc;
+ attribs.Desc.NumStaticSamplers = 1;
+
+ mDevice->CreateShader(attribs, &ps);
+ }
+ PSODesc.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB;
+ PSODesc.GraphicsPipeline.NumRenderTargets = 1;
+ PSODesc.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT;
+ PSODesc.GraphicsPipeline.PrimitiveTopologyType = PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+ PSODesc.Name = "Asteroids PSO";
+
+ PSODesc.GraphicsPipeline.pVS = vs;
+ PSODesc.GraphicsPipeline.pPS = ps;
+ Uint32 NumSRBs = 0;
+ if(m_BindingMode == BindingMode::Dynamic)
+ {
+ NumSRBs = mNumSubsets;
+ }
+ else if(m_BindingMode == BindingMode::Mutable)
+ {
+ PSODesc.SRBAllocationGranularity = 1024;
+ NumSRBs = NUM_ASTEROIDS;
+ }
+ else if(m_BindingMode == BindingMode::TextureMutable)
+ {
+ PSODesc.SRBAllocationGranularity = NUM_UNIQUE_TEXTURES;
+ NumSRBs = NUM_UNIQUE_TEXTURES;
+ }
+ mDevice->CreatePipelineState(PSODesc, &mAsteroidsPSO);
+ mAsteroidsSRBs.resize(NumSRBs);
+ for(size_t srb = 0; srb < mAsteroidsSRBs.size(); ++srb)
+ {
+ mAsteroidsPSO->CreateShaderResourceBinding(&mAsteroidsSRBs[srb]);
+ }
+ }
+
+
+ // Load textures
+ {
+ TextureLoadInfo loadInfo;
+ loadInfo.IsSRGB = true;
+ RefCntAutoPtr<ITexture> skybox;
+ CreateTextureFromFile("starbox_1024.dds", loadInfo, mDevice, &skybox);
+ mSkyboxSRV = skybox->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
+ }
+
+ // Create skybox constant buffer
+ {
+ BufferDesc desc;
+ desc.Name = "skybox constant buffer (dynamic)";
+ desc.Usage = USAGE_DYNAMIC;
+ desc.uiSizeInBytes = sizeof(SkyboxConstantBuffer);
+ desc.BindFlags = BIND_UNIFORM_BUFFER;
+ desc.CPUAccessFlags = CPU_ACCESS_WRITE;
+ mDevice->CreateBuffer(desc, BufferData(), &mSkyboxConstantBuffer);
+ }
+
+ // create skybox pipeline state
+ {
+ LayoutElement inputDesc[] = {
+ LayoutElement( 0, 0, 3, VT_FLOAT32),
+ LayoutElement( 1, 0, 3, VT_FLOAT32)
+ };
+
+ RefCntAutoPtr<IShader> vs, ps;
+ ShaderCreationAttribs attribs;
+ attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC;
+ attribs.Desc.ShaderType = SHADER_TYPE_VERTEX;
+ attribs.Desc.Name = "Skybox VS";
+ attribs.EntryPoint = "skybox_vs";
+ attribs.FilePath = "skybox_vs.hlsl";
+ attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
+ attribs.pShaderSourceStreamFactory = &BasicSSSFactory;
+ mDevice->CreateShader(attribs, &vs);
+ vs->GetShaderVariable("SkyboxConstantBuffer")->Set(mSkyboxConstantBuffer);
+
+ attribs.Desc.Name = "Skybox PS";
+ attribs.EntryPoint = "skybox_ps";
+ attribs.FilePath = "skybox_ps.hlsl";
+ attribs.Desc.ShaderType = SHADER_TYPE_PIXEL;
+
+ StaticSamplerDesc ssdesc;
+ ssdesc.TextureName = "Skybox";
+ ssdesc.Desc.MagFilter = FILTER_TYPE_ANISOTROPIC;
+ ssdesc.Desc.MinFilter = FILTER_TYPE_ANISOTROPIC;
+ ssdesc.Desc.MipFilter = FILTER_TYPE_ANISOTROPIC;
+ ssdesc.Desc.AddressU = TEXTURE_ADDRESS_WRAP;
+ ssdesc.Desc.AddressV = TEXTURE_ADDRESS_WRAP;
+ ssdesc.Desc.AddressW = TEXTURE_ADDRESS_WRAP;
+ ssdesc.Desc.MaxAnisotropy = TEXTURE_ANISO;
+ attribs.Desc.StaticSamplers = &ssdesc;
+ attribs.Desc.NumStaticSamplers = 1;
+ mDevice->CreateShader(attribs, &ps);
+ ps->GetShaderVariable("Skybox")->Set(mSkyboxSRV);
+
+ PipelineStateDesc PSODesc;
+ PSODesc.Name = "Skybox PSO";
+ PSODesc.GraphicsPipeline.InputLayout.LayoutElements = inputDesc;
+ PSODesc.GraphicsPipeline.InputLayout.NumElements = _countof(inputDesc);
+
+ PSODesc.GraphicsPipeline.DepthStencilDesc.DepthFunc = COMPARISON_FUNC_GREATER_EQUAL;
+ PSODesc.GraphicsPipeline.pVS = vs;
+ PSODesc.GraphicsPipeline.pPS = ps;
+
+ PSODesc.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB;
+ PSODesc.GraphicsPipeline.NumRenderTargets = 1;
+ PSODesc.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT;
+ PSODesc.GraphicsPipeline.PrimitiveTopologyType = PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+
+ mDevice->CreatePipelineState(PSODesc, &mSkyboxPSO);
+ }
+
+ // Create sampler
+ {
+ SamplerDesc desc;
+ desc.MagFilter = FILTER_TYPE_ANISOTROPIC;
+ desc.MinFilter = FILTER_TYPE_ANISOTROPIC;
+ desc.MipFilter = FILTER_TYPE_ANISOTROPIC;
+ desc.AddressU = TEXTURE_ADDRESS_WRAP;
+ desc.AddressV = TEXTURE_ADDRESS_WRAP;
+ desc.AddressW = TEXTURE_ADDRESS_WRAP;
+ desc.MinLOD = -D3D11_FLOAT32_MAX;
+ desc.MaxLOD = D3D11_FLOAT32_MAX;
+ desc.MipLODBias = 0.0f;
+ desc.MaxAnisotropy = TEXTURE_ANISO;
+ desc.ComparisonFunc = COMPARISON_FUNC_NEVER;
+ mDevice->CreateSampler(desc, &mSamplerState);
+ }
+
+ CreateGUIResources();
+
+ // Sprites and fonts
+ {
+ PipelineStateDesc PSODesc;
+ LayoutElement inputDesc[] = {
+ LayoutElement( 0, 0, 2, VT_FLOAT32),
+ LayoutElement( 1, 0, 2, VT_FLOAT32)
+ };
+ PSODesc.GraphicsPipeline.InputLayout.LayoutElements = inputDesc;
+ PSODesc.GraphicsPipeline.InputLayout.NumElements = _countof(inputDesc);
+
+ auto &BlendState = PSODesc.GraphicsPipeline.BlendDesc;
+ {
+ // Premultiplied over blend
+ BlendState.RenderTargets[0].BlendEnable = TRUE;
+ BlendState.RenderTargets[0].SrcBlend = BLEND_FACTOR_ONE;
+ BlendState.RenderTargets[0].BlendOp = BLEND_OPERATION_ADD;
+ BlendState.RenderTargets[0].DestBlend = BLEND_FACTOR_INV_SRC_ALPHA;
+ }
+
+ PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = false;
+
+ PSODesc.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB;
+ PSODesc.GraphicsPipeline.NumRenderTargets = 1;
+ PSODesc.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT;
+ PSODesc.GraphicsPipeline.PrimitiveTopologyType = PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+
+ RefCntAutoPtr<IShader> sprite_vs, sprite_ps, font_ps;
+ {
+ ShaderCreationAttribs attribs;
+ attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC;
+ attribs.Desc.ShaderType = SHADER_TYPE_VERTEX;
+ attribs.Desc.Name = "Sprite VS";
+ attribs.EntryPoint = "sprite_vs";
+ attribs.FilePath = "sprite_vs.hlsl";
+ attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
+ attribs.pShaderSourceStreamFactory = &BasicSSSFactory;
+ mDevice->CreateShader(attribs, &sprite_vs);
+ }
+
+ {
+ ShaderCreationAttribs attribs;
+ attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_DYNAMIC;
+ attribs.Desc.ShaderType = SHADER_TYPE_PIXEL;
+ attribs.Desc.Name = "Sprite PS";
+ attribs.EntryPoint = "sprite_ps";
+ attribs.FilePath = "sprite_ps.hlsl";
+ attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
+ attribs.pShaderSourceStreamFactory = &BasicSSSFactory;
+ mDevice->CreateShader(attribs, &sprite_ps);
+ }
+
+ {
+ ShaderCreationAttribs attribs;
+ attribs.Desc.DefaultVariableType = SHADER_VARIABLE_TYPE_STATIC;
+ attribs.Desc.ShaderType = SHADER_TYPE_PIXEL;
+ attribs.Desc.Name = "Font PS";
+ attribs.EntryPoint = "font_ps";
+ attribs.FilePath = "font_ps.hlsl";
+ attribs.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;
+ attribs.pShaderSourceStreamFactory = &BasicSSSFactory;
+ mDevice->CreateShader(attribs, &font_ps);
+ font_ps->GetShaderVariable("Tex")->Set(mFontTextureSRV);
+ }
+
+ PSODesc.Name = "Sprite PSO";
+ PSODesc.GraphicsPipeline.pVS = sprite_vs;
+ PSODesc.GraphicsPipeline.pPS = sprite_ps;
+ mDevice->CreatePipelineState(PSODesc, &mSpritePSO);
+ mSpritePSO->CreateShaderResourceBinding(&mSpriteSRB);
+
+ PSODesc.Name = "Font PSO";
+ PSODesc.GraphicsPipeline.pPS = font_ps;
+ mDevice->CreatePipelineState(PSODesc, &mFontPSO);
+ }
+
+
+ CreateMeshes();
+ InitializeTextureData();
+ if( m_BindingMode == BindingMode::Mutable )
+ {
+ for(size_t srb = 0; srb < NUM_ASTEROIDS; ++srb)
+ {
+ auto staticData = &mAsteroids->StaticData()[srb];
+ mAsteroidsSRBs[srb]->GetVariable(SHADER_TYPE_PIXEL, "Tex")->Set(mTextureSRVs[staticData->textureIndex]);
+ }
+ }
+ else if( m_BindingMode == BindingMode::TextureMutable )
+ {
+ for(size_t srb = 0; srb < NUM_UNIQUE_TEXTURES; ++srb)
+ {
+ mAsteroidsSRBs[srb]->GetVariable(SHADER_TYPE_PIXEL, "Tex")->Set(mTextureSRVs[srb]);
+ }
+ }
+
+}
+
+Asteroids::~Asteroids()
+{
+ {
+ std::unique_lock<std::mutex> lk(mMutex);
+ mExitThreads = true;
+ }
+ mCondVar.notify_all();
+
+ for(auto &thread : mWorkerThreads)
+ {
+ thread.join();
+ }
+}
+
+
+
+void Asteroids::ResizeSwapChain(HWND outputWindow, unsigned int width, unsigned int height)
+{
+ mSwapChain->Resize(width, height);
+ mBackBufferWidth = width;
+ mBackBufferHeight = height;
+}
+
+
+void Asteroids::CreateMeshes()
+{
+ auto asteroidMeshes = mAsteroids->Meshes();
+
+ // create vertex buffer
+ {
+ BufferDesc desc;
+ desc.Name = "Asteroid Meshes Vertex Buffer";
+ desc.uiSizeInBytes = (Uint32)asteroidMeshes->vertices.size() * sizeof(asteroidMeshes->vertices[0]);
+ desc.BindFlags = BIND_VERTEX_BUFFER;
+ desc.Usage = USAGE_DEFAULT;
+
+ BufferData data;
+ data.pData = asteroidMeshes->vertices.data();
+ data.DataSize = desc.uiSizeInBytes;
+
+ mDevice->CreateBuffer(desc, data, &mVertexBuffer);
+ }
+
+ // create index buffer
+ {
+ BufferDesc desc;
+ desc.Name = "Asteroid Meshes Index Buffer";
+ desc.uiSizeInBytes = (Uint32)asteroidMeshes->indices.size() * sizeof(asteroidMeshes->indices[0]);
+ desc.BindFlags = BIND_INDEX_BUFFER;
+ desc.Usage = USAGE_DEFAULT;
+
+ BufferData data;
+ data.pData = asteroidMeshes->indices.data();
+ data.DataSize = desc.uiSizeInBytes;
+
+ mDevice->CreateBuffer(desc, data, &mIndexBuffer);
+ }
+
+ std::vector<SkyboxVertex> skyboxVertices;
+ CreateSkyboxMesh(&skyboxVertices);
+
+
+ // create skybox vertex buffer
+ {
+ BufferDesc desc;
+ desc.Name = "Skybox Vertex Buffer";
+ desc.uiSizeInBytes = (Uint32)skyboxVertices.size() * sizeof(skyboxVertices[0]);
+ desc.BindFlags = BIND_VERTEX_BUFFER;
+ desc.Usage = USAGE_DEFAULT;
+
+ BufferData data;
+ data.pData = skyboxVertices.data();
+ data.DataSize = desc.uiSizeInBytes;
+
+ mDevice->CreateBuffer(desc, data, &mSkyboxVertexBuffer);
+ }
+
+ // create sprite vertex buffer (dynamic)
+ {
+ BufferDesc desc;
+ desc.Name = "sprite vertex buffer (dynamic)";
+ desc.uiSizeInBytes = (Uint32)MAX_SPRITE_VERTICES_PER_FRAME * sizeof(SpriteVertex);
+ desc.BindFlags = BIND_VERTEX_BUFFER;
+ desc.Usage = USAGE_DYNAMIC;
+ desc.CPUAccessFlags = CPU_ACCESS_WRITE;
+
+ mDevice->CreateBuffer(desc, BufferData(), &mSpriteVertexBuffer);
+ }
+}
+
+void Asteroids::InitializeTextureData()
+{
+ TextureDesc textureDesc;
+ textureDesc.Type = RESOURCE_DIM_TEX_2D_ARRAY;
+ textureDesc.Width = TEXTURE_DIM;
+ textureDesc.Height = TEXTURE_DIM;
+ textureDesc.ArraySize = 3;
+ textureDesc.MipLevels = 0; // Full chain
+ textureDesc.Format = TEX_FORMAT_RGBA8_UNORM_SRGB;
+ textureDesc.SampleCount = 1;
+ textureDesc.Usage = USAGE_DEFAULT;
+ textureDesc.BindFlags = BIND_SHADER_RESOURCE;
+
+ for (UINT t = 0; t < NUM_UNIQUE_TEXTURES; ++t) {
+ std::vector<TextureSubResData> subResData(textureDesc.ArraySize*mAsteroids->GetTextureMipLevels());
+ auto *texData = mAsteroids->TextureData(t);
+ for(size_t subRes=0; subRes < subResData.size(); ++subRes)
+ {
+ subResData[subRes].pData = texData[subRes].pSysMem;
+ subResData[subRes].Stride = texData[subRes].SysMemPitch;
+ subResData[subRes].DepthStride = texData[subRes].SysMemSlicePitch;
+ }
+ TextureData initData;
+ initData.NumSubresources = (Uint32)subResData.size();
+ initData.pSubResources = subResData.data();
+ mDevice->CreateTexture(textureDesc, initData, &mTextures[t]);
+ mTextureSRVs[t] = mTextures[t]->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
+ mTextureSRVs[t]->SetSampler(mSamplerState);
+ }
+}
+
+void Asteroids::CreateGUIResources()
+{
+ auto font = mGUI->Font();
+ TextureDesc textureDesc;
+ textureDesc.Type = RESOURCE_DIM_TEX_2D;
+ textureDesc.Format = TEX_FORMAT_R8_UNORM;
+ textureDesc.Width = font->BitmapWidth();
+ textureDesc.Height = font->BitmapHeight();
+ textureDesc.MipLevels = 1;
+ textureDesc.ArraySize = 1;
+ textureDesc.BindFlags = BIND_SHADER_RESOURCE;
+ textureDesc.Usage = USAGE_DEFAULT;
+
+ TextureData initialData;
+ TextureSubResData subresources[] = {
+ TextureSubResData((void*)font->Pixels(), font->BitmapWidth())
+ };
+ initialData.pSubResources = subresources;
+ initialData.NumSubresources = _countof(subresources);
+
+ RefCntAutoPtr<ITexture> texture;
+ mDevice->CreateTexture(textureDesc, initialData, &texture);
+ mFontTextureSRV = texture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
+ mFontTextureSRV->SetSampler(mSamplerState);
+
+ // Load any GUI sprite textures
+ for (int i = -1; i < (int)mGUI->size(); ++i) {
+ auto control = i >= 0 ? (*mGUI)[i] : mSprite.get();
+ if (control->TextureFile().length() > 0 && mSpriteTextures.find(control->TextureFile()) == mSpriteTextures.end()) {
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
+ ID3D11ShaderResourceView* textureSRV = nullptr;
+ auto path = NarrowString(converter.from_bytes(control->TextureFile()).c_str());
+ TextureLoadInfo loadInfo;
+ loadInfo.IsSRGB = true;
+ RefCntAutoPtr<ITexture> spriteTexture;
+ CreateTextureFromFile(path.c_str(), loadInfo, mDevice, &spriteTexture);
+ auto *pSRV = spriteTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE);
+ pSRV->SetSampler(mSamplerState);
+ mSpriteTextures[control->TextureFile()] = pSRV;
+ }
+ }
+}
+
+static_assert(sizeof(IndexType) == 2, "Expecting 16-bit index buffer");
+
+void Asteroids::WorkerThreadFunc(Asteroids *pThis, Diligent::Uint32 ThreadNum)
+{
+ for (;;)
+ {
+ // Wait for mUpdateSubsets or mExitThreads flag on conditional variable
+ {
+ std::unique_lock<std::mutex> lk(pThis->mMutex);
+ pThis->mCondVar.wait(lk, [&]{return pThis->mUpdateSubsets || pThis->mExitThreads;});
+ }
+
+ if(pThis->mExitThreads)
+ return;
+
+ auto SubsetSize = NUM_ASTEROIDS / pThis->mNumSubsets;
+ auto SubsetStart = SubsetSize * (ThreadNum+1);
+ auto &FrameAttribs = pThis->mFrameAttribs;
+
+ pThis->mAsteroids->Update(FrameAttribs.frameTime, FrameAttribs.camera->Eye(), *FrameAttribs.settings, SubsetStart, SubsetSize);
+
+ // Increment number of completed threads
+ ++pThis->m_NumThreadsCompleted;
+
+ // Wait for mRenderSubsets flag on conditional variable
+ {
+ std::unique_lock<std::mutex> lk(pThis->mMutex);
+ pThis->mCondVar.wait(lk, [&]{return pThis->mRenderSubsets || pThis->mExitThreads;});
+ }
+
+ pThis->RenderSubset(1+ThreadNum, pThis->mDeferredCtxt[ThreadNum], *FrameAttribs.camera, SubsetStart, SubsetSize);
+
+ RefCntAutoPtr<ICommandList> pCmdList;
+ pThis->mCmdLists[ThreadNum].Release();
+ pThis->mDeferredCtxt[ThreadNum]->FinishCommandList(&pThis->mCmdLists[ThreadNum]);
+
+ // Increment number of completed threads
+ ++pThis->m_NumThreadsCompleted;
+ }
+
+}
+
+void Asteroids::RenderSubset(Diligent::Uint32 SubsetNum,
+ IDeviceContext *pCtx,
+ const OrbitCamera& camera,
+ Uint32 startIdx,
+ Uint32 numAsteroids)
+{
+ pCtx->SetRenderTargets(0, nullptr, nullptr);
+
+ // Frame data
+ auto staticAsteroidData = mAsteroids->StaticData();
+ auto dynamicAsteroidData = mAsteroids->DynamicData();
+
+ pCtx->SetPipelineState(mAsteroidsPSO);
+
+ {
+ IBuffer* ia_buffers[] = { mVertexBuffer };
+ Uint32 ia_strides[] = { sizeof(Vertex) };
+ Uint32 ia_offsets[] = { 0 };
+ pCtx->SetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets, 0);
+ pCtx->SetIndexBuffer(mIndexBuffer, 0);
+ }
+
+ auto pVar = m_BindingMode == BindingMode::Dynamic ? mAsteroidsSRBs[SubsetNum]->GetVariable(SHADER_TYPE_PIXEL, "Tex") : nullptr;
+ auto viewProjection = camera.ViewProjection();
+ for (UINT drawIdx = startIdx; drawIdx < startIdx+numAsteroids; ++drawIdx)
+ {
+ auto staticData = &staticAsteroidData[drawIdx];
+ auto dynamicData = &dynamicAsteroidData[drawIdx];
+
+ {
+ MapHelper<DrawConstantBuffer> drawConstants(pCtx, mDrawConstantBuffer, MAP_WRITE_DISCARD, 0);
+ XMStoreFloat4x4(&drawConstants->mWorld, dynamicData->world);
+ XMStoreFloat4x4(&drawConstants->mViewProjection, viewProjection);
+ drawConstants->mSurfaceColor = staticData->surfaceColor;
+ drawConstants->mDeepColor = staticData->deepColor;
+ }
+ if( m_BindingMode == BindingMode::Dynamic )
+ {
+ pVar->Set(mTextureSRVs[staticData->textureIndex]);
+ pCtx->CommitShaderResources(mAsteroidsSRBs[SubsetNum], COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
+ }
+ else if( m_BindingMode == BindingMode::Mutable )
+ {
+ pCtx->CommitShaderResources(mAsteroidsSRBs[drawIdx], COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
+ }
+ else if( m_BindingMode == BindingMode::TextureMutable )
+ {
+ pCtx->CommitShaderResources(mAsteroidsSRBs[staticData->textureIndex], 0);
+ }
+
+ DrawAttribs attribs;
+ attribs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+ attribs.IsIndexed = true;
+ attribs.NumIndices = dynamicData->indexCount;
+ attribs.IndexType = VT_UINT16;
+ attribs.FirstIndexLocation = dynamicData->indexStart;
+ attribs.BaseVertex = staticData->vertexStart;
+ pCtx->Draw(attribs);
+ }
+}
+
+void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Settings& settings)
+{
+ mFrameAttribs.frameTime = frameTime;
+ mFrameAttribs.camera = &camera;
+ mFrameAttribs.settings = &settings;
+
+ // Clear the render target
+ float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ mDeviceCtxt->SetRenderTargets(0, nullptr, nullptr);
+ mDeviceCtxt->ClearRenderTarget(nullptr, clearcol);
+ mDeviceCtxt->ClearDepthStencil(nullptr, CLEAR_DEPTH_FLAG, 0.0f, 0);
+
+ if( m_BindingMode == BindingMode::TextureMutable )
+ {
+ for(auto &srb=mAsteroidsSRBs.begin(); srb!=mAsteroidsSRBs.end(); ++srb)
+ {
+ mDeviceCtxt->TransitionShaderResources(mAsteroidsPSO, *srb);
+ }
+ }
+
+ LONG64 currCounter;
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ mUpdateTicks = currCounter;
+
+ auto SubsetSize = NUM_ASTEROIDS / (settings.multithreadedRendering ? mNumSubsets : 1);
+
+ if (settings.multithreadedRendering)
+ {
+ // Set mUpdateSubsets flag
+ {
+ std::unique_lock<std::mutex> lk(mMutex);
+ mUpdateSubsets = true;
+ m_NumThreadsCompleted = 0;
+ }
+ mCondVar.notify_all();
+ }
+
+ mAsteroids->Update(frameTime, camera.Eye(), settings, 0, SubsetSize);
+
+ if (settings.multithreadedRendering)
+ {
+ // Wait for worker threads to finish
+ while(m_NumThreadsCompleted < (int)mNumSubsets-1)
+ std::this_thread::yield();
+ // Clear mUpdateSubsets flag while all threads are waiting for mRenderSubsets flag
+ mUpdateSubsets = false;
+ }
+
+
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ mUpdateTicks = currCounter-mUpdateTicks;
+
+ mRenderTicks = currCounter;
+
+ if (settings.multithreadedRendering)
+ {
+ // Set mRenderSubsets flag
+ {
+ std::unique_lock<std::mutex> lk(mMutex);
+ mRenderSubsets = true;
+ m_NumThreadsCompleted = 0;
+ }
+ mCondVar.notify_all();
+ }
+
+ RenderSubset(0, mDeviceCtxt, camera, 0, SubsetSize);
+
+ if (settings.multithreadedRendering)
+ {
+ // Wait for worker threads to finish
+ while(m_NumThreadsCompleted < (int)mNumSubsets-1)
+ std::this_thread::yield();
+ // Clear mRenderSubsets flag while all threads are waiting for mUpdateSubsets flag
+ mRenderSubsets = false;
+
+ for(auto &cmdList : mCmdLists)
+ {
+ mDeviceCtxt->ExecuteCommandList(cmdList);
+ }
+ }
+
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ mRenderTicks = currCounter-mRenderTicks;
+
+ mDeviceCtxt->SetRenderTargets(0, nullptr, nullptr);
+ // Draw skybox
+ {
+ {
+ MapHelper<SkyboxConstantBuffer> skyboxConstants(mDeviceCtxt, mSkyboxConstantBuffer, MAP_WRITE_DISCARD, 0);
+ XMStoreFloat4x4(&skyboxConstants->mViewProjection, camera.ViewProjection());
+ }
+
+ IBuffer* ia_buffers[] = { mSkyboxVertexBuffer };
+ UINT ia_strides[] = { sizeof(SkyboxVertex) };
+ UINT ia_offsets[] = { 0 };
+ mDeviceCtxt->SetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets, 0);
+
+ mDeviceCtxt->SetPipelineState(mSkyboxPSO);
+ mDeviceCtxt->CommitShaderResources(nullptr, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
+
+ DrawAttribs DrawAttrs;
+ DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+ DrawAttrs.NumVertices = 6*6;
+ mDeviceCtxt->Draw(DrawAttrs);
+ }
+
+ // Draw sprites and fonts
+ {
+ // Fill in vertices (TODO: could move this vector to be a member - not a big deal)
+ std::vector<UINT> controlVertices;
+ controlVertices.reserve(mGUI->size());
+
+ {
+ MapHelper<SpriteVertex> vertexBase(mDeviceCtxt, mSpriteVertexBuffer, MAP_WRITE_DISCARD, 0);
+ auto vertexEnd = (SpriteVertex*)vertexBase;
+
+ for (int i = -1; i < (int)mGUI->size(); ++i) {
+ auto control = i >= 0 ? (*mGUI)[i] : mSprite.get();
+ controlVertices.push_back((UINT)(control->Draw((float)mBackBufferWidth, (float)mBackBufferHeight, vertexEnd) - vertexEnd));
+ vertexEnd += controlVertices.back();
+ }
+ }
+
+ IBuffer* ia_buffers[] = { mSpriteVertexBuffer };
+ Uint32 ia_strides[] = { sizeof(SpriteVertex) };
+ Uint32 ia_offsets[] = { 0 };
+ mDeviceCtxt->SetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets, 0);
+
+ // Draw
+ UINT vertexStart = 0;
+ for (int i = -1; i < (int)mGUI->size(); ++i) {
+ auto control = i >= 0 ? (*mGUI)[i] : mSprite.get();
+ if (control->Visible()) {
+ if (control->TextureFile().length() == 0) { // Font
+ mDeviceCtxt->SetPipelineState(mFontPSO);
+ mDeviceCtxt->CommitShaderResources(nullptr, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
+ } else { // Sprite
+ auto textureSRV = mSpriteTextures[control->TextureFile()];
+ mDeviceCtxt->SetPipelineState(mSpritePSO);
+ mSpriteSRB->GetVariable(SHADER_TYPE_PIXEL, "Tex")->Set(textureSRV);
+ mDeviceCtxt->CommitShaderResources(mSpriteSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
+ }
+ DrawAttribs DrawAttrs;
+ DrawAttrs.Topology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+ DrawAttrs.NumVertices = controlVertices[1+i];
+ DrawAttrs.StartVertexLocation = vertexStart;
+ mDeviceCtxt->Draw(DrawAttrs);
+ }
+ vertexStart += controlVertices[1+i];
+ }
+ }
+
+ mSwapChain->Present();//settings.vsync ? 1 : 0, 0);
+}
+
+void Asteroids::GetPerfCounters(float &UpdateTime, float &RenderTime)
+{
+ UpdateTime = (float)mUpdateTicks/(float)mPerfCounterFreq;
+ RenderTime = (float)mRenderTicks/(float)mPerfCounterFreq;
+}
+
+} // namespace AsteroidsDE
diff --git a/Projects/Asteroids/src/asteroids_DE.h b/Projects/Asteroids/src/asteroids_DE.h
new file mode 100644
index 0000000..271d511
--- /dev/null
+++ b/Projects/Asteroids/src/asteroids_DE.h
@@ -0,0 +1,123 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include "RenderDevice.h"
+#include "SwapChain.h"
+#include "DeviceContext.h"
+#include <map>
+#include <mutex>
+#include <atomic>
+
+#include "camera.h"
+#include "settings.h"
+#include "simulation.h"
+#include "util.h"
+#include "gui.h"
+#include "RefCntAutoPtr.h"
+
+namespace AsteroidsDE {
+
+struct DrawConstantBuffer {
+ DirectX::XMFLOAT4X4 mWorld;
+ DirectX::XMFLOAT4X4 mViewProjection;
+ DirectX::XMFLOAT3 mSurfaceColor;
+ float unused0;
+ DirectX::XMFLOAT3 mDeepColor;
+ float unused1;
+};
+
+struct SkyboxConstantBuffer {
+ DirectX::XMFLOAT4X4 mViewProjection;
+};
+
+class Asteroids {
+public:
+ Asteroids(UINT NumThreads, AsteroidsSimulation* asteroids, GUI* gui, HWND hWnd, Diligent::DeviceType DevType);
+ ~Asteroids();
+
+ void Render(float frameTime, const OrbitCamera& camera, const Settings& settings);
+
+ void ResizeSwapChain(HWND outputWindow, unsigned int width, unsigned int height);
+
+ void GetPerfCounters(float &UpdateTime, float &RenderTime);
+
+private:
+ void CreateMeshes();
+ void InitializeTextureData();
+ void CreateGUIResources();
+ void RenderSubset(Diligent::Uint32 SubsetNum, Diligent::IDeviceContext *pCtx, const OrbitCamera& camera, Diligent::Uint32 startIdx, Diligent::Uint32 numAsteroids);
+ void InitDevice(HWND hWnd, Diligent::DeviceType DevType);
+
+ enum class BindingMode
+ {
+ Dynamic = 1,
+ Mutable = 2,
+ TextureMutable = 3
+ }m_BindingMode = BindingMode::TextureMutable;
+
+ AsteroidsSimulation* mAsteroids = nullptr;
+ GUI* mGUI = nullptr;
+
+ Diligent::RefCntAutoPtr<Diligent::ISwapChain> mSwapChain;
+ Diligent::RefCntAutoPtr<Diligent::IRenderDevice> mDevice;
+ Diligent::RefCntAutoPtr<Diligent::IDeviceContext> mDeviceCtxt;
+ std::vector< Diligent::RefCntAutoPtr<Diligent::IDeviceContext> > mDeferredCtxt;
+ std::vector< Diligent::RefCntAutoPtr<Diligent::ICommandList> > mCmdLists;
+
+ Diligent::Uint32 mBackBufferWidth, mBackBufferHeight;
+ Diligent::Uint32 mNumSubsets = 0;
+ std::vector<std::thread> mWorkerThreads;
+
+ std::mutex mMutex;
+ std::condition_variable mCondVar;
+ bool mUpdateSubsets = false;
+ bool mRenderSubsets = false;
+ bool mExitThreads = false;
+ std::atomic_int m_NumThreadsCompleted;
+ static void WorkerThreadFunc(Asteroids *pThis, Diligent::Uint32 ThreadNum);
+
+ struct FrameAttribs
+ {
+ float frameTime;
+ const OrbitCamera* camera;
+ const Settings* settings;
+ }mFrameAttribs;
+
+ Diligent::RefCntAutoPtr<Diligent::IBuffer> mIndexBuffer;
+ Diligent::RefCntAutoPtr<Diligent::IBuffer> mVertexBuffer;
+ Diligent::RefCntAutoPtr<Diligent::IBuffer> mDrawConstantBuffer;
+ Diligent::RefCntAutoPtr<Diligent::IBuffer> mSpriteVertexBuffer;
+ Diligent::RefCntAutoPtr<Diligent::IBuffer> mSkyboxConstantBuffer;
+ Diligent::RefCntAutoPtr<Diligent::IBuffer> mSkyboxVertexBuffer;
+
+ Diligent::RefCntAutoPtr<Diligent::IPipelineState> mAsteroidsPSO;
+ std::vector< Diligent::RefCntAutoPtr<Diligent::IShaderResourceBinding> > mAsteroidsSRBs;
+
+ Diligent::RefCntAutoPtr<Diligent::IPipelineState> mFontPSO;
+ Diligent::RefCntAutoPtr<Diligent::IPipelineState> mSpritePSO;
+ Diligent::RefCntAutoPtr<Diligent::IShaderResourceBinding> mSpriteSRB;
+
+ Diligent::RefCntAutoPtr<Diligent::IPipelineState> mSkyboxPSO;
+
+ std::map<std::string, Diligent::RefCntAutoPtr<Diligent::ITextureView>> mSpriteTextures;
+ Diligent::RefCntAutoPtr<Diligent::ITextureView> mSkyboxSRV;
+ Diligent::RefCntAutoPtr<Diligent::ITextureView> mFontTextureSRV;
+ Diligent::RefCntAutoPtr<Diligent::ITexture> mTextures[NUM_UNIQUE_TEXTURES];
+ Diligent::RefCntAutoPtr<Diligent::ITextureView> mTextureSRVs[NUM_UNIQUE_TEXTURES];
+ Diligent::RefCntAutoPtr<Diligent::ISampler> mSamplerState;
+
+ std::unique_ptr<GUISprite> mSprite;
+ UINT64 mPerfCounterFreq = 0;
+ volatile LONG64 mUpdateTicks = 0, mRenderTicks = 0;
+};
+
+} // namespace AsteroidsD3D11
diff --git a/Projects/Asteroids/src/asteroids_d3d11.cpp b/Projects/Asteroids/src/asteroids_d3d11.cpp
new file mode 100644
index 0000000..85602e5
--- /dev/null
+++ b/Projects/Asteroids/src/asteroids_d3d11.cpp
@@ -0,0 +1,594 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#include <d3dcompiler.h>
+#include <directxmath.h>
+#include <math.h>
+
+#include <iostream>
+#include <algorithm>
+#include <vector>
+#include <future>
+#include <limits>
+#include <random>
+#include <locale>
+#include <codecvt>
+
+#include "asteroids_d3d11.h"
+#include "util.h"
+#include "mesh.h"
+#include "noise.h"
+#include "texture.h"
+#include "DDSTextureLoader.h"
+
+#include "asteroid_vs.h"
+#include "asteroid_ps_d3d11.h"
+#include "skybox_vs.h"
+#include "skybox_ps.h"
+#include "sprite_vs.h"
+#include "sprite_ps.h"
+#include "font_ps.h"
+
+using namespace DirectX;
+
+namespace AsteroidsD3D11 {
+
+Asteroids::Asteroids(AsteroidsSimulation* asteroids, GUI* gui, bool warp)
+ : mAsteroids(asteroids)
+ , mGUI(gui)
+ , mSwapChain(nullptr)
+ , mDevice(nullptr)
+ , mDeviceCtxt(nullptr)
+ , mRenderTarget(nullptr)
+ , mRenderTargetView(nullptr)
+ , mDepthStencilView(nullptr)
+ , mDepthStencilState(nullptr)
+ , mInputLayout(nullptr)
+ , mIndexBuffer(nullptr)
+ , mVertexBuffer(nullptr)
+ , mVertexShader(nullptr)
+ , mPixelShader(nullptr)
+ , mDrawConstantBuffer(nullptr)
+ , mSkyboxVertexShader(nullptr)
+ , mSkyboxPixelShader(nullptr)
+ , mSkyboxConstantBuffer(nullptr)
+ , mSamplerState(nullptr)
+ , mD3D11Sprite( new GUISprite(5, 10, 140, 50, "directx11.dds") )
+{
+ QueryPerformanceFrequency((LARGE_INTEGER*)&mPerfCounterFreq);
+
+ memset(&mViewPort, 0, sizeof(mViewPort));
+ memset(&mScissorRect, 0, sizeof(mScissorRect));
+ memset(mTextures, 0, sizeof(mTextures));
+ memset(mTextureSRVs, 0, sizeof(mTextureSRVs));
+
+ // Create device and swap chain
+ {
+ IDXGIAdapter* adapter = nullptr;
+ D3D_DRIVER_TYPE driverType = ( warp ) ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_HARDWARE;
+ HMODULE swModule = NULL;
+ UINT flags = 0;
+ D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 };
+ UINT numFeatureLevels = ARRAYSIZE(featureLevels);
+ UINT sdkVersion = D3D11_SDK_VERSION;
+
+#ifdef _DEBUG
+ flags = flags | D3D11_CREATE_DEVICE_DEBUG;
+#endif
+
+ auto hr = D3D11CreateDevice(adapter, driverType, swModule,
+ flags, featureLevels, numFeatureLevels, sdkVersion, &mDevice, nullptr, &mDeviceCtxt);
+ if (FAILED(hr)) {
+ // Try again without the debug flag...
+ flags = flags & ~D3D11_CREATE_DEVICE_DEBUG;
+ ThrowIfFailed(D3D11CreateDevice(adapter, driverType, swModule,
+ flags, featureLevels, numFeatureLevels, sdkVersion, &mDevice, nullptr, &mDeviceCtxt));
+ }
+ }
+
+ // create pipeline state
+ {
+ D3D11_INPUT_ELEMENT_DESC inputDesc[] = {
+ { "ATTRIB", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "ATTRIB", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc),
+ g_asteroid_vs, sizeof(g_asteroid_vs), &mInputLayout));
+
+ {
+ D3D11_DEPTH_STENCIL_DESC desc = CD3D11_DEPTH_STENCIL_DESC(D3D11_DEFAULT);
+ desc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL;
+ ThrowIfFailed(mDevice->CreateDepthStencilState(&desc, &mDepthStencilState));
+ }
+ {
+ CD3D11_BLEND_DESC desc = CD3D11_BLEND_DESC(CD3D11_DEFAULT());
+ ThrowIfFailed(mDevice->CreateBlendState(&desc, &mBlendState));
+
+ // Premultiplied over blend
+ desc.RenderTarget[0].BlendEnable = TRUE;
+ desc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
+ desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
+ desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
+ ThrowIfFailed(mDevice->CreateBlendState(&desc, &mSpriteBlendState));
+ }
+
+ ThrowIfFailed(mDevice->CreateVertexShader(g_asteroid_vs, sizeof(g_asteroid_vs), NULL, &mVertexShader));
+ ThrowIfFailed(mDevice->CreatePixelShader(g_asteroid_ps_d3d11, sizeof(g_asteroid_ps_d3d11), NULL, &mPixelShader));
+ }
+ // create skybox pipeline state
+ {
+ D3D11_INPUT_ELEMENT_DESC inputDesc[] = {
+ { "ATTRIB", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "ATTRIB", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc),
+ g_skybox_vs, sizeof(g_skybox_vs), &mSkyboxInputLayout));
+
+ ThrowIfFailed(mDevice->CreateVertexShader(g_skybox_vs, sizeof(g_skybox_vs), NULL, &mSkyboxVertexShader));
+ ThrowIfFailed(mDevice->CreatePixelShader(g_skybox_ps, sizeof(g_skybox_ps), NULL, &mSkyboxPixelShader));
+ }
+
+ // Sprites and fonts
+ {
+ D3D11_INPUT_ELEMENT_DESC inputDesc[] = {
+ { "ATTRIB", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "ATTRIB", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ ThrowIfFailed(mDevice->CreateInputLayout(inputDesc, ARRAYSIZE(inputDesc),
+ g_sprite_vs, sizeof(g_sprite_vs), &mSpriteInputLayout));
+
+ ThrowIfFailed(mDevice->CreateVertexShader(g_sprite_vs, sizeof(g_sprite_vs), NULL, &mSpriteVertexShader));
+ ThrowIfFailed(mDevice->CreatePixelShader(g_sprite_ps, sizeof(g_sprite_ps), NULL, &mSpritePixelShader));
+ ThrowIfFailed(mDevice->CreatePixelShader(g_font_ps, sizeof(g_font_ps), NULL, &mFontPixelShader));
+ }
+
+ // Create draw constant buffer
+ {
+ D3D11_BUFFER_DESC desc = {};
+ desc.Usage = D3D11_USAGE_DYNAMIC;
+ desc.ByteWidth = sizeof(DrawConstantBuffer);
+ desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ ThrowIfFailed(mDevice->CreateBuffer(&desc, nullptr, &mDrawConstantBuffer));
+ }
+ // Create skybox constant buffer
+ {
+ D3D11_BUFFER_DESC desc = {};
+ desc.Usage = D3D11_USAGE_DYNAMIC;
+ desc.ByteWidth = sizeof(SkyboxConstantBuffer);
+ desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ ThrowIfFailed(mDevice->CreateBuffer(&desc, nullptr, &mSkyboxConstantBuffer));
+ }
+
+ // Create sampler
+ {
+ D3D11_SAMPLER_DESC desc = {};
+ desc.Filter = D3D11_FILTER_ANISOTROPIC;
+ desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
+ desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
+ desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
+ desc.MinLOD = -D3D11_FLOAT32_MAX;
+ desc.MaxLOD = D3D11_FLOAT32_MAX;
+ desc.MipLODBias = 0.0f;
+ desc.MaxAnisotropy = TEXTURE_ANISO;
+ desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ ThrowIfFailed(mDevice->CreateSamplerState(&desc, &mSamplerState));
+ }
+
+ CreateMeshes();
+ InitializeTextureData();
+ CreateGUIResources();
+
+ // Load textures
+ ThrowIfFailed(CreateDDSTextureFromFile(mDevice, L"starbox_1024.dds", &mSkyboxSRV, true));
+}
+
+Asteroids::~Asteroids()
+{
+ ReleaseSwapChain();
+
+ SafeRelease(&mDepthStencilState);
+ SafeRelease(&mInputLayout);
+ SafeRelease(&mIndexBuffer);
+ SafeRelease(&mVertexBuffer);
+ SafeRelease(&mVertexShader);
+ SafeRelease(&mPixelShader);
+ SafeRelease(&mDrawConstantBuffer);
+ SafeRelease(&mSamplerState);
+
+ SafeRelease(&mBlendState);
+ SafeRelease(&mSpriteBlendState);
+
+ for (auto i : mSpriteTextures) {
+ i.second->Release();
+ }
+ SafeRelease(&mSpriteInputLayout);
+ SafeRelease(&mSpriteVertexShader);
+ SafeRelease(&mSpritePixelShader);
+ SafeRelease(&mSpriteVertexBuffer);
+
+ SafeRelease(&mFontPixelShader);
+ SafeRelease(&mFontTextureSRV);
+
+ SafeRelease(&mSkyboxVertexShader);
+ SafeRelease(&mSkyboxPixelShader);
+ SafeRelease(&mSkyboxConstantBuffer);
+ SafeRelease(&mSkyboxVertexBuffer);
+ SafeRelease(&mSkyboxInputLayout);
+ SafeRelease(&mSkyboxSRV);
+
+ for (auto& texture : mTextures) SafeRelease(&texture);
+ for (auto& srv : mTextureSRVs) SafeRelease(&srv);
+
+ if (mSwapChain != nullptr) {
+ mSwapChain->Release();
+ mSwapChain = nullptr;
+ }
+ SafeRelease(&mDeviceCtxt);
+ SafeRelease(&mDevice);
+
+ delete mD3D11Sprite;
+}
+
+
+void Asteroids::ReleaseSwapChain()
+{
+ // Cleanup any references...
+ SafeRelease(&mRenderTarget);
+ SafeRelease(&mRenderTargetView);
+ SafeRelease(&mDepthStencilView);
+ SafeRelease(&mSwapChain);
+ mDeviceCtxt->ClearState();
+ mDeviceCtxt->Flush();
+}
+
+inline void DisableDXGIWindowChanges(IUnknown* device, HWND window)
+{
+ IDXGIDevice * pDXGIDevice;
+ ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)));
+ IDXGIAdapter * pDXGIAdapter;
+ ThrowIfFailed(pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)));
+ IDXGIFactory * pIDXGIFactory;
+ ThrowIfFailed(pDXGIAdapter->GetParent(IID_PPV_ARGS(&pIDXGIFactory)));
+
+ ThrowIfFailed(pIDXGIFactory->MakeWindowAssociation(window, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER));
+
+ pIDXGIFactory->Release();
+ pDXGIAdapter->Release();
+ pDXGIDevice->Release();
+}
+
+void Asteroids::ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height)
+{
+ ReleaseSwapChain();
+
+ // Create swap chain
+ {
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // Can create an SRGB render target view on the swap chain buffer
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.BufferCount = NUM_SWAP_CHAIN_BUFFERS;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used
+ swapChainDesc.Flags = 0;
+
+ ThrowIfFailed(dxgiFactory->CreateSwapChainForHwnd(
+ mDevice, outputWindow, &swapChainDesc, nullptr, nullptr, &mSwapChain));
+ // MakeWindowAssociation must be called after CreateSwapChain
+ DisableDXGIWindowChanges(mDevice, outputWindow);
+ }
+
+ // create render target view
+ {
+ ThrowIfFailed(mSwapChain->GetBuffer(0, IID_PPV_ARGS(&mRenderTarget)));
+
+ D3D11_RENDER_TARGET_VIEW_DESC desc = {};
+ desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
+ desc.Texture2D.MipSlice = 0;
+ ThrowIfFailed(mDevice->CreateRenderTargetView(mRenderTarget, &desc, &mRenderTargetView));
+ }
+
+ // create depth stencil view
+ {
+ CD3D11_TEXTURE2D_DESC desc = CD3D11_TEXTURE2D_DESC(
+ DXGI_FORMAT_D32_FLOAT, width, height, 1, 1, D3D11_BIND_DEPTH_STENCIL);
+
+ ID3D11Texture2D* depthStencil = nullptr;
+ ThrowIfFailed(mDevice->CreateTexture2D(&desc, nullptr, &depthStencil));
+ ThrowIfFailed(mDevice->CreateDepthStencilView(depthStencil, nullptr, &mDepthStencilView));
+ depthStencil->Release();
+ }
+
+ // update the viewport and scissor
+ ZeroMemory(&mViewPort, sizeof(D3D11_VIEWPORT));
+ mViewPort.TopLeftX = 0;
+ mViewPort.TopLeftY = 0;
+ mViewPort.Width = (float)width;
+ mViewPort.Height = (float)height;
+ mViewPort.MinDepth = 0.0f;
+ mViewPort.MaxDepth = 1.0f;
+
+ mScissorRect.left = 0;
+ mScissorRect.top = 0;
+ mScissorRect.right = width;
+ mScissorRect.bottom = height;
+}
+
+
+void Asteroids::CreateMeshes()
+{
+ auto asteroidMeshes = mAsteroids->Meshes();
+
+ // create vertex buffer
+ {
+ CD3D11_BUFFER_DESC desc(
+ (UINT)asteroidMeshes->vertices.size() * sizeof(asteroidMeshes->vertices[0]),
+ D3D11_BIND_VERTEX_BUFFER,
+ D3D11_USAGE_DEFAULT);
+
+ D3D11_SUBRESOURCE_DATA data = {};
+ data.pSysMem = asteroidMeshes->vertices.data();
+
+ ThrowIfFailed(mDevice->CreateBuffer(&desc, &data, &mVertexBuffer));
+ }
+
+ // create index buffer
+ {
+ CD3D11_BUFFER_DESC desc(
+ (UINT)asteroidMeshes->indices.size() * sizeof(asteroidMeshes->indices[0]),
+ D3D11_BIND_INDEX_BUFFER,
+ D3D11_USAGE_DEFAULT);
+
+ D3D11_SUBRESOURCE_DATA data = {};
+ data.pSysMem = asteroidMeshes->indices.data();
+
+ ThrowIfFailed(mDevice->CreateBuffer(&desc, &data, &mIndexBuffer));
+ }
+
+ std::vector<SkyboxVertex> skyboxVertices;
+ CreateSkyboxMesh(&skyboxVertices);
+
+ // create skybox vertex buffer
+ {
+ CD3D11_BUFFER_DESC desc(
+ (UINT)skyboxVertices.size() * sizeof(skyboxVertices[0]),
+ D3D11_BIND_VERTEX_BUFFER,
+ D3D11_USAGE_DEFAULT);
+
+ D3D11_SUBRESOURCE_DATA data = {};
+ data.pSysMem = skyboxVertices.data();
+
+ ThrowIfFailed(mDevice->CreateBuffer(&desc, &data, &mSkyboxVertexBuffer));
+ }
+
+ // create sprite vertex buffer (dynamic)
+ {
+ CD3D11_BUFFER_DESC desc(
+ MAX_SPRITE_VERTICES_PER_FRAME * sizeof(SpriteVertex),
+ D3D11_BIND_VERTEX_BUFFER,
+ D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
+
+ ThrowIfFailed(mDevice->CreateBuffer(&desc, nullptr, &mSpriteVertexBuffer));
+ }
+}
+
+void Asteroids::InitializeTextureData()
+{
+ D3D11_TEXTURE2D_DESC textureDesc = {};
+ textureDesc.Width = TEXTURE_DIM;
+ textureDesc.Height = TEXTURE_DIM;
+ textureDesc.ArraySize = 3;
+ textureDesc.MipLevels = 0; // Full chain
+ textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ textureDesc.SampleDesc.Count = 1;
+ textureDesc.Usage = D3D11_USAGE_DEFAULT;
+ textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+
+ for (UINT t = 0; t < NUM_UNIQUE_TEXTURES; ++t) {
+ ThrowIfFailed(mDevice->CreateTexture2D(&textureDesc, mAsteroids->TextureData(t), &mTextures[t]));
+ ThrowIfFailed(mDevice->CreateShaderResourceView(mTextures[t], nullptr, &mTextureSRVs[t]));
+ }
+}
+
+void Asteroids::CreateGUIResources()
+{
+ auto font = mGUI->Font();
+ D3D11_TEXTURE2D_DESC textureDesc = CD3D11_TEXTURE2D_DESC(DXGI_FORMAT_R8_UNORM, font->BitmapWidth(), font->BitmapHeight(), 1, 1);
+
+ D3D11_SUBRESOURCE_DATA initialData = {};
+ initialData.pSysMem = font->Pixels();
+ initialData.SysMemPitch = font->BitmapWidth();
+
+ ID3D11Texture2D* texture = nullptr;
+ ThrowIfFailed(mDevice->CreateTexture2D(&textureDesc, &initialData, &texture));
+ ThrowIfFailed(mDevice->CreateShaderResourceView(texture, nullptr, &mFontTextureSRV));
+ SafeRelease(&texture);
+
+ // Load any GUI sprite textures
+ for (int i = -1; i < (int)mGUI->size(); ++i) {
+ auto control = i >= 0 ? (*mGUI)[i] : mD3D11Sprite;
+ if (control->TextureFile().length() > 0 && mSpriteTextures.find(control->TextureFile()) == mSpriteTextures.end()) {
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
+ ID3D11ShaderResourceView* textureSRV = nullptr;
+ ThrowIfFailed(CreateDDSTextureFromFile(mDevice, converter.from_bytes(control->TextureFile()).c_str(), &textureSRV, true));
+ mSpriteTextures[control->TextureFile()] = textureSRV;
+ }
+ }
+}
+
+static_assert(sizeof(IndexType) == 2, "Expecting 16-bit index buffer");
+
+void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Settings& settings)
+{
+ LONG64 currCounter = 0;
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+
+ // Frame data
+ mAsteroids->Update(frameTime, camera.Eye(), settings);
+
+ mTotalUpdateTicks = currCounter;
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ mTotalUpdateTicks = currCounter - mTotalUpdateTicks;
+
+ auto staticAsteroidData = mAsteroids->StaticData();
+ auto dynamicAsteroidData = mAsteroids->DynamicData();
+
+ // Clear the render target
+ float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ mDeviceCtxt->ClearRenderTargetView(mRenderTargetView, clearcol);
+ mDeviceCtxt->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH, 0.0f, 0);
+
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ {
+ ID3D11Buffer* ia_buffers[] = { mVertexBuffer };
+ UINT ia_strides[] = { sizeof(Vertex) };
+ UINT ia_offsets[] = { 0 };
+ mDeviceCtxt->IASetInputLayout(mInputLayout);
+ mDeviceCtxt->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ mDeviceCtxt->IASetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets);
+ mDeviceCtxt->IASetIndexBuffer(mIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
+ }
+
+ mDeviceCtxt->VSSetShader(mVertexShader, nullptr, 0);
+ mDeviceCtxt->VSSetConstantBuffers(0, 1, &mDrawConstantBuffer);
+
+ mDeviceCtxt->RSSetViewports(1, &mViewPort);
+ mDeviceCtxt->RSSetScissorRects(1, &mScissorRect);
+
+ mDeviceCtxt->PSSetShader(mPixelShader, nullptr, 0);
+ mDeviceCtxt->PSSetSamplers(0, 1, &mSamplerState);
+
+ mDeviceCtxt->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
+ mDeviceCtxt->OMSetDepthStencilState(mDepthStencilState, 0);
+ mDeviceCtxt->OMSetBlendState(mBlendState, nullptr, 0xFFFFFFFF);
+
+ auto viewProjection = camera.ViewProjection();
+ for (UINT drawIdx = 0; drawIdx < NUM_ASTEROIDS; ++drawIdx)
+ {
+ auto staticData = &staticAsteroidData[drawIdx];
+ auto dynamicData = &dynamicAsteroidData[drawIdx];
+
+ D3D11_MAPPED_SUBRESOURCE mapped = {};
+ ThrowIfFailed(mDeviceCtxt->Map(mDrawConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped));
+
+ auto drawConstants = (DrawConstantBuffer*) mapped.pData;
+ XMStoreFloat4x4(&drawConstants->mWorld, dynamicData->world);
+ XMStoreFloat4x4(&drawConstants->mViewProjection, viewProjection);
+ drawConstants->mSurfaceColor = staticData->surfaceColor;
+ drawConstants->mDeepColor = staticData->deepColor;
+
+ mDeviceCtxt->Unmap(mDrawConstantBuffer, 0);
+
+ mDeviceCtxt->PSSetShaderResources(0, 1, &mTextureSRVs[staticData->textureIndex]);
+
+ mDeviceCtxt->DrawIndexedInstanced(dynamicData->indexCount, 1, dynamicData->indexStart, staticData->vertexStart, 0);
+ }
+
+ mTotalRenderTicks = currCounter;
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ mTotalRenderTicks = currCounter - mTotalRenderTicks;
+
+ // Draw skybox
+ {
+ D3D11_MAPPED_SUBRESOURCE mapped = {};
+ ThrowIfFailed(mDeviceCtxt->Map(mSkyboxConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped));
+ auto skyboxConstants = (SkyboxConstantBuffer*) mapped.pData;
+ XMStoreFloat4x4(&skyboxConstants->mViewProjection, camera.ViewProjection());
+ mDeviceCtxt->Unmap(mSkyboxConstantBuffer, 0);
+
+ ID3D11Buffer* ia_buffers[] = { mSkyboxVertexBuffer };
+ UINT ia_strides[] = { sizeof(SkyboxVertex) };
+ UINT ia_offsets[] = { 0 };
+ mDeviceCtxt->IASetInputLayout(mSkyboxInputLayout);
+ mDeviceCtxt->IASetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets);
+
+ mDeviceCtxt->VSSetShader(mSkyboxVertexShader, nullptr, 0);
+ mDeviceCtxt->VSSetConstantBuffers(0, 1, &mSkyboxConstantBuffer);
+
+ mDeviceCtxt->PSSetShader(mSkyboxPixelShader, nullptr, 0);
+ mDeviceCtxt->PSSetSamplers(0, 1, &mSamplerState);
+ mDeviceCtxt->PSSetShaderResources(0, 1, &mSkyboxSRV);
+
+ mDeviceCtxt->Draw(6*6, 0);
+ }
+
+ mDeviceCtxt->OMSetRenderTargets(1, &mRenderTargetView, 0); // No more depth buffer
+
+ // Draw sprites and fonts
+ {
+ // Fill in vertices (TODO: could move this vector to be a member - not a big deal)
+ std::vector<UINT> controlVertices;
+ controlVertices.reserve(mGUI->size());
+
+ {
+ D3D11_MAPPED_SUBRESOURCE mapped = {};
+ ThrowIfFailed(mDeviceCtxt->Map(mSpriteVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped));
+ auto vertexBase = (SpriteVertex*)mapped.pData;
+ auto vertexEnd = vertexBase;
+
+
+ for (int i = -1; i < (int)mGUI->size(); ++i) {
+ auto control = i >= 0 ? (*mGUI)[i] : mD3D11Sprite;
+ controlVertices.push_back((UINT)(control->Draw(mViewPort.Width, mViewPort.Height, vertexEnd) - vertexEnd));
+ vertexEnd += controlVertices.back();
+ }
+
+ mDeviceCtxt->Unmap(mSpriteVertexBuffer, 0);
+ }
+
+ ID3D11Buffer* ia_buffers[] = { mSpriteVertexBuffer };
+ UINT ia_strides[] = { sizeof(SpriteVertex) };
+ UINT ia_offsets[] = { 0 };
+ mDeviceCtxt->IASetInputLayout(mSpriteInputLayout);
+ mDeviceCtxt->IASetVertexBuffers(0, 1, ia_buffers, ia_strides, ia_offsets);
+ mDeviceCtxt->VSSetShader(mSpriteVertexShader, 0, 0);
+ mDeviceCtxt->OMSetBlendState(mSpriteBlendState, nullptr, 0xFFFFFFFF);
+
+ // Draw
+ UINT vertexStart = 0;
+
+ for (int i = -1; i < (int)mGUI->size(); ++i) {
+ auto control = i >= 0 ? (*mGUI)[i] : mD3D11Sprite;
+ if (control->Visible()) {
+ if (control->TextureFile().length() == 0) { // Font
+ mDeviceCtxt->PSSetShader(mFontPixelShader, 0, 0);
+ mDeviceCtxt->PSSetShaderResources(0, 1, &mFontTextureSRV);
+ } else { // Sprite
+ auto textureSRV = mSpriteTextures[control->TextureFile()];
+ mDeviceCtxt->PSSetShader(mSpritePixelShader, 0, 0);
+ mDeviceCtxt->PSSetShaderResources(0, 1, &textureSRV);
+ }
+ mDeviceCtxt->Draw(controlVertices[1+i], vertexStart);
+ }
+ vertexStart += controlVertices[1+i];
+ }
+ }
+
+ mSwapChain->Present(settings.vsync ? 1 : 0, 0);
+}
+
+void Asteroids::GetPerfCounters(float &UpdateTime, float &RenderTime)
+{
+ UpdateTime = (float)mTotalUpdateTicks/(float)mPerfCounterFreq;
+ RenderTime = (float)mTotalRenderTicks/(float)mPerfCounterFreq;
+}
+
+} // namespace AsteroidsD3D11
diff --git a/Projects/Asteroids/src/asteroids_d3d11.h b/Projects/Asteroids/src/asteroids_d3d11.h
new file mode 100644
index 0000000..da9548e
--- /dev/null
+++ b/Projects/Asteroids/src/asteroids_d3d11.h
@@ -0,0 +1,108 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include <d3d11.h>
+#include <dxgi1_2.h>
+#include <directxmath.h>
+#include <random>
+#include <map>
+
+#include "camera.h"
+#include "settings.h"
+#include "simulation.h"
+#include "util.h"
+#include "gui.h"
+
+namespace AsteroidsD3D11 {
+
+struct DrawConstantBuffer {
+ DirectX::XMFLOAT4X4 mWorld;
+ DirectX::XMFLOAT4X4 mViewProjection;
+ DirectX::XMFLOAT3 mSurfaceColor;
+ float unused0;
+ DirectX::XMFLOAT3 mDeepColor;
+ float unused1;
+};
+
+struct SkyboxConstantBuffer {
+ DirectX::XMFLOAT4X4 mViewProjection;
+};
+
+class Asteroids {
+public:
+ Asteroids(AsteroidsSimulation* asteroids, GUI* gui, bool warp);
+ ~Asteroids();
+
+ void Render(float frameTime, const OrbitCamera& camera, const Settings& settings);
+
+ void ReleaseSwapChain();
+ void ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height);
+
+ void GetPerfCounters(float &UpdateTime, float &RenderTime);
+
+private:
+ void CreateMeshes();
+ void InitializeTextureData();
+ void CreateGUIResources();
+
+ AsteroidsSimulation* mAsteroids = nullptr;
+ GUI* mGUI = nullptr;
+
+ IDXGISwapChain1* mSwapChain = nullptr;
+ ID3D11Device* mDevice = nullptr;
+ ID3D11DeviceContext* mDeviceCtxt = nullptr;
+
+ // These depend on the swap chain buffer size
+ ID3D11Texture2D* mRenderTarget = nullptr;
+ ID3D11RenderTargetView* mRenderTargetView = nullptr;
+ ID3D11DepthStencilView* mDepthStencilView = nullptr;
+ D3D11_VIEWPORT mViewPort;
+ D3D11_RECT mScissorRect;
+
+ ID3D11DepthStencilState* mDepthStencilState = nullptr;
+ ID3D11BlendState* mBlendState = nullptr;
+ ID3D11BlendState* mSpriteBlendState = nullptr;
+
+ ID3D11InputLayout* mInputLayout = nullptr;
+ ID3D11Buffer* mIndexBuffer = nullptr;
+ ID3D11Buffer* mVertexBuffer = nullptr;
+ ID3D11VertexShader* mVertexShader = nullptr;
+ ID3D11PixelShader* mPixelShader = nullptr;
+ ID3D11Buffer* mDrawConstantBuffer = nullptr;
+
+ ID3D11VertexShader* mSpriteVertexShader = nullptr;
+ ID3D11PixelShader* mSpritePixelShader = nullptr;
+ ID3D11InputLayout* mSpriteInputLayout = nullptr;
+ ID3D11Buffer* mSpriteVertexBuffer = nullptr;
+ std::map<std::string, ID3D11ShaderResourceView*> mSpriteTextures;
+
+ ID3D11PixelShader* mFontPixelShader = nullptr;
+ ID3D11ShaderResourceView* mFontTextureSRV = nullptr;
+
+ ID3D11VertexShader* mSkyboxVertexShader = nullptr;
+ ID3D11PixelShader* mSkyboxPixelShader = nullptr;
+ ID3D11Buffer* mSkyboxConstantBuffer = nullptr;
+ ID3D11Buffer* mSkyboxVertexBuffer = nullptr;
+ ID3D11InputLayout* mSkyboxInputLayout = nullptr;
+ ID3D11ShaderResourceView* mSkyboxSRV = nullptr;
+
+ ID3D11Texture2D* mTextures[NUM_UNIQUE_TEXTURES];
+ ID3D11ShaderResourceView* mTextureSRVs[NUM_UNIQUE_TEXTURES];
+ ID3D11SamplerState* mSamplerState = nullptr;
+
+ GUISprite* mD3D11Sprite = nullptr;
+
+ UINT64 mPerfCounterFreq = 0;
+ volatile LONG64 mTotalUpdateTicks = 0, mTotalRenderTicks = 0;
+};
+
+} // namespace AsteroidsD3D11
diff --git a/Projects/Asteroids/src/asteroids_d3d12.cpp b/Projects/Asteroids/src/asteroids_d3d12.cpp
new file mode 100644
index 0000000..1d6fcdd
--- /dev/null
+++ b/Projects/Asteroids/src/asteroids_d3d12.cpp
@@ -0,0 +1,938 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#include <d3dcompiler.h>
+#include <directxmath.h>
+#include <d3dx12.h>
+#include <math.h>
+
+#include <iostream>
+#include <algorithm>
+#include <vector>
+#include <limits>
+#include <random>
+#include <sstream>
+#include <ppl.h>
+
+#include "asteroids_d3d12.h"
+#include "util.h"
+#include "mesh.h"
+#include "noise.h"
+#include "texture.h"
+
+#include "asteroid_vs.h"
+#include "asteroid_ps.h"
+
+#include "skybox_vs.h"
+#include "skybox_ps.h"
+
+#include "sprite_vs.h"
+#include "sprite_ps.h"
+#include "font_ps.h"
+
+using namespace DirectX;
+
+namespace AsteroidsD3D12 {
+
+enum RootParameters
+{
+ RP_DRAW_CBV,
+ RP_TEX_SRV,
+ RP_SMP,
+};
+
+Asteroids::Asteroids(AsteroidsSimulation* asteroids, GUI *gui, UINT minCmdLsts, IDXGIAdapter* adapter)
+ : mAsteroids(asteroids)
+ , mGUI(gui)
+ , mFenceEventHandle(CreateEvent(NULL, FALSE, FALSE, NULL))
+ , mD3D12Sprite( new GUISprite(5, 10, 140, 50, "directx12.dds") )
+{
+ QueryPerformanceFrequency((LARGE_INTEGER*)&mPerfCounterFreq);
+
+ memset(&mViewPort, 0, sizeof(mViewPort));
+ memset(&mScissorRect, 0, sizeof(mScissorRect));
+ memset(mAsteroidTextures, 0, sizeof(mAsteroidTextures));
+ memset(mIndexOffsets, 0xff, sizeof(mIndexOffsets));
+
+#if defined(_DEBUG)
+ // Enable the D3D12 debug layer.
+ {
+ ID3D12Debug* debugController = nullptr;
+ if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
+ {
+ debugController->EnableDebugLayer();
+ debugController->Release();
+ }
+ }
+#endif
+
+ // Create device
+ {
+ ThrowIfFailed(D3D12CreateDevice(
+ adapter,
+ D3D_FEATURE_LEVEL_11_0,
+ IID_PPV_ARGS(&mDevice)));
+
+ D3D12_COMMAND_QUEUE_DESC QDesc;
+ QDesc.NodeMask = 1;
+ QDesc.Priority = 0;
+ QDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+ QDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+ ThrowIfFailed(mDevice->CreateCommandQueue(&QDesc, IID_PPV_ARGS(&mCommandQueue)));
+
+ ThrowIfFailed(mDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence)));
+ }
+
+ // General use descriptor heaps
+ mRTVDescs = new RTVDescriptorList(mDevice, NUM_SWAP_CHAIN_BUFFERS);
+ mDSVDescs = new DSVDescriptorList(mDevice, 1);
+ mSMPDescs = new SMPDescriptorList(mDevice, 1);
+ mSRVDescs = new SRVDescriptorList(mDevice, NUM_UNIQUE_TEXTURES);
+
+ // Filled in in Resize - just take slots for them here
+ mDepthStencilView = mDSVDescs->Append();
+ mRTVFormat = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
+ mDSVFormat = DXGI_FORMAT_D32_FLOAT;
+
+ CreatePSOs();
+ CreateMeshes();
+
+ // Create textures
+ {
+ // TODO: Query simulation for this data? Defines good enough for now...
+ D3D12_RESOURCE_DESC textureDesc =
+ CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, TEXTURE_DIM, TEXTURE_DIM, 3, 0);
+
+ for (UINT i = 0; i < NUM_UNIQUE_TEXTURES; ++i) {
+ ThrowIfFailed(mDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &textureDesc,
+ D3D12_RESOURCE_STATE_COMMON,
+ nullptr, // Clear value
+ IID_PPV_ARGS(&mAsteroidTextures[i])
+ ));
+ textureDesc = mAsteroidTextures[i]->GetDesc();
+
+ InitializeTexture2D(mDevice, mCommandQueue, mAsteroidTextures[i], &textureDesc, 4, mAsteroids->TextureData(i));
+
+ // Append a descriptor to the heap
+ mSRVDescs->AppendSRV(mAsteroidTextures[i]);
+ }
+
+ ThrowIfFailed(CreateTexture2DFromDDS_XXXX8(
+ mDevice, mCommandQueue, &mSkybox, "starbox_1024.dds", DXGI_FORMAT_R8G8B8A8_UNORM_SRGB));
+ }
+
+ CreateGUIResources();
+
+ // Fill in general heaps
+ { // Samplers
+ D3D12_SAMPLER_DESC sampler = {};
+ sampler.Filter = D3D12_FILTER_ANISOTROPIC;
+ sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
+ sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
+ sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
+ sampler.MaxAnisotropy = TEXTURE_ANISO;
+ sampler.MinLOD = -std::numeric_limits<float>::max();
+ sampler.MaxLOD = std::numeric_limits<float>::max();
+ mSampler = mSMPDescs->Append(&sampler);
+ }
+
+ // Swap chain resources
+ for (UINT s = 0; s < NUM_SWAP_CHAIN_BUFFERS; s++) {
+ // Filled in in resize, just make a slot here
+ mSwapChainBuffer[s].mRenderTargetView = mRTVDescs->Append();
+ }
+
+ // Per-frame resources
+ for (UINT f = 0; f < NUM_FRAMES_TO_BUFFER; f++) {
+ auto frame = &mFrame[f];
+ ThrowIfFailed(mDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&frame->mCmdAlloc)));
+
+ frame->mDynamicUpload = new UploadHeapT<DynamicUploadHeap>(mDevice);
+ auto dynamicUploadWO = frame->mDynamicUpload->DataWO();
+ auto dynamicUploadGPUVA = frame->mDynamicUpload->Heap()->GetGPUVirtualAddress();
+
+ frame->mDrawConstantBuffersGPUVA = dynamicUploadGPUVA + offsetof(DynamicUploadHeap, mDrawConstantBuffers);
+
+ // Set any static asteroid data now
+ auto staticData = mAsteroids->StaticData();
+ for (int j = 0; j < NUM_ASTEROIDS; ++j) {
+ auto constants = &dynamicUploadWO->mDrawConstantBuffers[j];
+ constants->mSurfaceColor = staticData[j].surfaceColor;
+ constants->mDeepColor = staticData[j].deepColor;
+ constants->mTextureIndex = staticData[j].textureIndex;
+
+ auto indirectDraw = &dynamicUploadWO->mIndirectArgs[j];
+ indirectDraw->mConstantBuffer = frame->mDrawConstantBuffersGPUVA + sizeof(DrawConstantBuffer) * j;
+ indirectDraw->mDrawIndexed.InstanceCount = 1;
+ indirectDraw->mDrawIndexed.StartInstanceLocation = 0;
+ indirectDraw->mDrawIndexed.BaseVertexLocation = staticData[j].vertexStart;
+ }
+
+ // Dynamic sprite vertices
+ {
+ frame->mSpriteVertexBufferView.BufferLocation = dynamicUploadGPUVA + offsetof(DynamicUploadHeap, mSpriteVertices);
+ frame->mSpriteVertexBufferView.StrideInBytes = sizeof(SpriteVertex);
+ frame->mSpriteVertexBufferView.SizeInBytes = sizeof(SpriteVertex) * MAX_SPRITE_VERTICES_PER_FRAME;
+ }
+
+ // General frame SRV descriptor heap
+ {
+ // We allocate a pile of extra space for dynamic descriptors (GUI, etc)
+ frame->mSRVDescs = new SRVDescriptorList(mDevice, 100);
+
+ // Skybox constants
+ frame->mSkyboxConstants = dynamicUploadGPUVA + offsetof(DynamicUploadHeap, mSkyboxConstants);
+
+ // Skybox texture
+ {
+ auto textureDesc = mSkybox->GetDesc();
+
+ D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
+ srvDesc.Format = textureDesc.Format;
+ srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
+ srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE;
+ srvDesc.TextureCube.MipLevels = 1;
+ srvDesc.TextureCube.MostDetailedMip = 0;
+ srvDesc.TextureCube.ResourceMinLODClamp = 0.0f;
+
+ frame->mSkyboxTexture = frame->mSRVDescs->AppendSRV(mSkybox, &srvDesc);
+ }
+
+ // The rest of the heap we'll use for dynamically copy descriptors into, etc.
+ frame->mSRVDescsDynamicStart = frame->mSRVDescs->Size();
+ }
+ }
+
+ // Command Lists
+ ThrowIfFailed(mDevice->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, mFrame[0].mCmdAlloc, mAsteroidPSO, IID_PPV_ARGS(&mPostCmdLst)));
+ ThrowIfFailed(mPostCmdLst->Close()); // Avoid allocator issues... command lists really should be created in a "closed" state...
+ ThrowIfFailed(mDevice->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, mFrame[0].mCmdAlloc, mAsteroidPSO, IID_PPV_ARGS(&mPreCmdLst)));
+ ThrowIfFailed(mPreCmdLst->Close());
+
+ // Each command list for asteroid drawing maps 1:1 with a descriptor heap
+ // Change heaps is "free" at cmdlst boundaries and this greatly simplifies the code
+ // Thus the expectation is that we have ~ #threads heaps for multithreaded rendering on most GPUs
+ // Need at least one draw in each heap/cmd list...
+ minCmdLsts = std::min(minCmdLsts, (UINT)NUM_ASTEROIDS);
+ CreateSubsets(minCmdLsts);
+ std::cout << "Using " << mSubsetCount << " subsets per frame." << std::endl;
+
+ // Just in case
+ WaitForAll();
+}
+
+Asteroids::~Asteroids()
+{
+ WaitForAll();
+ ReleaseSwapChain();
+
+ SafeRelease(&mPreCmdLst);
+ SafeRelease(&mPostCmdLst);
+
+ for (UINT i = 0; i < NUM_UNIQUE_TEXTURES; ++i) {
+ SafeRelease(&mAsteroidTextures[i]);
+ }
+ for (auto i : mSpriteTextures) {
+ i.second->Release();
+ }
+
+ SafeRelease(&mAsteroidPSO);
+ SafeRelease(&mFontTexture);
+ SafeRelease(&mFontPSO);
+ SafeRelease(&mSpritePSO);
+ SafeRelease(&mSkybox);
+ SafeRelease(&mSkyboxPSO);
+
+ for (UINT f = 0; f < NUM_FRAMES_TO_BUFFER; ++f) {
+ auto frame = &mFrame[f];
+ SafeRelease(&frame->mCmdAlloc);
+ delete frame->mDynamicUpload;
+ delete frame->mSRVDescs;
+ }
+
+ ReleaseSubsets();
+
+ delete mMeshUpload;
+
+ delete mRTVDescs;
+ delete mDSVDescs;
+ delete mSMPDescs;
+ delete mSRVDescs;
+
+ SafeRelease(&mGenericRootSignature);
+ SafeRelease(&mAsteroidsRootSignature);
+ SafeRelease(&mCommandSignature);
+ SafeRelease(&mFence);
+
+ SafeRelease(&mCommandQueue);
+ SafeRelease(&mDevice);
+
+ if (mFenceEventHandle != NULL) {
+ CloseHandle(mFenceEventHandle);
+ mFenceEventHandle = NULL;
+ }
+
+ delete mD3D12Sprite;
+}
+
+
+void Asteroids::ReleaseSwapChain()
+{
+ WaitForAll();
+
+ for (UINT s = 0; s < NUM_SWAP_CHAIN_BUFFERS; s++) {
+ SafeRelease(&mSwapChainBuffer[s].mRenderTarget);
+ }
+ SafeRelease(&mDepthStencil);
+ SafeRelease(&mSwapChain);
+}
+
+inline void DisableDXGIWindowChanges(IUnknown* device, HWND window)
+{
+ IDXGIDevice * pDXGIDevice;
+ ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)));
+ IDXGIAdapter * pDXGIAdapter;
+ ThrowIfFailed(pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)));
+ IDXGIFactory * pIDXGIFactory;
+ ThrowIfFailed(pDXGIAdapter->GetParent(IID_PPV_ARGS(&pIDXGIFactory)));
+
+ ThrowIfFailed(pIDXGIFactory->MakeWindowAssociation(window, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER));
+
+ pIDXGIFactory->Release();
+ pDXGIAdapter->Release();
+ pDXGIDevice->Release();
+}
+
+void Asteroids::ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height)
+{
+ ReleaseSwapChain();
+
+ // Create swap chain
+ {
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
+ swapChainDesc.Width = width;
+ swapChainDesc.Height = height;
+ swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // Can create an SRGB render target view on the swap chain buffer
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.BufferCount = NUM_SWAP_CHAIN_BUFFERS;
+ swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used
+ swapChainDesc.Flags = 0;
+
+ IDXGISwapChain1 *swapChain1 = nullptr;
+ ThrowIfFailed(dxgiFactory->CreateSwapChainForHwnd(
+ mCommandQueue, outputWindow, &swapChainDesc, nullptr, nullptr, &swapChain1));
+ // MakeWindowAssociation must be called after CreateSwapChain
+ ThrowIfFailed(dxgiFactory->MakeWindowAssociation(outputWindow,
+ DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_PRINT_SCREEN));
+ ThrowIfFailed(swapChain1->QueryInterface(&mSwapChain));
+ swapChain1->Release();
+ }
+
+ {
+ // Create an SRGB view of the swap chain buffer
+ D3D12_RENDER_TARGET_VIEW_DESC desc = {};
+ desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
+ desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
+ desc.Texture2D.MipSlice = 0;
+ desc.Texture2D.PlaneSlice = 0;
+
+ // Create render target view for each swap chain buffer
+ for (UINT s = 0; s < NUM_SWAP_CHAIN_BUFFERS; s++) {
+ auto buffer = &mSwapChainBuffer[s];
+ ThrowIfFailed(mSwapChain->GetBuffer(s, IID_PPV_ARGS(&buffer->mRenderTarget)));
+ mDevice->CreateRenderTargetView(buffer->mRenderTarget, &desc, buffer->mRenderTargetView);
+ }
+ }
+
+ // create depth stencil view
+ {
+ D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex2D(
+ DXGI_FORMAT_D32_FLOAT, width, height, 1, 1, 1, 0,
+ D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL );
+
+ // We use (1-z) so typically clear depth to 0
+ D3D12_CLEAR_VALUE clearValue = {};
+ clearValue.Format = desc.Format;
+ clearValue.DepthStencil.Depth = 0.0f;
+ clearValue.DepthStencil.Stencil = 0;
+
+ ThrowIfFailed(mDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &desc,
+ D3D12_RESOURCE_STATE_DEPTH_WRITE,
+ &clearValue,
+ IID_PPV_ARGS(&mDepthStencil)
+ ));
+
+ mDevice->CreateDepthStencilView(mDepthStencil, nullptr, mDepthStencilView);
+ }
+
+ // create the viewport and scissor
+ ZeroMemory(&mViewPort, sizeof(D3D11_VIEWPORT));
+ mViewPort.TopLeftX = 0;
+ mViewPort.TopLeftY = 0;
+ mViewPort.Width = (float)width;
+ mViewPort.Height = (float)height;
+ mViewPort.MinDepth = 0.0f;
+ mViewPort.MaxDepth = 1.0f;
+
+ mScissorRect.left = 0;
+ mScissorRect.top = 0;
+ mScissorRect.right = width;
+ mScissorRect.bottom = height;
+}
+
+void Asteroids::CreatePSOs()
+{
+ // Generic root signature (t0, s0, b0)
+ {
+ CD3DX12_DESCRIPTOR_RANGE descRanges[2];
+ descRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0, 0); // t0
+ descRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); // s0
+
+ CD3DX12_ROOT_PARAMETER rootParams[3];
+ rootParams[RP_DRAW_CBV].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_ALL); // b0
+ rootParams[RP_TEX_SRV].InitAsDescriptorTable(1, &descRanges[0], D3D12_SHADER_VISIBILITY_PIXEL); // t0
+ rootParams[RP_SMP].InitAsDescriptorTable(1, &descRanges[1], D3D12_SHADER_VISIBILITY_PIXEL); // s0
+
+ CD3DX12_ROOT_SIGNATURE_DESC RSLayout(ARRAYSIZE(rootParams), rootParams, 0, 0,
+ D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS);
+
+ ID3DBlob* serializedLayout = nullptr;
+ D3D12SerializeRootSignature(&RSLayout, D3D_ROOT_SIGNATURE_VERSION_1, &serializedLayout, 0);
+
+ ThrowIfFailed(mDevice->CreateRootSignature(
+ 1,
+ serializedLayout->GetBufferPointer(),
+ serializedLayout->GetBufferSize(),
+ IID_PPV_ARGS(&mGenericRootSignature)));
+
+ serializedLayout->Release();
+ }
+
+ // Asteroids root signature (tN, s0, b0)
+ {
+ CD3DX12_DESCRIPTOR_RANGE descRanges[2];
+ descRanges[0].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, NUM_UNIQUE_TEXTURES, 0, 0); // t0...tN
+ descRanges[1].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 1, 0); // s0
+
+ CD3DX12_ROOT_PARAMETER rootParams[3];
+ rootParams[RP_DRAW_CBV].InitAsConstantBufferView(0, 0, D3D12_SHADER_VISIBILITY_ALL); // b0
+ rootParams[RP_TEX_SRV].InitAsDescriptorTable(1, &descRanges[0], D3D12_SHADER_VISIBILITY_PIXEL); // t0
+ rootParams[RP_SMP].InitAsDescriptorTable(1, &descRanges[1], D3D12_SHADER_VISIBILITY_PIXEL); // s0
+
+ CD3DX12_ROOT_SIGNATURE_DESC RSLayout(ARRAYSIZE(rootParams), rootParams, 0, 0,
+ D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |
+ D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS);
+
+ ID3DBlob* serializedLayout = nullptr;
+ D3D12SerializeRootSignature(&RSLayout, D3D_ROOT_SIGNATURE_VERSION_1, &serializedLayout, 0);
+
+ ThrowIfFailed(mDevice->CreateRootSignature(
+ 1,
+ serializedLayout->GetBufferPointer(),
+ serializedLayout->GetBufferSize(),
+ IID_PPV_ARGS(&mAsteroidsRootSignature)));
+
+ serializedLayout->Release();
+ }
+
+ // Command signature
+ {
+ D3D12_INDIRECT_ARGUMENT_DESC args[2] = {};
+ args[0].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW;
+ args[0].ConstantBufferView.RootParameterIndex = RP_DRAW_CBV;
+ args[1].Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED;
+
+ D3D12_COMMAND_SIGNATURE_DESC desc;
+ desc.ByteStride = sizeof(ExecuteIndirectArgs);
+ desc.NodeMask = 1;
+ desc.pArgumentDescs = args;
+ desc.NumArgumentDescs = ARRAYSIZE(args);
+
+ ThrowIfFailed(mDevice->CreateCommandSignature(&desc, mGenericRootSignature, IID_PPV_ARGS(&mCommandSignature)));
+ }
+
+ // Common state for this app
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC defaultDesc = {};
+ defaultDesc.BlendState = CD3DX12_BLEND_DESC(CD3DX12_DEFAULT());
+ defaultDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(CD3DX12_DEFAULT());
+ defaultDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(CD3DX12_DEFAULT());
+ defaultDesc.pRootSignature = mGenericRootSignature;
+ defaultDesc.SampleMask = UINT_MAX;
+ defaultDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
+ defaultDesc.NumRenderTargets = 1;
+ defaultDesc.RTVFormats[0] = mRTVFormat;
+ defaultDesc.DSVFormat = mDSVFormat;
+ defaultDesc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL;
+ defaultDesc.SampleDesc.Count = 1;
+
+ // asteroid pipeline state
+ D3D12_INPUT_ELEMENT_DESC asteroidInputDesc[] = {
+ { "ATTRIB", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "ATTRIB", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ };
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC asteroidDesc = defaultDesc;
+ asteroidDesc.pRootSignature = mAsteroidsRootSignature;
+ asteroidDesc.VS = { g_asteroid_vs, sizeof(g_asteroid_vs) };
+ asteroidDesc.PS = { g_asteroid_ps, sizeof(g_asteroid_ps) };
+ asteroidDesc.InputLayout = { asteroidInputDesc, ARRAYSIZE(asteroidInputDesc) };
+
+ // skybox pipeline state
+ D3D12_INPUT_ELEMENT_DESC skyboxInputDesc[] = {
+ { "ATTRIB", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "ATTRIB", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ };
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC skyboxDesc = defaultDesc;
+ skyboxDesc.VS = { g_skybox_vs, sizeof(g_skybox_vs) };
+ skyboxDesc.PS = { g_skybox_ps, sizeof(g_skybox_ps) };
+ skyboxDesc.InputLayout = { skyboxInputDesc, ARRAYSIZE(skyboxInputDesc) };
+
+ // sprite pipeline state
+ D3D12_INPUT_ELEMENT_DESC spriteInputDesc[] = {
+ { "ATTRIB", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ { "ATTRIB", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+ };
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC spriteDesc = defaultDesc;
+ spriteDesc.VS = { g_sprite_vs, sizeof(g_sprite_vs) };
+ spriteDesc.PS = { g_sprite_ps, sizeof(g_sprite_ps) };
+ spriteDesc.InputLayout = { spriteInputDesc, ARRAYSIZE(spriteInputDesc) };
+ spriteDesc.DepthStencilState.DepthEnable = FALSE;
+ // Premultiplied over blend
+ spriteDesc.BlendState.RenderTarget[0].BlendEnable = TRUE;
+ spriteDesc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_ONE;
+ spriteDesc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
+ spriteDesc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
+
+ // font pipeline state
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC fontDesc = spriteDesc;
+ fontDesc.PS = { g_font_ps, sizeof(g_font_ps) };
+
+ concurrency::parallel_invoke(
+ [&] { ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&asteroidDesc, IID_PPV_ARGS(&mAsteroidPSO))); },
+ [&] { ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&skyboxDesc, IID_PPV_ARGS(&mSkyboxPSO))); },
+ [&] { ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&spriteDesc, IID_PPV_ARGS(&mSpritePSO))); },
+ [&] { ThrowIfFailed(mDevice->CreateGraphicsPipelineState(&fontDesc, IID_PPV_ARGS(&mFontPSO))); }
+ );
+}
+
+
+void Asteroids::CreateSubsets(UINT numHeapsPerFrame)
+{
+ ReleaseSubsets();
+
+ mDrawsPerSubset = (NUM_ASTEROIDS + numHeapsPerFrame - 1) / numHeapsPerFrame;
+ mSubsetCount = numHeapsPerFrame;
+
+ for (UINT f = 0; f < NUM_FRAMES_TO_BUFFER; f++) {
+ // Per-frame data
+ auto frame = &mFrame[f];
+ auto dynamicUploadGPUVA = frame->mDynamicUpload->Heap()->GetGPUVirtualAddress();
+
+ for (UINT subsetIdx = 0; subsetIdx < mSubsetCount; ++subsetIdx) {
+ void* memory = _aligned_malloc(sizeof(SubsetD3D12), 64);
+ auto subset = new(memory) SubsetD3D12(mDevice, NUM_UNIQUE_TEXTURES, mAsteroidPSO);
+ frame->mSubsets.push_back(subset);
+ }
+ }
+}
+
+void Asteroids::ReleaseSubsets()
+{
+ WaitForAll();
+
+ for (UINT i = 0; i < NUM_FRAMES_TO_BUFFER; ++i) {
+ for (auto j : mFrame[i].mSubsets) {
+ j->~SubsetD3D12();
+ _aligned_free(j);
+ }
+ mFrame[i].mSubsets.clear();
+ }
+
+ mSubsetCount = 0;
+ mDrawsPerSubset = 0;
+}
+
+
+void Asteroids::CreateMeshes()
+{
+ auto asteroidMeshes = mAsteroids->Meshes();
+ std::vector<SkyboxVertex> skyboxVertices;
+ CreateSkyboxMesh(&skyboxVertices);
+
+ // Simple linear allocate
+ UINT64 asteroidVBSize = asteroidMeshes->vertices.size() * sizeof(asteroidMeshes->vertices[0]);
+ UINT64 asteroidIBSize = asteroidMeshes->indices.size() * sizeof(asteroidMeshes->indices[0]);
+ UINT64 skyboxVBSize = skyboxVertices.size() * sizeof(SkyboxVertex);
+
+ UINT64 asteroidVBOffset = 0;
+ UINT64 asteroidIBOffset = asteroidVBOffset + asteroidVBSize;
+ UINT64 skyboxVBOffset = asteroidIBOffset + asteroidIBSize;
+ UINT64 totalSize = skyboxVBOffset + skyboxVBSize;
+
+ mMeshUpload = new UploadHeap(mDevice, totalSize);
+ auto bufferWO = (BYTE*)mMeshUpload->DataWO();
+ auto gpuVA = mMeshUpload->Heap()->GetGPUVirtualAddress();
+
+ // Asteroid vertices
+ {
+ memcpy(bufferWO + asteroidVBOffset, asteroidMeshes->vertices.data(), asteroidVBSize);
+
+ mAsteroidVertexBufferView.BufferLocation = gpuVA + asteroidVBOffset;
+ mAsteroidVertexBufferView.SizeInBytes = static_cast<UINT>(asteroidVBSize);
+ mAsteroidVertexBufferView.StrideInBytes = sizeof(asteroidMeshes->vertices[0]);
+ }
+
+ // Asteroid indices
+ {
+ memcpy(bufferWO + asteroidIBOffset, asteroidMeshes->indices.data(), asteroidIBSize);
+
+ mAsteroidIndexBufferView.BufferLocation = gpuVA + asteroidIBOffset;
+ mAsteroidIndexBufferView.SizeInBytes = static_cast<UINT>(asteroidIBSize);
+ mAsteroidIndexBufferView.Format = sizeof(IndexType) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
+ }
+
+ // Skybox vertices
+ {
+ memcpy(bufferWO + skyboxVBOffset, skyboxVertices.data(), skyboxVBSize);
+
+ mSkyboxVertexBufferView.BufferLocation = gpuVA + skyboxVBOffset;
+ mSkyboxVertexBufferView.SizeInBytes = static_cast<UINT>(skyboxVBSize);
+ mSkyboxVertexBufferView.StrideInBytes = sizeof(skyboxVertices[0]);
+ }
+}
+
+
+void Asteroids::CreateGUIResources()
+{
+ auto font = mGUI->Font();
+ auto textureDesc = CD3DX12_RESOURCE_DESC::Tex2D(
+ DXGI_FORMAT_R8_UNORM, font->BitmapWidth(), font->BitmapHeight(), 1, 1);
+
+ ThrowIfFailed(mDevice->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &textureDesc,
+ D3D12_RESOURCE_STATE_COMMON,
+ nullptr,
+ IID_PPV_ARGS(&mFontTexture)
+ ));
+
+ D3D11_SUBRESOURCE_DATA initialData = {};
+ initialData.pSysMem = font->Pixels();
+ initialData.SysMemPitch = font->BitmapWidth();
+
+ InitializeTexture2D(mDevice, mCommandQueue, mFontTexture, &textureDesc, 1, &initialData);
+
+ // Load any GUI sprite textures
+ for (int i = -1; i < (int)mGUI->size(); ++i) {
+ auto control = i>=0 ? (*mGUI)[i] : mD3D12Sprite;
+ if (control->TextureFile().length() > 0 && mSpriteTextures.find(control->TextureFile()) == mSpriteTextures.end()) {
+ ID3D12Resource* texture = nullptr;
+ ThrowIfFailed(CreateTexture2DFromDDS_XXXX8(
+ mDevice, mCommandQueue, &texture, control->TextureFile().c_str(), DXGI_FORMAT_B8G8R8A8_UNORM_SRGB));
+ mSpriteTextures[control->TextureFile()] = texture;
+ }
+ }
+}
+
+void Asteroids::WaitForAll()
+{
+ ThrowIfFailed(mCommandQueue->Signal(mFence, ++mCurrentFence));
+ ThrowIfFailed(mFence->SetEventOnCompletion(mCurrentFence, mFenceEventHandle));
+ WaitForSingleObject(mFenceEventHandle, INFINITE);
+}
+
+void Asteroids::WaitForReadyToRender()
+{
+ // Wait for both the GPU to be done with our per-frame resources
+ HANDLE handles[] = { mFenceEventHandle };
+
+ ThrowIfFailed(mFence->SetEventOnCompletion(mFrame[mCurrentFrameIndex].mFrameCompleteFence, mFenceEventHandle));
+ WaitForMultipleObjects(ARRAYSIZE(handles), handles, TRUE, INFINITE);
+}
+
+void Asteroids::RenderSubset(
+ D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView,
+ size_t frameIndex, float frameTime,
+ SubsetD3D12* subset, UINT subsetIdx,
+ XMVECTOR cameraEye, XMMATRIX viewProjection,
+ const Settings& settings)
+{
+ UINT drawStart = mDrawsPerSubset * subsetIdx;
+ UINT drawEnd = std::min(drawStart + mDrawsPerSubset, (UINT)NUM_ASTEROIDS);
+ assert(drawStart < drawEnd);
+ auto staticAsteroidData = mAsteroids->StaticData();
+ auto dynamicAsteroidData = mAsteroids->DynamicData();
+ // Frame data
+ auto frame = &mFrame[frameIndex];
+ auto drawConstantBuffers = frame->mDynamicUpload->DataWO()->mDrawConstantBuffers;
+ auto indirectArgs = frame->mDynamicUpload->DataWO()->mIndirectArgs;
+
+ auto cmdLst = subset->Begin(mAsteroidPSO);
+
+ // Root signature and common bindings
+ cmdLst->SetGraphicsRootSignature(mAsteroidsRootSignature);
+ ID3D12DescriptorHeap* heaps[2] = {mSRVDescs->Heap(), mSMPDescs->Heap()};
+ cmdLst->SetDescriptorHeaps(ARRAYSIZE(heaps), heaps);
+
+ // Common state
+ cmdLst->IASetIndexBuffer(&mAsteroidIndexBufferView);
+ cmdLst->IASetVertexBuffers(0, 1, &mAsteroidVertexBufferView);
+ cmdLst->RSSetViewports(1, &mViewPort);
+ cmdLst->RSSetScissorRects(1, &mScissorRect);
+ cmdLst->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ cmdLst->OMSetRenderTargets(1, &renderTargetView, true, &mDepthStencilView);
+
+ // Set textures (all as a single descriptor table) and samplers
+ cmdLst->SetGraphicsRootDescriptorTable(RP_TEX_SRV, mSRVDescs->GPU(0));
+ cmdLst->SetGraphicsRootDescriptorTable(RP_SMP, mSampler);
+
+ if (!settings.executeIndirect)
+ {
+ // Standard draw path
+ auto constantsPointer = frame->mDrawConstantBuffersGPUVA + sizeof(DrawConstantBuffer) * drawStart;
+ for (UINT drawIdx = drawStart; drawIdx < drawEnd; ++drawIdx)
+ {
+ auto staticData = &staticAsteroidData[drawIdx];
+ auto dynamicData = &dynamicAsteroidData[drawIdx];
+
+ XMStoreFloat4x4(&drawConstantBuffers[drawIdx].mWorld, dynamicData->world);
+ XMStoreFloat4x4(&drawConstantBuffers[drawIdx].mViewProjection, viewProjection);
+
+ // Set root cbuffer
+ //cmdLst->SetGraphicsRootDescriptorTable(RP_TEX_SRV, mSRVDescs->GPU(0));
+ cmdLst->SetGraphicsRootConstantBufferView(RP_DRAW_CBV, constantsPointer);
+ constantsPointer += sizeof(DrawConstantBuffer);
+
+ cmdLst->DrawIndexedInstanced(dynamicData->indexCount, 1, dynamicData->indexStart, staticData->vertexStart, 0);
+ }
+ }
+ else
+ {
+ // ExecuteIndirect path
+ for (UINT drawIdx = drawStart; drawIdx < drawEnd; ++drawIdx)
+ {
+ auto dynamicData = &dynamicAsteroidData[drawIdx];
+
+ XMStoreFloat4x4(&drawConstantBuffers[drawIdx].mWorld, dynamicData->world);
+ XMStoreFloat4x4(&drawConstantBuffers[drawIdx].mViewProjection, viewProjection);
+
+ auto drawIndexed = &indirectArgs[drawIdx].mDrawIndexed;
+ drawIndexed->IndexCountPerInstance = dynamicData->indexCount;
+ drawIndexed->StartIndexLocation = dynamicData->indexStart;
+ }
+
+ UINT64 offset = (BYTE*)(&indirectArgs[drawStart]) - (BYTE*)frame->mDynamicUpload->DataWO();
+ cmdLst->ExecuteIndirect(mCommandSignature, drawEnd - drawStart,
+ frame->mDynamicUpload->Heap(), offset,
+ nullptr, 0);
+ }
+
+ subset->End();
+}
+
+void Asteroids::Render(float frameTime, const OrbitCamera& camera, const Settings& settings)
+{
+ // Pick the right swap chain buffer based on where DXGI says we are...
+ auto backBufferIndex = mSwapChain->GetCurrentBackBufferIndex();
+ assert(backBufferIndex < NUM_SWAP_CHAIN_BUFFERS);
+ auto swapChainBuffer = &mSwapChainBuffer[backBufferIndex];
+
+ // And the right frame data based on our own rotation/fences
+ assert(mCurrentFrameIndex < NUM_FRAMES_TO_BUFFER);
+ auto frame = &mFrame[mCurrentFrameIndex];
+
+ QueryPerformanceCounter((LARGE_INTEGER*)&mTotalUpdateTicks);
+ // Update asteroid simulation
+ if (settings.multithreadedRendering)
+ {
+ concurrency::parallel_for<UINT>(0, mSubsetCount, [&](UINT subsetIdx) {
+ UINT drawStart = mDrawsPerSubset * subsetIdx;
+ UINT drawEnd = std::min(drawStart + mDrawsPerSubset, (UINT)NUM_ASTEROIDS);
+ mAsteroids->Update(frameTime, camera.Eye(), settings, drawStart, drawEnd - drawStart);
+ });
+ }
+ else
+ {
+ mAsteroids->Update(frameTime, camera.Eye(), settings, 0, (UINT)NUM_ASTEROIDS);
+ }
+ LONG64 currCounter;
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ mTotalUpdateTicks = currCounter - mTotalUpdateTicks;
+
+ mTotalRenderTicks = currCounter;
+ // Generate command lists
+ if (settings.multithreadedRendering)
+ {
+ concurrency::parallel_for<UINT>(0, mSubsetCount, [&](UINT subsetIdx) {
+ RenderSubset(swapChainBuffer->mRenderTargetView, mCurrentFrameIndex, frameTime,
+ frame->mSubsets[subsetIdx], subsetIdx, camera.Eye(), camera.ViewProjection(), settings);
+ });
+ }
+ else
+ {
+ LONG64 SubsetUpdateTicks = 0, SubsetRenderTicks = 0;
+ for (unsigned int subsetIdx = 0; subsetIdx < mSubsetCount; ++subsetIdx) {
+ RenderSubset(swapChainBuffer->mRenderTargetView, mCurrentFrameIndex, frameTime,
+ frame->mSubsets[subsetIdx], subsetIdx, camera.Eye(), camera.ViewProjection(), settings);
+ }
+ }
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ mTotalRenderTicks = currCounter - mTotalRenderTicks;
+
+ LONG64 prevCounter = currCounter;
+ // Set up pre and post commands
+ {
+ auto cmdAlloc = frame->mCmdAlloc;
+ auto dynamicUploadWO = frame->mDynamicUpload->DataWO();
+ ThrowIfFailed(cmdAlloc->Reset());
+
+ // Set resource states for rendering
+ ResourceBarrier rb;
+ rb.AddTransition(swapChainBuffer->mRenderTarget, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET);
+
+ // Pre
+ {
+ ThrowIfFailed(mPreCmdLst->Reset(cmdAlloc, mAsteroidPSO));
+ rb.Submit(mPreCmdLst);
+
+ // Don't need to clear color at the moment - skybox overwrites it all and no MSAA
+ //float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
+ //mPreCmdLst->ClearRenderTargetView(swapChainBuffer->mRenderTargetView, clearcol, 0, 0);
+
+ // Clear depth
+ mPreCmdLst->ClearDepthStencilView(mDepthStencilView, D3D12_CLEAR_FLAG_DEPTH, 0.0f, 0, 0, nullptr);
+
+ ThrowIfFailed(mPreCmdLst->Close());
+ }
+
+ rb.ReverseTransitions();
+
+ // Post
+ {
+ ThrowIfFailed(mPostCmdLst->Reset(cmdAlloc, mSkyboxPSO));
+
+ // Root signature and descriptor heaps
+ mPostCmdLst->SetGraphicsRootSignature(mGenericRootSignature);
+ ID3D12DescriptorHeap* heaps[2] = { frame->mSRVDescs->Heap(), mSMPDescs->Heap() };
+ mPostCmdLst->SetDescriptorHeaps(2, heaps);
+
+ mPostCmdLst->SetGraphicsRootDescriptorTable(RP_SMP, mSampler);
+
+ // Common state
+ mPostCmdLst->RSSetViewports(1, &mViewPort);
+ mPostCmdLst->RSSetScissorRects(1, &mScissorRect);
+ mPostCmdLst->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ mPostCmdLst->OMSetRenderTargets(1, &swapChainBuffer->mRenderTargetView, true, &mDepthStencilView);
+
+ // Draw skybox
+ {
+ auto constants = &frame->mDynamicUpload->DataWO()->mSkyboxConstants;
+ XMStoreFloat4x4(&constants->mViewProjection, camera.ViewProjection());
+
+ mPostCmdLst->IASetVertexBuffers(0, 1, &mSkyboxVertexBufferView);
+
+ mPostCmdLst->SetGraphicsRootConstantBufferView(RP_DRAW_CBV, frame->mSkyboxConstants);
+ mPostCmdLst->SetGraphicsRootDescriptorTable(RP_TEX_SRV, frame->mSkyboxTexture);
+ mPostCmdLst->DrawInstanced(6 * 6, 1, 0, 0);
+ }
+
+ // Draw sprites
+ {
+ auto vertexBase = dynamicUploadWO->mSpriteVertices;
+ auto vertexEnd = vertexBase;
+
+ // Drop off any dynamic descriptors from the last frame
+ auto descHeap = frame->mSRVDescs;
+ descHeap->Resize(frame->mSRVDescsDynamicStart);
+
+ mPostCmdLst->IASetVertexBuffers(0, 1, &frame->mSpriteVertexBufferView);
+
+ for (int i = -1; i < (int)mGUI->size(); ++i) {
+ auto control = i >=0 ? (*mGUI)[i] : mD3D12Sprite;
+ if (!control->Visible()) continue;
+
+ UINT numVertices = (UINT)(control->Draw(mViewPort.Width, mViewPort.Height, vertexEnd) - vertexEnd);
+ ID3D12Resource* texture = nullptr;
+
+ // TODO: Could eliminate redundant state setting and cache descriptors... meh for now.
+ if (control->TextureFile().length() == 0) { // Font
+ mPostCmdLst->SetPipelineState(mFontPSO);
+ texture = mFontTexture;
+ }
+ else { // Sprite
+ mPostCmdLst->SetPipelineState(mSpritePSO);
+ texture = mSpriteTextures[control->TextureFile()];
+ }
+
+ if (texture) {
+ mPostCmdLst->SetGraphicsRootDescriptorTable(RP_TEX_SRV, descHeap->AppendSRV(texture));
+ }
+
+ mPostCmdLst->DrawInstanced(numVertices, 1, (UINT)(vertexEnd - vertexBase), 0);
+ vertexEnd += numVertices;
+ }
+ }
+
+ // Final resource state transitions
+ rb.Submit(mPostCmdLst);
+ ThrowIfFailed(mPostCmdLst->Close());
+ }
+ }
+
+ // Set up command lists for submission
+ mCmdListsToSubmit.resize(0);
+ mCmdListsToSubmit.push_back(mPreCmdLst);
+ if (settings.submitRendering) {
+ for (auto &i :frame->mSubsets)
+ mCmdListsToSubmit.push_back(i->mCmdLst);
+ }
+ mCmdListsToSubmit.push_back(mPostCmdLst);
+
+ mCommandQueue->ExecuteCommandLists(
+ (UINT)mCmdListsToSubmit.size(),
+ CommandListCast(mCmdListsToSubmit.data()));
+
+ if (settings.vsync)
+ ThrowIfFailed(mSwapChain->Present(1, 0));
+ else
+ ThrowIfFailed(mSwapChain->Present(0, 0));
+
+ ThrowIfFailed(mCommandQueue->Signal(mFence, ++mCurrentFence));
+ frame->mFrameCompleteFence = mCurrentFence;
+ mCurrentFrameIndex = (mCurrentFrameIndex + 1) % NUM_FRAMES_TO_BUFFER;
+
+ //LONG64 currCounter;
+ QueryPerformanceCounter((LARGE_INTEGER*)&currCounter);
+ mTotalRenderTicks += currCounter - prevCounter;
+}
+
+void Asteroids::GetPerfCounters(float &UpdateTime, float &RenderTime)
+{
+ UpdateTime = (float)mTotalUpdateTicks/(float)mPerfCounterFreq;
+ RenderTime = (float)mTotalRenderTicks/(float)mPerfCounterFreq;
+}
+
+} // namespace AsteroidsD3D12
diff --git a/Projects/Asteroids/src/asteroids_d3d12.h b/Projects/Asteroids/src/asteroids_d3d12.h
new file mode 100644
index 0000000..3021d28
--- /dev/null
+++ b/Projects/Asteroids/src/asteroids_d3d12.h
@@ -0,0 +1,182 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include <d3d11.h>
+#include <d3d12.h>
+#include <dxgi1_4.h>
+#include <directxmath.h>
+#include <deque>
+#include <random>
+#include <map>
+
+#include "camera.h"
+#include "settings.h"
+#include "simulation.h"
+#include "subset_d3d12.h"
+#include "descriptor.h"
+#include "upload_heap.h"
+#include "util.h"
+#include "gui.h"
+
+namespace AsteroidsD3D12 {
+
+CBUFFER_ALIGN struct DrawConstantBuffer {
+ DirectX::XMFLOAT4X4 mWorld;
+ DirectX::XMFLOAT4X4 mViewProjection;
+ DirectX::XMFLOAT3 mSurfaceColor;
+ float unused0;
+ DirectX::XMFLOAT3 mDeepColor;
+ float unused1;
+ UINT mTextureIndex;
+};
+
+CBUFFER_ALIGN struct SkyboxConstantBuffer {
+ DirectX::XMFLOAT4X4 mViewProjection;
+};
+
+struct ExecuteIndirectArgs {
+ D3D12_GPU_VIRTUAL_ADDRESS mConstantBuffer;
+ D3D12_DRAW_INDEXED_ARGUMENTS mDrawIndexed;
+};
+
+struct DynamicUploadHeap {
+ DrawConstantBuffer mDrawConstantBuffers[NUM_ASTEROIDS];
+ SkyboxConstantBuffer mSkyboxConstants;
+ ExecuteIndirectArgs mIndirectArgs[NUM_ASTEROIDS];
+ SpriteVertex mSpriteVertices[MAX_SPRITE_VERTICES_PER_FRAME];
+};
+
+class Asteroids {
+public:
+ Asteroids(AsteroidsSimulation* asteroids, GUI *gui, UINT minCmdLsts, IDXGIAdapter* adapter);
+ ~Asteroids();
+
+ void WaitForReadyToRender();
+ void Render(float frameTime, const OrbitCamera& camera, const Settings& settings);
+
+ void ReleaseSwapChain();
+ void ResizeSwapChain(IDXGIFactory2* dxgiFactory, HWND outputWindow, unsigned int width, unsigned int height);
+
+ void GetPerfCounters(float &UpdateTime, float &RenderTime);
+
+private:
+ void WaitForAll();
+
+ void RenderSubset(
+ D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView,
+ size_t frameIndex, float frameTime,
+ SubsetD3D12* subset, UINT subsetIdx,
+ DirectX::XMVECTOR cameraEye, DirectX::XMMATRIX viewProjection,
+ const Settings& settings);
+
+ void CreatePSOs();
+
+ void CreateSubsets(UINT numHeapsPerFrame);
+ void ReleaseSubsets();
+
+ void CreateMeshes();
+ void CreateGUIResources();
+
+ struct Frame {
+ std::vector<SubsetD3D12*> mSubsets;
+ ID3D12CommandAllocator* mCmdAlloc = nullptr;
+
+ UploadHeapT<DynamicUploadHeap>* mDynamicUpload = nullptr;
+ D3D12_VERTEX_BUFFER_VIEW mSpriteVertexBufferView;
+ D3D12_GPU_VIRTUAL_ADDRESS mDrawConstantBuffersGPUVA;
+
+ // Descriptor heap and associated GPU handles
+ SRVDescriptorList* mSRVDescs = nullptr;
+ D3D12_GPU_VIRTUAL_ADDRESS mSkyboxConstants;
+ D3D12_GPU_DESCRIPTOR_HANDLE mSkyboxTexture;
+ UINT mSRVDescsDynamicStart = 0;
+
+ UINT64 mFrameCompleteFence = 0;
+ } mFrame[NUM_FRAMES_TO_BUFFER];
+
+ // Swap chain resources
+ struct SwapChainBuffer {
+ ID3D12Resource* mRenderTarget = nullptr;
+ D3D12_CPU_DESCRIPTOR_HANDLE mRenderTargetView;
+ } mSwapChainBuffer[NUM_SWAP_CHAIN_BUFFERS];
+
+ // Swap chain stuff
+ IDXGISwapChain3* mSwapChain = nullptr;
+ DXGI_FORMAT mRTVFormat;
+ D3D12_VIEWPORT mViewPort;
+ D3D11_RECT mScissorRect;
+
+ // Fences and synchronization
+ size_t mCurrentFrameIndex = 0;
+ ID3D12Fence* mFence = nullptr;
+ HANDLE mFenceEventHandle = NULL;
+ UINT64 mCurrentFence = 0;
+
+ // Device
+ ID3D12Device* mDevice = nullptr;
+ ID3D12CommandQueue* mCommandQueue = nullptr;
+
+ // Root signature, descriptors and binding
+ ID3D12RootSignature* mGenericRootSignature = nullptr;
+ ID3D12RootSignature* mAsteroidsRootSignature = nullptr;
+ ID3D12CommandSignature* mCommandSignature = nullptr;
+ RTVDescriptorList* mRTVDescs = nullptr;
+ DSVDescriptorList* mDSVDescs = nullptr;
+ SRVDescriptorList* mSRVDescs = nullptr;
+ SMPDescriptorList* mSMPDescs = nullptr;
+ D3D12_CPU_DESCRIPTOR_HANDLE mDepthStencilView;
+ D3D12_GPU_DESCRIPTOR_HANDLE mSampler;
+ D3D12_VERTEX_BUFFER_VIEW mSkyboxVertexBufferView;
+ D3D12_INDEX_BUFFER_VIEW mAsteroidIndexBufferView;
+ D3D12_VERTEX_BUFFER_VIEW mAsteroidVertexBufferView;
+
+ // Command lists
+ ID3D12GraphicsCommandList* mPreCmdLst = nullptr;
+ ID3D12GraphicsCommandList* mPostCmdLst = nullptr;
+
+ DXGI_FORMAT mDSVFormat;
+ ID3D12Resource* mDepthStencil = nullptr;
+
+ AsteroidsSimulation* mAsteroids = nullptr;
+ ID3D12Resource* mAsteroidTextures[NUM_UNIQUE_TEXTURES];
+
+ // Mesh
+ UploadHeap* mMeshUpload = nullptr;
+ UINT mIndexOffsets[MESH_MAX_SUBDIV_LEVELS + 2]; // inclusive
+ UINT mNumVerticesPerMesh = 0;
+
+ ID3D12PipelineState* mAsteroidPSO = nullptr;
+
+ ID3D12PipelineState* mSkyboxPSO = nullptr;
+ ID3D12Resource* mSkybox = nullptr;
+
+ ID3D12PipelineState* mFontPSO = nullptr;
+ ID3D12Resource* mFontTexture = nullptr;
+
+ ID3D12PipelineState* mSpritePSO = nullptr;
+ std::map<std::string, ID3D12Resource*> mSpriteTextures;
+
+ GUI* mGUI = nullptr;
+
+ // Transient, just here to avoid allocations each frame
+ std::vector<ID3D12GraphicsCommandList*> mCmdListsToSubmit;
+
+ UINT mSubsetCount = 0;
+ UINT mDrawsPerSubset = 0;
+
+ GUISprite* mD3D12Sprite = nullptr;
+
+ UINT64 mPerfCounterFreq = 0;
+ volatile LONG64 mTotalUpdateTicks = 0, mTotalRenderTicks = 0;
+};
+
+} // namespace AsteroidsD3D12
diff --git a/Projects/Asteroids/src/asteroids_d3d12.ico b/Projects/Asteroids/src/asteroids_d3d12.ico
new file mode 100644
index 0000000..449296f
--- /dev/null
+++ b/Projects/Asteroids/src/asteroids_d3d12.ico
Binary files differ
diff --git a/Projects/Asteroids/src/camera.cpp b/Projects/Asteroids/src/camera.cpp
new file mode 100644
index 0000000..ac5ceec
--- /dev/null
+++ b/Projects/Asteroids/src/camera.cpp
@@ -0,0 +1,170 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#include "camera.h"
+#include "util.h"
+#include <algorithm>
+
+using namespace DirectX;
+
+
+OrbitCamera::OrbitCamera()
+{
+ // Defaults
+ mCenter = XMVectorSet(0, 0, 0, 0);
+ mUp = XMVectorSet(0, 1, 0, 0);
+ mRadius = 1.0f;
+ mMinRadius = 1.0f;
+ mMaxRadius = 1.0f;
+ mLongAngle = 0.0f;
+ mLatAngle = 0.0f;
+
+ // Set up interaction context (i.e. touch input processing, etc)
+ ThrowIfFailed(CreateInteractionContext(&mInteractionContext));
+ ThrowIfFailed(SetPropertyInteractionContext(mInteractionContext, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, TRUE));
+
+ {
+ INTERACTION_CONTEXT_CONFIGURATION config[] =
+ {
+ {INTERACTION_ID_MANIPULATION,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_X |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_Y |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_SCALING |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_INERTIA |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_SCALING_INERTIA |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_MULTIPLE_FINGER_PANNING
+ },
+ };
+
+ ThrowIfFailed(SetInteractionConfigurationInteractionContext(mInteractionContext, ARRAYSIZE(config), config));
+ }
+
+ ThrowIfFailed(RegisterOutputCallbackInteractionContext(mInteractionContext, OrbitCamera::StaticInteractionOutputCallback, this));
+}
+
+
+OrbitCamera::~OrbitCamera()
+{
+ DestroyInteractionContext(mInteractionContext);
+}
+
+
+void OrbitCamera::View(
+ DirectX::XMVECTOR center, float radius, float minRadius, float maxRadius,
+ float longAngle, float latAngle)
+{
+ mCenter = center;
+ mRadius = radius;
+ mMinRadius = minRadius;
+ mMaxRadius = maxRadius;
+ mLongAngle = longAngle;
+ mLatAngle = latAngle;
+ UpdateData();
+}
+
+
+void OrbitCamera::Projection(float fov, float aspect)
+{
+ float fovY = (aspect <= 1.0 ? fov : fov / aspect);
+ mProjection = XMMatrixPerspectiveFovRH(fovY, aspect, 10000.0f, 0.1f);
+ UpdateData();
+}
+
+
+void OrbitCamera::UpdateData()
+{
+ mEye = XMVectorSet(
+ mRadius * std::sin(mLatAngle) * std::cos(mLongAngle),
+ mRadius * std::cos(mLatAngle),
+ mRadius * std::sin(mLatAngle) * std::sin(mLongAngle),
+ 0.0f);
+
+ mView = XMMatrixLookAtRH(mEye, mCenter, mUp);
+ mViewProjection = XMMatrixMultiply(mView, mProjection);
+}
+
+
+void OrbitCamera::OrbitX(float angle)
+{
+ mLongAngle += angle;
+ UpdateData();
+}
+
+
+void OrbitCamera::OrbitY(float angle)
+{
+ float limit = XM_PI * 0.01f;
+ mLatAngle = std::max(limit, std::min(XM_PI-limit, mLatAngle + angle));
+ UpdateData();
+}
+
+
+void OrbitCamera::ZoomRadius(float delta)
+{
+ mRadius = std::max(mMinRadius, std::min(mMaxRadius, mRadius + delta));
+ UpdateData();
+}
+
+void OrbitCamera::ZoomRadiusScale(float delta)
+{
+ mRadius = std::max(mMinRadius, std::min(mMaxRadius, mRadius * delta));
+ UpdateData();
+}
+
+
+void OrbitCamera::AddPointer(UINT pointerId)
+{
+ AddPointerInteractionContext(mInteractionContext, pointerId);
+}
+
+
+void OrbitCamera::ProcessPointerFrames(UINT pointerId, const POINTER_INFO* pointerInfo)
+{
+ ProcessPointerFramesInteractionContext(mInteractionContext, 1, 1, pointerInfo);
+}
+
+
+void OrbitCamera::RemovePointer(UINT pointerId)
+{
+ RemovePointerInteractionContext(mInteractionContext, pointerId);
+}
+
+
+void OrbitCamera::ProcessInertia()
+{
+ ProcessInertiaInteractionContext(mInteractionContext);
+}
+
+
+VOID CALLBACK OrbitCamera::StaticInteractionOutputCallback(VOID *clientData, const INTERACTION_CONTEXT_OUTPUT *output)
+{
+ auto camera = reinterpret_cast<OrbitCamera*>(clientData);
+ camera->InteractionOutputCallback(output);
+}
+
+
+void OrbitCamera::InteractionOutputCallback(const INTERACTION_CONTEXT_OUTPUT *output)
+{
+ switch(output->interactionId)
+ {
+ case INTERACTION_ID_MANIPULATION: {
+ auto delta = &output->arguments.manipulation.delta;
+ OrbitX(delta->translationX * 0.0007f);
+ OrbitY(-delta->translationY * 0.0007f);
+ ZoomRadiusScale(1.0f / delta->scale);
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
diff --git a/Projects/Asteroids/src/camera.h b/Projects/Asteroids/src/camera.h
new file mode 100644
index 0000000..69ffc3f
--- /dev/null
+++ b/Projects/Asteroids/src/camera.h
@@ -0,0 +1,62 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include <DirectXMath.h>
+#include <interactioncontext.h>
+
+class OrbitCamera
+{
+public:
+ OrbitCamera();
+ ~OrbitCamera();
+
+ void View(DirectX::XMVECTOR center,
+ float radius, float minRadius, float maxRadius,
+ float longAngle, float latAngle);
+
+ // Uses the provided fov for the larger dimension
+ void Projection(float fov, float aspect);
+
+ DirectX::XMVECTOR const& Eye() const { return mEye; }
+ DirectX::XMMATRIX const& ViewProjection() const { return mViewProjection; }
+
+ void AddPointer(UINT pointerId);
+ void ProcessPointerFrames(UINT pointerId, const POINTER_INFO* pointerInfo);
+ void ProcessInertia();
+ void RemovePointer(UINT pointerId);
+
+ void OrbitX(float angle);
+ void OrbitY(float angle);
+ void ZoomRadius(float delta);
+ void ZoomRadiusScale(float delta);
+
+private:
+ void UpdateData();
+ static VOID CALLBACK StaticInteractionOutputCallback(VOID *clientData, const INTERACTION_CONTEXT_OUTPUT *output);
+ void InteractionOutputCallback(const INTERACTION_CONTEXT_OUTPUT *output);
+
+ DirectX::XMVECTOR mCenter;
+ DirectX::XMVECTOR mUp;
+ float mMinRadius;
+ float mMaxRadius;
+
+ float mLatAngle;
+ float mLongAngle;
+ float mRadius;
+
+ DirectX::XMVECTOR mEye;
+ DirectX::XMMATRIX mView;
+ DirectX::XMMATRIX mProjection;
+ DirectX::XMMATRIX mViewProjection;
+
+ HINTERACTIONCONTEXT mInteractionContext;
+};
diff --git a/Projects/Asteroids/src/common.hlsl b/Projects/Asteroids/src/common.hlsl
new file mode 100644
index 0000000..3609db6
--- /dev/null
+++ b/Projects/Asteroids/src/common.hlsl
@@ -0,0 +1,45 @@
+#ifndef COMMON_HLSL
+#define COMMON_HLSL
+
+struct VSIn
+{
+ float3 position : POSITION;
+ float3 normal : NORMAL;
+};
+
+struct VSOut
+{
+ float4 position : SV_Position;
+ float3 positionModel : POSITIONMODEL;
+ float3 normalWorld : NORMAL;
+ float3 albedo : ALBEDO; // Alternatively, can pass just "ao" to PS and read cbuffer in PS
+};
+
+
+struct Skybox_VSIn
+{
+ float3 position : POSITION;
+ float3 uvFace : UVFACE;
+};
+
+struct Skybox_VSOut
+{
+ float4 position : SV_Position;
+ float3 coords : UVFACE;
+};
+
+
+struct Font_VSIn
+{
+ float2 position : POSITION;
+ float2 uv : UV;
+};
+
+struct Font_VSOut
+{
+ float4 position : SV_Position;
+ float2 uv : UV;
+};
+
+
+#endif
diff --git a/Projects/Asteroids/src/common_defines.h b/Projects/Asteroids/src/common_defines.h
new file mode 100644
index 0000000..4af7169
--- /dev/null
+++ b/Projects/Asteroids/src/common_defines.h
@@ -0,0 +1,6 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#define NUM_UNIQUE_TEXTURES 10
+
+#endif
diff --git a/Projects/Asteroids/src/dds.h b/Projects/Asteroids/src/dds.h
new file mode 100644
index 0000000..65fe730
--- /dev/null
+++ b/Projects/Asteroids/src/dds.h
@@ -0,0 +1,145 @@
+//--------------------------------------------------------------------------------------
+// dds.h
+//
+// This header defines constants and structures that are useful when parsing
+// DDS files. DDS files were originally designed to use several structures
+// and constants that are native to DirectDraw and are defined in ddraw.h,
+// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar
+// (compatible) constants and structures so that one can use DDS files
+// without needing to include ddraw.h.
+//--------------------------------------------------------------------------------------
+
+#ifndef _DDS_H_
+#define _DDS_H_
+
+#include <dxgiformat.h>
+#include <d3d11.h>
+
+#pragma pack(push,1)
+
+#define DDS_MAGIC 0x20534444 // "DDS "
+
+struct DDS_PIXELFORMAT
+{
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwFourCC;
+ DWORD dwRGBBitCount;
+ DWORD dwRBitMask;
+ DWORD dwGBitMask;
+ DWORD dwBBitMask;
+ DWORD dwABitMask;
+};
+
+#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_ALPHA 0x00000002 // DDPF_ALPHA
+
+const DDS_PIXELFORMAT DDSPF_DXT1 =
+ { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','1'), 0, 0, 0, 0, 0 };
+
+const DDS_PIXELFORMAT DDSPF_DXT2 =
+ { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','2'), 0, 0, 0, 0, 0 };
+
+const DDS_PIXELFORMAT DDSPF_DXT3 =
+ { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','3'), 0, 0, 0, 0, 0 };
+
+const DDS_PIXELFORMAT DDSPF_DXT4 =
+ { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','4'), 0, 0, 0, 0, 0 };
+
+const DDS_PIXELFORMAT DDSPF_DXT5 =
+ { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','T','5'), 0, 0, 0, 0, 0 };
+
+const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
+ { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
+
+const DDS_PIXELFORMAT DDSPF_A1R5G5B5 =
+ { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 };
+
+const DDS_PIXELFORMAT DDSPF_A4R4G4B4 =
+ { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 };
+
+const DDS_PIXELFORMAT DDSPF_R8G8B8 =
+ { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
+
+const DDS_PIXELFORMAT DDSPF_R5G6B5 =
+ { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 };
+
+// This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
+const DDS_PIXELFORMAT DDSPF_DX10 =
+ { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('D','X','1','0'), 0, 0, 0, 0, 0 };
+
+#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
+
+// Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION
+typedef enum DDS_RESOURCE_DIMENSION
+{
+ DDS_DIMENSION_TEXTURE1D = 2,
+ DDS_DIMENSION_TEXTURE2D = 3,
+ DDS_DIMENSION_TEXTURE3D = 4,
+} DDS_RESOURCE_DIMENSION;
+
+// Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
+typedef enum DDS_RESOURCE_MISC_FLAG
+{
+ DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L,
+} DDS_RESOURCE_MISC_FLAG;
+
+typedef struct
+{
+ DWORD dwSize;
+ DWORD dwFlags;
+ DWORD dwHeight;
+ DWORD dwWidth;
+ DWORD dwPitchOrLinearSize;
+ DWORD dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags
+ DWORD dwMipMapCount;
+ DWORD dwReserved1[11];
+ DDS_PIXELFORMAT ddspf;
+ DWORD dwCaps;
+ DWORD dwCaps2;
+ DWORD dwCaps3;
+ DWORD dwCaps4;
+ DWORD dwReserved2;
+} DDS_HEADER;
+
+typedef struct
+{
+ DXGI_FORMAT dxgiFormat;
+ UINT resourceDimension;
+ DWORD miscFlag; // see DDS_RESOURCE_MISC_FLAG
+ UINT arraySize;
+ UINT reserved;
+} DDS_HEADER_DXT10;
+
+#pragma pack(pop)
+
+#endif // _DDS_H
diff --git a/Projects/Asteroids/src/descriptor.h b/Projects/Asteroids/src/descriptor.h
new file mode 100644
index 0000000..4c87286
--- /dev/null
+++ b/Projects/Asteroids/src/descriptor.h
@@ -0,0 +1,165 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include "util.h"
+
+#include <assert.h>
+#include <d3d12.h>
+#include <d3dx12.h>
+
+// Used for CPU-only desriptors; simple linear allocator.
+class DescriptorArray
+{
+public:
+ // device must live for the lifetime of this object (no explicit refcount increment)
+ DescriptorArray(ID3D12Device* device, UINT maxDescriptors, D3D12_DESCRIPTOR_HEAP_TYPE type,
+ bool shaderVisible = false)
+ : mDevice(device)
+ , mMaxSize(maxDescriptors)
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC desc = {};
+ desc.Type = type;
+ desc.Flags = shaderVisible ? D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE : D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ desc.NumDescriptors = mMaxSize;
+
+ ThrowIfFailed(mDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&mHeap)));
+
+ mCPUBegin = mHeap->GetCPUDescriptorHandleForHeapStart();
+ mHandleIncrementSize = mDevice->GetDescriptorHandleIncrementSize(desc.Type);
+
+ if (shaderVisible) {
+ mGPUBegin = mHeap->GetGPUDescriptorHandleForHeapStart();
+ }
+ }
+
+ ~DescriptorArray()
+ {
+ SafeRelease(&mHeap);
+ }
+
+ // Direct access to handles
+ CD3DX12_CPU_DESCRIPTOR_HANDLE CPU(UINT index = 0) const
+ {
+ return CD3DX12_CPU_DESCRIPTOR_HANDLE(mCPUBegin, index, mHandleIncrementSize);
+ }
+ CD3DX12_GPU_DESCRIPTOR_HANDLE GPU(UINT index = 0) const
+ {
+ return CD3DX12_GPU_DESCRIPTOR_HANDLE(mGPUBegin, index, mHandleIncrementSize);
+ }
+ CD3DX12_GPU_DESCRIPTOR_HANDLE GPUEnd() const { return GPU(mCurrentSize); }
+ INT HandleIncrementSize() const { return mHandleIncrementSize; }
+
+ // NOTE: Caller can fill in data at new handle and/or derived classes provide
+ // specialized methods to do it in one step.
+ CD3DX12_CPU_DESCRIPTOR_HANDLE Append()
+ {
+ assert(mCurrentSize < mMaxSize);
+ return CPU(mCurrentSize++);
+ }
+
+ // Invalidates contents of any previous handles
+ void Clear() { mCurrentSize = 0; }
+ void Resize(UINT newSize) { mCurrentSize = newSize; }
+ UINT Size() const { return mCurrentSize; }
+
+protected:
+ ID3D12Device* mDevice = nullptr;
+ ID3D12DescriptorHeap* mHeap = nullptr;
+ CD3DX12_CPU_DESCRIPTOR_HANDLE mCPUBegin;
+ CD3DX12_GPU_DESCRIPTOR_HANDLE mGPUBegin;
+ UINT mHandleIncrementSize = 0;
+ UINT mCurrentSize = 0;
+ UINT mMaxSize = 0;
+};
+
+
+// Render target views
+class RTVDescriptorList : public DescriptorArray
+{
+public:
+ RTVDescriptorList(ID3D12Device* device, UINT maxDescriptors)
+ : DescriptorArray( device, maxDescriptors, D3D12_DESCRIPTOR_HEAP_TYPE_RTV )
+ {}
+
+ using DescriptorArray::Append;
+
+ D3D12_CPU_DESCRIPTOR_HANDLE Append(ID3D12Resource* resource, D3D12_RENDER_TARGET_VIEW_DESC* desc = nullptr)
+ {
+ auto handle = Append();
+ mDevice->CreateRenderTargetView(resource, desc, handle);
+ return handle;
+ }
+};
+
+// Depth stencil views
+class DSVDescriptorList : public DescriptorArray
+{
+public:
+ DSVDescriptorList(ID3D12Device* device, UINT descriptorCount)
+ : DescriptorArray( device, descriptorCount, D3D12_DESCRIPTOR_HEAP_TYPE_DSV )
+ {}
+
+ using DescriptorArray::Append;
+
+ D3D12_CPU_DESCRIPTOR_HANDLE Append(ID3D12Resource* resource, D3D12_DEPTH_STENCIL_VIEW_DESC* desc = nullptr)
+ {
+ auto handle = Append();
+ mDevice->CreateDepthStencilView(resource, desc, handle);
+ return handle;
+ }
+};
+
+// SRVs, CBVs, UAVs, etc.
+class SRVDescriptorList : public DescriptorArray
+{
+public:
+ SRVDescriptorList(ID3D12Device* device, UINT descriptorCount)
+ : DescriptorArray( device, descriptorCount, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, true )
+ {}
+
+ ID3D12DescriptorHeap* Heap() { return mHeap; }
+
+ // In this class it's more useful to have the GPU handle returned
+ // In the long run it's useful to have both (for copying, etc) but this suits our purposes for now
+
+ D3D12_GPU_DESCRIPTOR_HANDLE AppendSRV(ID3D12Resource* resource, D3D12_SHADER_RESOURCE_VIEW_DESC* desc = nullptr)
+ {
+ auto handle = GPU(mCurrentSize);
+ mDevice->CreateShaderResourceView(resource, desc, DescriptorArray::Append());
+ return handle;
+ }
+
+ D3D12_GPU_DESCRIPTOR_HANDLE AppendCBV(D3D12_CONSTANT_BUFFER_VIEW_DESC* desc = nullptr)
+ {
+ auto handle = GPU(mCurrentSize);
+ mDevice->CreateConstantBufferView(desc, DescriptorArray::Append());
+ return handle;
+ }
+};
+
+// Samplers
+class SMPDescriptorList : public DescriptorArray
+{
+public:
+ SMPDescriptorList(ID3D12Device* device, UINT descriptorCount)
+ : DescriptorArray( device, descriptorCount, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, true )
+ {}
+
+ ID3D12DescriptorHeap* Heap() { return mHeap; }
+
+ D3D12_GPU_DESCRIPTOR_HANDLE Append(D3D12_SAMPLER_DESC* desc)
+ {
+ auto handle = GPU(mCurrentSize);
+ mDevice->CreateSampler(desc, DescriptorArray::Append());
+ return handle;
+ }
+};
diff --git a/Projects/Asteroids/src/font.h b/Projects/Asteroids/src/font.h
new file mode 100644
index 0000000..cd32626
--- /dev/null
+++ b/Projects/Asteroids/src/font.h
@@ -0,0 +1,98 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include "sprite.h"
+#include "intel_clear_bd_50_usascii.inl"
+#include "stb_font_consolas_bold_50_usascii.inl"
+
+#include <vector>
+#include <assert.h>
+
+class BitmapFont
+{
+public:
+ SpriteVertex* DrawString(const char* str, float x, float y, float viewportWidth, float viewportHeight, SpriteVertex* outVertex) const
+ {
+ for (; *str; ++str) {
+ auto codePoint = *str - STB_SOMEFONT_FIRST_CHAR;
+ assert(codePoint >= 0 && codePoint < mFontData.size());
+ const stb_fontchar* cd = &mFontData[codePoint];
+
+ outVertex[0] = {x + cd->x0, y + cd->y0, cd->s0, cd->t0};
+ outVertex[1] = {x + cd->x1, y + cd->y0, cd->s1, cd->t0};
+ outVertex[2] = {x + cd->x1, y + cd->y1, cd->s1, cd->t1};
+ outVertex[3] = outVertex[0];
+ outVertex[4] = outVertex[2];
+ outVertex[5] = {x + cd->x0, y + cd->y1, cd->s0, cd->t1};
+
+ for (int i = 0; i < 6; ++i) {
+ outVertex[i].x = (outVertex[i].x / viewportWidth * 2.0f - 1.0f);
+ outVertex[i].y = -(outVertex[i].y / viewportHeight * 2.0f - 1.0f);
+ }
+
+ outVertex += 6;
+ x += cd->advance_int;
+ }
+
+ return outVertex;
+ }
+
+ void GetDimensions(const char* str, int* width, int* height) const
+ {
+ UINT w = 0;
+ for (; *str; ++str) {
+ auto codePoint = *str - STB_SOMEFONT_FIRST_CHAR;
+ assert(codePoint >= 0 && codePoint < mFontData.size());
+ const stb_fontchar* cd = &mFontData[codePoint];
+ w += cd->advance_int;
+ }
+
+ *width = w;
+ *height = FontHeight();
+ }
+
+ int BitmapWidth() const { return mBitmapWidth; }
+ int BitmapHeight() const { return mBitmapHeight; }
+ int FontHeight() const { return mFontHeight; }
+
+ virtual const unsigned char* Pixels() const = 0;
+
+protected:
+ // Setup by derived class
+ std::vector<stb_fontchar> mFontData;
+ int mBitmapWidth;
+ int mBitmapHeight;
+ int mFontHeight;
+
+ BitmapFont() {}
+ BitmapFont(const BitmapFont&) {}
+};
+
+
+class IntelClearBold : public BitmapFont
+{
+public:
+ IntelClearBold()
+ {
+ mFontData.resize(STB_FONT_intelclearbd_NUM_CHARS);
+ stb_font_intelclearbd(mFontData.data(), mFontPixels, STB_FONT_intelclearbd_BITMAP_HEIGHT);
+
+ mBitmapWidth = STB_FONT_intelclearbd_BITMAP_WIDTH;
+ mBitmapHeight = STB_FONT_intelclearbd_BITMAP_HEIGHT;
+ mFontHeight = 50; // This doesn't seem to get put into the file anywhere...
+ }
+
+ virtual const unsigned char* Pixels() const override { return mFontPixels[0]; }
+
+private:
+ unsigned char mFontPixels[STB_FONT_intelclearbd_BITMAP_HEIGHT][STB_FONT_intelclearbd_BITMAP_WIDTH];
+};
diff --git a/Projects/Asteroids/src/font_ps.hlsl b/Projects/Asteroids/src/font_ps.hlsl
new file mode 100644
index 0000000..3100db9
--- /dev/null
+++ b/Projects/Asteroids/src/font_ps.hlsl
@@ -0,0 +1,12 @@
+#include "sprite_vs.hlsl"
+
+Texture2D Tex;// : register(t0);
+SamplerState Tex_sampler;// : register(s0);
+
+void font_ps(in float4 position : SV_Position,
+ in Font_VSOut vs_out,
+ out float4 color : SV_Target )
+{
+ float alpha = Tex.Sample(Tex_sampler, vs_out.uv).r;
+ color = float4(1, 1, 1, 1) * alpha;
+}
diff --git a/Projects/Asteroids/src/gui.h b/Projects/Asteroids/src/gui.h
new file mode 100644
index 0000000..d56aab6
--- /dev/null
+++ b/Projects/Asteroids/src/gui.h
@@ -0,0 +1,149 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include "font.h"
+
+#include <vector>
+#include <string>
+
+
+class GUIControl
+{
+protected:
+ int mX;
+ int mY;
+ int mWidth;
+ int mHeight;
+ std::string mTextureFile = "";
+ bool mVisible = true;;
+
+public:
+ GUIControl() {}
+ virtual ~GUIControl() {}
+
+ // For now, empty string means use the font texture/shader... let's not overengineer this yet :)
+ std::string TextureFile() const { return mTextureFile; }
+
+ void Visible(bool visible) { mVisible = visible; }
+ bool Visible() const { return mVisible; }
+
+ virtual SpriteVertex* Draw(float viewportWidth, float viewportHeight, SpriteVertex* outVertex) const = 0;
+
+ bool HitTest(int x, int y) const
+ {
+ return mVisible && (x >= mX && x < (mX + mWidth) && y > mY && y < (mY + mHeight));
+ }
+};
+
+
+class GUIText : public GUIControl
+{
+private:
+ std::string mText;
+ const BitmapFont* mFont;
+
+ void ComputeDimensions()
+ {
+ mFont->GetDimensions(mText.c_str(), &mWidth, &mHeight);
+ }
+
+public:
+ // Font lifetime managed by caller
+ GUIText(int x, int y, const BitmapFont* font, const std::string& text)
+ : mFont(font), mText(text)
+ {
+ mX = x;
+ mY = y;
+ ComputeDimensions();
+ }
+
+ void Text(const std::string& text)
+ {
+ mText = text;
+ ComputeDimensions();
+ }
+
+ virtual SpriteVertex* Draw(float viewportWidth, float viewportHeight, SpriteVertex* outVertex) const override
+ {
+ return mFont->DrawString(mText.c_str(), float(mX), float(mY), viewportWidth, viewportHeight, outVertex);
+ }
+};
+
+
+class GUISprite : public GUIControl
+{
+private:
+ std::string mSpriteFile;
+
+public:
+ GUISprite(int x, int y, int width, int height, const std::string& spriteFile)
+ : mSpriteFile(spriteFile)
+ {
+ mX = x;
+ mY = y;
+ mWidth = width;
+ mHeight = height;
+ mTextureFile = spriteFile;
+ }
+
+ virtual SpriteVertex* Draw(float viewportWidth, float viewportHeight, SpriteVertex* outVertex) const override
+ {
+ return DrawSprite(float(mX), float(mY), float(mWidth), float(mHeight), viewportWidth, viewportHeight, outVertex);
+ }
+};
+
+
+class GUI
+{
+private:
+ std::vector<GUIControl*> mControls;
+ IntelClearBold mFont; // Single font for the entire GUI works for now
+
+public:
+ GUI()
+ {
+ }
+ ~GUI()
+ {
+ for (auto i : mControls) {
+ delete i;
+ }
+ }
+
+ const BitmapFont* Font() const { return &mFont; }
+
+ GUIText* AddText(int x, int y, const std::string& text = "")
+ {
+ auto control = new GUIText(x, y, &mFont, text);
+ mControls.push_back(control);
+ return control;
+ }
+
+ GUISprite* AddSprite(int x, int y, int width, int height, const std::string& spriteFile)
+ {
+ auto control = new GUISprite(x, y, width, height, spriteFile);
+ mControls.push_back(control);
+ return control;
+ }
+
+ // NOTE: Caller needs to preadjust x/y for any stretching/scaling going on
+ GUIControl* HitTest(int x, int y) const
+ {
+ for (auto i : mControls) {
+ if (i->HitTest(x, y)) return i;
+ }
+ return nullptr;
+ }
+
+ GUIControl* operator[](size_t i) { return mControls[i]; }
+ size_t size() const { return mControls.size(); }
+};
diff --git a/Projects/Asteroids/src/intel_clear_bd_50_usascii.inl b/Projects/Asteroids/src/intel_clear_bd_50_usascii.inl
new file mode 100644
index 0000000..7a294a5
--- /dev/null
+++ b/Projects/Asteroids/src/intel_clear_bd_50_usascii.inl
@@ -0,0 +1,920 @@
+// Font generated by stb_font_inl_generator.c (4/1 bpp)
+//
+// Following instructions show how to use the only included font, whatever it is, in
+// a generic way so you can replace it with any other font by changing the include.
+// To use multiple fonts, replace STB_SOMEFONT_* below with STB_FONT_intelclearbd_*,
+// and separately install each font. Note that the CREATE function call has a
+// totally different name; it's just 'stb_font_intelclearbd'.
+//
+/* // Example usage:
+
+static stb_fontchar fontdata[STB_SOMEFONT_NUM_CHARS];
+
+static void init(void)
+{
+ // optionally replace both STB_SOMEFONT_BITMAP_HEIGHT with STB_SOMEFONT_BITMAP_HEIGHT_POW2
+ static unsigned char fontpixels[STB_SOMEFONT_BITMAP_HEIGHT][STB_SOMEFONT_BITMAP_WIDTH];
+ STB_SOMEFONT_CREATE(fontdata, fontpixels, STB_SOMEFONT_BITMAP_HEIGHT);
+ ... create texture ...
+ // for best results rendering 1:1 pixels texels, use nearest-neighbor sampling
+ // if allowed to scale up, use bilerp
+}
+
+// This function positions characters on integer coordinates, and assumes 1:1 texels to pixels
+// Appropriate if nearest-neighbor sampling is used
+static void draw_string_integer(int x, int y, char *str) // draw with top-left point x,y
+{
+ ... use texture ...
+ ... turn on alpha blending and gamma-correct alpha blending ...
+ glBegin(GL_QUADS);
+ while (*str) {
+ int char_codepoint = *str++;
+ stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR];
+ glTexCoord2f(cd->s0, cd->t0); glVertex2i(x + cd->x0, y + cd->y0);
+ glTexCoord2f(cd->s1, cd->t0); glVertex2i(x + cd->x1, y + cd->y0);
+ glTexCoord2f(cd->s1, cd->t1); glVertex2i(x + cd->x1, y + cd->y1);
+ glTexCoord2f(cd->s0, cd->t1); glVertex2i(x + cd->x0, y + cd->y1);
+ // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct
+ x += cd->advance_int;
+ }
+ glEnd();
+}
+
+// This function positions characters on float coordinates, and doesn't require 1:1 texels to pixels
+// Appropriate if bilinear filtering is used
+static void draw_string_float(float x, float y, char *str) // draw with top-left point x,y
+{
+ ... use texture ...
+ ... turn on alpha blending and gamma-correct alpha blending ...
+ glBegin(GL_QUADS);
+ while (*str) {
+ int char_codepoint = *str++;
+ stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR];
+ glTexCoord2f(cd->s0f, cd->t0f); glVertex2f(x + cd->x0f, y + cd->y0f);
+ glTexCoord2f(cd->s1f, cd->t0f); glVertex2f(x + cd->x1f, y + cd->y0f);
+ glTexCoord2f(cd->s1f, cd->t1f); glVertex2f(x + cd->x1f, y + cd->y1f);
+ glTexCoord2f(cd->s0f, cd->t1f); glVertex2f(x + cd->x0f, y + cd->y1f);
+ // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct
+ x += cd->advance;
+ }
+ glEnd();
+}
+*/
+
+#ifndef STB_FONTCHAR__TYPEDEF
+#define STB_FONTCHAR__TYPEDEF
+typedef struct
+{
+ // coordinates if using integer positioning
+ float s0,t0,s1,t1;
+ signed short x0,y0,x1,y1;
+ int advance_int;
+ // coordinates if using floating positioning
+ float s0f,t0f,s1f,t1f;
+ float x0f,y0f,x1f,y1f;
+ float advance;
+} stb_fontchar;
+#endif
+
+#define STB_FONT_intelclearbd_BITMAP_WIDTH 256
+#define STB_FONT_intelclearbd_BITMAP_HEIGHT 222
+#define STB_FONT_intelclearbd_BITMAP_HEIGHT_POW2 256
+
+#define STB_FONT_intelclearbd_FIRST_CHAR 32
+#define STB_FONT_intelclearbd_NUM_CHARS 95
+
+#define STB_FONT_intelclearbd_LINE_SPACING 27
+
+static unsigned int stb__intelclearbd_pixels[]={
+ 0x20266666,0x10ccccc9,0x00001333,0x00019990,0x009a9880,0x310ccccc,
+ 0x00001333,0x00066666,0x9aaa9880,0x26620000,0x09999999,0x00133331,
+ 0x33333310,0x40001333,0x00000019,0xcccc9800,0xfffff10c,0xfffff507,
+ 0x3fffff63,0xff00001d,0x9100001f,0x40dfffff,0x265ffffc,0x001fffff,
+ 0x3ffffdc0,0xfecba800,0xffffffff,0x7fec003d,0x5fffffff,0x00dffff9,
+ 0xffffffd0,0x26009fff,0xeffffedb,0x220001bd,0xacdffedb,0x50999999,
+ 0x223fffff,0xa83fffff,0xfb1fffff,0x09ffffff,0x01fff000,0xffffb800,
+ 0xff106fff,0xffe85fff,0x6c0005ff,0x4005ffff,0xffffffeb,0xffffffff,
+ 0xffb002ef,0xbfffffff,0x03ffffea,0xfffffd00,0x8809ffff,0xfffffffd,
+ 0x004fffff,0x7ffffe44,0xffffffff,0xffff52ff,0x3fffe23f,0xffffa83f,
+ 0xfffffb1f,0x80005fff,0x20000fff,0xfffffff9,0xffff706f,0xfffff50d,
+ 0x3fe20003,0xf3002fff,0xffffffff,0xffffffff,0xd803bfff,0xffffffff,
+ 0xfffff15f,0xfffe8007,0x04ffffff,0x3fffffea,0xffffffff,0xffd001ef,
+ 0xffffffff,0x25ffffff,0x11fffffa,0x507fffff,0x363fffff,0xffffffff,
+ 0xfb98000f,0x0009bdff,0x7ffffff4,0xffff06ff,0x3fffe07f,0xff50006f,
+ 0xf7001fff,0xdfffffff,0xffdb759b,0x09ffffff,0x7fffffec,0x3ff65fff,
+ 0x7f4005ff,0xffffffff,0xfffff904,0xffffffff,0x807fffff,0xcefffffd,
+ 0xfffffffc,0xffff52ff,0x3fffe23f,0xaaaa883f,0x7ffdcc0a,0xb1002fff,
+ 0xffffffff,0xf3005dff,0x037fffff,0x07ffffdc,0x1fffffc8,0xffffd800,
+ 0xffffd806,0x71001cff,0x09ffffff,0x2ffffec0,0x01fffff7,0x27ffff40,
+ 0xfffff980,0xecaaceff,0x0fffffff,0x7fffff10,0x0dffff70,0x21555551,
+ 0x03fffff8,0xffff9800,0xfffc803f,0xffffffff,0x2a01efff,0x802fffff,
+ 0x204ffffe,0x04fffff8,0x3fffff80,0x7ffffe40,0xf910001e,0x2003ffff,
+ 0x225ffffd,0x002fffff,0x013ffffa,0x77fffff4,0x3fffe601,0xfff505ff,
+ 0x3ffe20ff,0x7c4001ff,0x0003ffff,0x09fffff0,0xffffffc8,0xffffffff,
+ 0x3fee05ff,0xffa807ff,0x7ec01fff,0x54007fff,0x200fffff,0x03fffffa,
+ 0xffff3000,0xfffb001d,0xffffe8bf,0x3fffa004,0xfffb804f,0xe8800dff,
+ 0xc82fffff,0x3604ffff,0x4003ffff,0x83fffff8,0x00ccccc8,0x817ffff6,
+ 0xdffffffa,0xffecbfff,0x3ff200ff,0xffe806ff,0xffa806ff,0x32002fff,
+ 0x2206ffff,0x003fffff,0x7fffd400,0xffffd804,0x3ffffdc5,0x9ffffd00,
+ 0xfffff880,0x3fe6001f,0xffb86fff,0x3ffa06ff,0x666443ff,0xffff10cc,
+ 0xffff307f,0x7ffec03f,0x3fff605f,0x41fff0df,0x7e403fc8,0x7c406fff,
+ 0x8804ffff,0x004fffff,0x813ffffe,0x105ffffb,0x4437bd95,0x7ffec2aa,
+ 0x7ffec01f,0x7fffcc5f,0xfffd001f,0xfffa809f,0xfe8005ff,0x7cc1ffff,
+ 0xf980ffff,0x7cc1ffff,0xff11ffff,0xff307fff,0x7ec03fff,0x3fe05fff,
+ 0x3ffe1fff,0xffc80080,0x7fd406ff,0xff003fff,0x2600dfff,0x101fffff,
+ 0x301fffff,0x7ffffffd,0xf883fffe,0x7ec03fff,0xffe85fff,0xffd004ff,
+ 0xffb809ff,0xa8001fff,0xe82fffff,0x98beffff,0x0fffffeb,0x8fffffcc,
+ 0x83fffff8,0x01fffff9,0x417ffff6,0x7c6ffff8,0xf90000ff,0xfb80dfff,
+ 0xd002ffff,0x200fffff,0x207ffffb,0xa83ffffa,0xffffffff,0x40ffffcf,
+ 0x6c05fffc,0xfc85ffff,0xfd006fff,0xfc809fff,0x8000ffff,0x83fffff8,
+ 0xfffffff9,0x2fffffff,0x1fffff98,0x07fffff1,0x03fffff3,0x82ffffec,
+ 0x20fffff8,0x90000fff,0xd80dffff,0x001fffff,0x03fffffb,0x09ffffd0,
+ 0x207fffe4,0xfffffff8,0xffffffff,0x037ffd40,0x217ffff6,0x01fffff9,
+ 0x04ffffe8,0x03fffff4,0xfffff880,0xfffff505,0x7fffffff,0x3ffffe60,
+ 0x7fffff11,0x3fffff30,0x2ffffec0,0x47fffff0,0x90000fff,0xe80dffff,
+ 0x000fffff,0x05fffff9,0x2fffff88,0x21ffffe0,0x21effffc,0x0fffffe9,
+ 0x007fffcc,0x20bffffb,0x803fffff,0x404ffffe,0x006fffff,0x1bffffe0,
+ 0x3fffffee,0x00cfffff,0x47ffffe6,0x83fffff8,0x01fffff9,0x81fffff2,
+ 0xaefffffd,0xd0000fff,0xf80bffff,0x2007ffff,0x03fffffb,0x03ffffdc,
+ 0x88bffff1,0x880fffff,0x440fffff,0x3601ffff,0xf905ffff,0xfd00dfff,
+ 0x7c409fff,0x0005ffff,0x71fffffa,0x5537ffff,0x3e600355,0xff11ffff,
+ 0xff307fff,0x7d403fff,0x880affff,0xffffffff,0xf98001ff,0x7c03ffff,
+ 0x2006ffff,0x04fffffa,0x02ffffec,0x989ffff3,0x3204ffff,0xff80ffff,
+ 0x3ff602ff,0xfff505ff,0xffe801ff,0x7ffc04ff,0x3e0006ff,0x7f47ffff,
+ 0x980006ff,0xf11fffff,0xf307ffff,0x4403ffff,0xeffffffe,0x7ffffd40,
+ 0x0bdfffff,0x7fffff40,0x3fe200ff,0x26005fff,0x204fffff,0x02fffff8,
+ 0x50ffffea,0x5405ffff,0xfe80ffff,0x3ff602ff,0xfff105ff,0xffe807ff,
+ 0x7ff404ff,0x3e0007ff,0x7fc6ffff,0x40000fff,0x11fffff9,0x307fffff,
+ 0x803fffff,0xffffffe8,0xffffe980,0xcfffffff,0xffffff00,0xfff8801d,
+ 0x3e2004ff,0x2a05ffff,0x200fffff,0x5c1ffffa,0x2601ffff,0xff80ffff,
+ 0x3ff601ff,0x3ff605ff,0x7ff405ff,0x7fec04ff,0xf10007ff,0xfc8bffff,
+ 0xcccdffff,0x2601abcc,0xf11fffff,0xf307ffff,0x8803ffff,0x0ffffffd,
+ 0x3ffff660,0x2fffffff,0xeffffff8,0x7fffc400,0x7ffc004f,0x3ff605ff,
+ 0x7fd406ff,0x7ffdc1ff,0x3ffea01f,0x0ffff80f,0x17ffff60,0x0fffffb8,
+ 0x13ffffa0,0x1fffff70,0xffff3000,0xfffd889f,0xffffffff,0xff982eff,
+ 0xfff11fff,0xfff307ff,0x7f4403ff,0x00ffffff,0xfffffa88,0x7c1fffff,
+ 0x0effffff,0x3ffffe20,0x3ffe2005,0x3ffe04ff,0x7fd403ff,0x7ffd43ff,
+ 0x3ffee02f,0x3fffcc0f,0x17ffff60,0x2fffff88,0x13ffffa0,0x9fffff50,
+ 0xffff9000,0xfffd105f,0xffffffff,0xff989fff,0xfff11fff,0xfff307ff,
+ 0x7fd403ff,0x8000bfff,0xffffcfff,0xffa886ff,0x7fc03fff,0x2a006fff,
+ 0x504fffff,0x801fffff,0x4c4ffff9,0x3a04ffff,0x7e40ffff,0x7fec06ff,
+ 0x7ff405ff,0x3ffa04ff,0x7fcc04ff,0x2000ffff,0x87fffff8,0xfffffffa,
+ 0xffffffff,0x3ffe62ff,0xffff11ff,0xffff307f,0x7ffdc03f,0x3fe0007f,
+ 0xffffc88f,0xffffd01f,0xfffff809,0x3ffee007,0xfff903ff,0xfff100df,
+ 0xfffff0bf,0xfffff705,0x17fffc45,0x17ffff60,0x0fffff70,0x027ffff4,
+ 0x27ffffe4,0xfffffb00,0xfffff98b,0xfffb980a,0x3ffe64ff,0xffff11ff,
+ 0xffff307f,0x7ffec03f,0x3fe0005f,0x3ffffa0f,0xdffff903,0x7fffff80,
+ 0x3ffff200,0xfffff02f,0x3fffe009,0xfffffb86,0xffffdaae,0xffeaaeff,
+ 0xfffd806f,0x7ffcc05f,0xfffd01ff,0xfff1009f,0xd880bfff,0x40ffffff,
+ 0x804ffffc,0x266ffffd,0xf11fffff,0xf307ffff,0x6c03ffff,0x0005ffff,
+ 0xffb83ffe,0xfff904ff,0xfffd80df,0xffb000ff,0xff303fff,0x36003fff,
+ 0xff887fff,0xffffffff,0xffffff9f,0xd802ffff,0xe805ffff,0xfd04ffff,
+ 0x2e009fff,0xbeffffff,0xffeca88a,0xfe82ffff,0xfb802fff,0x3fe65fff,
+ 0xfff11fff,0xfff307ff,0x7fec03ff,0xf00c05ff,0x7ffe41ff,0xffff902f,
+ 0xffffc80d,0xfffd001f,0x3ffee0ff,0x3fea007f,0xfff983ff,0x71ffffff,
+ 0xffffffff,0x3fff6007,0xfffc805f,0xffffd06f,0x7fff4009,0xffffffff,
+ 0x4fffffff,0x0dffffd0,0x45ffffd0,0x11fffff9,0x307fffff,0x403fffff,
+ 0x205ffffd,0xfff80dfa,0x1fffff10,0x1bffff20,0x5fffff50,0x3ffffe00,
+ 0x9ffffd06,0x7fffc400,0xfffe880f,0x7fec2eff,0x2001efff,0x805ffffd,
+ 0x81fffff9,0x004ffffe,0x7fffffe4,0xffffffff,0x3ff203ff,0x260acfff,
+ 0x0fffffdb,0x47ffffe6,0x83fffff8,0x01fffff9,0x417ffff6,0x0acfffe8,
+ 0xffd73fff,0x7fe40dff,0x7fc406ff,0xf8803fff,0xf884ffff,0x4002ffff,
+ 0x205ffffc,0x2600ab98,0xd8000aba,0xf005ffff,0xfd07ffff,0x30009fff,
+ 0xfffffffd,0x1bffffff,0x7ffffc40,0xffffffff,0x7cc1ffff,0xff11ffff,
+ 0xff307fff,0x7ec03fff,0xff905fff,0xffffffff,0xffffffff,0x7fffe401,
+ 0xffffe806,0xffffa806,0xffffb82f,0xfff88007,0x000002ff,0xffffb000,
+ 0x3fff200b,0xffffe86f,0x3fb20004,0xffffffff,0x301dffff,0xffffffff,
+ 0x5fffffff,0x3fffff30,0x0fffffe2,0x07ffffe6,0x05ffffe8,0xffffffd3,
+ 0xffffffff,0xffc805ff,0xffb807ff,0x7ec01fff,0xffb06fff,0x2e000bff,
+ 0x004fffff,0xfd800000,0xf5005fff,0xfe81ffff,0x00004fff,0xfffb9751,
+ 0x7dffffff,0xfffeb881,0x2effffff,0x3ffe2000,0xfff983ff,0xfff301ff,
+ 0xfea807ff,0xffffffff,0xa800dfff,0x802fffff,0x204fffff,0x83fffff8,
+ 0x02fffff8,0x3ffff200,0x4a8002ef,0xfffd8000,0xfff1005f,0xfffe87ff,
+ 0x4000004f,0xffffffea,0x2ea601ff,0x0009abcc,0xfffff880,0xfffffb83,
+ 0xffffea80,0xfb95002f,0x39dfffff,0x7fffcc00,0x7fdc02ef,0xff700fff,
+ 0x3fea0fff,0x40000fff,0xdffffffd,0xeb9981ab,0x6c0001ff,0x2005ffff,
+ 0x745ffffd,0x0004ffff,0xfffb3000,0x00000dff,0xffff1000,0xfffe987f,
+ 0x3ffff67f,0x000fffff,0x003fff10,0x7fffffc0,0xff886fff,0xfff03fff,
+ 0x3ff607ff,0x500006ff,0xffffffff,0xfffffdff,0x6400bfff,0xffffeeee,
+ 0x3fee005f,0x3ffa0fff,0x3eeeefff,0x2e200000,0x00002fff,0xfff88000,
+ 0xffff73ff,0x7fecdfff,0x03ffffff,0x007ffc00,0xfffff500,0x3f20dfff,
+ 0xffa86fff,0xfff00fff,0x400007ff,0xffffffc8,0xffffffff,0xb000ffff,
+ 0xffffffff,0x7fc400bf,0x3ffa2fff,0x4fffffff,0xb5000000,0x00000000,
+ 0x4fffffe2,0xfffffffb,0x3fffff62,0xf80005ff,0x640000ff,0x6fffffff,
+ 0x3fffff10,0x04ffffd8,0x01fffff3,0xffd30000,0xffffffff,0x0017dfff,
+ 0x7fffffec,0x74005fff,0x3fa4ffff,0xffffffff,0x00000004,0x80000000,
+ 0x73fffff8,0x8bffffff,0x1efffffd,0x1fff0000,0xffb30000,0x7e40dfff,
+ 0x3fe24fff,0xff900fff,0x00000dff,0xffecba88,0x001cceff,0xffffffb0,
+ 0xb800bfff,0x3fa7ffff,0xffffffff,0x00000004,0x80000000,0x73fffff8,
+ 0x107fffff,0x00013555,0x000aaa80,0x05554c00,0x45555510,0x202aaaa8,
+ 0x001aaaaa,0x00100000,0xaaaa9800,0x002aaaaa,0x85555544,0xaaaaaaaa,
+ 0x000001aa,0x00000000,0xfffff880,0x00135513,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x4ccccc00,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x09999970,
+ 0x39999930,0x000cc000,0x1ddddd30,0x01331000,0x3bbbba60,0x40000000,
+ 0x00000998,0x00001998,0x3bbbba20,0x00262001,0x99999100,0xffdb9807,
+ 0x332a21bd,0x1599911c,0x6f7f6544,0x3fffee03,0x7ffe401f,0xb73000ff,
+ 0x7bdffffd,0x3ffea003,0xfd7000ff,0x7bdfffff,0xfffff301,0x44000003,
+ 0xfffffecb,0x54000bef,0xfffffedc,0x200003ee,0x02fffff8,0x7ffffecc,
+ 0xff88001d,0x3ee06fff,0x3fffffff,0x265ffff9,0xff54ffff,0x1dffffff,
+ 0x9fffff10,0x5ffffe80,0xffffd880,0xffffffff,0xffffa804,0x7ffdc00f,
+ 0xffffffff,0x7ffcc3ff,0x000001ff,0xfffffff7,0x17ffffff,0xffffe980,
+ 0xffffffff,0x440000bf,0x102fffff,0xfffffffb,0xf8800bff,0xfb06ffff,
+ 0xffffffff,0x5ffffb7f,0x27bfffe6,0xffffffff,0xffd81fff,0x3fe206ff,
+ 0x7d402fff,0xffffffff,0x1effffff,0x3ffffea0,0x3ffff600,0xffffffff,
+ 0xff31ffff,0x00003fff,0xfffffd88,0xffffffff,0xff9101ff,0xffffffff,
+ 0x03ffffff,0xffff8800,0xffffb02f,0x7fffffff,0x7fffc400,0xffffb86f,
+ 0xffffffff,0xf32fffff,0xfffddfff,0xffffffff,0xfffff50d,0x3fffee01,
+ 0x7fffe407,0xffffffff,0x03ffffff,0x01fffff5,0x3fffffee,0xffffffff,
+ 0xfff30fff,0x400003ff,0xfffffffa,0xffffffff,0xffff304f,0xffffffff,
+ 0x00bfffff,0xfffff100,0xfffff705,0xffffff9d,0x3ffe2001,0x7ffc46ff,
+ 0xca9befff,0x2fffffff,0xfffffff3,0xfffb537b,0xfff05fff,0x3ff607ff,
+ 0x3fe604ff,0xacefffff,0xfffffeca,0xfffa80ff,0xfff980ff,0xaabdffff,
+ 0x22fffecb,0x01fffff9,0xffff1000,0x559bffff,0x201fff97,0xfffffffe,
+ 0xfdcaabce,0x880000ff,0xd82fffff,0x7e43ffff,0xf1002fff,0xfc8dffff,
+ 0xf705ffff,0x265fffff,0x04ffffff,0x0dfffff7,0x20bffff9,0x201fffff,
+ 0x1efffffe,0x3ffffe60,0xffffa85f,0xffffb80f,0x46d9805f,0x01fffff9,
+ 0xffff9000,0x077009ff,0x3fffffee,0x025c400d,0xffff8800,0x7ffff82f,
+ 0x04ffff98,0x0aaaaaa0,0x01fffffd,0x97ffffec,0x07fffff9,0x43fffff4,
+ 0x987ffff8,0x2e06ffff,0x00dfffff,0xfffffe88,0x7ffffd42,0xfffffc80,
+ 0x3fe60000,0x80001fff,0x2ffffff9,0x7ffcc000,0x00002fff,0xffff1000,
+ 0xbffff05f,0x09ffff10,0xffff8000,0x7ffd404f,0xffff32ff,0xfffb807f,
+ 0xfffe80ff,0x7fffe42f,0xfffff103,0x7fcc003f,0x7fd46fff,0xffe80fff,
+ 0x4c0007ff,0x511fffff,0x807bdfd9,0x04fffffe,0xffffd800,0x3000004f,
+ 0x239bffb7,0x82fffff8,0xfa87fffd,0x00002fff,0x0fffffe2,0x5fffff10,
+ 0x07ffffe6,0x3fffff50,0x89ffff50,0x500ffffe,0x00bfffff,0x3fffffd0,
+ 0x07ffffd4,0x17fffff4,0xffff3000,0xffffd13f,0xf101dfff,0x001fffff,
+ 0xfffff880,0xb800000f,0xffffffff,0x2fffff8b,0x42ffffb8,0x0007fffc,
+ 0x7ffffcc0,0x7fffc402,0xfffff32f,0xffff9801,0xdffff02f,0x02ffffc4,
+ 0x03fffff7,0xfffff500,0x7ffffd45,0xfffffc80,0x3fe60005,0xffffbfff,
+ 0x1fffffff,0x1fffffcc,0x7ffcc000,0x800003ff,0xfffffffd,0xffffcfff,
+ 0xffff982f,0xbffff91f,0xffa80000,0xff801fff,0xfff32fff,0xff9801ff,
+ 0xff902fff,0x3ffee3ff,0x3fff202f,0xf88000ff,0x3ea3ffff,0xfb80ffff,
+ 0x0bffffff,0x7fffcc00,0xffffffff,0x5c6fffff,0x002fffff,0xfffffb80,
+ 0x7dc00002,0xffffffff,0xffffffff,0xdffff702,0x03fffffb,0xfff98000,
+ 0x7fc402ff,0xfff32fff,0xffa801ff,0xff301fff,0x3fff67ff,0x7ffff407,
+ 0xfff10007,0x7ffd4bff,0xfffd00ff,0x17bfffff,0xfffff300,0xfb537bff,
+ 0x645fffff,0x000fffff,0xfffffc80,0x3e200000,0x9befffff,0xffffffca,
+ 0x3fff602f,0x01ffffff,0xfff88000,0x7fcc03ff,0xfff32fff,0xffb803ff,
+ 0x3fa00fff,0x9ffff5ff,0x6fffff80,0x3fffe000,0x3fffea6f,0xffff300f,
+ 0xdfffffff,0x3ffe6017,0xff704fff,0x7fecdfff,0xb00007ff,0x4c0fffff,
+ 0xaaaaaaaa,0x3ffff22a,0xffff705f,0x7fc405ff,0x00dfffff,0x3ffe0000,
+ 0x7fe406ff,0xfff32fff,0xffe809ff,0x7fdc07ff,0x1ffffaff,0x3ffffe20,
+ 0x3ffa0005,0x3ffea7ff,0x3fa200ff,0xffffffff,0xff984fff,0x7f407fff,
+ 0x3ffe7fff,0xf00007ff,0x640fffff,0xffffffff,0x3ffffa5f,0x3fffa00f,
+ 0xfff502ff,0x5c0dffff,0x77440bde,0x7fec4eee,0xff101fff,0x3e65ffff,
+ 0x300fffff,0x809fffff,0xfffffff8,0xffff806f,0x3fe0006f,0x3fea7fff,
+ 0xea800fff,0xffffffff,0x3e60efff,0x5c03ffff,0xfd0fffff,0x0000ffff,
+ 0x81fffffa,0xfffffffc,0x3fffe5ff,0x7ffd404f,0x7fec42ff,0x4fffffff,
+ 0x889fffd0,0x4c6fffff,0x42ffffff,0xfffffff9,0xffffff32,0xffffa83d,
+ 0xffd801ff,0x803fffff,0x007ffffe,0x97ffffe0,0x00fffffa,0x3fff6e20,
+ 0x25ffffff,0x01fffff9,0x8fffffd4,0x00fffffd,0xffffd800,0xffff900f,
+ 0x22bfffff,0x403fffff,0x22fffff8,0xcfffffe8,0x444fffff,0x7c41ffff,
+ 0xfd86ffff,0xfeffffff,0xffffffff,0xffffff32,0xffffdfff,0x2a00bfff,
+ 0x0fffffff,0x7ffffd80,0xffff1000,0x7fffd49f,0x3660000f,0x2fffffff,
+ 0x01fffff3,0x2fffff98,0x03fffff7,0xffff7000,0x3fff203f,0x35ffffff,
+ 0x805fffff,0x22fffff8,0x52fffffc,0x547fffff,0xff887fff,0xff986fff,
+ 0xffffffff,0x2fffffef,0xfffffff3,0xffffffff,0x7fc003ff,0x7005ffff,
+ 0x001fffff,0x7fffff30,0x07ffffd4,0x7ff44000,0xfff35fff,0xff9801ff,
+ 0xfff52fff,0x500005ff,0x007fffff,0xaaffffdc,0x801fffff,0xf32fffff,
+ 0xfa85ffff,0xffd2ffff,0xffff109f,0x3ffa60bf,0x8dffffff,0xf32fffff,
+ 0xffb3ffff,0x3dffffff,0xffffc800,0xfff5002f,0xf90009ff,0x7d43ffff,
+ 0x0000ffff,0xdfffff50,0x03ffffe6,0x3fffff50,0x1bffffe6,0x3ffe6000,
+ 0x3ee006ff,0xfff35fff,0xff8805ff,0xfff72fff,0x3ffee0df,0x1ffffbff,
+ 0x4fffff88,0x3ffff620,0xffff14ff,0x3fffe65f,0xfffff91f,0xf30001bf,
+ 0x4c00ffff,0x00ffffff,0x3ffffe20,0x3fffea0f,0x3e00000f,0xff36ffff,
+ 0xfb803fff,0xff10ffff,0x0005ffff,0xffffff88,0xffff7003,0x1fffffcb,
+ 0x3ffffe60,0x09ffff92,0x7fffffdc,0x7fc406ff,0x1553003f,0x2fffff88,
+ 0x83fffff3,0x40001aa9,0x004ffffa,0x27ffffe4,0xfffffb00,0xfffffa87,
+ 0x44001501,0xf35fffff,0xe809ffff,0x7dc7ffff,0x000effff,0x7ffffdc0,
+ 0xfffb800f,0x3ffffe5f,0x7fffe406,0x9ffffb2f,0xfffffc80,0x7fcc01ff,
+ 0xf880003f,0xff32ffff,0x00003fff,0x3ffffa20,0x7ffc4001,0x6c405fff,
+ 0x986fffff,0x882fffff,0xfc800cff,0xff33ffff,0x2601ffff,0xe85fffff,
+ 0x02ffffff,0xfffd0498,0xfb807fff,0x3ff65fff,0xff101fff,0x3ee5ffff,
+ 0x6c00efff,0x806fffff,0x0002fffb,0x2fffff88,0x03fffff3,0xffb30000,
+ 0x2e0009ff,0xbeffffff,0xffeca88a,0xf882ffff,0x21aeffff,0x9bcffffd,
+ 0xfffeba88,0xfff31fff,0xfa83dfff,0x981fffff,0xdfffffff,0xfdaa99ab,
+ 0xffff982f,0x89abdfff,0x5ffffd99,0x3fffffe6,0x7ffffcc2,0xffff32ff,
+ 0x3f6a03bf,0x400effff,0x0000fffd,0x2fffff88,0x03fffff3,0x3ffee000,
+ 0x001fffff,0x3fffffa0,0xffffffff,0x205fffff,0x7fffffff,0xfffffff5,
+ 0xffffffff,0x7fcc7fff,0xefffffff,0x5fffffff,0x3fffff60,0xffffffff,
+ 0xff906fff,0xffffffff,0xffffffff,0xfffffd8b,0xfffffeff,0x3fa2ffff,
+ 0xeeffffff,0xfffffffe,0xff100eff,0x220000bf,0xf32fffff,0x0003ffff,
+ 0x3ffffee0,0x440004ff,0xfffffffc,0xffffffff,0x7ffe404f,0xffd37fff,
+ 0xffffffff,0x8bffffff,0xfceffff9,0xffffffff,0x7fdc01ff,0xffffffff,
+ 0x03ffffff,0xfffffff7,0xffffffff,0xfff98bff,0xffffffff,0x22ffffed,
+ 0xfffffff9,0xffffffff,0x706fffff,0x00005fff,0x4bffffe2,0x01fffff9,
+ 0xffff7000,0x40000dff,0xfffffffa,0x1effffff,0xfffff880,0x7fffd47f,
+ 0xffffffff,0xfff984ff,0xfffff95f,0x2003dfff,0xffffffe8,0xdfffffff,
+ 0x3fff6201,0xffffffff,0xe983ffff,0xffffffff,0x85ffffb5,0xfffffff9,
+ 0x9cffffff,0x505ffffe,0x440000fd,0xf32fffff,0x0003ffff,0x3ffffee0,
+ 0x4400000c,0xffffffec,0x44003eff,0x707ffffc,0xfffffffd,0x3e6019ff,
+ 0x3ff21eff,0x000dffff,0xfffffdb8,0x001dffff,0x3fffff66,0x0befffff,
+ 0x3ffff620,0x3ffa64ef,0xfffd702f,0x41bfffff,0x05ffffe8,0xf8800002,
+ 0xff32ffff,0x00003fff,0x0026aaa2,0x5d440000,0x200000ab,0x97310009,
+ 0x40000135,0x00001aa8,0x026b2a62,0x5dd4c000,0x5300009a,0x22000015,
+ 0x0009aaa9,0x20000000,0x26099999,0x00001999,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0xa8800000,0x0000abdb,0x4eeedc98,0x01ddddd3,0x33331000,0x33333333,
+ 0x98800133,0x001abcdb,0x5e6e5d44,0x2200000a,0x002eeeee,0x26200033,
+ 0x20009bcb,0x20019998,0x00eeeee9,0x654c4000,0xed802acd,0xddd34eee,
+ 0x7fd407dd,0x2fffffff,0xfffd9800,0xfff36fff,0xb00003ff,0xffffffff,
+ 0x05ffffff,0x3ffffae0,0x802effff,0xfffffffb,0x100003ff,0x107fffff,
+ 0xfffffd97,0xfff5003b,0x2003ffff,0x2007fffd,0x01fffff9,0xfffd3000,
+ 0x07ffffff,0x9afffff4,0x903fffff,0xffffffff,0x44009fff,0xffffffff,
+ 0x3fffff36,0xfffd0000,0xffffffff,0xd8805fff,0xffffffff,0xf105ffff,
+ 0xffffffff,0x0001ffff,0x3fffff88,0x7fffffdc,0x00efffff,0xfffffff7,
+ 0xff9807ff,0x3e6003ff,0x0001ffff,0x7ffffecc,0xffffffff,0x5ffffe80,
+ 0x87fffff3,0xffffffe8,0xefffffff,0xffffd800,0xff36ffff,0x00003fff,
+ 0xffffffff,0x5fffffff,0x7ffffd40,0xffffffff,0xfffe881f,0xffffffff,
+ 0x20000eff,0x33fffff8,0xfffffffd,0x1dffffff,0xdfffff98,0x201fffff,
+ 0x000ffffd,0x07ffffe6,0xffffb000,0xffffffff,0xfffd0dff,0x3fffe6bf,
+ 0x7fffe43f,0xffffefff,0x7cc04fff,0xceffffff,0x3fffff33,0xffff0000,
+ 0xffffffff,0x3e605fff,0xefffffff,0x906ffffe,0x9dffffff,0x9ffffffd,
+ 0x7ffc4000,0xffff73ff,0xffffffff,0xffd8bfff,0xfffd30df,0x3fffe60b,
+ 0x7ffcc004,0x440001ff,0xfeffffff,0x4fffffff,0x9afffff4,0x223fffff,
+ 0x0bffffff,0xffffff71,0x7fffd401,0xffff304f,0xf880003f,0x9999dfff,
+ 0x00999999,0x3dfffffb,0x7fc07aa0,0x7cc1efff,0x0007ffff,0x8fffffe2,
+ 0x9abdfffd,0x7fffffdb,0x307fffe2,0xfb01ffff,0x98001fff,0x001fffff,
+ 0x40aefb80,0x6fffffd9,0x9afffff4,0x323fffff,0x703fffff,0x409fffff,
+ 0x207ffffb,0x01fffff9,0x7fffcc00,0x7fcc0003,0x20004fff,0x04fffff8,
+ 0x01fffff9,0x3fffe200,0x8077e23f,0x31fffffe,0x3fe0ffff,0x7ffcc1ff,
+ 0xff98004f,0x00001fff,0xfffff005,0x5ffffe8f,0x27fffff3,0x06fffff8,
+ 0x07ffffec,0x06ffffc8,0x07ffffe6,0xffff5000,0xffe80007,0x4c0005ff,
+ 0x301fffff,0x005fffff,0x3ffffe20,0x7fd40043,0xfff52fff,0x0bfffe0d,
+ 0x001ffffb,0x3fffff30,0x64000000,0x3a1fffff,0xff35ffff,0x3fea7fff,
+ 0x7dc03fff,0x32a2ffff,0xcfffffec,0xfff32ccc,0x3f6e23ff,0x3ea02def,
+ 0x20002fff,0x01fffff9,0x7fffc400,0xffff301f,0x3e20001f,0x8003ffff,
+ 0x71fffffa,0x3fa0dfff,0x3ffe23ff,0xff30004f,0x32203fff,0x0003cccc,
+ 0xd1ffffee,0x3e6bffff,0xff73ffff,0xf8801fff,0x3ee3ffff,0xffffffff,
+ 0xfff34fff,0xffff33ff,0x2e09ffff,0x0001ffff,0x417fffee,0x3ff60009,
+ 0xfff904ff,0x7c4000bf,0x8003ffff,0x2a7ffffd,0xfff07fff,0x7fffe45f,
+ 0xfff30000,0x3ffa03ff,0x20001fff,0x745ffffe,0xff15ffff,0x3ff25fff,
+ 0xfff007ff,0x7ffdc9ff,0xffffffff,0xfffff34f,0xfffffff9,0xff907fff,
+ 0xdfdb53ff,0x7fe4017b,0xffd913ff,0xfb805bff,0x7d42ffff,0x0003ffff,
+ 0x0fffffe2,0xfffff700,0x83fffcc7,0xff11ffff,0x4c0009ff,0xc81fffff,
+ 0x003fffff,0x3ffffe60,0xafffff43,0xb2fffff8,0x200fffff,0x2e5ffffe,
+ 0xffffffff,0xff34ffff,0xffffffff,0x1fffffff,0xfeffffc8,0x3fffffff,
+ 0x55ffffb0,0xffffffff,0x3f6201bf,0xffdfffff,0x000effff,0x3ffffe20,
+ 0x3ffee003,0x7ffc45ff,0x7fffd41f,0x81ffff90,0x301bcdba,0xa83fffff,
+ 0x005fffff,0xff955553,0xfe81dfff,0xfff15fff,0x3fffa5ff,0xfffd006f,
+ 0x7f6654df,0xccccffff,0xffffff32,0xfff9359f,0xffd87fff,0xffffffff,
+ 0xfe86ffff,0xffffcfff,0x6fffffff,0x7ffffe40,0x04ffffff,0xffff8800,
+ 0xfff7003f,0xff901dff,0x3ffaa5df,0xbffff14f,0x7fffff4c,0x7ffcc0df,
+ 0x3ffe21ff,0x3f2006ff,0xffffffff,0xffffe80d,0x5fffff15,0x017ffffe,
+ 0x83ffffec,0x206ffffc,0x3ffffff9,0x4fffff98,0x7ffffff4,0xffffffff,
+ 0x7ffffc3f,0xffffffff,0x404fffff,0xfffffffe,0x100006ff,0x007fffff,
+ 0x1dfffff9,0x3ffffe20,0x90ffffff,0x3ea3ffff,0xffffffff,0x3fffe60e,
+ 0x3ffff61f,0x3ff2000f,0x1fffffff,0x2bffffd0,0xf2fffff8,0x200bffff,
+ 0x907ffffd,0x4c0dffff,0x206fffff,0x545fffff,0xdcdffffe,0xffffffff,
+ 0xffffff10,0xf93135df,0x301fffff,0xfffffffd,0x003dffff,0xfffff880,
+ 0x7fffd403,0x7fd400ef,0x2fffffff,0x74bffff1,0xffedffff,0x3ffe64ff,
+ 0xffff91ff,0xffc8005f,0xffffffff,0x7ffff40d,0x5fffff15,0x01bffffa,
+ 0x837ffff4,0x206ffffc,0x03fffff9,0x41bffff6,0xffd503da,0x7ffc7fff,
+ 0x3ee06fff,0x7e42ffff,0xfeffffff,0x04ffffff,0x3fffe200,0x7fffc03f,
+ 0xfd1000ef,0x641dffff,0xff71ffff,0x7ffdc3df,0xfffff30f,0x9fffffdb,
+ 0xffff9000,0xdfffffff,0xafffff41,0xb2fffff8,0x200fffff,0x905ffffe,
+ 0x4c0dffff,0x202fffff,0x006ffffc,0x3ffffe60,0x3fffffe4,0x7ffffc01,
+ 0x3ffffee3,0x7ffe542c,0xf10003ff,0x4c07ffff,0x002fffff,0x4409a988,
+ 0x3f65ffff,0xfffe83ff,0xffffff33,0x00dfffff,0x7fedcc00,0x3ffa4fff,
+ 0xffff15ff,0x3ffff25f,0xfffff007,0x3ffff209,0x3fffe606,0x3fff201f,
+ 0x7fc0006f,0x3ff65fff,0xffd807ff,0x3fffe5ff,0x7ffe404f,0xff10007f,
+ 0x7d407fff,0x0000ffff,0x1ffffc80,0x320bfffe,0xfff34fff,0xffffffff,
+ 0xf1000009,0x3a1fffff,0xff15ffff,0x3fee3fff,0x7cc01fff,0xf903ffff,
+ 0x7cc0dfff,0x3201ffff,0x0006ffff,0x937ffff4,0xb00fffff,0x3e69ffff,
+ 0x4c01ffff,0x001fffff,0x2fffff98,0x3ffffea0,0x7c400000,0x7ffc5fff,
+ 0x5fffc81f,0xfffffff3,0x005fffff,0xffff9000,0x3ffffa3f,0xa8666665,
+ 0x404fffff,0x02fffffb,0x40dffff9,0x01fffff9,0x01bffff2,0x9fffff00,
+ 0x03ffffdc,0xa9ffffec,0x400fffff,0x02fffff8,0xfffffa80,0x0ccccc01,
+ 0x7fe40000,0x3ffe21ff,0x6fffb81f,0x33fffff3,0x01fffffd,0xfffa8000,
+ 0xffffd2ff,0x7fffc00b,0x7fff406f,0xfff900ff,0x7ffcc0df,0x3ff201ff,
+ 0x260006ff,0x263fffff,0x401fffff,0xf32fffff,0x9803ffff,0x001fffff,
+ 0x0fffffc8,0x40000000,0xf86ffff8,0xffc81fff,0xfffff35f,0x3ffffe63,
+ 0x7dc00005,0xffd1ffff,0x7dc00bff,0xf904ffff,0x6407ffff,0x2606ffff,
+ 0x201fffff,0x4c6ffffc,0xfffe802f,0x7ffec1ff,0x3ffee05f,0x3fffe0ff,
+ 0x7ffe405f,0x100d40ff,0x00ffffff,0xf7000000,0xffd05fff,0x7fffb05f,
+ 0x87ffffe6,0x02fffffb,0x3e200664,0x3fa7ffff,0xddd35fff,0xffff87dd,
+ 0xfda8adff,0x6407ffff,0x2606ffff,0x201fffff,0x226ffffc,0x109beffe,
+ 0xdfffffd5,0x9fffff30,0xfffffb81,0x7fffff45,0x3ff2a0ac,0x7fc46fff,
+ 0xfea989ad,0x5404ffff,0x002eeeee,0x1bfffe00,0x7c2fffec,0xfff32fff,
+ 0xfffe83ff,0xfff500ff,0x7fdcc359,0x3fa5ffff,0xfff55fff,0xfffb89ff,
+ 0xffffffff,0x6403ffff,0x2606ffff,0x201fffff,0x326ffffc,0xffffffff,
+ 0xffffffff,0xfffffb01,0xfffffddf,0xfffa81ff,0xffefffff,0x42ffffff,
+ 0xfffffffc,0x0fffffff,0x7ffffdc0,0xff700003,0x3fe605ff,0xffea8dff,
+ 0x3fffe66f,0x7fffd41f,0xffff885f,0xffffffff,0x3a1fffff,0xff55ffff,
+ 0xff909fff,0xffffffff,0xf9009fff,0x7cc0dfff,0x3201ffff,0x3f66ffff,
+ 0xffffffff,0x03ffffff,0x3fffff62,0xffffffff,0xfffff703,0xffffffff,
+ 0xfff987ff,0xffffffff,0xfb803fff,0x0003ffff,0x80dffff0,0xfffffffc,
+ 0x3fe62fff,0xffd81fff,0x7fd43fff,0xffffffff,0x42ffffff,0xf55ffffe,
+ 0x2a09ffff,0xffffffff,0xf9002fff,0x7cc0dfff,0x3201ffff,0x7546ffff,
+ 0xffffffff,0x7002ffff,0xffffffff,0xfb805fff,0xffffffff,0xd883ffff,
+ 0xffffffff,0x7003ffff,0x007fffff,0x5ffff700,0xffffd880,0x7cc3ffff,
+ 0xf881ffff,0x441fffff,0xfffffffd,0x83ffffff,0xf55ffffe,0x4409ffff,
+ 0xfffffffd,0x3ff2000d,0x3fe606ff,0x3f201fff,0xfd706fff,0x9fffffff,
+ 0xfffb3000,0x0019ffff,0x3ffffee2,0x400bffff,0xffffffd9,0x2e000dff,
+ 0x003fffff,0x06ffff80,0x3ffffae0,0xffff981d,0xffff701f,0x3fb660df,
+ 0x3fffffff,0x57ffffa0,0x04fffffa,0x00155510,0x1bffff20,0x1fffff98,
+ 0x1bffff20,0x026aaa20,0x55544000,0x54c40000,0x300009aa,0x00035775,
+ 0x0fffffee,0x40000000,0x7fcc0198,0x3fa01fff,0x9804ffff,0x00009aaa,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x32e62000,0x3ba001bc,0x2e003eee,0x3aa6eeee,
+ 0x0004eeee,0x77774400,0x3bbbb25e,0xeec8003e,0xddd52eee,0xdddddddd,
+ 0xdddddddd,0x77647ddd,0xb1004eee,0x6c1bdddd,0xeeeeeeee,0x8009acde,
+ 0xeeeeeee8,0xeeeeeeee,0xdb2eeeee,0xdddddddd,0x6c01359b,0x0004eeee,
+ 0xffffc880,0x400dffff,0x004fffff,0x99fffff2,0x007fffff,0x7ffd4000,
+ 0x3ffea5ff,0xff8006ff,0xff70ffff,0xffffffff,0xffffffff,0x7cc9ffff,
+ 0x801fffff,0x43fffffc,0xfffffffe,0x3fffffff,0x7ffffc40,0xffffffff,
+ 0x3fffffff,0xfffffffd,0x5fffffff,0x17ffffa0,0xfff50000,0xffffffff,
+ 0x7fffc03d,0x3ff2004f,0x7fffc7ff,0x7fcc00ff,0xfc806fff,0x7fc3ffff,
+ 0x2000ffff,0x25fffffa,0xfffffffb,0xffffffff,0x4fffffff,0x37ffffdc,
+ 0x3ffffe60,0xfffffe85,0xffffffff,0xff101fff,0xffffffff,0xffffffff,
+ 0x3fffa7ff,0xffffffff,0x741effff,0x0005ffff,0x3ffffe60,0xffffffff,
+ 0xfffff02f,0x7ffe4009,0x7fffec7f,0x7ffdc02f,0x7ec00fff,0x7e41ffff,
+ 0x2003ffff,0x22fffffc,0xfffffffb,0xffffffff,0x4fffffff,0x2fffffe8,
+ 0x3fffffa0,0xfffffe80,0xffffffff,0xf880efff,0xffffffff,0xffffffff,
+ 0xfffd3fff,0xffffffff,0xe8dfffff,0x0005ffff,0x3fffffa0,0xffffdcce,
+ 0xffff80ff,0x3ff2004f,0x7ffdc7ff,0x7fec04ff,0x7c02ffff,0xf987ffff,
+ 0x2005ffff,0x20ffffff,0xccccccca,0xcfffffec,0x2ccccccc,0x6fffff98,
+ 0x7fffff70,0x3bffffa0,0xffeecccc,0x9905ffff,0x99999999,0xffff9999,
+ 0x3fffa5ff,0xdcaaaadf,0x24ffffff,0x005ffffe,0xfffff700,0xfffff309,
+ 0x9fffff07,0x7fffe400,0x7ffffc47,0x7ffffc05,0x3fe204ff,0xfff05fff,
+ 0xf3001fff,0x000bffff,0x00dffffb,0x7ffffe40,0x7ffffc43,0x3ffffa05,
+ 0x3fffea04,0x900000ff,0x749fffff,0x2a04ffff,0xd0ffffff,0x000bffff,
+ 0x17ffffa0,0x86ffffa8,0x004fffff,0x21fffff2,0x207ffffe,0xfffffff9,
+ 0x3fffea06,0xffff902f,0xfff7005f,0xfb0005ff,0x8000dfff,0x20fffffe,
+ 0x00fffffd,0x013ffffa,0x03fffff7,0xffff5000,0xffffe8bf,0x7fffdc04,
+ 0xbffffd2f,0x3ffe0000,0x7ff401ff,0x7fffc2ff,0x3ff2004f,0xfffc87ff,
+ 0xfff900ff,0x203fffff,0x00fffffc,0x0bfffff3,0x0fffffd0,0x3ffff600,
+ 0x7fcc0006,0xfff55fff,0xffe805ff,0x7fc404ff,0x40003fff,0x86fffff9,
+ 0x404ffffe,0xd3fffff8,0x000bffff,0x1fffff10,0x5ffffd80,0x027ffffc,
+ 0x0fffff90,0x05fffff5,0x3ffffffa,0xfffb03ff,0xfffe80df,0x7ffc407f,
+ 0xfb0004ff,0x0000dfff,0xd5fffff9,0xd00bffff,0xf009ffff,0x0007ffff,
+ 0x7fffffc4,0x4ffffe80,0x4fffff80,0x00bffffd,0xfffff500,0xdffffb00,
+ 0x04fffff8,0x1fffff20,0x13ffffe2,0x3fbfffe2,0xfff05fff,0xffb809ff,
+ 0x3ea01fff,0x0001ffff,0x00dffffb,0xffffd100,0x01ffffff,0x09ffffd0,
+ 0x2fffff88,0xfffd1000,0x3ffa03ff,0xfff804ff,0xffffd4ff,0xff30000b,
+ 0xfe801fff,0x7ffc7fff,0x3f2004ff,0xffd07fff,0xfff50bff,0x0fffff5f,
+ 0x05fffff1,0x4fffff88,0x1bffff60,0xffffd800,0xff500006,0x5fffffff,
+ 0x3ffffa00,0x7fffdc04,0xffb0001f,0x7f405fff,0x7c404fff,0xffd3ffff,
+ 0x10000bff,0x805fffff,0x7c7fffff,0x2004ffff,0x707ffffc,0xf90fffff,
+ 0xfffb1fff,0xffffa83f,0xfffd800f,0x3fffe06f,0x3f60003f,0x00006fff,
+ 0x3ffffff6,0x3ffa005f,0x3fea04ff,0x90005fff,0x809fffff,0x404ffffe,
+ 0xd2fffffa,0x000bffff,0x1bffffe0,0xffffffb8,0x13ffffe0,0x7ffffc80,
+ 0x3fffff30,0xf76fffe8,0xffb87fff,0xff5006ff,0xff303fff,0x40001fff,
+ 0x006ffffd,0x3fffe200,0x3a000fff,0xaaadffff,0xfffffecb,0xffa8001f,
+ 0xfe805fff,0x3e604fff,0xfd0fffff,0x0000bfff,0x3bfffff6,0xffff910b,
+ 0x7ffc3fff,0x3f2004ff,0x3fe07fff,0x3fe22fff,0xffff14ff,0x3ffffd8d,
+ 0xfffff100,0xbffff907,0xfffd8000,0x7400006f,0x00ffffff,0x3fffffa0,
+ 0xffffffff,0x98002fff,0x00efffff,0xadffffe8,0xfffdbaaa,0x3ffa4fff,
+ 0x300005ff,0xffffffff,0xfffffffd,0x7fffc1ff,0x3ff2004f,0x3ff607ff,
+ 0x3ffea4ff,0x3ffffa1f,0x07ffffe0,0x6ffffd80,0x02ffffe8,0x7fffec00,
+ 0x3f200006,0x05ffffff,0x3fffffa0,0xffffffff,0xf88002ef,0x000fffff,
+ 0xfffffffd,0xffffffff,0xffffe8df,0x3f200005,0xffffffff,0x7ffffeff,
+ 0x027ffffc,0x0fffff90,0xb2ffffdc,0xffc8ffff,0xffff12ff,0xfffa800f,
+ 0x3ffe60ff,0x6c0000ff,0x0006ffff,0xffffff30,0x3a005fff,0xffffffff,
+ 0x001fffff,0x3fffffa0,0x3fffa001,0xffffffff,0x741effff,0x0005ffff,
+ 0x7ffffe40,0xffacffff,0x7fffc6ff,0x3ff2004f,0x3fe207ff,0x3fffe7ff,
+ 0xa7fffcc5,0x005ffffa,0x22fffff8,0x005ffffb,0x6ffffd80,0xfffd0000,
+ 0x1fffffff,0xdffffd00,0xfffffd99,0x3ff60007,0x74003fff,0xffffffff,
+ 0x03ffffff,0x00bffffd,0xfffd5000,0x3fee7dff,0x7fff45ff,0x3ff6005f,
+ 0x7ff406ff,0xffff99ff,0x76ffff83,0x0007ffff,0x6cbffff9,0x0002ffff,
+ 0x06ffffd8,0xffffb800,0x5fffffbf,0x4ffffe80,0x07fffff4,0x3ffff200,
+ 0xffe8004f,0xdeeeefff,0x3fa00abc,0x00005fff,0x7ec0d4c0,0x7fec4fff,
+ 0x3fa006ff,0x7e405fff,0xfffbafff,0xffffd81f,0x01ffffd8,0x7ffff980,
+ 0x00fffff1,0x3ffff600,0x7fcc0006,0xfffb3fff,0xffe805ff,0x7ffcc4ff,
+ 0x3ea006ff,0x0005ffff,0x009ffffd,0x5ffffe80,0x10000000,0xc85fffff,
+ 0x2007ffff,0x404fffff,0xfdcffffa,0xfff706ff,0x0dfffd5f,0x7ffff400,
+ 0x04ffffaa,0xffffb000,0xffe8000d,0x3ffe26ff,0x3fa00fff,0xffc84fff,
+ 0xf9803fff,0x000effff,0x09ffffd0,0xffffe800,0x00000005,0x70dffff9,
+ 0x007fffff,0x07fffff7,0xfeffff88,0xff104fff,0x9ffffdff,0x7ffdc000,
+ 0x1ffffdcf,0xfffb0000,0x7dc000df,0x7dc2ffff,0x3a05ffff,0xf884ffff,
+ 0x200fffff,0x0ffffff8,0x3fffa000,0x7f40004f,0x00005fff,0x3fee0062,
+ 0xff882fff,0x2601ffff,0x00ffffff,0xffffffe8,0x3ffa02ff,0x02ffffff,
+ 0x3fffe200,0x006fffff,0x3ffff600,0xfff10006,0x3ffa0bff,0xffd02fff,
+ 0x3fea09ff,0x3fa05fff,0x0001ffff,0x027ffff4,0x3ffffa00,0x3f600005,
+ 0xfb5309bd,0x5c0dffff,0xacffffff,0xffffca88,0xff7004ff,0x01ffffff,
+ 0x7fffffe4,0x740000ff,0xffffffff,0x3f600003,0xd0006fff,0x201fffff,
+ 0x0ffffff9,0x04ffffe8,0x0ffffff6,0x37fffff6,0xaaaaaaaa,0xd1aaaaaa,
+ 0x0009ffff,0xaeffffe8,0xaaaaaaaa,0xfff302aa,0xffffffff,0xf803ffff,
+ 0xffffffff,0xffffffff,0x3ffe6007,0x5406ffff,0x6fffffff,0xfffb8000,
+ 0x000fffff,0x3ffff600,0xfffb8006,0x7fe403ff,0xffe85fff,0x3fe604ff,
+ 0x7f40ffff,0xffffffff,0xffffffff,0xfffd3fff,0xfe80009f,0xffffffff,
+ 0x5fffffff,0xffffffd0,0xdfffffff,0xffff5003,0xffffffff,0x8005ffff,
+ 0x3fffffff,0xffffff80,0xf880004f,0x06ffffff,0x7ffec000,0x7fc4006f,
+ 0xf8806fff,0x742fffff,0x6404ffff,0x745fffff,0xffffffff,0xffffffff,
+ 0xffd3ffff,0xe80009ff,0xffffffff,0xffffffff,0xfffff705,0xbfffffff,
+ 0x7ff4c001,0xffffffff,0xd8000eff,0x01ffffff,0xffffffd8,0xffb00001,
+ 0x0007ffff,0x6ffffd80,0x7fffec00,0xfff5002f,0x7ff41fff,0x7fc404ff,
+ 0x3fa2ffff,0xffffffff,0xffffffff,0xfffd3fff,0xfe80009f,0xffffffff,
+ 0x5fffffff,0x3fffee20,0x003dffff,0x3ffffae0,0x003effff,0x3ffffee0,
+ 0xffff7007,0x540000ff,0x00ffffff,0x7ffec000,0x3fea006f,0x6c005fff,
+ 0x3a5fffff,0xa804ffff,0xd0ffffff,0xffffffff,0xffffffff,0x3fa7ffff,
+ 0x40004fff,0xfffffffe,0xffffffff,0x2aa6005f,0x9800000a,0x0001abba,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x77775400,0x3b62004e,0x3bb65eee,0xd3002eee,
+ 0x776cdddd,0x30002eee,0x36bddddd,0xb004eeee,0x6c7ddddd,0xeeeeeeee,
+ 0xeeeeeeee,0x09ddddb2,0x277776c0,0x440cccc0,0xeed80999,0xeeeeeeee,
+ 0x1eeeeeee,0x3372ea20,0x2666202a,0x99999999,0x09999999,0xdddddddb,
+ 0x003579bd,0xffffff10,0x3ffee003,0x3fffa2ff,0xf9800fff,0x3ffa7fff,
+ 0xb0006fff,0x3adfffff,0xc805ffff,0x746fffff,0xffffffff,0xffffffff,
+ 0x0bffffd3,0x37ffff40,0x21fffe60,0xfe84fffc,0xffffffff,0xffffffff,
+ 0xfffffb82,0xc82effff,0xffffffff,0xffffffff,0xffffd5ff,0xffffffff,
+ 0xfb8005bf,0xf004ffff,0xfe8dffff,0x803fffff,0x3a7ffff9,0x03ffffff,
+ 0x7ffffcc0,0xbffffd6f,0xfffff980,0x7ffff40f,0xffffffff,0xffd3ffff,
+ 0x7f400bff,0x7d406fff,0xfffd86ff,0xfffffe83,0xffffffff,0x3aa2ffff,
+ 0xffffffff,0x7e45ffff,0xffffffff,0xffffffff,0xfffffd5f,0xffffffff,
+ 0xfe800bff,0x5c00ffff,0x742fffff,0x0fffffff,0x3ffffcc0,0xdffffffd,
+ 0xffffd800,0xffffd6ff,0x7fffc40b,0xfffe82ff,0xffffffff,0xfd3fffff,
+ 0x7400bfff,0x5c06ffff,0xffe85fff,0xffffe81f,0xffffffff,0xf52fffff,
+ 0xffffffff,0x47ffffff,0xfffffffc,0xffffffff,0xfffd5fff,0xffffffff,
+ 0x007fffff,0x27ffffd4,0x17ffffa0,0x3ffffffa,0x7ffcc04f,0x3ffffa7f,
+ 0xf3003fff,0x2dffffff,0x205ffffe,0x04fffffd,0x99dffffd,0x99999999,
+ 0x3ffffa59,0x3fffa005,0x7ffe406f,0x80ffff83,0xcceffffe,0xcccccccc,
+ 0x3fffa1cc,0xffffeeff,0xff91ffff,0xffffffff,0xffffffff,0x3bffffab,
+ 0xfffeeccc,0x2001ffff,0x00fffffe,0x03fffff5,0xfffffffd,0x7ffcc01f,
+ 0x3ffffa7f,0xfb006fff,0x2dffffff,0x705ffffe,0x40dfffff,0x005ffffe,
+ 0x0bffffd0,0x37ffff40,0x10bfff60,0x3fa0ffff,0x40005fff,0x2209dff8,
+ 0x2fffffea,0x33333331,0xfd333333,0x3ffa7fff,0xffd304ff,0x4c005fff,
+ 0xd03fffff,0x3a09ffff,0xffffffff,0x3fffe605,0x3fffffa7,0x7cc02fff,
+ 0x6fffffff,0x10bffffd,0x01ffffff,0x02fffff4,0x5ffffe80,0x3ffffa00,
+ 0x0ffff406,0x741bffe6,0x0005ffff,0x7fdc01a8,0x20004fff,0xd0fffff9,
+ 0x4409ffff,0x004fffff,0x437fffec,0x00fffffa,0xfffffffd,0x3fe603ff,
+ 0x3fffa7ff,0x406fffff,0xfffffffd,0xbffffd6f,0x5fffffd0,0x5ffffe80,
+ 0xffffd000,0x7fff400b,0x3fffea6f,0xffffffff,0xffffffff,0x0bffffd2,
+ 0x3e200000,0x0005ffff,0xe93ffff6,0x7c04ffff,0x4005ffff,0x42fffff8,
+ 0x204ffffe,0xffdffffe,0xfff305ff,0x7ffff4ff,0x302fffff,0xffffffff,
+ 0x3ffffadf,0x7ffffe45,0xffffe804,0xfffd0005,0x7ff400bf,0x3ffea6ff,
+ 0xffffffff,0xffffffff,0xbffffd2f,0x7c000000,0x0003ffff,0x41fffff1,
+ 0x404ffffe,0x003ffffe,0x26ffffc8,0x00fffff9,0x3afffffa,0xf981ffff,
+ 0x3ffa7fff,0x6ffffcff,0xf9ffffb0,0x3ffadfff,0x3ffea5ff,0xffd005ff,
+ 0x3a000bff,0x2005ffff,0x2a6ffffe,0xffffffff,0xffffffff,0xffd2ffff,
+ 0x00000bff,0x3ffffe60,0xfff90001,0xffffe8bf,0x3fffe204,0xff88001f,
+ 0xfffb2fff,0xfffe807f,0x6ffff9bf,0x27ffff98,0xfcbffffe,0x7fcc2fff,
+ 0xffffbcff,0x2bffffd6,0x0ffffffa,0xbffffd00,0x3fffa000,0x3ffa005f,
+ 0x333266ff,0xcccefffe,0xccdffffc,0xbffffd1c,0x32000000,0x0007ffff,
+ 0xd07ffffe,0x2209ffff,0x007ffffd,0x37fffee0,0x806ffff9,0xfb3ffffe,
+ 0xff985fff,0x3fffa7ff,0x6ffff8bf,0x5c7fffec,0xffd6ffff,0xffffffff,
+ 0x7f4003ff,0x9999efff,0x74099999,0xeeefffff,0xfeeeeeee,0x3206ffff,
+ 0xfff84fff,0xffffd01f,0xdddddddf,0x20005ddd,0x05fffffb,0xdffff700,
+ 0x9dffffd0,0xffffdb99,0xf80001df,0xfffeffff,0xfffe802f,0xdffff13f,
+ 0x27ffff98,0xf93ffffe,0x3fe65fff,0xffff74ff,0x3fffffad,0x03ffffff,
+ 0x7fffff40,0xffffffff,0x7ffff45f,0xffffffff,0xffffffff,0x0ffff606,
+ 0x201ffff1,0xfffffffe,0xffffffff,0xfffa8002,0xd0001fff,0xfd07ffff,
+ 0xffffffff,0x009fffff,0x3fffee00,0xd005ffff,0x7e47ffff,0x3fe63fff,
+ 0x3fffa7ff,0xdffff13f,0x5c3ffff6,0xffd6ffff,0xffffffff,0xffe8007f,
+ 0xffffffff,0x7f45ffff,0xffffffff,0xffffffff,0x3fa06fff,0x7ffcc2ff,
+ 0x3ffffa07,0xffffffff,0x64002fff,0x03ffffff,0xfffff500,0x3fffffa0,
+ 0xffffffff,0xd00002df,0x3fffffff,0x3ffffa00,0x9ffffe23,0x3a7ffff9,
+ 0x3f23ffff,0xffffcfff,0x5bfffee4,0xfffffffe,0x001fffff,0x3ffffffa,
+ 0xffffffff,0x7fffff45,0xffffffff,0x6fffffff,0x507fffe0,0x7f40dfff,
+ 0xffffffff,0x02ffffff,0xfffffb10,0x7ec0007f,0xffd04fff,0xffffffff,
+ 0x1bffffff,0xfffa8000,0x3a005fff,0x7dc3ffff,0xfff33fff,0x7ffff4ff,
+ 0x3ffffe23,0x3ee0ffff,0xfffd6fff,0xffffd5df,0x3fa001df,0xffffffff,
+ 0x745fffff,0xccceffff,0xfccccccc,0xf106ffff,0xfff70fff,0x7ffff409,
+ 0xccccccce,0xf9801ccc,0x02ffffff,0x3fffe600,0xffffd00f,0xd975555b,
+ 0x00dfffff,0xfffffd00,0x7fff4001,0xfffff83f,0x27ffff98,0x643ffffe,
+ 0x4fffffff,0xeb7fffdc,0x3f65ffff,0xd005ffff,0x555dffff,0x85555555,
+ 0x005ffffe,0x41bffffa,0xfc87fff9,0x3ffa03ff,0x200005ff,0xfffffffa,
+ 0x7fe40001,0x3ffa05ff,0x7fdc04ff,0x40003fff,0x007ffffd,0x41fffff4,
+ 0xf9cffffb,0x3ffa7fff,0x7ffc43ff,0x7dc0ffff,0xfffd6fff,0x7fffc4bf,
+ 0xffe803ff,0xfd0005ff,0x7400bfff,0xff56ffff,0xffffffff,0xffffffff,
+ 0x7fff45ff,0xf300005f,0x01bfffff,0xffff8800,0x3fffa01f,0xfffd804f,
+ 0x7ec0006f,0x74007fff,0xfd03ffff,0xffff5fff,0x1fffff4f,0x27ffffe4,
+ 0xeb7fffdc,0x7d45ffff,0x401fffff,0x005ffffe,0x0bffffd0,0xb7ffff40,
+ 0xfffffffa,0xffffffff,0x3a2fffff,0x0005ffff,0xffffff98,0xff700004,
+ 0xffe80dff,0xffb804ff,0x6c0007ff,0x4007ffff,0x503ffffe,0xfffdffff,
+ 0x7ffff4ff,0xfffff883,0x6ffffb80,0x90bffffd,0x01ffffff,0x02fffff4,
+ 0x5ffffe80,0x3ffffa00,0xffffff56,0xffffffff,0x45ffffff,0x005ffffe,
+ 0x7ffffc40,0x3e00002f,0x7402ffff,0xb804ffff,0x000fffff,0x1fffff60,
+ 0x7ffffd00,0x7ffffec0,0x3ffa7fff,0x333103ff,0x3fffee01,0x0bffffd6,
+ 0x17fffffa,0x05ffffe8,0xbffffd00,0x7ffff400,0xffd55516,0xff75559f,
+ 0x415555ff,0x005ffffe,0x7ffffec0,0x3ea00002,0xfe807fff,0xfd804fff,
+ 0x40007fff,0x007ffffd,0x01fffff4,0xfffffff3,0x7ffff4ff,0x7fdc0003,
+ 0xffffd6ff,0x3fffe60b,0xfffd03ff,0x3fa000bf,0x3a005fff,0xff06ffff,
+ 0xfff983ff,0x7ffff406,0x7ffc0005,0x400003ff,0x803ffffe,0x404ffffe,
+ 0x05fffffb,0x7fffec00,0x7fff4007,0x7ffec03f,0x3fa7ffff,0x40003fff,
+ 0xfd6ffffb,0x7dc0bfff,0xe81fffff,0x0005ffff,0x00bffffd,0x437ffff4,
+ 0x5c0ffff8,0x7f405fff,0xaaaaefff,0xaaaaaaaa,0x7fffff31,0x55555555,
+ 0xff980355,0xfe800fff,0xaaaadfff,0xfffffecb,0x7ec0003f,0x74007fff,
+ 0x4403ffff,0x7fffffff,0x00fffffa,0xdffff700,0x017ffffa,0x1ffffffb,
+ 0x05ffffe8,0xbffffd00,0x7ffff400,0x87fff986,0x7404fffc,0xffffffff,
+ 0xffffffff,0xfffff74f,0xffffffff,0xfd80bfff,0xfd004fff,0xffffffff,
+ 0xffffffff,0xffb0000d,0xfe800fff,0xfc803fff,0x3a7fffff,0x0003ffff,
+ 0xeb7fffdc,0x4405ffff,0x46ffffff,0x005ffffe,0x0bffffd0,0x37ffff40,
+ 0x6c37ffd4,0x7f402fff,0xffffffff,0xffffffff,0xffffffb4,0xffffffff,
+ 0x7fc40bff,0xfd001fff,0xffffffff,0xffffffff,0xffb00001,0xfe800fff,
+ 0xf8803fff,0x3a7fffff,0x0003ffff,0xeb7fffdc,0xa805ffff,0x24ffffff,
+ 0x005ffffe,0x0bffffd0,0x37ffff40,0x742fffdc,0x7f401fff,0xffffffff,
+ 0xffffffff,0xffffffb4,0xffffffff,0x7fe40bff,0x3fa005ff,0xffffffff,
+ 0x0cffffff,0xfffb0000,0xffe800ff,0xff7003ff,0x7ff4ffff,0x5c0003ff,
+ 0xffd6ffff,0x3f600bff,0xfd2fffff,0x2000bfff,0x005ffffe,0x21bffffa,
+ 0xff83fffc,0x7ff400ff,0xffffffff,0x4fffffff,0xfffffffb,0xffffffff,
+ 0x3ffe20bf,0x3fa002ff,0xffffffff,0x000bcdef,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0xddddd100,0x3300000b,0x44000333,0xed809999,0xdeeeeeee,0x220001ac,
+ 0x00019999,0x00000000,0x00000000,0x00000000,0x00000000,0xf5000000,
+ 0x003fffff,0x3fffaa00,0xe88000ff,0xfe84ffff,0xffffffff,0x003effff,
+ 0x03ffffe4,0xdfffdb30,0xb9500179,0x007bdffd,0x3ffb2e60,0x93000bde,
+ 0x017bdfdb,0xffedb980,0x664402cd,0x3b2a20ac,0xcc882def,0x3f6e60ac,
+ 0xdb980acf,0xb0003eff,0x09ffffff,0xfffea800,0x8000ffff,0x84fffffd,
+ 0xfffffffe,0xffffffff,0xfff9001e,0xffb100ff,0xffffffff,0xfffd5019,
+ 0x5dffffff,0x7fffe400,0x04ffffff,0x3fffff62,0x8803ffff,0xfffffffd,
+ 0xff302eff,0x3ffe69ff,0x4c4fffff,0xff54ffff,0xc8dfffff,0xefffffff,
+ 0x3ffe2000,0x0007ffff,0xffffffd5,0xa8001fff,0x84ffffff,0xfffffffe,
+ 0xffffffff,0xffc804ff,0x7f4407ff,0xffffffff,0x3fa25fff,0xffffffff,
+ 0x4c01ffff,0xfffffffe,0xf505ffff,0xffffffff,0x7d40bfff,0xffffffff,
+ 0xf985ffff,0xfff9efff,0x3fffffff,0x27bfffe6,0xffffffff,0xfffff95f,
+ 0x400dffff,0xfffffffb,0x3fae002f,0xffffffff,0x3e2000ff,0x84ffffff,
+ 0xeefffffe,0xffffffee,0x7e403fff,0x7e407fff,0xffffffff,0x7ec1ffff,
+ 0xffffffff,0x2206ffff,0xffffffff,0x881fffff,0xffffffff,0x82ffffff,
+ 0xfffffff8,0xffffffff,0x7ffffcc4,0xffffffff,0xff30ffff,0xffffffff,
+ 0xfbffffff,0xffffffff,0x3fa005ff,0x5fffffff,0xfffff500,0xffffffff,
+ 0x7fff4001,0xfe84ffff,0xd5105fff,0x81ffffff,0xffffecc9,0x3a0ccccf,
+ 0x99bfffff,0xf885fdb9,0xeca9abef,0xb02fffff,0x9bffffff,0x360df975,
+ 0x52dfffff,0x81fffffb,0xaefffffd,0xfffffca9,0x3fffe61f,0xfc9acfff,
+ 0xf33fffff,0x59ffffff,0xfffffff7,0xfff759ff,0xf300dfff,0xffff5fff,
+ 0x3ffa001f,0xfffdefff,0xff9000ff,0x09ffffff,0x00bffffd,0x8bfffff9,
+ 0xfffffffb,0xf11fffff,0x4c07ffff,0xff805701,0xffa84fff,0x0202ffff,
+ 0x07ffffea,0x517fffec,0x209fffff,0x26fffff9,0x3ffffff9,0x4fffff98,
+ 0x5ffffff3,0xffffffd0,0xffffff03,0x1ffff900,0x005ffffb,0x5cffffea,
+ 0x800fffff,0xfffffffa,0xfffe84ff,0xfffd005f,0x7ffdc5ff,0xffffffff,
+ 0xfffff11f,0x64000007,0xfd85ffff,0x8001ffff,0x206ffffd,0x364ffffa,
+ 0x6407ffff,0xf30fffff,0x7c0dffff,0xff35ffff,0x3f20bfff,0xf905ffff,
+ 0xff00ffff,0x3ffeabff,0x0ffa005f,0x01fffff7,0xdfffff88,0xfe84ffff,
+ 0xf5005fff,0x7dcbffff,0xffffffff,0x3ffe1fff,0x0000cfff,0x6ffffa80,
+ 0x05ffffe8,0x5ffffd00,0x2ffffc40,0x809fffff,0x32fffff9,0x407fffff,
+ 0xf36ffffd,0x2a05ffff,0x502fffff,0x401fffff,0xf13ffffa,0x2001ffff,
+ 0xfffff700,0xffffd801,0x84ffffbb,0x005ffffe,0x99fffffa,0xfffffecc,
+ 0x3ee0cccc,0xceffffff,0x332a2001,0xffffeeee,0x7ffffc46,0xfff88003,
+ 0xeeeeeeff,0x16ffffee,0x007fffff,0x267fffff,0x202fffff,0xf36ffffc,
+ 0x2603ffff,0x501fffff,0x401fffff,0x360ffffd,0x0003ffff,0x07ffffdc,
+ 0x2dffff70,0xe84ffffb,0x2005ffff,0x80fffffc,0x807ffffc,0xfffffffd,
+ 0x32202eff,0xffffffff,0x7cc6ffff,0x8002ffff,0xfffffff9,0xffffffff,
+ 0xffff36ff,0xffff005f,0x3fffe69f,0x3fff201f,0xfffff36f,0x3fffe603,
+ 0xffff500f,0x3ffe201f,0x7fffdc6f,0x7fdc0006,0xff300fff,0x3fee1fff,
+ 0xfffe84ff,0x3ff2005f,0xffc81fff,0xfb3007ff,0xffffffff,0xfffff109,
+ 0xffffffff,0xffffa8df,0xff98001f,0xffffffff,0x6fffffff,0x03fffff5,
+ 0x2bffffd0,0x01fffff9,0x4dbffff2,0x301fffff,0x201fffff,0x00fffffa,
+ 0x887ffff7,0x001fffff,0x3ffffee0,0xffffe880,0x13fffee2,0x017ffffa,
+ 0x2fffffb8,0x07ffffc8,0x7fffecc0,0x3a23ffff,0xabdfffff,0x46ffffca,
+ 0x02fffff8,0xfffff880,0xaaaaaaab,0xff11aaaa,0xff005fff,0x3fe69fff,
+ 0x3f201fff,0xfff36fff,0x3fe603ff,0xff500fff,0x3fa01fff,0xffe81fff,
+ 0x2e0004ff,0xd80fffff,0x7dc5ffff,0xffe84fff,0x3ea005ff,0xfc83ffff,
+ 0x20007fff,0x7fffffd9,0x07ffffea,0x21bfffea,0x004fffff,0x03fffff0,
+ 0x7ffffc00,0x7fffc403,0xfffff32f,0x7fffe403,0x3fffff36,0x3ffffe60,
+ 0xfffff500,0xfffff101,0x1ffffee0,0xffffb800,0x7fffd40f,0x7fffdc0e,
+ 0x5ffffe84,0x3fffea00,0xffffc83f,0xffc80007,0xfff70fff,0x3fff20bf,
+ 0xffffe86f,0xfffd0007,0x7f40009f,0x7d406fff,0xff31ffff,0x7e403fff,
+ 0xfff36fff,0x3fe603ff,0xff500fff,0xff701fff,0x3fe609ff,0x70002fff,
+ 0x441fffff,0xb81fffff,0xfe84ffff,0x2e005fff,0xc81fffff,0x2807ffff,
+ 0x7ffffd40,0x09ffffb0,0x21bffffe,0x04fffffc,0xfffffc80,0xfff90001,
+ 0x7ff403ff,0x3ffe67ff,0x3ff201ff,0xffff36ff,0x3ffe603f,0xfff500ff,
+ 0xfffd01ff,0xdddddddf,0x00bfffff,0x3ffffee0,0x13ffffa0,0x427fffdc,
+ 0x005ffffe,0x03fffff2,0x01fffff2,0xe8815df7,0x3f27ffff,0x2e20ffff,
+ 0x887fffff,0x9effffff,0x3e21ae60,0x303fffff,0xffff10bb,0xffe885ff,
+ 0x3fe63fff,0x3f201fff,0xfff36fff,0x3fe603ff,0xff500fff,0xff981fff,
+ 0xffffffff,0xffffffff,0xfffb8000,0xffff70ff,0xb999999f,0x999dffff,
+ 0x017ffffa,0x07ffffd8,0x40fffff9,0xdefffff8,0x5ffffffe,0x3fffffea,
+ 0xffffffcd,0x7fd43eff,0xffffffff,0xffb82fff,0xeeefffff,0xfb82ffff,
+ 0xfeffffff,0x46ffffff,0x01fffff9,0x4dbffff2,0x301fffff,0x201fffff,
+ 0x40fffffa,0xfffffffc,0xffffffff,0xb8003fff,0xf90fffff,0xffffffff,
+ 0xffffffff,0x3fffafff,0xfff1005f,0x3fee0dff,0xff900fff,0xffffffff,
+ 0xfe81ffff,0xffffffff,0x5fffffdf,0xffffffd8,0x05ffffff,0xfffffffb,
+ 0x0dffffff,0x3ffffff6,0xffffffff,0x7ffffcc1,0x3ffff201,0x3fffff36,
+ 0x3ffffe60,0xfffff500,0xffffff81,0xffffffff,0x006fffff,0x0fffffb8,
+ 0xfffffff9,0xffffffff,0x3fafffff,0xf9005fff,0x2a07ffff,0x103fffff,
+ 0xfffffffb,0x305fffff,0xffffffff,0x3ffff69f,0xfffff705,0x1fffffff,
+ 0x3ffffee0,0x4fffffff,0x3ffffee0,0x0dffffff,0x1fffff98,0x5bffff20,
+ 0x01fffff9,0x01fffff3,0x83ffffea,0xaafffffa,0xdaaaaaaa,0x000fffff,
+ 0x87ffffdc,0xfffffffc,0xffffffff,0xffd7ffff,0xff500bff,0x7cc0dfff,
+ 0x1bcfffff,0xfffffd98,0x2200cfff,0x3efffffd,0x817fff62,0xffffffd8,
+ 0x6c400cff,0xffffffff,0xffd8800d,0x02efffff,0x07ffffe6,0x36ffffc8,
+ 0x203fffff,0x00fffff9,0x41fffff5,0x005ffffd,0x07fffff3,0xfffffb80,
+ 0x99999950,0xffb99999,0x3a999dff,0x2205ffff,0x2ffffffd,0x3ffffe20,
+ 0x2201ffff,0x0009aaa9,0x30026a62,0x554c4001,0x53100009,0x44000135,
+ 0x00001aa9,0x00000000,0xffff1000,0x7ffc007f,0x7dc006ff,0x0000ffff,
+ 0xd09ffff7,0x999dffff,0xfffffdb9,0xff900bff,0x03ffffff,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0xff700000,0x64001fff,0x001fffff,
+ 0x03ffffee,0x7fffdc00,0xfffffe84,0xffffffff,0x000effff,0xfffffffd,
+ 0x00000003,0x00000000,0x00000000,0x00000000,0xd0000000,0x800dffff,
+ 0x04fffffa,0x3ffffee0,0xfff70000,0xffffd09f,0xffffffff,0x0007ffff,
+ 0x3fffffd5,0x00000000,0x00000000,0x00000000,0x00000000,0xf9800000,
+ 0x8003ffff,0x007fffff,0x03ffffee,0x7fffdc00,0xfffffe84,0xffffffff,
+ 0x880000df,0x00000019,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x03fffff9,0xfffffb00,0x3ffee005,0xf70000ff,0xffd09fff,0xdfffffff,
+ 0x00003579,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x30000000,0x44099999,0x910ccccc,0x00079999,0x00288540,
+ 0x33332e00,0xcccc9804,0x9999971c,0x66640000,0x999933cc,0x6664c059,
+ 0x999950cc,0x99999999,0x50019999,0x91005555,0xdb881599,0x33332005,
+ 0xdddd1004,0x3bba209d,0x3bbba604,0x7fffdc04,0x3fffe207,0xfffff11f,
+ 0xeb88000d,0x017df31f,0xffffb800,0x7ffe401f,0xffff70ff,0x2666203f,
+ 0xffff1009,0x7fffec7f,0xffffd00f,0x7ffffe4b,0xffffffff,0xfe801fff,
+ 0xff9806ff,0xfffd34ff,0x3ffea00f,0xff8802ff,0xff106fff,0x7ffd40bf,
+ 0x7ffdc06f,0x3ffe207f,0xffff11ff,0x322000df,0xff31ffff,0x200019ff,
+ 0x04fffff8,0x32fffff4,0x207fffff,0x506ffffb,0x443fffff,0xb85fffff,
+ 0x320effff,0xffffffff,0xffffffff,0x6fffe801,0x6ffff980,0x00fffffd,
+ 0x1bfffffa,0x3ffffe20,0x09fff026,0x02ffffcc,0x81ffffee,0x11fffff8,
+ 0x00dfffff,0xfffffda8,0xfffff31f,0xfb0005bf,0x7c40dfff,0x7f42ffff,
+ 0xffd04fff,0xff701fff,0xfff50dff,0x7ffc45ff,0x7ffe41ff,0xffffffff,
+ 0x801fffff,0x9806fffe,0xffbeffff,0xfa807fff,0x02ffffff,0x37ffffc4,
+ 0x4bffe1bd,0x3ffe63ea,0x7ffdc05f,0x3ffe207f,0xffff11ff,0xfd7100df,
+ 0x3fffffff,0x3fffffe6,0x5000beff,0x201fffff,0xc87ffffb,0xf886ffff,
+ 0xd83fffff,0xfb04ffff,0x7fe4dfff,0xccca84ff,0xfdcccccc,0x800effff,
+ 0x9806fffe,0xffffffff,0xfe806fff,0x06ffffff,0xafffffc4,0xffecfff9,
+ 0x3e66ffec,0x7dc05fff,0x3e207fff,0xff11ffff,0x6440dfff,0xffffffff,
+ 0x3ff623ef,0xffffffff,0xffff800c,0xffffb03f,0xfffff309,0xfffffa81,
+ 0xfffff85f,0xfffff101,0x0dffff37,0x7fffc400,0xffd000ef,0xfff300df,
+ 0x013dffff,0x3bfffea0,0x2202ffff,0xf94fffff,0xffffffff,0x3fe63fff,
+ 0x7fdc04ff,0x3fe207ff,0x2aaa1fff,0xffda82aa,0xcfffffff,0x3ffae201,
+ 0xdfffffff,0x3ffff201,0x1fffff05,0x07ffffe0,0xfffffff9,0x07ffff88,
+ 0x77ffffd4,0x0000ffff,0x1fffffd1,0x37fff400,0x7ffffcc0,0xffe8004f,
+ 0x6ffff8ff,0x73fff880,0xfffffffb,0x3e23bfff,0x7dc04fff,0x3e207fff,
+ 0x2001ffff,0xffffffeb,0x4000beff,0xffffffc9,0xf983efff,0xffa87fff,
+ 0x3ff606ff,0x7fffc3ff,0x3ea1ffff,0xfc804fff,0x3fffffff,0xfffd1000,
+ 0xfe8003ff,0xff9806ff,0x4000ffff,0xf94ffffa,0xf9805fff,0x7fd443ff,
+ 0xf881dfff,0x7dc04fff,0x3e207fff,0x3001ffff,0xffffffff,0x51000039,
+ 0xfffffffd,0xffffd03f,0x2ffffc85,0x97fffea0,0xffddfff9,0x3fffee3f,
+ 0xfffe8802,0x20005fff,0x01fffffd,0xfffffff9,0xffffffff,0x3ffe6bff,
+ 0xfe8004ff,0xfff30fff,0xfffb80df,0xfffffc82,0xffff881f,0x7fffdc03,
+ 0x3fffe207,0xfff3001f,0x00005bff,0x7fffe4c0,0xfffb81ff,0x7ffffc4f,
+ 0x3fffe200,0x2efffee7,0x3ff65fff,0x3fe6007f,0x0000ffff,0x05fffffb,
+ 0x7fffffe4,0xffffffff,0xfff35fff,0xfa8007ff,0x7ff45fff,0x3ff602ff,
+ 0x6fffdc0f,0xff80ffff,0x7fdc03ff,0x3fe207ff,0xf3001fff,0x017dffff,
+ 0x7ecc0000,0xf881ffff,0x3fe66fff,0xffd804ff,0x1fffb0ff,0x7fcffff1,
+ 0x3e6005ff,0x001fffff,0x2fffffc8,0x7ffffe40,0xffffffff,0xff35ffff,
+ 0xe8005fff,0x7dc2ffff,0xff106fff,0xffffb8bf,0x40efffb8,0x5c009999,
+ 0x2607ffff,0x001fffff,0xfffffff3,0x200005bf,0xfffffeb8,0xfffb01ff,
+ 0x3fffee3f,0xffffb801,0x7f4dfff2,0xffff89ff,0x3fffa003,0x2000efff,
+ 0x03fffffb,0xffffffc8,0xffffffff,0xfff35fff,0x7d4003ff,0xfff06fff,
+ 0xfff705ff,0x22fffd85,0x0002fffe,0x07ffffdc,0x1fffffb8,0x3fffee00,
+ 0x0cffffff,0xfffda800,0x0cffffff,0x27ffff50,0x1006fffe,0xff59ffff,
+ 0x67ffe49f,0x000ffffa,0xfffffff9,0x3fee009f,0x31004fff,0xffd33333,
+ 0x333333ff,0x3ffffe61,0x3fffa001,0xffff903f,0x5c1faa0d,0x0077cc6f,
+ 0x7fffd400,0xffffb01f,0xfd50003f,0xffffffff,0xffb8805b,0xefffffff,
+ 0xffff800b,0x03ffff8d,0x33bfffa0,0x3fea2fff,0x06fffcef,0xfdffff50,
+ 0xa805ffff,0x004fffff,0x0dfffd00,0x3fffff30,0x3fffea00,0xffff300f,
+ 0x3300405f,0x4c000050,0x883fffff,0x11ffffff,0x409ddddd,0xffffffd9,
+ 0x2a0cffff,0xfffffffd,0x64001dff,0xfffbffff,0x3ff2000f,0x447ffeff,
+ 0xfffeffff,0xffff8803,0xfffffb9f,0xfffff300,0x7f40000b,0xff9806ff,
+ 0xfd001fff,0xfd80bfff,0x00006fff,0x3e200000,0x221effff,0x1ffffffd,
+ 0x0dfffff1,0xfffff910,0x3e63ffff,0xffffffff,0xff10000c,0x0bffffff,
+ 0xfffff980,0xfffd85ff,0xd801ffff,0x3fa4ffff,0xff985fff,0x9999efff,
+ 0x00999999,0x806fffe8,0x01fffff9,0x1fffffa8,0x7ffffd40,0x00000001,
+ 0x3ffffa00,0xffffefff,0xff11ffff,0xa800dfff,0x1ffffffe,0xdffffff3,
+ 0x3f600007,0x02ffffff,0xffffff80,0xffffb83f,0xffb806ff,0x3fe60eff,
+ 0x7ff43fff,0xffffffff,0x02ffffff,0x806fffe8,0x01fffff9,0x01999988,
+ 0x01333330,0x00000000,0x7fffffd4,0xffedffff,0xffff11ff,0x366000df,
+ 0xff31ffff,0x00003bff,0xffffffa8,0xfff90007,0xff301fff,0x9809ffff,
+ 0xc82fffff,0x3a0fffff,0xffffffff,0xffffffff,0x6fffe802,0xfffff980,
+ 0x00000001,0x00000000,0xfffffd80,0xfffb5fff,0x3fffe23f,0x6440006f,
+ 0x19ff31ff,0x7fc00000,0x0004ffff,0x0dfffff5,0x0ffffffc,0x17ffffa0,
+ 0x37ffffc4,0xfffffffd,0xffffffff,0xfffd005f,0xffff300d,0x0000003f,
+ 0x00000000,0x3ffee000,0xfd30dfff,0x3ffe23ff,0x200006ff,0x0000710a,
+ 0x3ffff200,0xff10001f,0x7e409fff,0x7e407fff,0x2a00ffff,0xfd4fffff,
+ 0xffffffff,0x5fffffff,0x05555500,0x3fffff30,0x00000000,0x00000000,
+ 0x00554c40,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0xaaaaaa88,0xaaaaaaaa,0xddd30aaa,
+ 0x7777649d,0x0aaaaaa1,0x0b37b2a0,0x22bdddd0,0x515eeeee,0x55555555,
+ 0x3bba1555,0xeeeeeeee,0xeeeeeeee,0x00000001,0x00000000,0x00000000,
+ 0x00000000,0x3fe20000,0xffffffff,0x0fffffff,0x74dffff5,0x3ee2ffff,
+ 0xd102ffff,0x3dffffff,0x2dffff10,0x76fffff8,0xffffffff,0x3fe3ffff,
+ 0xffffffff,0xffffffff,0x0000002f,0x00000000,0x00000000,0x00000000,
+ 0x3e200000,0xffffffff,0xffffffff,0x4bffff30,0x6c1ffffd,0xfd06ffff,
+ 0xffffffff,0x5ffff989,0x2dfffff1,0xfffffffb,0xff1fffff,0xffffffff,
+ 0xffffffff,0x0000005f,0x00000000,0x00000000,0x00000000,0x7c400000,
+ 0xffffffff,0xffffffff,0x4bffff30,0x441ffffd,0x543fffff,0xffffffff,
+ 0xfebbefff,0xfff14fff,0x3ffeedff,0xffffffff,0xffffff1f,0xffffffff,
+ 0x005fffff,0x00000000,0x00000000,0x00000000,0x00000000,0x77777440,
+ 0xeeeeeeee,0xff30eeee,0x7ffecbff,0xffffa81f,0x7ffffe47,0xffffffcb,
+ 0x12ffffff,0x2edfffff,0xffffffff,0x1111ffff,0x11111111,0x11111111,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x24ffff98,
+ 0x900ffffc,0x7ec7ffff,0x3f621fff,0xffffffff,0x3ffffe26,0x22222226,
+ 0x00088888,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0xfff88000,0x3ffff24f,0x3ffffa00,0x01ffffd0,0xffffffd5,0x0000003d,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xf8800000,
+ 0x3ff24fff,0x266200ff,0xddddb099,0x3deeca80,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0xfff10000,0x3fffe47f,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x88000000,0xeeeeeeee,0xeeeeeeee,0x8ffffe0e,0x0007fffb,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0xfff10000,
+ 0xffffffff,0x41ffffff,0x26209999,0x00000199,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0xfffff100,0xffffffff,
+ 0x0001ffff,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x80000000,0xfffffff8,0xffffffff,0x000000ff,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x54400000,
+ 0xaaaaaaaa,0xaaaaaaaa,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+};
+
+static signed short stb__intelclearbd_x[95]={ 0,2,1,0,1,1,1,1,1,0,1,2,1,1,
+1,0,0,2,2,1,1,1,1,1,1,1,1,1,2,2,2,0,1,0,3,2,3,3,3,2,3,3,0,3,
+3,3,3,1,3,1,3,1,0,2,0,0,0,0,1,3,0,0,1,0,4,1,2,1,1,1,0,1,2,2,
+-1,2,2,2,2,1,2,1,2,1,0,2,0,0,0,0,1,0,3,0,1, };
+static signed short stb__intelclearbd_y[95]={ 38,11,11,11,7,11,10,11,9,9,11,15,32,25,
+32,9,11,11,11,11,11,11,11,11,11,11,18,18,15,18,15,10,11,11,11,10,11,11,11,10,11,11,11,11,
+11,11,11,10,11,10,11,10,11,11,11,11,11,11,11,9,9,9,11,42,8,17,10,17,10,17,10,17,10,10,
+10,10,10,17,17,17,17,17,18,17,13,18,18,18,18,18,18,9,9,9,21, };
+static unsigned short stb__intelclearbd_w[95]={ 0,7,14,23,21,35,26,6,12,11,14,19,7,14,
+7,17,23,15,18,20,21,20,21,20,21,21,7,7,19,19,19,18,36,26,21,22,23,19,18,23,22,6,18,23,
+18,27,23,28,20,28,22,21,24,24,26,38,26,25,22,11,17,11,21,20,11,19,21,18,21,19,14,21,19,7,
+10,20,9,31,19,21,21,21,14,17,14,19,21,30,20,21,18,15,7,15,21, };
+static unsigned short stb__intelclearbd_h[95]={ 0,27,11,27,36,28,29,11,36,36,14,20,14,6,
+6,36,28,27,27,28,27,28,28,27,28,28,20,28,20,14,20,28,36,27,27,29,27,27,27,29,27,27,28,27,
+27,27,27,29,27,33,27,29,27,28,27,27,27,27,27,36,36,36,17,5,8,22,29,22,29,22,28,30,28,28,
+37,28,29,21,21,22,30,30,20,22,26,21,20,20,20,29,20,36,38,36,8, };
+static unsigned short stb__intelclearbd_s[95]={ 255,248,41,145,36,163,219,242,74,87,227,
+162,219,98,90,99,1,28,189,220,44,60,81,208,103,1,21,246,29,21,49,
+144,117,1,229,150,66,169,103,173,122,241,125,79,233,51,27,67,212,196,166,
+106,114,23,87,48,139,1,189,184,166,154,197,113,56,123,128,143,197,162,25,
+225,40,247,9,199,96,224,204,182,23,1,182,105,90,1,69,91,122,45,143,
+58,1,20,68, };
+static unsigned short stb__intelclearbd_t[95]={ 1,71,206,129,1,71,40,185,1,1,185,
+185,185,206,206,1,71,157,129,71,157,71,71,129,71,100,185,40,185,206,185,
+71,1,157,129,40,157,129,129,40,129,71,71,129,100,129,129,40,100,1,100,
+40,100,100,100,100,100,129,100,1,1,1,185,206,206,157,40,157,40,157,71,
+1,71,1,1,71,40,157,157,157,40,40,185,157,157,185,185,185,185,40,185,
+1,1,1,206, };
+static unsigned short stb__intelclearbd_a[95]={ 151,180,256,368,368,597,422,136,
+200,200,249,368,155,253,155,262,368,368,368,368,368,368,368,368,
+368,368,155,155,368,368,368,300,609,413,393,393,439,367,346,433,
+447,190,327,411,340,528,451,479,390,479,395,379,386,448,412,600,
+406,391,378,222,262,222,368,310,310,330,385,305,385,344,219,352,
+376,175,175,351,196,557,376,375,385,385,242,300,226,368,329,480,
+319,329,311,242,213,242,368, };
+
+// Call this function with
+// font: NULL or array length
+// data: NULL or specified size
+// height: STB_FONT_intelclearbd_BITMAP_HEIGHT or STB_FONT_intelclearbd_BITMAP_HEIGHT_POW2
+// return value: spacing between lines
+static void stb_font_intelclearbd(stb_fontchar font[STB_FONT_intelclearbd_NUM_CHARS],
+ unsigned char data[STB_FONT_intelclearbd_BITMAP_HEIGHT][STB_FONT_intelclearbd_BITMAP_WIDTH],
+ int height)
+{
+ int i,j;
+ if (data != 0) {
+ unsigned int *bits = stb__intelclearbd_pixels;
+ unsigned int bitpack = *bits++, numbits = 32;
+ for (i=0; i < STB_FONT_intelclearbd_BITMAP_WIDTH*height; ++i)
+ data[0][i] = 0; // zero entire bitmap
+ for (j=1; j < STB_FONT_intelclearbd_BITMAP_HEIGHT-1; ++j) {
+ for (i=1; i < STB_FONT_intelclearbd_BITMAP_WIDTH-1; ++i) {
+ unsigned int value;
+ if (numbits==0) bitpack = *bits++, numbits=32;
+ value = bitpack & 1;
+ bitpack >>= 1, --numbits;
+ if (value) {
+ if (numbits < 3) bitpack = *bits++, numbits = 32;
+ data[j][i] = (bitpack & 7) * 0x20 + 0x1f;
+ bitpack >>= 3, numbits -= 3;
+ } else {
+ data[j][i] = 0;
+ }
+ }
+ }
+ }
+
+ // build font description
+ if (font != 0) {
+ float recip_width = 1.0f / STB_FONT_intelclearbd_BITMAP_WIDTH;
+ float recip_height = 1.0f / height;
+ for (i=0; i < STB_FONT_intelclearbd_NUM_CHARS; ++i) {
+ // pad characters so they bilerp from empty space around each character
+ font[i].s0 = (stb__intelclearbd_s[i]) * recip_width;
+ font[i].t0 = (stb__intelclearbd_t[i]) * recip_height;
+ font[i].s1 = (stb__intelclearbd_s[i] + stb__intelclearbd_w[i]) * recip_width;
+ font[i].t1 = (stb__intelclearbd_t[i] + stb__intelclearbd_h[i]) * recip_height;
+ font[i].x0 = stb__intelclearbd_x[i];
+ font[i].y0 = stb__intelclearbd_y[i];
+ font[i].x1 = stb__intelclearbd_x[i] + stb__intelclearbd_w[i];
+ font[i].y1 = stb__intelclearbd_y[i] + stb__intelclearbd_h[i];
+ font[i].advance_int = (stb__intelclearbd_a[i]+8)>>4;
+ font[i].s0f = (stb__intelclearbd_s[i] - 0.5f) * recip_width;
+ font[i].t0f = (stb__intelclearbd_t[i] - 0.5f) * recip_height;
+ font[i].s1f = (stb__intelclearbd_s[i] + stb__intelclearbd_w[i] + 0.5f) * recip_width;
+ font[i].t1f = (stb__intelclearbd_t[i] + stb__intelclearbd_h[i] + 0.5f) * recip_height;
+ font[i].x0f = stb__intelclearbd_x[i] - 0.5f;
+ font[i].y0f = stb__intelclearbd_y[i] - 0.5f;
+ font[i].x1f = stb__intelclearbd_x[i] + stb__intelclearbd_w[i] + 0.5f;
+ font[i].y1f = stb__intelclearbd_y[i] + stb__intelclearbd_h[i] + 0.5f;
+ font[i].advance = stb__intelclearbd_a[i]/16.0f;
+ }
+ }
+}
+
+#ifndef STB_SOMEFONT_CREATE
+#define STB_SOMEFONT_CREATE stb_font_intelclearbd
+#define STB_SOMEFONT_BITMAP_WIDTH STB_FONT_intelclearbd_BITMAP_WIDTH
+#define STB_SOMEFONT_BITMAP_HEIGHT STB_FONT_intelclearbd_BITMAP_HEIGHT
+#define STB_SOMEFONT_BITMAP_HEIGHT_POW2 STB_FONT_intelclearbd_BITMAP_HEIGHT_POW2
+#define STB_SOMEFONT_FIRST_CHAR STB_FONT_intelclearbd_FIRST_CHAR
+#define STB_SOMEFONT_NUM_CHARS STB_FONT_intelclearbd_NUM_CHARS
+#define STB_SOMEFONT_LINE_SPACING STB_FONT_intelclearbd_LINE_SPACING
+#endif
+
diff --git a/Projects/Asteroids/src/mesh.cpp b/Projects/Asteroids/src/mesh.cpp
new file mode 100644
index 0000000..bef24b6
--- /dev/null
+++ b/Projects/Asteroids/src/mesh.cpp
@@ -0,0 +1,352 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#include "mesh.h"
+#include "noise.h"
+#include <map>
+#include <random>
+
+using namespace DirectX;
+
+void CreateIcosahedron(Mesh *outMesh)
+{
+ static const float a = std::sqrt(2.0f / (5.0f - std::sqrt(5.0f)));
+ static const float b = std::sqrt(2.0f / (5.0f + std::sqrt(5.0f)));
+
+ static const size_t num_vertices = 12;
+ static const Vertex vertices[num_vertices] = // x, y, z
+ {
+ {-b, a, 0},
+ { b, a, 0},
+ {-b, -a, 0},
+ { b, -a, 0},
+ { 0, -b, a},
+ { 0, b, a},
+ { 0, -b, -a},
+ { 0, b, -a},
+ { a, 0, -b},
+ { a, 0, b},
+ {-a, 0, -b},
+ {-a, 0, b},
+ };
+
+ static const size_t num_triangles = 20;
+ static const IndexType indices[num_triangles*3] =
+ {
+ 0, 5, 11,
+ 0, 1, 5,
+ 0, 7, 1,
+ 0, 10, 7,
+ 0, 11, 10,
+ 1, 9, 5,
+ 5, 4, 11,
+ 11, 2, 10,
+ 10, 6, 7,
+ 7, 8, 1,
+ 3, 4, 9,
+ 3, 2, 4,
+ 3, 6, 2,
+ 3, 8, 6,
+ 3, 9, 8,
+ 4, 5, 9,
+ 2, 11, 4,
+ 6, 10, 2,
+ 8, 7, 6,
+ 9, 1, 8,
+ };
+
+ outMesh->clear();
+ outMesh->vertices.insert(outMesh->vertices.end(), vertices, vertices + num_vertices);
+ outMesh->indices.insert(outMesh->indices.end(), indices, indices + num_triangles*3);
+}
+
+
+// Maps edge (lower index first!) to
+struct Edge
+{
+ Edge(IndexType i0, IndexType i1)
+ : v0(i0), v1(i1)
+ {
+ if (v0 > v1)
+ std::swap(v0, v1);
+ }
+ IndexType v0;
+ IndexType v1;
+
+ bool operator<(const Edge &c) const
+ {
+ return v0 < c.v0 || (v0 == c.v0 && v1 < c.v1);
+ }
+};
+
+typedef std::map<Edge, IndexType> MidpointMap;
+
+inline IndexType EdgeMidpoint(Mesh *mesh, MidpointMap *midpoints, Edge e)
+{
+ auto index = midpoints->find(e);
+ if (index == midpoints->end())
+ {
+ auto a = mesh->vertices[e.v0];
+ auto b = mesh->vertices[e.v1];
+
+ Vertex m;
+ m.x = (a.x + b.x) * 0.5f;
+ m.y = (a.y + b.y) * 0.5f;
+ m.z = (a.z + b.z) * 0.5f;
+
+ index = midpoints->insert(std::make_pair(e, static_cast<IndexType>(mesh->vertices.size()))).first;
+ mesh->vertices.push_back(m);
+ }
+ return index->second;
+}
+
+
+void SubdivideInPlace(Mesh *outMesh)
+{
+ MidpointMap midpoints;
+
+ std::vector<IndexType> newIndices;
+ newIndices.reserve(outMesh->indices.size() * 4);
+ outMesh->vertices.reserve(outMesh->vertices.size() * 2);
+
+ assert(outMesh->indices.size() % 3 == 0); // trilist
+ size_t triangles = outMesh->indices.size() / 3;
+ for (size_t t = 0; t < triangles; ++t)
+ {
+ auto t0 = outMesh->indices[t*3+0];
+ auto t1 = outMesh->indices[t*3+1];
+ auto t2 = outMesh->indices[t*3+2];
+
+ auto m0 = EdgeMidpoint(outMesh, &midpoints, Edge(t0, t1));
+ auto m1 = EdgeMidpoint(outMesh, &midpoints, Edge(t1, t2));
+ auto m2 = EdgeMidpoint(outMesh, &midpoints, Edge(t2, t0));
+
+ IndexType indices[] = {
+ t0, m0, m2,
+ m0, t1, m1,
+ m0, m1, m2,
+ m2, m1, t2,
+ };
+ newIndices.insert(newIndices.end(), indices, indices + 4*3);
+ }
+
+ std::swap(outMesh->indices, newIndices); // Constant time
+}
+
+
+void SpherifyInPlace(Mesh *outMesh, float radius)
+{
+ for (auto &v : outMesh->vertices) {
+ float n = radius / std::sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
+ v.x *= n;
+ v.y *= n;
+ v.z *= n;
+ }
+}
+
+
+void ComputeAvgNormalsInPlace(Mesh *outMesh)
+{
+ for (auto &v : outMesh->vertices) {
+ v.nx = 0.0f;
+ v.ny = 0.0f;
+ v.nz = 0.0f;
+ }
+
+ assert(outMesh->indices.size() % 3 == 0); // trilist
+ size_t triangles = outMesh->indices.size() / 3;
+ for (size_t t = 0; t < triangles; ++t)
+ {
+ auto v1 = &outMesh->vertices[outMesh->indices[t*3+0]];
+ auto v2 = &outMesh->vertices[outMesh->indices[t*3+1]];
+ auto v3 = &outMesh->vertices[outMesh->indices[t*3+2]];
+
+ // Two edge vectors u,v
+ auto ux = v2->x - v1->x;
+ auto uy = v2->y - v1->y;
+ auto uz = v2->z - v1->z;
+ auto vx = v3->x - v1->x;
+ auto vy = v3->y - v1->y;
+ auto vz = v3->z - v1->z;
+
+ // cross(u,v)
+ float nx = uy*vz - uz*vy;
+ float ny = uz*vx - ux*vz;
+ float nz = ux*vy - uy*vx;
+
+ // Do not normalize... weight average by contributing face area
+ v1->nx += nx; v1->ny += ny; v1->nz += nz;
+ v2->nx += nx; v2->ny += ny; v2->nz += nz;
+ v3->nx += nx; v3->ny += ny; v3->nz += nz;
+ }
+
+ // Normalize
+ for (auto &v : outMesh->vertices) {
+ float n = 1.0f / std::sqrt(v.nx*v.nx + v.ny*v.ny + v.nz*v.nz);
+ v.nx *= n;
+ v.ny *= n;
+ v.nz *= n;
+ }
+}
+
+
+void CreateGeospheres(Mesh *outMesh, unsigned int subdivLevelCount, unsigned int* outSubdivIndexOffsets)
+{
+ CreateIcosahedron(outMesh);
+ outSubdivIndexOffsets[0] = 0;
+
+ std::vector<Vertex> vertices(outMesh->vertices);
+ std::vector<IndexType> indices(outMesh->indices);
+
+ for (unsigned int i = 0; i < subdivLevelCount; ++i) {
+ outSubdivIndexOffsets[i+1] = (unsigned int)indices.size();
+ SubdivideInPlace(outMesh);
+
+ // Ensure we add the proper offset to the indices from this subdiv level for the combined mesh
+ // This avoids also needing to track a base vertex index for each subdiv level
+ IndexType vertexOffset = (IndexType)vertices.size();
+ vertices.insert(vertices.end(), outMesh->vertices.begin(), outMesh->vertices.end());
+
+ for (auto newIndex : outMesh->indices) {
+ indices.push_back(newIndex + vertexOffset);
+ }
+ }
+ outSubdivIndexOffsets[subdivLevelCount+1] = (unsigned int)indices.size();
+
+ SpherifyInPlace(outMesh);
+
+ // Put the union of vertices/indices back into the mesh object
+ std::swap(outMesh->indices, indices);
+ std::swap(outMesh->vertices, vertices);
+}
+
+
+void CreateAsteroidsFromGeospheres(Mesh *outMesh,
+ unsigned int subdivLevelCount, unsigned int meshInstanceCount,
+ unsigned int rngSeed,
+ unsigned int* outSubdivIndexOffsets, unsigned int* vertexCountPerMesh)
+{
+ assert(subdivLevelCount <= meshInstanceCount);
+
+ std::mt19937 rng(rngSeed);
+
+ Mesh baseMesh;
+ CreateGeospheres(&baseMesh, subdivLevelCount, outSubdivIndexOffsets);
+
+ // Per unique mesh
+ *vertexCountPerMesh = (unsigned int)baseMesh.vertices.size();
+ std::vector<Vertex> vertices;
+ vertices.reserve(meshInstanceCount * baseMesh.vertices.size());
+ // Reuse indices for the different unique meshes
+
+ auto randomNoise = std::uniform_real_distribution<float>(0.0f, 10000.0f);
+ auto randomPersistence = std::normal_distribution<float>(0.95f, 0.04f);
+ float noiseScale = 0.5f;
+ float radiusScale = 0.9f;
+ float radiusBias = 0.3f;
+
+ // Create and randomize unique vertices for each mesh instance
+ for (unsigned int m = 0; m < meshInstanceCount; ++m) {
+ Mesh newMesh(baseMesh);
+ NoiseOctaves<4> textureNoise(randomPersistence(rng));
+ float noise = randomNoise(rng);
+
+ for (auto &v : newMesh.vertices) {
+ float radius = textureNoise(v.x*noiseScale, v.y*noiseScale, v.z*noiseScale, noise);
+ radius = radius * radiusScale + radiusBias;
+ v.x *= radius;
+ v.y *= radius;
+ v.z *= radius;
+ }
+ ComputeAvgNormalsInPlace(&newMesh);
+
+ vertices.insert(vertices.end(), newMesh.vertices.begin(), newMesh.vertices.end());
+ }
+
+ // Copy to output
+ std::swap(outMesh->indices, baseMesh.indices);
+ std::swap(outMesh->vertices, vertices);
+}
+
+
+void CreateSkyboxMesh(std::vector<SkyboxVertex>* outVertices)
+{
+ // See http://msdn.microsoft.com/en-us/library/windows/desktop/bb204881(v=vs.85).aspx
+
+ // Cube mesh centered at zero
+ static const float c = 0.5f;
+ static const DirectX::XMFLOAT3 vertexPos[] = { // x, y, z
+ {-c, c, -c}, // 0
+ { c, c, -c}, // 1
+ { c, c, c}, // 2
+ {-c, c, c}, // 3
+ {-c, -c, c}, // 4
+ { c, -c, c}, // 5
+ { c, -c, -c}, // 6
+ {-c, -c, -c}, // 7
+ };
+
+ static const size_t numIndices = 6*6;
+ static const unsigned int indices[numIndices] = {
+ 2, 6, 1, 2, 5, 6, // right (+c, ., .), face 0
+ 0, 4, 3, 0, 7, 4, // left (-c, ., .), face 1
+ 0, 2, 1, 0, 3, 2, // top ( ., +c, .), face 2
+ 4, 6, 5, 4, 7, 6, // bottom ( ., -c, .), face 3
+ 3, 5, 2, 3, 4, 5, // back ( ., ., +c), face 4
+ 1, 6, 7, 1, 7, 0, // front ( ., ., -c), face 5
+ };
+
+ // Flatten out the indexed mesh and add the per-face parameters
+ std::vector<SkyboxVertex> vertices(numIndices);
+ for (size_t i = 0; i < numIndices; ++i) {
+ auto &v = vertices[i];
+
+ v.x = vertexPos[indices[i]].x;
+ v.y = vertexPos[indices[i]].y;
+ v.z = vertexPos[indices[i]].z;
+
+ auto face = i / 6;
+ v.face = (float)face;
+
+ // Face uv's are fairly manual
+ switch (face)
+ {
+ case 0:
+ v.u = -v.z;
+ v.v = -v.y;
+ break;
+ case 1:
+ v.u = v.z;
+ v.v = -v.y;
+ break;
+ case 2:
+ v.u = v.x;
+ v.v = v.z;
+ break;
+ case 3:
+ v.u = v.x;
+ v.v = -v.z;
+ break;
+ case 4:
+ v.u = v.x;
+ v.v = -v.y;
+ break;
+ case 5:
+ v.u = -v.x;
+ v.v = -v.y;
+ break;
+ };
+ // Move to 0..1
+ v.u += 0.5f;
+ v.v += 0.5f;
+ }
+
+ std::swap(*outVertices, vertices);
+}
diff --git a/Projects/Asteroids/src/mesh.h b/Projects/Asteroids/src/mesh.h
new file mode 100644
index 0000000..4031a7e
--- /dev/null
+++ b/Projects/Asteroids/src/mesh.h
@@ -0,0 +1,74 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include <vector>
+#include <directxmath.h>
+
+typedef unsigned short IndexType;
+
+// NOTE: This data could be compressed, but it's not really the bottleneck at the moment
+struct Vertex
+{
+ float x;
+ float y;
+ float z;
+ float nx;
+ float ny;
+ float nz;
+};
+
+struct Mesh
+{
+ void clear()
+ {
+ vertices.clear();
+ indices.clear();
+ }
+
+ std::vector<Vertex> vertices;
+ std::vector<IndexType> indices;
+};
+
+void CreateIcosahedron(Mesh *outMesh);
+
+// 1 face -> 4 faces
+void SubdivideInPlace(Mesh *outMesh);
+
+void SpherifyInPlace(Mesh *outMesh, float radius = 1.0f);
+
+void ComputeAvgNormalsInPlace(Mesh *outMesh);
+
+// subdivIndexOffset array should be [subdivLevels+2] in size
+void CreateGeospheres(Mesh *outMesh, unsigned int subdivLevelCount, unsigned int* outSubdivIndexOffsets);
+
+// Returns a combined "mesh" that includes:
+// - A set of indices for each subdiv level (outSubdivIndexOffsets for offsets/counts)
+// - A set of vertices for each mesh instance (base vertices per mesh computed from vertexCountPerMesh)
+// - Indices already have the vertex offsets for the correct subdiv level "baked-in", so only need the mesh offset
+void CreateAsteroidsFromGeospheres(Mesh *outMesh,
+ unsigned int subdivLevelCount, unsigned int meshInstanceCount,
+ unsigned int rngSeed,
+ unsigned int* outSubdivIndexOffsets, unsigned int* vertexCountPerMesh);
+
+
+struct SkyboxVertex
+{
+ float x;
+ float y;
+ float z;
+ float u;
+ float v;
+ float face;
+};
+
+// Skybox mesh... vertices-only currently
+void CreateSkyboxMesh(std::vector<SkyboxVertex>* outVertices); \ No newline at end of file
diff --git a/Projects/Asteroids/src/noise.h b/Projects/Asteroids/src/noise.h
new file mode 100644
index 0000000..250ae5c
--- /dev/null
+++ b/Projects/Asteroids/src/noise.h
@@ -0,0 +1,57 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include "simplexnoise1234.h"
+
+// Very simple multi-octave simplex noise helper
+// Returns noise in the range [0, 1] vs. the usual [-1, 1]
+template <size_t N = 4>
+class NoiseOctaves
+{
+private:
+ float mWeights[N];
+ float mWeightNorm;
+
+public:
+ NoiseOctaves(float persistence = 0.5f)
+ {
+ float weightSum = 0.0f;
+ for (size_t i = 0; i < N; ++i) {
+ mWeights[i] = persistence;
+ weightSum += persistence;
+ persistence *= persistence;
+ }
+ mWeightNorm = 0.5f / weightSum; // Will normalize to [-0.5, 0.5]
+ }
+
+ // Returns [0, 1]
+ float operator()(float x, float y, float z) const
+ {
+ float r = 0.0f;
+ for (size_t i = 0; i < N; ++i) {
+ r += mWeights[i] * snoise3(x, y, z);
+ x *= 2.0f; y *= 2.0f; z *= 2.0f;
+ }
+ return r * mWeightNorm + 0.5f;
+ }
+
+ // Returns [0, 1]
+ float operator()(float x, float y, float z, float w) const
+ {
+ float r = 0.0f;
+ for (size_t i = 0; i < N; ++i) {
+ r += mWeights[i] * snoise4(x, y, z, w);
+ x *= 2.0f; y *= 2.0f; z *= 2.0f; w *= 2.0f;
+ }
+ return r * mWeightNorm + 0.5f;
+ }
+}; \ No newline at end of file
diff --git a/Projects/Asteroids/src/settings.h b/Projects/Asteroids/src/settings.h
new file mode 100644
index 0000000..d130eca
--- /dev/null
+++ b/Projects/Asteroids/src/settings.h
@@ -0,0 +1,92 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include "camera.h"
+#include "common_defines.h"
+
+// Profiling
+#define ENABLE_VTUNE_TASK_PROFILING 1
+
+// Content settings
+#ifdef _DEBUG
+enum { NUM_ASTEROIDS = 2000 };
+#else
+enum { NUM_ASTEROIDS = 50000 };
+#endif
+enum { TEXTURE_DIM = 256 }; // Req'd to be pow2 at the moment
+enum { TEXTURE_ANISO = 2 };
+enum { NUM_UNIQUE_MESHES = 1000 };
+enum { MESH_MAX_SUBDIV_LEVELS = 3 }; // 4x polys for each step.
+// See common_defines.h for NUM_UNIQUE_TEXTURES (also needed by shader now)
+
+#define SIM_ORBIT_RADIUS 450.f
+#define SIM_DISC_RADIUS 120.f
+#define SIM_MIN_SCALE 0.2f
+
+// In FLIP swap chains the compositor owns one of your buffers at any given point
+// Thus to run unconstrained (>vsync) frame rates, you need 3 buffers
+enum { NUM_SWAP_CHAIN_BUFFERS = 5 };
+
+// In D3D12, this is the pipeline depth in frames - larger = more latency, shorter = potential bubbles.
+// Usually 2-4 are good values.
+enum { NUM_FRAMES_TO_BUFFER = 3 };
+
+// In D3D12 this is the number of command buffers we generate for the main scene rendering
+// Also effectively max thread parallelism
+enum { NUM_SUBSETS = 4 };
+
+// Buffer size for dynamic sprite data
+enum { MAX_SPRITE_VERTICES_PER_FRAME = 6 * 1024 };
+
+
+// This structure is often copied/passed by value so don't put anything really expensive in it.
+struct Settings
+{
+ double closeAfterSeconds = 0.0;
+
+ // Will be scaled based on DPI at app start for convenience
+ double renderScale = 1.0; // 1.0 = window dimensions, <1 = upscaling, >1 = supersampling
+ int windowWidth = 1080;
+ int windowHeight = 720;
+ int renderWidth;
+ int renderHeight;
+
+ int numThreads = 0; // 0 means #cpu-1
+ unsigned int lockedFrameRate = 15;
+
+ bool logFrameTimes = false;
+ bool vsync = 0;
+
+ bool windowed = true;
+ enum RenderMode
+ {
+ NativeD3D11,
+ NativeD3D12,
+ DiligentD3D11,
+ DiligentD3D12,
+ DiligentGL
+ }mode = DiligentD3D11;
+
+ bool lockFrameRate = false;
+ bool animate = true;
+
+ // Multithreading actually makes debugging annoying so disable by default
+#if defined(_DEBUG)
+ bool multithreadedRendering = true;
+#else
+ bool multithreadedRendering = true;
+#endif
+
+ bool submitRendering = true;
+ bool executeIndirect = false;
+ bool warp = false;
+};
diff --git a/Projects/Asteroids/src/simplexnoise1234.c b/Projects/Asteroids/src/simplexnoise1234.c
new file mode 100644
index 0000000..a0f0814
--- /dev/null
+++ b/Projects/Asteroids/src/simplexnoise1234.c
@@ -0,0 +1,499 @@
+/* SimplexNoise1234, Simplex noise with true analytic
+ * derivative in 1D to 4D.
+ *
+ * Author: Stefan Gustavson, 2003-2005
+ * Contact: stegu@itn.liu.se
+ */
+
+ /*
+This code was GPL licensed until February 2011.
+As the original author of this code, I hereby
+release it irrevocably into the public domain.
+Please feel free to use it for whatever you want.
+Credit is appreciated where appropriate, and I also
+appreciate being told where this code finds any use,
+but you may do as you like. Alternatively, if you want
+to have a familiar OSI-approved license, you may use
+This code under the terms of the MIT license:
+
+Copyright (C) 2003-2005 by Stefan Gustavson. All rights reserved.
+This code is licensed to you under the terms of the MIT license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/** \file
+ \brief C implementation of Perlin Simplex Noise over 1,2,3, and 4 dimensions.
+ \author Stefan Gustavson (stegu@itn.liu.se)
+*/
+
+/*
+ * This implementation is "Simplex Noise" as presented by
+ * Ken Perlin at a relatively obscure and not often cited course
+ * session "Real-Time Shading" at Siggraph 2001 (before real
+ * time shading actually took on), under the title "hardware noise".
+ * The 3D function is numerically equivalent to his Java reference
+ * code available in the PDF course notes, although I re-implemented
+ * it from scratch to get more readable code. The 1D, 2D and 4D cases
+ * were implemented from scratch by me from Ken Perlin's text.
+ *
+ * This file has no dependencies on any other file, not even its own
+ * header file. The header file is made for use by external code only.
+ */
+
+
+// We don't need to include this. It does no harm, but no use either.
+#include "simplexnoise1234.h"
+
+#pragma warning(disable: 4244) // conversion double -> float
+
+#define FASTFLOOR(x) ( ((x)>0) ? ((int)x) : (((int)x)-1) )
+
+//---------------------------------------------------------------------
+// Static data
+
+/*
+ * Permutation table. This is just a random jumble of all numbers 0-255,
+ * repeated twice to avoid wrapping the index at 255 for each lookup.
+ * This needs to be exactly the same for all instances on all platforms,
+ * so it's easiest to just keep it as static explicit data.
+ * This also removes the need for any initialisation of this class.
+ *
+ * Note that making this an int[] instead of a char[] might make the
+ * code run faster on platforms with a high penalty for unaligned single
+ * byte addressing. Intel x86 is generally single-byte-friendly, but
+ * some other CPUs are faster with 4-aligned reads.
+ * However, a char[] is smaller, which avoids cache trashing, and that
+ * is probably the most important aspect on most architectures.
+ * This array is accessed a *lot* by the noise functions.
+ * A vector-valued noise over 3D accesses it 96 times, and a
+ * float-valued 4D noise 64 times. We want this to fit in the cache!
+ */
+unsigned char perm[512] = {151,160,137,91,90,15,
+ 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
+ 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
+ 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
+ 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
+ 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
+ 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
+ 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
+ 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
+ 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
+ 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
+ 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
+ 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
+ 151,160,137,91,90,15,
+ 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
+ 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
+ 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
+ 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
+ 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
+ 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
+ 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
+ 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
+ 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
+ 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
+ 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
+ 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
+};
+
+//---------------------------------------------------------------------
+
+/*
+ * Helper functions to compute gradients-dot-residualvectors (1D to 4D)
+ * Note that these generate gradients of more than unit length. To make
+ * a close match with the value range of classic Perlin noise, the final
+ * noise values need to be rescaled to fit nicely within [-1,1].
+ * (The simplex noise functions as such also have different scaling.)
+ * Note also that these noise functions are the most practical and useful
+ * signed version of Perlin noise. To return values according to the
+ * RenderMan specification from the SL noise() and pnoise() functions,
+ * the noise values need to be scaled and offset to [0,1], like this:
+ * float SLnoise = (noise(x,y,z) + 1.0) * 0.5;
+ */
+
+float grad1( int hash, float x ) {
+ int h = hash & 15;
+ float grad = 1.0f + (h & 7); // Gradient value 1.0, 2.0, ..., 8.0
+ if (h&8) grad = -grad; // Set a random sign for the gradient
+ return ( grad * x ); // Multiply the gradient with the distance
+}
+
+float grad2( int hash, float x, float y ) {
+ int h = hash & 7; // Convert low 3 bits of hash code
+ float u = h<4 ? x : y; // into 8 simple gradient directions,
+ float v = h<4 ? y : x; // and compute the dot product with (x,y).
+ return ((h&1)? -u : u) + ((h&2)? -2.0f*v : 2.0f*v);
+}
+
+float grad3( int hash, float x, float y , float z ) {
+ int h = hash & 15; // Convert low 4 bits of hash code into 12 simple
+ float u = h<8 ? x : y; // gradient directions, and compute dot product.
+ float v = h<4 ? y : h==12||h==14 ? x : z; // Fix repeats at h = 12 to 15
+ return ((h&1)? -u : u) + ((h&2)? -v : v);
+}
+
+float grad4( int hash, float x, float y, float z, float t ) {
+ int h = hash & 31; // Convert low 5 bits of hash code into 32 simple
+ float u = h<24 ? x : y; // gradient directions, and compute dot product.
+ float v = h<16 ? y : z;
+ float w = h<8 ? z : t;
+ return ((h&1)? -u : u) + ((h&2)? -v : v) + ((h&4)? -w : w);
+}
+
+ // A lookup table to traverse the simplex around a given point in 4D.
+ // Details can be found where this table is used, in the 4D noise method.
+ /* TODO: This should not be required, backport it from Bill's GLSL code! */
+ static unsigned char simplex[64][4] = {
+ {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0},
+ {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0},
+ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
+ {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0},
+ {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0},
+ {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},
+ {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0},
+ {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0}};
+
+// 1D simplex noise
+float snoise1(float x) {
+
+ int i0 = FASTFLOOR(x);
+ int i1 = i0 + 1;
+ float x0 = x - i0;
+ float x1 = x0 - 1.0f;
+
+ float n0, n1;
+
+ float t0 = 1.0f - x0*x0;
+// if(t0 < 0.0f) t0 = 0.0f; // this never happens for the 1D case
+ t0 *= t0;
+ n0 = t0 * t0 * grad1(perm[i0 & 0xff], x0);
+
+ float t1 = 1.0f - x1*x1;
+// if(t1 < 0.0f) t1 = 0.0f; // this never happens for the 1D case
+ t1 *= t1;
+ n1 = t1 * t1 * grad1(perm[i1 & 0xff], x1);
+ // The maximum value of this noise is 8*(3/4)^4 = 2.53125
+ // A factor of 0.395 would scale to fit exactly within [-1,1], but
+ // we want to match PRMan's 1D noise, so we scale it down some more.
+ return 0.25f * (n0 + n1);
+
+}
+
+// 2D simplex noise
+float snoise2(float x, float y) {
+
+#define F2 0.366025403 // F2 = 0.5*(sqrt(3.0)-1.0)
+#define G2 0.211324865 // G2 = (3.0-Math.sqrt(3.0))/6.0
+
+ float n0, n1, n2; // Noise contributions from the three corners
+
+ // Skew the input space to determine which simplex cell we're in
+ float s = (x+y)*F2; // Hairy factor for 2D
+ float xs = x + s;
+ float ys = y + s;
+ int i = FASTFLOOR(xs);
+ int j = FASTFLOOR(ys);
+
+ float t = (float)(i+j)*G2;
+ float X0 = i-t; // Unskew the cell origin back to (x,y) space
+ float Y0 = j-t;
+ float x0 = x-X0; // The x,y distances from the cell origin
+ float y0 = y-Y0;
+
+ // For the 2D case, the simplex shape is an equilateral triangle.
+ // Determine which simplex we are in.
+ int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
+ if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
+ else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
+
+ // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
+ // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
+ // c = (3-sqrt(3))/6
+
+ float x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
+ float y1 = y0 - j1 + G2;
+ float x2 = x0 - 1.0f + 2.0f * G2; // Offsets for last corner in (x,y) unskewed coords
+ float y2 = y0 - 1.0f + 2.0f * G2;
+
+ // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
+ int ii = i & 0xff;
+ int jj = j & 0xff;
+
+ // Calculate the contribution from the three corners
+ float t0 = 0.5f - x0*x0-y0*y0;
+ if(t0 < 0.0f) n0 = 0.0f;
+ else {
+ t0 *= t0;
+ n0 = t0 * t0 * grad2(perm[ii+perm[jj]], x0, y0);
+ }
+
+ float t1 = 0.5f - x1*x1-y1*y1;
+ if(t1 < 0.0f) n1 = 0.0f;
+ else {
+ t1 *= t1;
+ n1 = t1 * t1 * grad2(perm[ii+i1+perm[jj+j1]], x1, y1);
+ }
+
+ float t2 = 0.5f - x2*x2-y2*y2;
+ if(t2 < 0.0f) n2 = 0.0f;
+ else {
+ t2 *= t2;
+ n2 = t2 * t2 * grad2(perm[ii+1+perm[jj+1]], x2, y2);
+ }
+
+ // Add contributions from each corner to get the final noise value.
+ // The result is scaled to return values in the interval [-1,1].
+ return 40.0f * (n0 + n1 + n2); // TODO: The scale factor is preliminary!
+ }
+
+// 3D simplex noise
+float snoise3(float x, float y, float z) {
+
+// Simple skewing factors for the 3D case
+#define F3 0.333333333
+#define G3 0.166666667
+
+ float n0, n1, n2, n3; // Noise contributions from the four corners
+
+ // Skew the input space to determine which simplex cell we're in
+ float s = (x+y+z)*F3; // Very nice and simple skew factor for 3D
+ float xs = x+s;
+ float ys = y+s;
+ float zs = z+s;
+ int i = FASTFLOOR(xs);
+ int j = FASTFLOOR(ys);
+ int k = FASTFLOOR(zs);
+
+ float t = (float)(i+j+k)*G3;
+ float X0 = i-t; // Unskew the cell origin back to (x,y,z) space
+ float Y0 = j-t;
+ float Z0 = k-t;
+ float x0 = x-X0; // The x,y,z distances from the cell origin
+ float y0 = y-Y0;
+ float z0 = z-Z0;
+
+ // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
+ // Determine which simplex we are in.
+ int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
+ int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
+
+/* This code would benefit from a backport from the GLSL version! */
+ if(x0>=y0) {
+ if(y0>=z0)
+ { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order
+ else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order
+ else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order
+ }
+ else { // x0<y0
+ if(y0<z0) { i1=0; j1=0; k1=1; i2=0; j2=1; k2=1; } // Z Y X order
+ else if(x0<z0) { i1=0; j1=1; k1=0; i2=0; j2=1; k2=1; } // Y Z X order
+ else { i1=0; j1=1; k1=0; i2=1; j2=1; k2=0; } // Y X Z order
+ }
+
+ // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
+ // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
+ // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
+ // c = 1/6.
+
+ float x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
+ float y1 = y0 - j1 + G3;
+ float z1 = z0 - k1 + G3;
+ float x2 = x0 - i2 + 2.0f*G3; // Offsets for third corner in (x,y,z) coords
+ float y2 = y0 - j2 + 2.0f*G3;
+ float z2 = z0 - k2 + 2.0f*G3;
+ float x3 = x0 - 1.0f + 3.0f*G3; // Offsets for last corner in (x,y,z) coords
+ float y3 = y0 - 1.0f + 3.0f*G3;
+ float z3 = z0 - 1.0f + 3.0f*G3;
+
+ // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
+ int ii = i & 0xff;
+ int jj = j & 0xff;
+ int kk = k & 0xff;
+
+ // Calculate the contribution from the four corners
+ float t0 = 0.6f - x0*x0 - y0*y0 - z0*z0;
+ if(t0 < 0.0f) n0 = 0.0f;
+ else {
+ t0 *= t0;
+ n0 = t0 * t0 * grad3(perm[ii+perm[jj+perm[kk]]], x0, y0, z0);
+ }
+
+ float t1 = 0.6f - x1*x1 - y1*y1 - z1*z1;
+ if(t1 < 0.0f) n1 = 0.0f;
+ else {
+ t1 *= t1;
+ n1 = t1 * t1 * grad3(perm[ii+i1+perm[jj+j1+perm[kk+k1]]], x1, y1, z1);
+ }
+
+ float t2 = 0.6f - x2*x2 - y2*y2 - z2*z2;
+ if(t2 < 0.0f) n2 = 0.0f;
+ else {
+ t2 *= t2;
+ n2 = t2 * t2 * grad3(perm[ii+i2+perm[jj+j2+perm[kk+k2]]], x2, y2, z2);
+ }
+
+ float t3 = 0.6f - x3*x3 - y3*y3 - z3*z3;
+ if(t3<0.0f) n3 = 0.0f;
+ else {
+ t3 *= t3;
+ n3 = t3 * t3 * grad3(perm[ii+1+perm[jj+1+perm[kk+1]]], x3, y3, z3);
+ }
+
+ // Add contributions from each corner to get the final noise value.
+ // The result is scaled to stay just inside [-1,1]
+ return 32.0f * (n0 + n1 + n2 + n3); // TODO: The scale factor is preliminary!
+ }
+
+
+// 4D simplex noise
+float snoise4(float x, float y, float z, float w) {
+
+ // The skewing and unskewing factors are hairy again for the 4D case
+#define F4 0.309016994 // F4 = (Math.sqrt(5.0)-1.0)/4.0
+#define G4 0.138196601 // G4 = (5.0-Math.sqrt(5.0))/20.0
+
+ float n0, n1, n2, n3, n4; // Noise contributions from the five corners
+
+ // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
+ float s = (x + y + z + w) * F4; // Factor for 4D skewing
+ float xs = x + s;
+ float ys = y + s;
+ float zs = z + s;
+ float ws = w + s;
+ int i = FASTFLOOR(xs);
+ int j = FASTFLOOR(ys);
+ int k = FASTFLOOR(zs);
+ int l = FASTFLOOR(ws);
+
+ float t = (i + j + k + l) * G4; // Factor for 4D unskewing
+ float X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
+ float Y0 = j - t;
+ float Z0 = k - t;
+ float W0 = l - t;
+
+ float x0 = x - X0; // The x,y,z,w distances from the cell origin
+ float y0 = y - Y0;
+ float z0 = z - Z0;
+ float w0 = w - W0;
+
+ // For the 4D case, the simplex is a 4D shape I won't even try to describe.
+ // To find out which of the 24 possible simplices we're in, we need to
+ // determine the magnitude ordering of x0, y0, z0 and w0.
+ // The method below is a good way of finding the ordering of x,y,z,w and
+ // then find the correct traversal order for the simplex we’re in.
+ // First, six pair-wise comparisons are performed between each possible pair
+ // of the four coordinates, and the results are used to add up binary bits
+ // for an integer index.
+ int c1 = (x0 > y0) ? 32 : 0;
+ int c2 = (x0 > z0) ? 16 : 0;
+ int c3 = (y0 > z0) ? 8 : 0;
+ int c4 = (x0 > w0) ? 4 : 0;
+ int c5 = (y0 > w0) ? 2 : 0;
+ int c6 = (z0 > w0) ? 1 : 0;
+ int c = c1 + c2 + c3 + c4 + c5 + c6;
+
+ int i1, j1, k1, l1; // The integer offsets for the second simplex corner
+ int i2, j2, k2, l2; // The integer offsets for the third simplex corner
+ int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
+
+ // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
+ // Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
+ // impossible. Only the 24 indices which have non-zero entries make any sense.
+ // We use a thresholding to set the coordinates in turn from the largest magnitude.
+ // The number 3 in the "simplex" array is at the position of the largest coordinate.
+ i1 = simplex[c][0]>=3 ? 1 : 0;
+ j1 = simplex[c][1]>=3 ? 1 : 0;
+ k1 = simplex[c][2]>=3 ? 1 : 0;
+ l1 = simplex[c][3]>=3 ? 1 : 0;
+ // The number 2 in the "simplex" array is at the second largest coordinate.
+ i2 = simplex[c][0]>=2 ? 1 : 0;
+ j2 = simplex[c][1]>=2 ? 1 : 0;
+ k2 = simplex[c][2]>=2 ? 1 : 0;
+ l2 = simplex[c][3]>=2 ? 1 : 0;
+ // The number 1 in the "simplex" array is at the second smallest coordinate.
+ i3 = simplex[c][0]>=1 ? 1 : 0;
+ j3 = simplex[c][1]>=1 ? 1 : 0;
+ k3 = simplex[c][2]>=1 ? 1 : 0;
+ l3 = simplex[c][3]>=1 ? 1 : 0;
+ // The fifth corner has all coordinate offsets = 1, so no need to look that up.
+
+ float x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords
+ float y1 = y0 - j1 + G4;
+ float z1 = z0 - k1 + G4;
+ float w1 = w0 - l1 + G4;
+ float x2 = x0 - i2 + 2.0f*G4; // Offsets for third corner in (x,y,z,w) coords
+ float y2 = y0 - j2 + 2.0f*G4;
+ float z2 = z0 - k2 + 2.0f*G4;
+ float w2 = w0 - l2 + 2.0f*G4;
+ float x3 = x0 - i3 + 3.0f*G4; // Offsets for fourth corner in (x,y,z,w) coords
+ float y3 = y0 - j3 + 3.0f*G4;
+ float z3 = z0 - k3 + 3.0f*G4;
+ float w3 = w0 - l3 + 3.0f*G4;
+ float x4 = x0 - 1.0f + 4.0f*G4; // Offsets for last corner in (x,y,z,w) coords
+ float y4 = y0 - 1.0f + 4.0f*G4;
+ float z4 = z0 - 1.0f + 4.0f*G4;
+ float w4 = w0 - 1.0f + 4.0f*G4;
+
+ // Wrap the integer indices at 256, to avoid indexing perm[] out of bounds
+ int ii = i & 0xff;
+ int jj = j & 0xff;
+ int kk = k & 0xff;
+ int ll = l & 0xff;
+
+ // Calculate the contribution from the five corners
+ float t0 = 0.6f - x0*x0 - y0*y0 - z0*z0 - w0*w0;
+ if(t0 < 0.0f) n0 = 0.0f;
+ else {
+ t0 *= t0;
+ n0 = t0 * t0 * grad4(perm[ii+perm[jj+perm[kk+perm[ll]]]], x0, y0, z0, w0);
+ }
+
+ float t1 = 0.6f - x1*x1 - y1*y1 - z1*z1 - w1*w1;
+ if(t1 < 0.0f) n1 = 0.0f;
+ else {
+ t1 *= t1;
+ n1 = t1 * t1 * grad4(perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]], x1, y1, z1, w1);
+ }
+
+ float t2 = 0.6f - x2*x2 - y2*y2 - z2*z2 - w2*w2;
+ if(t2 < 0.0f) n2 = 0.0f;
+ else {
+ t2 *= t2;
+ n2 = t2 * t2 * grad4(perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]], x2, y2, z2, w2);
+ }
+
+ float t3 = 0.6f - x3*x3 - y3*y3 - z3*z3 - w3*w3;
+ if(t3 < 0.0f) n3 = 0.0f;
+ else {
+ t3 *= t3;
+ n3 = t3 * t3 * grad4(perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]], x3, y3, z3, w3);
+ }
+
+ float t4 = 0.6f - x4*x4 - y4*y4 - z4*z4 - w4*w4;
+ if(t4 < 0.0f) n4 = 0.0f;
+ else {
+ t4 *= t4;
+ n4 = t4 * t4 * grad4(perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]], x4, y4, z4, w4);
+ }
+
+ // Sum up and scale the result to cover the range [-1,1]
+ return 27.0f * (n0 + n1 + n2 + n3 + n4); // TODO: The scale factor is preliminary!
+ }
+//---------------------------------------------------------------------
diff --git a/Projects/Asteroids/src/simplexnoise1234.h b/Projects/Asteroids/src/simplexnoise1234.h
new file mode 100644
index 0000000..18c42f9
--- /dev/null
+++ b/Projects/Asteroids/src/simplexnoise1234.h
@@ -0,0 +1,70 @@
+/* SimplexNoise1234, Simplex noise with true analytic
+ * derivative in 1D to 4D.
+ *
+ * Author: Stefan Gustavson, 2003-2005
+ * Contact: stegu@itn.liu.se
+ */
+
+/*
+This code was GPL licensed until February 2011.
+As the original author of this code, I hereby
+release it irrevocably into the public domain.
+Please feel free to use it for whatever you want.
+Credit is appreciated where appropriate, and I also
+appreciate being told where this code finds any use,
+but you may do as you like. Alternatively, if you want
+to have a familiar OSI-approved license, you may use
+This code under the terms of the MIT license:
+
+Copyright (C) 2003-2005 by Stefan Gustavson. All rights reserved.
+This code is licensed to you under the terms of the MIT license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+/** \file
+ \brief Header for "simplexnoise1234.c" for producing Perlin simplex noise.
+ \author Stefan Gustavson (stegu@itn.liu.se)
+*/
+
+/*
+ * This is a clean, fast, modern and free Perlin Simplex noise function.
+ * It is a stand-alone compilation unit with no external dependencies,
+ * highly reusable without source code modifications.
+ *
+ *
+ * Note:
+ * Replacing the "float" type with "double" can actually make this run faster
+ * on some platforms. Having both versions could be useful.
+ */
+
+/** 1D, 2D, 3D and 4D float Perlin simplex noise
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ float snoise1( float x );
+ float snoise2( float x, float y );
+ float snoise3( float x, float y, float z );
+ float snoise4( float x, float y, float z, float w );
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/Projects/Asteroids/src/simulation.cpp b/Projects/Asteroids/src/simulation.cpp
new file mode 100644
index 0000000..74e9019
--- /dev/null
+++ b/Projects/Asteroids/src/simulation.cpp
@@ -0,0 +1,250 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#include "simulation.h"
+#include "settings.h"
+#include "texture.h"
+#include "util.h"
+
+#include <random>
+#include <limits>
+#include <algorithm>
+#include <iostream>
+#include <ppl.h>
+
+using namespace DirectX;
+
+static int const COLOR_SCHEMES[] = {
+ 156, 139, 113, 55, 49, 40,
+ 156, 139, 113, 58, 38, 14,
+ 156, 139, 113, 98, 101, 104,
+ 156, 139, 113, 205, 197, 178,
+ 153, 146, 136, 88, 88, 88,
+ 189, 181, 164, 148, 108, 102,
+};
+
+static int const NUM_COLOR_SCHEMES = (int) (sizeof(COLOR_SCHEMES) / (6 * sizeof(int)));
+
+static XMVECTOR RandomPointOnSphere(std::mt19937& rng)
+{
+ std::normal_distribution<float> dist;
+
+ XMVECTOR r;
+ for (;;) {
+ r = XMVectorSet(dist(rng), dist(rng), dist(rng), 0.0f);
+ auto d2 = XMVectorGetX(XMVector3LengthSq(r));
+ if (d2 > std::numeric_limits<float>::min()) {
+ return XMVector3Normalize(r);
+ }
+ }
+ // Unreachable
+}
+
+// From http://guihaire.com/code/?p=1135
+static inline float VeryApproxLog2f(float x)
+{
+ union { float f; uint32_t i; } ux;
+ ux.f = x;
+ return (float)ux.i * 1.1920928955078125e-7f - 126.94269504f;
+}
+
+
+AsteroidsSimulation::AsteroidsSimulation(unsigned int rngSeed, unsigned int asteroidCount,
+ unsigned int meshInstanceCount, unsigned int subdivCount,
+ unsigned int textureCount)
+ : mAsteroidStatic(asteroidCount)
+ , mAsteroidDynamic(asteroidCount)
+ , mIndexOffsets(subdivCount + 2) // Mesh subdivs are inclusive on both ends and need forward differencing for count
+ , mSubdivCount(subdivCount)
+{
+ std::mt19937 rng(rngSeed);
+
+ // Create meshes
+ std::cout
+ << "Creating " << meshInstanceCount << " meshes, each with "
+ << subdivCount << " subdivision levels..." << std::endl;
+
+ CreateAsteroidsFromGeospheres(&mMeshes, mSubdivCount, meshInstanceCount,
+ rng(), mIndexOffsets.data(), &mVertexCountPerMesh);
+
+ CreateTextures(textureCount, rng());
+
+ // Constants
+ std::normal_distribution<float> orbitRadiusDist(SIM_ORBIT_RADIUS, 0.6f * SIM_DISC_RADIUS);
+ std::normal_distribution<float> heightDist(0.0f, 0.4f);
+ std::uniform_real_distribution<float> angleDist(-XM_PI, XM_PI);
+ std::uniform_real_distribution<float> radialVelocityDist(5.0f, 15.0f);
+ std::uniform_real_distribution<float> spinVelocityDist(-2.0f, 2.0f);
+ std::normal_distribution<float> scaleDist(1.3f, 0.7f);
+ std::normal_distribution<float> colorSchemeDist(0, NUM_COLOR_SCHEMES - 1);
+ std::uniform_int_distribution<unsigned int> textureIndexDist(0, textureCount-1);
+
+ auto instancesPerMesh = std::max(1U, asteroidCount / meshInstanceCount);
+
+ // Approximate SRGB->Linear for colors
+ float linearColorSchemes[NUM_COLOR_SCHEMES * 6];
+ for (int i = 0; i < ARRAYSIZE(linearColorSchemes); ++i) {
+ linearColorSchemes[i] = std::powf((float)COLOR_SCHEMES[i] / 255.0f, 2.2f);
+ }
+
+ // Create a torus of asteroids that spin around the ring
+ for (unsigned int i = 0; i < asteroidCount; ++i) {
+ auto scale = scaleDist(rng);
+#if SIM_USE_GAMMA_DIST_SCALE
+ scale = scale * 0.3f;
+#endif
+ scale = std::max(scale, SIM_MIN_SCALE);
+ auto scaleMatrix = XMMatrixScaling(scale, scale, scale);
+
+ auto orbitRadius = orbitRadiusDist(rng);
+ auto discPosY = float(SIM_DISC_RADIUS) * heightDist(rng);
+
+ auto disc = XMMatrixTranslation(orbitRadius, discPosY, 0.0f);
+
+ auto positionAngle = angleDist(rng);
+ auto orbit = XMMatrixRotationY(positionAngle);
+
+ auto meshInstance = (unsigned int)(i / instancesPerMesh); // Vcache friendly ordering
+
+ // Static data
+ mAsteroidStatic[i].spinVelocity = spinVelocityDist(rng) / scale; // Smaller asteroids spin faster
+ mAsteroidStatic[i].orbitVelocity = radialVelocityDist(rng) / (scale * orbitRadius); // Smaller asteroids go faster, and use arc length
+ mAsteroidStatic[i].vertexStart = mVertexCountPerMesh * meshInstance;
+ mAsteroidStatic[i].spinAxis = XMVector3Normalize(RandomPointOnSphere(rng));
+ mAsteroidStatic[i].scale = scale;
+ mAsteroidStatic[i].textureIndex = textureIndexDist(rng);
+
+ auto colorScheme = ((int)abs(colorSchemeDist(rng))) % NUM_COLOR_SCHEMES;
+ auto c = linearColorSchemes + 6 * colorScheme;
+ mAsteroidStatic[i].surfaceColor = XMFLOAT3(c[0], c[1], c[2]);
+ mAsteroidStatic[i].deepColor = XMFLOAT3(c[3], c[4], c[5]);
+
+ // Initialize dynamic data
+ mAsteroidDynamic[i].world = scaleMatrix * disc * orbit;
+
+ assert(mAsteroidStatic[i].scale > 0.0f);
+ assert(mAsteroidStatic[i].orbitVelocity > 0.0f);
+ }
+}
+
+
+void AsteroidsSimulation::Update(float frameTime, DirectX::XMVECTOR cameraEye, const Settings& settings,
+ size_t startIndex, size_t count)
+{
+ bool animate = settings.animate;
+
+ // TODO: This constant should really depend on resolution and/or be configurable...
+ static const float minSubdivSizeLog2 = std::log2f(0.0019f);
+
+ size_t last = count ? startIndex + count : mAsteroidDynamic.size();
+ for (size_t i = startIndex; i < last; ++i) {
+ const AsteroidStatic& staticData = mAsteroidStatic[i];
+ AsteroidDynamic& dynamicData = mAsteroidDynamic[i];
+
+ if (animate) {
+ auto orbit = XMMatrixRotationY(staticData.orbitVelocity * frameTime);
+ auto spin = XMMatrixRotationNormal(staticData.spinAxis, staticData.spinVelocity * frameTime);
+ dynamicData.world = spin * dynamicData.world * orbit;
+ }
+
+ // Pick LOD based on approx screen area - can be very approximate
+ auto position = dynamicData.world.r[3];
+ auto distanceToEyeRcp = XMVectorGetX(XMVector3ReciprocalLengthEst(XMVectorSubtract(cameraEye, position)));
+ // Add one subdiv for each factor of 2 past min
+ auto relativeScreenSizeLog2 = VeryApproxLog2f(staticData.scale * distanceToEyeRcp);
+ float subdivFloat = std::max(0.0f, relativeScreenSizeLog2 - minSubdivSizeLog2);
+ auto subdiv = std::min(mSubdivCount, (unsigned int)subdivFloat);
+
+ // TODO: Ignore/cull/force lowest subdiv if offscreen?
+
+ dynamicData.indexStart = mIndexOffsets[subdiv];
+ dynamicData.indexCount = mIndexOffsets[subdiv+1] - dynamicData.indexStart;
+ }
+}
+
+
+void AsteroidsSimulation::CreateTextures(unsigned int textureCount, unsigned int rngSeed)
+{
+ mTextureDim = TEXTURE_DIM;
+ mTextureCount = textureCount;
+ mTextureArraySize = 3;
+ {
+ DWORD msbIndex = 0;
+ auto result = _BitScanReverse(&msbIndex, mTextureDim);
+ assert(result); // Should only fail if mTextureDim = 0
+ mTextureMipLevels = msbIndex + 1;
+ }
+
+ assert((mTextureDim & (mTextureDim-1)) == 0); // Must be pow2 currently; we don't handle wacky mip chains
+
+ std::cout
+ << "Creating " << textureCount << " "
+ << mTextureDim << "x" << mTextureDim << " textures..." << std::endl;
+
+ // Allocate space
+ UINT texelSizeInBytes = 4; // RGBA8
+ UINT extraSpaceForMips = 2;
+ UINT totalTextureSizeInBytes = texelSizeInBytes * mTextureDim * mTextureDim * mTextureArraySize * extraSpaceForMips;
+ totalTextureSizeInBytes = Align(totalTextureSizeInBytes, 64U); // Avoid false sharing
+
+ mTextureDataBuffer.resize(totalTextureSizeInBytes * textureCount);
+ mTextureSubresources.resize(mTextureArraySize * mTextureMipLevels * textureCount);
+
+ // Parallel over textures
+ std::vector<unsigned int> rngSeeds(textureCount);
+ {
+ std::mt19937 seeds;
+ for (auto &i : rngSeeds) i = seeds();
+ }
+
+ concurrency::parallel_for(UINT(0), textureCount, [&](UINT t) {
+ std::mt19937 rng(rngSeeds[t]);
+ auto randomNoise = std::uniform_real_distribution<float>(0.0f, 10000.0f);
+ auto randomNoiseScale = std::uniform_real_distribution<float>(100, 150);
+ auto randomPersistence = std::normal_distribution<float>(0.9f, 0.2f);
+
+ BYTE* data = mTextureDataBuffer.data() + t * totalTextureSizeInBytes;
+ for (UINT a = 0; a < mTextureArraySize; ++a) {
+ for (UINT m = 0; m < mTextureMipLevels; ++m) {
+ auto width = mTextureDim >> m;
+ auto height = mTextureDim >> m;
+
+ D3D11_SUBRESOURCE_DATA initialData = {};
+ initialData.pSysMem = data;
+ initialData.SysMemPitch = width * texelSizeInBytes;
+ mTextureSubresources[SubresourceIndex(t, a, m)] = initialData;
+
+ data += initialData.SysMemPitch * height;
+ }
+ }
+
+ // Use same parameters for each of the tri-planar projection planes/cube map faces/etc.
+ float noiseScale = randomNoiseScale(rng) / float(mTextureDim);
+ float persistence = randomPersistence(rng);
+ float strength = 1.5f;
+
+ for (UINT a = 0; a < mTextureArraySize; ++a) {
+ float redScale = 255.0f;
+ float greenScale = 255.0f;
+ float blueScale = 255.0f;
+
+ // DEBUG colors
+#if 0
+ redScale = t & 1 ? 255.0f : 0.0f;
+ greenScale = t & 2 ? 255.0f : 0.0f;
+ blueScale = t & 4 ? 255.0f : 0.0f;
+#endif
+
+ FillNoise2D_RGBA8(&mTextureSubresources[SubresourceIndex(t, a)], mTextureDim, mTextureDim, mTextureMipLevels,
+ randomNoise(rng), persistence, noiseScale, strength,
+ redScale, greenScale, blueScale);
+ }
+ }); // parallel_for
+}
diff --git a/Projects/Asteroids/src/simulation.h b/Projects/Asteroids/src/simulation.h
new file mode 100644
index 0000000..c14270d
--- /dev/null
+++ b/Projects/Asteroids/src/simulation.h
@@ -0,0 +1,90 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include <d3d11.h> // For D3D11_SUBRESOURCE_DATA
+#include <DirectXMath.h>
+#include <vector>
+#include <algorithm>
+#include <random>
+
+#include "mesh.h"
+#include "settings.h"
+
+// We may want to ISPC-ify this down the road and just let it own the data structure in AoSoA format or similar
+// For now we'll just do the dumb thing and see if it's fast enough
+struct AsteroidDynamic
+{
+ DirectX::XMMATRIX world;
+ // These depend on chosen subdiv level, hence are not constant
+ unsigned int indexStart;
+ unsigned int indexCount;
+};
+
+struct AsteroidStatic
+{
+ DirectX::XMFLOAT3 surfaceColor;
+ DirectX::XMFLOAT3 deepColor;
+ DirectX::XMVECTOR spinAxis;
+ float scale;
+ float spinVelocity;
+ float orbitVelocity;
+ unsigned int vertexStart;
+ unsigned int textureIndex;
+};
+
+class AsteroidsSimulation
+{
+private:
+ // NOTE: Memory could be optimized further for efficient cache traversal, etc.
+ std::vector<AsteroidStatic> mAsteroidStatic;
+ std::vector<AsteroidDynamic> mAsteroidDynamic;
+
+ Mesh mMeshes;
+ std::vector<unsigned int> mIndexOffsets;
+ unsigned int mSubdivCount;
+ unsigned int mVertexCountPerMesh;
+
+ unsigned int mTextureDim;
+ unsigned int mTextureCount;
+ unsigned int mTextureArraySize;
+ unsigned int mTextureMipLevels;
+ std::vector<BYTE> mTextureDataBuffer;
+ std::vector<D3D11_SUBRESOURCE_DATA> mTextureSubresources;
+
+ unsigned int SubresourceIndex(unsigned int texture, unsigned int arrayElement = 0, unsigned int mip = 0)
+ {
+ return mip + mTextureMipLevels * (arrayElement + mTextureArraySize * texture);
+ }
+
+ void CreateTextures(unsigned int textureCount, unsigned int rngSeed);
+
+public:
+ AsteroidsSimulation(unsigned int rngSeed, unsigned int asteroidCount,
+ unsigned int meshInstanceCount, unsigned int subdivCount,
+ unsigned int textureCount);
+
+ const Mesh* Meshes() { return &mMeshes; }
+ const D3D11_SUBRESOURCE_DATA* TextureData(unsigned int textureIndex)
+ {
+ return mTextureSubresources.data() + SubresourceIndex(textureIndex);
+ }
+
+ unsigned int GetTextureMipLevels()const{return mTextureMipLevels;}
+
+ const AsteroidStatic* StaticData() const { return mAsteroidStatic.data(); }
+ const AsteroidDynamic* DynamicData() const { return mAsteroidDynamic.data(); }
+
+ // Can optionall provide a range of asteroids to update; count = 0 => to the end
+ // This is useful for multithreading
+ void Update(float frameTime, DirectX::XMVECTOR cameraEye, const Settings& settings,
+ size_t startIndex = 0, size_t count = 0);
+};
diff --git a/Projects/Asteroids/src/skybox_ps.hlsl b/Projects/Asteroids/src/skybox_ps.hlsl
new file mode 100644
index 0000000..4107073
--- /dev/null
+++ b/Projects/Asteroids/src/skybox_ps.hlsl
@@ -0,0 +1,16 @@
+struct Skybox_VSOut
+{
+ float3 coords : UVFACE;
+};
+
+TextureCube Skybox;// : register(t0);
+SamplerState Skybox_sampler;// : register(s0);
+
+void skybox_ps(in float4 position : SV_Position,
+ in Skybox_VSOut vsoutput,
+ out float4 color : SV_Target)
+{
+ //return input.coords.xyzx;
+ float4 tex = Skybox.Sample(Skybox_sampler, vsoutput.coords);
+ color = float4(tex.xyz, 1.0f);
+}
diff --git a/Projects/Asteroids/src/skybox_vs.hlsl b/Projects/Asteroids/src/skybox_vs.hlsl
new file mode 100644
index 0000000..acefcd5
--- /dev/null
+++ b/Projects/Asteroids/src/skybox_vs.hlsl
@@ -0,0 +1,20 @@
+cbuffer SkyboxConstantBuffer// : register(b0)
+{
+ float4x4 mViewProjection;
+};
+
+struct Skybox_VSOut
+{
+ float3 coords : UVFACE;
+};
+
+void skybox_vs( in float3 in_position : ATTRIB0,
+ in float3 uvFace : ATTRIB1,
+ out float4 position : SV_Position,
+ out Skybox_VSOut vsoutput)
+{
+ // NOTE: Don't translate skybox and make sure depth == 1 (no clipping)
+ position = mul(mViewProjection, float4(in_position, 0.0f)).xyww;
+ position.z = 0.0f; // 1-z
+ vsoutput.coords = in_position.xyz;
+}
diff --git a/Projects/Asteroids/src/sprite.h b/Projects/Asteroids/src/sprite.h
new file mode 100644
index 0000000..4a8311d
--- /dev/null
+++ b/Projects/Asteroids/src/sprite.h
@@ -0,0 +1,36 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+struct SpriteVertex {
+ float x;
+ float y;
+ float u;
+ float v;
+};
+
+inline SpriteVertex* DrawSprite(float x, float y, float width, float height, float viewportWidth, float viewportHeight, SpriteVertex* outVertex)
+{
+ outVertex[0] = {x , y , 0.0f, 0.0f};
+ outVertex[1] = {x + width, y , 1.0f, 0.0f};
+ outVertex[2] = {x + width, y + height, 1.0f, 1.0f};
+ outVertex[3] = outVertex[0];
+ outVertex[4] = outVertex[2];
+ outVertex[5] = {x , y + height, 0.0f, 1.0f};
+
+ for (int i = 0; i < 6; ++i) {
+ outVertex[i].x = (outVertex[i].x / viewportWidth * 2.0f - 1.0f);
+ outVertex[i].y = -(outVertex[i].y / viewportHeight * 2.0f - 1.0f);
+ }
+
+ outVertex += 6;
+ return outVertex;
+}
diff --git a/Projects/Asteroids/src/sprite_ps.hlsl b/Projects/Asteroids/src/sprite_ps.hlsl
new file mode 100644
index 0000000..fa47f83
--- /dev/null
+++ b/Projects/Asteroids/src/sprite_ps.hlsl
@@ -0,0 +1,11 @@
+#include "sprite_vs.hlsl"
+
+Texture2D<float4> Tex;// : register(t0);
+SamplerState Tex_sampler;// : register(s0);
+
+void sprite_ps(in float4 position : SV_Position,
+ in Font_VSOut vs_out,
+ out float4 color : SV_Target )
+{
+ color = Tex.Sample(Tex_sampler, vs_out.uv);
+}
diff --git a/Projects/Asteroids/src/sprite_vs.hlsl b/Projects/Asteroids/src/sprite_vs.hlsl
new file mode 100644
index 0000000..6fea9e5
--- /dev/null
+++ b/Projects/Asteroids/src/sprite_vs.hlsl
@@ -0,0 +1,14 @@
+
+struct Font_VSOut
+{
+ float2 uv : UV;
+};
+
+void sprite_vs( float2 in_position : ATTRIB0,
+ float2 in_uv : ATTRIB1,
+ out float4 position : SV_Position,
+ out Font_VSOut vs_out)
+{
+ position = float4(in_position, 0, 1);
+ vs_out.uv = in_uv;
+}
diff --git a/Projects/Asteroids/src/stb_font_consolas_bold_50_usascii.inl b/Projects/Asteroids/src/stb_font_consolas_bold_50_usascii.inl
new file mode 100644
index 0000000..066ba29
--- /dev/null
+++ b/Projects/Asteroids/src/stb_font_consolas_bold_50_usascii.inl
@@ -0,0 +1,1195 @@
+// Font generated by stb_font_inl_generator.c (4/1 bpp)
+//
+// Following instructions show how to use the only included font, whatever it is, in
+// a generic way so you can replace it with any other font by changing the include.
+// To use multiple fonts, replace STB_SOMEFONT_* below with STB_FONT_consolas_bold_50_usascii_*,
+// and separately install each font. Note that the CREATE function call has a
+// totally different name; it's just 'stb_font_consolas_bold_50_usascii'.
+//
+/* // Example usage:
+
+static stb_fontchar fontdata[STB_SOMEFONT_NUM_CHARS];
+
+static void init(void)
+{
+ // optionally replace both STB_SOMEFONT_BITMAP_HEIGHT with STB_SOMEFONT_BITMAP_HEIGHT_POW2
+ static unsigned char fontpixels[STB_SOMEFONT_BITMAP_HEIGHT][STB_SOMEFONT_BITMAP_WIDTH];
+ STB_SOMEFONT_CREATE(fontdata, fontpixels, STB_SOMEFONT_BITMAP_HEIGHT);
+ ... create texture ...
+ // for best results rendering 1:1 pixels texels, use nearest-neighbor sampling
+ // if allowed to scale up, use bilerp
+}
+
+// This function positions characters on integer coordinates, and assumes 1:1 texels to pixels
+// Appropriate if nearest-neighbor sampling is used
+static void draw_string_integer(int x, int y, char *str) // draw with top-left point x,y
+{
+ ... use texture ...
+ ... turn on alpha blending and gamma-correct alpha blending ...
+ glBegin(GL_QUADS);
+ while (*str) {
+ int char_codepoint = *str++;
+ stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR];
+ glTexCoord2f(cd->s0, cd->t0); glVertex2i(x + cd->x0, y + cd->y0);
+ glTexCoord2f(cd->s1, cd->t0); glVertex2i(x + cd->x1, y + cd->y0);
+ glTexCoord2f(cd->s1, cd->t1); glVertex2i(x + cd->x1, y + cd->y1);
+ glTexCoord2f(cd->s0, cd->t1); glVertex2i(x + cd->x0, y + cd->y1);
+ // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct
+ x += cd->advance_int;
+ }
+ glEnd();
+}
+
+// This function positions characters on float coordinates, and doesn't require 1:1 texels to pixels
+// Appropriate if bilinear filtering is used
+static void draw_string_float(float x, float y, char *str) // draw with top-left point x,y
+{
+ ... use texture ...
+ ... turn on alpha blending and gamma-correct alpha blending ...
+ glBegin(GL_QUADS);
+ while (*str) {
+ int char_codepoint = *str++;
+ stb_fontchar *cd = &fontdata[char_codepoint - STB_SOMEFONT_FIRST_CHAR];
+ glTexCoord2f(cd->s0f, cd->t0f); glVertex2f(x + cd->x0f, y + cd->y0f);
+ glTexCoord2f(cd->s1f, cd->t0f); glVertex2f(x + cd->x1f, y + cd->y0f);
+ glTexCoord2f(cd->s1f, cd->t1f); glVertex2f(x + cd->x1f, y + cd->y1f);
+ glTexCoord2f(cd->s0f, cd->t1f); glVertex2f(x + cd->x0f, y + cd->y1f);
+ // if bilerping, in D3D9 you'll need a half-pixel offset here for 1:1 to behave correct
+ x += cd->advance;
+ }
+ glEnd();
+}
+*/
+
+#ifndef STB_FONTCHAR__TYPEDEF
+#define STB_FONTCHAR__TYPEDEF
+typedef struct
+{
+ // coordinates if using integer positioning
+ float s0,t0,s1,t1;
+ signed short x0,y0,x1,y1;
+ int advance_int;
+ // coordinates if using floating positioning
+ float s0f,t0f,s1f,t1f;
+ float x0f,y0f,x1f,y1f;
+ float advance;
+} stb_fontchar;
+#endif
+
+#define STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH 256
+#define STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT 317
+#define STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT_POW2 512
+
+#define STB_FONT_consolas_bold_50_usascii_FIRST_CHAR 32
+#define STB_FONT_consolas_bold_50_usascii_NUM_CHARS 95
+
+#define STB_FONT_consolas_bold_50_usascii_LINE_SPACING 33
+
+static unsigned int stb__consolas_bold_50_usascii_pixels[]={
+ 0x207fffff,0x08000000,0x00000000,0x0aa88000,0x2ea60000,0x359950cc,
+ 0x66540003,0xcccccccc,0x999950cc,0x99999999,0x3bb20001,0x8800002e,
+ 0x000000aa,0x2aaaa200,0x2aaaa61a,0x3fffe0aa,0x000ed83f,0x00fe6000,
+ 0xdfb95100,0x00000379,0x027fffd4,0xffffd300,0x3fff61ff,0xc8004fff,
+ 0xffffffff,0xff91ffff,0xffffffff,0x3a0003ff,0x80002fff,0xfffffdc8,
+ 0x00001cdf,0x3ffff200,0x3ffff20f,0x3fffe0ff,0x077fec3f,0x7fcc0000,
+ 0xff70003f,0xffffffff,0xf9800003,0x003fffff,0x7ffffe44,0xfffb0fff,
+ 0x005fffff,0x7fffffe4,0x91ffffff,0xffffffff,0x0003ffff,0x0007fffe,
+ 0xffffff50,0x09ffffff,0xff100000,0xffc8bfff,0x3fe0ffff,0x3ff63fff,
+ 0x00000eff,0x0fffffe6,0xffffd880,0xffffffff,0x3f200001,0x006fffff,
+ 0x7ffffff4,0xfffb0fff,0x03ffffff,0x3fffff20,0x1fffffff,0xfffffff9,
+ 0x003fffff,0x01ffff30,0x7fffec00,0xffffffff,0x00000dff,0x3ffffee0,
+ 0x7ffffe42,0x3ffffe0f,0xffffff13,0xf500001d,0x009fffff,0x3fffffe6,
+ 0xffffffff,0xfb00002f,0x00ffffff,0x7fffffd4,0xffb0ffff,0xdfffffff,
+ 0x3ffff200,0xffffffff,0xffffff91,0x03ffffff,0x0ffff500,0x3fffa200,
+ 0xffffffff,0x01efffff,0xfffd0000,0xffff90df,0x7fffc1ff,0x3fffe63f,
+ 0x20000eff,0x4ffffff9,0xfffff100,0xffb757df,0x0003ffff,0xffffff70,
+ 0x7fff400d,0x4c00aeff,0x3ffffffc,0x7ffffc80,0xfff98000,0xba8801ff,
+ 0xacffffec,0xfffb0009,0xffffffff,0xbfffffff,0xff500000,0xff707fff,
+ 0xfff8ffff,0x7ffcc3ff,0x10005fff,0x0bfffffd,0x7fffff40,0xffffd102,
+ 0xff10000b,0x2005ffff,0x05fffffa,0xfffff980,0xffffc806,0xff980007,
+ 0x3ea01fff,0xffffffff,0x405fffff,0xeffffff9,0xffca889b,0x001fffff,
+ 0x7fffec00,0xffffb80f,0x7ffffc7f,0xfffff983,0xffd8003f,0x32005fff,
+ 0x401fffff,0x00fffff8,0xfffe9800,0x3ffee003,0xf90000ff,0xf900ffff,
+ 0x0000ffff,0x03fffff3,0xffffffd3,0xffffffff,0xfffe80bf,0x3ee00fff,
+ 0x005fffff,0x3fffe200,0xffff704f,0xfffff8ff,0xfffff503,0x7fd4001f,
+ 0x2a006fff,0x001fffff,0x007ffff5,0x4000c400,0x005ffffc,0x3ffffe60,
+ 0x7fffe400,0xff980007,0x7fd41fff,0xffffffff,0x5fffffff,0x3ffffea0,
+ 0xfffb801f,0x00001fff,0x03fffff9,0x1fffffea,0x407fffff,0x05fffffd,
+ 0xffffff10,0x7fff4003,0x7ff4003f,0x0000006f,0x4ffffd80,0x3ffe2000,
+ 0x7fe401ff,0x980007ff,0x221fffff,0xffffffff,0xffffffff,0x3ffa05ff,
+ 0x3e004fff,0x004fffff,0xbfffff00,0x7ffffd40,0x1fffffc6,0xffffff10,
+ 0xffffb005,0x7fcc009f,0xfc8006ff,0x00001fff,0x7fff4000,0x7fc0003f,
+ 0x7e402fff,0x80007fff,0x21fffff9,0xdffffffe,0xa9ffffaa,0xff305fdc,
+ 0x4003ffff,0x06fffffd,0xffffb800,0x3ffea02f,0x7fffc6ff,0x7ffdc03f,
+ 0x3e600fff,0x000effff,0x00bffff6,0x13fffea0,0xddddddd3,0xdddddddd,
+ 0x3fa007dd,0x40003fff,0x402fffff,0x007ffffc,0xfffff980,0xffffff31,
+ 0x837ffd47,0xfffff701,0xfffa800d,0xe80007ff,0x5406ffff,0x7c6fffff,
+ 0xe803ffff,0x202fffff,0x02fffffc,0x1bfffe20,0xfff13008,0xffff989f,
+ 0xffffffff,0x004fffff,0x007ffffd,0x2fffff80,0x3ffffe40,0x7ffcc000,
+ 0xffff71ff,0x5fffb8ff,0x7fffe400,0x7fc4004f,0x0000ffff,0x0fffffe6,
+ 0xdfffff30,0x03fffff8,0x6fffff98,0xdfffff10,0xffffc800,0x77ffed43,
+ 0xfffd6fec,0xfffff98b,0xffffffff,0xd004ffff,0x0007ffff,0x02fffff8,
+ 0x03ffffe4,0x7fffcc00,0xfffff91f,0x04fffd8b,0x7fffff40,0xffff8003,
+ 0x360001ff,0x400fffff,0x45fffff9,0x003fffff,0x01fffffd,0x07fffff7,
+ 0x0ffffe80,0x3ffffff2,0xfffb6fff,0xfffff98d,0xffffffff,0xd004ffff,
+ 0x0007ffff,0x02fffff8,0x03ffffe4,0x7fffcc00,0xfffff91f,0x1ffff41f,
+ 0x3ffffa00,0xfff8003f,0x10002fff,0x009fffff,0x8bfffff3,0x003fffff,
+ 0x07fffff7,0x01fffffd,0x2ffffc40,0xfffffff9,0x3ff6bfff,0x77774c7f,
+ 0xeeeeeeee,0x004fffff,0x005fffff,0x3ffffe80,0x3ffffe40,0x7ffcc000,
+ 0xffff71ff,0x3ffe19ff,0x7ffc002f,0xe8002fff,0x003fffff,0x3fffff90,
+ 0xfffff100,0x3fffff8b,0xfffff300,0xfffff98d,0x7ffd4005,0xfffff12f,
+ 0x29ffffff,0x0007fffc,0x27ffffdc,0x7ffffc40,0x7fec0002,0x7fe404ff,
+ 0x980007ff,0xf31fffff,0x7fffffff,0x8003ffff,0x01ffffff,0xfffffe80,
+ 0xffff0003,0x3fe200df,0x7ffc4fff,0x3fa003ff,0x3ee1ffff,0x4002ffff,
+ 0xfb1ffffc,0xffb7ffff,0x3fff27ff,0x3ee0000f,0xa804ffff,0x001fffff,
+ 0x7ffffec0,0x3ffff200,0xff980007,0x3ffe1fff,0xffffffff,0x7fc4007f,
+ 0x8001ffff,0x03fffffd,0xfffffa80,0xffff1002,0xfffff89f,0x3ffee003,
+ 0x3fff22ff,0x7f4000ff,0x3fffe7ff,0x7ffff90f,0x007fffee,0xfffffb80,
+ 0x7fff4404,0xfa80006f,0x3204ffff,0x0007ffff,0x1fffff98,0x3fffffe6,
+ 0x1cffffff,0x3ffffe00,0xffe8002f,0xe8002fff,0x2007ffff,0x44fffff8,
+ 0x003fffff,0x8fffffea,0x007ffffd,0x9b7fffc4,0x3f25ffff,0xfff72fff,
+ 0x7dc0003f,0x2a24ffff,0xfffffcba,0xfd00003f,0x559dffff,0x1fffff25,
+ 0x3ffe6000,0x7ffdc1ff,0xffffffff,0xfe802eff,0x8003ffff,0x01ffffff,
+ 0x7ffffcc0,0x7fffc003,0x7ffffc4f,0x3ffe6003,0x3fffa4ff,0x7fcc006f,
+ 0xffff94ff,0x8ffffec5,0x000ffffb,0x3ffffee0,0x3ffffe64,0x0004ffff,
+ 0x3ffffa60,0xff95ffff,0x30000fff,0x503fffff,0xfffffffd,0x3dffffff,
+ 0x7fffff40,0xffff8003,0x7ec000ff,0x4000ffff,0x7c3fffff,0x2003ffff,
+ 0x25fffff8,0x005fffff,0xd97fffd4,0x3fa1ffff,0xfff90fff,0xffb8000f,
+ 0x3fe64fff,0x02dfffff,0xfeb88000,0xf95fffff,0x0000ffff,0x03fffff3,
+ 0x7fffffe4,0xffffffff,0xfffffb03,0xfff88009,0x7c4007ff,0x8005ffff,
+ 0x7c3fffff,0x4003ffff,0xf15fffff,0x8009ffff,0xfd2ffffa,0x7ff41fff,
+ 0xffff90ff,0xfffb8000,0x3ffe64ff,0x002cffff,0xffeb8800,0xff95ffff,
+ 0x30000fff,0x803fffff,0xfffffea8,0x2fffffff,0x6fffffc8,0x7fffd400,
+ 0x7fdc007f,0xf8001fff,0x7fc3ffff,0x7c003fff,0xff36ffff,0xb8007fff,
+ 0xfff1ffff,0x7ffff8ff,0x001ffff2,0x9fffff70,0x7fffffcc,0x00004fff,
+ 0x3fffffe6,0xfff95fff,0xf30000ff,0x2003ffff,0xfffffff8,0x41ffffff,
+ 0x0ffffffb,0x3ffff200,0x7ffc005f,0xfd0006ff,0xfff85fff,0x7f4003ff,
+ 0xfff36fff,0xfb8009ff,0xffff1fff,0x26ffff8d,0x0006fffd,0x27ffffdc,
+ 0xfffb7551,0x00005fff,0x3bfffffe,0xfff92aac,0xf30000ff,0x2003ffff,
+ 0xffcffffa,0x44ffffff,0x3ffffff8,0x3ffffe00,0x3fea001f,0xd0002fff,
+ 0xff85ffff,0x7c003fff,0xff35ffff,0xc800bfff,0xff88ffff,0x3ffe26ff,
+ 0x1bfffa6f,0xffff7000,0xfff9809f,0xa80006ff,0x204fffff,0x007ffffc,
+ 0xfffff980,0xdfff7001,0x3fffff62,0xffffd86f,0xffb800ef,0x74006fff,
+ 0x0007ffff,0x7ffffc00,0x3ffe2003,0xffff14ff,0xffd800df,0xffff88ff,
+ 0x93fffe66,0x0004ffff,0x27ffffdc,0x7ffffdc0,0x7fec0001,0x7fe406ff,
+ 0x980007ff,0x001fffff,0xfe89fff9,0xfa87ffff,0x00efffff,0x3fffffea,
+ 0x3ffe6003,0x000004ff,0x01fffffc,0x7fffff30,0x037ffffc,0x45ffff60,
+ 0x3ea6ffff,0xfff14fff,0xfb80005f,0x8804ffff,0x001fffff,0x27ffff40,
+ 0x1fffff20,0x3ffe6000,0xffb001ff,0xffffb87f,0xffff80ff,0x260aefff,
+ 0x7ffffffb,0x7fffe400,0x4000000f,0x003fffff,0x8bffffe6,0x007ffffe,
+ 0xf87fffe4,0x3ff66fff,0xffff74ff,0xffb80001,0xff004fff,0x80005fff,
+ 0x403ffffe,0x007ffffc,0xfffff980,0x5fffd001,0x6fffffa8,0xffffff70,
+ 0xffffffff,0x005fffff,0x2fffffc4,0x3bf66000,0x3fffff84,0x3fffee00,
+ 0x3ffff61f,0x3ff2001f,0xffffd0ff,0x9fffff51,0x0017fffa,0x3ffffee0,
+ 0xffffd004,0xfff80007,0x7fe402ff,0x980007ff,0x001fffff,0xfc83ffff,
+ 0x3205ffff,0xffffffff,0xffffffff,0x7fdc003f,0x20001fff,0x45fffff9,
+ 0x003fffff,0x83fffff6,0x04fffffc,0x47fffee0,0xffeffffd,0xffefffff,
+ 0xb80003ff,0x004fffff,0x007ffffd,0x2fffff80,0x3ffffe40,0x7ffcc000,
+ 0x103791ff,0x7dc1ffff,0x403fffff,0xfffffffc,0xffffffff,0xfffe8003,
+ 0x7ec0006f,0x3e1fffff,0x1003ffff,0x98bfffff,0x006fffff,0x5cbfffea,
+ 0xffffffff,0xffffffff,0xfb80000e,0xd004ffff,0x0007ffff,0x02fffff8,
+ 0x03ffffe4,0x7fffcc00,0x9bfffb1f,0x73ffff75,0xfffffffd,0xffff9001,
+ 0xffffffff,0xff50005d,0x80007fff,0x3fffffff,0x00fffffe,0x17ffffdc,
+ 0x0ffffff4,0x3ffff980,0xfffffff1,0xffffffd7,0x2e00001f,0x004fffff,
+ 0x007ffffd,0x2fffff80,0x3ffffe40,0x7ffcc000,0xffffb1ff,0xffffffff,
+ 0xffffffff,0xffea8003,0x02dfffff,0x3ffff600,0xffe80007,0x3fe2ffff,
+ 0xfd003fff,0x3ee0ffff,0x1004ffff,0x7d47ffff,0xff34ffff,0x0003ffff,
+ 0x7ffffdc0,0xffffd004,0xfff80007,0x7fe402ff,0x980007ff,0xfb1fffff,
+ 0xffffffff,0xffffffff,0x540005ff,0x003fffff,0x7ffffcc0,0xffc80004,
+ 0x3fe0ffff,0xf9803fff,0xf104ffff,0x001fffff,0x98dffff1,0x6dcc1cec,
+ 0xb800002c,0x004fffff,0x007ffffd,0x2fffff80,0x3ffffe40,0x7ffcc000,
+ 0xffffb1ff,0xffffffff,0x05dfffff,0xffff8800,0x7e40005f,0x0000ffff,
+ 0x85ffffb0,0x803fffff,0x01fffffd,0x13fffff6,0x0fffffc0,0x00000000,
+ 0x0fffffee,0x1fffff40,0x3fffe000,0x7ffe402f,0xf980007f,0xffb1ffff,
+ 0xffffffff,0x05dfffff,0x7fff4000,0x880601ff,0x005fffff,0x4055d400,
+ 0x403fffff,0x06fffffa,0x7fffffd4,0xffffc801,0x00000003,0x7ffffe40,
+ 0xffffb002,0x7fc40009,0x7e401fff,0x80007fff,0x41fffff9,0xfffedba9,
+ 0x001acdef,0xffffd800,0x27e443ff,0x2fffffb8,0x7c000000,0x2203ffff,
+ 0x01ffffff,0x6fffffd8,0x6ffff980,0x00000000,0x0fffffec,0x5ffffc80,
+ 0x3ffe6000,0x7fe400ff,0x980007ff,0x401fffff,0x000ffff9,0xfffa8000,
+ 0xffefffff,0xffe81fff,0x000006ff,0x3fffff80,0x3fffff20,0xffff1004,
+ 0xffd007ff,0x000005ff,0x3ffe2000,0x3ee007ff,0x0000ffff,0x00fffff7,
+ 0x00fffff9,0xfffff300,0x7fffa803,0x36000000,0xffffffff,0x546fffff,
+ 0x003fffff,0xfff80000,0xfff503ff,0xfa800dff,0x401fffff,0x02fffffb,
+ 0x00400440,0xdfffff90,0x7fffd400,0xff88004f,0xfc806fff,0x80007fff,
+ 0x01fffff9,0x002fffdc,0xffd10000,0xffffffff,0x7fec5fff,0x00000fff,
+ 0xfffff800,0xfffff983,0xffd8001f,0x2200ffff,0x01ffffff,0x4400fc88,
+ 0x7fe402df,0x2003ffff,0xdffffff8,0xfffb8801,0xfc803fff,0x80007fff,
+ 0x01fffff9,0x0027ffe4,0x3f220000,0xffffffff,0x4cccc1ef,0x00000009,
+ 0x87fffff0,0x3ffffff9,0xffff1000,0x7e401dff,0x1bdfffff,0x1fffb733,
+ 0xeffff880,0xfffedccc,0xb8005fff,0xffffffff,0xfffd90ef,0x00dfffff,
+ 0x3ffffff2,0x91ffffff,0xffffffff,0xe803ffff,0x00003fff,0xffdb1000,
+ 0x0007bdff,0xf0000000,0x7c47ffff,0x005fffff,0x7ffffcc0,0x3ffa00ef,
+ 0xffffffff,0x00ffffff,0x7fffffc4,0xffffffff,0xfd0000ff,0xffffffff,
+ 0x3fffff61,0x9002ffff,0xffffffff,0x3f23ffff,0xffffffff,0x7fc01fff,
+ 0x000002ff,0x00131000,0x00000000,0x13fffff8,0x0bfffffd,0x3ffe6000,
+ 0x3a205fff,0xffffffff,0x0fffffff,0x7ffffc40,0xffffffff,0x220002ff,
+ 0xfffffffe,0xfffffb0f,0x64007fff,0xffffffff,0xff91ffff,0xffffffff,
+ 0x000003ff,0x00000000,0x00000000,0x3fffff80,0x017ffff6,0xffff3000,
+ 0xfff9003f,0xffffffff,0xff1007df,0xffffffff,0x00019fff,0x3ffffaa0,
+ 0xffffb0ff,0xc8001bff,0xffffffff,0xff91ffff,0xffffffff,0x000003ff,
+ 0x00000000,0x00000000,0x3fffff80,0x0002ffec,0x01fff980,0x3fffae20,
+ 0x001cefff,0x7fffedc4,0x000ceeff,0x99753000,0x2af32a19,0x99500009,
+ 0x99999999,0x3332a199,0xcccccccc,0x0000000c,0x00000000,0x00000000,
+ 0x41fffffc,0x4000005d,0x440001f9,0x10000019,0x00000033,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x7fc00000,0x00003fff,0x00002000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x7ffffc00,0x00000003,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0xf8000000,0x0003ffff,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x55555500,0x20000000,0x00000999,
+ 0x00002620,0x33bf6e60,0x5554c002,0x026aaa0a,0x77774c00,0xeb8001ee,
+ 0x0004eeee,0x001004cc,0x4002a620,0x00aaaaa9,0x2a200000,0x7fe4000a,
+ 0x00000fff,0xfffed980,0xeeeeefff,0xb7005eee,0x07dfffff,0xffff7000,
+ 0x1001bfff,0x7c4dffff,0x2cefffff,0x3ffffa00,0xffe8005f,0x2a003fff,
+ 0xfffffedb,0x70ffdbbd,0xea87dddd,0x02deffff,0x0bfffff2,0x7dc00000,
+ 0x26004fff,0x003fffff,0x3ff62000,0xffffffff,0x6fffffff,0x7ffff4c0,
+ 0x02efffff,0xfffff900,0x900bffff,0x7c43ffff,0xffffffff,0xfffb802e,
+ 0x26000fff,0x00ffffff,0xfffffe98,0xffffffff,0xffff90ff,0x3ffff629,
+ 0x903fffff,0x005fffff,0xfff30000,0x74005fff,0x0007ffff,0xfffff100,
+ 0xffffffff,0x0dffffff,0x7fffffdc,0x2fffffff,0x7fffc400,0x1fffffef,
+ 0x0ffffe60,0xfffffff1,0x405dffff,0x2ffffff8,0x3ffff200,0xfffb805f,
+ 0xffffffff,0x90ffffff,0xff19ffff,0xffffffff,0xfff909ff,0x000005ff,
+ 0xffffff90,0x7ffd400d,0x800002ff,0xfffffffe,0xfffffffe,0xf306ffff,
+ 0xffffffff,0x01ffffff,0x8f7ffe40,0x205ffffa,0xf886fffe,0xffffffff,
+ 0x3602ffff,0x005fffff,0x0bfffffe,0xffffffd0,0xffffffff,0x3f21ffff,
+ 0xfffedfff,0xffffffff,0x7ffe43ff,0x000002ff,0xffffffd8,0x7fffc007,
+ 0x6400006f,0x41efffff,0xcffffffa,0xfffd03cc,0xff957dff,0x400bffff,
+ 0x7e44fffe,0xfff906ff,0xffff103f,0xffffffff,0x3fea03ff,0x9800ffff,
+ 0x406fffff,0xfffffffb,0xffeccace,0xff90ffff,0xffffffff,0xffffffdf,
+ 0xffffc8ff,0x8000002f,0x5ffffffc,0x7fffdc00,0x3e00001f,0x2206ffff,
+ 0x403fffff,0x84fffffa,0x07fffff9,0x70bfffe0,0xff30ffff,0x533009ff,
+ 0xfffffff9,0x3ffe01ff,0xfc803fff,0x2203ffff,0x1fffffff,0x3fffffa0,
+ 0xffffff90,0x36217dff,0x22ffffff,0x02fffffc,0xff880000,0x4002ffff,
+ 0x04fffff8,0xffff1000,0xfffc805f,0x7ffdc07f,0xfff900ff,0xff1001ff,
+ 0xfff983ff,0x06fffe87,0xffff7100,0x3ee0bfff,0xf806ffff,0x200fffff,
+ 0x0efffffd,0x7fffff40,0xffffff90,0x7ffec0bf,0x3fff26ff,0x000002ff,
+ 0x05fffd30,0x3ffff600,0xfa80000f,0x5400ffff,0x200fffff,0x206ffffd,
+ 0x01fffffa,0x42ffff88,0x7e47fffb,0x40001fff,0x7ffffffa,0xffffff10,
+ 0x7fffd403,0x3ffe605f,0xfe802fff,0xff90ffff,0x401dffff,0x0ffffffa,
+ 0x05fffff9,0x18800000,0x7ffcc000,0xb80003ff,0xa807ffff,0x200fffff,
+ 0x206ffffe,0x00fffffb,0xc89ffff0,0x3fe65fff,0x900004ff,0x01ffffff,
+ 0x13fffff6,0x2fffffd8,0x3ffffee0,0xffffd006,0x3ffff21f,0xfff800ef,
+ 0xfff91fff,0x026203ff,0x00000000,0x037ffff4,0x7fffd400,0x7ffdc00f,
+ 0x7ffe407f,0xfffb00ff,0x7ff400df,0xffff51ef,0x037fff49,0xffff3000,
+ 0x3fea05ff,0xff107fff,0xfc80ffff,0xd003ffff,0x321fffff,0x002fffff,
+ 0x25fffffb,0x21fffffc,0xdefffeca,0x00000002,0x3ffffea0,0x7fc40002,
+ 0x7f403fff,0x7dc05fff,0xfa82ffff,0x2004ffff,0xfefffffa,0xff70ffff,
+ 0x800003ff,0x03ffffff,0x0bfffffe,0x13ffffee,0x5fffffb0,0x3ffffa00,
+ 0xfffff90f,0x3fff6005,0xffff93ff,0x3ffff23f,0x203fffff,0xeeeeeeeb,
+ 0x002eeeee,0x17ffffe0,0x3fffe000,0xfff901ff,0xff9809ff,0x3ea0ffff,
+ 0x000fffff,0x7ffffff4,0xfff33fff,0x8800009f,0x02ffffff,0x17fffff2,
+ 0x03fffffa,0x3fffffd0,0x3ffffa00,0xfffff90f,0x3fff2005,0xffff94ff,
+ 0xfffffb3f,0x09ffffff,0x3ffffff2,0x03ffffff,0x3ffff200,0x7d40001f,
+ 0xaacfffff,0xffffffeb,0xffffd800,0xffffc8df,0xd88002ff,0x2fffffff,
+ 0x003bfffa,0xffff5000,0x7fc401ff,0x3e60ffff,0xf806ffff,0x000fffff,
+ 0x21fffffd,0x02fffffc,0x9fffff90,0x3bfffff2,0xffffffff,0xc83fffff,
+ 0xffffffff,0x0003ffff,0x13ffffe2,0x3fff6000,0xffffffff,0x3001ffff,
+ 0xffffffff,0x007fffff,0xbdfeca80,0x0bfffee0,0xfff10000,0xfb00ffff,
+ 0x7e45ffff,0x4402ffff,0x00ffffff,0x1fffffd0,0x0bfffff2,0x7ffffec0,
+ 0xffffff93,0xffdfffff,0x90ffffff,0xffffffff,0x0007ffff,0x0fffffd8,
+ 0x3ffe2000,0xffffffff,0x4003ffff,0xfffffffc,0x0001ffff,0xffff8800,
+ 0x73100004,0x7fffffff,0xfffff500,0x3fffffcb,0xffffff80,0xffffd001,
+ 0x3ffff21f,0xfffb002f,0x3fff25ff,0x0befffff,0xffffffb1,0xeeeeeb85,
+ 0x3ffffffe,0x7ffcc000,0x360003ff,0xffffffff,0x00cfffff,0xfffffd00,
+ 0x00019fff,0x3fffa000,0x3fe0000f,0xffffffff,0x3fe006ff,0xff98ffff,
+ 0xfd004fff,0x2003ffff,0x90fffffe,0x005fffff,0x43fffffe,0xfffffffc,
+ 0x3ffff605,0x3ff2006f,0x80003fff,0x006ffffe,0x2dffff50,0x0abcdcca,
+ 0x3ffe6000,0x001fffff,0x3fee0000,0x7c0002ff,0xffffffff,0x32001fff,
+ 0xfcbfffff,0xb001ffff,0x007fffff,0x1ffffff5,0x0bfffff2,0x3ffffe60,
+ 0x3fffff27,0x3fea00ef,0x9000ffff,0x007fffff,0xfffff700,0xfffb0005,
+ 0x4000005f,0xfffffffb,0x999904ff,0x7c400039,0x80005fff,0xffffffff,
+ 0x4c000dff,0xffefffff,0x32006fff,0x405fffff,0xfffffff9,0x5fffff90,
+ 0xfffffb00,0x7ffffe4d,0xffff800e,0xff9001ff,0x00007fff,0x017ffffe,
+ 0x0fffffe0,0x7fdc0000,0xffffffff,0x7fffc43f,0x3f60002f,0x80000fff,
+ 0xffffffff,0x3fa0002d,0xffffffff,0x3fea003f,0xf100ffff,0x1fffffff,
+ 0x0bfffff2,0xffffff50,0x7ffffe47,0xffffb002,0x3ff2005f,0x00003fff,
+ 0x01fffff9,0xffffff80,0x7d400002,0xffefffff,0x3e21ffff,0x0001ffff,
+ 0x885ffff5,0xfd0009aa,0x0003dfff,0x3ffffea0,0x000fffff,0x77fffffc,
+ 0x7ffff5c0,0xff90ffff,0x7dc05fff,0x645fffff,0x002fffff,0x07fffffb,
+ 0x3fffff20,0xff100003,0xd8009fff,0xefffffff,0x9accdeee,0xffffe800,
+ 0xfffffd3f,0x3fffe21f,0xff88000f,0x3ffea5ff,0xfe804fff,0x00004fff,
+ 0x7ffffffc,0xfb8004ff,0xcdffffff,0xffffffff,0xfff90fff,0x75559dff,
+ 0xfffffffb,0xfffffc81,0xffff9002,0x3ff2009f,0x00003fff,0x03fffff6,
+ 0xfffffa80,0xffffffff,0x501dffff,0x449fffff,0x8effffff,0x007ffffa,
+ 0x21ffffb0,0xfffffffc,0x3ff600ef,0x400004ff,0xfffffffc,0xff88001f,
+ 0xffffffff,0xffffffff,0xffff90ff,0xffffffff,0x07ffffff,0x05fffff9,
+ 0x3fffff20,0xffff9004,0x5400007f,0x003fffff,0x7fffffd4,0xffffffff,
+ 0xfe84ffff,0x7cc1ffff,0xfbdfffff,0xa8007fff,0xff33ffff,0xffffffff,
+ 0x7fffec09,0x7cc00003,0x05ffffff,0x3fffea00,0xffffffff,0x0fffffcd,
+ 0xfffffff9,0xffffffff,0x3ff207ff,0xfb002fff,0x2007ffff,0x03fffffc,
+ 0x7fff4000,0x7f44006f,0xffffffff,0xffffffff,0x7ffffc3f,0xfffff707,
+ 0x09ffffff,0x5ffff880,0x2efffffa,0xb00fffff,0x0007ffff,0xfffffd00,
+ 0xf980003f,0xffffffff,0xfffff94f,0x3fffff21,0xffffffff,0x3f200dff,
+ 0xb002ffff,0x005fffff,0x0ffffff2,0xfff70000,0x3a6003ff,0xeeefffff,
+ 0xfffffeee,0xff10ffff,0x7e40bfff,0xffffffff,0x7fec001f,0xffff30ff,
+ 0x17fffc43,0x20000000,0x05fffffe,0xfffb3000,0x7ec5dfff,0xff90ffff,
+ 0xffffffff,0x9005bdff,0x005fffff,0x03fffffe,0x7ffffe40,0x7c400003,
+ 0x8805ffff,0x01fffffe,0x7ffffe44,0xfffff12f,0xffffd80b,0x4006ffff,
+ 0x2a3ffffa,0xfff87fff,0x0000003f,0x3ffffea0,0x9800002f,0xffd81abb,
+ 0xfff90fff,0x355535ff,0xffff9000,0xfff3005f,0x7e400fff,0x0003ffff,
+ 0xfffffc80,0x7fffe400,0x3ff2002f,0x3ffe4fff,0x7f4407ff,0x03ffffff,
+ 0x1bfffe20,0xfb0dfff7,0x008809ff,0xffe88000,0x00006fff,0x3fff6000,
+ 0xffff90ff,0x3200005f,0x802fffff,0x06fffffd,0x3fffff20,0xf9800003,
+ 0x7c04ffff,0x4007ffff,0x24fffffb,0x02fffffe,0x7fffffcc,0x3ff2000f,
+ 0x7ffdc1ff,0x04fffd86,0x003dfff5,0x7fffec00,0x000001ff,0x3ffffa00,
+ 0xfffff90f,0x3f200005,0x5402ffff,0x03ffffff,0x3fffff20,0xfb000003,
+ 0x7c40ffff,0x4007ffff,0x22fffffc,0x1ffffffc,0x3ffffea0,0xff5004ff,
+ 0xfff507ff,0x07ffff0f,0x3ffffff3,0xffe98000,0x0002ffff,0x7ff40000,
+ 0xfff90fff,0x200005ff,0x02fffffc,0x3fffffee,0x7ffe4005,0x000003ff,
+ 0x05fffff5,0x17fffffc,0xfffffa80,0x3fffe60f,0xba9bdfff,0xfffffffd,
+ 0x7f4403ff,0xfff306ff,0x7fffc43f,0xfffffd82,0x3bb2005f,0xfffffffe,
+ 0x0000004f,0xfffffe80,0x5fffff90,0x3ff20000,0xaaacefff,0xffffffdb,
+ 0x7fe4000f,0x00003fff,0x1bffffa0,0xffffffd8,0x7ecc41ac,0xc84fffff,
+ 0xffffffff,0xffffffff,0x02ffffff,0x407ffff2,0xbcfffff8,0xff06ffff,
+ 0x00dfffff,0x7fffffe4,0x0006ffff,0xffd00000,0x3ff21fff,0x00002fff,
+ 0xfffffff9,0xffffffff,0x99307fff,0xffd99999,0x9999dfff,0xb8000599,
+ 0x501fffff,0xffffffff,0xffffffff,0x740bffff,0xffffffff,0xffffffff,
+ 0x80ffffff,0x403ffff9,0xfffffffb,0xffd02fff,0x400bffff,0xfffffffc,
+ 0x00000dff,0xfffd0000,0x3fff21ff,0x900002ff,0xffffffff,0xffffffff,
+ 0x3ffee07f,0xffffffff,0xffffffff,0x7c40004f,0x2a05ffff,0xffffffff,
+ 0xffffffff,0x7e4406ff,0xffffffff,0xff8aefff,0x740effff,0xfd006fff,
+ 0x9fffffff,0x7ffffdc0,0x3ff2002f,0x02efffff,0x40000000,0x90fffffe,
+ 0x005fffff,0x3ffff200,0xffffffff,0x2e00dfff,0xffffffff,0xffffffff,
+ 0x0004ffff,0x0fffffc8,0x3ffffaa0,0xffffffff,0x22002dff,0xfffffffd,
+ 0x7ffcc3ff,0x3ff25fff,0x3ee001ff,0x802fffff,0x004ffffc,0x677fffe4,
+ 0x00000003,0xfffffd00,0x3fffff21,0x2e600002,0xfffffffd,0xb802deff,
+ 0xffffffff,0xffffffff,0x0004ffff,0x4fffff98,0xfffec980,0x1cdeffff,
+ 0x654c4000,0x0000009a,0x01553000,0x001bb980,0x00003330,0x2e000000,
+ 0x950ccccc,0x00039999,0x554cc400,0xffb8001a,0xffffffff,0xffffffff,
+ 0xd00004ff,0x000fffff,0x00002662,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0xf5000000,0x0005ffff,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0xfffff000,0x555554cd,0x00000000,0x77ff65d4,0x55511bce,0x80000355,
+ 0xaaaaaaa9,0x001aaaaa,0x26000000,0x2000000b,0x00000aa8,0x13555100,
+ 0x2a660000,0x000099aa,0xf7000000,0x3f23ffff,0x0002ffff,0xffd50000,
+ 0xffffffff,0x3ffffea9,0x7e400004,0xffffffff,0x20003fff,0x000cefea,
+ 0x07fff6e6,0xfdc98000,0x1cdfffff,0xdca88000,0xffffffff,0x36a000bd,
+ 0xffffffff,0xea81bdff,0x00000cef,0x09999980,0x05fffff9,0xe8800000,
+ 0xffffffff,0xff54ffff,0x00009fff,0xffffffc8,0x03ffffff,0xfffff700,
+ 0x3ffa001d,0x00001fff,0xfffffff7,0x009fffff,0x7ffffdc0,0xffffffff,
+ 0xffe9803f,0xffffffff,0x2e0fffff,0x00efffff,0x32000000,0x002fffff,
+ 0x7fec0000,0xffffffff,0xfff54fff,0x800009ff,0xfffffffc,0x003fffff,
+ 0xffffff98,0xfffd004f,0x880003ff,0xfffffffd,0xdfffffff,0x3ff62000,
+ 0xffffffff,0x403fffff,0xfffffffb,0xffffffff,0xffff30ff,0x00009fff,
+ 0x15555540,0x05fffff9,0x7d400000,0xefffffff,0xf54fffee,0x0009ffff,
+ 0xfffffc80,0x3fffffff,0xffffb800,0xfd007fff,0x0003ffff,0x7fffffcc,
+ 0xffffffff,0x9801efff,0xfffffffe,0xffffffff,0xfffd103f,0xffffffff,
+ 0x1fffffff,0x3fffffee,0x2000007f,0x90fffffe,0x005fffff,0x3fe20000,
+ 0x102fffff,0x3fffea53,0x4400004f,0xfd999999,0x8003ffff,0xfffffffc,
+ 0xfffe800f,0x3a0001ff,0xffffffff,0xffffffff,0x7fcc05ff,0xffffffff,
+ 0xffffffff,0xfffff883,0xffffffff,0x0fffffff,0xfffffff9,0x2000001f,
+ 0x90fffffe,0x005fffff,0x3fe60000,0x2001ffff,0x04fffffa,0x3f200000,
+ 0x8003ffff,0xfffffffa,0xffffd006,0x3ea0003f,0x1befffff,0xfffff951,
+ 0x7ff403ff,0x9bdfffff,0x7ffb5310,0xffffff90,0x4c4159df,0xf50fffca,
+ 0x0dffffff,0x7ff40000,0xfff90fff,0x000005ff,0x3ffffea0,0x7ffd4004,
+ 0x000004ff,0x3fffff20,0xfff88003,0xd003ffff,0x003fffff,0x3fffffa0,
+ 0x3ffee00e,0xff505fff,0x005fffff,0xfff30aa2,0x800bffff,0xffff10c9,
+ 0x00007fff,0x7fffff40,0x5fffff90,0x32000000,0x002fffff,0x27ffffd4,
+ 0xf9000000,0x0007ffff,0x17ffffe6,0xfdddddd7,0xdddfffff,0x8bdddddd,
+ 0x0ffffffb,0xfffffb80,0xffffe80f,0xd80001ff,0x03ffffff,0xffff3000,
+ 0x800000bf,0x90fffffe,0x105fffff,0x20000153,0x01fffffd,0x7ffffd40,
+ 0x20000004,0x03fffffc,0x0b36e200,0x3ffffff2,0xffffffff,0x6fffffff,
+ 0x1ffffffc,0xffffff00,0xfffffb89,0xfa80002f,0x004fffff,0x166dc400,
+ 0x7f400000,0xff90ffff,0x7f543fff,0x001dffff,0x3fffffa0,0x7ffd4000,
+ 0x76c404ff,0x001eeeee,0x0ffffff2,0xff900000,0xffffffff,0xffffffff,
+ 0x7fccdfff,0x2001ffff,0x46fffffd,0x07ffffff,0xffffd000,0x000001ff,
+ 0xd0000000,0x321fffff,0xd89fffff,0xffffffff,0xffd0003f,0xa8001fff,
+ 0x404fffff,0x3ffffffd,0x7fffe400,0x4000003f,0xfffffffc,0xffffffff,
+ 0x26ffffff,0x06fffffb,0x7ffffd40,0x3ffffe27,0xff00003f,0x0009ffff,
+ 0x00000000,0x3fffffa0,0x3fffff90,0xfffffffd,0x0007ffff,0x01fffffd,
+ 0xfffffa80,0x3ffff204,0xfc8004ff,0x0003ffff,0x77775c00,0xffffffee,
+ 0xeeeeeeee,0x3ffff65e,0x7fc4004f,0xff30ffff,0x0001ffff,0xffffff10,
+ 0x00000001,0x42660000,0x90fffffe,0xffdfffff,0xffffffff,0x26660fff,
+ 0xfffe9999,0x99999aff,0x3fea0999,0xff704fff,0x000bffff,0x0ffffff2,
+ 0xe8000000,0x001fffff,0x1ffffff4,0x7ffffc00,0xfffff51f,0x3e60000f,
+ 0x0007ffff,0x50000000,0xfffffdb9,0x21ffffff,0xfffffffc,0xfffeffff,
+ 0xff83ffff,0xffffffff,0xffffffff,0x3ea6ffff,0xf984ffff,0x006fffff,
+ 0x3fffff20,0x00000003,0x07fffffa,0xffffff00,0xffff0007,0x3ffee3ff,
+ 0x500006ff,0x40dfffff,0xaaaaaaaa,0x00000aaa,0xfffffd30,0xffffffff,
+ 0x3fff21ff,0x0befffff,0xbfffffd5,0xfffffff0,0xffffffff,0xdfffffff,
+ 0x27ffffd4,0x3fffffe2,0x3f20000e,0x0003ffff,0x3ffa0000,0x7c001fff,
+ 0x002fffff,0x2fffffe8,0x0bfffffb,0x3ffee000,0xfff105ff,0xffffffff,
+ 0xc8800003,0xffffffff,0xffffffff,0xfffff90f,0x3fea0bff,0xfff86fff,
+ 0xffffffff,0xffffffff,0x3fea6fff,0x3fa24fff,0x000fffff,0x7ffffe40,
+ 0x00000003,0x07fffffa,0xffffff00,0xfffd0003,0x3fffa7ff,0xb00004ff,
+ 0x209fffff,0xfffffff8,0x0001ffff,0x7fffff40,0xffffffff,0xf90fffff,
+ 0x01dfffff,0x1fffffe2,0x3ffffffe,0xffffffff,0x6fffffff,0x93ffffea,
+ 0x1ffffffd,0xfffc8000,0x2e0003ff,0x74004efe,0x001fffff,0x0ffffffc,
+ 0x7fffec00,0xffffff3f,0x3fa00009,0xf104ffff,0xffffffff,0x002203ff,
+ 0xffffff70,0xfd9959df,0x321fffff,0x00efffff,0x07fffff4,0x2aaaaaaa,
+ 0xabfffffe,0x2aaaaaaa,0x53ffffea,0x2ffffffc,0xfff90000,0x320007ff,
+ 0x00dfffff,0x3fffffd0,0xfffff800,0xffe8002f,0xfffd3fff,0x20000bff,
+ 0x04fffffd,0xfffffff1,0xfb83ffff,0xf8801eff,0x01ffffff,0x43fffffa,
+ 0x02fffffc,0x0fffffe8,0x3ffffa00,0x7fd4000f,0xfffacfff,0x00003fff,
+ 0x0ffffff2,0x3fffe200,0xfd004fff,0x8003ffff,0x03fffffe,0xffffff80,
+ 0xdfffffb2,0x3ff20000,0x2aa05fff,0xffffeaaa,0x3ffff61f,0x7fec01ff,
+ 0x7400efff,0xf90fffff,0xd005ffff,0x001fffff,0x07fffff4,0x3fffea00,
+ 0xffffffef,0x7e400003,0x8003ffff,0xfffffffa,0xfffe800f,0x7ec001ff,
+ 0x8003ffff,0x92ffffff,0x00ffffff,0x3fffee00,0x7fec006f,0xfff31fff,
+ 0x4c0bffff,0x02ffffff,0x0fffffe8,0x05fffff9,0x1fffffd0,0x7ffff400,
+ 0x7fd4000f,0xffffffff,0xc800006f,0x003fffff,0xffffffa8,0xffe802ff,
+ 0x64001fff,0x004fffff,0x7fffffc4,0xffffff71,0x3fe60000,0x6c007fff,
+ 0xf71fffff,0x0fffffff,0x37ffffd4,0xfffffe80,0x5fffff90,0xfffffd00,
+ 0x7fff4001,0x7d4000ff,0xffffffff,0x00003fff,0x1fffffe4,0x7fffc400,
+ 0xe803ffff,0x001fffff,0x37ffffdc,0x3fffea00,0x3fffea7f,0x880003ff,
+ 0x01ffffff,0x3fffff60,0xffffff91,0x7ffe40ff,0xffd003ff,0x3ff21fff,
+ 0xfe802fff,0x2000ffff,0x00fffffe,0x7ffffd40,0xffffffdc,0x3f200001,
+ 0x0003ffff,0xfffffff5,0xffffd009,0xffa8003f,0x2000ffff,0x25fffffc,
+ 0x6ffffff9,0xffff0000,0x7ec00bff,0xff51ffff,0x40dfffff,0x02fffffd,
+ 0x1fffffd0,0x0bfffff2,0x3fffffa0,0x3fffa000,0x7d4000ff,0xfe8cffff,
+ 0x000fffff,0xfffff900,0x7fe40007,0xe803ffff,0x001fffff,0x7fffffc4,
+ 0x3fffe003,0x7fffc3ff,0x80002fff,0x0ffffffe,0xfffffb00,0x7fffff43,
+ 0x3fffa02f,0xffd001ff,0x3ff21fff,0xfe802fff,0x2000ffff,0x00fffffe,
+ 0x7ffffd40,0xffffff34,0x3f20000d,0x0003ffff,0x17fffff4,0x7fffff40,
+ 0xfffd8002,0xfb800eff,0xfb87ffff,0x01efffff,0x7fffcc00,0xffb005ff,
+ 0x7f443fff,0x7fc03fff,0xd000ffff,0x321fffff,0x802fffff,0x00fffffe,
+ 0x3fffffa0,0x7ffd4000,0x3ffee4ff,0x80005fff,0x03fffffc,0x7fffe400,
+ 0xfffd800f,0xf98003ff,0x406fffff,0x3ffffffa,0xffffffd0,0x0ae2005f,
+ 0xdffffffb,0xffffd801,0x00aba81f,0x7fffffc4,0xffffd000,0x3ffff21f,
+ 0xfffe802f,0x3fa000ff,0x4000ffff,0x44fffffa,0x3ffffffd,0x7ffe4000,
+ 0x6c0003ff,0x7007ffff,0x01ffffff,0xfffffd00,0x7dcc15df,0x206fffff,
+ 0xfffffffa,0x2e609bdf,0x7fc43ffd,0xabffffff,0x7fffec40,0xff80001f,
+ 0xd001ffff,0x321fffff,0x802fffff,0x00fffffe,0x3fffffa0,0x7ffd4000,
+ 0x7ffc44ff,0x0001ffff,0x0ffffff2,0xffff8800,0xfff5002f,0x3357ffff,
+ 0xff50bb75,0xffffffff,0xffffffff,0xfffe805f,0xffffffff,0x3fffffff,
+ 0xffffffc8,0xfeefffff,0x01ffffff,0xffffe800,0xfffd001f,0x3fff21ff,
+ 0xffe802ff,0x3a000fff,0x000fffff,0x27ffffd4,0x7fffffd4,0xff90000f,
+ 0x20007fff,0x05fffff9,0x7fffff40,0xffffffff,0xfffffb06,0xffffffff,
+ 0x300bffff,0xfffffffd,0xffffffff,0xffd107ff,0xffffffff,0xffffffff,
+ 0xfb00003f,0x5007ffff,0x21ffffff,0x02fffffc,0x0fffffe8,0x3ffffa00,
+ 0x7fd4000f,0xff904fff,0x260dffff,0xeccccccc,0xccefffff,0x5512cccc,
+ 0xdfffffd7,0xfff98001,0xffffffff,0x3fee06ff,0xffffffff,0x003fffff,
+ 0x7fffffe4,0xffffffff,0x3fee03ff,0xffffffff,0xffffffff,0xffc80001,
+ 0x7cc05fff,0x90ffffff,0x005fffff,0x01fffffd,0x7fffff40,0x7ffd4000,
+ 0x3ffa04ff,0xfb85ffff,0xffffffff,0xffffffff,0xfff94fff,0x03dfffff,
+ 0x3fffee00,0xffffffff,0x7fffcc06,0xffffffff,0xfd50001e,0xffffffff,
+ 0x805fffff,0xffffffe9,0xffffffff,0xa80000ef,0x00ffffff,0xfffffff1,
+ 0x3ffff21f,0xfffe802f,0x3fa000ff,0x4000ffff,0x04fffffa,0x3fffffe2,
+ 0x7fffdc3f,0xffffffff,0xffffffff,0xffffff94,0x9100007f,0xffffffff,
+ 0xd9100bff,0xdfffffff,0xb8800019,0xffffffec,0x2000adff,0xfffffedb,
+ 0x00beffff,0x7fffc000,0x7f5c0eff,0x0fffffff,0x05fffff9,0x1fffffd0,
+ 0x7ffff400,0x7fd4000f,0x7d404fff,0x22ffffff,0xfffffffb,0xffffffff,
+ 0xf94fffff,0x0019dfff,0x79553000,0x44000355,0x00001aba,0x09aaa880,
+ 0x32a60000,0x000099aa,0x3fffee00,0xfffcdfff,0xffffffff,0x5fffff90,
+ 0xfffffd00,0x7fff4001,0x7d4000ff,0xc804ffff,0x0fffffff,0xfffffff7,
+ 0xffffffff,0x2a9fffff,0x0000009a,0x00000000,0x00000000,0x00000000,
+ 0xffff1000,0xffffffff,0xfffffbff,0x00000001,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x3ffea000,0xffffffff,
+ 0xfffff8df,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x3ffe6000,0x4fffffff,0x003ffffe,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0xfffffb30,0xffff85df,0x0000000f,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x2e600000,0x000001ab,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x0006aa20,0x55554c40,0x44000009,0x00009aa9,
+ 0x4d554c40,0xffffc801,0xffffffff,0x005fffff,0x3b72ea60,0x20007fff,
+ 0x00009a98,0x0026a620,0x0fffffe8,0x3ffff200,0x9998002f,0xaaa98019,
+ 0x5c4002aa,0xefffffed,0xfb71000c,0xffffffff,0x2a0003bf,0xfffffffe,
+ 0xd98002ef,0xfffffffe,0xfc81ceff,0xffffffff,0xffffffff,0x7fdc4005,
+ 0xffffffff,0x7ff5c007,0x02efffff,0x7ff65c40,0x402dffff,0x00fffffe,
+ 0x3fffff20,0x3ffaa002,0xffb807ff,0x2a007fff,0xffffffff,0xd802ffff,
+ 0xffffffff,0x1dffffff,0xffffd500,0xffffffff,0xffb3005d,0xffffffff,
+ 0xf909ffff,0xffffffff,0xffffffff,0x3ff6600b,0xffffffff,0xfd5007ff,
+ 0xffffffff,0xf7001bff,0xffffffff,0x3a03bfff,0x000fffff,0x0bfffff2,
+ 0x3ffffa60,0xffb807ff,0xf7007fff,0xffffffff,0x809fffff,0xfffffffd,
+ 0xffffffff,0x7ffdc00f,0xffffffff,0x202fffff,0xfffffffb,0xffffffff,
+ 0xffffc84f,0xffffffff,0x805fffff,0xfffffff9,0x7fffffff,0x7fffec40,
+ 0xffffffff,0xfd302fff,0xffffffff,0x03ffffff,0x01fffffd,0x7ffffe40,
+ 0x3fff6602,0x807fffff,0x06fffffa,0xffffffd8,0xffffffff,0x3ff605ff,
+ 0xffffffff,0x06ffffff,0x3fffffe6,0xffffffff,0xfa81ffff,0xffffffff,
+ 0xffffffff,0xfffffc84,0xffffffff,0x5405ffff,0xffffffff,0x7fffffff,
+ 0x7ffffec0,0xffffffff,0x7dc0ffff,0xffffffff,0xffffffff,0xfffffe86,
+ 0x3fff2000,0xffd882ff,0xffffffff,0xffffa807,0x7ffe406f,0xfdbdffff,
+ 0x2fffffff,0xbddfffb0,0xfffffb99,0xff107fff,0x37bfffff,0xfffffb75,
+ 0xffff88bf,0xeeefffff,0x84ffffee,0xeefffffc,0xeeeeeeee,0x3fea04ee,
+ 0xccffffff,0x0199999a,0x3fffffea,0xfffeccef,0x7dc4ffff,0xefffffff,
+ 0xffffffff,0x7ffff44f,0x3ff2000f,0x3f222fff,0xffffffff,0xf9807fff,
+ 0x2205ffff,0x85ffffff,0xffffffa8,0x80159906,0x5ffffffb,0x5fffffa8,
+ 0x7ffffcc0,0x7ffffe47,0x6dcc01df,0x7ffffc83,0x7ff40000,0x000cffff,
+ 0x3ffffe20,0xffe881ef,0x7e40ffff,0x260acfff,0x7ffffffd,0x07fffff4,
+ 0xfffff900,0x7fffffc5,0xffffffff,0xffff9807,0x3fff205f,0x3ea00eff,
+ 0x001fffff,0xfffffb80,0xfffffc87,0xffffc800,0x3ffffa1f,0xf900005f,
+ 0x0000ffff,0x7fffffdc,0xffb80001,0x2200ffff,0x85fffffe,0x7ec01efe,
+ 0x3a1fffff,0x000fffff,0x8bfffff2,0xeffffffd,0x07fffffb,0x4fffff88,
+ 0xffffff10,0xffffb001,0xf10000df,0xd81fffff,0x7007ffff,0x7c3fffff,
+ 0x002fffff,0xfffff900,0x3fe20000,0x0003ffff,0x7fffffb0,0xfffff500,
+ 0x1004881f,0x45ffffff,0x00fffffe,0x3fffff20,0x3ffffe62,0xffffff13,
+ 0xfffff100,0x3fffee09,0xfff1005f,0x00003fff,0x81ffffff,0x00fffffd,
+ 0x0fffffc8,0x5ffffff3,0x3ff20000,0x500007ff,0x00dfffff,0x7ffff400,
+ 0xfff8801f,0x40002fff,0x24ffffff,0x00fffffe,0x3fffff20,0x1067ff42,
+ 0x00ffffff,0x40fffffe,0x01fffffe,0xffffff30,0xff880007,0xffc87fff,
+ 0x7c404fff,0x3e27ffff,0x004fffff,0xfffff900,0x3ff20000,0x00003fff,
+ 0x0ffffff1,0x7ffffec0,0x7ff40003,0x3ffa4fff,0x32000fff,0x5c2fffff,
+ 0xffff880d,0xffff007f,0x3fffe07f,0xfff7006f,0x000bffff,0x5fffffa8,
+ 0xffffffa8,0x3ffff203,0x7ffffc3f,0xc80003ff,0x0007ffff,0x3fffffd0,
+ 0x3fe20000,0x32007fff,0x005fffff,0x7fffff40,0x3fffffa2,0x3fff2000,
+ 0x3e2002ff,0xd007ffff,0xf105ffff,0x880bffff,0xfffffffd,0x3e20006f,
+ 0xd01fffff,0x1bffffff,0x7fffffc8,0xffffffd8,0x320002ef,0xeeefffff,
+ 0x8800abcc,0x517fffff,0x359bddb9,0xffffff00,0x3ffee001,0x220005ff,
+ 0x21ffffff,0x00fffffe,0x3fffff20,0x3ffe2002,0x997007ff,0xfff30399,
+ 0x7fd409ff,0xffffffff,0xffc88007,0x2a03ffff,0xffffffff,0xfffffeac,
+ 0xffffb81f,0x0bffffff,0x7fffe400,0xffffffff,0x3fe602df,0xfffdffff,
+ 0xdfffffff,0x3ffffa00,0xfff7003f,0x5c000dff,0x20ffffff,0x00fffffe,
+ 0x3fffff20,0x3ffe2002,0x400007ff,0x03fffffa,0xfffffff9,0x640fffff,
+ 0xffffeeee,0xb801efff,0xffffffff,0x1fffffff,0x3fffff60,0x2dffffff,
+ 0xfffff900,0xffffffff,0xff501dff,0xffffffff,0xffffffff,0x3fff609f,
+ 0xfc800fff,0x0006ffff,0x13fffffa,0x01fffffd,0x7ffffe40,0x3ffe2002,
+ 0x400007ff,0x43fffffb,0xffffffe9,0x0ffffffe,0xffffffb0,0x001bffff,
+ 0x7fffffdc,0x0dffffff,0x7ffffc40,0xffffffff,0x7ffe403e,0xffffffff,
+ 0x40efffff,0xfffffffa,0xffffffff,0xb83fffff,0xbfffffff,0x3fff2621,
+ 0x0006ffff,0x3ffffff7,0x0fffffe8,0x3ffff200,0x3fe2002f,0x54007fff,
+ 0x7fe43efd,0x3fee2fff,0xfd4fffff,0x3601ffff,0xffffffff,0x2001ceff,
+ 0xffffffe8,0x1004ffff,0xfffffffb,0x1dffffff,0x3fffff20,0xffffffff,
+ 0x2e0effff,0xffffffff,0xffffffff,0xe80fffff,0xffffffff,0xffffffff,
+ 0x8006ffff,0x5ffffff9,0x0fffffe8,0x3ffff200,0x3fe2002f,0x36007fff,
+ 0xb0efffff,0xb13fffff,0x5fffffff,0x07fffff4,0xffffffd8,0xdfffffff,
+ 0xffffb800,0xffffffff,0xfff7001e,0xffffffff,0x88005fff,0xfffffba9,
+ 0x3fee4fff,0x9befffff,0xffffb988,0xff985fff,0xffffffff,0xffffffff,
+ 0x744005ff,0x80efffff,0x00fffffe,0x3fffff20,0x3ffe2002,0xff7007ff,
+ 0x32bfffff,0xffcfffff,0x40dfffff,0x207fffff,0xfffeeeec,0xefffffff,
+ 0xffffd100,0xffffffff,0x54003fff,0xfffffffe,0x000fffff,0x7ffffdc0,
+ 0xffff90ff,0xfe8803df,0xf707ffff,0xffffffff,0xffffffff,0x744009ff,
+ 0x01ffffff,0x01fffffd,0x7ffffe40,0x3ffe2002,0xffd007ff,0x91ffffff,
+ 0xffffffff,0x3e07ffff,0x0006ffff,0xffffff93,0xfffd10bf,0xffd59fff,
+ 0x03ffffff,0xffffc980,0x06ffffff,0xffffc800,0xffff72ff,0x3fe600df,
+ 0xb301ffff,0xffffffff,0xffffddff,0x7ff4007f,0x3a03ffff,0x000fffff,
+ 0x0bfffff2,0xfffff880,0xfffff007,0xff75ffff,0xffffffff,0x3ffe203d,
+ 0xd80005ff,0x42ffffff,0x1efffffe,0x7fffffdc,0x3aa0006f,0xffffffff,
+ 0x7fc40002,0xff52ffff,0x7400dfff,0x402fffff,0xdefeecb9,0xfffff91c,
+ 0x3fff6007,0x7f403fff,0x2000ffff,0x02fffffc,0x3ffffe20,0xfffff007,
+ 0xff53ffff,0xbfffffff,0x7fffcc01,0xe880004f,0x2a4fffff,0x00efffff,
+ 0xffffffd3,0xffb80005,0x003fffff,0xffffff80,0xffffff33,0x7fffec00,
+ 0x3a00003f,0x802fffff,0x4ffffffd,0xfffffe80,0x3fff6000,0x3e2000ff,
+ 0xb007ffff,0xffffffff,0x3fffffe6,0xffa802ff,0x00003fff,0x4bfffff9,
+ 0x01ffffff,0x7fffffc4,0xffa80004,0x0005ffff,0x2fffffe8,0x0ffffff1,
+ 0x7ffffe40,0xff100003,0xfb00ffff,0x009fffff,0x07fffff6,0x7ffffe80,
+ 0x7fffc400,0xfff1007f,0x7fc7ffff,0x000effff,0x05fffffb,0x3ffee000,
+ 0xffff16ff,0x3fea00bf,0x00005fff,0x0dffffff,0xffff8800,0x3fffe0ff,
+ 0xffd002ff,0x00003fff,0x13ffffea,0xffffffb0,0x7ffe4009,0x3fe002ff,
+ 0x44006fff,0x007fffff,0x0fffffea,0x07fffffd,0x3ffffe20,0xf900000f,
+ 0x3ea9ffff,0x1004ffff,0x00ffffff,0x3ffff600,0x7dc0004f,0x7f47ffff,
+ 0x8805ffff,0x00ffffff,0xffff8800,0x3ff601ff,0x4003ffff,0x05fffffb,
+ 0xbfffff30,0xffff8800,0x5d44007f,0xffffa80a,0xffb800ff,0x00004fff,
+ 0x4ffffffa,0x04fffffb,0xdfffff10,0x3ffe0000,0x20003fff,0x5ffffff9,
+ 0x7fffffd4,0x7fffe400,0xfb00006f,0x6c0dffff,0x03ffffff,0xfffffa80,
+ 0xfffd801f,0x7c4003ff,0x0007ffff,0xfffffd00,0xffff980b,0x900000ff,
+ 0x23ffffff,0x06fffff9,0x9fffff50,0x7dc0006a,0x061fffff,0x7fffe440,
+ 0xffe82fff,0xf901ffff,0x009fffff,0xffffea80,0xfffb03ff,0x40005fff,
+ 0x1ffffffe,0x3fffff20,0x7fc4000f,0x00007fff,0xffffff50,0xffff3017,
+ 0x800109ff,0xffffffda,0x3ffffe27,0x7ffcc04f,0xbff92fff,0x7ecc0137,
+ 0x227fffff,0xccccdeff,0xffffffed,0xfff503ff,0x979bffff,0xdffffffd,
+ 0x26666620,0xfffecaa9,0xfb04ffff,0x55bfffff,0x55555555,0x7ffd4555,
+ 0xbaceffff,0xffffffec,0x33333302,0xffffff53,0x03333333,0xffffe800,
+ 0xfdbadfff,0x80ffffff,0xccccdefc,0xffffeecc,0x7f41ffff,0xbdffffff,
+ 0xffffca99,0xfff90fff,0xfdddffff,0xffffffff,0x7fffc45f,0xffffffff,
+ 0x404fffff,0xfffffffe,0xffffffff,0xfff500ff,0xffffffff,0x20bfffff,
+ 0xfffffffc,0xffffffff,0x746fffff,0xffffffff,0xffffffff,0xffff305f,
+ 0xffffffff,0xffffffff,0xffa8000f,0xffffffff,0x3fffffff,0xffffff90,
+ 0xffffffff,0xf305ffff,0xffffffff,0xffffffff,0x7ffe43ff,0xffffffff,
+ 0xffffffff,0x7ffffc44,0xffffffff,0xe8804fff,0xffffffff,0x2fffffff,
+ 0x3ffffea0,0xffffffff,0xffd00eff,0xffffffff,0xffffffff,0xfff98dff,
+ 0xffffffff,0x00efffff,0xfffffff3,0xffffffff,0x00ffffff,0xfffff500,
+ 0xffffffff,0x7fe403ff,0xffffffff,0x3fffffff,0x3ffffea0,0xffffffff,
+ 0x7e42ffff,0xffffffff,0xffffffff,0xffff885f,0xffffffff,0x64000cff,
+ 0xffffffff,0x400dffff,0xfffffffa,0x2fffffff,0x7fffff40,0xffffffff,
+ 0x6fffffff,0xfffffc88,0xffffffff,0x7fffcc03,0xffffffff,0xffffffff,
+ 0xfd100007,0xffffffff,0xfc801dff,0xffffffff,0x0cffffff,0xffffea80,
+ 0xffffffff,0xfffc82ef,0xffffffff,0x02efffff,0xfffffff1,0x019dffff,
+ 0x7ffed400,0x01dfffff,0xffffff50,0x07dfffff,0x3fffffa0,0xffffffff,
+ 0x6fffffff,0x3ffff660,0x00dfffff,0xffffff98,0xffffffff,0x07ffffff,
+ 0x7ff5c000,0x03dfffff,0xffffff90,0x7bffffff,0x3ffaa000,0xdfffffff,
+ 0x3ff6e602,0xffffffff,0x33002dff,0x01355555,0x2ea20000,0xfa80009b,
+ 0xceeeffff,0x7ff4000a,0xffffffff,0xffffffff,0x531006ff,0x98001359,
+ 0xffffffff,0xffffffff,0x0007ffff,0x02aea600,0x5554c400,0x00009aaa,
+ 0x56554c40,0x5310001a,0x01357955,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0xfffffff9,0xffffffff,
+ 0x3ffe21ff,0x2a0000ff,0xffd5ffff,0xddffffff,0xe800579b,0x00ffffff,
+ 0x3fffffe0,0x7ffffc0f,0xffffffff,0xffffffff,0xffffb4ff,0x7fc00dff,
+ 0x3fea2fff,0x4c04ffff,0x46ffffff,0x07fffffe,0x3ffffe00,0xfffffd2f,
+ 0xffff7003,0x7ffdcbff,0xffffffff,0xafffffff,0xfffffffc,0xffffffff,
+ 0xffff10ff,0x7dc0001f,0xfffd4fff,0xffffffff,0x0017ffff,0x9ffffff5,
+ 0x3fffee00,0xffff83ff,0xffffffff,0xffffffff,0xfffb4fff,0x2003ffff,
+ 0x2a2fffff,0x06ffffff,0x7fffffdc,0x7ffffe46,0xff98001f,0xffd0ffff,
+ 0xf8803fff,0x20ffffff,0xfffffffb,0xffffffff,0xfffcafff,0xffffffff,
+ 0x20ffffff,0x000fffff,0x53fffee0,0xfffffffe,0xffffffff,0xffe801ff,
+ 0xf800ffff,0xf07fffff,0xffffffff,0xffffffff,0x29ffffff,0xfffffffd,
+ 0xfffff005,0x7ffffdc5,0x3ffa00ff,0x7cc7ffff,0x003fffff,0x5fffffc8,
+ 0x07fffffa,0xffffffb0,0xfffffb85,0xffffffff,0xfcafffff,0xffffffff,
+ 0xffffffff,0x07ffffe0,0xffffb800,0xffffffd3,0xffffffff,0x9801ffff,
+ 0x04ffffff,0x7fffffdc,0xffffff02,0xffffffff,0xffffffff,0x3ffff69f,
+ 0xf801ffff,0x3ee2ffff,0x03ffffff,0xfffffff1,0xffffff0f,0xfffd000b,
+ 0x7fff47ff,0x3fea01ff,0xfb84ffff,0xffffffff,0xffffffff,0xfffffcaf,
+ 0xffffffff,0x3fe0ffff,0x20001fff,0xfd3ffffb,0xffffffff,0xffffffff,
+ 0xffd801df,0x3e00ffff,0x206fffff,0xffffffff,0xffffffff,0x4fffffff,
+ 0xfffffffb,0xffff009f,0x7fffdc5f,0xff706fff,0x90ffffff,0x00ffffff,
+ 0xffffff88,0x3fffffa0,0xfffff101,0x3ffee0df,0xffffffff,0x2fffffff,
+ 0xfffff800,0x3ffffa0f,0x3ff20001,0xffffd2ff,0x7f5ccc1f,0x02ffffff,
+ 0x7fffffcc,0xfffff704,0x7d40005f,0x2006ffff,0xfffffffd,0x7ffc00ff,
+ 0x3fff22ff,0xd80fffff,0x7fffffff,0xffffffa8,0x3ffee002,0x7fff46ff,
+ 0xfffb01ff,0x3ee03fff,0x999dffff,0x99999999,0xfff80009,0x3ffa0fff,
+ 0x320002ff,0xffd2ffff,0x7dc01fff,0x804fffff,0x0ffffffc,0x5ffffff8,
+ 0x7ffd4000,0x3f6006ff,0xffffffff,0x7ffffc04,0x3fffff22,0x7fc42fff,
+ 0x0fffffff,0x7fffffc4,0x3fff6004,0x7fff43ff,0xfffa81ff,0x3ee03fff,
+ 0x0004ffff,0xfffff000,0x7fffec1f,0x3ff20002,0xffffd1ff,0xfffd801f,
+ 0xff8805ff,0x7dc5ffff,0x001fffff,0x7ffffd40,0x3fff6006,0x0fffffff,
+ 0x8bffffe0,0xffeefffd,0x7fffd45f,0xd80ffffd,0x006fffff,0x07fffffe,
+ 0x83fffffd,0x5ffffff8,0x7ffffdc0,0xf0000004,0x6c1fffff,0x0002ffff,
+ 0x747ffff6,0x400fffff,0x07fffffb,0xffffff70,0x7fffffc3,0xffa80005,
+ 0x36006fff,0xffffffff,0x3ffe03ff,0x3fff62ff,0x6c7fffce,0xfffcdfff,
+ 0xffffb81f,0xff9800ff,0xffe87fff,0x7fec1fff,0x5c00ffff,0x004fffff,
+ 0xffff0000,0x7ffec1ff,0x0133302f,0x747ffff6,0x400fffff,0x07fffff9,
+ 0xffffff10,0x3ffffeeb,0xfa80000f,0x2006ffff,0xffdffffd,0x3fe06fff,
+ 0x3ff62fff,0x2ffffaef,0xf95ffff1,0xff103fff,0x9005ffff,0xd09fffff,
+ 0x543fffff,0x02ffffff,0x4fffffb8,0xff000000,0x7e41ffff,0xff983fff,
+ 0xffffb07f,0x3fffffa1,0x7fffdc00,0x3fee005f,0xfff9ffff,0x00004fff,
+ 0x0dfffff5,0x6ffffec0,0x02fffffb,0x745fffff,0xfff8efff,0x1ffff54f,
+ 0x203ffff9,0x05fffffe,0x2fffffe8,0x1fffffe8,0xbffffff1,0x3fffee00,
+ 0x0000004f,0x41ffffff,0xb83ffffc,0xfd82ffff,0xfffd0fff,0xffd801ff,
+ 0x74004fff,0xffffffff,0x0000ffff,0xdfffff50,0x7fffec00,0x6fffff8d,
+ 0x45fffff0,0xffb6fffe,0x5bfff2df,0x702ffffc,0x80ffffff,0x07fffff8,
+ 0x23fffffd,0x0efffffc,0xfffff700,0x20000009,0x20ffffff,0xe83ffffb,
+ 0xfe84ffff,0x3fffa7ff,0x3ff200ff,0x4001ffff,0xfffffffa,0x0003ffff,
+ 0x3ffffea0,0x3fff6006,0xfffffb5f,0x5fffff03,0xfbaffffc,0xfffe8fff,
+ 0x05ffff73,0x3fffffe6,0x3fffea01,0xffffd05f,0xfffff53f,0x7fdc003f,
+ 0x00004fff,0xffffff00,0x27fffdc1,0x1fffffe2,0xfe9ffffa,0x5440ffff,
+ 0x4ffffffe,0xffffb000,0x00dfffff,0xffffa800,0x3ff6006f,0xffff35ff,
+ 0xfffff0bf,0x9affffc5,0xfffcffff,0x7ffff70f,0x7fffffc0,0x3ffff603,
+ 0xffffd02f,0xfffffd3f,0xfffb8007,0x000004ff,0x1ffffff0,0x227fffd4,
+ 0x1ffffffa,0xfd3ffff4,0xfdddffff,0xffffffff,0x3e60001d,0xffffffff,
+ 0x7d400002,0x2006ffff,0x365ffffd,0x7c1fffff,0x3fe2ffff,0x3fffa5ff,
+ 0x3ee6ffff,0x3f203fff,0x3e06ffff,0xd00fffff,0xffdfffff,0x7000dfff,
+ 0xffffffff,0xffffffff,0x3fe0009f,0x3ea0ffff,0x7fec4fff,0x7f43ffff,
+ 0x3fffa6ff,0xffffffff,0x003fffff,0xfffffd80,0x800006ff,0x06fffffa,
+ 0x97ffff60,0x44fffffa,0xf12fffff,0x7fe4bfff,0x2e3fffff,0x2a03ffff,
+ 0x80ffffff,0x06fffff9,0x3ffffffa,0x002fffff,0xffffffb8,0xffffffff,
+ 0xf0004fff,0x4c1fffff,0x7fc4ffff,0x7c6fffff,0x3ffa6fff,0xffffffff,
+ 0x000adfff,0xfffff880,0x0001ffff,0x7ffffd40,0x3fff6006,0x7ffff45f,
+ 0x3ffffe0f,0x49ffff12,0xfffffffa,0x13fffea0,0x5ffffff0,0x7fffff90,
+ 0x7fffff40,0x0fffffff,0x7fffdc00,0xffffffff,0x004fffff,0x1ffffff0,
+ 0x52ffffcc,0xffffffff,0xd2ffffc1,0xffffffff,0x03dfffff,0x3fff2000,
+ 0x06ffffff,0x7ffd4000,0x3f6006ff,0x7fdc5fff,0x3ffe4fff,0xffff12ff,
+ 0xffffff89,0x27fffd46,0x3fffff60,0xfffffe84,0x3ffffa01,0xffffffaf,
+ 0x7ffdc005,0xffffffff,0x04ffffff,0xffffff00,0x2ffffcc1,0xfffdfff9,
+ 0x2ffffc7f,0xddfffffd,0xffffffff,0xff980005,0xffffffff,0x2a00002f,
+ 0x006fffff,0x217ffff6,0xf0ffffff,0x3e65ffff,0x7fec4fff,0x7fd43fff,
+ 0x7fd405ff,0x7fc47fff,0x7f406fff,0xffb9ffff,0x2002ffff,0xfffffffb,
+ 0xffffffff,0xff0004ff,0x7c41ffff,0x3ffe5fff,0x25ffff9f,0x3fa4ffff,
+ 0xf510ffff,0x01ffffff,0x7fffec00,0xffffffff,0xff500000,0x6c00dfff,
+ 0xfc85ffff,0xfff3ffff,0x3ffe65ff,0x7fffdc4f,0x7fffd41f,0x7fffc405,
+ 0x3ffea1ff,0x7ff404ff,0xfffd1fff,0x2e001fff,0x004fffff,0xffff0000,
+ 0x7ffc41ff,0x2ffff36f,0xf88ffffd,0x3ffa4fff,0x7fcc0fff,0x0005ffff,
+ 0xbffffff5,0x09ffffff,0x3ffea000,0x3f6006ff,0xff885fff,0xfff8efff,
+ 0xffff52ff,0x6ffff887,0x05ffff98,0x3fffffe8,0x07fffff2,0x3fffffd0,
+ 0x3fffffe6,0xffff7005,0x0000009f,0x03fffffe,0x3f2dffff,0xffff74ff,
+ 0x49ffff15,0x80fffffe,0x1ffffffb,0xffffe800,0xfffffd6f,0xf500001f,
+ 0x400dffff,0xb05ffffd,0xff5fffff,0x3fea5fff,0xfffe83ff,0x6ffff984,
+ 0xfffffb80,0x1fffffe6,0x3fffffa0,0x3fffff61,0xfffb802f,0x000004ff,
+ 0x7fffff88,0xfd7ffff8,0x3ffe65ff,0x3ffff9df,0x03fffffa,0x2ffffff4,
+ 0x3fffee00,0xffff52ff,0x50000bff,0x00dfffff,0x82ffffec,0xfdfffff9,
+ 0xff72ffff,0x999507ff,0xdffff301,0xfffff300,0xfffff31f,0xffffd00b,
+ 0x7fffc43f,0x7dc00fff,0x0004ffff,0xffff9800,0xfffff86f,0x3a0ffff8,
+ 0xfff9ffff,0x3ffffa3f,0xffff700f,0x3e2003ff,0x746fffff,0x02ffffff,
+ 0x7fffd400,0x3ff6006f,0x3ff605ff,0xffffffff,0x07ffff72,0x3fffe600,
+ 0xffffd007,0xfffff75f,0xffffd005,0xffffb83f,0x7fdc05ff,0x00004fff,
+ 0xfffffb80,0xbffffe85,0x7fe45fff,0x2ffffbff,0x03fffffa,0x7fffffc4,
+ 0xffff9005,0xfff985ff,0x40006fff,0x06fffffa,0x17ffff60,0xffffffa8,
+ 0xff72ffff,0x220005ff,0x9007ffff,0xfb9fffff,0xd001ffff,0xd03fffff,
+ 0x07ffffff,0x27ffffdc,0x8800b800,0x84ffffff,0xffdffffe,0x7fffcc2f,
+ 0x3a2ffffd,0x200fffff,0x0ffffffc,0x7ffffc40,0xffffb06f,0x540007ff,
+ 0x006fffff,0x017ffff6,0xfffffffd,0x3fff25ff,0xff10002f,0x3e600fff,
+ 0xfffeffff,0xffd005ff,0xff303fff,0x201fffff,0x04fffffb,0x2039fb00,
+ 0xffffffe9,0xfffffd82,0xffe80fff,0x21ffffff,0x00fffffe,0x3fffffe2,
+ 0x7fffec04,0xfff301ff,0x0001ffff,0x1bffffea,0x5ffffd80,0x7ffffdc0,
+ 0xff92ffff,0x220005ff,0x000fffff,0xffffffff,0x3a007fff,0x901fffff,
+ 0x0bffffff,0x13ffffee,0x7fffec00,0xffffdccd,0xffb05fff,0x20bfffff,
+ 0xfffffffc,0x3ffffa1f,0x7ffec00f,0xff300fff,0xd80bffff,0x04ffffff,
+ 0xfffff500,0x7ffec00d,0xffff805f,0xfb2fffff,0x20005fff,0x00fffff8,
+ 0xffffffb0,0x2001ffff,0x01fffffe,0x3ffffffa,0xfffffb83,0xfffb0004,
+ 0xffffffff,0x3201ffff,0x3fffffff,0xffffff30,0x7fff41ff,0x7fd400ff,
+ 0xfd04ffff,0x803fffff,0xfffffff9,0xfffa8001,0x3f6006ff,0xfc805fff,
+ 0x2fffffff,0x003ffffb,0x07ffffc0,0xfffffa80,0x2006ffff,0x01fffffe,
+ 0x3fffffea,0x7fffdc0f,0xffb0004f,0xffffffff,0x6407ffff,0x0fffffff,
+ 0x3fffffe0,0x3fffa0ff,0xffe800ff,0x7d40ffff,0x005fffff,0xbffffff9,
+ 0xffff5000,0x7fec00df,0xff8805ff,0xb2ffffff,0x0003ffff,0x00fffffc,
+ 0xffffff88,0x3a004fff,0x401fffff,0x6ffffffd,0x27ffffdc,0xffffd800,
+ 0xffffffff,0x7ffe401e,0x7e406fff,0x20ffffff,0x00fffffe,0xffffffb8,
+ 0x7fffff43,0xfff1001f,0x8005ffff,0x06fffffa,0x17ffff60,0x7ffffec0,
+ 0xffffd2ff,0x7ffc0003,0x3f6001ff,0x1fffffff,0x3ffffa00,0x7ffc401f,
+ 0x3ee3ffff,0x0004ffff,0x3fffff6a,0x7002efff,0x07ffffff,0xffffffa8,
+ 0x7fffff47,0xfffff000,0x7fffdcff,0x7e4005ff,0x006fffff,0x37ffffd4,
+ 0xbffffb00,0x3fffe600,0xfffd2fff,0x7fc0003f,0x2e002fff,0x7fffffff,
+ 0x7ffff400,0xfffb801f,0xff71ffff,0x00009fff,0x0026aa66,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0xffffc800,0xfa8000ff,0x7fc7ffff,0xffffffff,
+ 0xffffffff,0xfff95fff,0x7f4005ff,0x5400ffff,0xff02ffff,0x3fee0dff,
+ 0xffffffff,0xffffffff,0xffffffd5,0x3579dfff,0xffff8800,0x7f40006f,
+ 0xffffffff,0x001bcdee,0xfffff900,0x6c001fff,0xffffffff,0x009accef,
+ 0x7ffffc40,0xffe8004f,0x7ffc3fff,0xffffffff,0xffffffff,0xffff95ff,
+ 0x7ff4005f,0x7dc00fff,0xfff01fff,0x3ffee0bf,0xffffffff,0x5fffffff,
+ 0xfffffffd,0xffffffff,0xfff10019,0xe8000dff,0xffffffff,0xefffffff,
+ 0x3fa0000b,0x2fffffff,0x3ffff600,0xffffffff,0x2000cfff,0x0ffffffc,
+ 0x3fffea00,0xfffff87f,0xffffffff,0xffffffff,0x5fffff95,0x7ffff400,
+ 0x7ffe400f,0xffff881f,0xfffff704,0xffffffff,0x3abfffff,0xffffffff,
+ 0xffffffff,0x7ffc402f,0x740006ff,0xffffffff,0xffffffff,0xf88000ef,
+ 0xffffffff,0x3fff6004,0xffffffff,0x04ffffff,0xffffff10,0x7fff4007,
+ 0xffff83ff,0xffffffff,0xffffffff,0xfffff95f,0x7fff4005,0x7fe400ff,
+ 0xfff980ff,0xffff703f,0xffffffff,0x2bffffff,0xfffffffe,0xffffffff,
+ 0xf100efff,0x000dffff,0xffffffe8,0xffffffff,0x8006ffff,0xfffffffb,
+ 0x3f6007ff,0xffffffff,0xffffffff,0xfff9005f,0x3ea00fff,0xff06ffff,
+ 0xffffffff,0xffffffff,0x3ff2bfff,0x3a002fff,0x400fffff,0xf507fffd,
+ 0x3ee07fff,0xffffffff,0xffffffff,0xfffffd5f,0xffffffff,0x0dffffff,
+ 0x1bffffe2,0xffffd000,0xfffddddf,0x9fffffff,0xffffd800,0x01ffffff,
+ 0xffffffb0,0xffffffff,0x007fffff,0x7ffffff1,0xfffffd00,0x33333207,
+ 0xcccccccc,0xfffffffc,0x5fffff92,0x7ffff400,0x7fff400f,0x5ffff707,
+ 0x3ffffee0,0x9999999d,0xfd099999,0x3333ffff,0xfffffb75,0xff107fff,
+ 0x8000dfff,0x00fffffe,0xffffffb5,0xffff800d,0x3fffffff,0xfffffb00,
+ 0xfffba985,0x801fffff,0x06fffffc,0x37ffffd4,0x3fee0000,0x3f25ffff,
+ 0x2002ffff,0x00fffffe,0xb837fffc,0xf701ffff,0x0009ffff,0x07fffff4,
+ 0xfffffd10,0xfff881ff,0x740006ff,0x400fffff,0x0ffffffd,0xfffff500,
+ 0x0dfffffb,0x3fffff60,0x3fff2202,0xf8805fff,0x202fffff,0x02fffffe,
+ 0x3ffe2000,0x3f20ffff,0x2002ffff,0x20fffffe,0xfff99998,0xd99999df,
+ 0x999affff,0x9fffff70,0x7fff4000,0xffc800ff,0x7c44ffff,0x0006ffff,
+ 0x07fffff4,0x3ffffe20,0xfff9001f,0xfffff1ff,0xfffb001f,0xffd005ff,
+ 0x3200dfff,0x506fffff,0x00dfffff,0xffffe800,0x7ffe42ff,0x3fa002ff,
+ 0x3f60ffff,0xffffffff,0xffffffff,0x73ffffff,0x009fffff,0x7fffff40,
+ 0xffffd000,0x7ffc41ff,0x740006ff,0x800fffff,0x01ffffff,0x2bffffd0,
+ 0x02fffffd,0x2fffffd8,0xfffff980,0xfff8800f,0xffe82fff,0x00002fff,
+ 0x3fffffee,0xfffffc84,0x3fffa002,0x3fff60ff,0xffffffff,0xffffffff,
+ 0xff73ffff,0x40009fff,0x00fffffe,0xffffff70,0x7ffffc47,0x7ff40006,
+ 0xff800fff,0x9800ffff,0xf73fffff,0xb00bffff,0x005fffff,0x3ffffff1,
+ 0x3ffff200,0x7fffd46f,0x2200006f,0x0fffffff,0x2fffffc8,0x3ffffa00,
+ 0x3ffff60f,0xffffffff,0xffffffff,0xfff73fff,0x740009ff,0x000fffff,
+ 0x9ffffff1,0x37ffffc4,0x3fffa000,0x7fcc00ff,0xf7006fff,0x3e63ffff,
+ 0xd807ffff,0x002fffff,0x05fffffd,0x3ffffe20,0x3ffffa1f,0x3a00002f,
+ 0x02ffffff,0x05fffff9,0x7fffff40,0x3fffff60,0xffffffff,0xffffffff,
+ 0xffff73ff,0x7f40009f,0x2000ffff,0x26fffffd,0x06fffff8,0x7ffff400,
+ 0x7fff400f,0xffb003ff,0xffff8fff,0x7fec01ff,0xff002fff,0x4003ffff,
+ 0x35fffffc,0x00dfffff,0x7fffdc00,0x3ff204ff,0x3a002fff,0x220fffff,
+ 0xffffc999,0xffa9999a,0x09999dff,0x09fffff7,0x7ffff400,0x3ff2000f,
+ 0x3fe27fff,0x40006fff,0x00fffffe,0xdfffffd3,0x3fffe200,0x7fffe44f,
+ 0x7ffec04f,0xff8802ff,0x44007fff,0xd8ffffff,0x002fffff,0xfffff100,
+ 0x7fe401df,0xffffffff,0xffffffff,0x3200ffff,0xf980ffff,0x3ee03fff,
+ 0xeeefffff,0xeeeeeeee,0xfffffd0e,0x7ffdc001,0x3ffe27ff,0x740006ff,
+ 0xeeefffff,0xffffffee,0xff5000ef,0xffa85fff,0x7ec06fff,0xb802ffff,
+ 0x006fffff,0xdfffffc8,0x006fffff,0x3ffffa00,0x7fe401ff,0xffffffff,
+ 0xffffffff,0x3600ffff,0xff507fff,0x7fdc07ff,0xffffffff,0xffffffff,
+ 0x1fffffd0,0x7fffd400,0xffff10ff,0xfe8000df,0xffffffff,0x3fffffff,
+ 0x7fffe400,0x7fffc40f,0x3ff600ff,0x7c402fff,0x005fffff,0xffffff88,
+ 0x002fffff,0xfffff700,0xfff9009f,0xffffffff,0xffffffff,0x7f401fff,
+ 0xfff706ff,0x7ffdc05f,0xffffffff,0x0fffffff,0x01fffffd,0x7ffffcc0,
+ 0xfffff10f,0xffe8000d,0xffffffff,0x2dffffff,0x3ffffe00,0xfffffd06,
+ 0x7fffec07,0x3ffa602f,0x0001ffff,0xfffffff9,0x20000dff,0x6ffffff8,
+ 0xfffff900,0xffffffff,0xffffffff,0x7fffc01f,0x3ffff706,0x7ffffdc0,
+ 0xffffffff,0xfd0fffff,0x4001ffff,0x0ffffff9,0x0dfffff1,0xffffe800,
+ 0xffffffff,0x0dffffff,0x7ffffcc0,0xfffff904,0x7fffec0b,0xdba999bf,
+ 0x3fffffff,0x3ffe2000,0x02ffffff,0xffffb000,0x3f2003ff,0xffffffff,
+ 0xffffffff,0x200fffff,0xf905ffff,0x7dc01fff,0xffffffff,0xffffffff,
+ 0xfffffd0f,0x7ffd4001,0x3ffe27ff,0x740006ff,0xeeefffff,0xfffffffe,
+ 0x7e406fff,0xf301ffff,0x6c0fffff,0xffffffff,0xffffffff,0xc80006ff,
+ 0x6fffffff,0xfff70000,0x64009fff,0x99bfffff,0x99999999,0x00fffffe,
+ 0x209ffff1,0x5c07fffd,0x004fffff,0x3fffffa0,0x3ffee000,0x3ffe26ff,
+ 0x740006ff,0x300fffff,0xfffffff9,0x7ffff409,0x7ffffc07,0xffffb02f,
+ 0xffffffff,0x01dfffff,0xffff1000,0x00005fff,0xdffffff1,0xffffc800,
+ 0x3ffa002f,0xdddb0fff,0xdddffffd,0xfffffddd,0x7dc1dddd,0x0004ffff,
+ 0x03fffffa,0xfffffc80,0x3ffffe24,0x7ff40006,0x7c400fff,0x80ffffff,
+ 0x05fffff8,0x27ffffec,0xffffffd8,0xffffffff,0x400003ff,0x06fffffc,
+ 0xffffb000,0xfc8003ff,0x2002ffff,0xf0fffffe,0xffffffff,0xffffffff,
+ 0x1fffffff,0x27ffffdc,0xffffd000,0x7fec001f,0x3fe23fff,0x40006fff,
+ 0x00fffffe,0xffffff98,0xfffffb81,0x9999999c,0x07fffffc,0xfffffffb,
+ 0x9fffffff,0xf5000001,0x000bffff,0xffffff70,0xfff90007,0x7f4005ff,
+ 0xfff0ffff,0xffffffff,0xffffffff,0x5c1fffff,0x004fffff,0x3fffffa0,
+ 0xffff1000,0x7ffc45ff,0x740006ff,0x000fffff,0x07ffffff,0xfffffffb,
+ 0xffffffff,0xb03fffff,0xdddfffff,0x0001359b,0xffffa800,0x7c40005f,
+ 0x006fffff,0x5fffff90,0x7ffff400,0xffffff0f,0xffffffff,0xffffffff,
+ 0x7ffdc1ff,0x3a0004ff,0x000fffff,0x1ffffff9,0x37ffffc4,0x3fffa000,
+ 0xffd000ff,0xfff07fff,0xffffffff,0xffffffff,0xfffb07ff,0x000005ff,
+ 0x7fffd400,0x7ec0005f,0x001fffff,0x5fffff90,0x7ffff400,0xfd99990f,
+ 0x99999fff,0x99bffffb,0x7ffdc199,0x3a0004ff,0x800fffff,0x4ffffff8,
+ 0x37ffffc4,0x3fffa000,0xff8800ff,0x7cc2ffff,0xffffffff,0xffffffff,
+ 0xfd85ffff,0x0002ffff,0x3fea0000,0x20005fff,0x3ffffffb,0x3fff2000,
+ 0x3fa002ff,0xfb00ffff,0x3fea0fff,0x7fdc02ff,0x20004fff,0x00fffffe,
+ 0x7ffffec4,0x7fffc40f,0x7f40006f,0xb800ffff,0x40ffffff,0xfffffffc,
+ 0xffffffff,0x0fffffff,0x17ffffec,0x50000000,0x00bfffff,0x3ffffe20,
+ 0x7e40006f,0x2002ffff,0x00fffffe,0x2e0dfffd,0x5c01ffff,0x004fffff,
+ 0x3fffffa0,0x3fffa600,0xff883fff,0x40006fff,0x00fffffe,0x7fffffcc,
+ 0xfffffe87,0xeeeeeeee,0xfffffeee,0x7fffec2f,0x0000002f,0x3ffffea0,
+ 0xfffb0005,0x55559fff,0x55555555,0x3ffff255,0x3ffa002f,0xfff00fff,
+ 0x3fff20bf,0x7ffdc01f,0x3a0004ff,0x220fffff,0xfffffdba,0xff880fff,
+ 0x9999ffff,0x99999999,0xfffffd09,0xfff93101,0xf88bffff,0x4004ffff,
+ 0x44fffffd,0x02fffffd,0x2a000000,0x005fffff,0xffffffa8,0xffffffff,
+ 0x7fffffff,0x05fffff9,0x7fffff40,0x5ffff880,0x01ffff90,0xffffffb8,
+ 0xffffffff,0xffd5ffff,0xffffffff,0xffffffff,0x3ffe205f,0xffffffff,
+ 0xffffffff,0xffffffd2,0xffffffff,0x81dfffff,0x02fffffb,0x7ffffdc0,
+ 0x7ffffec7,0x00000002,0x17ffffea,0x3fffee00,0xffffffff,0xffffffff,
+ 0xfffff97f,0x7fff4005,0xfff980ff,0xffffb04f,0xfffff700,0xffffffff,
+ 0x3abfffff,0xffffffff,0xffffffff,0x3fe202ff,0xffffffff,0xffffffff,
+ 0xfffffd2f,0xffffffff,0x03ffffff,0x01fffffb,0xfffff980,0x3ffff61f,
+ 0x0000002f,0x3ffffea0,0xfffb8005,0xffffffff,0xffffffff,0xffff97ff,
+ 0x7ff4005f,0xff980fff,0xfffd03ff,0xffff700d,0xffffffff,0x2bffffff,
+ 0xfffffffe,0xffffffff,0x7fc401ef,0xffffffff,0xffffffff,0xfffffd2f,
+ 0xffffffff,0x105fffff,0x00bfffff,0x3fffffe0,0x3fffff64,0x00000002,
+ 0x17ffffea,0x3fffee00,0xffffffff,0xffffffff,0xfffff97f,0x7fff4005,
+ 0xfffa80ff,0xdffff02f,0xfffff700,0xffffffff,0x3abfffff,0xffffffff,
+ 0x2effffff,0xfffff100,0xffffffff,0x25ffffff,0xfffffffe,0xffffffff,
+ 0x3ffea02e,0xf90003ff,0x7ecdffff,0x0002ffff,0x3fea0000,0xb8005fff,
+ 0xffffffff,0xffffffff,0xf97fffff,0x4005ffff,0x80fffffe,0x881ffffb,
+ 0xb805ffff,0xffffffff,0xffffffff,0xffffd5ff,0x9ddfffff,0xff880015,
+ 0xffffffff,0xffffffff,0xfffffd2f,0x9bdfffff,0xfff90037,0x2a0003ff,
+ 0xb0ffffff,0x005fffff,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x7fffd400,0xffffffff,
+ 0x6fffffff,0xfffffff5,0xffffffff,0x0bffffff,0x7ffff400,0x00004fff,
+ 0x00000000,0x00266000,0x00260000,0x00099800,0x999a9800,0x54cc0000,
+ 0x00000009,0xffffffa8,0xffffffff,0xf56fffff,0xffffffff,0xffffffff,
+ 0x000bffff,0x3fffffee,0x5d1004ff,0x80000000,0x5c4004d8,0xdfffffed,
+ 0x2a20000c,0xfffffedb,0xca800bde,0xcdfffffe,0x7f644000,0xffffffff,
+ 0x7f5cc04e,0xefffffff,0x7e44001d,0x7fd402df,0xffffffff,0xffffffff,
+ 0xfffff56f,0xffffffff,0xffffffff,0xfff1000b,0x09ffffff,0x007ffd10,
+ 0x3a200000,0xff7004ff,0xffffffff,0xf50007ff,0xffffffff,0x4405ffff,
+ 0xfffffffd,0x8802ffff,0xfffffffc,0x07ffffff,0xfffffff5,0xffffffff,
+ 0x3ffa003b,0x3ea04fff,0xffffffff,0xffffffff,0xffff56ff,0xffffffff,
+ 0xffffffff,0xffb000bf,0x9fffffff,0xffffe880,0x40000004,0x04fffff9,
+ 0x3fffff62,0xffffffff,0xfd8801ef,0xffffffff,0x302fffff,0xfffffffd,
+ 0x1bffffff,0x3ffffa20,0xffffffff,0xfff507ff,0xffffffff,0x01ffffff,
+ 0xffffffa8,0xffff502f,0xffffffff,0xdfffffff,0x3fffffea,0xffffffff,
+ 0x5fffffff,0x7fffcc00,0x04ffffff,0x7ffffff4,0x8000000d,0xfffffffa,
+ 0xfffff883,0xffffffff,0x4c06ffff,0xffffffff,0xffffffff,0xfffffa82,
+ 0xffffffff,0xffd04fff,0xffffffff,0x20ffffff,0xfffffffa,0xffffffff,
+ 0x7fe405ff,0x005fffff,0x5fffff98,0xeeeeea80,0xeeeeeeee,0xffffffee,
+ 0x7fff4004,0x4fffffff,0x7ffffd40,0x00000eff,0x3fffff20,0xfffb05ff,
+ 0xffdfffff,0x7fffffff,0x7fffff40,0xffffffff,0xffe82fff,0xa99aefff,
+ 0x1ffffffe,0x7fffffe4,0xb75331bd,0x3ffea0ff,0xba99aacd,0x2fffffff,
+ 0x3fffff20,0x4c000fff,0x005fffff,0x7ffd4000,0x2e000fff,0xffcfffff,
+ 0xe9804fff,0x1fffffff,0xffd80000,0x304fffff,0x5dffffff,0x7fffdc41,
+ 0xffb80fff,0x0acfffff,0x70bfae62,0x409fffff,0x46fffffc,0x06fffffe,
+ 0x056d4020,0x7ffff440,0x3ffea04f,0x001fffff,0x2fffffcc,0x3fa00000,
+ 0x2005ffff,0x8efffff8,0x004fffff,0xffffffb1,0x2200007f,0xfffffffe,
+ 0x3ffffa02,0x3fe600ef,0x7cc5ffff,0x02ffffff,0x7ffc4130,0xffe805ff,
+ 0x3ffe2fff,0x00002fff,0xffff3000,0xfffd80bf,0x4002ffff,0x05fffff9,
+ 0x3fea0000,0x2001ffff,0x89fffffd,0x004fffff,0x7fffffe4,0x74c0004f,
+ 0x1effffff,0x3ffffea0,0xfffc800f,0x7ffec7ff,0x20001fff,0x01fffffc,
+ 0x3fffffa8,0x7ffffff1,0x40000000,0x807fffff,0x1ffffffe,0x7fffcc00,
+ 0x2000005f,0x05fffffe,0x3ffffea0,0x9fffff14,0xffff7000,0x0001bfff,
+ 0xfffffff5,0xfffc801d,0xff1005ff,0x7fc1ffff,0x0004ffff,0x03fffff4,
+ 0x4fffff98,0x3ffffffe,0x0000000b,0x07ffffe8,0x7fffff98,0xffff9800,
+ 0x5000005f,0x03ffffff,0x37ffff40,0x09fffff1,0x3fffea00,0x2000efff,
+ 0xfffffffb,0xffffb004,0x7ff4005f,0xfff11fff,0x80001fff,0x99efffff,
+ 0x99999999,0x365fffff,0xffffffff,0x2000001c,0xffff9999,0xffff007f,
+ 0xff3000df,0x0000bfff,0x3fffffa0,0x3fff2005,0x3ffe21ff,0x260004ff,
+ 0xfffffffe,0xffffc801,0x3a003fff,0x000fffff,0x4ffffff6,0x07fffffa,
+ 0x7fffc400,0xffffffff,0xffffffff,0x3fffe67f,0xcfffffff,0xdb910001,
+ 0xffffffff,0xf100ffff,0x0009ffff,0x0bfffff3,0xfff50000,0x22003fff,
+ 0x445fffff,0x004fffff,0x7fffec40,0xfb102fff,0x05ffffff,0xffffff80,
+ 0x3fff2000,0xffff74ff,0xf98000df,0xffffffff,0xffffffff,0x7e47ffff,
+ 0xffffffff,0x800befff,0xffffffd9,0xffffffff,0xfffb807f,0xf98000ff,
+ 0x0005ffff,0xfffffd80,0x3fff6006,0x7ffc40ff,0x900004ff,0x7fffffff,
+ 0xfffffe88,0x7c4000ef,0x4007ffff,0xb5fffffb,0x00bfffff,0xfffffa80,
+ 0xffffffff,0xffffffff,0xfffffa87,0xffffffff,0x3fff601e,0xffffffff,
+ 0x07ffffff,0x17ffffdc,0xffff9800,0x4c00005f,0x02ffffff,0x5fffff50,
+ 0x9fffff10,0x7fdc0000,0xf34fffff,0x1dffffff,0xffff1000,0xffc800ff,
+ 0xfff94fff,0xb8000bff,0xffffffff,0xffffffff,0x106fffff,0xfffffff9,
+ 0x05ffffff,0xfffffff9,0xffffffff,0x554cffff,0x5ffffffc,0x3ffe6000,
+ 0x400005ff,0x06fffffd,0xbfffff10,0x3ffffe20,0xfd100004,0x41dfffff,
+ 0xfffffffb,0xffff0004,0x7e4001ff,0xff72ffff,0x8000ffff,0x9dfffff9,
+ 0x99999999,0x00999999,0xfffffc98,0x20ffffff,0xfffffffa,0xfffe809b,
+ 0x3ffffa7f,0x000dffff,0x3ffffe60,0x3e600005,0x002fffff,0x01fffff9,
+ 0x13ffffe2,0x3ffea000,0xa80dffff,0xdfffffff,0x7fff4000,0x3fa001ff,
+ 0xff51ffff,0x0001ffff,0x2fffffc4,0x26000000,0xfffffffc,0x3ffff63f,
+ 0xfffe806f,0x3ffffa7f,0x80001eff,0x05fffff9,0x3fff6000,0xff3006ff,
+ 0x7c407fff,0x0004ffff,0x7fffffdc,0x7ffcc04f,0x000effff,0x13fffff6,
+ 0x7ffffc40,0xfffff10f,0xff80009f,0x00007fff,0xfffb1000,0x7ffc9fff,
+ 0xfe801fff,0x3ffa7fff,0x00002eff,0x17ffffe6,0x7ffcc000,0xfd003fff,
+ 0xf880dfff,0x0004ffff,0x3ffffff2,0xffd1003f,0x005fffff,0x3ffffff2,
+ 0xffffc800,0x7ffffc7f,0x3a0000ff,0x002fffff,0x3fa00000,0xff36ffff,
+ 0xf100ffff,0x55cfffff,0x30000009,0x00bfffff,0x3ffff600,0xfff7006f,
+ 0xff8803ff,0x88004fff,0xfffffffe,0x7fec4002,0x803fffff,0x4ffffffa,
+ 0x7ffffcc0,0x7fffec3f,0x82001eff,0x0ffffffc,0xb0000000,0x269fffff,
+ 0x01ffffff,0x3fffffe6,0x40000007,0x05fffff9,0xffff8800,0xfff003ff,
+ 0xdddddfff,0xffffdddd,0x05ddddff,0x7fffff4c,0x320001ef,0x4fffffff,
+ 0xfffffd80,0xfffa80df,0xff886fff,0x0bffffff,0x7c47d730,0x01efffff,
+ 0x01c88620,0x3ffffea0,0xfffff12f,0x3ffea09f,0x3f67ffff,0xffffffff,
+ 0x001fffff,0x0bfffff3,0xffff9000,0x7ffc00ff,0xffffffff,0xffffffff,
+ 0x03ffffff,0xfffffff5,0xf700001d,0x1bffffff,0x7ffffcc0,0xffdcefff,
+ 0x02ffffff,0xfffffff7,0xffdddfff,0xfffb87ff,0x9abdffff,0x4ffdbaa9,
+ 0x2ab7ffe2,0x3ffee609,0x3fe0ffff,0x9bdfffff,0xffffffeb,0x3fffa7ff,
+ 0xffffffff,0xf3001fff,0x000bffff,0xffffff88,0x3fffe003,0xffffffff,
+ 0xffffffff,0xb83fffff,0x5fffffff,0x7fcc0000,0x01efffff,0x3ffffff2,
+ 0xffffffff,0x7f405fff,0xffffffff,0x3fffffff,0xffffffe8,0xffffffff,
+ 0x3fe24fff,0xffffffff,0xffffffff,0x7ffffdc5,0xffffffff,0x27ffffff,
+ 0xfffffffe,0x1fffffff,0xfffff300,0xffc8000b,0x2000ffff,0xffffffff,
+ 0xffffffff,0xffffffff,0x7fffec3f,0x00003fff,0xfffffd10,0x3f6205ff,
+ 0xffffffff,0x04ffffff,0xfffffd88,0xffffffff,0xffe883ff,0xffffffff,
+ 0x24ffffff,0xfffffff8,0xffffffff,0xfffd05ff,0xffffffff,0xfffff3df,
+ 0x7ffffff4,0xffffffff,0xffff3001,0x7c4000bf,0x004fffff,0x7ffffffc,
+ 0xffffffff,0xffffffff,0x3fffa3ff,0x0002ffff,0x7ffec400,0x2a02ffff,
+ 0xffffffff,0x002fffff,0x7fffffd4,0xffffffff,0x3fffee03,0xffffffff,
+ 0x3fe24fff,0xffffffff,0x04ffffff,0x3fffffe6,0x88dfffff,0x3fa7ffff,
+ 0xffffffff,0x001fffff,0x0bfffff3,0x7fffe400,0x664000ff,0xcccccccc,
+ 0xfffdcccc,0x1cccceff,0x3fffffee,0x20000001,0x0efffffc,0x7fff6440,
+ 0x00ceffff,0x3fffae00,0x2cefffff,0xffffd880,0xefffffff,0x3ffb621c,
+ 0xffffffff,0xc8800bef,0xdfffffff,0x9ffffe22,0xaaaaaaa9,0x0aaaaaaa,
+ 0xfffff300,0x3fe2000b,0x0004ffff,0x3ffe6000,0xffb804ff,0x000000ef,
+ 0x0efffb80,0x55d4c400,0x31000001,0x00013355,0xaabcca98,0x2aaa6001,
+ 0x0019abcb,0x15595310,0x40000000,0xfffffffa,0xffffffff,0x3206ffff,
+ 0x00ffffff,0x3e600000,0x7004ffff,0x000001bf,0x0077d400,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x3ffffea0,0xffffffff,0x06ffffff,
+ 0x9ffffff1,0x98000000,0x004fffff,0x0000000a,0x000004c0,0x00000000,
+ 0x00000000,0x00000000,0x54000000,0xffffffff,0xffffffff,0xff706fff,
+ 0x0001ffff,0xfff98000,0x000004ff,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x3ffffea0,0xffffffff,0x06ffffff,0x0bffffff,
+ 0xf3000000,0x0009ffff,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x7ffd4000,0xffffffff,0xffffffff,0xfffffb86,0x0000001f,
+ 0x4fffff98,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x000054c4,0x31004cc4,0x26200001,
+ 0xeeeb800a,0xeed801ee,0xddd30eee,0x70003ddd,0x009ddddd,0x01333330,
+ 0xeeeeea80,0x3bae004e,0x3bb25eee,0x440005ee,0x3a0eeeee,0xeeeeeeee,
+ 0xeeeeeeee,0x553003ee,0x75c00155,0x7ed44eee,0x701dffff,0x7fdcbddd,
+ 0x7fec44ff,0xeeeb83ff,0x7fff543e,0xff901dff,0xfd003fff,0x7f41ffff,
+ 0x8005ffff,0x03fffffe,0x3fffff80,0xffffd800,0xff9802ff,0x3f22ffff,
+ 0x40007fff,0x7c7ffff9,0xffffffff,0xffffffff,0xffb004ff,0x7e4003ff,
+ 0xffb16fff,0x7fffffff,0x32dfff90,0x13ffffff,0x9ffffffd,0x14ffffc8,
+ 0xfffffffb,0xfff907ff,0xffd003ff,0x7fdc1fff,0x2000ffff,0x0ffffff9,
+ 0xfffff800,0xfff88003,0x7400ffff,0x5c5fffff,0x000fffff,0x1ffffea0,
+ 0xffffffff,0xffffffff,0x32009fff,0x2000ffff,0xe8fffffc,0xffffffff,
+ 0x7fe44fff,0xfffff9ef,0xffffb6ff,0x7e41ffff,0xfff8cfff,0xffffffff,
+ 0x7fffe43f,0xfffe801f,0x3ffe20ff,0x32002fff,0x005fffff,0x07fffff0,
+ 0x3fffea00,0x3ff205ff,0x7d40ffff,0x0001ffff,0xf17fffee,0xffffffff,
+ 0xffffffff,0xf70089ff,0x64020fff,0xffdfffff,0xffffffff,0x3ff20fff,
+ 0xfffffeff,0xffffcfff,0x323fffff,0xffedffff,0xffffffff,0x7ffe47ff,
+ 0xffe801ff,0x7fec0fff,0x3e005fff,0x002fffff,0x07fffff0,0x7fffe400,
+ 0xfff983ff,0xff981fff,0x20002fff,0x7c4ffffc,0xffffffff,0xffffffff,
+ 0x2076c3ff,0xfb87fffb,0xfffffc81,0xedffffff,0x23ffffff,0xfffffffc,
+ 0xffffffdc,0xffffebff,0x3fffff25,0xfeffffff,0x23ffffff,0x01fffffc,
+ 0x0fffffe8,0x7fffffd4,0xffff9800,0x3fe0006f,0x40003fff,0x0ffffffe,
+ 0x27fffff4,0x07fffff0,0x7fffec00,0x4cccccc3,0xffb99999,0x7cc5ffff,
+ 0x3ffea2ff,0x21bff626,0xfffffffc,0x7ffec2ef,0x3fff26ff,0x3ffe2fff,
+ 0xff50efff,0x7ffe4dff,0x0befffff,0xbfffffd5,0x0fffffe4,0x7fffff40,
+ 0xffffff80,0xffffc803,0x3fe0003f,0x40003fff,0x6ffffff9,0x1bfffff2,
+ 0x09ffffd0,0x7fffec00,0xfff10002,0xfe81ffff,0xfff34fff,0x3ffffe6b,
+ 0x7ffffe42,0xfff105ff,0x7ffe4fff,0x7fff45ff,0x3ffe22ff,0x3ffff27f,
+ 0xff505fff,0x7fe4dfff,0xfe801fff,0xfb80ffff,0xf806ffff,0x000fffff,
+ 0x0fffffe0,0x3ffee000,0xfff9bfff,0x7ec01fff,0xffc85fff,0xfffe81ff,
+ 0xffd0001f,0xfb83ffff,0xfaefffff,0xffffcdff,0x7ffe46ff,0x7f406fff,
+ 0xff90ffff,0xffe83fff,0x7ffc46ff,0x3ffff27f,0xff100eff,0x7fe4ffff,
+ 0xfe801fff,0xf880ffff,0x201fffff,0x05fffffa,0x7ffffc00,0xffb00003,
+ 0xfffdffff,0xff9007ff,0xfffd0dff,0xfffff09f,0xfffb0001,0x3ae07fff,
+ 0xffffffff,0xffffffff,0x7fffe41d,0x7fec00ff,0xfff91fff,0xffffb0bf,
+ 0x7ffff887,0x3bfffff2,0x7ffff400,0xfffff90f,0xffffd003,0x3fff601f,
+ 0x3ff604ff,0x40002fff,0x003fffff,0xfffff100,0x0dffffff,0x1ffffee0,
+ 0x8ffffff3,0x007ffff8,0xffffffb8,0xfffea805,0xffffffff,0xfff900cf,
+ 0xdd7007ff,0x3ff23ddd,0xfffd84ff,0x7fffc41f,0x3fffff27,0xffffe802,
+ 0xfffff90f,0xffffd003,0x3ffea01f,0xfff107ff,0x77440fff,0xfeeeeeee,
+ 0xeeeeffff,0x003eeeee,0xfffffff5,0x2a001fff,0x320fffff,0x21ffffff,
+ 0x006ffff9,0x7fffffcc,0x3f66000e,0xbfffffff,0x7fffe400,0xfc80003f,
+ 0xffd84fff,0x7ffc41ff,0x3ffff27f,0xfffe802f,0xffff90ff,0xfffd003f,
+ 0x7ffc01ff,0xffb82fff,0x3e204fff,0xffffffff,0xffffffff,0x04ffffff,
+ 0x3fffff20,0x26003fff,0x3a1fffff,0x24ffffff,0x005ffff9,0x3fffffe2,
+ 0x7e4c001f,0x2effffff,0xfffffc80,0xffc80003,0xfffd84ff,0x7fffc41f,
+ 0x3fffff27,0xffffe802,0xfffff90f,0xffffd003,0x7ffe401f,0xfffe85ff,
+ 0x3fe200ff,0xffffffff,0xffffffff,0x004fffff,0x3fffffe2,0xfff8007f,
+ 0xffff32ff,0x7fd4ffff,0x3f6004ff,0x002fffff,0x3fffff66,0xbfffffff,
+ 0xfffff900,0xff900007,0xfffb09ff,0xffff883f,0x3fffff27,0xffffe802,
+ 0xfffff90f,0xffffd003,0x7ffc401f,0x3fe60fff,0x7c406fff,0xffffffff,
+ 0xffffffff,0x04ffffff,0x3fffff20,0x74003fff,0xff93ffff,0x25ffffff,
+ 0x002ffffb,0x9ffffff9,0x3fffaa00,0xffffffff,0x40cfffff,0x03fffffc,
+ 0xffffc800,0x1ffffd84,0x93ffffc4,0x005fffff,0x21fffffd,0x01fffffc,
+ 0x0fffffe8,0x7ffffec0,0x3fffff22,0x7fffc402,0xffffffff,0xffffffff,
+ 0xf5004fff,0xffffffff,0x7fec003f,0xdfffd4ff,0x3f2bffff,0xfa801fff,
+ 0x006fffff,0xfffffff7,0xffbbfff7,0xfc8fffff,0x0003ffff,0x84ffffc8,
+ 0x441ffffd,0x3f27ffff,0xe802ffff,0xf90fffff,0xd003ffff,0x801fffff,
+ 0x25fffffa,0x007fffff,0x33333333,0x39fffff3,0x13333333,0xfffff100,
+ 0x0dffffff,0x6ffffe40,0xffaffff9,0xfffd8fff,0x7ffc400f,0x2000ffff,
+ 0x98dffffe,0xfff55fff,0xfffc87ff,0xc80003ff,0xfd84ffff,0x7fc41fff,
+ 0x3fff27ff,0xffe802ff,0xfff90fff,0xffa805ff,0xf800ffff,0xf98fffff,
+ 0x0004ffff,0x0fffffe0,0x7fff4000,0xfffffeff,0xfff7004f,0x1ffff7df,
+ 0xfd5ffffb,0xffd00fff,0x8005ffff,0x3ea3fffa,0x3ffa26ff,0xfffffc86,
+ 0xffc80003,0xfffd84ff,0x7fffc41f,0x3fffff27,0xffffe802,0xfffff90f,
+ 0x7fffcc09,0xfc800fff,0xffcbffff,0x00001fff,0x00fffffe,0x3ffff200,
+ 0xffffd8ff,0xffa802ff,0x5fffdfff,0xffbffff5,0xffc80dff,0x0003ffff,
+ 0xfffa83db,0xfc81fc86,0x0003ffff,0x84ffffc8,0x441ffffd,0x3f27ffff,
+ 0xe802ffff,0xf70fffff,0x220dffff,0xffffffff,0xffff9800,0x6fffffef,
+ 0x7ffc0000,0x540003ff,0x13ffffff,0x1fffffff,0xfffff980,0xff13ffff,
+ 0xbfffffff,0x7ffffdc0,0x4020005f,0x0307fffb,0x0ffffff2,0x3fff2000,
+ 0xffffd84f,0x3ffffc41,0x05fffff9,0x1fffffd0,0x3fffffea,0x3fffee22,
+ 0x000fffff,0xfffffffd,0x00007fff,0x03fffff8,0x3fffe200,0x7ffd45ff,
+ 0x7c405fff,0xffffffff,0x3fffff60,0xff304fff,0x333fffff,0x33333333,
+ 0x3fff2001,0x3ff2000f,0x80003fff,0xd84ffffc,0x7c41ffff,0x3ff27fff,
+ 0xfe802fff,0xff10ffff,0xf9dfffff,0xffffffff,0x3ea001ff,0xffffffff,
+ 0x7c00000f,0x0003ffff,0x3ffffffa,0xfffffd80,0x7fffc03f,0x7d46ffff,
+ 0x3fffffff,0xfffffe88,0xffffffff,0x006fffff,0x003ffff9,0x1fffffe4,
+ 0x7ffe4000,0xffffd84f,0x3ffffc41,0x05fffff9,0x1fffffd0,0x7fffffe4,
+ 0xdfffffff,0x000fffff,0x3ffffffe,0x800004ff,0x003fffff,0xffffff90,
+ 0x3fffe205,0x3f601fff,0x43ffffff,0xfffffff8,0xffffa82f,0xffffffff,
+ 0x6fffffff,0x19999700,0x7fffe400,0xfc80003f,0xffd84fff,0x7ffc41ff,
+ 0x3ffff27f,0xfffe802f,0x3ffe20ff,0xffffffff,0xfffff8df,0x3fff2000,
+ 0x001fffff,0xfffff800,0xfffa8003,0x7d405fff,0x00efffff,0xfffffff9,
+ 0xfffffb01,0xfff503ff,0xffffffff,0xffffffff,0x2000000d,0x03fffffc,
+ 0xffffc800,0x1ffffd84,0x93ffffc4,0x005fffff,0x81fffffd,0xfffffffa,
+ 0xfff14fff,0x7cc001ff,0x06ffffff,0xffff0000,0xff88007f,0x800fffff,
+ 0x4ffffffd,0xffffff70,0x3fffea0d,0xfff507ff,0xffffffff,0xffffffff,
+ 0x2000000d,0x03fffffc,0xffffc800,0x1ffffd84,0x93ffffc4,0x005fffff,
+ 0x01fffffd,0xffffffd1,0x7fffc45d,0x7ff4000f,0x0003ffff,0x39999900,
+ 0xffffd800,0xff1002ff,0x505fffff,0x07ffffff,0x3fffffe2,0xfffff507,
+ 0xffffffff,0x0dffffff,0x3f200000,0x0003ffff,0x84ffffc8,0x441ffffd,
+ 0x3f27ffff,0xe802ffff,0x200fffff,0x001abb98,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x1ffffd00,
+ 0x66665c00,0xcccccccc,0xcccccccc,0x80000000,0x42aaaaa8,0x42aaaaa8,
+ 0xaaaaaaa8,0x6eeeec01,0xdddddddd,0xdddddddd,0x02dddddd,0x00000000,
+ 0x00000000,0x00000000,0x7dc00000,0x2005ffff,0xfffffffd,0xffffffff,
+ 0x501fffff,0x005bdfd9,0xfffff500,0xfffffa8d,0xfffffb86,0x3ffe02ff,
+ 0xffffffff,0xffffffff,0xffffffff,0x00000003,0x00000000,0x00000000,
+ 0x20000000,0xfffffff8,0xffffb002,0xffffffff,0xffffffff,0xfffffb03,
+ 0xa9801bff,0xfff50aaa,0xfffa8dff,0xffd306ff,0x3e05ffff,0xffffffff,
+ 0xffffffff,0xffffffff,0x000003ff,0x00000000,0x00000000,0x00000000,
+ 0x3fffff60,0xffb006ff,0xffffffff,0xffffffff,0x7ff443ff,0xffffffff,
+ 0x3ffff601,0xbfffff31,0x5fffff98,0x3ffff620,0xffff81ff,0xffffffff,
+ 0xffffffff,0x3fffffff,0x00000000,0x00000000,0x00000000,0xf3000000,
+ 0xffffdfff,0xffffb009,0xffffffff,0xffffffff,0x7ffffdc3,0x2fffffff,
+ 0x21ffffb0,0x45fffff9,0x05fffff9,0xffffffb8,0x7fffffc1,0xffffffff,
+ 0xffffffff,0x003fffff,0x00000000,0x00000000,0x00000000,0xfffd0000,
+ 0x03ffffad,0x33333310,0x33333333,0xe8333333,0xffffffff,0x442fffff,
+ 0x3e27ffff,0x7c44ffff,0x3004ffff,0x03fffffd,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x7fdc0000,0xffff51ff,0x0000000b,0x67ffffd4,
+ 0xffffffb9,0xfffe98cf,0x3fffe26f,0xfffff84f,0x3bb22004,0x00000dee,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x45ffff88,0x002ffffd,
+ 0xff700000,0xffe889ff,0xffffffff,0x7ffc3fff,0xffff83ff,0x0000003f,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x3fff2000,0x7fffcc1f,
+ 0x0000000f,0x81ffffc8,0xffffffe8,0x40ffffff,0xf82fffff,0x0003ffff,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0xf3000000,0x3f209fff,
+ 0x00004fff,0xffffd800,0xffffb101,0x07ffffff,0xd05ffffd,0x0005ffff,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x3a000000,0xf100ffff,
+ 0xd903ffff,0xdddddddd,0xdddddddd,0x2aaa3ddd,0x7fe400aa,0x02ffffff,
+ 0xd03ffffd,0x0003ffff,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0xf5000000,0xfb807fff,0xffd86fff,0xffffffff,0xffffffff,0x4c0001ff,
+ 0x01cefffd,0x207ffff6,0x001ffffd,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x44000000,0xd006ffff,0xfd87ffff,0xffffffff,0xffffffff,
+ 0x00001fff,0xccca8002,0xcccca80c,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x17fffe40,0xfffffa80,0x3fffff60,0xffffffff,
+ 0x1fffffff,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x7ffcc000,0x7ff4006f,0x3bbb24ff,0xeeeeeeee,0xeeeeeeee,
+ 0x0000001e,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x65400000,0x4c001ccc,0x000ccccc,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,
+ 0x00000000,0x00000000,0x00000000,0x00000000,
+};
+
+static signed short stb__consolas_bold_50_usascii_x[95]={ 0,9,5,1,2,0,0,10,6,5,3,1,5,6,
+8,1,1,2,3,3,0,3,2,2,2,1,9,5,2,3,4,6,0,0,3,2,2,4,4,1,2,3,4,3,
+4,1,2,0,3,0,3,2,1,2,0,0,0,0,2,7,2,6,2,0,0,2,3,3,1,2,0,1,3,3,
+2,3,3,1,3,1,3,1,4,3,1,3,0,0,0,0,3,3,11,5,1, };
+static signed short stb__consolas_bold_50_usascii_y[95]={ 37,2,2,5,0,2,2,2,0,0,2,11,27,21,
+27,2,4,4,4,4,5,5,5,5,4,4,11,11,9,16,9,2,1,5,5,4,5,5,5,4,5,5,5,5,
+5,5,5,4,5,4,5,4,5,5,5,5,5,5,5,1,2,1,5,42,2,11,2,11,2,11,2,11,2,1,
+1,2,2,11,11,11,11,11,11,11,4,12,12,12,12,12,12,1,-3,1,17, };
+static unsigned short stb__consolas_bold_50_usascii_w[95]={ 0,9,17,26,24,28,29,8,17,16,22,25,14,16,
+11,24,26,23,22,22,27,22,24,23,23,24,10,14,21,22,21,18,28,28,23,23,25,20,20,25,24,21,19,24,
+21,26,24,27,23,28,24,23,25,24,28,27,28,28,23,14,24,14,24,28,17,23,23,21,24,23,26,25,22,22,
+21,24,22,26,22,25,23,24,22,21,23,22,28,28,27,28,21,20,6,19,26, };
+static unsigned short stb__consolas_bold_50_usascii_h[95]={ 0,36,13,32,44,36,36,13,48,48,22,25,19,6,
+11,41,34,33,33,34,32,33,33,32,34,33,27,35,29,15,29,36,47,32,32,34,32,32,32,34,32,32,33,32,
+32,32,32,34,32,43,32,34,32,33,32,32,32,32,32,46,41,46,16,6,11,27,36,27,36,27,35,37,35,36,
+47,35,35,26,26,27,36,36,26,27,34,26,25,25,25,36,25,46,51,46,13, };
+static unsigned short stb__consolas_bold_50_usascii_s[95]={ 254,244,76,79,165,82,52,244,25,8,231,
+126,237,237,244,219,1,220,172,28,47,99,122,23,51,147,241,124,97,26,75,
+111,43,199,175,191,127,106,235,215,54,1,1,210,153,154,129,163,228,190,49,
+75,103,195,181,21,74,1,30,135,1,150,1,112,94,213,208,145,1,167,49,
+26,26,232,72,76,101,24,51,119,184,159,1,191,139,74,97,180,152,130,209,
+94,1,115,49, };
+static unsigned short stb__consolas_bold_50_usascii_t[95]={ 1,1,294,201,1,53,53,132,1,1,267,
+267,234,254,146,1,132,132,132,132,234,132,132,234,132,132,91,91,234,294,234,
+53,1,201,201,91,201,201,167,91,201,234,167,167,201,167,167,91,201,1,167,
+132,167,132,167,167,167,201,201,1,53,1,294,294,294,234,53,234,95,234,91,
+53,91,53,1,91,91,267,267,234,53,53,267,234,91,267,267,267,267,53,267,
+1,1,1,294, };
+static unsigned short stb__consolas_bold_50_usascii_a[95]={ 440,440,440,440,440,440,440,440,
+440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
+440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
+440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
+440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
+440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,
+440,440,440,440,440,440,440, };
+
+// Call this function with
+// font: NULL or array length
+// data: NULL or specified size
+// height: STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT or STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT_POW2
+// return value: spacing between lines
+static void stb_font_consolas_bold_50_usascii(stb_fontchar font[STB_FONT_consolas_bold_50_usascii_NUM_CHARS],
+ unsigned char data[STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT][STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH],
+ int height)
+{
+ int i,j;
+ if (data != 0) {
+ unsigned int *bits = stb__consolas_bold_50_usascii_pixels;
+ unsigned int bitpack = *bits++, numbits = 32;
+ for (i=0; i < STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH*height; ++i)
+ data[0][i] = 0; // zero entire bitmap
+ for (j=1; j < STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT-1; ++j) {
+ for (i=1; i < STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH-1; ++i) {
+ unsigned int value;
+ if (numbits==0) bitpack = *bits++, numbits=32;
+ value = bitpack & 1;
+ bitpack >>= 1, --numbits;
+ if (value) {
+ if (numbits < 3) bitpack = *bits++, numbits = 32;
+ data[j][i] = (bitpack & 7) * 0x20 + 0x1f;
+ bitpack >>= 3, numbits -= 3;
+ } else {
+ data[j][i] = 0;
+ }
+ }
+ }
+ }
+
+ // build font description
+ if (font != 0) {
+ float recip_width = 1.0f / STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH;
+ float recip_height = 1.0f / height;
+ for (i=0; i < STB_FONT_consolas_bold_50_usascii_NUM_CHARS; ++i) {
+ // pad characters so they bilerp from empty space around each character
+ font[i].s0 = (stb__consolas_bold_50_usascii_s[i]) * recip_width;
+ font[i].t0 = (stb__consolas_bold_50_usascii_t[i]) * recip_height;
+ font[i].s1 = (stb__consolas_bold_50_usascii_s[i] + stb__consolas_bold_50_usascii_w[i]) * recip_width;
+ font[i].t1 = (stb__consolas_bold_50_usascii_t[i] + stb__consolas_bold_50_usascii_h[i]) * recip_height;
+ font[i].x0 = stb__consolas_bold_50_usascii_x[i];
+ font[i].y0 = stb__consolas_bold_50_usascii_y[i];
+ font[i].x1 = stb__consolas_bold_50_usascii_x[i] + stb__consolas_bold_50_usascii_w[i];
+ font[i].y1 = stb__consolas_bold_50_usascii_y[i] + stb__consolas_bold_50_usascii_h[i];
+ font[i].advance_int = (stb__consolas_bold_50_usascii_a[i]+8)>>4;
+ font[i].s0f = (stb__consolas_bold_50_usascii_s[i] - 0.5f) * recip_width;
+ font[i].t0f = (stb__consolas_bold_50_usascii_t[i] - 0.5f) * recip_height;
+ font[i].s1f = (stb__consolas_bold_50_usascii_s[i] + stb__consolas_bold_50_usascii_w[i] + 0.5f) * recip_width;
+ font[i].t1f = (stb__consolas_bold_50_usascii_t[i] + stb__consolas_bold_50_usascii_h[i] + 0.5f) * recip_height;
+ font[i].x0f = stb__consolas_bold_50_usascii_x[i] - 0.5f;
+ font[i].y0f = stb__consolas_bold_50_usascii_y[i] - 0.5f;
+ font[i].x1f = stb__consolas_bold_50_usascii_x[i] + stb__consolas_bold_50_usascii_w[i] + 0.5f;
+ font[i].y1f = stb__consolas_bold_50_usascii_y[i] + stb__consolas_bold_50_usascii_h[i] + 0.5f;
+ font[i].advance = stb__consolas_bold_50_usascii_a[i]/16.0f;
+ }
+ }
+}
+
+#ifndef STB_SOMEFONT_CREATE
+#define STB_SOMEFONT_CREATE stb_font_consolas_bold_50_usascii
+#define STB_SOMEFONT_BITMAP_WIDTH STB_FONT_consolas_bold_50_usascii_BITMAP_WIDTH
+#define STB_SOMEFONT_BITMAP_HEIGHT STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT
+#define STB_SOMEFONT_BITMAP_HEIGHT_POW2 STB_FONT_consolas_bold_50_usascii_BITMAP_HEIGHT_POW2
+#define STB_SOMEFONT_FIRST_CHAR STB_FONT_consolas_bold_50_usascii_FIRST_CHAR
+#define STB_SOMEFONT_NUM_CHARS STB_FONT_consolas_bold_50_usascii_NUM_CHARS
+#define STB_SOMEFONT_LINE_SPACING STB_FONT_consolas_bold_50_usascii_LINE_SPACING
+#endif
+
diff --git a/Projects/Asteroids/src/subset_d3d12.h b/Projects/Asteroids/src/subset_d3d12.h
new file mode 100644
index 0000000..8fe2a1b
--- /dev/null
+++ b/Projects/Asteroids/src/subset_d3d12.h
@@ -0,0 +1,50 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include "util.h"
+#include "descriptor.h"
+
+#include <d3d12.h>
+
+__declspec(align(64)) // Avoid false sharing
+class SubsetD3D12
+{
+public:
+ SubsetD3D12(ID3D12Device* mDevice, UINT srvCount, ID3D12PipelineState* pso)
+ {
+ ThrowIfFailed(mDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&mCmdAlloc)));
+ ThrowIfFailed(mDevice->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, mCmdAlloc, pso, IID_PPV_ARGS(&mCmdLst)));
+ ThrowIfFailed(mCmdLst->Close());
+ }
+
+ ~SubsetD3D12()
+ {
+ SafeRelease(&mCmdLst);
+ SafeRelease(&mCmdAlloc);
+ }
+
+ ID3D12GraphicsCommandList* Begin(ID3D12PipelineState* pso)
+ {
+ ThrowIfFailed(mCmdAlloc->Reset());
+ ThrowIfFailed(mCmdLst->Reset(mCmdAlloc, pso));
+ return mCmdLst;
+ }
+
+ ID3D12GraphicsCommandList* End()
+ {
+ ThrowIfFailed(mCmdLst->Close());
+ return mCmdLst;
+ }
+
+ ID3D12GraphicsCommandList* mCmdLst = nullptr;
+ ID3D12CommandAllocator* mCmdAlloc = nullptr;
+};
diff --git a/Projects/Asteroids/src/texture.cpp b/Projects/Asteroids/src/texture.cpp
new file mode 100644
index 0000000..d62b913
--- /dev/null
+++ b/Projects/Asteroids/src/texture.cpp
@@ -0,0 +1,285 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#include "texture.h"
+#include "util.h"
+#include "noise.h"
+#include "DDSTextureLoader.h"
+
+#include <stdint.h>
+#include <sstream>
+
+
+static void WaitForAll(ID3D12Device* device, ID3D12CommandQueue* queue)
+{
+ // Kind of ugly, but yeah...
+ ID3D12Fence* fence = nullptr;
+ ThrowIfFailed(device->CreateFence( 0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)));
+ auto eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+ queue->Signal(fence, 1);
+ fence->SetEventOnCompletion(1, eventHandle);
+ WaitForSingleObject(eventHandle, INFINITE);
+
+ CloseHandle(eventHandle);
+ fence->Release();
+}
+
+
+void GenerateMips2D_XXXX8(D3D11_SUBRESOURCE_DATA* subresources, size_t widthLevel0, size_t heightLevel0, size_t mipLevels)
+{
+ for (size_t m = 1; m < mipLevels; ++m) {
+ auto rowPitchSrc = subresources[m - 1].SysMemPitch;
+ const BYTE* dataSrc = (BYTE*)subresources[m - 1].pSysMem;
+
+ auto rowPitchDst = subresources[m].SysMemPitch;
+ BYTE* dataDst = (BYTE*)subresources[m].pSysMem;
+
+ auto width = widthLevel0 >> m;
+ auto height = heightLevel0 >> m;
+
+ // Iterating byte-wise is simpler in this case (pulls apart color nicely)
+ // Not optimized at all, obviously...
+ for (size_t y = 0; y < height; ++y) {
+ auto rowSrc0 = (dataSrc + (y*2+0)*rowPitchSrc);
+ auto rowSrc1 = (dataSrc + (y*2+1)*rowPitchSrc);
+ auto rowDst = (dataDst + (y )*rowPitchDst);
+ for (size_t x = 0; x < width; ++x) {
+ for (size_t comp = 0; comp < 4; ++comp) {
+ uint32_t c = rowSrc0[x*8+comp+0];
+ c += rowSrc0[x*8+comp+4];
+ c += rowSrc1[x*8+comp+0];
+ c += rowSrc1[x*8+comp+4];
+ c = c / 4;
+ assert(c < 256);
+ rowDst[4*x+comp] = (byte)c;
+ }
+ }
+ }
+ }
+}
+
+
+void FillNoise2D_RGBA8(D3D11_SUBRESOURCE_DATA* subresources, size_t width, size_t height, size_t mipLevels,
+ float seed, float persistence, float noiseScale, float noiseStrength,
+ float redScale, float greenScale, float blueScale)
+{
+ NoiseOctaves<4> textureNoise(persistence);
+
+ // Level 0
+ for (size_t y = 0; y < height; ++y) {
+ uint32_t* row = (uint32_t*)((BYTE*)subresources[0].pSysMem + y*subresources[0].SysMemPitch);
+ for (size_t x = 0; x < width; ++x) {
+ auto c = textureNoise((float)x*noiseScale, (float)y*noiseScale, seed);
+ c = std::max(0.0f, std::min(1.0f, (c - 0.5f) * noiseStrength + 0.5f));
+
+ int32_t cr = (int32_t)(c * redScale);
+ int32_t cg = (int32_t)(c * greenScale);
+ int32_t cb = (int32_t)(c * blueScale);
+ assert(cr >= 0 && cr < 256);
+ assert(cg >= 0 && cg < 256);
+ assert(cb >= 0 && cb < 256);
+
+ row[x] = (cr) << 16 | (cg) << 8 | (cb) << 0;
+ }
+ }
+
+ if (mipLevels > 1)
+ GenerateMips2D_XXXX8(subresources, width, height, mipLevels);
+}
+
+
+void InitializeTexture2D(
+ ID3D12Device* device, ID3D12CommandQueue* cmdQueue,
+ ID3D12Resource* texture, const D3D12_RESOURCE_DESC* desc, UINT bytesPerPixel,
+ const D3D11_SUBRESOURCE_DATA* initialData,
+ D3D12_RESOURCE_STATES stateAfter)
+{
+ // Pull some data
+ auto format = desc->Format;
+ UINT width = (UINT)desc->Width;
+ UINT height = desc->Height;
+ UINT arraySize = desc->DepthOrArraySize;
+ UINT mipLevels = desc->MipLevels;
+
+ // Pow2 mip chain!
+ assert(mipLevels == 1 || ((width & (width-1)) == 0 && (height & (height-1)) == 0));
+
+ std::vector<D3D12_PLACED_SUBRESOURCE_FOOTPRINT> placedUpload;
+ UINT64 totalSize = 0;
+ for (UINT a = 0; a < arraySize; ++a) {
+ for (UINT m = 0; m < mipLevels; ++m) {
+ D3D12_PLACED_SUBRESOURCE_FOOTPRINT placed = {};
+ placed.Footprint.Format = format;
+ placed.Footprint.Width = width >> m; // TODO: Handle mip sizes properly!
+ placed.Footprint.Height = height >> m; // TODO: Handle mip sizes properly!
+ placed.Footprint.Depth = 1;
+ placed.Footprint.RowPitch = Align<UINT>(placed.Footprint.Width * bytesPerPixel, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT);
+ placed.Offset = totalSize;
+
+ totalSize = Align<UINT64>(placed.Offset + (placed.Footprint.RowPitch * placed.Footprint.Height),
+ D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT);
+ placedUpload.push_back(placed);
+ }
+ }
+
+ ID3D12Resource* uploadBuffer = nullptr;
+ ThrowIfFailed(device->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
+ D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer(totalSize),
+ D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr,
+ IID_PPV_ARGS(&uploadBuffer)
+ ));
+
+ BYTE *baseData = nullptr;
+ ThrowIfFailed(uploadBuffer->Map(0, nullptr, reinterpret_cast<void**>(&baseData)));
+
+ // Fill in data (RGBA8)
+ for (UINT a = 0; a < arraySize; ++a) {
+ for (UINT m = 0; m < mipLevels; ++m) {
+ auto subresource = a * mipLevels + m;
+
+ BYTE* dataSrc = (BYTE*)initialData[subresource].pSysMem;
+ auto rowPitchSrc = initialData[subresource].SysMemPitch;
+
+ auto placed = &placedUpload[subresource];
+ BYTE* dataDst = baseData + placed->Offset;
+ auto rowPitchDst = placed->Footprint.RowPitch;
+ UINT width_mip = placed->Footprint.Width;
+ UINT height_mip = placed->Footprint.Height;
+
+ for (UINT y = 0; y < height_mip; ++y) {
+ memcpy(dataDst + y*rowPitchDst, dataSrc + y*rowPitchSrc, bytesPerPixel * width_mip);
+ }
+ }
+ }
+
+ // Create some new resources for initialization
+ ID3D12GraphicsCommandList* cmdLst = nullptr;
+ ID3D12CommandAllocator* cmdAlloc = nullptr;
+ ThrowIfFailed(device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc)));
+ ThrowIfFailed(device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdLst)));
+
+ {
+ ResourceBarrier rb;
+ rb.AddTransition(texture, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST);
+ rb.Submit(cmdLst);
+ }
+
+ // Copy data from each subresource into texture
+ for (size_t s = 0; s < placedUpload.size(); ++s) {
+ CD3DX12_TEXTURE_COPY_LOCATION dest(texture, static_cast<UINT>(s));
+ CD3DX12_TEXTURE_COPY_LOCATION src(uploadBuffer, placedUpload[s]);
+
+ cmdLst->CopyTextureRegion(
+ &dest, 0, 0, 0,
+ &src, nullptr);
+ }
+
+ {
+ ResourceBarrier rb;
+ rb.AddTransition(texture, D3D12_RESOURCE_STATE_COPY_DEST, stateAfter);
+ rb.Submit(cmdLst);
+ }
+
+ ThrowIfFailed(cmdLst->Close());
+ cmdQueue->ExecuteCommandLists(1, reinterpret_cast<ID3D12CommandList*const*>(&cmdLst));
+
+ // Kind of ugly... but yeah
+ WaitForAll(device, cmdQueue);
+
+ SafeRelease(&uploadBuffer);
+ SafeRelease(&cmdLst);
+ SafeRelease(&cmdAlloc);
+}
+
+
+HRESULT CreateTexture2DFromDDS_XXXX8(
+ ID3D12Device* device, ID3D12CommandQueue* cmdQueue,
+ ID3D12Resource** texture,
+ const char* fileName,
+ DXGI_FORMAT format,
+ D3D12_RESOURCE_STATES stateAfter )
+{
+ BYTE* heapData = nullptr;
+ DDS_HEADER* header = nullptr;
+ BYTE* bitData = nullptr;
+ UINT bitSize = 0;
+
+ std::wostringstream wfileName;
+ wfileName << fileName;
+
+ HRESULT hr = LoadTextureDataFromFile(wfileName.str().c_str(), &heapData, &header, &bitData, &bitSize);
+ if (FAILED(hr)) {
+ delete[] heapData;
+ return hr;
+ }
+
+ unsigned int arraySize = 1;
+
+ if (header->dwCaps2 & DDS_CUBEMAP) {
+ assert((header->dwCaps2 & DDS_CUBEMAP_ALLFACES ) == DDS_CUBEMAP_ALLFACES);
+ arraySize = 6;
+ }
+
+ // We only support XXXX8_UNORM[_SRGB] atm...
+ if (format != DXGI_FORMAT_B8G8R8A8_UNORM && format != DXGI_FORMAT_R8G8B8A8_UNORM &&
+ format != DXGI_FORMAT_B8G8R8A8_UNORM_SRGB && format != DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) {
+ return E_NOTIMPL;
+ }
+
+ unsigned int mipLevels = header->dwMipMapCount;
+ if (mipLevels == 0) mipLevels = 1; // Hacky... but good enough for now
+
+ // TODO: lots of stuff is not checked... just don't be stupid, this is hacky sample code after all :)
+
+ auto desc = CD3DX12_RESOURCE_DESC::Tex2D(
+ format, header->dwWidth, header->dwHeight,
+ (UINT16)arraySize, (UINT16)mipLevels );
+
+ ThrowIfFailed(device->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
+ D3D12_HEAP_FLAG_NONE,
+ &desc,
+ D3D12_RESOURCE_STATE_COMMON,
+ nullptr,
+ IID_PPV_ARGS(texture)
+ ));
+
+ std::vector<D3D11_SUBRESOURCE_DATA> initialData(desc.MipLevels * arraySize);
+
+ BYTE* srcBits = bitData;
+ const BYTE *endBits = bitData + bitSize;
+
+ for (UINT a = 0; a < arraySize; ++a) {
+ for (UINT m = 0; m < desc.MipLevels; ++m) {
+ auto width = (UINT)desc.Width >> m;
+ auto height = desc.Height >> m;
+ auto subresource = a * desc.MipLevels + m;
+ auto rowPitch = 4 * width;
+ auto bytes = rowPitch * height;
+
+ assert(srcBits + bytes <= endBits);
+
+ initialData[subresource].pSysMem = (void*)srcBits;
+ initialData[subresource].SysMemPitch = rowPitch;
+ initialData[subresource].SysMemSlicePitch = bytes;
+
+ srcBits += bytes;
+ }
+ }
+
+ InitializeTexture2D(device, cmdQueue, *texture, &desc, 4, initialData.data(), stateAfter);
+
+ delete[] heapData;
+ return S_OK;
+}
diff --git a/Projects/Asteroids/src/texture.h b/Projects/Asteroids/src/texture.h
new file mode 100644
index 0000000..d3ed698
--- /dev/null
+++ b/Projects/Asteroids/src/texture.h
@@ -0,0 +1,46 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include <d3d12.h>
+#include <d3dx12.h>
+#include <d3d11.h>
+
+void GenerateMips2D_XXXX8(D3D11_SUBRESOURCE_DATA* subresources, size_t widthLevel0, size_t heightLevel0, size_t mipLevels);
+
+// Will generate mips (into subresources array) is mipLevels > 0
+void FillNoise2D_RGBA8(D3D11_SUBRESOURCE_DATA* subresources, size_t width, size_t height, size_t mipLevels,
+ float seed, float persistence, float noiseScale, float noiseStrength,
+ float redScale = 255.0f, float greenScale = 255.0f, float blueScale = 255.0f);
+
+
+// Helper for uploading initial texture data in D3D12; as with D3D11, one initialData structure per subresource
+// Creates temporary resources internally and syncs with GPU... this is a convenience function for init time!
+// NOTE: Currently textures with mip chain must be pow2!
+// Transitions resource from D3D12_RESOURCE_USAGE_INITIAL to "stateAfter"
+void InitializeTexture2D(
+ ID3D12Device* device,
+ ID3D12CommandQueue* cmdQueue,
+ ID3D12Resource* texture,
+ const D3D12_RESOURCE_DESC* desc,
+ UINT bytesPerPixel,
+ const D3D11_SUBRESOURCE_DATA* initialData,
+ D3D12_RESOURCE_STATES stateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
+
+// NOTE: This function very much only works for the specific path(s) that we use it for!
+// Not very general-purpose yet.
+HRESULT CreateTexture2DFromDDS_XXXX8(
+ ID3D12Device* device,
+ ID3D12CommandQueue* cmdQueue,
+ ID3D12Resource** texture,
+ const char* fileName,
+ DXGI_FORMAT format, // Should match file otherwise expect explosion/wackiness...
+ D3D12_RESOURCE_STATES stateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
diff --git a/Projects/Asteroids/src/upload_heap.h b/Projects/Asteroids/src/upload_heap.h
new file mode 100644
index 0000000..582925e
--- /dev/null
+++ b/Projects/Asteroids/src/upload_heap.h
@@ -0,0 +1,60 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include "util.h"
+#include <d3d12.h>
+
+// Untyped version
+class UploadHeap
+{
+public:
+ UploadHeap(ID3D12Device* device, UINT64 size)
+ {
+ ThrowIfFailed(device->CreateCommittedResource(
+ &CD3DX12_HEAP_PROPERTIES( D3D12_HEAP_TYPE_UPLOAD ),
+ D3D12_HEAP_FLAG_NONE,
+ &CD3DX12_RESOURCE_DESC::Buffer( size ),
+ D3D12_RESOURCE_STATE_GENERIC_READ,
+ nullptr,
+ IID_PPV_ARGS(&mHeap)
+ ));
+
+ ThrowIfFailed(mHeap->Map(0, nullptr, reinterpret_cast<void**>(&mHeapWO)));
+ }
+
+ ~UploadHeap()
+ {
+ SafeRelease(&mHeap);
+ }
+
+ ID3D12Resource* Heap() { return mHeap; }
+
+ // Write-only!
+ void* DataWO() { return mHeapWO; }
+
+private:
+ ID3D12Resource* mHeap = nullptr;
+ void* mHeapWO = nullptr;
+};
+
+
+// Structure/typed version
+template <typename T>
+class UploadHeapT : public UploadHeap
+{
+public:
+ UploadHeapT(ID3D12Device* device)
+ : UploadHeap(device, sizeof(T))
+ {}
+
+ T* DataWO() { return (T*)UploadHeap::DataWO(); }
+};
diff --git a/Projects/Asteroids/src/util.h b/Projects/Asteroids/src/util.h
new file mode 100644
index 0000000..7779954
--- /dev/null
+++ b/Projects/Asteroids/src/util.h
@@ -0,0 +1,79 @@
+// Copyright 2014 Intel Corporation All Rights Reserved
+//
+// Intel makes no representations about the suitability of this software for any purpose.
+// THIS SOFTWARE IS PROVIDED ""AS IS."" INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES,
+// EXPRESS OR IMPLIED, AND ALL LIABILITY, INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES,
+// FOR THE USE OF THIS SOFTWARE, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY
+// RIGHTS, AND INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+// Intel does not assume any responsibility for any errors which may appear in this software
+// nor any responsibility to update it.
+
+#pragma once
+
+#include <assert.h>
+#include <d3d12.h>
+
+#include <algorithm>
+#include <vector>
+
+#define CBUFFER_ALIGN __declspec(align(D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT))
+
+#define WIDE_HELPER_2(x) L##x
+#define WIDE_HELPER_1(x) WIDE_HELPER_2(x)
+#define W__FILE__ WIDE_HELPER_1(__FILE__)
+
+template<typename T>
+inline void SafeRelease(T** p)
+{
+ auto q = *p;
+ if (q != nullptr) {
+ q->Release();
+ *p = nullptr;
+ }
+}
+
+inline HRESULT ThrowIfFailed(HRESULT hr)
+{
+ if (FAILED(hr)) throw;
+ return hr;
+}
+
+template <typename T>
+inline T Align(T v, T align)
+{
+ return (v + (align-1)) & ~(align-1);
+}
+
+struct ResourceBarrier {
+ std::vector<D3D12_RESOURCE_BARRIER> mDescs;
+
+ void AddTransition(
+ ID3D12Resource* resource,
+ D3D12_RESOURCE_STATES stateBefore,
+ D3D12_RESOURCE_STATES stateAfter,
+ UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES)
+ {
+ D3D12_RESOURCE_BARRIER desc = {};
+ desc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ desc.Transition.pResource = resource;
+ desc.Transition.StateBefore = stateBefore;
+ desc.Transition.StateAfter = stateAfter;
+ desc.Transition.Subresource = subresource;
+ mDescs.push_back(desc);
+ }
+
+ void ReverseTransitions()
+ {
+ for (auto ii = mDescs.begin(), ie = mDescs.end(); ii != ie; ++ii) {
+ if (ii->Type == D3D12_RESOURCE_BARRIER_TYPE_TRANSITION) {
+ std::swap(ii->Transition.StateBefore, ii->Transition.StateAfter);
+ }
+ }
+ }
+
+ void Submit(ID3D12GraphicsCommandList* commandList) const
+ {
+ assert(mDescs.size() <= UINT_MAX);
+ commandList->ResourceBarrier((UINT)mDescs.size(), mDescs.data());
+ }
+};