[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n\n# Custom for Visual Studio\n*.cs     diff=csharp\n*.sln    merge=union\n*.csproj merge=union\n*.vbproj merge=union\n*.fsproj merge=union\n*.dbproj merge=union\n\n# Standard to msysgit\n*.doc\t diff=astextplain\n*.DOC\t diff=astextplain\n*.docx diff=astextplain\n*.DOCX diff=astextplain\n*.dot  diff=astextplain\n*.DOT  diff=astextplain\n*.pdf  diff=astextplain\n*.PDF\t diff=astextplain\n*.rtf\t diff=astextplain\n*.RTF\t diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "#################\n## Eclipse\n#################\n\n*.pydevproject\n.project\n.metadata\nbin/\ntmp/\n*.tmp\n*.bak\n*.swp\n*~.nib\nlocal.properties\n.classpath\n.settings/\n.loadpath\n\n# External tool builders\n.externalToolBuilders/\n\n# Locally stored \"Eclipse launch configurations\"\n*.launch\n\n# CDT-specific\n.cproject\n\n# PDT-specific\n.buildpath\n\n\n#################\n## Visual Studio\n#################\n\n## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n\n# Build results\n\n[Dd]ebug/\n[Rr]elease/\nx64/\nbuild/\n[Bb]in/\n[Oo]bj/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n*_i.c\n*_p.c\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.log\n*.scc\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n*.ncrunch*\n.*crunch*.local.xml\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.Publish.xml\n*.pubxml\n\n# NuGet Packages Directory\n## TODO: If you have NuGet Package Restore enabled, uncomment the next line\n#packages/\n\n# Windows Azure Build Output\ncsx\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\nsql/\n*.Cache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.[Pp]ublish.xml\n*.pfx\n*.publishsettings\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file to a newer\n# Visual Studio version. Backup files are not needed, because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\nApp_Data/*.mdf\nApp_Data/*.ldf\n\n#############\n## Windows detritus\n#############\n\n# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Mac crap\n.DS_Store\n\n\n#############\n## Python\n#############\n\n*.py[co]\n\n# Packages\n*.egg\n*.egg-info\ndist/\nbuild/\neggs/\nparts/\nvar/\nsdist/\ndevelop-eggs/\n.installed.cfg\n\n# Installer logs\npip-log.txt\n\n# Unit test / coverage reports\n.coverage\n.tox\n\n#Translations\n*.mo\n\n#Mr Developer\n.mr.developer.cfg\n"
  },
  {
    "path": "CPUT/CPUT/CPUT.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n// use this file except in compliance with the License.  You may obtain a copy\n// of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\n// License for the specific language governing permissions and limitations\n// under the License.\n////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTBASE_H__\n#define __CPUTBASE_H__\n\n// Master #defines for which target\n#define CPUT_FOR_DX11\n\n#include <stdlib.h>\n#include <crtdbg.h>\n#include <stdio.h>\n#include <string>\n#include <sstream>\n#include <assert.h>\n#include \"CPUTMath.h\"\n#include \"CPUTEventHandler.h\"\n#include \"CPUTCallbackHandler.h\"\n#include \"CPUTTimer.h\"\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n// For D3DPERF_* calls, you also need d3d9.lib included\n#include <d3d9.h>               // required for all the pix D3DPERF_BeginEvent()/etc calls\n#include <ittnotify.h>\n#include \"CPUTITTTaskMarker.h\"  // markup helper for GPA Platform Analyzer tags\n#include \"CPUTPerfTaskMarker.h\" // markup helper for GPA Frame Analyzer tags\n\n// GLOBAL instrumentation junk\nenum CPUT_GPA_INSTRUMENTATION_STRINGS{\n    GPA_HANDLE_CPUT_CREATE = 0,\n    GPA_HANDLE_CONTEXT_CREATION,\n    GPA_HANDLE_SYSTEM_INITIALIZATION,\n    GPA_HANDLE_MAIN_MESSAGE_LOOP,\n    GPA_HANDLE_EVENT_DISPATCH_AND_HANDLE,\n    GPA_HANDLE_LOAD_SET,\n    GPA_HANDLE_LOAD_MODEL,\n    GPA_HANDLE_LOAD_MATERIAL,\n    GPA_HANDLE_LOAD_TEXTURE,\n    GPA_HANDLE_LOAD_CAMERAS,\n    GPA_HANDLE_LOAD_LIGHTS,\n    GPA_HANDLE_LOAD_VERTEX_SHADER,\n    GPA_HANDLE_LOAD_GEOMETRY_SHADER,\n    GPA_HANDLE_LOAD_PIXEL_SHADER,\n    GPA_HANDLE_DRAW_GUI,\n    GPA_HANDLE_STRING_ENUMS_SIZE,\n};\n#endif // CPUT_GPA_INSTRUMENTATION\n\n\n// Heap corruption, ASSERT, and TRACE defines\n//-----------------------------------------------------------------------------\n#ifdef _DEBUG\n    #include <tchar.h>\n    #define TRACE(String)  {OutputDebugString(String);}\n    #define DEBUGMESSAGEBOX(Title, Text) { CPUTOSServices::GetOSServices()->OpenMessageBox(Title, Text);}\n    #define ASSERT(Condition, Message) { if( !(Condition) ) { cString msg = cString(_T(__FUNCTION__)) + _L(\":  \") + Message; OutputDebugString(msg.c_str()); DEBUGMESSAGEBOX(_L(\"Assert\"), msg ); } assert(Condition);}\n    #define HEAPCHECK     { int  heapstatus = _heapchk(); ASSERT(_HEAPOK == heapstatus, _L(\"Heap corruption\") ); }\n    // #define HEAPCHECK     {}\n#else\n    #define ASSERT(Condition, Message)\n    #define TRACE(String)\n    #define DEBUGMESSAGEBOX(Title, Text)\n    #define HEAPCHECK\n#endif // _DEBUG\n\n\n// Error codes\n//-----------------------------------------------------------------------------\ntypedef enum CPUTResult\n{\n    // success\n    CPUT_SUCCESS = 0x00000000,\n\n    // warnings\n//    CPUT_WARNING_OUT_OF_RANGE,\n    CPUT_WARNING_NOT_FOUND,\n//    CPUT_WARNING_ALREADY_EXISTS,\n//    CPUT_WARNING_FILE_IN_SEARCH_PATH_BUT_NOT_WHERE_SPECIFIED,\n//    CPUT_WARNING_PHONG_SHADER_MISSING_TEXTURE,\n    CPUT_WARNING_CANCELED,\n//    CPUT_WARNING_NO_SUITABLE_FORMAT_FOUND,\n//\n    CPUT_WARNING_SHADER_INPUT_SLOT_NOT_MATCHED,\n//\n//    // file errors\n    CPUT_ERROR_FILE_NOT_FOUND = 0xF0000001,\n    CPUT_ERROR_FILE_READ_ERROR = CPUT_ERROR_FILE_NOT_FOUND+1,\n    CPUT_ERROR_FILE_CLOSE_ERROR = CPUT_ERROR_FILE_NOT_FOUND+2,\n    CPUT_ERROR_FILE_IO_ERROR = CPUT_ERROR_FILE_NOT_FOUND+3,\n    CPUT_ERROR_FILE_NO_SUCH_DEVICE_OR_ADDRESS = CPUT_ERROR_FILE_NOT_FOUND+4,\n    CPUT_ERROR_FILE_BAD_FILE_NUMBER = CPUT_ERROR_FILE_NOT_FOUND+5,\n    CPUT_ERROR_FILE_NOT_ENOUGH_MEMORY = CPUT_ERROR_FILE_NOT_FOUND+6,\n    CPUT_ERROR_FILE_PERMISSION_DENIED = CPUT_ERROR_FILE_NOT_FOUND+7,\n    CPUT_ERROR_FILE_DEVICE_OR_RESOURCE_BUSY = CPUT_ERROR_FILE_NOT_FOUND+8,\n    CPUT_ERROR_FILE_EXISTS = CPUT_ERROR_FILE_NOT_FOUND+9,\n    CPUT_ERROR_FILE_IS_A_DIRECTORY = CPUT_ERROR_FILE_NOT_FOUND+10,\n    CPUT_ERROR_FILE_TOO_MANY_OPEN_FILES = CPUT_ERROR_FILE_NOT_FOUND+11,\n    CPUT_ERROR_FILE_TOO_LARGE = CPUT_ERROR_FILE_NOT_FOUND+12,\n    CPUT_ERROR_FILE_DEVICE_FULL = CPUT_ERROR_FILE_NOT_FOUND+13,\n    CPUT_ERROR_FILE_FILENAME_TOO_LONG = CPUT_ERROR_FILE_NOT_FOUND+14,\n    CPUT_ERROR_FILE_PATH_ERROR = CPUT_ERROR_FILE_NOT_FOUND+15,\n    CPUT_ERROR_FILE_ERROR = CPUT_ERROR_FILE_NOT_FOUND+16,\n//\n//    CPUT_ERROR_DIRECTORY_NOT_FOUND = CPUT_ERROR_FILE_NOT_FOUND+21,\n//\n//    // subsystem errors\n    CPUT_ERROR_INVALID_PARAMETER = 0xF0000100,\n    CPUT_ERROR_NOT_FOUND = CPUT_ERROR_INVALID_PARAMETER+1,\n//    CPUT_ERROR_COMPONENT_NOT_INITIALIZED = CPUT_ERROR_INVALID_PARAMETER+2,\n//    CPUT_ERROR_SUBSYSTEM_OUT_OF_MEMORY = CPUT_ERROR_INVALID_PARAMETER+3,\n//    CPUT_ERROR_OUT_OF_BOUNDS = CPUT_ERROR_INVALID_PARAMETER+4,\n//    CPUT_ERROR_HEAP_CORRUPTION = CPUT_ERROR_INVALID_PARAMETER+5,\n//\n//    // image format errors\n    CPUT_ERROR_UNSUPPORTED_IMAGE_FORMAT = 0xF0000200,\n//    CPUT_ERROR_ERROR_LOADING_IMAGE = CPUT_ERROR_UNSUPPORTED_IMAGE_FORMAT+1,\n    CPUT_ERROR_UNSUPPORTED_SRGB_IMAGE_FORMAT,\n//\n//    // shader loading errors\n//    CPUT_SHADER_LOAD_ERROR = 0xF0000300,\n//    CPUT_SHADER_COMPILE_ERROR = CPUT_SHADER_LOAD_ERROR+1,\n//    CPUT_SHADER_LINK_ERROR = CPUT_SHADER_LOAD_ERROR+2,\n//    CPUT_SHADER_REGISTRATION_ERROR = CPUT_SHADER_LOAD_ERROR+3,\n//    CPUT_SHADER_CONSTANT_BUFFER_ERROR = CPUT_SHADER_LOAD_ERROR+4,\n//    CPUT_SHADER_REFLECTION_ERROR = CPUT_SHADER_LOAD_ERROR+5,\n//\n//    // texture loading errors\n    CPUT_TEXTURE_LOAD_ERROR = 0xF0000400,\n    CPUT_ERROR_TEXTURE_FILE_NOT_FOUND = CPUT_TEXTURE_LOAD_ERROR+1,\n//\n//    // GUI errors\n    CPUT_GUI_GEOMETRY_CREATION_ERROR = 0xF0000500,\n//    CPUT_GUI_SAMPLER_CREATION_ERROR = CPUT_GUI_GEOMETRY_CREATION_ERROR+1,\n//    CPUT_GUI_TEXTURE_CREATION_ERROR = CPUT_GUI_GEOMETRY_CREATION_ERROR+2,\n//    CPUT_GUI_CANNOT_CREATE_CONTROL = CPUT_GUI_GEOMETRY_CREATION_ERROR+3,\n    CPUT_GUI_INVALID_CONTROL_ID = CPUT_GUI_GEOMETRY_CREATION_ERROR+4,\n//\n//    // Texture loading errors\n//    CPUT_FONT_TEXTURE_TYPE_ERROR = 0xF0000600,\n//    CPUT_FONT_TEXTURE_LOAD_ERROR = CPUT_FONT_TEXTURE_TYPE_ERROR+1,\n//\n//    // Model loading errors\n//    CPUT_ERROR_MODEL_LOAD_ERROR = 0xF0000650,\n//    CPUT_ERROR_MODEL_FILE_NOT_FOUND = CPUT_ERROR_MODEL_LOAD_ERROR+1,\n//\n//    // Shader errors\n    CPUT_ERROR_VERTEX_LAYOUT_PROBLEM = 0xF0000700,\n//    CPUT_ERROR_VERTEX_BUFFER_CREATION_PROBLEM = CPUT_ERROR_VERTEX_LAYOUT_PROBLEM+1,\n//    CPUT_ERROR_INDEX_BUFFER_CREATION_PROBLEM = CPUT_ERROR_VERTEX_LAYOUT_PROBLEM+2,\n//    CPUT_ERROR_UNSUPPORTED_VERTEX_ELEMENT_TYPE = CPUT_ERROR_VERTEX_LAYOUT_PROBLEM+3,\n//    CPUT_ERROR_INDEX_BUFFER_LAYOUT_PROBLEM = CPUT_ERROR_VERTEX_LAYOUT_PROBLEM+4,\n    CPUT_ERROR_SHADER_INPUT_SLOT_NOT_MATCHED = CPUT_ERROR_VERTEX_LAYOUT_PROBLEM+5,\n//\n//\n//    // Context creation errors\n//    CPUT_ERROR_CONTEXT_CREATION_FAILURE = 0xF0000C00,\n//    CPUT_ERROR_SWAP_CHAIN_CREATION_FAILURE = CPUT_ERROR_CONTEXT_CREATION_FAILURE+1,\n//    CPUT_ERROR_RENDER_TARGET_VIEW_CREATION_FAILURE = CPUT_ERROR_CONTEXT_CREATION_FAILURE+2,\n//\n//    // Depth buffer errors\n//    CPUT_ERROR_DEPTH_BUFFER_CREATION_ERROR = 0xF0000800,\n//    CPUT_ERROR_DEPTH_STENCIL_BUFFER_CREATION_ERROR = CPUT_ERROR_DEPTH_BUFFER_CREATION_ERROR+1,\n//    CPUT_ERROR_RASTER_STATE_CREATION_ERROR = CPUT_ERROR_DEPTH_BUFFER_CREATION_ERROR+2,\n//\n//    // GUI shaders\n    CPUT_ERROR_INITIALIZATION_GUI_VERTEX_SHADER_NOT_FOUND = 0xF0000130,\n    CPUT_ERROR_INITIALIZATION_GUI_PIXEL_SHADER_NOT_FOUND = CPUT_ERROR_INITIALIZATION_GUI_VERTEX_SHADER_NOT_FOUND+1,\n    CPUT_ERROR_INITIALIZATION_GUI_CONTROL_TEXTURES_NOT_FOUND = CPUT_ERROR_INITIALIZATION_GUI_VERTEX_SHADER_NOT_FOUND+2,\n//\n//    // gfx system errors\n//    CPUT_ERROR_GFX_SUBSYSTEM_BUSY = 0xF0000B00,\n//    CPUT_ERROR_GFX_SUBSYSTEM_TO_MANY_OBJECTS = CPUT_ERROR_GFX_SUBSYSTEM_BUSY+1,\n//\n//    // window layer errors\n    CPUT_ERROR_WINDOW_CANNOT_REGISTER_APP = 0xF0000D00,\n    CPUT_ERROR_WINDOW_ALREADY_EXISTS = CPUT_ERROR_WINDOW_CANNOT_REGISTER_APP+1,\n//    CPUT_ERROR_CANNOT_GET_WINDOW_CLASS = CPUT_ERROR_WINDOW_CANNOT_REGISTER_APP+3,\n    CPUT_ERROR_CANNOT_GET_WINDOW_INSTANCE = CPUT_ERROR_WINDOW_CANNOT_REGISTER_APP+4,\n//    CPUT_ERROR_WINDOW_OS_PROPERTY_GET_ERROR = CPUT_ERROR_WINDOW_CANNOT_REGISTER_APP+5,\n//\n//    // AssetLibrary/AssetSet errors\n    CPUT_ERROR_ASSET_LIBRARY_INVALID_LIBRARY = 0xF0000E00,\n//    CPUT_ERROR_ASSET_SET_INVALID_TYPE = CPUT_ERROR_ASSET_LIBRARY_INVALID_LIBRARY+1,\n//    CPUT_ERROR_ASSET_LIBRARY_OBJECT_NOT_FOUND,\n//    CPUT_ERROR_ASSET_ALREADY_EXISTS = CPUT_ERROR_ASSET_LIBRARY_INVALID_LIBRARY+3,\n//\n//    // Paramter block errors.\n    CPUT_ERROR_PARAMETER_BLOCK_NOT_FOUND = 0xF0000F00,\n//\n//    // misc errors\n//    CPUT_ERROR_FULLSCREEN_SWITCH_ERROR = 0xF0000F00,\n} CPUTResult;\n\nstatic int gRefCount = 0;\n//handy defines\n//-----------------------------------------------------------------------------\n#define SAFE_RELEASE(p)     {if((p)){HEAPCHECK; gRefCount = (p)->Release(); (p)=NULL; HEAPCHECK;} }\n#define SAFE_DELETE(p)      {if((p)){HEAPCHECK; delete (p);     (p)=NULL;HEAPCHECK; }}\n#define SAFE_DELETE_ARRAY(p){if((p)){HEAPCHECK; delete[](p);    (p)=NULL;HEAPCHECK; }}\n#define UNREFERENCED_PARAMETER(P) (P)\n\n// CPUT data types\n//-----------------------------------------------------------------------------\n#define CPUTSUCCESS(returnCode) ((returnCode) < 0xF0000000)\n#define CPUTFAILED(returnCode) ((returnCode) >= 0xF0000000)\n\n\n//typedef UINT CPUTResult;\ntypedef unsigned int UINT;\ntypedef unsigned long DWORD;\n\n// color\nstruct CPUTColor4\n{\n    float r;\n    float g;\n    float b;\n    float a;\n\n    bool operator == (const CPUTColor4& rhs) const\n    {\n        return((rhs.r == r) && \n               (rhs.g == g) &&\n               (rhs.b == b) &&\n               (rhs.a == a));\n    }\n    bool operator != (const CPUTColor4& rhs) const\n    {\n        return((rhs.r != r) || \n               (rhs.g != g) ||\n               (rhs.b != b) ||\n               (rhs.a != a));\n    }\n};\n\n// where the loader should start looking from to locate files\nenum CPUT_PATH_SEARCH_MODE\n{\n    CPUT_PATH_SEARCH_RESOURCE_DIRECTORY,\n    CPUT_PATH_SEARCH_NONE,\n};\n\n// string size limitations\nconst UINT CPUT_MAX_PATH = 2048;\nconst UINT CPUT_MAX_STRING_LENGTH = 1024;\nconst UINT CPUT_MAX_SHADER_ERROR_STRING_LENGTH = 8192;\nconst UINT CPUT_MAX_DIGIT_STRING_LENGTH = 5;\n\n\n\n// Data format types used in interpreting mesh data\nenum CPUT_DATA_FORMAT_TYPE\n{\n    CPUT_UNKNOWN=0,\n\n    CPUT_DOUBLE=1,\n    CPUT_F32=2,\n\n    CPUT_U64=3,\n    CPUT_I64=4,\n\n    CPUT_U32=5,\n    CPUT_I32=6,\n\n    CPUT_U16=7,\n    CPUT_I16=8,\n\n    CPUT_U8=9,\n    CPUT_I8=10,\n\n    CPUT_CHAR=11,\n    CPUT_BOOL=12,\n};\n\n// Corresponding sizes (in bytes) that match CPUT_DATA_FORMAT_TYPE\nconst int CPUT_DATA_FORMAT_SIZE[] =\n{\n        0, //CPUT_UNKNOWN=0,\n        \n        8, //CPUT_DOUBLE,\n        4, //CPUT_F32,\n        \n        8, //CPUT_U64,\n        8, //CPUT_I64,\n        \n        4, //CPUT_U32,\n        4, //CPUT_I32,\n        \n        2, //CPUT_U16,\n        2, //CPUT_I16,\n        \n        1, //CPUT_U8,\n        1, //CPUT_I8,\n\n        1, //CPUT_CHAR\n        1, //CPUT_BOOL\n};\n\n//-----------------------------------------------------------------------------\nenum eCPUTMapType\n{\n    CPUT_MAP_UNDEFINED = 0,\n    CPUT_MAP_READ = 1,\n    CPUT_MAP_WRITE = 2,\n    CPUT_MAP_READ_WRITE = 3,\n    CPUT_MAP_WRITE_DISCARD = 4,\n    CPUT_MAP_NO_OVERWRITE = 5\n};\n\n// routines to support unicode + multibyte\n// TODO: Move to string file\n//-----------------------------------------------------------------------------\n#if defined (UNICODE) || defined(_UNICODE)\n\n    // define string and literal types\n    #define cString std::wstring\n\t#define cStringStream std::wstringstream\n\t#define cFile std::wfstream\n    #define _L(x)      L##x\n\n    // convert integer to wide/unicode ascii\n    //-----------------------------------------------------------------------------\n    inline std::wstring itoc(const int integer)\n    {\n        wchar_t wcstring[CPUT_MAX_STRING_LENGTH];\n        swprintf_s(&wcstring[0], CPUT_MAX_STRING_LENGTH, _L(\"%d\"),integer);\n        std::wstring ws(wcstring);\n\n        return ws;\n    }\n\n    // convert pointer to wide/unicode ascii\n    //-----------------------------------------------------------------------------\n    inline std::wstring ptoc(const void *pPointer)\n    {\n        std::wstringstream wstream;\n        //std::ostringstream os;\n        wstream << pPointer;\n\n        std::wstring address;\n        address = wstream.str();\n\n        return address;\n    }\n\n    // convert char* to wide/unicode string\n    //-----------------------------------------------------------------------------\n    inline std::wstring s2ws(const char* stringArg)\n    {\n        // compute the size of the buffer I need to allocate\n        size_t numConvertedChars;\n        mbstowcs_s(&numConvertedChars, NULL, 0, stringArg, _TRUNCATE);\n        numConvertedChars++;  // +1 for null termination\n        if(numConvertedChars>CPUT_MAX_STRING_LENGTH)\n        {\n            numConvertedChars = CPUT_MAX_STRING_LENGTH;\n        }\n\n        // allocate the converted string and copy\n        wchar_t *pWString = new wchar_t[numConvertedChars];\n        mbstowcs_s(&numConvertedChars, pWString, numConvertedChars, stringArg, _TRUNCATE);\n        std::wstring ws(pWString);\n        delete [] pWString;\n        return ws;\n        /*\n        // alternate method - less 'safe', but possibly useful for unix\n        std::string s = stringArg;\n\n        std::wstring ws(s.begin(), s.end());\n        ws.assign(s.begin(), s.end());\n\n        return ws;\n        */\n    }\n\n    // convert wide/unicode string to char\n    //-----------------------------------------------------------------------------\n    inline char* ws2s(std::wstring string)\n    {\n        size_t numConverted, finalCount;\n\n        // what size of buffer (in bytes) do we need to allocate for conversion?\n        wcstombs_s(&numConverted, NULL, 0, string.c_str(), CPUT_MAX_STRING_LENGTH);\n        numConverted+=2; // for null termination\n        char *pBuffer = new char[numConverted];\n\n        // do the actual conversion\n        wcstombs_s(&finalCount, pBuffer, numConverted, string.c_str(), CPUT_MAX_STRING_LENGTH);\n\n        return pBuffer;\n    }\n\n#else\n\n    // define string and literal types\n    #define cString std::string\n\t#define cStringStream std::stringstream\n\t#define cFile std::fstream\n    #define _L(x)      x\n\n    // conversion routine\n    //-----------------------------------------------------------------------------\n    inline std::string s2ws(const char* stringArg) { return std::string(stringArg); }\n\n    // convert integer to char string\n    //-----------------------------------------------------------------------------\n    inline std::string itoc(const int integer)\n    {\n        char string[CPUT_MAX_STRING_LENGTH];\n        sprintf_s(string, CPUT_MAX_STRING_LENGTH, \"%d\",integer);\n        std::string s(string);\n\n        return s;\n    }\n\n    // convert pointer to wide/unicode ascii\n    //-----------------------------------------------------------------------------\n    inline std::string ptoc(const void *pPointer)\n    {\n        std::ostringstream stream;\n\n        stream << pPointer;\n\n        std::string address;\n        address = stream.str();\n\n        return address;\n    }\n\n    // conversion from ws2s\n    // Doesn't do anything in multibyte version since string is already a char*\n    //-----------------------------------------------------------------------------\n    inline char* ws2s(const char* string)\n    {\n        return const_cast<char*>(string);\n    }\n#endif\n\n#ifdef CPUT_FOR_DX11\n#include \"CPUTRenderTarget.h\"\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n\nclass CPUTCamera;\nclass CPUTRenderStateBlock;\n\n// CPUT class\n//-----------------------------------------------------------------------------\nclass CPUT:public CPUTEventHandler, public CPUTCallbackHandler\n{\nprotected:\n    CPUTCamera  *mpCamera;\n    CPUTCamera  *mpShadowCamera;\n\tCPUTTimer   *mpTimer;\n    float3       mLightColor; // TODO: Get from light(s)\n    float3       mAmbientColor;\n    CPUTBuffer  *mpBackBuffer;\n    CPUTBuffer  *mpDepthBuffer;\n    CPUTTexture *mpBackBufferTexture;\n    CPUTTexture *mpDepthBufferTexture;\n\npublic:\n    CPUT() :\n        mpCamera(NULL),\n        mpShadowCamera(NULL),\n        mAmbientColor(0.2f, 0.2f, 0.2f),\n        mLightColor(1.0f, 1.0f, 1.0f),\n        mpBackBuffer(NULL),\n        mpDepthBuffer(NULL),\n        mpBackBufferTexture(NULL),\n        mpDepthBufferTexture(NULL)\n    {}\n    virtual ~CPUT() {}\n\n    CPUTCamera  *GetCamera() { return mpCamera; }\n    CPUTCamera  *GetShadowCamera() { return mpShadowCamera; } // TODO: Support more than one.\n    virtual void InnerExecutionLoop() {;}\n    virtual void ResizeWindowSoft(UINT width, UINT height) {UNREFERENCED_PARAMETER(width);UNREFERENCED_PARAMETER(height);}\n    virtual void ResizeWindow(UINT width, UINT height) {\n        CPUTRenderTargetColor::SetActiveWidthHeight( width, height );\n        CPUTRenderTargetDepth::SetActiveWidthHeight( width, height );\n    }\n    virtual void DeviceShutdown(){}\n\n    virtual CPUTEventHandledCode CPUTHandleKeyboardEvent(CPUTKey key) {UNREFERENCED_PARAMETER(key);return CPUT_EVENT_UNHANDLED;}\n    virtual CPUTEventHandledCode CPUTHandleMouseEvent(int x, int y, int wheel, CPUTMouseState state) {UNREFERENCED_PARAMETER(x);UNREFERENCED_PARAMETER(y);UNREFERENCED_PARAMETER(wheel);UNREFERENCED_PARAMETER(state);return CPUT_EVENT_UNHANDLED;}\n\n    float3 &GetAmbientColor() { return mAmbientColor; }\n    void    SetAmbientColor( float3 &ambientColor ) {  mAmbientColor = ambientColor; }\n    float3 &GetLightColor() { return mLightColor; }\n    void    SetLightColor( float3 &lightColor ) {  mLightColor = lightColor; }\n};\n\n// Include this here to make sure ASSERT resolves correctly\n#include \"CPUTOSServicesWin.h\"\n\nvoid CPUTSetDebugName( void *pResource, cString name );\n#endif // #ifndef __CPUTBASE_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTAssetLibrary.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n// use this file except in compliance with the License.  You may obtain a copy\n// of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\n// License for the specific language governing permissions and limitations\n// under the License.\n////////////////////////////////////////////////////////////////////////////////\n#include <algorithm> // for std::string.transform()\n#include \"CPUTAssetLibrary.h\"\n#include \"CPUTRenderNode.h\"\n#include \"CPUTAssetSet.h\"\n#include \"CPUTMaterial.h\"\n#include \"CPUTRenderStateBlock.h\"\n#include \"CPUTModel.h\"\n#include \"CPUTCamera.h\"\n#include \"CPUTLight.h\"\n#include \"CPUTFont.h\"\n#include \"CPUTBuffer.h\"\n\n// TODO: How do we want to store both DX and OGL assets in the same library?\n//       Could use API-specific libraries.  Could move both platforms to single file.  etc.\n// CPUTAssetLibrary   *CPUTAssetLibrary::mpAssetLibrary = new CPUTAssetLibraryDX11();\nCPUTAssetListEntry *CPUTAssetLibrary::mpAssetSetList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpNullNodeList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpModelList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpCameraList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpLightList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpMaterialList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpTextureList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpBufferList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpConstantBufferList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpRenderStateBlockList = NULL;\nCPUTAssetListEntry *CPUTAssetLibrary::mpFontList = NULL;\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetLibrary::ReleaseTexturesAndBuffers()\n{\n    CPUTAssetListEntry *pMaterial = mpMaterialList;\n    while( pMaterial )\n    {\n        ((CPUTMaterial*)pMaterial->pData)->ReleaseTexturesAndBuffers();\n        pMaterial = pMaterial->pNext;\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetLibrary::RebindTexturesAndBuffers()\n{\n    CPUTAssetListEntry *pMaterial = mpMaterialList;\n    while( pMaterial )\n    {\n        ((CPUTMaterial*)pMaterial->pData)->RebindTexturesAndBuffers();\n        pMaterial = pMaterial->pNext;\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetLibrary::DeleteAssetLibrary()\n{\n    SAFE_DELETE(mpAssetLibrary);\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetLibrary::ReleaseAllLibraryLists()\n{\n    // Release philosophy:  Everyone that references releases.  If node refers to parent, then it should release parent, etc...\n    // TODO: Traverse lists.  Print names and ref counts (as debug aid)\n#undef SAFE_RELEASE_LIST\n#define SAFE_RELEASE_LIST(x) {ReleaseList(x); x = NULL;}\n\n    SAFE_RELEASE_LIST(mpAssetSetList);\n    SAFE_RELEASE_LIST(mpMaterialList);\n    SAFE_RELEASE_LIST(mpModelList);\n    SAFE_RELEASE_LIST(mpLightList);\n    SAFE_RELEASE_LIST(mpCameraList);\n    SAFE_RELEASE_LIST(mpNullNodeList);\n    SAFE_RELEASE_LIST(mpTextureList );\n    SAFE_RELEASE_LIST(mpBufferList );\n    SAFE_RELEASE_LIST(mpConstantBufferList );\n    SAFE_RELEASE_LIST(mpRenderStateBlockList );\n    SAFE_RELEASE_LIST(mpFontList);\n\n    // The following -specific items are destroyed in the derived class\n    // TODO.  Move their declaration and definition to the derived class too\n    // SAFE_RELEASE_LIST(mpPixelShaderList);\n    // SAFE_RELEASE_LIST(mpVertexShaderList);\n    // SAFE_RELEASE_LIST(mpGeometryShaderList);\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetLibrary::ReleaseList(CPUTAssetListEntry *pLibraryRoot)\n{\n    CPUTAssetListEntry *pNext;\n    for( CPUTAssetListEntry *pNodeEntry = pLibraryRoot; NULL != pNodeEntry; pNodeEntry = pNext )\n    {\n        pNext = pNodeEntry->pNext;\n        CPUTRefCount *pRefCountedNode = (CPUTRefCount*)pNodeEntry->pData;\n        pRefCountedNode->Release();\n        HEAPCHECK;\n        delete pNodeEntry;\n    }\n}\n\n// Find an asset in a specific library\n// ** Does not Addref() returned items **\n// Asset library doesn't care if we're using absolute paths for names or not, it\n// just adds/finds/deletes the matching string literal.\n//-----------------------------------------------------------------------------\nvoid *CPUTAssetLibrary::FindAsset(const cString &name, CPUTAssetListEntry *pList, bool nameIsFullPathAndFilename)\n{\n    cString absolutePathAndFilename;\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename ? name : (mAssetSetDirectoryName + name), &absolutePathAndFilename);\n    absolutePathAndFilename = nameIsFullPathAndFilename ? name : absolutePathAndFilename;\n\n    UINT hash = CPUTComputeHash( absolutePathAndFilename );\n    while(NULL!=pList)\n    {\n        if( hash == pList->hash && (0 == _wcsicmp( absolutePathAndFilename.data(), pList->name.data() )) )\n        {\n            return (void*)pList->pData;\n        }\n        pList = pList->pNext;\n    }\n    return NULL;\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetLibrary::AddAsset(const cString &name, void *pAsset, CPUTAssetListEntry **pHead)\n{\n    // convert string to lowercase\n    cString lowercaseName = name;\n    std::transform(lowercaseName.begin(), lowercaseName.end(), lowercaseName.begin(), ::tolower);\n\n    // Do we already have one by this name?\n    CPUTAssetListEntry *pTail = *pHead;\n    // TODO:  Save explicit tail pointer instead of iterating to find the null.\n    for( CPUTAssetListEntry *pCur=*pHead; NULL!=pCur; pCur=pCur->pNext )\n    {\n        // Assert that we haven't added one with this name\n        ASSERT( 0 != _wcsicmp( pCur->name.data(), name.data() ), _L(\"Warning: asset \")+name+_L(\" already exists\") );\n        pTail = pCur;\n    }\n    CPUTAssetListEntry **pDest = pTail ? &pTail->pNext : pHead;\n    *pDest = new CPUTAssetListEntry();\n    (*pDest)->hash = CPUTComputeHash(name);\n    (*pDest)->name = name;\n    (*pDest)->pData = pAsset;\n    (*pDest)->pNext = NULL;\n\n    // TODO: Our assets are not yet all derived from CPUTRenderNode.\n    // TODO: For now, rely on caller performing the AddRef() as it knows the assets type.\n    ((CPUTRefCount*)pAsset)->AddRef();\n}\n\n//-----------------------------------------------------------------------------\nCPUTRenderStateBlock *CPUTAssetLibrary::GetRenderStateBlock(const cString &name, bool nameIsFullPathAndFilename )\n{\n    // Resolve name to absolute path before searching\n    cString finalName;\n    if( name.at(0) == '$' )\n    {\n        finalName = name;\n    } else\n    {\n        // Resolve name to absolute path\n        CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName);\n    }\n\n    // see if the render state block is already in the library\n    CPUTRenderStateBlock *pRenderStateBlock = FindRenderStateBlock(finalName, true);\n    if(NULL==pRenderStateBlock)\n    {\n        return CPUTRenderStateBlock::CreateRenderStateBlock( name, finalName );\n    }\n    pRenderStateBlock->AddRef();\n    return pRenderStateBlock;\n}\n\n//-----------------------------------------------------------------------------\nCPUTAssetSet *CPUTAssetLibrary::GetAssetSet( const cString &name, bool nameIsFullPathAndFilename )\n{\n    // Resolve the absolute path\n    cString absolutePathAndFilename;\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename ? name\n        : (mAssetSetDirectoryName + name + _L(\".set\")), &absolutePathAndFilename );\n    absolutePathAndFilename = nameIsFullPathAndFilename ? name : absolutePathAndFilename;\n\n    CPUTAssetSet *pAssetSet = FindAssetSet(absolutePathAndFilename, true);\n    if(NULL == pAssetSet)\n    {\n        return CPUTAssetSet::CreateAssetSet( name, absolutePathAndFilename );\n    }\n    pAssetSet->AddRef();\n    return pAssetSet;\n}\n\n\n// TODO: All of these Get() functions look very similar.\n// Keep them all for their interface, but have them call a common function\n//-----------------------------------------------------------------------------\nCPUTMaterial *CPUTAssetLibrary::GetMaterial(const cString &name, bool nameIsFullPathAndFilename, const cString &modelSuffix, const cString &meshSuffix)\n{\n    // Resolve name to absolute path before searching\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    cString absolutePathAndFilename;\n    pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mMaterialDirectoryName + name + _L(\".mtl\")), &absolutePathAndFilename);\n\n    // If we already have one by this name, then return it\n    CPUTMaterial *pMaterial = FindMaterial(absolutePathAndFilename, true);\n    if(NULL==pMaterial)\n    {\n        // We don't already have it in the library, so create it.\n        pMaterial = CPUTMaterial::CreateMaterial( absolutePathAndFilename, modelSuffix, meshSuffix );\n        return pMaterial;\n    }\n    else if( (0==modelSuffix.length()) && !pMaterial->MaterialRequiresPerModelPayload() )\n    {\n        // This material doesn't have per-model elements, so we don't need to clone it.\n        pMaterial->AddRef();\n        return pMaterial;\n    }\n\n#ifdef _DEBUG\n    // We need to clone the material.  Do that by loading it again, but with a different name.\n    // Add the model's suffix (address as string, plus model's material array index as string)\n    CPUTMaterial *pUniqueMaterial = FindMaterial(absolutePathAndFilename + modelSuffix + meshSuffix, true);\n    ASSERT( NULL == pUniqueMaterial, _L(\"Unique material already not unique: \") + absolutePathAndFilename + modelSuffix + meshSuffix );\n#endif\n\n    CPUTMaterial *pClonedMaterial = pMaterial->CloneMaterial( absolutePathAndFilename, modelSuffix, meshSuffix );\n    AddMaterial( absolutePathAndFilename + modelSuffix + meshSuffix, pClonedMaterial );\n\n    return pClonedMaterial;\n}\n\n// Get CPUTModel from asset library\n// If the model exists, then the existing model is Addref'ed and returned\n//-----------------------------------------------------------------------------\nCPUTModel *CPUTAssetLibrary::GetModel(const cString &name, bool nameIsFullPathAndFilename)\n{\n    // Resolve name to absolute path before searching\n    cString absolutePathAndFilename;\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mModelDirectoryName + name + _L(\".mdl\")), &absolutePathAndFilename);\n    absolutePathAndFilename = nameIsFullPathAndFilename ? name : absolutePathAndFilename;\n\n    // If we already have one by this name, then return it\n    CPUTModel *pModel = FindModel(absolutePathAndFilename, true);\n    if(NULL!=pModel)\n    {\n        pModel->AddRef();\n        return pModel;\n    }\n\n    // Looks like no one calls GetModel().  Or, they never call it for missing models.\n#if TODO // delegate\n    // Model was not in the library, so create and load a new model\n    pModel = new CPUTModel();\n    pModel->LoadModelPayload(absolutePathAndFilename);\n    AddModel(name, pModel);\n\n    return CPUTModel::CreateMode( absolutePathAndFilename, aboslutePathAndFilename );\n#endif\n\n    return pModel;\n}\n\n//-----------------------------------------------------------------------------\nCPUTCamera *CPUTAssetLibrary::GetCamera(const cString &name)\n{\n    // TODO: Should we prefix camera names with a path anyway?  To keek them unique?\n    // If we already have one by this name, then return it\n    CPUTCamera *pCamera = FindCamera(name, true);\n    if(NULL!=pCamera)\n    {\n        pCamera->AddRef();\n        return pCamera;\n    }\n    return NULL;\n}\n\n//-----------------------------------------------------------------------------\nCPUTLight *CPUTAssetLibrary::GetLight(const cString &name)\n{\n    // If we already have one by this name, then return it\n    CPUTLight *pLight = FindLight(name, true);\n    if(NULL!=pLight)\n    {\n        pLight->AddRef();\n        return pLight;\n    }\n    return NULL;\n}\n\n//-----------------------------------------------------------------------------\nCPUTTexture *CPUTAssetLibrary::GetTexture(const cString &name, bool nameIsFullPathAndFilename, bool loadAsSRGB )\n{\n    cString finalName;\n    if( name.at(0) == '$' )\n    {\n        finalName = name;\n    } else\n    {\n        // Resolve name to absolute path\n        CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mTextureDirectoryName + name), &finalName);\n    }\n    // If we already have one by this name, then return it\n    CPUTTexture *pTexture = FindTexture(finalName, true);\n    if(NULL==pTexture)\n    {\n        return CPUTTexture::CreateTexture( name, finalName, loadAsSRGB);\n    }\n    pTexture->AddRef();\n    return pTexture;\n}\n\n//-----------------------------------------------------------------------------\nCPUTBuffer *CPUTAssetLibrary::GetBuffer(const cString &name )\n{\n    // If we already have one by this name, then return it\n    CPUTBuffer *pBuffer = FindBuffer(name, true);\n    ASSERT( pBuffer, _L(\"Can't find buffer \") + name );\n    pBuffer->AddRef();\n    return pBuffer;\n}\n\n//-----------------------------------------------------------------------------\nCPUTBuffer *CPUTAssetLibrary::GetConstantBuffer(const cString &name )\n{\n    // If we already have one by this name, then return it\n    CPUTBuffer *pBuffer = FindConstantBuffer(name, true);\n    ASSERT( pBuffer, _L(\"Can't find constant buffer \") + name );\n    pBuffer->AddRef();\n    return pBuffer;\n}\n\n//-----------------------------------------------------------------------------\nCPUTFont *CPUTAssetLibrary::GetFont(const cString &name )\n{\n    // Resolve name to absolute path\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    cString absolutePathAndFilename;\n    pServices->ResolveAbsolutePathAndFilename( (mFontDirectoryName + name), &absolutePathAndFilename);\n\n    // If we already have one by this name, then return it\n    CPUTFont *pFont = FindFont(absolutePathAndFilename, true);\n    if(NULL==pFont)\n    {\n        return CPUTFont::CreateFont( name, absolutePathAndFilename);\n    }\n    pFont->AddRef();\n    return pFont;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTAssetLibrary.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n// use this file except in compliance with the License.  You may obtain a copy\n// of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\n// License for the specific language governing permissions and limitations\n// under the License.\n////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTASSETLIBRARY_H__\n#define __CPUTASSETLIBRARY_H__\n\n#include \"CPUT.h\"\n#include \"CPUTOSServicesWin.h\" // TODO: why is this windows-specific?\n\n// Global Asset Library\n//\n// The purpose of this library is to keep a copy of all loaded assets and\n// provide a one-stop-loading system.  All assets that are loaded into the\n// system via the Getxxx() operators stays in the library.  Further Getxxx()\n// operations on an already loaded object will addref and return the previously\n// loaded object.\n//-----------------------------------------------------------------------------\n// node that holds a single library object\nstruct CPUTAssetListEntry\n{\n    UINT                hash;\n    cString             name;\n    void               *pData;\n    CPUTAssetListEntry *pNext;\n};\n#define SAFE_RELEASE_LIST(list) ReleaseList(list);(list)=NULL;\n\nclass CPUTAssetSet;\nclass CPUTNullNode;\nclass CPUTModel;\nclass CPUTMaterial;\nclass CPUTLight;\nclass CPUTCamera;\nclass CPUTTexture;\nclass CPUTBuffer;\nclass CPUTRenderStateBlock;\nclass CPUTFont;\n\nclass CPUTAssetLibrary\n{\nprotected:\n    static CPUTAssetLibrary *mpAssetLibrary;\n\n    // simple linked lists for now, but if we want to optimize or load blocks\n    // we can change these to dynamically re-sizing arrays and then just do\n    // memcopies into the structs.\n    // Note: No camera, light, or NullNode directory names - they don't have payload files (i.e., they are defined completely in the .set file)\n    cString  mAssetSetDirectoryName;\n    cString  mModelDirectoryName;\n    cString  mMaterialDirectoryName;\n    cString  mTextureDirectoryName;\n    cString  mShaderDirectoryName;\n    cString  mFontDirectoryName;\n\npublic: // TODO: temporary for debug.\n    // TODO: Make these lists static.  Share assets (e.g., texture) across all requests for this process.\n    static CPUTAssetListEntry  *mpAssetSetList;\n    static CPUTAssetListEntry  *mpNullNodeList;\n    static CPUTAssetListEntry  *mpModelList;\n    static CPUTAssetListEntry  *mpCameraList;\n    static CPUTAssetListEntry  *mpLightList;\n    static CPUTAssetListEntry  *mpMaterialList;\n    static CPUTAssetListEntry  *mpTextureList;\n    static CPUTAssetListEntry  *mpBufferList;\n    static CPUTAssetListEntry  *mpConstantBufferList;\n    static CPUTAssetListEntry  *mpRenderStateBlockList;\n    static CPUTAssetListEntry  *mpFontList;\n\n    static void RebindTexturesAndBuffers();\n    static void ReleaseTexturesAndBuffers();\n\npublic:\n    static CPUTAssetLibrary *GetAssetLibrary(){ return mpAssetLibrary; }\n    static void              DeleteAssetLibrary();\n\n    CPUTAssetLibrary() {}\n    virtual ~CPUTAssetLibrary() {}\n\n    // Add/get/delete items to specified library\n    void *FindAsset(const cString &name, CPUTAssetListEntry *pList, bool nameIsFullPathAndFilename=false);\n    virtual void ReleaseAllLibraryLists();\n\n    void SetMediaDirectoryName( const cString &directoryName)\n    {\n        mAssetSetDirectoryName = directoryName + _L(\"Asset\\\\\");\n        mModelDirectoryName    = directoryName + _L(\"Asset\\\\\");\n        mMaterialDirectoryName = directoryName + _L(\"Material\\\\\");\n        mTextureDirectoryName  = directoryName + _L(\"Texture\\\\\");\n        mShaderDirectoryName   = directoryName + _L(\"Shader\\\\\");\n        // mFontStateBlockDirectoryName   = directoryName + _L(\"Font\\\\\");\n    }\n    void SetAssetSetDirectoryName(        const cString &directoryName) { mAssetSetDirectoryName  = directoryName; }\n    void SetModelDirectoryName(           const cString &directoryName) { mModelDirectoryName     = directoryName; }\n    void SetMaterialDirectoryName(        const cString &directoryName) { mMaterialDirectoryName  = directoryName; }\n    void SetTextureDirectoryName(         const cString &directoryName) { mTextureDirectoryName   = directoryName; }\n    void SetShaderDirectoryName(          const cString &directoryName) { mShaderDirectoryName    = directoryName; }\n    void SetFontDirectoryName(            const cString &directoryName) { mFontDirectoryName      = directoryName; }\n    void SetAllAssetDirectoryNames(       const cString &directoryName) {\n            mAssetSetDirectoryName       = directoryName;\n            mModelDirectoryName          = directoryName;\n            mMaterialDirectoryName       = directoryName;\n            mTextureDirectoryName        = directoryName;\n            mShaderDirectoryName         = directoryName;\n            mFontDirectoryName           = directoryName;\n    };\n\n    cString &GetAssetSetDirectoryName() { return mAssetSetDirectoryName; }\n    cString &GetModelDirectory()        { return mModelDirectoryName; }\n    cString &GetMaterialDirectory()     { return mMaterialDirectoryName; }\n    cString &GetTextureDirectory()      { return mTextureDirectoryName; }\n    cString &GetShaderDirectory()       { return mShaderDirectoryName; }\n    cString &GetFontDirectory()         { return mFontDirectoryName; }\n\n    void AddAssetSet(        const cString &name, CPUTAssetSet         *pAssetSet)        { AddAsset( name, pAssetSet,         &mpAssetSetList ); }\n    void AddNullNode(        const cString &name, CPUTNullNode         *pNullNode)        { AddAsset( name, pNullNode,         &mpNullNodeList ); }\n    void AddModel(           const cString &name, CPUTModel            *pModel)           { AddAsset( name, pModel,            &mpModelList ); }\n    void AddMaterial(        const cString &name, CPUTMaterial         *pMaterial)        { AddAsset( name, pMaterial,         &mpMaterialList ); }\n    void AddLight(           const cString &name, CPUTLight            *pLight)           { AddAsset( name, pLight,            &mpLightList ); }\n    void AddCamera(          const cString &name, CPUTCamera           *pCamera)          { AddAsset( name, pCamera,           &mpCameraList ); }\n    void AddTexture(         const cString &name, CPUTTexture          *pTexture)         { AddAsset( name, pTexture,          &mpTextureList ); }\n    void AddBuffer(          const cString &name, CPUTBuffer           *pBuffer)          { AddAsset( name, pBuffer,           &mpBufferList ); }\n    void AddConstantBuffer(  const cString &name, CPUTBuffer           *pBuffer)          { AddAsset( name, pBuffer,           &mpConstantBufferList ); }\n    void AddRenderStateBlock(const cString &name, CPUTRenderStateBlock *pRenderStateBlock){ AddAsset( name, pRenderStateBlock, &mpRenderStateBlockList ); }\n    void AddFont(            const cString &name, CPUTFont             *pFont)            { AddAsset( name, pFont,             &mpFontList ); }\n\n    CPUTAssetSet *FindAssetSet(const cString &name, bool nameIsFullPathAndFilename=false)       { return (CPUTAssetSet*)FindAsset( name, mpAssetSetList, nameIsFullPathAndFilename ); }\n    CPUTNullNode *FindNullNode(const cString &name, bool nameIsFullPathAndFilename=false)       { return (CPUTNullNode*)FindAsset( name, mpNullNodeList, nameIsFullPathAndFilename ); }\n    CPUTModel    *FindModel(const cString &name, bool nameIsFullPathAndFilename=false)          { return (CPUTModel*)FindAsset(    name, mpModelList,    nameIsFullPathAndFilename ); }\n    CPUTMaterial *FindMaterial(const cString &name, bool nameIsFullPathAndFilename=false)       { return (CPUTMaterial*)FindAsset( name, mpMaterialList, nameIsFullPathAndFilename ); }\n    CPUTLight    *FindLight(const cString &name, bool nameIsFullPathAndFilename=false)          { return (CPUTLight*)FindAsset(    name, mpLightList,    nameIsFullPathAndFilename ); }\n    CPUTCamera   *FindCamera(const cString &name, bool nameIsFullPathAndFilename=false)         { return (CPUTCamera*)FindAsset(   name, mpCameraList,   nameIsFullPathAndFilename ); }\n    CPUTTexture  *FindTexture(const cString &name, bool nameIsFullPathAndFilename=false)        { return (CPUTTexture*)FindAsset(  name, mpTextureList,  nameIsFullPathAndFilename ); }\n    CPUTBuffer   *FindBuffer(const cString &name, bool nameIsFullPathAndFilename=false)         { return (CPUTBuffer*)FindAsset(   name, mpBufferList,   nameIsFullPathAndFilename ); }\n    CPUTBuffer   *FindConstantBuffer(const cString &name, bool nameIsFullPathAndFilename=false) { return (CPUTBuffer*)FindAsset(   name, mpConstantBufferList, nameIsFullPathAndFilename ); }\n    CPUTRenderStateBlock *FindRenderStateBlock(const cString &name, bool nameIsFullPathAndFilename=false ) { return (CPUTRenderStateBlock*)FindAsset( name, mpRenderStateBlockList, nameIsFullPathAndFilename ); }\n    CPUTFont     *FindFont(const cString &name, bool nameIsFullPathAndFilename=false)           { return (CPUTFont*)FindAsset(     name, mpFontList,     nameIsFullPathAndFilename ); }\n\n    // If the asset exists, these 'Get' methods will addref and return it.  Otherwise,\n    // they will create it and return it.\n    CPUTAssetSet         *GetAssetSet(        const cString &name, bool nameIsFullPathAndFilename=false );\n    CPUTTexture          *GetTexture(         const cString &name, bool nameIsFullPathAndFilename=false, bool loadAsSRGB=true );\n    CPUTMaterial         *GetMaterial(        const cString &name, bool nameIsFullPathAndFilename=false, const cString &modelSuffix=_L(\"\"), const cString &meshSuffix=_L(\"\") );\n    CPUTModel            *GetModel(           const cString &name, bool nameIsFullPathAndFilename=false  );\n    CPUTRenderStateBlock *GetRenderStateBlock(const cString &name, bool nameIsFullPathAndFilename=false);\n    CPUTBuffer           *GetBuffer(          const cString &name );\n    CPUTBuffer           *GetConstantBuffer(  const cString &name );\n    CPUTCamera           *GetCamera(          const cString &name );\n    CPUTLight            *GetLight(           const cString &name );\n    CPUTFont             *GetFont(            const cString &name );\n\nprotected:\n    // helper functions\n    void ReleaseList(CPUTAssetListEntry *pLibraryRoot);\n    void AddAsset( const cString &name, void *pAsset, CPUTAssetListEntry **pHead );\n    UINT CPUTComputeHash( const cString &string )\n    {\n        size_t length = string.length();\n        UINT hash = 0;\n        for( size_t ii=0; ii<length; ii++ )\n        {\n            hash += tolower(string[ii]);\n        }\n        return hash;\n    }\n};\n\n#endif //#ifndef __CPUTASSETLIBRARY_H__\n\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTAssetLibraryDX11.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n// use this file except in compliance with the License.  You may obtain a copy\n// of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\n// License for the specific language governing permissions and limitations\n// under the License.\n////////////////////////////////////////////////////////////////////////////////\n#include \"D3dx9tex.h\"  // super-annoying - must be first or you get new() operator overloading errors during compile b/c of D3DXGetImageInfoFromFile() function\n\n#include \"CPUTAssetLibraryDX11.h\"\n\n// define the objects we'll need\n#include \"CPUTModelDX11.h\"\n#include \"CPUTMaterialDX11.h\"\n#include \"CPUTTextureDX11.h\"\n#include \"CPUTRenderStateBlockDX11.h\"\n#include \"CPUTLight.h\"\n#include \"CPUTCamera.h\"\n#include \"CPUTVertexShaderDX11.h\"\n#include \"CPUTPixelShaderDX11.h\"\n#include \"CPUTGeometryShaderDX11.h\"\n#include \"CPUTComputeShaderDX11.h\"\n#include \"CPUTHullShaderDX11.h\"\n#include \"CPUTDomainShaderDX11.h\"\n\n// MPF: opengl es - yipe - can't do both at the same time - need to have it bind dynamically/via compile-time \nCPUTAssetLibrary   *CPUTAssetLibrary::mpAssetLibrary = new CPUTAssetLibraryDX11();\nCPUTAssetListEntry *CPUTAssetLibraryDX11::mpPixelShaderList    = NULL;\nCPUTAssetListEntry *CPUTAssetLibraryDX11::mpComputeShaderList  = NULL;\nCPUTAssetListEntry *CPUTAssetLibraryDX11::mpVertexShaderList   = NULL;\nCPUTAssetListEntry *CPUTAssetLibraryDX11::mpGeometryShaderList = NULL;\nCPUTAssetListEntry *CPUTAssetLibraryDX11::mpHullShaderList = NULL;\nCPUTAssetListEntry *CPUTAssetLibraryDX11::mpDomainShaderList = NULL;\n\n// TODO: Change OS Services to a flat list of CPUT* functions.  Avoid calls all over the place like:\n// CPUTOSServices::GetOSServices();\n\n// Deletes and properly releases all asset library lists that contain\n// unwrapped IUnknown DirectX objects.\n//-----------------------------------------------------------------------------\nvoid CPUTAssetLibraryDX11::ReleaseAllLibraryLists()\n{\n    // TODO: we really need to wrap the DX assets so we don't need to distinguish their IUnknown type.\n    SAFE_RELEASE_LIST(mpPixelShaderList);\n    SAFE_RELEASE_LIST(mpComputeShaderList);\n    SAFE_RELEASE_LIST(mpVertexShaderList);\n    SAFE_RELEASE_LIST(mpGeometryShaderList);\n    SAFE_RELEASE_LIST(mpHullShaderList);\n    SAFE_RELEASE_LIST(mpDomainShaderList);\n\n    // Call base class implementation to clean up the non-DX object lists\n    return CPUTAssetLibrary::ReleaseAllLibraryLists();\n}\n\n// Erase the specified list, Release()-ing underlying objects\n//-----------------------------------------------------------------------------\nvoid CPUTAssetLibraryDX11::ReleaseIunknownList( CPUTAssetListEntry *pList )\n{\n    CPUTAssetListEntry *pNode = pList;\n    CPUTAssetListEntry *pOldNode = NULL;\n\n    while( NULL!=pNode )\n    {\n        // release the object using the DirectX IUnknown interface\n        ((IUnknown*)(pNode->pData))->Release();\n        pOldNode = pNode;\n        pNode = pNode->pNext;\n        delete pOldNode;\n    }\n    HEAPCHECK;\n}\n\n// Retrieve specified pixel shader\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::GetPixelShader(\n    const cString        &name,\n    ID3D11Device         *pD3dDevice,\n    const cString        &shaderMain,\n    const cString        &shaderProfile,\n    CPUTPixelShaderDX11 **ppPixelShader,\n    bool                  nameIsFullPathAndFilename\n)\n{\n    CPUTResult result = CPUT_SUCCESS;\n    cString finalName;\n    if( name.at(0) == '$' )\n    {\n        finalName = name;\n    } else\n    {\n        // Resolve name to absolute path\n        CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName);\n    }\n\n    // see if the shader is already in the library\n    void *pShader = FindPixelShader(finalName + shaderMain + shaderProfile, true);\n    if(NULL!=pShader)\n    {\n        *ppPixelShader = (CPUTPixelShaderDX11*) pShader;\n        (*ppPixelShader)->AddRef();\n        return result;\n    }\n    *ppPixelShader = CPUTPixelShaderDX11::CreatePixelShader( finalName, pD3dDevice, shaderMain, shaderProfile );\n\n    return result;\n}\n\n// Retrieve specified pixel shader\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::GetComputeShader(\n    const cString          &name,\n    ID3D11Device           *pD3dDevice,\n    const cString          &shaderMain,\n    const cString          &shaderProfile,\n    CPUTComputeShaderDX11 **ppComputeShader,\n    bool                    nameIsFullPathAndFilename\n)\n{\n    CPUTResult result = CPUT_SUCCESS;\n    cString finalName;\n    if( name.at(0) == '$' )\n    {\n        finalName = name;\n    } else\n    {\n        // Resolve name to absolute path\n        CPUTOSServices* pServices = CPUTOSServices::GetOSServices();\n        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName);\n    }\n\n    // see if the shader is already in the library\n    void *pShader = FindComputeShader(finalName + shaderMain + shaderProfile, true);\n    if(NULL!=pShader)\n    {\n        *ppComputeShader = (CPUTComputeShaderDX11*) pShader;\n        (*ppComputeShader)->AddRef();\n        return result;\n    }\n    *ppComputeShader = CPUTComputeShaderDX11::CreateComputeShader( finalName, pD3dDevice, shaderMain, shaderProfile );\n\n    return result;\n}\n\n// Retrieve specified vertex shader\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::GetVertexShader(\n    const cString         &name,\n    ID3D11Device          *pD3dDevice,\n    const cString          &shaderMain,\n    const cString          &shaderProfile,\n    CPUTVertexShaderDX11 **ppVertexShader,\n    bool                   nameIsFullPathAndFilename\n)\n{\n    CPUTResult result = CPUT_SUCCESS;\n    cString finalName;\n    if( name.at(0) == '$' )\n    {\n        finalName = name;\n    } else\n    {\n        // Resolve name to absolute path\n        CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName);\n    }\n\n    // see if the shader is already in the library\n    void *pShader = FindVertexShader(finalName + shaderMain + shaderProfile, true);\n    if(NULL!=pShader)\n    {\n        *ppVertexShader = (CPUTVertexShaderDX11*) pShader;\n        (*ppVertexShader)->AddRef();\n        return result;\n    }\n    *ppVertexShader = CPUTVertexShaderDX11::CreateVertexShader( finalName, pD3dDevice, shaderMain, shaderProfile );\n\n    return result;\n}\n\n// Retrieve specified geometry shader\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::GetGeometryShader(\n    const cString           &name,\n    ID3D11Device            *pD3dDevice,\n    const cString           &shaderMain,\n    const cString           &shaderProfile,\n    CPUTGeometryShaderDX11 **ppGeometryShader,\n    bool                     nameIsFullPathAndFilename\n    )\n{\n    CPUTResult result = CPUT_SUCCESS;\n    cString finalName;\n    if( name.at(0) == '$' )\n    {\n        finalName = name;\n    } else\n    {\n        // Resolve name to absolute path\n        CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName);\n    }\n\n    // see if the shader is already in the library\n    void *pShader = FindGeometryShader(finalName + shaderMain + shaderProfile, true);\n    if(NULL!=pShader)\n    {\n        *ppGeometryShader = (CPUTGeometryShaderDX11*) pShader;\n        (*ppGeometryShader)->AddRef();\n        return result;\n    }\n    *ppGeometryShader = CPUTGeometryShaderDX11::CreateGeometryShader( finalName, pD3dDevice, shaderMain, shaderProfile );\n\n    return result;\n}\n\n// Retrieve specified hull shader\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::GetHullShader(\n    const cString           &name,\n    ID3D11Device            *pD3dDevice,\n    const cString           &shaderMain,\n    const cString           &shaderProfile,\n    CPUTHullShaderDX11 **ppHullShader,\n    bool                     nameIsFullPathAndFilename\n    )\n{\n    CPUTResult result = CPUT_SUCCESS;\n    cString finalName;\n    if( name.at(0) == '$' )\n    {\n        finalName = name;\n    } else\n    {\n        // Resolve name to absolute path\n        CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName);\n    }\n\n    // see if the shader is already in the library\n    void *pShader = FindHullShader(finalName + shaderMain + shaderProfile, true);\n    if(NULL!=pShader)\n    {\n        *ppHullShader = (CPUTHullShaderDX11*) pShader;\n        (*ppHullShader)->AddRef();\n        return result;\n    }\n    *ppHullShader = CPUTHullShaderDX11::CreateHullShader( finalName, pD3dDevice, shaderMain, shaderProfile );\n\n    return result;\n\n}\n\n// Retrieve specified domain shader\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::GetDomainShader(\n    const cString           &name,\n    ID3D11Device            *pD3dDevice,\n    const cString           &shaderMain,\n    const cString           &shaderProfile,\n    CPUTDomainShaderDX11 **ppDomainShader,\n    bool                     nameIsFullPathAndFilename\n    )\n{\n    CPUTResult result = CPUT_SUCCESS;\n    cString finalName;\n    if( name.at(0) == '$' )\n    {\n        finalName = name;\n    } else\n    {\n        // Resolve name to absolute path\n        CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n        pServices->ResolveAbsolutePathAndFilename( nameIsFullPathAndFilename? name : (mShaderDirectoryName + name), &finalName);\n    }\n\n    // see if the shader is already in the library\n    void *pShader = FindDomainShader(finalName + shaderMain + shaderProfile, true);\n    if(NULL!=pShader)\n    {\n        *ppDomainShader = (CPUTDomainShaderDX11*) pShader;\n        (*ppDomainShader)->AddRef();\n        return result;\n    }\n    *ppDomainShader = CPUTDomainShaderDX11::CreateDomainShader( finalName, pD3dDevice, shaderMain, shaderProfile );\n\n    return result;\n}\n\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::CreatePixelShaderFromMemory(\n    const cString        &name,\n    ID3D11Device         *pD3dDevice,\n    const cString        &shaderMain,\n    const cString        &shaderProfile,\n    CPUTPixelShaderDX11 **ppShader,\n    char                 *pShaderSource\n)\n{\n    CPUTResult result = CPUT_SUCCESS;\n    void *pShader = FindPixelShader(name + shaderMain + shaderProfile, true);\n    ASSERT( NULL == pShader, _L(\"Shader already exists.\") );\n    *ppShader = CPUTPixelShaderDX11::CreatePixelShaderFromMemory( name, pD3dDevice, shaderMain, shaderProfile, pShaderSource);\n    return result;\n}\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::CreateVertexShaderFromMemory(\n    const cString        &name,\n    ID3D11Device         *pD3dDevice,\n    const cString        &shaderMain,\n    const cString        &shaderProfile,\n    CPUTVertexShaderDX11 **ppShader,\n    char                 *pShaderSource\n)\n{\n    CPUTResult result = CPUT_SUCCESS;\n    void *pShader = FindPixelShader(name + shaderMain + shaderProfile, true);\n    ASSERT( NULL == pShader, _L(\"Shader already exists.\") );\n    *ppShader = CPUTVertexShaderDX11::CreateVertexShaderFromMemory( name, pD3dDevice, shaderMain, shaderProfile, pShaderSource);\n    return result;\n}\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::CreateComputeShaderFromMemory(\n    const cString          &name,\n    ID3D11Device           *pD3dDevice,\n    const cString          &shaderMain,\n    const cString          &shaderProfile,\n    CPUTComputeShaderDX11 **ppShader,\n    char                   *pShaderSource\n)\n{\n    CPUTResult result = CPUT_SUCCESS;\n    void *pShader = FindPixelShader(name + shaderMain + shaderProfile, true);\n    ASSERT( NULL == pShader, _L(\"Shader already exists.\") );\n    *ppShader = CPUTComputeShaderDX11::CreateComputeShaderFromMemory( name, pD3dDevice, shaderMain, shaderProfile, pShaderSource);\n    return result;\n}\n\n// Use DX11 compile from file method to do all the heavy lifting\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::CompileShaderFromFile(\n    const cString  &fileName,\n    const cString  &shaderMain,\n    const cString  &shaderProfile,\n    ID3DBlob      **ppBlob\n)\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    char pShaderMainAsChar[128];\n    char pShaderProfileAsChar[128];\n    ASSERT( shaderMain.length()     < 128, _L(\"Shader main name '\")    + shaderMain    + _L(\"' longer than 128 chars.\") );\n    ASSERT( shaderProfile.length()  < 128, _L(\"Shader profile name '\") + shaderProfile + _L(\"' longer than 128 chars.\") );\n    size_t count;\n    wcstombs_s( &count, pShaderMainAsChar,    shaderMain.c_str(),    128 );\n    wcstombs_s( &count, pShaderProfileAsChar, shaderProfile.c_str(), 128 );\n\n    // use DirectX to compile the shader file\n    ID3DBlob *pErrorBlob = NULL;\n    D3D10_SHADER_MACRO pShaderMacros[2] = { \"_CPUT\", \"1\", NULL, NULL };\n    HRESULT hr = D3DX11CompileFromFile(\n        fileName.c_str(),     // fileName\n        pShaderMacros,        // macro define's\n        NULL,                 // includes\n        pShaderMainAsChar,    // main function name\n        pShaderProfileAsChar, // shader profile/feature level\n        0,                    // flags 1\n        0,                    // flags 2\n        NULL,                 // threaded load? (no for right now)\n        ppBlob,               // blob data with compiled code\n        &pErrorBlob,          // any compile errors stored here\n        NULL\n    );\n    ASSERT( SUCCEEDED(hr), _L(\"Error compiling shader '\") + fileName + _L(\"'.\\n\") + (pErrorBlob ? s2ws((char*)pErrorBlob->GetBufferPointer()) : _L(\"no error message\") ) );\n    if(pErrorBlob)\n    {\n        pErrorBlob->Release();\n    }\n    return result;\n}\n\n// Use DX11 compile from file method to do all the heavy lifting\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetLibraryDX11::CompileShaderFromMemory(\n    const char     *pShaderSource,\n    const cString  &shaderMain,\n    const cString  &shaderProfile,\n    ID3DBlob      **ppBlob\n)\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    char pShaderMainAsChar[128];\n    char pShaderProfileAsChar[128];\n    ASSERT( shaderMain.length()     < 128, _L(\"Shader main name '\")    + shaderMain    + _L(\"' longer than 128 chars.\") );\n    ASSERT( shaderProfile.length()  < 128, _L(\"Shader profile name '\") + shaderProfile + _L(\"' longer than 128 chars.\") );\n    size_t count;\n    wcstombs_s( &count, pShaderMainAsChar,    shaderMain.c_str(),    128 );\n    wcstombs_s( &count, pShaderProfileAsChar, shaderProfile.c_str(), 128 );\n\n    // use DirectX to compile the shader file\n    ID3DBlob *pErrorBlob = NULL;\n    D3D10_SHADER_MACRO pShaderMacros[2] = { \"_CPUT\", \"1\", NULL, NULL }; // TODO: Support passed-in, and defined in .mtl file.  Perhaps under [Shader Defines], etc\n    char *pShaderMainAsChars = ws2s(shaderMain.c_str());\n    HRESULT hr = D3DX11CompileFromMemory(\n        pShaderSource,     // shader as a string\n        strlen( pShaderSource ), //\n        pShaderMainAsChars, // Use entrypoint as file name\n        pShaderMacros,        // macro define's\n        NULL,                 // includes\n        pShaderMainAsChar,    // main function name\n        pShaderProfileAsChar, // shader profile/feature level\n        0,                    // flags 1\n        0,                    // flags 2\n        NULL,                 // threaded load? (no for right now)\n        ppBlob,               // blob data with compiled code\n        &pErrorBlob,          // any compile errors stored here\n        NULL\n    );\n    ASSERT( SUCCEEDED(hr), _L(\"Error compiling shader '\") + shaderMain + _L(\"'.\\n\") + (pErrorBlob ? s2ws((char*)pErrorBlob->GetBufferPointer()) : _L(\"no error message\") ) );\n    if(pErrorBlob)\n    {\n        pErrorBlob->Release();\n    }\n    delete pShaderMainAsChars;\n    return result;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTAssetLibraryDX11.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n// use this file except in compliance with the License.  You may obtain a copy\n// of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\n// License for the specific language governing permissions and limitations\n// under the License.\n////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTASSETLIBRARYDX11_H__\n#define __CPUTASSETLIBRARYDX11_H__\n\n#include \"CPUTAssetLibrary.h\"\n#include \"CPUTConfigBlock.h\"\n\n#include <d3d11.h>\n#include <D3DX11tex.h> // for D3DX11_IMAGE_LOAD_INFO structs\n\nclass CPUTAssetSet;\nclass CPUTMaterial;\nclass CPUTModel;\nclass CPUTNullNode;\nclass CPUTCamera;\nclass CPUTRenderStateBlock;\nclass CPUTLight;\nclass CPUTTexture;\nclass CPUTVertexShaderDX11;\nclass CPUTPixelShaderDX11;\nclass CPUTComputeShaderDX11;\nclass CPUTGeometryShaderDX11;\nclass CPUTHullShaderDX11;\nclass CPUTDomainShaderDX11;\n\n//-----------------------------------------------------------------------------\nstruct CPUTSRGBLoadFlags\n{\n    bool bInterpretInputasSRGB;\n    bool bWritetoSRGBOutput;\n};\n\n//-----------------------------------------------------------------------------\nclass CPUTAssetLibraryDX11:public CPUTAssetLibrary\n{\nprotected:\n    static CPUTAssetListEntry  *mpPixelShaderList;\n    static CPUTAssetListEntry  *mpComputeShaderList;\n    static CPUTAssetListEntry  *mpVertexShaderList;\n    static CPUTAssetListEntry  *mpGeometryShaderList;\n    static CPUTAssetListEntry  *mpHullShaderList;\n    static CPUTAssetListEntry  *mpDomainShaderList;\n\npublic:\n    CPUTAssetLibraryDX11(){}\n    virtual ~CPUTAssetLibraryDX11()\n    {\n        ReleaseAllLibraryLists();\n    }\n\n    virtual void ReleaseAllLibraryLists();\n    void ReleaseIunknownList( CPUTAssetListEntry *pList );\n\n    void AddPixelShader(    const cString &name, CPUTPixelShaderDX11    *pShader) { AddAsset( name, pShader, &mpPixelShaderList ); }\n    void AddComputeShader(  const cString &name, CPUTComputeShaderDX11  *pShader) { AddAsset( name, pShader, &mpComputeShaderList ); }\n    void AddVertexShader(   const cString &name, CPUTVertexShaderDX11   *pShader) { AddAsset( name, pShader, &mpVertexShaderList ); }\n    void AddGeometryShader( const cString &name, CPUTGeometryShaderDX11 *pShader) { AddAsset( name, pShader, &mpGeometryShaderList ); }\n    void AddHullShader(     const cString &name, CPUTHullShaderDX11     *pShader) { AddAsset( name, pShader, &mpHullShaderList ); }\n    void AddDomainShader(   const cString &name, CPUTDomainShaderDX11   *pShader) { AddAsset( name, pShader, &mpDomainShaderList ); }\n    \n    CPUTPixelShaderDX11    *FindPixelShader(    const cString &name, bool nameIsFullPathAndFilename=false ) { return    (CPUTPixelShaderDX11*)FindAsset( name, mpPixelShaderList,    nameIsFullPathAndFilename ); }\n    CPUTComputeShaderDX11  *FindComputeShader(  const cString &name, bool nameIsFullPathAndFilename=false ) { return  (CPUTComputeShaderDX11*)FindAsset( name, mpComputeShaderList,  nameIsFullPathAndFilename ); }\n    CPUTVertexShaderDX11   *FindVertexShader(   const cString &name, bool nameIsFullPathAndFilename=false ) { return   (CPUTVertexShaderDX11*)FindAsset( name, mpVertexShaderList,   nameIsFullPathAndFilename ); }\n    CPUTGeometryShaderDX11 *FindGeometryShader( const cString &name, bool nameIsFullPathAndFilename=false ) { return (CPUTGeometryShaderDX11*)FindAsset( name, mpGeometryShaderList, nameIsFullPathAndFilename ); }\n    CPUTHullShaderDX11     *FindHullShader(     const cString &name, bool nameIsFullPathAndFilename=false ) { return     (CPUTHullShaderDX11*)FindAsset( name, mpHullShaderList,     nameIsFullPathAndFilename ); }\n    CPUTDomainShaderDX11   *FindDomainShader(   const cString &name, bool nameIsFullPathAndFilename=false ) { return   (CPUTDomainShaderDX11*)FindAsset( name, mpDomainShaderList,   nameIsFullPathAndFilename ); }\n\n    // shaders - vertex, pixel\n    CPUTResult GetPixelShader(     const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTPixelShaderDX11    **ppShader, bool nameIsFullPathAndFilename=false);\n    CPUTResult GetComputeShader(   const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTComputeShaderDX11  **ppShader, bool nameIsFullPathAndFilename=false);\n    CPUTResult GetVertexShader(    const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTVertexShaderDX11   **ppShader, bool nameIsFullPathAndFilename=false);\n    CPUTResult GetGeometryShader(  const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTGeometryShaderDX11 **ppShader, bool nameIsFullPathAndFilename=false);\n    CPUTResult GetHullShader(      const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTHullShaderDX11     **ppShader, bool nameIsFullPathAndFilename=false);\n    CPUTResult GetDomainShader(    const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTDomainShaderDX11   **ppShader, bool nameIsFullPathAndFilename=false);\n \n    // shaders - vertex, pixel\n    CPUTResult CreatePixelShaderFromMemory(     const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTPixelShaderDX11    **ppShader, char *pShaderSource );\n    CPUTResult CreateComputeShaderFromMemory(   const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTComputeShaderDX11  **ppShader, char *pShaderSource );\n    CPUTResult CreateVertexShaderFromMemory(    const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTVertexShaderDX11   **ppShader, char *pShaderSource );\n    CPUTResult CreateGeometryShaderFromMemory(  const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTGeometryShaderDX11 **ppShader, char *pShaderSource );\n    CPUTResult CreateHullShaderFromMemory(      const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTHullShaderDX11     **ppShader, char *pShaderSource );\n    CPUTResult CreateDomainShaderFromMemory(    const cString &name, ID3D11Device *pD3dDevice, const cString &shaderMain, const cString &shaderProfile, CPUTDomainShaderDX11   **ppShader, char *pShaderSource );\n \n    CPUTResult CompileShaderFromFile(  const cString &fileName,   const cString &shaderMain, const cString &shaderProfile, ID3DBlob **ppBlob);\n    CPUTResult CompileShaderFromMemory(const char *pShaderSource, const cString &shaderMain, const cString &shaderProfile, ID3DBlob **ppBlob);\n};\n\n#endif // #ifndef __CPUTASSETLIBRARYDX11_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTAssetSet.cpp",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n// use this file except in compliance with the License.  You may obtain a copy\n// of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\n// License for the specific language governing permissions and limitations\n// under the License.\n////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTAssetSet.h\"\n#ifdef CPUT_FOR_DX11\n    #include \"CPUTAssetLibraryDX11.h\"\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n\n\n//-----------------------------------------------------------------------------\nCPUTAssetSet::CPUTAssetSet() :\n    mppAssetList(NULL),\n    mAssetCount(0),\n    mpRootNode(NULL),\n    mpFirstCamera(NULL),\n    mCameraCount(0)\n{\n}\n\n//-----------------------------------------------------------------------------\nCPUTAssetSet::~CPUTAssetSet()\n{\n    SAFE_RELEASE(mpFirstCamera);\n\n    // Deleteing the asset set implies recursively releasing all the assets in the hierarchy\n    if(mpRootNode && !mpRootNode->ReleaseRecursive() )\n    {\n        mpRootNode = NULL;\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetSet::RenderRecursive(CPUTRenderParameters &renderParams )\n{\n    if(mpRootNode)\n    {\n        mpRootNode->RenderRecursive(renderParams);\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetSet::RenderShadowRecursive(CPUTRenderParameters &renderParams )\n{\n    if(mpRootNode)\n    {\n        mpRootNode->RenderShadowRecursive(renderParams);\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTAssetSet::GetBoundingBox(float3 *pCenter, float3 *pHalf)\n{\n    *pCenter = *pHalf = float3(0.0f);\n    if(mpRootNode)\n    {\n        mpRootNode->GetBoundingBoxRecursive(pCenter, pHalf);\n    }\n}\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetSet::GetAssetByIndex(const UINT index, CPUTRenderNode **ppRenderNode)\n{\n    ASSERT( NULL != ppRenderNode, _L(\"Invalid NULL parameter\") );\n    *ppRenderNode = mppAssetList[index];\n    mppAssetList[index]->AddRef();\n    return CPUT_SUCCESS;\n}\n\n// Note: We create an object of derived type here.  What do we want to do when we also support OGL?  Have DX and OGL specific Create functions?\n#include \"CPUTAssetSetDX11.h\"\n//-----------------------------------------------------------------------------\nCPUTAssetSet *CPUTAssetSet::CreateAssetSet( const cString &name, const cString &absolutePathAndFilename )\n{\n    // TODO: accept DX11/OGL param to control which platform we generate.\n    // TODO: be sure to support the case where we want to support only one of them\n#ifdef CPUT_FOR_DX11\n    return CPUTAssetSetDX11::CreateAssetSet( name, absolutePathAndFilename );\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n    \n}\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTAssetSet.h",
    "content": "////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n// use this file except in compliance with the License.  You may obtain a copy\n// of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the\n// License for the specific language governing permissions and limitations\n// under the License.\n////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTASSETSET_H__\n#define __CPUTASSETSET_H__\n\n#include \"CPUTRefCount.h\"\n#include \"CPUTNullNode.h\"\n#include \"CPUTCamera.h\"\n\nclass CPUTRenderNode;\nclass CPUTNullNode;\nclass CPUTRenderParameters;\n\n// initial size and growth defines\nclass CPUTAssetSet : public CPUTRefCount\n{\nprotected:\n    CPUTRenderNode **mppAssetList;\n    UINT             mAssetCount;\n    CPUTNullNode    *mpRootNode;\n    CPUTCamera      *mpFirstCamera;\n    UINT             mCameraCount;\n\n    ~CPUTAssetSet(); // Destructor is not public.  Must release instead of delete.\n\npublic:\n    static CPUTAssetSet *CreateAssetSet( const cString &name, const cString &absolutePathAndFilename );\n\n    CPUTAssetSet::CPUTAssetSet();\n\n    UINT               GetAssetCount() { return mAssetCount; }\n    UINT               GetCameraCount() { return mCameraCount; }\n    CPUTResult         GetAssetByIndex(const UINT index, CPUTRenderNode **ppRenderNode);\n    CPUTRenderNode    *GetRoot() { if(mpRootNode){mpRootNode->AddRef();} return mpRootNode; }\n    void               SetRoot( CPUTNullNode *pRoot) { SAFE_RELEASE(mpRootNode); mpRootNode = pRoot; }\n    CPUTCamera        *GetFirstCamera() { if(mpFirstCamera){mpFirstCamera->AddRef();} return mpFirstCamera; } // TODO: Consider supporting indexed access to each asset type\n    void               RenderRecursive(CPUTRenderParameters &renderParams);\n    void               RenderShadowRecursive(CPUTRenderParameters &renderParams);\n\n    void               UpdateRecursive( float deltaSeconds );\n    virtual CPUTResult LoadAssetSet(cString name) = 0;\n    void               GetBoundingBox(float3 *pCenter, float3 *pHalf);\n};\n\n#endif // #ifndef __CPUTASSETSET_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTAssetSetDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTAssetSetDX11.h\"\n\n#include \"CPUTModelDX11.h\"\n#include \"CPUTAssetLibraryDX11.h\"\n#include \"CPUTCamera.h\"\n#include \"CPUTLight.h\"\n\n//-----------------------------------------------------------------------------\nCPUTAssetSetDX11::~CPUTAssetSetDX11()\n{\n    // Release all the elements in the asset list.  Note that we don't\n    // recursively delete the hierarchy here.\n    // We release the entries here because this class is where we add them.\n    // TODO: Howevere, all derivations will have this, so perhaps it should go in the base.\n    for( UINT ii=0; ii<mAssetCount; ii++ )\n    {\n        SAFE_RELEASE( mppAssetList[ii] );\n    }\n    SAFE_DELETE_ARRAY(mppAssetList);\n}\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTAssetSetDX11::LoadAssetSet(cString name)\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    // if not found, load the set file\n    CPUTConfigFile ConfigFile;\n    result = ConfigFile.LoadFile(name);\n    if( !CPUTSUCCESS(result) )\n    {\n        return result;\n    }\n    // ASSERT( CPUTSUCCESS(result), _L(\"Failed loading set file '\") + name + _L(\"'.\") );\n\n    mAssetCount = ConfigFile.BlockCount() + 1; // Add one for the implied root node\n    mppAssetList = new CPUTRenderNode*[mAssetCount];\n    mppAssetList[0] = mpRootNode;\n    mpRootNode->AddRef();\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n\n    for(UINT ii=0; ii<mAssetCount-1; ii++) // Note: -1 because we added one for the root node (we don't load it)\n    {\n        CPUTConfigBlock *pBlock = ConfigFile.GetBlock(ii);\n\t\tASSERT(pBlock != NULL, _L(\"Cannot find block\"));\n        cString nodeType = pBlock->GetValueByName(_L(\"type\"))->ValueAsString();\n        CPUTRenderNode *pParentNode = NULL;\n\n        // TODO: use Get*() instead of Load*() ?\n\n        cString name = pBlock->GetValueByName(_L(\"name\"))->ValueAsString();\n\n        int parentIndex;\n        CPUTRenderNode *pNode = NULL;\n        if(0==nodeType.compare(_L(\"null\")))\n        {\n            pNode  = pNode = new CPUTNullNode();\n            result = ((CPUTNullNode*)pNode)->LoadNullNode(pBlock, &parentIndex);\n            pParentNode = mppAssetList[parentIndex+1];\n            cString &parentPrefix = pParentNode->GetPrefix();\n            pNode->SetPrefix( parentPrefix + _L(\".\") + name );\n            pAssetLibrary->AddNullNode(parentPrefix + name, (CPUTNullNode*)pNode);\n            // Add this null's name to our prefix\n            // Append this null's name to our parent's prefix\n            pNode->SetParent( pParentNode );\n            pParentNode->AddChild( pNode );\n        }\n        else if(0==nodeType.compare(_L(\"model\")))\n        {\n            CPUTConfigEntry *pValue = pBlock->GetValueByName( _L(\"instance\") );\n            CPUTModelDX11 *pModel = new CPUTModelDX11();\n            if( pValue == &CPUTConfigEntry::sNullConfigValue )\n            {\n                // Not found.  So, not an instance.\n                pModel->LoadModel(pBlock, &parentIndex, NULL);\n            }\n            else\n            {\n                int instance = pValue->ValueAsInt();\n                pModel->LoadModel(pBlock, &parentIndex, (CPUTModel*)mppAssetList[instance+1]);\n            }\n            pParentNode = mppAssetList[parentIndex+1];\n            pModel->SetParent( pParentNode );\n            pParentNode->AddChild( pModel );\n            cString &parentPrefix = pParentNode->GetPrefix();\n            pModel->SetPrefix( parentPrefix );\n            pAssetLibrary->AddModel(parentPrefix + name, pModel);\n\n            pModel->UpdateBoundsWorldSpace();\n\n#ifdef SUPPORT_DRAWING_BOUNDING_BOXES\n            // Create a mesh for rendering the bounding box\n            // TODO: There is definitely a better way to do this.  But, want to see the bounding boxes!\n            pModel->CreateBoundingBoxMesh();\n#endif\n            pNode = pModel;\n        }\n        else if(0==nodeType.compare(_L(\"light\")))\n        {\n            pNode = new CPUTLight();\n            ((CPUTLight*)pNode)->LoadLight(pBlock, &parentIndex);\n            pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start\n            pNode->SetParent( pParentNode );\n            pParentNode->AddChild( pNode );\n            cString &parentPrefix = pParentNode->GetPrefix();\n            pNode->SetPrefix( parentPrefix );\n            pAssetLibrary->AddLight(parentPrefix + name, (CPUTLight*)pNode);\n        }\n        else if(0==nodeType.compare(_L(\"camera\")))\n        {\n            pNode = new CPUTCamera();\n            ((CPUTCamera*)pNode)->LoadCamera(pBlock, &parentIndex);\n            pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start\n            pNode->SetParent( pParentNode );\n            pParentNode->AddChild( pNode );\n            cString &parentPrefix = pParentNode->GetPrefix();\n            pNode->SetPrefix( parentPrefix );\n            pAssetLibrary->AddCamera(parentPrefix + name, (CPUTCamera*)pNode);\n            if( !mpFirstCamera ) { mpFirstCamera = (CPUTCamera*)pNode; mpFirstCamera->AddRef();}\n            ++mCameraCount;\n        }\n        else\n        {\n            ASSERT(0,_L(\"Unsupported node type '\") + nodeType + _L(\"'.\"));\n        }\n\n        // Add the node to our asset list (i.e., the linear list, not the hierarchical)\n        mppAssetList[ii+1] = pNode;\n        // Don't AddRef.Creating it set the refcount to 1.  We add it to the list, and then we're done with it.\n        // Net effect is 0 (+1 to add to list, and -1 because we're done with it)\n        // pNode->AddRef();\n    }\n    return result;\n}\n\n//-----------------------------------------------------------------------------\nCPUTAssetSet *CPUTAssetSetDX11::CreateAssetSet( const cString &name, const cString &absolutePathAndFilename )\n{\n    CPUTAssetLibraryDX11 *pAssetLibrary = ((CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary());\n\n    // Create the root node.\n    CPUTNullNode *pRootNode = new CPUTNullNode();\n    pRootNode->SetName(_L(\"_CPUTAssetSetRootNode_\"));\n\n    // Create the asset set, set its root, and load it\n    CPUTAssetSet   *pNewAssetSet = new CPUTAssetSetDX11();\n    pNewAssetSet->SetRoot( pRootNode );\n    pAssetLibrary->AddNullNode( name + _L(\"_Root\"), pRootNode );\n\n    CPUTResult result = pNewAssetSet->LoadAssetSet(absolutePathAndFilename);\n    if( CPUTSUCCESS(result) )\n    {\n        pAssetLibrary->AddAssetSet(name, pNewAssetSet);\n        return pNewAssetSet;\n    }\n    ASSERT( CPUTSUCCESS(result), _L(\"Error loading AssetSet\\n'\")+absolutePathAndFilename+_L(\"'\"));\n    pNewAssetSet->Release();\n    return NULL;\n}\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTAssetSetDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTASSETSETDX11_H__\n#define __CPUTASSETSETDX11_H__\n\n#include \"CPUTAssetSet.h\"\n\nclass CPUTAssetSetDX11 : public CPUTAssetSet\n{\npublic:\n    static CPUTAssetSet *CreateAssetSet( const cString &name, const cString &absolutePathAndFilename );\n\n    CPUTAssetSetDX11() : CPUTAssetSet() {}\n    virtual ~CPUTAssetSetDX11();\n    virtual CPUTResult LoadAssetSet(cString name);\n};\n\n#endif // #ifndef __CPUTASSETSETDX11_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTBuffer.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTBuffer.h\"\n#ifdef CPUT_FOR_DX11\n#include \"CPUTBufferDX11.h\"\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n"
  },
  {
    "path": "CPUT/CPUT/CPUTBuffer.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTBUFFER_H\n#define _CPUTBUFFER_H\n\n#include \"CPUT.h\"\n#include \"CPUTRefCount.h\"\n\n// TODO: Move to dedicated file\nclass CPUTBuffer : public CPUTRefCount\n{\nprotected:\n    cString      mName;\n    eCPUTMapType mMappedType;\n\n    ~CPUTBuffer(){\n        mName.clear();\n    } // Destructor is not public.  Must release instead of delete.\npublic:\n    CPUTBuffer(){mMappedType = CPUT_MAP_UNDEFINED;}\n    CPUTBuffer(cString &name) {mName = name; mMappedType = CPUT_MAP_UNDEFINED;}\n};\n\n#endif //_CPUTBUFFER_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTBufferDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTBufferDX11.h\"\n\n//-----------------------------------------------------------------------------\nD3D11_MAPPED_SUBRESOURCE CPUTBufferDX11::MapBuffer( CPUTRenderParameters &params, eCPUTMapType type, bool wait )\n{\n    // Mapping for DISCARD requires dynamic buffer.  Create dynamic copy?\n    // Could easily provide input flag.  But, where would we specify? Don't like specifying in the .set file\n    // Because mapping is something the application wants to do - it isn't inherent in the data.\n    // Could do Clone() and pass dynamic flag to that.\n    // But, then we have two.  Could always delete the other.\n    // Could support programatic flag - apply to all loaded models in the .set\n    // Could support programatic flag on model.  Load model first, then load set.\n    // For now, simply support CopyResource mechanism.\n    HRESULT hr;\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    if( !mpBufferStaging )\n    {\n        D3D11_BUFFER_DESC desc;\n        mpBuffer->GetDesc( &desc );\n        desc.Usage = D3D11_USAGE_STAGING;\n        switch( type )\n        {\n        case CPUT_MAP_READ:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n            desc.BindFlags = 0;\n            break;\n        case CPUT_MAP_READ_WRITE:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n            desc.BindFlags = 0;\n            break;\n        case CPUT_MAP_WRITE:\n        case CPUT_MAP_WRITE_DISCARD:\n        case CPUT_MAP_NO_OVERWRITE:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n            desc.BindFlags = 0;\n            break;\n        };\n        hr = pD3dDevice->CreateBuffer( &desc, NULL, &mpBufferStaging );\n        ASSERT( SUCCEEDED(hr), _L(\"Failed to create staging buffer\") );\n        CPUTSetDebugName( mpBufferStaging, _L(\"Staging Buffer\"));\n    }\n    else\n    {\n        ASSERT( mMappedType == type, _L(\"Mapping with a different CPU access than creation parameter.\") );\n    }\n    D3D11_MAPPED_SUBRESOURCE info;\n    switch( type )\n    {\n    case CPUT_MAP_READ:\n    case CPUT_MAP_READ_WRITE:\n        // TODO: Copying and immediately mapping probably introduces a stall.\n        // Expose the copy externally?\n        // TODO: copy only if changed?\n        // Copy only first time?\n        // Copy the GPU version before we read from it.\n        pContext->CopyResource( mpBufferStaging, mpBuffer );\n        break;\n    };\n    hr = pContext->Map( mpBufferStaging, wait ? 0 : D3D11_MAP_FLAG_DO_NOT_WAIT, (D3D11_MAP)type, 0, &info );\n    mMappedType = type;\n    return info;\n} // CPUTBufferDX11::Map()\n\n//-----------------------------------------------------------------------------\nvoid CPUTBufferDX11::UnmapBuffer( CPUTRenderParameters &params )\n{\n    ASSERT( mMappedType != CPUT_MAP_UNDEFINED, _L(\"Can't unmap a render target that isn't mapped.\") );\n\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    pContext->Unmap( mpBufferStaging, 0 );\n\n    // If we were mapped for write, then copy staging buffer to GPU\n    switch( mMappedType )\n    {\n    case CPUT_MAP_READ:\n        break;\n    case CPUT_MAP_READ_WRITE:\n    case CPUT_MAP_WRITE:\n    case CPUT_MAP_WRITE_DISCARD:\n    case CPUT_MAP_NO_OVERWRITE:\n        pContext->CopyResource( mpBuffer, mpBufferStaging );\n        break;\n    };\n} // CPUTBufferDX11::Unmap()\n\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTBufferDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTBUFFERDX11_H\n#define _CPUTBUFFERDX11_H\n\n#include \"CPUTBuffer.h\"\n#include \"CPUT_DX11.h\"\n\n//--------------------------------------------------------------------------------------\n// TODO: Move to dedicated file\nclass CPUTBufferDX11 : public CPUTBuffer\n{\nprivate:\n    // resource view pointer\n    ID3D11ShaderResourceView  *mpShaderResourceView;\n    ID3D11UnorderedAccessView *mpUnorderedAccessView;\n    ID3D11Buffer              *mpBuffer;\n    ID3D11Buffer              *mpBufferStaging;\n\n    // Destructor is not public.  Must release instead of delete.\n    ~CPUTBufferDX11() {\n        SAFE_RELEASE( mpShaderResourceView );\n        SAFE_RELEASE( mpUnorderedAccessView );\n        SAFE_RELEASE( mpBuffer );\n        SAFE_RELEASE( mpBufferStaging );\n    }\n\npublic:\n    CPUTBufferDX11() :\n        mpShaderResourceView(NULL),\n        mpUnorderedAccessView(NULL),\n        mpBuffer(NULL),\n        mpBufferStaging(NULL)\n    {\n    }\n    CPUTBufferDX11(cString &name, ID3D11Buffer *pBuffer) :\n        mpBuffer(pBuffer),\n        mpBufferStaging(NULL),\n        mpShaderResourceView(NULL),\n        mpUnorderedAccessView(NULL),\n        CPUTBuffer(name)\n    {\n        if(pBuffer) pBuffer->AddRef();\n    }\n\n    CPUTBufferDX11(cString &name, ID3D11Buffer *pBuffer, ID3D11ShaderResourceView *pView) :\n        mpBuffer(pBuffer),\n        mpBufferStaging(NULL),\n        mpShaderResourceView(pView),\n        mpUnorderedAccessView(NULL),\n        CPUTBuffer(name)\n    {\n        if(pBuffer) pBuffer->AddRef();\n        if(pView) pView->AddRef();\n    }\n\n    CPUTBufferDX11(cString &name, ID3D11Buffer *pBuffer, ID3D11UnorderedAccessView *pView) :\n        mpBuffer(pBuffer),\n        mpBufferStaging(NULL),\n        mpShaderResourceView(NULL),\n        mpUnorderedAccessView(pView),\n        CPUTBuffer(name)\n    {\n        if(pBuffer) pBuffer->AddRef();\n        if(pView) pView->AddRef();\n    }\n\n    ID3D11ShaderResourceView *GetShaderResourceView()\n    {\n        return mpShaderResourceView;\n    }\n\n    ID3D11UnorderedAccessView *GetUnorderedAccessView()\n    {\n        return mpUnorderedAccessView;\n    }\n\n    void SetShaderResourceView(ID3D11ShaderResourceView *pShaderResourceView)\n    {\n        // release any resource view we might already be pointing too\n        SAFE_RELEASE( mpShaderResourceView );\n        mpShaderResourceView = pShaderResourceView;\n        mpShaderResourceView->AddRef();\n    }\n    void SetUnorderedAccessView(ID3D11UnorderedAccessView *pUnorderedAccessView)\n    {\n        // release any resource view we might already be pointing too\n        SAFE_RELEASE( mpUnorderedAccessView );\n        mpUnorderedAccessView = pUnorderedAccessView;\n        mpUnorderedAccessView->AddRef();\n    }\n    void SetBufferAndViews(ID3D11Buffer *pBuffer, ID3D11ShaderResourceView *pShaderResourceView, ID3D11UnorderedAccessView *pUnorderedAccessView )\n    {\n        SAFE_RELEASE(mpBuffer);\n        mpBuffer = pBuffer;\n        if(mpBuffer) mpBuffer->AddRef();\n\n        // release any resource view we might already be pointing too\n        SAFE_RELEASE( mpShaderResourceView );\n        mpShaderResourceView = pShaderResourceView;\n        if(mpShaderResourceView) mpShaderResourceView->AddRef();\n\n        // release any resource view we might already be pointing too\n        SAFE_RELEASE( mpUnorderedAccessView );\n        mpUnorderedAccessView = pUnorderedAccessView;\n        if(mpUnorderedAccessView) mpUnorderedAccessView->AddRef();\n    }\n    ID3D11Buffer *GetNativeBuffer() { return mpBuffer; }\n    D3D11_MAPPED_SUBRESOURCE  MapBuffer(   CPUTRenderParameters &params, eCPUTMapType type, bool wait=true );\n    void                      UnmapBuffer( CPUTRenderParameters &params );\n    void ReleaseBuffer()\n    {\n        SAFE_RELEASE(mpShaderResourceView);\n        SAFE_RELEASE(mpUnorderedAccessView);\n        SAFE_RELEASE(mpBuffer);\n        SAFE_RELEASE(mpBufferStaging);\n    }\n};\n#endif //_CPUTBUFFERDX11_H\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTButton.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTButton.h\"\n#include \"CPUTText.h\"\n\n// static initializers\nbool CPUTButton::mStaticRegistered = false;\n\n// list of resources sizes\nCPUT_SIZE CPUTButton::mpButtonIdleImageSizeList[CPUT_NUM_IMAGES_IN_BUTTON] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\nCPUT_SIZE CPUTButton::mpButtonPressedImageSizeList[CPUT_NUM_IMAGES_IN_BUTTON] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\nCPUT_SIZE CPUTButton::mpButtonDisabledImageSizeList[CPUT_NUM_IMAGES_IN_BUTTON] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\n\nint CPUTButton::mSmallestLeftSizeIdle=0;\nint CPUTButton::mSmallestRightSizeIdle=0;\nint CPUTButton::mSmallestTopSizeIdle=0;\nint CPUTButton::mSmallestBottomSizeIdle=0;\n\nint CPUTButton::mSmallestLeftSizePressed=0;\nint CPUTButton::mSmallestRightSizePressed=0;\nint CPUTButton::mSmallestTopSizePressed=0;\nint CPUTButton::mSmallestBottomSizePressed=0;\n\nint CPUTButton::mSmallestLeftSizeDisabled=0;\nint CPUTButton::mSmallestRightSizeDisabled=0;\nint CPUTButton::mSmallestTopSizeDisabled=0;\nint CPUTButton::mSmallestBottomSizeDisabled=0;\n\n// texture atlas information\nfloat gAtlasWidth = 256.0f;\nfloat gAtlasHeight = 64.0f;\n\n// Texture atlas coordinates of the active-idle button image\nint gUVLocations_active[] = { \n    8,8, 15,31,  // lt\n    8,31, 15,32, // lm\n    8,32, 15,40, // lb\n\n    15,8,  16,31, // mt\n    15,31, 16,32, // mm\n    15,32, 16,40, // mb\n\n    16,8, 25,31,  // rt\n    16,31, 25,32, // rm\n    16,32, 25,40  // rb\n};\n\n// Texture atlas coordinates of the pressed button image\nint gUVLocations_pressed[] = { \n    63,8, 70,31,  // lt\n    63,31, 70,32, // lm\n    63,32, 70,40, // lb\n\n    70,8,  71,31, // mt\n    70,31, 71,32, // mm\n    70,32, 71,40, // mb\n\n    71,8, 81,31,  // rt\n    71,31, 81,32, // rm\n    71,32, 81,40  // rb\n};\n\n// Texture atlas coordinates of the disabled button image\nint gUVLocations_disabled[] = { \n    36,8, 43,31,  // lt\n    36,31, 43,32, // lm\n    36,32, 43,40, // lb\n\n    43,8,  45,31, // mt\n    43,31, 45,32, // mm\n    43,32, 45,40, // mb\n\n    45,8, 55,31,  // rt\n    45,31, 55,32, // rm\n    45,32, 55,40  // rb\n};\n\nfloat3 mpUVCoords_active[9*2];\nfloat3 mpUVCoords_pressed[9*2];\nfloat3 mpUVCoords_disabled[9*2];\n\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTButton::CPUTButton(const cString ControlText, CPUTControlID id, CPUTFont *pFont):\n    mbMouseInside(false),\n    mbStartedClickInside(false),\n    mpButtonText(NULL),\n    mpMirrorBufferActive(NULL),\n    mpMirrorBufferPressed(NULL),\n    mpMirrorBufferDisabled(NULL),\n    mpFont(pFont)\n{\n    // initialize the state variables\n    InitializeState();\n\n    // save the control ID for callbacks\n    mcontrolID = id;\n\n    // save the font to use for text on this button\n    mpFont = pFont;\n\n    // set as enabled\n    CPUTControl::SetEnable(true);\n\n    // initialize the size lists\n    memset(&mpButtonIdleSizeList, 0, sizeof(CPUT_SIZE) * CPUT_NUM_IMAGES_IN_BUTTON);\n    memset(&mpButtonPressedSizeList, 0, sizeof(CPUT_SIZE) * CPUT_NUM_IMAGES_IN_BUTTON);\n    memset(&mpButtonDisabledSizeList, 0, sizeof(CPUT_SIZE) * CPUT_NUM_IMAGES_IN_BUTTON);\n\n    // set up the per-instance data\n    RegisterInstanceResources();\n\n    // set the text on the button and resize it accordingly\n    SetText(ControlText);\n\n    // set the default control position\n    SetPosition( 0, 0 );\n\n}\n\n// Initial state of the control's member variables\n//-----------------------------------------------------------------------------\nvoid CPUTButton::InitializeState()\n{\n    mcontrolType = CPUT_BUTTON;\n\n    mButtonState = CPUT_BUTTON_NEUTRAL;\n\n    // dimensions\n    mButtonDimensions.x=0;\n    mButtonDimensions.y=0;\n    mButtonDimensions.width=0;\n    mButtonDimensions.height=0;\n}\n\n// Destructor\n//------------------------------------------------------------------------------\nCPUTButton::~CPUTButton()\n{\n    UnRegisterInstanceResources();\n}\n\n\n// Return the upper-left screen coordinate location of this control\n//--------------------------------------------------------------------------------\nvoid CPUTButton::GetPosition(int &x, int &y)\n{\n    x = mButtonDimensions.x;\n    y = mButtonDimensions.y;\n}\n\n// Return the width/height of the control\n//--------------------------------------------------------------------------------\nvoid CPUTButton::GetDimensions(int &width, int &height)\n{\n    width = mButtonDimensions.width;\n    height = mButtonDimensions.height;\n}\n\n// Returns the number of quads needed to draw this control\n//--------------------------------------------------------------------------------\nunsigned int CPUTButton::GetOutputVertexCount()\n{\n    // A button is always made of 9 quads.\n    // Quads 2,4,5,6, and 8 'stretch' in height and/or width to fit the \n    // static text/content inside the button\n    //\n    //   ---+-----------+---\n    //  | 1 |     4     | 7 |              \n    //  |---+-----------+---|\n    //  |   |           |   | \n    //  | 2 |     5     | 8 |              \n    //  |   |           |   | \n    //  |---+-----------+---|\n    //  | 3 |     6     | 9 |\n    //   ---+-----------+---\n    //\n    // calculation: 3 verts/triangle * 2 triangle/quad * 9 quads\n    return (2*3)*9;\n}\n\n\n\n\n\n\n//CPUTEventHandler\n\n// Handle keyboard events\n//--------------------------------------------------------------------------------\nCPUTEventHandledCode CPUTButton::HandleKeyboardEvent(CPUTKey key)\n{\n    UNREFERENCED_PARAMETER(key);\n    return CPUT_EVENT_UNHANDLED;\n}\n\n// Handle mouse events\n//--------------------------------------------------------------------------------\nCPUTEventHandledCode CPUTButton::HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state)\n{\n    UNREFERENCED_PARAMETER(wheel);\n    CPUTEventHandledCode handledCode = CPUT_EVENT_UNHANDLED;\n\n    if((CPUT_CONTROL_INACTIVE == mControlState) || (false == mControlVisible) )\n    {\n        mbMouseInside = false;\n        return handledCode;\n    }\n\n    // if we're continuing to be pressed, move around with the mouse movement\n    if( (CPUT_BUTTON_PRESSED == mButtonState ) && (CPUT_MOUSE_LEFT_DOWN == state))\n    {\n        return CPUT_EVENT_HANDLED;\n    }\n\n    if(ContainsPoint(x,y))\n    {\n        // did we start our click inside the button?\n        if((state & CPUT_MOUSE_LEFT_DOWN) && (true == mbMouseInside))\n        {\n            mbStartedClickInside = true;\n            mButtonState = CPUT_BUTTON_PRESSED;\n            handledCode = CPUT_EVENT_HANDLED;\n\n            // tell gui system this control image is now dirty\n            // and needs to rebuild it's draw list\n            mControlGraphicsDirty = true;\n        }\n\n        // did they click inside the button?\n        if(!(state & CPUT_MOUSE_LEFT_DOWN) && (true == mbStartedClickInside) && (CPUT_BUTTON_PRESSED == mButtonState))\n        {\n            // they let up the click - trigger the user's callback\n            mpCallbackHandler->HandleCallbackEvent(1, mcontrolID, (CPUTControl*) this);\n            handledCode = CPUT_EVENT_HANDLED;\n            mButtonState = CPUT_BUTTON_NEUTRAL;\n\n            // tell gui system this control image is now dirty\n            // and needs to rebuild it's draw list\n            mControlGraphicsDirty = true;               \n        }\n\n        if(!(state & CPUT_MOUSE_LEFT_DOWN))\n        {\n            mbMouseInside = true;\n        }\n    }\n    else\n    {\n        // we left the button\n        // if we weren't already in neutral state, return to neutral sate\n        // this handles case of clicking button, exiting button, and releasing button outside control\n        if(CPUT_BUTTON_NEUTRAL != mButtonState)\n        {\n            mButtonState = CPUT_BUTTON_NEUTRAL;\n            mControlGraphicsDirty = true;\n        }\n        mbMouseInside = false;\n        mButtonState = CPUT_BUTTON_NEUTRAL;\n        mbStartedClickInside = false;  \n    }\n\n    return handledCode;\n}\n\n// Returns true if the x,y coordinate is inside the button's control region\n//--------------------------------------------------------------------------------\nbool CPUTButton::ContainsPoint(int x, int y)\n{\n    if( (x>=mButtonDimensions.x) && (x<=mButtonDimensions.x+mButtonDimensions.width))\n    {\n        if( (y>=mButtonDimensions.y) && (y<=mButtonDimensions.y+mButtonDimensions.height))\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\n// Returns the x,y coordinate inside the button area that should be 'safe' to draw on\n//--------------------------------------------------------------------------------\nvoid CPUTButton::GetInsetTextCoordinate(int &x, int &y)\n{\n    // get text size\n    CPUT_RECT ButtonTextDimensions;\n    if(mpButtonText)\n    {\n        mpButtonText->GetDimensions(ButtonTextDimensions.width, ButtonTextDimensions.height);\n    }\n    else\n    {\n        ButtonTextDimensions.width=0;\n        ButtonTextDimensions.height=0;\n    }\n\n    // calculate a good 'center' point\n    x =(int) ( mButtonDimensions.x + mButtonDimensions.width/2.0f - ButtonTextDimensions.width/2.0f);\n    y =(int) ( mButtonDimensions.y + mButtonDimensions.height/2.0f - ButtonTextDimensions.height/2.0f);\n}\n\n// Sets the text on the control\n//--------------------------------------------------------------------------------\nvoid CPUTButton::SetText(const cString String)\n{\n    // Zero out the size and location\n    InitializeState();\n\n    // create the static text object if it doesn't exist\n    if(NULL == mpButtonText)\n    {\n        mpButtonText = new CPUTText(mpFont);\n    }\n\n    // set the Static control's text\n    mpButtonText->SetText(String);\n\n    // get the dimensions of the string in pixels\n    CPUT_RECT rect;\n    mpButtonText->GetDimensions(rect.width, rect.height);\n\n    // resize this control to fix that string with padding\n    Resize(rect.width, rect.height);\n\n    // move the text to a nice inset location inside the 'safe' area\n    // of the button image\n    int x,y;\n    GetInsetTextCoordinate(x, y);\n    mpButtonText->SetPosition(x, y);\n\n    // position or size may move - force a recalculation of this control's location\n    // if it is managed by the auto-arrange function\n    if(this->IsAutoArranged())\n    {\n        mControlNeedsArrangmentResizing = true;\n    }\n    else\n    {\n        // otherwise, we mark this as dirty\n        mControlGraphicsDirty = true;\n    }\n}\n\n// sets the dimensions of the button\n//--------------------------------------------------------------------------------\nvoid CPUTButton::SetDimensions(int width, int height)\n{\n    // Zero out the size and location\n    InitializeState();\n\n    // get the dimensions of the string in pixels\n    CPUT_RECT rect;\n    mpButtonText->GetDimensions(rect.width, rect.height);\n\n    width = max(rect.width, width);\n    height = max(rect.height, height);\n\n    // resize this control to fix that string with padding\n    Resize(width, height);\n\n    // move the text to a nice inset location inside the 'safe' area\n    // of the button image\n    int x,y;\n    GetInsetTextCoordinate(x, y);\n    mpButtonText->SetPosition(x, y);\n}\n\n// Fills the users buffer with the button text\n//--------------------------------------------------------------------------------\nvoid CPUTButton::GetText(cString &String)\n{\n    if(mpButtonText)\n    {\n        mpButtonText->GetString(String);\n    }\n}\n\n// Enable/disable the control\n//--------------------------------------------------------------------------------\nvoid CPUTButton::SetEnable(bool in_bEnabled)\n{\n    // chain to CPUTControl set enabled\n    CPUTControl::SetEnable(in_bEnabled);\n\n    // set the control's text to match\n    mpButtonText->SetEnable(in_bEnabled);\n\n    // otherwise, we mark this as dirty\n    mControlGraphicsDirty = true;\n}\n\n// Set the upper-left screen coordinate location of this control\n//--------------------------------------------------------------------------------\nvoid CPUTButton::SetPosition(int x, int y)\n{\n    // move the button graphics\n    mButtonDimensions.x = x;\n    mButtonDimensions.y = y;\n\n    // move the static text (if any)\n    if(mpButtonText)\n    {\n\t\t// resize things in the buffers\n\t\tCPUT_RECT rect;\n\t\tmpButtonText->GetDimensions(rect.width, rect.height);\n\t\tResize(rect.width, rect.height);\n\n\t\tint insetX, insetY;\n\t\tGetInsetTextCoordinate(insetX, insetY);\n\t\tmpButtonText->SetPosition(insetX, insetY);\n    }\n}\n\n// 'Draw' this control into the supplied vertex buffer object\n//--------------------------------------------------------------------------------\nvoid CPUTButton::DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize, CPUTGUIVertex *pTextVertexBufferMirror, UINT *pTextInsertIndex, UINT MaxTextVertexBufferSize)\n{\n    if(!mControlVisible)\n    {\n        return;\n    }\n\n    // invalid output buffer pointers?\n    if((NULL==pVertexBufferMirror) || (NULL==pInsertIndex))\n    {\n        return;\n    }\n\n    // invalid buffer pointers?\n    if(!mpMirrorBufferActive || !mpMirrorBufferPressed || !mpMirrorBufferDisabled)\n    {\n        return;\n    }\n\n    // Do we have enough room to put this control into the output buffer?\n    int VertexCopyCount = GetOutputVertexCount();\n    ASSERT( (pMaxBufferSize >= *pInsertIndex + VertexCopyCount), _L(\"Too many CPUT GUI controls for allocated GUI buffer. Allocated GUI vertex buffer is too small.\\n\\nIncrease CPUT_GUI_BUFFER_SIZE size.\") );\n    \n    switch(mControlState)\n    {\n    case CPUT_CONTROL_ACTIVE:\n        // copy the active+idle button into the stream\n        if(CPUT_BUTTON_NEUTRAL == mButtonState)\n        {\n            memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferActive, sizeof(CPUTGUIVertex)*VertexCopyCount);\n        }        \n\n        // copy the pressed button into the stream\n        if(CPUT_BUTTON_PRESSED == mButtonState)\n        {\n            memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferPressed, sizeof(CPUTGUIVertex)*VertexCopyCount);\n        }\n        \n        break;\n    case CPUT_CONTROL_INACTIVE:\n        // copy the inactive button into the stream\n        memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferDisabled, sizeof(CPUTGUIVertex)*VertexCopyCount);\n        break;\n\n    default:\n        // error! unknown state\n        ASSERT(0,_L(\"CPUTButton: Control is in unknown state\"));\n        return;\n    }\n\n    // move the index the correct number of floats to account\n    // for 9 new quads, each quad with 6 verts in it (and each vert with 3+2 floats in it).\n    *pInsertIndex+= VertexCopyCount;\n\n    // now do the text\n    // draw the text\n    if(mpButtonText)\n    {\n        mpButtonText->DrawIntoBuffer(pTextVertexBufferMirror, pTextInsertIndex, MaxTextVertexBufferSize);\n    }\n\n    // we'll mark the control as no longer being 'dirty'\n    mControlGraphicsDirty = false;\n}\n\n\n// Allocates/registers resources used by all buttons\n//--------------------------------------------------------------------------------\nCPUTResult CPUTButton::RegisterStaticResources()\n{\n    // calculate the UV coordinates of each of the 9 images that\n    // make up a button.  Do this for the active, pressed, and disabled states.\n    for(int ii=0; ii<18; ii++)\n    {\n        mpUVCoords_active[ii].x = gUVLocations_active[2*ii]/gAtlasWidth;\n        mpUVCoords_active[ii].y = gUVLocations_active[2*ii+1]/gAtlasHeight;\n\n        mpUVCoords_pressed[ii].x = gUVLocations_pressed[2*ii]/gAtlasWidth;\n        mpUVCoords_pressed[ii].y = gUVLocations_pressed[2*ii+1]/gAtlasHeight;\n\n        mpUVCoords_disabled[ii].x = gUVLocations_disabled[2*ii]/gAtlasWidth;\n        mpUVCoords_disabled[ii].y = gUVLocations_disabled[2*ii+1]/gAtlasHeight;\n    }\n\n    // calculate the width/height in pixels of each of the 9 image slices\n    // that makes up the button images\n    int QuadIndex=0;\n    for(int ii=0; ii<9*4; ii+=4)\n    {\n        mpButtonIdleImageSizeList[QuadIndex].width = gUVLocations_active[ii+2] - gUVLocations_active[ii+0];\n        mpButtonIdleImageSizeList[QuadIndex].height = gUVLocations_active[ii+3] - gUVLocations_active[ii+1];\n \n        mpButtonPressedImageSizeList[QuadIndex].width = gUVLocations_pressed[ii+2] - gUVLocations_pressed[ii+0];\n        mpButtonPressedImageSizeList[QuadIndex].height = gUVLocations_pressed[ii+3] - gUVLocations_pressed[ii+1];\n\n        mpButtonDisabledImageSizeList[QuadIndex].width = gUVLocations_disabled[ii+2] - gUVLocations_disabled[ii+0];\n        mpButtonDisabledImageSizeList[QuadIndex].height = gUVLocations_disabled[ii+3] - gUVLocations_disabled[ii+1];\n        QuadIndex++;\n    }\n    \n    // find the narrowest (width) left side images\n    mSmallestLeftSizeIdle = min(min(mpButtonIdleImageSizeList[0].width, mpButtonIdleImageSizeList[1].width), mpButtonIdleImageSizeList[2].width);\n    mSmallestLeftSizePressed = min(min(mpButtonPressedImageSizeList[0].width, mpButtonPressedImageSizeList[1].width), mpButtonPressedImageSizeList[2].width);\n    mSmallestLeftSizeDisabled = min(min(mpButtonDisabledImageSizeList[0].width, mpButtonDisabledImageSizeList[1].width), mpButtonDisabledImageSizeList[2].width);  \n    \n    // find the narrowest (width) right side images\n    mSmallestRightSizeIdle = min(min(mpButtonIdleImageSizeList[6].width, mpButtonIdleImageSizeList[7].width), mpButtonIdleImageSizeList[8].width);\n    mSmallestRightSizePressed = min(min(mpButtonPressedImageSizeList[6].width, mpButtonPressedImageSizeList[7].width), mpButtonPressedImageSizeList[8].width);\n    mSmallestRightSizeDisabled = min(min(mpButtonDisabledImageSizeList[6].width, mpButtonDisabledImageSizeList[7].width), mpButtonDisabledImageSizeList[8].width);  \n    \n\n    // find the shortest (height) of the top row of images\n    mSmallestTopSizeIdle = min(min( mpButtonIdleImageSizeList[0].height,mpButtonIdleImageSizeList[3].height), mpButtonIdleImageSizeList[6].height);\n    mSmallestTopSizePressed = min(min( mpButtonPressedImageSizeList[0].height,mpButtonPressedImageSizeList[3].height), mpButtonPressedImageSizeList[6].height);\n    mSmallestTopSizeDisabled = min( min( mpButtonDisabledImageSizeList[0].height,mpButtonDisabledImageSizeList[3].height), mpButtonDisabledImageSizeList[6].height);\n\n    // find the shortest (height) of the bottom row of images\n    mSmallestBottomSizeIdle = min(min( mpButtonIdleImageSizeList[2].height,mpButtonIdleImageSizeList[5].height), mpButtonIdleImageSizeList[8].height);\n    mSmallestBottomSizePressed = min(min( mpButtonPressedImageSizeList[2].height,mpButtonPressedImageSizeList[5].height), mpButtonPressedImageSizeList[8].height);\n    mSmallestBottomSizeDisabled = min(min( mpButtonDisabledImageSizeList[2].height,mpButtonDisabledImageSizeList[5].height), mpButtonDisabledImageSizeList[8].height);\n        \n    mStaticRegistered = true;\n\n    return CPUT_SUCCESS;\n}\n\n\n// Deletes any statically allocated resources used for all buttons\n//--------------------------------------------------------------------------------\nCPUTResult CPUTButton::UnRegisterStaticResources()\n{\n    return CPUT_SUCCESS;\n}\n\n// Allocates an initialize all per-instance resources for this button\n//--------------------------------------------------------------------------------\nCPUTResult CPUTButton::RegisterInstanceResources()\n{\n    // clear any previously allocated buffers\n    SAFE_DELETE_ARRAY(mpMirrorBufferActive);\n    SAFE_DELETE_ARRAY(mpMirrorBufferPressed);\n    SAFE_DELETE_ARRAY(mpMirrorBufferDisabled);\n\n    // allocate the per-instance sizes (each button will have different dimensions)\n    mpMirrorBufferActive = new CPUTGUIVertex[6 * 9];\n    mpMirrorBufferPressed = new CPUTGUIVertex[6 * 9];\n    mpMirrorBufferDisabled = new CPUTGUIVertex[6 * 9];\n\n\n    // store all the default button component quad sizes in instance variables\n    // Re-sizable parts will get re-calculated during setText and other operations\n    for(int i=0; i<CPUT_NUM_IMAGES_IN_BUTTON; i++)\n    {\n        mpButtonIdleSizeList[i].height = mpButtonIdleImageSizeList[i].height;\n        mpButtonIdleSizeList[i].width = mpButtonIdleImageSizeList[i].width;\n\n        mpButtonPressedSizeList[i].height = mpButtonPressedImageSizeList[i].height;\n        mpButtonPressedSizeList[i].width = mpButtonPressedImageSizeList[i].width;\n\n        mpButtonDisabledSizeList[i].height = mpButtonDisabledImageSizeList[i].height;\n        mpButtonDisabledSizeList[i].width = mpButtonDisabledImageSizeList[i].width;\n    }\n\n    return CPUT_SUCCESS;\n}\n\n// Delete all instance resources alloated for this button\n//--------------------------------------------------------------------------------\nCPUTResult CPUTButton::UnRegisterInstanceResources()\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    // delete the static text object\n    SAFE_DELETE(mpButtonText);\n\n    // Release the mirrored vertex lists\n    SAFE_DELETE_ARRAY(mpMirrorBufferActive);\n    SAFE_DELETE_ARRAY(mpMirrorBufferPressed);\n    SAFE_DELETE_ARRAY(mpMirrorBufferDisabled);\n\n    return result;\n}\n\n\n\n// Resize the button \n// Recalculates the size of the button based on the supplied dimensions and \n// generates new vertex buffer lists for each of the 3 states of the control.\n//\n// It does NOT move the inside text, nor does it base itself on the size of the \n// text. You need to do that yourself outside this function and pass it in\n//--------------------------------------------------------------------------------\nCPUTResult CPUTButton::Resize(int width, int height)\n{\n    // verify that the new dimensions fit the minimal 'safe' dimensions needed to draw the button\n    // or ugly clipping will occur\n    int safeWidth=0;\n    int safeHeight=0;\n\n    switch(mControlState)\n    {\n    case CPUT_CONTROL_ACTIVE:\n        if(CPUT_BUTTON_NEUTRAL == mButtonState)\n        {\n            safeWidth =  mSmallestLeftSizeIdle + mSmallestRightSizeIdle + 1;\n            safeHeight =  mSmallestTopSizeIdle + mSmallestBottomSizeIdle + 1;\n        }\n        if(CPUT_BUTTON_PRESSED == mButtonState)\n        {\n            safeWidth =  mSmallestLeftSizePressed + mSmallestRightSizePressed + 1;\n            safeHeight =  mSmallestTopSizePressed + mSmallestBottomSizePressed + 1;\n        }\n        break;\n\n    case CPUT_CONTROL_INACTIVE:        \n        safeWidth =  mSmallestLeftSizeDisabled + mSmallestRightSizeDisabled + 1;\n        safeHeight =  mSmallestTopSizeDisabled + mSmallestBottomSizeDisabled + 1;\n        break;\n\n    default:\n        ASSERT(0,_L(\"\")); // todo: error! unknown state - using idle dimensions as a default\n        safeWidth =  mSmallestLeftSizeIdle + mSmallestRightSizeIdle + 1;\n        safeHeight =  mSmallestTopSizeIdle + mSmallestBottomSizeIdle + 1;\n    }\n\n    // if the user's dimensions are smaller than the smallest 'safe' dimensions of the button,\n    // use the safe ones instead.\n    if(safeWidth > width)\n    {\n        width = safeWidth;\n    }\n    if(safeHeight > height)\n    {\n        height = safeHeight;\n    }\n\n    // add some padding for nicety\n    width += CPUT_BUTTON_TEXT_BORDER_PADDING_X;\n    height += CPUT_BUTTON_TEXT_BORDER_PADDING_Y;\n  \n    {\n        // store the new dimensions\n        mButtonDimensions.width = width;\n        mButtonDimensions.height = height;\n\n        // calculate the pieces we'll need to rebuild\n        int middleWidth = width - mSmallestLeftSizeIdle - mSmallestRightSizeIdle;\n        int middleHeight = height - mSmallestTopSizeIdle - mSmallestBottomSizeIdle;\n\n        // delete the old button quads for the middle sections\n        //result = UnRegisterResizableInstanceQuads();\n\n        // create a new quads with the correct size\n        // Idle button quads        \n        \n        // left\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 0*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y, (float) mpButtonIdleSizeList[0].width, (float) mpButtonIdleSizeList[0].height, mpUVCoords_active[2*0], mpUVCoords_active[2*0+1] );\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 1*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y+mSmallestTopSizeIdle, (float) mpButtonIdleSizeList[1].width, (float) middleHeight, mpUVCoords_active[2*1], mpUVCoords_active[2*1+1] );\n        mpButtonIdleSizeList[1].height = middleHeight;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 2*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) mpButtonIdleSizeList[2].width, (float) mpButtonIdleSizeList[2].height, mpUVCoords_active[2*2], mpUVCoords_active[2*2+1] );\n\n        // middle\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 3*6, (float)mButtonDimensions.x+mSmallestLeftSizeIdle, (float)mButtonDimensions.y, (float) middleWidth, (float) mpButtonIdleSizeList[3].height, mpUVCoords_active[2*3], mpUVCoords_active[2*3+1] );\n        mpButtonIdleSizeList[3].width = middleWidth;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 4*6, (float)mButtonDimensions.x+mSmallestLeftSizeIdle, (float)mButtonDimensions.y+mSmallestTopSizeIdle, (float) middleWidth, (float) middleHeight, mpUVCoords_active[2*4], mpUVCoords_active[2*4+1] );\n        mpButtonIdleSizeList[4].width = middleWidth;\n        mpButtonIdleSizeList[4].height = middleHeight;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 5*6, (float)mButtonDimensions.x+mSmallestLeftSizeIdle, (float)mButtonDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) middleWidth, (float) mpButtonIdleSizeList[5].height, mpUVCoords_active[2*5], mpUVCoords_active[2*5+1] );\n        mpButtonIdleSizeList[5].width = middleWidth;\n\n        // right\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 6*6, (float)mButtonDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mButtonDimensions.y, (float) mpButtonIdleSizeList[6].width, (float)mpButtonIdleSizeList[6].height, mpUVCoords_active[2*6], mpUVCoords_active[2*6+1] );\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 7*6, (float)mButtonDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mButtonDimensions.y+mSmallestTopSizeIdle, (float) mpButtonIdleSizeList[7].width, (float)middleHeight, mpUVCoords_active[2*7], mpUVCoords_active[2*7+1] );\n        mpButtonIdleSizeList[7].height = middleHeight;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 8*6, (float)mButtonDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mButtonDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) mpButtonIdleSizeList[8].width, (float)mpButtonIdleSizeList[8].height, mpUVCoords_active[2*8], mpUVCoords_active[2*8+1] );\n\n        // register uberbuffer\n        //RegisterUberBuffer(pImmediateContext, &mpUberBufferActive, mpMirrorBufferActive);\n\n        \n        // Pressed button quads\n        // left\n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 0*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y, (float) mpButtonPressedSizeList[0].width, (float) mpButtonPressedSizeList[0].height, mpUVCoords_pressed[2*0], mpUVCoords_pressed[2*0+1] );\n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 1*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y+mSmallestTopSizePressed, (float) mpButtonPressedSizeList[1].width, (float) middleHeight, mpUVCoords_pressed[2*1], mpUVCoords_pressed[2*1+1] );\n        mpButtonPressedSizeList[1].height = middleHeight;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 2*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y+mSmallestTopSizePressed+middleHeight, (float) mpButtonPressedSizeList[2].width, (float) mpButtonPressedSizeList[2].height, mpUVCoords_pressed[2*2], mpUVCoords_pressed[2*2+1] );\n\n        // middle\n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 3*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed, (float)mButtonDimensions.y, (float) middleWidth, (float) mpButtonPressedSizeList[3].height, mpUVCoords_pressed[2*3], mpUVCoords_pressed[2*3+1] );\n        mpButtonPressedSizeList[3].width = middleWidth;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 4*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed, (float)mButtonDimensions.y+mSmallestTopSizePressed, (float) middleWidth, (float) middleHeight, mpUVCoords_pressed[2*4], mpUVCoords_pressed[2*4+1] );\n        mpButtonPressedSizeList[4].width = middleWidth;\n        mpButtonPressedSizeList[4].height = middleHeight;        \n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 5*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed, (float)mButtonDimensions.y+mSmallestTopSizePressed+middleHeight, (float) middleWidth, (float) mpButtonPressedSizeList[5].height, mpUVCoords_pressed[2*5], mpUVCoords_pressed[2*5+1] );\n        mpButtonPressedSizeList[5].width = middleWidth;\n\n        // right\n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 6*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed+middleWidth, (float)mButtonDimensions.y, (float) mpButtonPressedSizeList[6].width, (float) mpButtonPressedSizeList[6].height, mpUVCoords_pressed[2*6], mpUVCoords_pressed[2*6+1] );\n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 7*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed+middleWidth, (float)mButtonDimensions.y+mSmallestTopSizePressed, (float) mpButtonPressedSizeList[7].width, (float) middleHeight, mpUVCoords_pressed[2*7], mpUVCoords_pressed[2*7+1] );\n        mpButtonPressedSizeList[7].height = middleHeight;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, 8*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed+middleWidth, (float)mButtonDimensions.y+mSmallestTopSizePressed+middleHeight, (float) mpButtonPressedSizeList[8].width, (float) mpButtonPressedSizeList[8].height, mpUVCoords_pressed[2*8], mpUVCoords_pressed[2*8+1] );\n\n\n        // Disabled button quads\n        // left\n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 0*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y, (float) mpButtonDisabledSizeList[0].width, (float) mpButtonDisabledSizeList[0].height, mpUVCoords_disabled[2*0], mpUVCoords_disabled[2*0+1] );\n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 1*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y+mSmallestTopSizePressed, (float) mpButtonDisabledSizeList[1].width, (float) middleHeight, mpUVCoords_disabled[2*1], mpUVCoords_disabled[2*1+1] );\n        mpButtonDisabledSizeList[1].height = middleHeight;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 2*6, (float)mButtonDimensions.x, (float)mButtonDimensions.y+mSmallestTopSizePressed+middleHeight, (float) mpButtonDisabledSizeList[2].width, (float) mpButtonDisabledSizeList[2].height, mpUVCoords_disabled[2*2], mpUVCoords_disabled[2*2+1] );\n\n        // middle\n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 3*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed, (float)mButtonDimensions.y, (float) middleWidth, (float) mpButtonDisabledSizeList[3].height, mpUVCoords_disabled[2*3], mpUVCoords_disabled[2*3+1] );\n        mpButtonDisabledSizeList[3].width = middleWidth;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 4*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed, (float)mButtonDimensions.y+mSmallestTopSizePressed, (float) middleWidth, (float) middleHeight, mpUVCoords_disabled[2*4], mpUVCoords_disabled[2*4+1] );\n        mpButtonDisabledSizeList[4].width = middleWidth;\n        mpButtonDisabledSizeList[4].height = middleHeight;        \n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 5*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed, (float)mButtonDimensions.y+mSmallestTopSizePressed+middleHeight, (float) middleWidth, (float) mpButtonDisabledSizeList[5].height, mpUVCoords_disabled[2*5], mpUVCoords_disabled[2*5+1] );\n        mpButtonDisabledSizeList[5].width = middleWidth;\n\n        // right\n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 6*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed+middleWidth, (float)mButtonDimensions.y, (float) mpButtonDisabledSizeList[6].width, (float) mpButtonDisabledSizeList[6].height, mpUVCoords_disabled[2*6], mpUVCoords_disabled[2*6+1] );\n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 7*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed+middleWidth, (float)mButtonDimensions.y+mSmallestTopSizePressed, (float) mpButtonDisabledSizeList[7].width, (float) middleHeight, mpUVCoords_disabled[2*7], mpUVCoords_disabled[2*7+1] );\n        mpButtonDisabledSizeList[7].height = middleHeight;\n        AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 8*6, (float)mButtonDimensions.x+mSmallestLeftSizePressed+middleWidth, (float)mButtonDimensions.y+mSmallestTopSizePressed+middleHeight, (float) mpButtonDisabledSizeList[8].width, (float) mpButtonDisabledSizeList[8].height, mpUVCoords_disabled[2*8], mpUVCoords_disabled[2*8+1] );\n                        \n        // Mark this control as 'dirty' for drawing and inform the gui system that\n        // it needs to re-calculate it's drawing buffer\n        mControlGraphicsDirty = true;        \n    }\n\n    return CPUT_SUCCESS;\n}\n\n\n\n// This generates a quad with the supplied coordinates/uv's/etc.\n//------------------------------------------------------------------------\nvoid CPUTButton::AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer, \n    int index, \n    float x, \n    float y, \n    float w, \n    float h, \n    float3 uv1, \n    float3 uv2 )\n{\n    CPUTColor4 color;\n    color.r = 1.0f;color.g = 1.0f;color.b = 1.0f;color.a = 1.0f;\n    pMirrorBuffer[index+0].Pos = float3( x + 0.0f, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+0].UV = float2(uv1.x, uv1.y);\n    pMirrorBuffer[index+0].Color = color;\n\n    pMirrorBuffer[index+1].Pos = float3( x + w, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+1].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[index+1].Color = color;\n\n    pMirrorBuffer[index+2].Pos = float3( x + 0.0f, y + h, 1.0f);\n    pMirrorBuffer[index+2].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[index+2].Color = color;\n\n    pMirrorBuffer[index+3].Pos = float3( x + w, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+3].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[index+3].Color = color;\n\n    pMirrorBuffer[index+4].Pos = float3( x + w, y + h, 1.0f);\n    pMirrorBuffer[index+4].UV = float2(uv2.x, uv2.y);\n    pMirrorBuffer[index+4].Color = color;\n\n    pMirrorBuffer[index+5].Pos = float3( x + 0.0f, y +h, 1.0f);\n    pMirrorBuffer[index+5].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[index+5].Color = color;\n}\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTButton.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTBUTTON_H__\n#define __CPUTBUTTON_H__\n\n#include \"CPUTControl.h\"\n#include <string.h>\n#include \"CPUTGuiController.h\"\n\n// forward declarations\nclass CPUTFont;\nclass CPUTText;\n\n// default padding between controls\n#define CPUT_BUTTON_TEXT_BORDER_PADDING_X 15\n#define CPUT_BUTTON_TEXT_BORDER_PADDING_Y 5\n\ntypedef enum CPUTButtonState\n{\n    CPUT_BUTTON_NEUTRAL,\n    CPUT_BUTTON_PRESSED,\n} CPUTButtonState;\n\nconst int CPUT_NUM_IMAGES_IN_BUTTON=9;\nconst int CPUT_NUM_VERTS_IN_BUTTON_QUAD=6;\n\n// Button base - common functionality for the control\n//-----------------------------------------------------------------------------\nclass CPUTButton:public CPUTControl\n{\npublic:\n    // constructors\n    CPUTButton(CPUTButton& copy); // don't allow copy construction\n    CPUTButton(const cString ControlText, CPUTControlID id, CPUTFont *pFont);\n    virtual ~CPUTButton();\n\n    // CPUTControl\n    virtual void GetPosition(int &x, int &y);\n    virtual void GetDimensions(int &width, int &height);\n    virtual bool ContainsPoint(int x, int y);\n    virtual void SetPosition(int x, int y);    \n    virtual void SetText(const cString String);\n    virtual void GetText(cString &String);\n    virtual unsigned int GetOutputVertexCount();\n    virtual void SetEnable(bool in_bEnabled);\n    \n    //CPUTEventHandler\n    virtual CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key);\n    virtual CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n      \n    // Register assets\n    static CPUTResult RegisterStaticResources();\n    static CPUTResult UnRegisterStaticResources();\n\n    CPUTResult RegisterInstanceResources();\n    CPUTResult UnRegisterInstanceResources();\n\n    // draw\n    virtual void DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize, CPUTGUIVertex *pTextVertexBufferMirror, UINT *pTextInsertIndex, UINT MaxTextVertexBufferSize);\n        \nprotected:\n    CPUT_RECT mButtonDimensions;\n    CPUTButtonState mButtonState;\n\n    // helper functions\n    // control state\n    bool mbMouseInside;\n    bool mbStartedClickInside;\n    CPUTFont *mpFont;\n    \n    // Static resources\n    static bool mStaticRegistered;\n\n    // sizes of unmodified button graphics\n    static CPUT_SIZE mpButtonIdleImageSizeList[CPUT_NUM_IMAGES_IN_BUTTON];\n    static CPUT_SIZE mpButtonPressedImageSizeList[CPUT_NUM_IMAGES_IN_BUTTON];\n    static CPUT_SIZE mpButtonDisabledImageSizeList[CPUT_NUM_IMAGES_IN_BUTTON];\n    \n\n\n    static int mSmallestLeftSizeIdle;\n    static int mSmallestRightSizeIdle;\n    static int mSmallestTopSizeIdle;\n    static int mSmallestBottomSizeIdle;\n\n    static int mSmallestLeftSizePressed;\n    static int mSmallestRightSizePressed;\n    static int mSmallestTopSizePressed;\n    static int mSmallestBottomSizePressed;\n\n    static int mSmallestLeftSizeDisabled;\n    static int mSmallestRightSizeDisabled;\n    static int mSmallestTopSizeDisabled;\n    static int mSmallestBottomSizeDisabled;\n\n    \n    // per-instance information\n    CPUTText *mpButtonText;\n    CPUT_SIZE mpButtonIdleSizeList[CPUT_NUM_IMAGES_IN_BUTTON];\n    CPUT_SIZE mpButtonPressedSizeList[CPUT_NUM_IMAGES_IN_BUTTON];\n    CPUT_SIZE mpButtonDisabledSizeList[CPUT_NUM_IMAGES_IN_BUTTON];\n\n    CPUTGUIVertex *mpMirrorBufferActive;\n    CPUTGUIVertex *mpMirrorBufferPressed;\n    CPUTGUIVertex *mpMirrorBufferDisabled;\n\n    // helper functions   \n    void InitializeState();\n    void SetDimensions(int width, int height);\n    CPUTResult Resize(int width, int height);\n    void AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer, int index, float x, float y, float w, float h, float3 uv1, float3 uv2 );\n    void GetInsetTextCoordinate(int &x, int &y);\n\n\n};\n\n#endif //#ifndef __CPUTBUTTON_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTCallbackHandler.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTCALLBACKHANDLER_H__\n#define __CPUTCALLBACKHANDLER_H__\n\n#include \"CPUT.h\"\n#include \"CPUTControl.h\"\n\n//forward declarations\nclass CPUTControl;\ntypedef unsigned int UINT;\ntypedef UINT CPUTControlID;\ntypedef UINT CPUTEventID;\n#define UNREFERENCED_PARAMETER(P) (P)\n\nclass CPUTCallbackHandler\n{\npublic:\n    virtual void HandleCallbackEvent( CPUTEventID Event, CPUTControlID ControlID, CPUTControl *pControl ) {UNREFERENCED_PARAMETER(Event);UNREFERENCED_PARAMETER(ControlID);UNREFERENCED_PARAMETER(pControl);}\n};\n\n\n#endif // #ifndef __CPUTCALLBACKHANDLER_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTCamera.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTCamera.h\"\n#include \"CPUTFrustum.h\"\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTCamera::CPUTCamera() : \n    mFov(45.0f * 3.14159265f/180.0f),\n    mNearPlaneDistance(1.0f),\n    mFarPlaneDistance(100.0f),\n    mAspectRatio(16.0f/9.0f)\n{\n    // default maya position (roughly)\n    SetPosition( 1.0f, 0.8f, 1.0f );\n}\n\n// Load\n//-----------------------------------------------------------------------------\nCPUTResult CPUTCamera::LoadCamera(CPUTConfigBlock *pBlock, int *pParentID)\n{\n    // TODO: Have render node load common properties.\n    CPUTResult result = CPUT_SUCCESS;\n\n    mName = pBlock->GetValueByName(_L(\"name\"))->ValueAsString();\n    *pParentID = pBlock->GetValueByName(_L(\"parent\"))->ValueAsInt();\n\n    mFov = pBlock->GetValueByName(_L(\"FieldOfView\"))->ValueAsFloat();\n    mFov *= (3.14159265f/180.0f);\n    mNearPlaneDistance = pBlock->GetValueByName(_L(\"NearPlane\"))->ValueAsFloat();\n    mFarPlaneDistance = pBlock->GetValueByName(_L(\"FarPlane\"))->ValueAsFloat();\n\n    LoadParentMatrixFromParameterBlock( pBlock );\n\n    return result;\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTCamera::SetAspectRatio(const float aspectRatio)\n{\n    mAspectRatio = aspectRatio;\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTCamera::LookAt( float xx, float yy, float zz )\n{\n    float3 pos;\n    GetPosition( &pos);\n\n    float3 lookPoint(xx, yy, zz);\n    float3 look  = (lookPoint - pos).normalize();\n    float3 right = cross3(float3(0.0f,1.0f,0.0f), look).normalize(); // TODO: simplicy algebraically\n    float3 up    = cross3(look, right);\n    \n    mParentMatrix = float4x4(\n        right.x, right.y, right.z, 0.0f,\n           up.x,    up.y,    up.z, 0.0f,\n         look.x,  look.y,  look.z, 0.0f,\n          pos.x,   pos.y,   pos.z, 1.0f\n    );\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTCamera::SetFov(const float fov)\n{\n    mFov = fov;\n}\n\n#define KEY_DOWN(vk) ((GetAsyncKeyState(vk) & 0x8000)?1:0)\n//-----------------------------------------------------------------------------\nvoid CPUTCameraControllerFPS::Update(float deltaSeconds)\n{\n    float speed = mfMoveSpeed * deltaSeconds;\n    speed *= KEY_DOWN( VK_LSHIFT ) ? 10.0f : KEY_DOWN( VK_LCONTROL) ? 0.1f : 1.0f;\n\n    float4x4 *pParentMatrix = mpCamera->GetParentMatrix();\n\n    float3 vRight(pParentMatrix->getXAxis());\n    float3 vUp(pParentMatrix->getYAxis());\n    float3 vLook(pParentMatrix->getZAxis());\n    float3 vPositionDelta(0.0f);\n\n    if(CPUTOSServices::GetOSServices()->DoesWindowHaveFocus())\n    {\n        if(KEY_DOWN('W')) { vPositionDelta +=  vLook *  speed;}\n        if(KEY_DOWN('A')) { vPositionDelta += vRight * -speed;}\n        if(KEY_DOWN('S')) { vPositionDelta +=  vLook * -speed;}\n        if(KEY_DOWN('D')) { vPositionDelta += vRight *  speed;}\n        if(KEY_DOWN('E')) { vPositionDelta +=    vUp *  speed;}\n        if(KEY_DOWN('Q')) { vPositionDelta +=    vUp * -speed;}\n    }\n    float x,y,z;\n    mpCamera->GetPosition( &x, &y, &z );\n    mpCamera->SetPosition( x+vPositionDelta.x, y+vPositionDelta.y, z+vPositionDelta.z );\n    mpCamera->Update();\n}\n\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode CPUTCameraControllerFPS::HandleMouseEvent(\n    int x,\n    int y,\n    int wheel,\n    CPUTMouseState state\n)\n{\n    if(state & CPUT_MOUSE_LEFT_DOWN)\n    {\n        float3 position = mpCamera->GetPosition();\n\n        if(!(mPrevFrameState & CPUT_MOUSE_LEFT_DOWN)) // Mouse was just clicked\n        {\n            mnPrevFrameX = x;\n            mnPrevFrameY = y;\n        }\n\n        float nDeltaX = (float)(x-mnPrevFrameX);\n        float nDeltaY = (float)(y-mnPrevFrameY);\n\n        float4x4 rotationX = float4x4RotationX(nDeltaY*mfLookSpeed);\n        float4x4 rotationY = float4x4RotationY(nDeltaX*mfLookSpeed);\n\n        mpCamera->SetPosition(0.0f, 0.0f, 0.0f); // Rotate about camera center\n        float4x4 parent      = *mpCamera->GetParentMatrix();\n        float4x4 orientation = rotationX  *parent * rotationY;\n        orientation.orthonormalize();\n        mpCamera->SetParentMatrix( orientation );\n        mpCamera->SetPosition( position.x, position.y, position.z ); // Move back to original position\n        mpCamera->Update();\n\n        mnPrevFrameX = x;\n        mnPrevFrameY = y;\n        mPrevFrameState = state;\n        return CPUT_EVENT_HANDLED;\n    } else\n    {\n        mPrevFrameState = state;\n        return CPUT_EVENT_UNHANDLED;\n    }\n}\n\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode CPUTCameraControllerArcBall::HandleMouseEvent(\n    int x,\n    int y,\n    int wheel,\n    CPUTMouseState state\n)\n{\n    // TODO: We want move-in-x to orbit light in view space, not object space.\n\n    if(state & CPUT_MOUSE_RIGHT_DOWN) // TODO: How to make this flexible?  Want to choose which mouse button has effect.\n    {\n        float4x4  rotationX, rotationY;\n\n        if(!(mPrevFrameState & CPUT_MOUSE_RIGHT_DOWN)) // Mouse was just clicked\n        {\n            mnPrevFrameX = x;\n            mnPrevFrameY = y;\n        }\n        int nDeltaX = x-mnPrevFrameX;\n        int nDeltaY = y-mnPrevFrameY;\n\n        rotationY = float4x4RotationX(nDeltaY*mfLookSpeed);\n        rotationX = float4x4RotationY(nDeltaX*mfLookSpeed);\n        float4x4 orientation = *mpCamera->GetParentMatrix() * rotationY * rotationX;\n\n        orientation.orthonormalize();\n        mpCamera->SetParentMatrix( orientation );\n\n        mnPrevFrameX = x;\n        mnPrevFrameY = y;\n        mPrevFrameState = state;\n        return CPUT_EVENT_HANDLED;\n    } else\n    {\n        mPrevFrameState = state;\n        return CPUT_EVENT_UNHANDLED;\n    }\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTCamera.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTCamera_H__\n#define __CPUTCamera_H__\n\n#include <memory.h>\n#include <Windows.h>\n#include \"CPUT.h\"\n#include \"CPUTRenderNode.h\"\n#include \"CPUTConfigBlock.h\"\n#include \"CPUTFrustum.h\"\n\n//-----------------------------------------------------------------------------\nclass CPUTCamera:public CPUTRenderNode\n{\nprotected:\n    float mFov;                // the field of view in degrees\n    float mNearPlaneDistance;  // near plane distance\n    float mFarPlaneDistance;   // far plane distance\n    float mAspectRatio;        // width/height.  TODO: Support separate pixel and viewport aspect ratios\n\n    float4x4 mView;\n    float4x4 mProjection;\n\npublic:\n    CPUTFrustum mFrustum;\n\n    CPUTCamera();\n    ~CPUTCamera() {}\n\n    void Update( float deltaSeconds=0.0f ) {\n        // TODO: Do only if required (i.e. if dirty)\n        mProjection = float4x4PerspectiveFovLH( mFov, mAspectRatio, mFarPlaneDistance, mNearPlaneDistance );\n        mView = inverse(*GetWorldMatrix());\n        mFrustum.InitializeFrustum(this);\n    };\n\n    CPUTResult LoadCamera(CPUTConfigBlock *pBlock, int *pParentID);\n\n    float4x4 *GetViewMatrix(void)\n    {\n        // Update();  We can't afford to do this every time we're asked for the view matrix.  Caller needs to make sure camera is updated before entering render loop.\n        return &mView;\n    }\n\n    const float4x4* GetProjectionMatrix(void) const { return &mProjection; }\n    void            SetProjectionMatrix(const float4x4 &projection) { mProjection = projection; }\n    float           GetAspectRatio() { return mAspectRatio; }\n    float           GetFov() { return mFov; }\n    void            SetAspectRatio(const float aspectRatio);\n    void            SetFov( const float fov );\n    float           GetNearPlaneDistance() { return mNearPlaneDistance; }\n    float           GetFarPlaneDistance() {  return mFarPlaneDistance; }\n    void            SetNearPlaneDistance( const float nearPlaneDistance ) { mNearPlaneDistance = nearPlaneDistance; }\n    void            SetFarPlaneDistance(  const float farPlaneDistance ) { mFarPlaneDistance = farPlaneDistance; }\n    void            LookAt( float xx, float yy, float zz );\n};\n\n//-----------------------------------------------------------------------------\nclass CPUTCameraController : public CPUTEventHandler\n{\nprotected:\n    CPUTRenderNode *mpCamera;\n    float           mfMoveSpeed;\n    float           mfLookSpeed;\n    int             mnPrevFrameX;\n    int             mnPrevFrameY;\n    CPUTMouseState  mPrevFrameState;\n\npublic:\n    CPUTCameraController()\n        : mpCamera(NULL)\n        , mnPrevFrameX(0)\n        , mnPrevFrameY(0)\n        , mfMoveSpeed(1.0f)\n        , mfLookSpeed(1.0f)\n    {\n    }\n    ~CPUTCameraController(){ SAFE_RELEASE(mpCamera);}\n    void            SetCamera(CPUTRenderNode *pCamera)  { SAFE_RELEASE(mpCamera); mpCamera = pCamera; pCamera->AddRef(); }\n    CPUTRenderNode *GetCamera(void) const               { return mpCamera; }\n    void            SetMoveSpeed(float speed)           { mfMoveSpeed = speed; }\n    void            SetLookSpeed(float speed)           { mfLookSpeed = speed; }\n    virtual void    Update(float deltaSeconds=0.0f) = 0;\n};\n\n// TODO: Move these implementations to the .cpp file.\n//-----------------------------------------------------------------------------\nclass CPUTCameraControllerFPS : public CPUTCameraController\n{\npublic:\n    void Update( float deltaSeconds=0.0f);\n    // TODO: Change to Update(deltaSeconds) and IsKeyDown()\n    CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key) { return CPUT_EVENT_UNHANDLED; }\n    CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n};\n\n//-----------------------------------------------------------------------------\nclass CPUTCameraControllerArcBall : public CPUTCameraController\n{\npublic:\n    void Update( float deltaSeconds=0.0f ) {}\n    CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key) { return CPUT_EVENT_UNHANDLED; }\n    CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n};\n\n#endif //#ifndef __CPUTCamera_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTCheckbox.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTCheckbox.h\"\n#include \"CPUTGuiController.h\"\n#include \"CPUTText.h\"\n\nCPUT_SIZE CPUTCheckbox::mpCheckboxTextureSizeList[CPUT_CHECKBOX_NUM_IMAGES_IN_CHECKBOX] = { {0,0},{0,0},{0,0} };\n\n// texture atlas information\nfloat gAtlasWidthCheckbox = 256.0f;\nfloat gAtlasHeightCheckbox = 64.0f;\n\n// Pixel coordinates of the active-idle button image within the texture atlas\nint gUVLocationsCheckbox_active[] = { \n    109,3,  // tl\n\t124,3,  // tr\n\t109,17, // bl\n\t124,17  // br  \n};\n\n// Pixel coordinates of the pressed button image within the texture atlas\nint gUVLocationsCheckbox_pressed[] = { \n    109,20, // tl\n\t124,20, // tr\n\t109,35, // bl\n\t124,35  // br\n};\n\n// Pixel coordinates of the disabled button image within the texture atlas\nint gUVLocationsCheckbox_disabled[] = { \n    109,39, // tl\n\t124,39, // tr\n\t109,54, // bl\n\t124,54  // br\n};\n\n// Floating point 0.0f - 1.0f UV coordinates in the texture atlas for each corner of the image\nfloat3 mpUVCoordsCheckbox_active[4];\nfloat3 mpUVCoordsCheckbox_pressed[4];\nfloat3 mpUVCoordsCheckbox_disabled[4];\n\n\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTCheckbox::CPUTCheckbox(const cString ControlText, CPUTControlID id, CPUTFont *pFont):\n    mbMouseInside(false),\n    mbStartedClickInside(false),\n    mVertexStride(0),\n    mVertexOffset(0),\n    mpCheckboxText(NULL),\n    mpFont(pFont)\n{\n    // initialize the state variables\n    InitialStateSet();\n\n    // save the control ID for callbacks\n    mcontrolID = id;\n\n    // store the font to be used by this control\n    mpFont = pFont;\n\n    // set as enabled\n    CPUTControl::SetEnable(true);\n\n    // register all the instance resources\n    RegisterInstanceResources();\n\n    // set the control's text string\n    SetText(ControlText);\n}\n\n// Initial state of the control's member variables\n//-----------------------------------------------------------------------------\nvoid CPUTCheckbox::InitialStateSet()\n{\n    // state\n    mcontrolType = CPUT_CHECKBOX;\n    mControlState = CPUT_CONTROL_ACTIVE;\n    mCheckboxState = CPUT_CHECKBOX_UNCHECKED;\n    mCheckboxGuiState = CPUT_CHECKBOX_GUI_NEUTRAL;\n\n    // control ID\n    mcontrolID = 0;\n\n    // size\n    mControlDimensions.x=0;\n    mControlDimensions.y=0;\n    mControlDimensions.height=0;\n    mControlDimensions.width=0;\n\n    // default label\n    SetText(_L(\"checkbox\"));\n}\n\n// Destructor\n//------------------------------------------------------------------------------\nCPUTCheckbox::~CPUTCheckbox()\n{\n    UnRegisterInstanceResources();\n}\n\n// Get the x/y window position of this control\n//-----------------------------------------------------------------------------\nvoid CPUTCheckbox::GetPosition(int &x, int &y)\n{\n    x = mControlDimensions.x;\n    y = mControlDimensions.y;\n}\n\n\n// Get checkbox selection state\n//-----------------------------------------------------------------------------\nCPUTCheckboxState CPUTCheckbox::GetCheckboxState()\n{\n    return mCheckboxState;\n}\n\n// Set checkbox selection state\n//-----------------------------------------------------------------------------\nvoid CPUTCheckbox::SetCheckboxState(CPUTCheckboxState State)\n{\n    // if state changed, save it, and recalculate the control\n    if(State != mCheckboxState)\n    {\n        mCheckboxState = State;\n        Recalculate();\n    }\n}\n\n// Returns the number of quads needed to draw this control\n//--------------------------------------------------------------------------------\nunsigned int CPUTCheckbox::GetOutputVertexCount()\n{\n    // A checkbox is always made of 1 quad.\n    //\n    //   ---\n    //  | 1 |            \n    //   ---\n    // Calculation: 3 quads/triangle * 2 triangles/quad * 1 quad\n\n    return 3*2;\n}\n\n\n\n\n\n\n\n// Register assets\n//-----------------------------------------------------------------------------\nCPUTResult CPUTCheckbox::RegisterStaticResources()\n{\n    // calculate the floating point, 0.0f - 1.0f, UV coordinates of each of the 9 images that\n    // make up a button.  Do this for the active, pressed, and disabled states.\n    for(int ii=0; ii<4; ii++)\n    {\n        mpUVCoordsCheckbox_active[ii].x = gUVLocationsCheckbox_active[2*ii]/gAtlasWidthCheckbox;\n        mpUVCoordsCheckbox_active[ii].y = gUVLocationsCheckbox_active[2*ii+1]/gAtlasHeightCheckbox;\n\n        mpUVCoordsCheckbox_pressed[ii].x = gUVLocationsCheckbox_pressed[2*ii]/gAtlasWidthCheckbox;\n        mpUVCoordsCheckbox_pressed[ii].y = gUVLocationsCheckbox_pressed[2*ii+1]/gAtlasHeightCheckbox;\n\n        mpUVCoordsCheckbox_disabled[ii].x = gUVLocationsCheckbox_disabled[2*ii]/gAtlasWidthCheckbox;\n        mpUVCoordsCheckbox_disabled[ii].y = gUVLocationsCheckbox_disabled[2*ii+1]/gAtlasHeightCheckbox;\n    }\n\n\n\n    // calculate the width/height in pixels of each of the image slices\n    // that makes up the checkbox images\n    mpCheckboxTextureSizeList[0].width = gUVLocationsCheckbox_active[2] - gUVLocationsCheckbox_active[0];\n    mpCheckboxTextureSizeList[0].height = gUVLocationsCheckbox_active[5] - gUVLocationsCheckbox_active[1];\n\n    mpCheckboxTextureSizeList[1].width = gUVLocationsCheckbox_pressed[2] - gUVLocationsCheckbox_pressed[0];\n    mpCheckboxTextureSizeList[1].height = gUVLocationsCheckbox_pressed[5] - gUVLocationsCheckbox_pressed[1];\n\n    mpCheckboxTextureSizeList[2].width = gUVLocationsCheckbox_disabled[2] - gUVLocationsCheckbox_disabled[0];\n    mpCheckboxTextureSizeList[2].height = gUVLocationsCheckbox_disabled[5] - gUVLocationsCheckbox_disabled[1];\n\n    return CPUT_SUCCESS;\n}\n\n// Release all static resources - only do this if NO more checkbox controls\n// are used anywhere on the system\n//-----------------------------------------------------------------------------\nCPUTResult CPUTCheckbox::UnRegisterStaticResources()\n{\n    return CPUT_SUCCESS;\n}\n\n// Register any per-instance resources for this checkbox\n//-----------------------------------------------------------------------------\nCPUTResult CPUTCheckbox::RegisterInstanceResources()\n{\n    return CPUT_SUCCESS;\n}\n\n// Unregister the checkbox's instance resources\n//-----------------------------------------------------------------------------\nCPUTResult CPUTCheckbox::UnRegisterInstanceResources()\n{\n    // delete the static text object\n    SAFE_DELETE(mpCheckboxText);\n\n    return CPUT_SUCCESS;\n}\n\n//CPUTEventHandler\n// Handle keyboard events - none for this control\n//--------------------------------------------------------------------------------\nCPUTEventHandledCode CPUTCheckbox::HandleKeyboardEvent(CPUTKey key)\n{\n    UNREFERENCED_PARAMETER(key);\n    return CPUT_EVENT_UNHANDLED;\n}\n\n// Handle mouse events\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode CPUTCheckbox::HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state)\n{\n    UNREFERENCED_PARAMETER(wheel);\n    CPUTEventHandledCode handledCode = CPUT_EVENT_UNHANDLED;\n\n    if((CPUT_CONTROL_INACTIVE == mControlState) || (false == mControlVisible) )\n    {\n        mbMouseInside = false;\n        return handledCode;\n    }\n\n    // if we're continuing to be pressed, move around with the mouse movement\n    //(CPUT_CONTROL_PRESSED == mControlState )\n\n    if( (CPUT_CHECKBOX_GUI_PRESSED == mCheckboxGuiState) && (CPUT_MOUSE_LEFT_DOWN == state))\n    {\n        return CPUT_EVENT_HANDLED;\n    }\n\n    // handle events occuring in the control\n    if( ContainsPoint(x,y) )\n    {\n        // did we start our click inside the button?\n        if((state & CPUT_MOUSE_LEFT_DOWN) && (true == mbMouseInside))\n        {\n            mbStartedClickInside = true;\n            mCheckboxGuiState = CPUT_CHECKBOX_GUI_PRESSED;\n            handledCode = CPUT_EVENT_HANDLED;\n\n            // tell gui system this control image is now dirty\n            // and needs to rebuild it's draw list\n            mControlGraphicsDirty = true;\n        }\n\n        // did they click inside the button?\n        if(!(state & CPUT_MOUSE_LEFT_DOWN) && (true == mbStartedClickInside) && (CPUT_CHECKBOX_GUI_PRESSED == mCheckboxGuiState))\n        {\n            // set the GUI/mouse controller states\n            handledCode = CPUT_EVENT_HANDLED;\n            mCheckboxGuiState = CPUT_CHECKBOX_GUI_NEUTRAL;\n\n            // toggle the checkbox state\n            if(CPUT_CHECKBOX_UNCHECKED == mCheckboxState)\n            {\n                mCheckboxState = CPUT_CHECKBOX_CHECKED;\n            }\n            else if(CPUT_CHECKBOX_CHECKED == mCheckboxState)\n            {\n                mCheckboxState = CPUT_CHECKBOX_UNCHECKED;\n            }\n\n            // trigger the users callback\n            mpCallbackHandler->HandleCallbackEvent(1, mcontrolID, (CPUTControl*) this);\n\n            // tell gui system this control image is now dirty\n            // and needs to rebuild it's draw list    \n            mControlGraphicsDirty = true;\n        }\n        if(!(state & CPUT_MOUSE_LEFT_DOWN))\n        {\n            mbMouseInside = true;\n        }\n    }\n    else\n    {\n        // we left the button\n        mbMouseInside = false;\n        mCheckboxGuiState = CPUT_CHECKBOX_GUI_NEUTRAL;\n        mbStartedClickInside = false;\n    }\n\n    return handledCode;\n}\n\n//CPUTControl\n// set the upper-left position of the checkbox control (screen space coords)\n//-----------------------------------------------------------------------------\nvoid CPUTCheckbox::SetPosition(int x, int y)\n{\n    // set the new position\n    mControlDimensions.x = x;\n    mControlDimensions.y = y;\n\n    // recalculate the vertex buffer with new x/y coords\n    Recalculate();\n\n    // move the static text along with the bitmap graphic\n    int textX, textY;\n    GetTextPosition(textX, textY);\n    mpCheckboxText->SetPosition(textX, textY);\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTCheckbox::GetDimensions(int &width, int &height)\n{\n    CalculateBounds();\n    width = mControlDimensions.width;\n    height = mControlDimensions.height;\n}\n\n// Get the text label on this checkbox\n//--------------------------------------------------------------------------------\nvoid CPUTCheckbox::GetText(cString &TextString)\n{\n    if(mpCheckboxText)\n    {\n        mpCheckboxText->GetString(TextString);\n    }\n}\n\n// Sets the text label on this checkbox\n//--------------------------------------------------------------------------------\nvoid CPUTCheckbox::SetText(const cString String)\n{\n    // create the static text object if it doesn't exist\n    if(NULL == mpCheckboxText)\n    {\n        mpCheckboxText = new CPUTText(mpFont);\n    }\n\n    // set the static control's text\n    mpCheckboxText->SetText(String);\n\n    // move the text to the right spot\n    int x,y;\n    GetTextPosition(x,y);\n    mpCheckboxText->SetPosition(x, y);\n\n    // position or size may move - force a recalculation of this control's location\n    // if it is managed by the auto-arrange function\n    if(this->IsAutoArranged())\n    {\n         mControlNeedsArrangmentResizing = true;\n    }\n    else\n    {\n        // control graphics have been updated\n        mControlGraphicsDirty = true;\n    }\n}\n\n// Enable/disable the control\n//--------------------------------------------------------------------------------\nvoid CPUTCheckbox::SetEnable(bool in_bEnabled)\n{\n    // chain to CPUTControl \n    CPUTControl::SetEnable(in_bEnabled);\n\n    // set the control's text to match\n    mpCheckboxText->SetEnable(in_bEnabled);\n\n    // recalculate control's quads \n    Recalculate();\n}\n\n// With the given window x/y coordinate, is that point in this control\n//-----------------------------------------------------------------------------\nbool CPUTCheckbox::ContainsPoint(int x, int y)\n{   \n    if( (x>mControlDimensions.x) && (y>mControlDimensions.y) &&\n        (x< (mControlDimensions.x+mControlDimensions.width)) && (y< (mControlDimensions.y+mControlDimensions.height))\n        )\n    {\n        return true;\n    }\n\n    return false;\n}\n\n// Calculate the bounding rectangle for the control\n// For the checkbox it includes the checkbox image and the text\n//-----------------------------------------------------------------------------\nvoid CPUTCheckbox::CalculateBounds()\n{\n    int textX, textY;\n    int textWidth, textHeight;\n\n    // get the text\n    GetTextPosition(textX, textY);\n    mpCheckboxText->GetDimensions(textWidth, textHeight);\n\n    mControlDimensions.width = (textX - mControlDimensions.x ) + textWidth;\n    mControlDimensions.height = textHeight;\n\n    if(mpCheckboxTextureSizeList[0].height > textHeight)\n    {\n        mControlDimensions.height = mpCheckboxTextureSizeList[0].height;\n    }\n}\n\n// Calculate the correct location to place the text label - usually to the \n// right of the image allowing for spacing/image/etc\n//--------------------------------------------------------------------------------\nvoid CPUTCheckbox::GetTextPosition(int &x, int &y)\n{\n    // get the dimensions of the string in pixels\n    CPUT_RECT TextRect;\n    mpCheckboxText->GetDimensions(TextRect.width, TextRect.height);\n\n    // calculate a good spot for the text to be in relation to the checkbox bitmap\n    x = mControlDimensions.x + mpCheckboxTextureSizeList[0].width + CPUT_CHECKBOX_PADDING; // move right far enough not to overlap the bitmap\n    y = mControlDimensions.y + mpCheckboxTextureSizeList[0].height - TextRect.height;  // try to center text top-to-bottom\n}\n\n\n// 'Draw' this control into the supplied vertex buffer object\n//--------------------------------------------------------------------------------\nvoid CPUTCheckbox::DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize, CPUTGUIVertex *pTextVertexBufferMirror, UINT *pTextInsertIndex, UINT MaxTextVertexBufferSize)\n{\n    if(!mControlVisible)\n    {\n        return;\n    }\n\n    if((NULL==pVertexBufferMirror) || (NULL==pInsertIndex))\n    {\n        return;\n    }\n\n    // Do we have enough room to put this control into the output buffer?\n    int VertexCopyCount = GetOutputVertexCount();\n    ASSERT( (pMaxBufferSize >= *pInsertIndex + VertexCopyCount), _L(\"Too many CPUT GUI controls for allocated GUI buffer. Allocated GUI vertex buffer is too small.\\n\\nIncrease CPUT_GUI_BUFFER_SIZE size.\") );\n\n    switch(mControlState)\n    {\n    case CPUT_CONTROL_ACTIVE:\n        // copy the active+idle button into the stream\n        if(CPUT_CHECKBOX_UNCHECKED == mCheckboxState)\n        {\n            memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferActive, sizeof(CPUTGUIVertex)*6);\n        }        \n\n        // copy the pressed button into the stream\n        if(CPUT_CHECKBOX_CHECKED == mCheckboxState)\n        {\n            memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferPressed, sizeof(CPUTGUIVertex)*6);\n        }\n        \n        break;\n    case CPUT_CONTROL_INACTIVE:\n        // copy the inactive button into the stream\n        memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferDisabled, sizeof(CPUTGUIVertex)*6);\n        break;\n\n    default:\n        // error! unknown state\n        ASSERT(0,_L(\"CPUTCheckbox: Control is in unknown state\"));\n        return;\n    }\n\n    // move the index the correct number of floats to account\n    // for 1 new quad, each quad with 6 verts in it (and each vert with 3+2 floats in it).\n    *pInsertIndex+=6;\n\n\n    // now do the text\n    // draw the text\n    if(mpCheckboxText)\n    {\n        mpCheckboxText->DrawIntoBuffer(pTextVertexBufferMirror, pTextInsertIndex, MaxTextVertexBufferSize);\n    }\n\n    // we'll mark the control as no longer being 'dirty'\n    mControlGraphicsDirty = false;\n\n}\n\n// Recalculates the the control's image quads\n//------------------------------------------------------------------------\nvoid CPUTCheckbox::Recalculate()\n{\n    // active/idle\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, \n                            (float) mControlDimensions.x, (float) mControlDimensions.y,\n                            (float) mpCheckboxTextureSizeList[0].width, (float) mpCheckboxTextureSizeList[0].height, \n                            mpUVCoordsCheckbox_active[0], mpUVCoordsCheckbox_active[3]\n                        );\n\n    // pressed\n    AddQuadIntoMirrorBuffer(mpMirrorBufferPressed, \n                            (float) mControlDimensions.x, (float)mControlDimensions.y,\n                            (float) mpCheckboxTextureSizeList[1].width, (float) mpCheckboxTextureSizeList[1].height, \n                            mpUVCoordsCheckbox_pressed[0], mpUVCoordsCheckbox_pressed[3]\n                        );\n\n    // disabled\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, \n                            (float) mControlDimensions.x, (float) mControlDimensions.y,\n                            (float) mpCheckboxTextureSizeList[2].width, (float) mpCheckboxTextureSizeList[2].height, \n                            mpUVCoordsCheckbox_disabled[0], mpUVCoordsCheckbox_disabled[3]\n                        );\n\n    // re-calculate the bounding box for the control used for hit-testing/sizing\n    CalculateBounds();\n\n    // Mark this control as 'dirty' for drawing and inform the gui system that\n    // it needs to re-calculate it's drawing buffer\n    mControlGraphicsDirty = true;\n}\n\n// This generates a quad with the supplied coordinates/uv's/etc.\n//------------------------------------------------------------------------\nvoid CPUTCheckbox::AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer,  \n    float x, \n    float y, \n    float w, \n    float h, \n    float3 uv1, \n    float3 uv2 )\n{\n    CPUTColor4 color;\n    color.r = 1.0f;color.g = 1.0f;color.b = 1.0f;color.a = 1.0f;\n\n    pMirrorBuffer[0].Pos = float3( x + 0.0f, y + 0.0f, 1.0f);\n    pMirrorBuffer[0].UV = float2(uv1.x, uv1.y);\n    pMirrorBuffer[0].Color = color;\n\n    pMirrorBuffer[1].Pos = float3( x + w, y + 0.0f, 1.0f);\n    pMirrorBuffer[1].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[1].Color = color;\n\n    pMirrorBuffer[2].Pos = float3( x + 0.0f, y + h, 1.0f);\n    pMirrorBuffer[2].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[2].Color = color;\n\n    pMirrorBuffer[3].Pos = float3( x + w, y + 0.0f, 1.0f);\n    pMirrorBuffer[3].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[3].Color = color;\n\n    pMirrorBuffer[4].Pos = float3( x + w, y + h, 1.0f);\n    pMirrorBuffer[4].UV = float2(uv2.x, uv2.y);\n    pMirrorBuffer[4].Color = color;\n\n    pMirrorBuffer[5].Pos = float3( x + 0.0f, y +h, 1.0f);\n    pMirrorBuffer[5].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[5].Color = color;\n}"
  },
  {
    "path": "CPUT/CPUT/CPUTCheckbox.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTCHECKBOX_H__\n#define __CPUTCHECKBOX_H__\n\n#include \"CPUTControl.h\"\n#include \"CPUTGuiController.h\"\n\n// forward declarations\nclass CPUTFont;\nclass CPUTText;\n\n\ntypedef enum CPUTCheckboxState\n{\n    CPUT_CHECKBOX_UNCHECKED,\n    CPUT_CHECKBOX_CHECKED,\n} CPUTCheckboxState;\n\ntypedef enum CPUTCheckboxGUIState\n{\n    CPUT_CHECKBOX_GUI_NEUTRAL,\n    CPUT_CHECKBOX_GUI_PRESSED,\n} CPUTCheckboxGUIState;\n\nconst int CPUT_CHECKBOX_NUM_IMAGES_IN_CHECKBOX=3;\nconst int CPUT_CHECKBOX_PADDING=5;          // padding (in pixels) between checkbox image and the label\n\n// Checkbox \n//-----------------------------------------------------------------------------\nclass CPUTCheckbox:public CPUTControl\n{\npublic:\n    // button should self-register with the GuiController on create\n    CPUTCheckbox(CPUTCheckbox& copy);\n    CPUTCheckbox(const cString ControlText, CPUTControlID id, CPUTFont *pFont);\n    virtual ~CPUTCheckbox();\n\n    // CPUTControl\n    virtual void GetPosition(int &x, int &y);\n    virtual unsigned int GetOutputVertexCount();\n\n    // CPUTCheckboxDX11\n    virtual CPUTCheckboxState GetCheckboxState();\n    void SetCheckboxState(CPUTCheckboxState State);\n    \n    \n    //CPUTEventHandler\n    virtual CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key);\n    virtual CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n\n    //CPUTControl\n    virtual bool ContainsPoint(int x, int y);\n    virtual void SetPosition(int x, int y);\n    virtual void GetDimensions(int &width, int &height);\n    virtual void SetText(const cString String);\n    virtual void GetText(cString &TextString);\n    virtual void SetEnable(bool bEnabled);\n\n    // Register assets\n    static CPUTResult RegisterStaticResources();\n    static CPUTResult UnRegisterStaticResources();\n\n    CPUTResult RegisterInstanceResources();\n    CPUTResult UnRegisterInstanceResources();\n\n    // CPUTCheckboxDX11    \n    void DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize, CPUTGUIVertex *pTextVertexBufferMirror, UINT *pTextInsertIndex, UINT MaxTextVertexBufferSize);\n\n\nprotected:\n    CPUT_RECT               mControlDimensions;\n    CPUTCheckboxState       mCheckboxState;\n    CPUTCheckboxGUIState    mCheckboxGuiState;\n\n    // helper functions\n    void InitialStateSet();\n\n\n\n\n    // new for uber-buffer version\n    CPUTFont *mpFont;\n    CPUTGUIVertex mpMirrorBufferActive[6];\n    CPUTGUIVertex mpMirrorBufferPressed[6];\n    CPUTGUIVertex mpMirrorBufferDisabled[6];\n    void Recalculate();\n    void AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer, float x, float y, float w, float h, float3 uv1, float3 uv2 );\n\n\n    // static varibles used by ALL checkbox controls    \n    static CPUT_SIZE mpCheckboxTextureSizeList[CPUT_CHECKBOX_NUM_IMAGES_IN_CHECKBOX];\n\n    // GUI state\n    bool mbMouseInside;\n    bool mbStartedClickInside;\n\n    // instance variables for this particular checkbox\n    UINT mVertexStride;\n    UINT mVertexOffset;    \n    CPUTText *mpCheckboxText;\n\n    // helper functions\n    void GetTextPosition(int &x, int &y);\n    void CalculateBounds();\n\n};\n\n\n\n#endif //#ifndef __CPUTCHECKBOX_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTComputeShaderDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTComputeShaderDX11.h\"\n#include \"CPUTAssetLibraryDX11.h\"\n\nCPUTComputeShaderDX11 *CPUTComputeShaderDX11::CreateComputeShader(\n    const cString  &name,\n    ID3D11Device   *pD3dDevice,\n    const cString  &shaderMain,\n    const cString  &shaderProfile\n)\n{\n    ID3DBlob            *pCompiledBlob = NULL;\n    ID3D11ComputeShader *pNewComputeShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromFile(name, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling compute shader:\\n\\n\") );\n\n    // Create the compute shader\n    // TODO: Move to compute shader class\n    HRESULT hr = pD3dDevice->CreateComputeShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewComputeShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating compute shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetComputeShader \")+name;\n    // CPUTSetDebugName(pNewComputeShader, DebugName);\n\n    CPUTComputeShaderDX11 *pNewCPUTComputeShader = new CPUTComputeShaderDX11( pNewComputeShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddComputeShader(name + shaderMain + shaderProfile, pNewCPUTComputeShader);\n\n    // return the shader\n    return pNewCPUTComputeShader;\n}\n\n//--------------------------------------------------------------------------------------\nCPUTComputeShaderDX11 *CPUTComputeShaderDX11::CreateComputeShaderFromMemory(\n    const cString        &name,\n    ID3D11Device         *pD3dDevice,\n    const cString        &shaderMain,\n    const cString        &shaderProfile,\n    const char           *pShaderSource\n)\n{\n    ID3DBlob*           pCompiledBlob = NULL;\n    ID3D11ComputeShader*  pNewComputeShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromMemory(pShaderSource, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling Compute shader:\\n\\n\") );\n\n    // Create the Compute shader\n    // TODO: Move to Compute shader class\n    HRESULT hr = pD3dDevice->CreateComputeShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewComputeShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating Compute shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetComputeShader \")+name;\n    // CPUTSetDebugName(pNewComputeShader, DebugName);\n\n    CPUTComputeShaderDX11 *pNewCPUTComputeShader = new CPUTComputeShaderDX11( pNewComputeShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddComputeShader(name + shaderMain + shaderProfile, pNewCPUTComputeShader);\n    // pNewCPUTComputeShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTComputeShader;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTComputeShaderDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTCOMPUTESHADERDX11_H\n#define _CPUTCOMPUTESHADERDX11_H\n\n#include \"CPUT.h\"\n#include \"CPUTShaderDX11.h\"\n\nclass CPUTComputeShaderDX11 : public CPUTShaderDX11\n{\nprotected:\n    ID3D11ComputeShader *mpComputeShader;\n\n     // Destructor is not public.  Must release instead of delete.\n    ~CPUTComputeShaderDX11(){ SAFE_RELEASE(mpComputeShader) }\n\npublic:\n    static CPUTComputeShaderDX11 *CreateComputeShader(\n        const cString  &name,\n        ID3D11Device   *pD3dDevice,\n        const cString  &shaderMain,\n        const cString  &shaderProfile\n    );\n\n    static CPUTComputeShaderDX11 *CreateComputeShaderFromMemory(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile,\n        const char           *pShaderSource\n    );\n    CPUTComputeShaderDX11() : mpComputeShader(NULL), CPUTShaderDX11(NULL) {}\n    CPUTComputeShaderDX11(ID3D11ComputeShader *pD3D11ComputeShader, ID3DBlob *pBlob) : mpComputeShader(pD3D11ComputeShader), CPUTShaderDX11(pBlob) {}\n    ID3DBlob *GetBlob() { return mpBlob; }\n    ID3D11ComputeShader *GetNativeComputeShader() { return mpComputeShader; }\n};\n\n#endif //_CPUTCOMPUTESHADER_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTConfigBlock.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTConfigBlock.h\"\n#include \"CPUTOSServicesWin.h\"\n\nCPUTConfigEntry  &CPUTConfigEntry::sNullConfigValue = CPUTConfigEntry(_L(\"\"), _L(\"\"));\n\n//----------------------------------------------------------------\nstatic bool iswhite(char ch)\n{\n\treturn ch == ' ' || ch == '\\t' || ch == '\\r' || ch == '\\n';\n}\n\ntemplate<typename T>\nstatic void RemoveWhitespace(T &start, T &end)\n{\n\twhile (start < end && iswhite(*start))\n    {\n\t\t++start;\n    }\n\n\twhile (end > start && iswhite(*(end - 1)))\n    {\n\t\t--end;\n    }\n}\n\n//----------------------------------------------------------------\nstatic bool ReadLine(const char **ppStart, const char **ppEnd, const char **ppCur)\n{\n\tconst char *pCur = *ppCur;\n\tif (!*pCur) // check for EOF\n    {\n\t\treturn false;\n    }\n\n\t// We're at the start of a line now, skip leading whitespace\n\twhile (*pCur == ' ' || *pCur == '\\t')\n    {\n\t\t++pCur;\n    }\n\n\t*ppStart = pCur;\n\n\t// Forward to the end of the line and keep track of last non-whitespace char\n\tconst char *pEnd = pCur;\n\tfor (;;)\n\t{\n\t\tchar ch = *pCur++;\n\t\tif (!ch)\n\t\t{\n\t\t\t--pCur; // terminating NUL isn't consumed\n\t\t\tbreak;\n\t\t}\n\t\telse if (ch == '\\n')\n        {\n\t\t\tbreak;\n        }\n\t\telse if (!iswhite(ch))\n        {\n\t\t\tpEnd = pCur;\n        }\n\t}\n\n\t*ppEnd = pEnd;\n\t*ppCur = pCur;\n\treturn true;\n}\n\n//----------------------------------------------------------------\nstatic const char *FindFirst(const char *start, const char *end, char ch)\n{\n\tconst char *p = start;\n\twhile (p < end && *p != ch)\n    {\n\t\t++p;\n    }\n\treturn p;\n}\n\nstatic const char *FindLast(const char *start, const char *end, char ch)\n{\n\tconst char *p = end;\n\twhile (--p >= start && *p != ch)\n    {\n    }\n\n\treturn p;\n}\n\nstatic void AssignStr(cString &dest, const char *start, const char *end, _locale_t locale)\n{\n\tdest.clear();\n\tif (end <= start)\n    {\n\t\treturn;\n    }\n\n\tstatic const int NBUF = 64;\n\twchar_t buf[NBUF];\n\tint nb = 0;\n\n\tsize_t len = end - start;\n\tsize_t initial = len + 1; // assume most characters are 1-byte\n\tdest.reserve(initial);\n\n\tconst char *p = start;\n\twhile (p < end)\n\t{\n\t\tint len = _mbtowc_l(&buf[nb++], p, end - p, locale);\n\t\tif (len < 1)\n        {\n\t\t\tbreak;\n        }\n\n\t\tp += len;\n\t\tif (p >= end || nb >= NBUF)\n\t\t{\n\t\t\tdest.append(buf, nb);\n\t\t\tnb = 0;\n\t\t}\n\t}\n}\n\n//----------------------------------------------------------------\nvoid CPUTConfigEntry::ValueAsFloatArray(float *pFloats, int count)\n{\n    cString valueCopy = szValue;\n    TCHAR *szOrigValue = (TCHAR*)valueCopy.c_str();\n\n    TCHAR *szNewValue = NULL;\n    TCHAR *szCurrValue = wcstok_s(szOrigValue, _L(\" \"), &szNewValue);\n\tfor(int clear = 0; clear < count; clear++)\n\t{\n\t\tpFloats[clear] = 0.0f;\n\t}\n    for(int ii=0;ii<count;++ii)\n    {\n\t\tif(szCurrValue == NULL)\n        {\n            return;\n        }\n\t\tpFloats[ii] = (float) _wtof(szCurrValue);\n        szCurrValue = wcstok_s(NULL, _L(\" \"), &szNewValue);\n\n    }\n}\n//----------------------------------------------------------------\nCPUTConfigBlock::CPUTConfigBlock()\n    : mnValueCount(0)\n{\n}\n//----------------------------------------------------------------\nCPUTConfigBlock::~CPUTConfigBlock()\n{\n}\n//----------------------------------------------------------------\nconst cString &CPUTConfigBlock::GetName(void)\n{\n    return mszName;\n}\n//----------------------------------------------------------------\nint CPUTConfigBlock::GetNameValue(void)\n{\n    return mName.ValueAsInt();\n}\n//----------------------------------------------------------------\nCPUTConfigEntry *CPUTConfigBlock::GetValue(int nValueIndex)\n{\n    if(nValueIndex < 0 || nValueIndex >= mnValueCount)\n    {\n        return NULL;\n    }\n    return &mpValues[nValueIndex];\n}\n//----------------------------------------------------------------\nCPUTConfigEntry *CPUTConfigBlock::AddValue(const cString &szName, const cString &szValue )\n{\n    cString szNameLower = szName;\n    std::transform(szNameLower.begin(), szNameLower.end(), szNameLower.begin(), ::tolower);\n\n    cString szValueLower = szValue;\n    std::transform(szValueLower.begin(), szValueLower.end(), szValueLower.begin(), ::tolower);\n\n    // TODO: What should we do if it already exists?\n    CPUTConfigEntry *pEntry = &mpValues[mnValueCount++];\n    pEntry->szName  = szNameLower;\n    pEntry->szValue = szValueLower;\n    return pEntry;\n}\n//----------------------------------------------------------------\nCPUTConfigEntry *CPUTConfigBlock::GetValueByName(const cString &szName)\n{\n    for(int ii=0; ii<mnValueCount; ++ii)\n    {\n\t\tconst cString &valName = mpValues[ii].szName;\n\t\tif(valName.size() != szName.size())\n        {\n\t\t\tcontinue;\n        }\n\n\t\tsize_t j = 0;\n\t\twhile (j < valName.size() && tolower(szName[j]) == valName[j])\n        {\n\t\t\t++j;\n        }\n\n\t\tif (j == valName.size()) // match\n\t\t{\n            return &mpValues[ii];\n        }\n    }\n\n    // not found - return an 'empty' object to avoid crashes/extra error checking\n    return &CPUTConfigEntry::sNullConfigValue;\n}\n//----------------------------------------------------------------\nint CPUTConfigBlock::ValueCount(void)\n{\n    return mnValueCount;\n}\n//----------------------------------------------------------------\nCPUTConfigFile::CPUTConfigFile()\n    : mnBlockCount(0)\n    , mpBlocks(NULL)\n{\n}\n//----------------------------------------------------------------\nCPUTConfigFile::~CPUTConfigFile()\n{\n    if(mpBlocks)\n    {\n        delete [] mpBlocks;\n        mpBlocks = 0;\n    }\n    mnBlockCount = 0;\n}\n//----------------------------------------------------------------\nCPUTResult CPUTConfigFile::LoadFile(const cString &szFilename)\n{\n    // Load the file\n    cString             szCurrLine;\n    CPUTConfigBlock    *pCurrBlock = NULL;\n    FILE               *pFile = NULL;\n    int                 nCurrBlock = 0;\n    CPUTResult result = CPUTOSServices::GetOSServices()->OpenFile(szFilename, &pFile);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n\t_locale_t locale = _get_current_locale();\n\n\t/* Determine file size */\n\tfseek(pFile, 0, SEEK_END);\n\tint nBytes = ftell(pFile); // for text files, this is an overestimate\n\tfseek(pFile, 0, SEEK_SET);\n\n\t/* Read the whole thing */\n\tchar *pFileContents = new char[nBytes + 1];\n\tnBytes = (int)fread(pFileContents, 1, nBytes, pFile);\n\tfclose(pFile);\n\n\tpFileContents[nBytes] = 0; // add 0-terminator\n\n\t/* Count the number of blocks */\n\tconst char *pCur = pFileContents;\n\tconst char *pStart, *pEnd;\n\n\twhile(ReadLine(&pStart, &pEnd, &pCur))\n\t{\n\t\tconst char *pOpen = FindFirst(pStart, pEnd, '[');\n\t\tconst char *pClose = FindLast(pOpen + 1, pEnd, ']');\n\t\tif (pOpen < pClose)\n\t\t{\n\t\t\t// This line is a valid block header\n\t\t\tmnBlockCount++;\n\t\t}\n\t}\n\n    // For files that don't have any blocks, just add the entire file to one block\n    if(mnBlockCount == 0)\n    {\n        mnBlockCount   = 1;\n    }\n\n\tpCur = pFileContents;\n    mpBlocks = new CPUTConfigBlock[mnBlockCount];\n    pCurrBlock = mpBlocks;\n\n\t/* Find the first block first */\n\twhile(ReadLine(&pStart, &pEnd, &pCur))\n\t{\n\t\tconst char *pOpen = FindFirst(pStart, pEnd, '[');\n\t\tconst char *pClose = FindLast(pOpen + 1, pEnd, ']');\n\t\tif (pOpen < pClose)\n\t\t{\n\t\t\t// This line is a valid block header\n            pCurrBlock = mpBlocks + nCurrBlock++;\n\t\t\tAssignStr(pCurrBlock->mszName, pOpen + 1, pClose, locale);\n            std::transform(pCurrBlock->mszName.begin(), pCurrBlock->mszName.end(), pCurrBlock->mszName.begin(), ::tolower);\n\t\t}\n\t\telse if (pStart < pEnd)\n\t\t{\n\t\t\t// It's a value\n\t\t\tif (pCurrBlock == NULL)\n            {\n\t\t\t\tcontinue;\n            }\n\n\t\t\tconst char *pEquals = FindFirst(pStart, pEnd, '=');\n\t\t\tif (pEquals == pEnd)\n\t\t\t{\n                // No value, just a key, save it anyway\n\t\t\t\t// Optimistically, we assume it's new\n\t\t\t\tcString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName;\n\t\t\t\tAssignStr(name, pStart, pEnd, locale);\n\n                bool dup = false;\n                for(int ii=0;ii<pCurrBlock->mnValueCount;++ii)\n                {\n                    if(!pCurrBlock->mpValues[ii].szName.compare(name))\n                    {\n                        dup = true;\n                        break;\n                    }\n                }\n                if(!dup)\n                {\n                    pCurrBlock->mnValueCount++;\n                }\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconst char *pNameStart = pStart;\n\t\t\t\tconst char *pNameEnd = pEquals;\n\t\t\t\tconst char *pValStart = pEquals + 1;\n\t\t\t\tconst char *pValEnd = pEnd;\n\n\t\t\t\tRemoveWhitespace(pNameStart, pNameEnd);\n\t\t\t\tRemoveWhitespace(pValStart, pValEnd);\n\n\t\t\t\t// Optimistically assume the name is new\n\t\t\t\tcString &name = pCurrBlock->mpValues[pCurrBlock->mnValueCount].szName;\n\t\t\t\tAssignStr(name, pNameStart, pNameEnd, locale);\n\t\t\t\tstd::transform(name.begin(), name.end(), name.begin(), ::tolower);\n\n                bool dup = false;\n                for(int ii=0;ii<pCurrBlock->mnValueCount;++ii)\n                {\n                    if(!pCurrBlock->mpValues[ii].szName.compare(name))\n                    {\n                        dup = true;\n                        break;\n                    }\n                }\n                if(!dup)\n                {\n                    AssignStr(pCurrBlock->mpValues[pCurrBlock->mnValueCount].szValue, pValStart, pValEnd, locale);\n                    pCurrBlock->mnValueCount++;\n                }\n\t\t\t}\n\t\t}\n\t}\n\n\tdelete[] pFileContents;\n    return CPUT_SUCCESS;\n}\n\n//----------------------------------------------------------------\nCPUTConfigBlock *CPUTConfigFile::GetBlock(int nBlockIndex)\n{\n    if(nBlockIndex >= mnBlockCount || nBlockIndex < 0)\n    {\n        return NULL;\n    }\n\n    return &mpBlocks[nBlockIndex];\n}\n\n//----------------------------------------------------------------\nCPUTConfigBlock *CPUTConfigFile::GetBlockByName(const cString &szBlockName)\n{\n    cString szString = szBlockName;\n    std::transform(szString.begin(), szString.end(), szString.begin(), ::tolower);\n\n    for(int ii=0; ii<mnBlockCount; ++ii)\n    {\n        if(mpBlocks[ii].mszName.compare(szString) == 0)\n        {\n            return &mpBlocks[ii];\n        }\n    }\n    return NULL;\n}\n\n//----------------------------------------------------------------\nint CPUTConfigFile::BlockCount(void)\n{\n    return mnBlockCount;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTConfigBlock.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTPARSELIBRARY_H__\n#define __CPUTPARSELIBRARY_H__\n\n\n\n#include \"CPUT.h\"\n\n#include <algorithm> // for std::transform\n\n#if !defined(UNICODE) && !defined(_UNICODE)\n#define fgetws      fgets\n#define swscanf_s   sscanf_s\n#define wcstok_s    strtok_s\n#define wcsncmp     strncmp\n#define _wtoi       atoi\n#define _wtol       atol\n#endif\n\ntypedef UINT UINT;\n\nclass CPUTConfigEntry\n{\nprivate:\n    cString szName;\n    cString szValue;\n\n    friend class CPUTConfigBlock;\n    friend class CPUTConfigFile;\n\npublic:\n    CPUTConfigEntry() {}\n    CPUTConfigEntry(const cString &name, const cString &value): szName(name), szValue(value){};\n\n    static CPUTConfigEntry  &sNullConfigValue;\n\n    const cString & NameAsString(void){ return  szName;};\n    const cString & ValueAsString(void){ return szValue; }\n\tbool IsValid(void){ return !szName.empty(); }\n    float ValueAsFloat(void)\n    {\n        float fValue=0;\n        int retVal;\n        retVal=swscanf_s(szValue.c_str(), _L(\"%g\"), &fValue ); // float (regular float, or E exponentially notated float)\n        ASSERT(0!=retVal, _L(\"ValueAsFloat - value specified is not a float\"));\n        return fValue;\n    }\n    int ValueAsInt(void)\n    {\n        int nValue=0;\n        int retVal;\n        retVal=swscanf_s(szValue.c_str(), _L(\"%d\"), &nValue ); // signed int (NON-hex)\n        ASSERT(0!=retVal, _L(\"ValueAsInt - value specified is not a signed int\"));\n        return nValue;\n    }\n    UINT ValueAsUint(void)\n    {\n        UINT nValue=0;\n        int retVal;\n        retVal=swscanf_s(szValue.c_str(), _L(\"%u\"), &nValue ); // unsigned int\n        ASSERT(0!=retVal, _L(\"ValueAsUint - value specified is not a UINT\"));\n        return nValue;\n    }\n    bool ValueAsBool(void)\n    {\n        return  (szValue.compare(_L(\"true\")) == 0) || \n                (szValue.compare(_L(\"1\")) == 0) || \n                (szValue.compare(_L(\"t\")) == 0);\n    }\n\n    void ValueAsFloatArray(float *pFloats, int count);\n};\n\nclass CPUTConfigBlock\n{\npublic:\n    CPUTConfigBlock();\n    ~CPUTConfigBlock();\n\n    CPUTConfigEntry *AddValue(const cString &szName, const cString &szValue);\n    CPUTConfigEntry *GetValue(int nValueIndex);\n    CPUTConfigEntry *GetValueByName(const cString &szName);\n    const cString &GetName(void);\n    int GetNameValue(void);\n    int ValueCount(void);\n    bool IsValid() { return mnValueCount > 0; }\nprivate:\n    CPUTConfigEntry mpValues[64];\n    CPUTConfigEntry mName;\n    cString         mszName;\n    int             mnValueCount;\n\n    friend class CPUTConfigFile;\n};\n\nclass CPUTConfigFile\n{\npublic:\n    CPUTConfigFile();\n    ~CPUTConfigFile();\n\n    CPUTResult LoadFile(const cString &szFilename);\n\n    CPUTConfigBlock *GetBlock(int nBlockIndex);\n    CPUTConfigBlock *GetBlockByName(const cString &szBlockName);\n    int BlockCount(void);\nprivate:\n    CPUTConfigBlock    *mpBlocks;\n    int                 mnBlockCount;\n};\n\n#endif //#ifndef __CPUTPARSELIBRARY_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTControl.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTControl.h\"\n\n// Constructor\n//------------------------------------------------------------------------------\nCPUTControl::CPUTControl():mControlVisible(true),\n    mControlGraphicsDirty(false),\n    mControlAutoArranged(true),\n    mControlNeedsArrangmentResizing(true),\n    mhotkey(KEY_NONE),\n    mcontrolType(CPUT_CONTROL_UNKNOWN),\n    mcontrolID(0),\n    mpCallbackHandler(NULL),\n    mControlState(CPUT_CONTROL_ACTIVE)\n{\n}\n\n// Destructor\n//------------------------------------------------------------------------------\nCPUTControl::~CPUTControl()\n{\n}\n\n// Control type/identifier routines that have a common implementation for all controls\n\n// Sets the control's ID used for identification purposes (hopefully unique)\n//------------------------------------------------------------------------------\nvoid CPUTControl::SetControlID(CPUTControlID id)\n{\n    mcontrolID = id;\n}\n\n// Get the ID for this control\n//------------------------------------------------------------------------------\nCPUTControlID CPUTControl::GetControlID()\n{\n    return mcontrolID;\n}\n\n// Get the type of control this is (button/dropdown/etc)\n//------------------------------------------------------------------------------\nCPUTControlType CPUTControl::GetType()\n{\n    return mcontrolType;\n}\n\n\n// Set callback handler\n//------------------------------------------------------------------------------\nvoid CPUTControl::SetControlCallback(CPUTCallbackHandler *pHandler)\n{\n    mpCallbackHandler = pHandler;\n}\n\n\n// set whether controls is visible or not (it is still there, but not visible)\n//------------------------------------------------------------------------------\nvoid CPUTControl::SetVisibility(bool bVisible)\n{\n    mControlVisible = bVisible;\n}\n\n// visibility state\n//------------------------------------------------------------------------------\nbool CPUTControl::IsVisible()\n{\n    return mControlVisible;\n}\n\n// Set the hot key for keyboard events for this control\n//------------------------------------------------------------------------------\nvoid CPUTControl::SetHotkey(CPUTKey hotKey)\n{\n    mhotkey = hotKey;\n}\n\n// Get the hot key set for this control\n//------------------------------------------------------------------------------\nCPUTKey CPUTControl::GetHotkey()\n{\n    return mhotkey;\n}\n\n// Should this control be auto-arranged?\n//------------------------------------------------------------------------------\nvoid CPUTControl::SetAutoArranged(bool bIsAutoArranged)\n{\n    mControlAutoArranged = bIsAutoArranged;\n}\n\n//------------------------------------------------------------------------------\nbool CPUTControl::IsAutoArranged()\n{\n    return mControlAutoArranged;\n}\n\n// Set the control to enabled or greyed out\n//------------------------------------------------------------------------------\nvoid CPUTControl::SetEnable(bool bEnabled)\n{\n    if(!bEnabled)\n    {\n        mControlState = CPUT_CONTROL_INACTIVE;\n    }\n    else\n    {\n        mControlState = CPUT_CONTROL_ACTIVE;\n    }\n}\n\n// Return bool if the control is enabled/greyed out\n//------------------------------------------------------------------------------\nbool CPUTControl::IsEnabled()\n{\n    if(mControlState == CPUT_CONTROL_INACTIVE)\n    {\n        return false;\n    }\n\n    return true;\n}"
  },
  {
    "path": "CPUT/CPUT/CPUTControl.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTCONTROL_H__\n#define __CPUTCONTROL_H__\n\n#include <stdio.h>\n\n#include \"CPUT.h\"\n#include \"CPUTEventHandler.h\"\n\n// internal types\n// TODO: Why are these int and not float?\nstruct CPUT_SIZE\n{\n    int width;\n    int height;\n};\n\nstruct CPUT_POINT\n{\n    int x;\n    int y;\n};\n\nstruct CPUT_RECT\n{\n    int x;\n    int y;\n    int width;\n    int height;\n};\n// This is a list of all the known control types\n// if you make a new control, be sure to add it here\n// so the GUI controller can manage it properly\nenum CPUTControlType\n{\n    CPUT_CONTROL_UNKNOWN,\n    CPUT_BUTTON,\n    CPUT_CHECKBOX,\n    CPUT_DROPDOWN,\n    CPUT_SLIDER,\n    CPUT_STATIC,\n    CPUT_PANE,\n};\n\n// state of the control\ntypedef enum CPUTGUIControlState\n{\n    CPUT_CONTROL_ACTIVE,\n    CPUT_CONTROL_INACTIVE,\n} CPUTGUIControlState;\n\n// control/event ID defines\ntypedef unsigned int UINT;\ntypedef UINT CPUTControlID;\ntypedef UINT CPUTEventID;\nconst UINT CPUT_CONTROL_ID_INVALID=(UINT)-1;\n\n// forward declaration\nclass CPUTCallbackHandler;\n\n// CPUTControl base class\n// This is basically a virtual class that defines the common calls for manipulation\n// controls.  Individual controls implement this interface.\nclass CPUTControl:public CPUTEventHandler\n{\npublic:\n    CPUTControl();\n    virtual ~CPUTControl();\n\n    // Control type\n    virtual void SetControlID(CPUTControlID id);\n    virtual CPUTControlID GetControlID();\n    virtual CPUTControlType GetType();\n\n    // Set what object to call back on events\n    void SetControlCallback(CPUTCallbackHandler *pHandler);\n\n    // Graphical state manipulation\n    virtual void GetPosition(int &x, int &y)=0;\n    virtual void SetPosition(int x, int y)=0;\n    virtual void GetDimensions(int &width, int &height)=0;\n    virtual bool ContainsPoint(int x, int y)=0;\n    virtual void SetVisibility(bool bVisible);\n    virtual bool IsVisible();\n    virtual void SetEnable(bool in_bEnabled);\n    virtual bool IsEnabled();\n    virtual void SetAutoArranged(bool bIsAutoArranged);\n    virtual bool IsAutoArranged();\n\n    // keyboard event hotkey for this control\n    virtual void SetHotkey(CPUTKey hotKey);\n    virtual CPUTKey GetHotkey();\n\n    // buffer management\n    virtual unsigned int GetQuadCount() {return 0;}\n    virtual bool ControlGraphicsDirty() {return mControlGraphicsDirty;}\n    virtual bool ControlResizedItself() {return mControlNeedsArrangmentResizing;}\n    virtual void ControlResizingHandled() { mControlNeedsArrangmentResizing = false;}\n    virtual void DrawIntoBuffer(float *pVertexBufferMirror, int *pInsertIndex, int pMaxBufferSize) {return;}\n\nprotected:\n    bool                    mControlVisible;\n    bool                    mControlAutoArranged;\n    bool                    mControlGraphicsDirty;\n    bool                    mControlNeedsArrangmentResizing;\n    CPUTKey                 mhotkey;\n    CPUTControlType         mcontrolType;\n    CPUTControlID           mcontrolID;\n    CPUTCallbackHandler    *mpCallbackHandler;\n    CPUTGUIControlState     mControlState;\n};\n\n#endif //#ifndef __CPUTCONTROL_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTDomainShaderDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n\n#include \"CPUTDomainShaderDX11.h\"\n#include \"CPUTAssetLibraryDX11.h\"\n\nCPUTDomainShaderDX11 *CPUTDomainShaderDX11::CreateDomainShader(\n    const cString       &name,\n    ID3D11Device        *pD3dDevice,\n    const cString       &shaderMain,\n    const cString       &shaderProfile\n)\n{\n    ID3DBlob            *pCompiledBlob = NULL;\n    ID3D11DomainShader  *pNewDomainShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromFile(name, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling Domain shader:\\n\\n\") );\n\n    // Create the Domain shader\n    // TODO: Move to Domain shader class\n    HRESULT hr = pD3dDevice->CreateDomainShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewDomainShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating Domain shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetDomainShader \")+name;\n    // CPUTSetDebugName(pNewDomainShader, DebugName);\n\n    CPUTDomainShaderDX11 *pNewCPUTDomainShader = new CPUTDomainShaderDX11( pNewDomainShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddDomainShader(name, pNewCPUTDomainShader);\n    // pNewCPUTDomainShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTDomainShader;\n}\n\n//--------------------------------------------------------------------------------------\nCPUTDomainShaderDX11 *CPUTDomainShaderDX11::CreateDomainShaderFromMemory(\n    const cString       &name,\n    ID3D11Device        *pD3dDevice,\n    const cString       &shaderMain,\n    const cString       &shaderProfile,\n    const char          *pShaderSource\n)\n{\n    ID3DBlob            *pCompiledBlob = NULL;\n    ID3D11DomainShader  *pNewDomainShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromMemory(pShaderSource, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling Domain shader:\\n\\n\") );\n\n    // Create the Domain shader\n    // TODO: Move to Domain shader class\n    HRESULT hr = pD3dDevice->CreateDomainShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewDomainShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating Domain shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetDomainShader \")+name;\n    // CPUTSetDebugName(pNewDomainShader, DebugName);\n\n    CPUTDomainShaderDX11 *pNewCPUTDomainShader = new CPUTDomainShaderDX11( pNewDomainShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddDomainShader(name + shaderMain + shaderProfile, pNewCPUTDomainShader);\n    // pNewCPUTDomainShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTDomainShader;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTDomainShaderDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTDOMAINSHADERDX11_H\n#define _CPUTDOMAINSHADERDX11_H\n\n#include \"CPUT.h\"\n#include \"CPUTShaderDX11.h\"\n\nclass CPUTDomainShaderDX11 : public CPUTShaderDX11\n{\nprotected:\n    ID3D11DomainShader *mpDomainShader;\n\n    // Destructor is not public.  Must release instead of delete.\n    ~CPUTDomainShaderDX11(){ SAFE_RELEASE(mpDomainShader) }\n\npublic:\n    static CPUTDomainShaderDX11 *CreateDomainShader(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile\n    );\n    static CPUTDomainShaderDX11 *CreateDomainShaderFromMemory(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile,\n        const char           *pShaderSource\n    );\n\n\n    CPUTDomainShaderDX11() : mpDomainShader(NULL), CPUTShaderDX11(NULL) {}\n    CPUTDomainShaderDX11(ID3D11DomainShader *pD3D11DomainShader, ID3DBlob *pBlob) : mpDomainShader(pD3D11DomainShader), CPUTShaderDX11(pBlob) {}\n    ID3DBlob *GetBlob() { return mpBlob; }\n    ID3D11DomainShader *GetNativeDomainShader() { return mpDomainShader; }\n};\n\n#endif //_CPUTDOMAINSHADER_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTDropdown.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTDropdown.h\"\n\n#include \"CPUTText.h\"\n\n// uber-buffer\nCPUT_SIZE CPUTDropdown::mpDropdownIdleImageSizeList[] = { {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} };\nCPUT_SIZE CPUTDropdown::mpDropdownDisabledSizeList[] = { {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} };\n\n// texture atlas information\nfloat gDropdownAtlasWidth = 256.0f;\nfloat gDropdownAtlasHeight = 64.0f;\n\n// Texture atlas coordinates of the active-idle dropdown control\nint gDropdownUVLocations_active[] = { \n    140,42, 143,45, // lt\n    140,47, 143,48, // lm\n    140,50, 143,53, // lb\n\n    145,42, 146,45, // mt\n    145,47, 146,48, // mm\n    145,50, 146,53, // mb\n\n    148,42, 151,45, // rt\n    148,47, 151,48, // rm\n    148,50, 151,53, // rb\n\n    139,21, 159,41, // button\n    163,21, 183,41, // button down\n    230,21, 231,22  // highlight\n};\n\n\n// Texture atlas coordinates of the disabled dropdown control\nint gDropdownUVLocations_disabled[] = { \n    155,42, 158,45, // lt\n    155,47, 158,48, // lm\n    155,50, 158,53, // lb\n\n    160,42, 161,45, // mt\n    160,47, 161,48, // mm\n    160,50, 161,53, // mb\n\n    163,42, 166,45, // rt\n    163,47, 166,48, // rm\n    163,50, 166,53, // rb\n\n    186,21, 206,41, // button\n    208,21, 228,41, // button down\n    236,21, 237,22  // highlight\n};\nconst int DropdownQuadCount = 12;\nfloat3 mpDropdownUVCoords_active[DropdownQuadCount*2];\nfloat3 mpDropdownUVCoords_disabled[DropdownQuadCount*2];\n\nint CTrayLM = 1;\nint CTrayLB = 2;\nint CTrayMM = 4;\nint CTrayMB = 5;\nint CTrayRM = 7;\nint CTrayRB = 8;\nint CTrayHighlight = 11;\n\n\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTDropdown::CPUTDropdown(const cString ControlName, CPUTControlID id, CPUTFont *pFont):mVertexStride(0),\n    mVertexOffset(0),\n    mSelectedItemIndex(0),\n    mConfirmedSelectedItemIndex(0),\n    mbSizeDirty(false),\n    mbMouseInside(false),\n    mbStartedClickInside(false),\n    mbStartedClickInsideTray(false),\n    mRevertItem((UINT)-1),\n\n    mpMirrorBufferActive(NULL),\n    mpMirrorBufferDisabled(NULL),\n    mpButtonText(NULL),\n    mpFont(pFont)\n{\n    // initialize the state variables\n    InitialStateSet();\n\n    // save the control ID for callbacks\n    mcontrolID = id;\n\n    // set as enabled\n    CPUTControl::SetEnable(true);\n\n    // this is a copy of whatever item is selected\n    mpSelectedItemCopy = new CPUTText(pFont);\n\n        // clear the button selected area rect\n    mButtonRect.x=0; mButtonRect.y=0; mButtonRect.width=0; mButtonRect.height=0;\n    mTrayDimensions.x=0; mTrayDimensions.y=0; mTrayDimensions.width=0; mTrayDimensions.height=0;\n\n    // set the string to display with the slider\n    AddSelectionItem(ControlName, true);\n\n\n    // Register any instance resources\n    RegisterInstanceResources();\n}\n\n// Initial state of the control's member variables\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::InitialStateSet()\n{\n    // set the type\n    mcontrolType = CPUT_DROPDOWN;\n    mControlState = CPUT_CONTROL_ACTIVE;\n    mControlGuiState = CPUT_DROPDOWN_GUI_MOUSE_NEUTRAL;\n\n    // save the control ID for callbacks\n    mcontrolID = 0;\n\n    // default location\n    mControlDimensions.x=0;\n    mControlDimensions.y=0;\n    mControlDimensions.height=0;\n    mControlDimensions.width=0;\n}\n\n// Destructor\n//------------------------------------------------------------------------------\nCPUTDropdown::~CPUTDropdown()\n{\n    UnRegisterInstanceResources();\n}\n\n// Return xy position of control\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::GetPosition(int &x, int &y)\n{\n    x = mControlDimensions.x;\n    y = mControlDimensions.y;\n}\n\n// Returns the number of quads needed to draw this control\n//--------------------------------------------------------------------------------\nunsigned int CPUTDropdown::GetOutputVertexCount()\n{\n    // A dropdown is always made of:\n    //   - 9 quads for the display area\n    //   - 1 quad for the tray button\n    //   - 6 quads for the tray itself\n    //   - 1 quad for the highlighted area \n\n    // Quads 2,4,5,6, and 8 'stretch' in height and/or width to fit the \n    // static text/content inside the button\n    //\n    //   ---+------------------+---\n    //  | 1 |     4            | 7 |              \n    //  |---+------------------+---|\n    //  |   |           +----+ |   | \n    //  | 2 |     5     | 10 | | 8 |              \n    //  |   |           +----+ |   | \n    //  |---+------------------+---|\n    //  | 3 |     6            | 9 |\n    //   ---+------------------+---\n    //    |   |              |   | \n    //    | 11|     12       | 13|              \n    //    |   |              |   | \n    //    |---+--------------+---|\n    //    | 14|     15       | 16|\n    //     ---+--------------+---\n    //\n    // calculation: (3 verts/triangle * 2 triangles/quad) * (9 + 1 + 6 + 1 quads)\n\n    return (3*2) * (9+1+6+1); \n}\n\n\n\n\n\n// Load and register all instance variables\n//-----------------------------------------------------------------------------\nCPUTResult CPUTDropdown::RegisterInstanceResources()\n{\n    return CPUT_SUCCESS;\n}\n\n// Release all instance resources (vertex buffer quads/etc)\n//-----------------------------------------------------------------------------\nCPUTResult CPUTDropdown::UnRegisterInstanceResources()\n{\n    // delete the list of selection items (CPUTTexts)\n    for(UINT i=0; i<mpListOfSelectableItems.size(); i++)\n    {\n        // physically delete the text object\n        CPUTText *pItem = mpListOfSelectableItems[i];\n        SAFE_DELETE(pItem);        \n    }\n\n    // clear the list\n    mpListOfSelectableItems.clear();\n\n    // delete vertex mirror buffers\n    SAFE_DELETE_ARRAY(mpMirrorBufferActive);\n    SAFE_DELETE_ARRAY(mpMirrorBufferDisabled);\n    \n    // delete the extra static item used for display readout\n    SAFE_DELETE(mpSelectedItemCopy);\n    \n    return CPUT_SUCCESS;\n}\n\n\n\n// Add an item to the selection list\n//-----------------------------------------------------------------------------\nCPUTResult CPUTDropdown::AddSelectionItem(const cString Item, bool bIsSelected)\n{\n    // Don't allow adding 'empty' elements\n    // causes a spacing issue\n    if(0==Item.size())\n    {\n        return CPUT_ERROR_INVALID_PARAMETER;\n    }\n\n    // create a static item to hold the text\n    CPUTText *pNewItem = new CPUTText(mpFont);\n    pNewItem->SetText(Item, 0.35f); // set the text slightly higher than the 0.5 normal mode\n\n    mpListOfSelectableItems.push_back(pNewItem);\n\n    // Should this be the currently selected item?\n    if(bIsSelected)\n    {\n        mSelectedItemIndex = (int) mpListOfSelectableItems.size()-1;    // set the highlighted element to this item\n        mConfirmedSelectedItemIndex = mSelectedItemIndex;               // set the hard-selected item to this as well\n    }\n    // was this the first item added to an empty list?\n    if( 1==mpListOfSelectableItems.size() )\n    {\n        mSelectedItemIndex=0;\n        mConfirmedSelectedItemIndex=0;\n    }\n\n    // mark that a resize of dropdown selection box is needed\n    mbSizeDirty = true;\n\n    Recalculate();\n\n    // position or size may move - force a recalculation of this control's location\n    // if it is managed by the auto-arrange function\n    if(this->IsAutoArranged())\n    {\n        mControlNeedsArrangmentResizing = true;\n    }\n\n    return CPUT_SUCCESS;\n}\n\n// Return the number of items in the dropdown list\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::NumberOfSelectableItems(UINT &count)\n{\n    count = (UINT) mpListOfSelectableItems.size();\n}\n\n// Return the index of the currently selected item\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::GetSelectedItem(UINT &index)\n{\n    //index = mSelectedItemIndex+1;\n    index = mConfirmedSelectedItemIndex;\n}\n\n// Fill user's buffer with string of the currently selected item\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::GetSelectedItem(cString &Item)\n{\n    if(-1!=mSelectedItemIndex)\n    {\n        //mpListOfSelectableItems[mSelectedItemIndex]->GetString(Item);\n        mpListOfSelectableItems[mConfirmedSelectedItemIndex]->GetString(Item);\n    }\n}\n\n// Sets which item in the dropdown is currently selected\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::SetSelectedItem(const UINT index)\n{\n    if( (index>0) && (index <= mpListOfSelectableItems.size() ))\n    {\n        mSelectedItemIndex = (index-1);\n        mConfirmedSelectedItemIndex = mSelectedItemIndex; // set the hard-selected item to this as well\n    }\n\n    // Recalculate and mark control for redraw\n    Recalculate();\n}\n\n// Sets which item in the dropdown is currently highlighted\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::SetHighlightedItem(const UINT index)\n{\n    if( (index>0) && (index <= mpListOfSelectableItems.size() ))\n    {\n        mSelectedItemIndex = (index-1);\n    }\n\n    // Recalculate and mark control for redraw\n    Recalculate(); \n}\n\n// Delete an item at a specific index\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::DeleteSelectionItem(const UINT index)\n{\n    if((0==index) || (index>mpListOfSelectableItems.size()))\n        return;\n\n    // list is zero based, not 1 based\n    UINT itemIndex = index-1;\n\n    // physically delete the text object\n    CPUTText *pItem = mpListOfSelectableItems[itemIndex];\n    SAFE_DELETE(pItem);    \n\n    // remove the item from the list\n    mpListOfSelectableItems.erase(mpListOfSelectableItems.begin()+itemIndex);\n\n    // if we're deleting the selected item or any above it\n    // move the current selection down by oneq\n    if(mSelectedItemIndex > itemIndex)\n    {\n        mSelectedItemIndex--;\n        mConfirmedSelectedItemIndex = mSelectedItemIndex;\n    }\n    if(mSelectedItemIndex >= mpListOfSelectableItems.size())\n    {\n        mSelectedItemIndex = (UINT) mpListOfSelectableItems.size()-1;\n        mConfirmedSelectedItemIndex = mSelectedItemIndex;\n    }\n\n    // resize the dropdown selection box\n    mbSizeDirty = true;\n\n    Recalculate();\n\n    // position or size may move - force a recalculation of this control's location\n    // if it is managed by the auto-arrange function\n    if(this->IsAutoArranged())\n    {\n        mControlNeedsArrangmentResizing = true;\n    }\n}\n\n// Delete an item with string\n// Only deletes the first occurance of the string, you'd need to call multiple\n// times to delete each occurance\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::DeleteSelectionItem(const cString string)\n{\n    cString itemText;\n\n    for(UINT i=0; i<mpListOfSelectableItems.size(); i++)\n    {\n        mpListOfSelectableItems[i]->GetString(itemText);\n        if(0==itemText.compare(string))\n        {\n            DeleteSelectionItem(i+1);\n            break;\n        }\n    }\n\n    Recalculate();\n}\n\n\n// Handle mouse events\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode CPUTDropdown::HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state)\n{\n    UNREFERENCED_PARAMETER(wheel);\n    CPUTEventHandledCode handledCode = CPUT_EVENT_UNHANDLED;\n\n    // just return if the control is disabled or invisible\n    if((CPUT_CONTROL_INACTIVE == mControlState) || (false == mControlVisible) )\n    {\n        mbMouseInside = false;\n        return handledCode;\n    }\n\n    // tray is down, commence to selecting\n    if(CPUT_DROPDOWN_GUI_MOUSE_PRESSED == mControlGuiState) \n    {\n        if(ContainsPointTrayArea(x, y))\n        {\n            // tray is open\n            // float the selection up/down based on mouse position, making\n            // whichever item the mouse is over the selected item\n            CPUT_RECT inner, outer;\n            CalculateTrayRect(inner, outer);\n            if( (x>outer.x) && (x<outer.x+outer.width) &&\n                (y>inner.y) && (y<inner.y+inner.height))\n            {\n                // figure out which one was selected\n                int itemWidth, itemHeight;\n                CalculateMaxItemSize(itemWidth, itemHeight);\n                int itemSelect = (int)( (y - inner.y)  / (float)(itemHeight+2*CPUT_DROPDOWN_TEXT_PADDING));\n                SetHighlightedItem(itemSelect+1);\n            }\n\n            if( CPUT_MOUSE_LEFT_DOWN == state )\n            {\n                mbStartedClickInsideTray = true;\n            }\n\n            // released the left-down button, but there was a click started here\n            if( !(CPUT_MOUSE_LEFT_DOWN == state) && (true == mbStartedClickInsideTray) )\n            {\n                // mark click start as no longer active\n                mbStartedClickInsideTray = false;\n\n                // close the tray\n                //mControlState = CPUT_CONTROL_ACTIVE;\n                mControlGuiState = CPUT_DROPDOWN_GUI_MOUSE_NEUTRAL;\n                Recalculate();\n\n                // set the hard-selected item\n                mConfirmedSelectedItemIndex = mSelectedItemIndex;\n\n                // fire callback\n                mpCallbackHandler->HandleCallbackEvent(1, mcontrolID, (CPUTControl*) this);\n                \n                // remember this item as the last selected item\n                GetSelectedItem(mRevertItem);\n            }\n\n            // anything in the tray counts as handling the mouse event\n            return CPUT_EVENT_HANDLED;\n        }\n    }\n\n    // handle just the readout area\n    if(ContainsPointReadoutArea(x,y))\n    {\n        // click started outside this control - ignore it\n        if( (false == mbMouseInside ) && (CPUT_MOUSE_LEFT_DOWN == state) )\n        {\n            return handledCode;\n        }\n\n        // clicked and dragging around inside the control itself - ignore\n        if( (true == mbStartedClickInside ) && (CPUT_MOUSE_LEFT_DOWN == state) )\n        {\n            return CPUT_EVENT_HANDLED;\n        }\n\n        mbMouseInside = true;\n        if( !(CPUT_MOUSE_LEFT_DOWN == state))\n        {\n            mbStartedClickInside = false;\n            mbStartedClickInsideTray = false;\n        }\n\n        if( CPUT_MOUSE_LEFT_DOWN == state )\n        {\n            if(CPUT_DROPDOWN_GUI_MOUSE_NEUTRAL == mControlGuiState) \n            {\n                mbStartedClickInside = true;\n                mbStartedClickInsideTray = true;\n\n                // get the item to revert to\n                GetSelectedItem(mRevertItem);\n\n                // toggle tray state\n                mControlGuiState = CPUT_DROPDOWN_GUI_MOUSE_PRESSED;\n                Recalculate();\n\n            }\n            else\n            {\n                mbStartedClickInside = true;\n                mbStartedClickInsideTray = true;\n                //mControlState = CPUT_CONTROL_ACTIVE;\n                mControlGuiState = CPUT_DROPDOWN_GUI_MOUSE_NEUTRAL;\n                SetSelectedItem(mRevertItem);\n                mRevertItem=(UINT)-1;\n                Recalculate();\n            }\n\n            return CPUT_EVENT_HANDLED;\n        }\n    }\n    else if(CPUT_MOUSE_LEFT_DOWN == state)\n    {\n        // clicked outside the control\n        // if tray is down, restore previous selection and disable\n        // display of the tray\n        if(CPUT_DROPDOWN_GUI_MOUSE_NEUTRAL != mControlGuiState)\n        {\n            mControlGuiState = CPUT_DROPDOWN_GUI_MOUSE_NEUTRAL;\n            SetSelectedItem(mRevertItem+1);\n            mRevertItem=(UINT)-1;\n            Recalculate();\n        }\n        \n        mbStartedClickInside = false;\n        mbMouseInside = false;\n        return CPUT_EVENT_UNHANDLED;\n    }\n    return handledCode;\n}\n\n// Register static textures/etc for this control\n//-----------------------------------------------------------------------------\nCPUTResult CPUTDropdown::RegisterStaticResources()\n{\n    // calculate the UV coordinates of each of the 12 images that\n    // make up a button.  Do this for the active, pressed, and disabled states.\n    for(int ii=0; ii<DropdownQuadCount*2; ii++)\n    {\n        mpDropdownUVCoords_active[ii].x = gDropdownUVLocations_active[2*ii]/gDropdownAtlasWidth;\n        mpDropdownUVCoords_active[ii].y = gDropdownUVLocations_active[2*ii+1]/gDropdownAtlasHeight;\n\n        mpDropdownUVCoords_disabled[ii].x = gDropdownUVLocations_disabled[2*ii]/gDropdownAtlasWidth;\n        mpDropdownUVCoords_disabled[ii].y = gDropdownUVLocations_disabled[2*ii+1]/gDropdownAtlasHeight;\n    }\n\n    // calculate the width/height in pixels of each of the 9 image slices\n    // that makes up the button images\n    int QuadIndex=0;\n    for(int ii=0; ii<DropdownQuadCount*4; ii+=4)\n    {\n        mpDropdownIdleImageSizeList[QuadIndex].width = gDropdownUVLocations_active[ii+2] - gDropdownUVLocations_active[ii+0];\n        mpDropdownIdleImageSizeList[QuadIndex].height = gDropdownUVLocations_active[ii+3] - gDropdownUVLocations_active[ii+1];\n\n        mpDropdownDisabledSizeList[QuadIndex].width = gDropdownUVLocations_disabled[ii+2] - gDropdownUVLocations_disabled[ii+0];\n        mpDropdownDisabledSizeList[QuadIndex].height = gDropdownUVLocations_disabled[ii+3] - gDropdownUVLocations_disabled[ii+1];\n        QuadIndex++;\n    }\n\n\n    return CPUT_SUCCESS;\n}\n\n// Release all statically register resources\n//-----------------------------------------------------------------------------\nCPUTResult CPUTDropdown::UnRegisterStaticResources()\n{\n    // mpDropdownUVCoords_* and mpDropdown*ImageSizeList are both statically allocated\n    // nothing to dealloc anymore\n    return CPUT_SUCCESS;\n}\n\n//\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::CalculateButtonRect(CPUT_RECT &button)\n{\n    CPUT_RECT inner, outer;\n    CalculateReadoutRect(inner, outer);\n\n    button.x =  (inner.x + inner.width) - mpDropdownIdleImageSizeList[CButtonUp].width - CPUT_DROPDOWN_TEXT_PADDING;\n    button.y =  mControlDimensions.y + mpDropdownIdleImageSizeList[CLeftTop].height;\n\n    button.width = mpDropdownIdleImageSizeList[CButtonUp].width;\n    button.height = mpDropdownIdleImageSizeList[CButtonUp].height;\n\n    mButtonRect.x = button.x;\n    mButtonRect.y = button.y;\n    mButtonRect.width = button.width;\n    mButtonRect.height = button.height;\n}\n\n//\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::CalculateReadoutRect(CPUT_RECT &inner, CPUT_RECT &outer)\n{\n    bool ButtonIsBiggerThanText = false;\n\n    // calculate outer dimensions\n    outer.x = mControlDimensions.x;\n    outer.y = mControlDimensions.y;\n    int maxItemSizeWidth, maxItemSizeHeight;\n\n    CalculateMaxItemSize(maxItemSizeWidth, maxItemSizeHeight);\n    if( (maxItemSizeHeight+2*CPUT_DROPDOWN_TEXT_PADDING) < mpDropdownIdleImageSizeList[CButtonUp].height)\n    {\n        ButtonIsBiggerThanText = true;\n    }\n\n    outer.width = mpDropdownIdleImageSizeList[CLeftTop].width + CPUT_DROPDOWN_TEXT_PADDING + maxItemSizeWidth + CPUT_DROPDOWN_TEXT_PADDING + mpDropdownIdleImageSizeList[CButtonUp].width + mpDropdownIdleImageSizeList[CRightTop].width;\n    if(ButtonIsBiggerThanText)\n    {\n        outer.height = mpDropdownIdleImageSizeList[CLeftTop].height + mpDropdownIdleImageSizeList[CButtonUp].width + mpDropdownIdleImageSizeList[CLeftBot].height;\n    }\n    else\n    {\n        outer.height = mpDropdownIdleImageSizeList[CLeftTop].height + CPUT_DROPDOWN_TEXT_PADDING + maxItemSizeHeight + CPUT_DROPDOWN_TEXT_PADDING + mpDropdownIdleImageSizeList[CLeftBot].height;\n    }\n\n    // calculate the inner dimensions\n    inner.x = mControlDimensions.x + mpDropdownIdleImageSizeList[CLeftTop].width + CPUT_DROPDOWN_TEXT_PADDING;\n    inner.y = mControlDimensions.y + mpDropdownIdleImageSizeList[CLeftTop].height;\n\n    if(ButtonIsBiggerThanText)\n    {\n        inner.width = CPUT_DROPDOWN_TEXT_PADDING + maxItemSizeWidth + CPUT_DROPDOWN_TEXT_PADDING + mpDropdownIdleImageSizeList[CButtonUp].width;\n        inner.height = mpDropdownIdleImageSizeList[CButtonUp].height;\n    }\n    else\n    {\n        inner.width = CPUT_DROPDOWN_TEXT_PADDING + maxItemSizeWidth + CPUT_DROPDOWN_TEXT_PADDING + mpDropdownIdleImageSizeList[CButtonUp].width;\n        inner.height = maxItemSizeHeight + 2*CPUT_DROPDOWN_TEXT_PADDING;\n    }\n}\n\n//\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::CalculateReadoutTextPosition(int &x, int &y)\n{\n    CPUT_RECT inner, outer;\n    CalculateReadoutRect(inner, outer);\n\n    CPUT_RECT textDimensions;\n    if(0==mpListOfSelectableItems.size())\n    {\n        textDimensions.height=1;\n    }\n    else\n    {\n        mpListOfSelectableItems[mSelectedItemIndex]->GetDimensions(textDimensions.width, textDimensions.height);\n    }\n\n    x = inner.x;\n    y = (int) (inner.y + inner.height/2.0f - textDimensions.height/2.0f + CPUT_DROPDOWN_TEXT_PADDING/2.0f);\n\n}\n\n//\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::CalculateMaxItemSize(int &width, int &height)\n{\n    width=0; height=0;\n\n    if(mpListOfSelectableItems.size())\n    {\n        for(UINT i=0; i<mpListOfSelectableItems.size(); i++)\n        {\n            CPUT_RECT rect;\n            mpListOfSelectableItems[i]->GetDimensions(rect.width, rect.height);\n            if(width < rect.width)\n            {\n                width = rect.width;\n            }\n            if(height < rect.height)\n            {\n                height = rect.height;\n            }\n        }\n    }\n    else\n    {\n        // give dropdown a nice 'minimum' size if there is nothing\n        mpSelectedItemCopy->SetText(_L(\"                    \"));\n        mpSelectedItemCopy->GetDimensions(width, height);\n    }\n}\n\n//\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::CalculateTrayRect(CPUT_RECT &inner, CPUT_RECT &outer)\n{\n    int maxItemWidth, maxItemHeight;\n    CalculateMaxItemSize(maxItemWidth, maxItemHeight);\n\n    CPUT_RECT innerReadout, outerReadout;\n    CalculateReadoutRect(innerReadout, outerReadout);\n\n    // locations\n    outer.x = outerReadout.x + 5;\n    outer.y = outerReadout.y + outerReadout.height;\n    inner.x = outer.x + mpDropdownIdleImageSizeList[CLeftMid].width;\n    inner.y = outer.y + CPUT_DROPDOWN_TEXT_PADDING;\n\n    // dimension\n    inner.width = maxItemWidth + 2*CPUT_DROPDOWN_TEXT_PADDING;\n    inner.height = (int)((mpListOfSelectableItems.size())*(maxItemHeight+2*CPUT_DROPDOWN_TEXT_PADDING));\n\n    outer.width = inner.width + mpDropdownIdleImageSizeList[CLeftMid].width + mpDropdownIdleImageSizeList[CRightMid].width;\n    outer.height = inner.height + mpDropdownIdleImageSizeList[CLeftBot].height;\n}\n\n\n// Enable/disable the control\n//--------------------------------------------------------------------------------\nvoid CPUTDropdown::SetEnable(bool in_bEnabled)\n{\n    if(in_bEnabled)\n    {\n        mControlState = CPUT_CONTROL_ACTIVE;\n    }\n    else\n    {\n        mControlState = CPUT_CONTROL_INACTIVE;\n    }\n\n    // set the control's text to match\n    mpSelectedItemCopy->SetEnable(in_bEnabled);\n\n    // recalculate control's quads \n    Recalculate();\n}\n\n// Get enabled/disabled state of this control\n//-----------------------------------------------------------------------------\nbool CPUTDropdown::IsEnabled()\n{\n    if(CPUT_CONTROL_INACTIVE == mControlState)\n    {\n        return false;\n    }\n\n    return true;\n}\n\n//\n//-----------------------------------------------------------------------------\nbool CPUTDropdown::ContainsPoint(int x, int y)\n{\n    // clicking the readout box\n    CPUT_RECT inner, outer;\n    CalculateReadoutRect(inner, outer);\n    if( (x>outer.x) &&\n        (x<outer.x+outer.width) &&\n        (y>outer.y) &&\n        (y<outer.y+outer.height) )\n        return true;\n\n    // this is the dimensions of just the top selection\n    // tray = closed\n    if(CPUT_CONTROL_ACTIVE == mControlState)\n    {\n        if(CPUT_DROPDOWN_GUI_MOUSE_NEUTRAL == mControlGuiState)\n        {\n            // button?\n            if( (x< mButtonRect.x) ||\n                (x> mButtonRect.x+mButtonRect.width) ||\n                (y< mButtonRect.y) ||\n                (y> mButtonRect.y+mButtonRect.height) )\n            {\n                return false;\n            }\n            return true;\n        }\n\n        // this is dimensions of top selection + tray\n        // tray = open\n        if(CPUT_DROPDOWN_GUI_MOUSE_PRESSED == mControlGuiState ) //CPUT_CONTROL_PRESSED == mControlState)\n        {\n            // in button area?\n            if( (x> mButtonRect.x) &&\n                (x< mButtonRect.x+mButtonRect.width) &&\n                (y> mButtonRect.y) &&\n                (y< mButtonRect.y+mButtonRect.height) )\n            {\n                return true;\n            }\n\n            // in the tray area?\n            CPUT_RECT inner, outer;\n            CalculateTrayRect(inner, outer);\n\n            if( (x>outer.x) &&\n                (x<outer.x+outer.width) &&\n                (y>outer.y) &&\n                (y<outer.y+outer.height) )\n            {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n//\n//-----------------------------------------------------------------------------\nbool CPUTDropdown::ContainsPointReadoutArea(int x, int y)\n{\n\n    CPUT_RECT inner, outer;\n    CalculateReadoutRect(inner, outer);\n\n    // in the readout box area?\n    if( (x>outer.x) &&\n        (x<outer.x+outer.width) &&\n        (y>outer.y) &&\n        (y<outer.y+outer.height) )\n    {\n        return true;\n    }\n\n    // button area?\n    if( (x> mButtonRect.x) &&\n        (x< mButtonRect.x+mButtonRect.width) &&\n        (y> mButtonRect.y) &&\n        (y< mButtonRect.y+mButtonRect.height) )\n    {\n        return true;\n    }\n\n    return false;\n}\n\n//\n//-----------------------------------------------------------------------------\nbool CPUTDropdown::ContainsPointTrayArea(int x, int y)\n{\n    // this is dimensions of top selection + tray\n    // tray = open\n    if(CPUT_CONTROL_ACTIVE == mControlState)\n    {\n        if(CPUT_DROPDOWN_GUI_MOUSE_PRESSED == mControlGuiState)\n        {\n            // in the tray area?\n            CPUT_RECT inner, outer;\n            CalculateTrayRect(inner, outer);\n\n            if( (x>outer.x) &&\n                (x<outer.x+outer.width) &&\n                (y>outer.y-1) &&\n                (y<outer.y+outer.height) )\n            {\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\n//\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::SetPosition(int x, int y)\n{\n    mControlDimensions.x = x;\n    mControlDimensions.y = y;\n\n    int a,b;\n    CalculateReadoutTextPosition(a,b);\n    if(-1 != mSelectedItemIndex)\n    {\n        mpListOfSelectableItems[mSelectedItemIndex]->SetPosition(a,b);\n    }\n\n    Recalculate();\n}\n\n//\n//-----------------------------------------------------------------------------\nvoid CPUTDropdown::GetDimensions(int &width, int &height)\n{\n    CPUT_RECT inner, outer;\n    CalculateReadoutRect(inner, outer);\n    width = outer.width;\n    height = outer.height;\n}\n\n// Recalculate all the quads used to draw this control\n//--------------------------------------------------------------------------------\nvoid CPUTDropdown::Recalculate()\n{\n    mpDropdownIdleSizeList;\n\n    // calculate height/width of dropdown's interior based on string or button size\n    CPUT_RECT inner, outer;\n    CalculateReadoutRect(inner, outer);\n\n    // calculate the pieces we'll need to rebuild\n    int middleWidth = inner.width;\n    int middleHeight = inner.height;\n\n    // TODO: this should be calculated like \n    const int mSmallestTopSizeIdle = mpDropdownIdleImageSizeList[0].height;\n    const int mSmallestLeftSizeIdle =mpDropdownIdleImageSizeList[0].width;\n\n\n    // clear and allocate the buffers\n    const int VertexCount = 18*3*2;\n    SAFE_DELETE_ARRAY(mpMirrorBufferActive);\n    mpMirrorBufferActive = new CPUTGUIVertex[VertexCount];\n        \n    SAFE_DELETE_ARRAY(mpMirrorBufferDisabled);\n    mpMirrorBufferDisabled = new CPUTGUIVertex[VertexCount];\n\n    //\n    // delete the old button quads for the middle sections\n    //result = UnRegisterResizableInstanceQuads();\n\n    // Calculate the selected item area images\n    // Idle button quads\n    // left\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 0*6, (float)mControlDimensions.x, (float)mControlDimensions.y, (float) mpDropdownIdleImageSizeList[0].width, (float) mpDropdownIdleImageSizeList[0].height, mpDropdownUVCoords_active[2*0], mpDropdownUVCoords_active[2*0+1] );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 1*6, (float)mControlDimensions.x, (float)mControlDimensions.y+mSmallestTopSizeIdle, (float) mpDropdownIdleImageSizeList[1].width, (float) middleHeight, mpDropdownUVCoords_active[2*1], mpDropdownUVCoords_active[2*1+1] );\n    mpDropdownIdleSizeList[1].height = middleHeight;\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 2*6, (float)mControlDimensions.x, (float)mControlDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) mpDropdownIdleImageSizeList[2].width, (float) mpDropdownIdleImageSizeList[2].height, mpDropdownUVCoords_active[2*2], mpDropdownUVCoords_active[2*2+1] );\n\n    // middle\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 3*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle, (float)mControlDimensions.y, (float) middleWidth, (float) mpDropdownIdleImageSizeList[3].height, mpDropdownUVCoords_active[2*3], mpDropdownUVCoords_active[2*3+1] );\n    mpDropdownIdleSizeList[3].width = middleWidth;\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 4*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle, (float)mControlDimensions.y+mSmallestTopSizeIdle, (float) middleWidth, (float) middleHeight, mpDropdownUVCoords_active[2*4], mpDropdownUVCoords_active[2*4+1] );\n    mpDropdownIdleSizeList[4].width = middleWidth;\n    mpDropdownIdleSizeList[4].height = middleHeight;\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 5*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle, (float)mControlDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) middleWidth, (float) mpDropdownIdleImageSizeList[5].height, mpDropdownUVCoords_active[2*5], mpDropdownUVCoords_active[2*5+1] );\n    mpDropdownIdleSizeList[5].width = middleWidth;\n\n    // right\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 6*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mControlDimensions.y, (float) mpDropdownIdleImageSizeList[6].width, (float)mpDropdownIdleImageSizeList[6].height, mpDropdownUVCoords_active[2*6], mpDropdownUVCoords_active[2*6+1] );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 7*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mControlDimensions.y+mSmallestTopSizeIdle, (float) mpDropdownIdleImageSizeList[7].width, (float)middleHeight, mpDropdownUVCoords_active[2*7], mpDropdownUVCoords_active[2*7+1] );\n    mpDropdownIdleSizeList[7].height = middleHeight;\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 8*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mControlDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) mpDropdownIdleImageSizeList[8].width, (float)mpDropdownIdleImageSizeList[8].height, mpDropdownUVCoords_active[2*8], mpDropdownUVCoords_active[2*8+1] );\n\n    // 2 buttons (up and pressed) at same location\n    CPUT_RECT rect;\n    CalculateButtonRect(rect);\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive,  9*6, (float)rect.x, (float)rect.y, (float) mpDropdownIdleImageSizeList[ 9].width, (float)mpDropdownIdleImageSizeList[ 9].height, mpDropdownUVCoords_active[2*9], mpDropdownUVCoords_active[2*9+1] );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive, 10*6, (float)rect.x, (float)rect.y, (float) mpDropdownIdleImageSizeList[10].width, (float)mpDropdownIdleImageSizeList[10].height, mpDropdownUVCoords_active[2*10], mpDropdownUVCoords_active[2*10+1] );\n\n    // if the dropdown tray is active, draw it\n    int index=11;\n    if(CPUT_CONTROL_ACTIVE == mControlState)\n    {\n        if((CPUT_DROPDOWN_GUI_MOUSE_PRESSED == mControlGuiState) && (0 != mpListOfSelectableItems.size()))\n        {\n            CalculateTrayRect(inner, outer);\n            mTrayDimensions.width = inner.width;\n            mTrayDimensions.height = inner.height;\n\n            float tx, ty;\n            tx = (float)outer.x;\n            ty = (float)outer.y;\n\n            CalculateMaxItemSize(mTrayDimensions.width, mTrayDimensions.height);\n            mTrayDimensions.width += 2*CPUT_DROPDOWN_TEXT_PADDING;\n            mTrayDimensions.height = inner.height;\n            \n\n            // lm\n            AddQuadIntoMirrorBuffer(mpMirrorBufferActive,  index*6, (float)tx, (float)ty, (float) mpDropdownIdleImageSizeList[CTrayLM].width, (float)mTrayDimensions.height, mpDropdownUVCoords_active[2*CTrayLM], mpDropdownUVCoords_active[2*CTrayLM+1] );\n            index++;\n\n            // lb\n            ty+=mTrayDimensions.height; // inner.height\n            AddQuadIntoMirrorBuffer(mpMirrorBufferActive,  index*6, (float)tx, (float)ty, (float) mpDropdownIdleImageSizeList[CTrayLB].width, (float)mpDropdownIdleImageSizeList[CTrayLB].height, mpDropdownUVCoords_active[2*CTrayLB], mpDropdownUVCoords_active[2*CTrayLB+1] );\n            index++;\n\n            // mm\n            tx+=mpDropdownIdleImageSizeList[CLeftMid].width;\n            ty = (float)outer.y;\n            AddQuadIntoMirrorBuffer(mpMirrorBufferActive,  index*6, (float)tx, (float)ty, (float) mTrayDimensions.width, (float)mTrayDimensions.height, mpDropdownUVCoords_active[2*CTrayMM], mpDropdownUVCoords_active[2*CTrayMM+1] );\n            index++;\n\n            // mb\n            ty+=mTrayDimensions.height;\n            AddQuadIntoMirrorBuffer(mpMirrorBufferActive,  index*6, (float)tx, (float)ty, (float) mTrayDimensions.width, (float)mpDropdownIdleImageSizeList[CTrayMB].height, mpDropdownUVCoords_active[2*CTrayMB], mpDropdownUVCoords_active[2*CTrayMB+1] );\n            index++;\n\n\n            // rm\n            tx+=mTrayDimensions.width;\n            ty = (float)outer.y;\n            AddQuadIntoMirrorBuffer(mpMirrorBufferActive,  index*6, (float)tx, (float)ty, (float) mpDropdownIdleImageSizeList[CTrayRM].width, (float)mTrayDimensions.height, mpDropdownUVCoords_active[2*CTrayRM], mpDropdownUVCoords_active[2*CTrayRM+1] );\n            index++;\n\n            // rb\n            ty += mTrayDimensions.height;\n            AddQuadIntoMirrorBuffer(mpMirrorBufferActive,  index*6, (float)tx, (float)ty, (float) mpDropdownIdleImageSizeList[CTrayRB].width, (float)mpDropdownIdleImageSizeList[CTrayRB].height, mpDropdownUVCoords_active[2*CTrayRB], mpDropdownUVCoords_active[2*CTrayRB+1] );\n            index++;\n\n\n            // tray highlight\n            int MaxSizeItemWidth, MaxSizeItemHeight;\n            CalculateMaxItemSize(MaxSizeItemWidth, MaxSizeItemHeight);\n\n            int sx = (inner.x + mpDropdownIdleImageSizeList[CLeftMid].width);\n            int sy = (inner.y + CPUT_DROPDOWN_TEXT_PADDING);\n\n            for(UINT i=0;i<mpListOfSelectableItems.size();i++)\n            {\n                if( (mSelectedItemIndex) == i )\n                {\n                    //m = XMMatrixTranslation((float)(sx - CPUT_DROPDOWN_TEXT_PADDING), (float)(sy - CPUT_DROPDOWN_TEXT_PADDING), 0);\n                    AddQuadIntoMirrorBuffer(mpMirrorBufferActive,  index*6, (float)(sx - CPUT_DROPDOWN_TEXT_PADDING), (float)(sy - CPUT_DROPDOWN_TEXT_PADDING), (float) MaxSizeItemWidth + 2*CPUT_DROPDOWN_TEXT_PADDING, (float)MaxSizeItemHeight + CPUT_DROPDOWN_TEXT_PADDING, mpDropdownUVCoords_active[2*CTrayHighlight], mpDropdownUVCoords_active[2*CTrayHighlight+1] );\n                    index++;\n                }\n\n                CPUT_RECT rect;\n                mpListOfSelectableItems[i]->GetDimensions(rect.width, rect.height);\n                sy+=rect.height + 2*CPUT_DROPDOWN_TEXT_PADDING;\n            }\n        }\n    }\n\n    // calculate the disabled item list\n        // left\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 0*6, (float)mControlDimensions.x, (float)mControlDimensions.y, (float) mpDropdownIdleImageSizeList[0].width, (float) mpDropdownIdleImageSizeList[0].height, mpDropdownUVCoords_disabled[2*0], mpDropdownUVCoords_disabled[2*0+1] );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 1*6, (float)mControlDimensions.x, (float)mControlDimensions.y+mSmallestTopSizeIdle, (float) mpDropdownIdleImageSizeList[1].width, (float) middleHeight, mpDropdownUVCoords_disabled[2*1], mpDropdownUVCoords_disabled[2*1+1] );\n    mpDropdownIdleSizeList[1].height = middleHeight;\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 2*6, (float)mControlDimensions.x, (float)mControlDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) mpDropdownIdleImageSizeList[2].width, (float) mpDropdownIdleImageSizeList[2].height, mpDropdownUVCoords_disabled[2*2], mpDropdownUVCoords_disabled[2*2+1] );\n\n    // middle\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 3*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle, (float)mControlDimensions.y, (float) middleWidth, (float) mpDropdownIdleImageSizeList[3].height, mpDropdownUVCoords_disabled[2*3], mpDropdownUVCoords_disabled[2*3+1] );\n    mpDropdownIdleSizeList[3].width = middleWidth;\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 4*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle, (float)mControlDimensions.y+mSmallestTopSizeIdle, (float) middleWidth, (float) middleHeight, mpDropdownUVCoords_disabled[2*4], mpDropdownUVCoords_disabled[2*4+1] );\n    mpDropdownIdleSizeList[4].width = middleWidth;\n    mpDropdownIdleSizeList[4].height = middleHeight;\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 5*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle, (float)mControlDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) middleWidth, (float) mpDropdownIdleImageSizeList[5].height, mpDropdownUVCoords_disabled[2*5], mpDropdownUVCoords_disabled[2*5+1] );\n    mpDropdownIdleSizeList[5].width = middleWidth;\n\n    // right\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 6*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mControlDimensions.y, (float) mpDropdownIdleImageSizeList[6].width, (float)mpDropdownIdleImageSizeList[6].height, mpDropdownUVCoords_disabled[2*6], mpDropdownUVCoords_disabled[2*6+1] );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 7*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mControlDimensions.y+mSmallestTopSizeIdle, (float) mpDropdownIdleImageSizeList[7].width, (float)middleHeight, mpDropdownUVCoords_disabled[2*7], mpDropdownUVCoords_disabled[2*7+1] );\n    mpDropdownIdleSizeList[7].height = middleHeight;\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 8*6, (float)mControlDimensions.x+mSmallestLeftSizeIdle+middleWidth, (float)mControlDimensions.y+mSmallestTopSizeIdle+middleHeight, (float) mpDropdownIdleImageSizeList[8].width, (float)mpDropdownIdleImageSizeList[8].height, mpDropdownUVCoords_disabled[2*8], mpDropdownUVCoords_disabled[2*8+1] );\n\n    // 2 buttons (up and pressed) at same location\n    CalculateButtonRect(rect);\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled,  9*6, (float)rect.x, (float)rect.y, (float) mpDropdownIdleImageSizeList[ 9].width, (float)mpDropdownIdleImageSizeList[ 9].height, mpDropdownUVCoords_disabled[2*9], mpDropdownUVCoords_disabled[2*9+1] );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled, 10*6, (float)rect.x, (float)rect.y, (float) mpDropdownIdleImageSizeList[10].width, (float)mpDropdownIdleImageSizeList[10].height, mpDropdownUVCoords_disabled[2*10], mpDropdownUVCoords_disabled[2*10+1] );   \n\n\n    // -- now handle the text --\n\n    // draw the selected item in the readout display\n    if(-1!=mSelectedItemIndex)\n    {\n        int x,y;\n        CalculateReadoutTextPosition(x,y);\n        cString string;\n        mpListOfSelectableItems[mSelectedItemIndex]->GetString(string);\n        mpSelectedItemCopy->SetText(string);\n        mpSelectedItemCopy->SetPosition(x,y);\n\n        mpListOfSelectableItems[mSelectedItemIndex]->SetPosition(x,y);\n    }\n\n    // calculate each of the individual dropdown text string locations\n    CalculateTrayRect(inner, outer);\n\n    float tx, ty;\n    tx = (float)outer.x;\n    ty = (float)outer.y;\n\n    int sx = (inner.x + mpDropdownIdleImageSizeList[CLeftMid].width);\n    int sy = (inner.y + CPUT_DROPDOWN_TEXT_PADDING);\n\n    for(UINT i=0;i<mpListOfSelectableItems.size();i++)\n    {\n        mpListOfSelectableItems[i]->SetPosition(sx, sy);\n\n        CPUT_RECT rect;\n        mpListOfSelectableItems[i]->GetDimensions(rect.width, rect.height);\n        sy+=rect.height + 2*CPUT_DROPDOWN_TEXT_PADDING;\n    }\n\n    // mark this as dirty\n    mControlGraphicsDirty = true;\n}\n\n\n\n//--------------------------------------------------------------------------------\nvoid CPUTDropdown::DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize, CPUTGUIVertex *pTextVertexBufferMirror, UINT *pTextInsertIndex, UINT MaxTextVertexBufferSize)\n{\n    if(!mControlVisible)\n    {\n        return;\n    }\n\n    if((NULL==pVertexBufferMirror) || (NULL==pInsertIndex))\n    {\n        return;\n    }\n\n    if(!mpMirrorBufferActive )\n    {\n        return;    \n    }\n\n    // Do we have enough room to put this control into the output buffer?\n    int VertexCopyCount = GetOutputVertexCount();\n    ASSERT( (pMaxBufferSize >= *pInsertIndex + VertexCopyCount), _L(\"Too many CPUT GUI controls for allocated GUI buffer. Allocated GUI vertex buffer is too small.\\n\\nIncrease CPUT_GUI_BUFFER_SIZE size.\") );\n    \n    switch(mControlState)\n    {\n    case CPUT_CONTROL_ACTIVE:          \n        // copy the standard part of the control (selected box) - first 9 quads\n        memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferActive, sizeof(CPUTGUIVertex)*6*9);\n        *pInsertIndex+= 6*9;\n\n        if((CPUT_DROPDOWN_GUI_MOUSE_PRESSED == mControlGuiState) )//&& (0 != mpListOfSelectableItems.size()))\n        {\n            // copy the 'down' button\n            memcpy(&pVertexBufferMirror[*pInsertIndex], &mpMirrorBufferActive[10*6], sizeof(CPUTGUIVertex)*6*1);\n        }\n        else\n        {\n            // copy the 'up' button \n            memcpy(&pVertexBufferMirror[*pInsertIndex], &mpMirrorBufferActive[9*6], sizeof(CPUTGUIVertex)*6*1);\n        }\n        *pInsertIndex+= 6*1;\n\n        // tray is down, draw it, +1 for the highlit item\n        if((CPUT_DROPDOWN_GUI_MOUSE_PRESSED == mControlGuiState) && (0 != mpListOfSelectableItems.size()))\n        {\n            int QuadsInTray = 6;\n            memcpy(&pVertexBufferMirror[*pInsertIndex], &mpMirrorBufferActive[11*6], sizeof(CPUTGUIVertex)*6*(QuadsInTray+1));\n            *pInsertIndex+= 6*(QuadsInTray+1);\n        }\n\n        break;\n\n    case CPUT_CONTROL_INACTIVE:\n        // copy the inactive images into the stream\n        memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferDisabled, sizeof(CPUTGUIVertex)*6*10);\n        *pInsertIndex+= 6*10;\n        break;\n\n    default:\n        // error! unknown state\n        ASSERT(0,_L(\"CPUTButton: Control is in unknown state\"));\n        return;\n    }\n\n\n    // -- draw the text --\n    // draw selected item in the selection list\n    if(NULL!=mpSelectedItemCopy)\n    {\n        mpSelectedItemCopy->DrawIntoBuffer((CPUTGUIVertex*)pTextVertexBufferMirror, pTextInsertIndex, MaxTextVertexBufferSize);        \n    }\n\n    // draw the tray items\n    if((CPUT_DROPDOWN_GUI_MOUSE_PRESSED == mControlGuiState) && (0 != mpListOfSelectableItems.size()))\n    {\n        for(UINT i=0;i<mpListOfSelectableItems.size();i++)\n        {\n            mpListOfSelectableItems[i]->DrawIntoBuffer((CPUTGUIVertex*)pTextVertexBufferMirror, pTextInsertIndex, MaxTextVertexBufferSize);\n        }\n    }\n\n    // we'll mark the control as no longer being 'dirty'\n    mControlGraphicsDirty = false;\n}\n\n\n\n\n// This generates a quad with the supplied coordinates/uv's/etc.\n//--------------------------------------------------------------------------------\nvoid CPUTDropdown::AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer, int index, float x, float y, float w, float h, float3 uv1, float3 uv2 )\n{\n    CPUTColor4 color;\n    color.r = 1.0f;color.g = 1.0f;color.b = 1.0f;color.a = 1.0f;\n\n    pMirrorBuffer[index+0].Pos = float3( x + 0.0f, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+0].UV = float2(uv1.x, uv1.y);\n    pMirrorBuffer[index+0].Color = color;\n\n    pMirrorBuffer[index+1].Pos = float3( x + w, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+1].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[index+1].Color = color;\n\n    pMirrorBuffer[index+2].Pos = float3( x + 0.0f, y + h, 1.0f);\n    pMirrorBuffer[index+2].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[index+2].Color = color;\n\n    pMirrorBuffer[index+3].Pos = float3( x + w, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+3].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[index+3].Color = color;\n\n    pMirrorBuffer[index+4].Pos = float3( x + w, y + h, 1.0f);\n    pMirrorBuffer[index+4].UV = float2(uv2.x, uv2.y);\n    pMirrorBuffer[index+4].Color = color;\n\n    pMirrorBuffer[index+5].Pos = float3( x + 0.0f, y +h, 1.0f);\n    pMirrorBuffer[index+5].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[index+5].Color = color;\n}\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTDropdown.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTDROPDOWN_H__\n#define __CPUTDROPDOWN_H__\n\n#include \"CPUTControl.h\"\n\n#include <vector>\n\n\ntypedef enum CPUTDropdownGUIState\n{\n    CPUT_DROPDOWN_GUI_MOUSE_NEUTRAL,\n    CPUT_DROPDOWN_GUI_MOUSE_PRESSED,\n} CPUTDropdownGUIState;\n\n\n\n// forward declarations\nclass CPUTTextureDX11;\nstruct CPUTGUIVertex;\nclass CPUTFont;\nclass CPUTText;\n\n#define CPUT_NUM_IMAGES_IN_DROPDOWN_ARRAY 12\n#define CPUT_NUM_QUADS_IN_DROPDOWN_ARRAY 18\n#define CPUT_NUM_QUADS_IN_CLOSED_DROPDOWN 9\n#define CPUT_DROPDOWN_TEXT_PADDING 2\n\nconst int CLeftTop = 0;\nconst int CLeftMid = 1;\nconst int CLeftBot = 2;\nconst int CMidTop = 3;\nconst int CMidMid = 4;\nconst int CMidBot = 5;\nconst int CRightTop = 6;\nconst int CRightMid = 7;\nconst int CRightBot = 8;\nconst int CButtonUp = 9;\nconst int CButtonDown = 10;\n\n#define CPUT_NUM_IMAGES_IN_DROPDOWN  12\n\n\n// Dropdown base - common functionality for all dropdown controls\n//-----------------------------------------------------------------------------\nclass CPUTDropdown:public CPUTControl\n{\npublic:\n    // button should self-register with the GuiController on create\n    CPUTDropdown(CPUTDropdown& copy);\n    CPUTDropdown(const cString ControlName, CPUTControlID id, CPUTFont *pFont);\n    virtual ~CPUTDropdown();\n\n    // CPUTControl\n    virtual void GetPosition(int &x, int &y);\n    virtual unsigned int GetOutputVertexCount();\n\n    //CPUTEventHandler\n    virtual CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key){UNREFERENCED_PARAMETER(key);return CPUT_EVENT_UNHANDLED;}  \n\n\n    //CPUTEventHandler\n    virtual CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n\n    //CPUTControl\n    virtual void SetEnable(bool in_bEnabled);\n    virtual bool IsEnabled();\n    virtual bool ContainsPoint(int x, int y);\n    virtual bool ContainsPointReadoutArea(int x, int y);\n    virtual bool ContainsPointTrayArea(int x, int y);\n    virtual void SetText(cString ControlText) {;} // doesn't apply to this control\n    virtual void GetText(cString &ControlString) {UNREFERENCED_PARAMETER(ControlString);} // doesn't apply to this control\n    virtual void GetDimensions(int &width, int &height);\n    virtual void SetPosition(int x, int y);\n\n    //CPUTDropdownDX11\n    void NumberOfSelectableItems(UINT &count);\n    void GetSelectedItem(UINT &index);\n    void GetSelectedItem(cString &Item);\n    void SetSelectedItem(const UINT index);\n    CPUTResult AddSelectionItem(const cString Item, bool IsSelected=false);\n    void DeleteSelectionItem(const UINT index);\n    void DeleteSelectionItem(const cString string);\n    \n    // Draw\n    void DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize, CPUTGUIVertex *pTextVertexBufferMirror, UINT *pTextInsertIndex, UINT MaxTextVertexBufferSize);\n\n    // Register assets\n    static CPUTResult RegisterStaticResources();\n    static CPUTResult UnRegisterStaticResources();\n\n    CPUTResult RegisterInstanceResources();\n    CPUTResult UnRegisterInstanceResources();\n\n\n\nprotected:\n    CPUT_RECT               mControlDimensions;\n    CPUTGUIControlState     mControlState;\n    CPUTDropdownGUIState    mControlGuiState;\n    void InitialStateSet();\n\n\n\n    // uber-buffer adds\n    CPUTFont *mpFont;\n    CPUTText *mpButtonText;\n    static CPUT_SIZE mpDropdownIdleImageSizeList[CPUT_NUM_IMAGES_IN_DROPDOWN];    \n    static CPUT_SIZE mpDropdownDisabledSizeList[CPUT_NUM_IMAGES_IN_DROPDOWN];\n\n    // uber-buffer per-instance\n    CPUT_SIZE mpDropdownIdleSizeList[CPUT_NUM_IMAGES_IN_DROPDOWN];    \n    CPUT_SIZE mpDropdownDisabledList[CPUT_NUM_IMAGES_IN_DROPDOWN];\n\n    CPUTGUIVertex *mpMirrorBufferActive;\n    CPUTGUIVertex *mpMirrorBufferDisabled;\n    void Recalculate();\n    void AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer, int index, float x, float y, float w, float h, float3 uv1, float3 uv2 );\n\n\n    // instance data\n    \n    CPUT_RECT mButtonRect;\n    CPUT_RECT mReadoutRectInside;\n    CPUT_RECT mReadoutRectOutside;\n\n    CPUT_RECT mTrayDimensions;\n    bool mbMouseInside;\n    UINT mRevertItem;\n    bool mbStartedClickInside;\n    bool mbStartedClickInsideTray;\n\n    // list of items in the dropdown\n    UINT mSelectedItemIndex;            //zero-based index that tells what item is currently highlighted (soft selected)\n    UINT mConfirmedSelectedItemIndex;   //zero-based index that tells what item was last confirm-selected (hard selected)\n    std::vector<CPUTText*> mpListOfSelectableItems;\n    CPUTText *mpSelectedItemCopy;\n\n    bool mbSizeDirty;\n    UINT mVertexStride; // stride and offsets of the image quads we're drawing on\n    UINT mVertexOffset;\n\n    // helper functions\n    void CalculateButtonRect(CPUT_RECT& button);\n    void CalculateReadoutRect(CPUT_RECT& inner, CPUT_RECT& outer);\n    void CalculateTrayRect(CPUT_RECT& inner, CPUT_RECT& outer);\n\n    void CalculateReadoutTextPosition(int &x, int &y);\n    void CalculateMaxItemSize(int &width, int &height);\n\n    // sets which item is to be highlighted on a dropdown list\n    void SetHighlightedItem(const UINT index);\n\n};\n\n#endif //#ifndef __CPUTDROPDOWN_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTEventHandler.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTEVENTHANDLER_H__\n#define __CPUTEVENTHANDLER_H__\n\n#include <stdio.h>\n\n// event handling enums\n//-----------------------------------------------------------------------------\nenum CPUTKey\n{\n    KEY_NONE,\n\n    // caps keys\n    KEY_A,\n    KEY_B,\n    KEY_C,\n    KEY_D,\n    KEY_E,\n    KEY_F,\n    KEY_G,\n    KEY_H,\n    KEY_I,\n    KEY_J,\n    KEY_K,\n    KEY_L,\n    KEY_M,\n    KEY_N,\n    KEY_O,\n    KEY_P,\n    KEY_Q,\n    KEY_R,\n    KEY_S,\n    KEY_T,\n    KEY_U,\n    KEY_V,\n    KEY_W,\n    KEY_X,\n    KEY_Y,\n    KEY_Z,\n\n    // number keys\n    KEY_1,\n    KEY_2,\n    KEY_3,\n    KEY_4,\n    KEY_5,\n    KEY_6,\n    KEY_7,\n    KEY_8,\n    KEY_9,\n    KEY_0,\n\n    // symbols\n    KEY_SPACE,\n    KEY_BACKQUOTE,\n    KEY_TILDE,\n    KEY_EXCLAMATION,\n    KEY_AT,\n    KEY_HASH,\n    KEY_$,\n    KEY_PERCENT,\n    KEY_CARROT,\n    KEY_ANDSIGN,\n    KEY_STAR,\n    KEY_OPENPAREN,\n    KEY_CLOSEPARN,\n    KEY__,\n    KEY_MINUS,\n    KEY_PLUS,\n\n    KEY_OPENBRACKET,\n    KEY_CLOSEBRACKET,\n    KEY_OPENBRACE,\n    KEY_CLOSEBRACE,\n    KEY_BACKSLASH,\n    KEY_PIPE,\n    KEY_SEMICOLON,\n    KEY_COLON,\n    KEY_SINGLEQUOTE,\n    KEY_QUOTE,\n    KEY_COMMA,\n    KEY_PERIOD,\n    KEY_SLASH,\n    KEY_LESS,\n    KEY_GREATER,\n    KEY_QUESTION,\n\n    // function keys\n    KEY_F1,\n    KEY_F2,\n    KEY_F3,\n    KEY_F4,\n    KEY_F5,\n    KEY_F6,\n    KEY_F7,\n    KEY_F8,\n    KEY_F9,\n    KEY_F10,\n    KEY_F11,\n    KEY_F12,\n\n    // special keys\n    KEY_HOME,\n    KEY_END,\n    KEY_INSERT,\n    KEY_DELETE,\n    KEY_PAGEUP,\n    KEY_PAGEDOWN,\n\n    KEY_UP,\n    KEY_DOWN,\n    KEY_LEFT,\n    KEY_RIGHT,\n\n    KEY_BACKSPACE,\n    KEY_ENTER,\n    KEY_TAB,\n    KEY_PAUSE,\n    KEY_CAPSLOCK,\n    KEY_ESCAPE,\n\n    // control keys\n    KEY_LEFT_SHIFT,\n    KEY_RIGHT_SHIFT,\n    KEY_LEFT_CTRL,\n    KEY_RIGHT_CTRL,\n    KEY_LEFT_ALT,\n    KEY_RIGHT_ALT,\n};\n\n// these must be unique because we bitwise && them to get multiple states\nenum CPUTMouseState\n{\n    CPUT_MOUSE_NONE = 0,\n    CPUT_MOUSE_LEFT_DOWN = 1,\n    CPUT_MOUSE_RIGHT_DOWN = 2,\n    CPUT_MOUSE_MIDDLE_DOWN = 4,\n    CPUT_MOUSE_CTRL_DOWN = 8,\n    CPUT_MOUSE_SHIFT_DOWN = 16,\n    CPUT_MOUSE_WHEEL = 32,\n};\n\nenum CPUTEventHandledCode\n{\n    CPUT_EVENT_HANDLED = 0,\n    CPUT_EVENT_UNHANDLED = 1,\n    CPUT_EVENT_PASSTHROUGH = 2,\n};\n\n\n// Event handler interface - used by numerous classes in the system\nclass CPUTEventHandler\n{\npublic:\n    virtual CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key)=0;\n    virtual CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state)=0;\n};\n\n\n#endif //#ifndef __CPUTEVENTHANDLER_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTFont.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTFont.h\"\n#ifdef CPUT_FOR_DX11\n#include \"CPUTFontDX11.h\"\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n\n\n\nint gFontMap_active[] =\n{\n    'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',            // lower\n    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',            // upper\n    '1','2','3','4','5','6','7','8','9','0',                                                                            // numbers\n    ',', '.','/',';','\\'','[',']','\\\\','`','~','!','@','#','$','%','^','&','*','(',')','_','+','{','}','|',':','\\\"','<','>','?','-','=', // symbols\n    ' ','\\t',                                                                                                                // space, tab\n    -1\n};\n\n//-----------------------------------------------------------------------------\nCPUTFont *CPUTFont::CreateFont( cString FontName, cString AbsolutePathAndFilename )\n{\n    // TODO: accept DX11/OGL param to control which platform we generate.\n    // TODO: be sure to support the case where we want to support only one of them\n#ifdef CPUT_FOR_DX11\n    return CPUTFontDX11::CreateFont( FontName, AbsolutePathAndFilename );\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n\n}\n\n// return the size in pixels of the glyph\n//-----------------------------------------------------------------------------\nCPUT_SIZE CPUTFont::GetGlyphSize(const char c)\n{    \n    CPUT_SIZE size;\n    size.height=0;\n    size.width=0;\n\n    int index = FindGlyphIndex(c);\n    if(-1!=index)\n    {\n        size.width=mpGlyphSizes[index].width;\n        size.height=mpGlyphSizes[index].height;\n    }\n\n    return size;\n}\n\n// return the uv coordinates for the given glyph\n// upper left/lower right\n//-----------------------------------------------------------------------------\nvoid CPUTFont::GetGlyphUVS(const char c, const bool bEnabledVersion, float3 &UV1, float3 &UV2)\n{\n    int index = FindGlyphIndex(c);\n    if(-1!=index)\n    {\n        if(bEnabledVersion)\n        {\n            UV1.x=mpGlyphUVCoords[4*index+0];\n            UV1.y=mpGlyphUVCoords[4*index+1];\n            UV2.x=mpGlyphUVCoords[4*index+2];\n            UV2.y=mpGlyphUVCoords[4*index+3];        \n        }\n        else\n        {\n            UV1.x=mpGlyphUVCoordsDisabled[4*index+0];\n            UV1.y=mpGlyphUVCoordsDisabled[4*index+1];\n            UV2.x=mpGlyphUVCoordsDisabled[4*index+2];\n            UV2.y=mpGlyphUVCoordsDisabled[4*index+3];   \n        }\n    }    \n}\n\n// find the index of the glyph that corresponds to the char passed in\n//-----------------------------------------------------------------------------\nint CPUTFont::FindGlyphIndex(const char c)\n{\n    int index=0;\n    while(-1 != gFontMap_active[index])\n    {\n        if(c == gFontMap_active[index])\n        {\n            return index;\n        }\n        index++;\n    }\n\n    // not found\n    return -1;\n}\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTFont.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTFONT_H__\n#define __CPUTFONT_H__\n\n#include \"CPUT.h\"\n#include \"CPUTRefCount.h\"\n\n#define CPUT_MAX_NUMBER_OF_CHARACTERS 256\n\nclass CPUTFont : public CPUTRefCount\n{\nfriend class CPUTFontDX11;\n\npublic:\n    static CPUTFont *CreateFont( cString FontName, cString AbsolutePathAndFilename);\n    \n    CPUT_SIZE GetGlyphSize(const char c);\n    void GetGlyphUVS(const char c, const bool bEnabledVersion, float3& UV1, float3& UV2);\n\nprotected:\n    ~CPUTFont(){}  // Destructor is not public.  Must release instead of delete.\n\n    // atlas texture info\n    float mAtlasWidth;\n    float mAtlasHeight;\n    float mDisabledYOffset;\n    UINT mNumberOfGlyphsInAtlas;\n\n    int mpGlyphMap[CPUT_MAX_NUMBER_OF_CHARACTERS];    \n\n    int mpGlyphStarts[CPUT_MAX_NUMBER_OF_CHARACTERS];\n    CPUT_SIZE mpGlyphSizes[CPUT_MAX_NUMBER_OF_CHARACTERS];\n    float mpGlyphUVCoords[4*CPUT_MAX_NUMBER_OF_CHARACTERS]; // 4 floats/glyph = upper-left:(uv1.x, uv1.y), lower-right:(uv2.x, uv2.y)\n    float mpGlyphUVCoordsDisabled[4*CPUT_MAX_NUMBER_OF_CHARACTERS]; // 4 floats/glyph = upper-left:(uv1.x, uv1.y), lower-right:(uv2.x, uv2.y)\n\n    // helper functions\n    int FindGlyphIndex(const char c);\n};\n\n#endif // #ifndef __CPUTFONT_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTFontDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTFontDX11.h\"\n#include \"CPUTTextureDX11.h\"\n\nint gFontStartLocations_active[] =\n{\n    // auto-generated by off-line tool\n    0,7,15,22,30,37,42,50,58,61,66,73,77,                   //a-m\n    88,96,104,111,119,124,132,137,144,152,162,170,178,      //n-z\n    185,195,204,213,223,231,239,249,258,262,270,279,287,    //A-M\n    297,306,317,325,335,344,352,360,369,379,392,401,410,    //N-Z\n    419,425,432,440,448,456,463,470,478,485,                //1-0\n    493,497,500,506,510,515,520,525,530,535,543,547,561,    //symbols ,-#\n    569,577,589,596,606,612,616,621,629,637,642,648,653,    //symbols $-:\n    657,664,672,680,688,694,701                             //symbols \"-=\n    ,705,755,                                               //dead spot used for the space char and tab\n    -1,                                                     //end marker\n};\n\n// height of the font\nconst int gFontHeight = 12;\n\n// y offset to get to the next font down (the disabled font)\nconst int gYOffset = 12;\n    \n//-----------------------------------------------------------------------------\nCPUTFont *CPUTFontDX11::CreateFont( cString FontName, cString AbsolutePathAndFilename )\n{\n    CPUTFontDX11 *pNewFont = new CPUTFontDX11();\n\n    // load the actual font image\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary();\n    pNewFont->mpTextAtlas= (CPUTTextureDX11*) pAssetLibrary->GetTexture(AbsolutePathAndFilename, true);\n    ASSERT(pNewFont->mpTextAtlas, _L(\"CPUTFontDX11::CreateFont() - Error loading specified font texture\"));\n    // get the TextureResourceView\n    pNewFont->mpTextAtlasView = pNewFont->mpTextAtlas->GetShaderResourceView();\n    pNewFont->mpTextAtlasView->AddRef();\n    // CPUTSetDebugName( pNewFont->mpTextAtlasView, _L(\"GUI TextAtlasView\"));\n    \n    // Get and store the atlas size\n    D3D11_TEXTURE2D_DESC TextureDesc;\n    ID3D11Texture2D *p2DTexture = NULL;\n\n    // get the ID3D11Resource from the ID3D11ShaderResourceView\n    ID3D11Resource *pResource = NULL;\n    pNewFont->mpTextAtlasView->GetResource(&pResource);\n\n    // get the ID3D11Texture2D from the ID3D11Resource\n    HRESULT hr = pResource->QueryInterface(__uuidof(ID3D11Texture2D) ,(void**)&p2DTexture);\n    ASSERT( SUCCEEDED(hr), _L(\"CPUTFontDX11::CreateFont() - Error loading specified font texture\"));\n    p2DTexture->GetDesc(&TextureDesc);\n        \n    // store the image dimensions/size\n    pNewFont->mAtlasWidth = (float)TextureDesc.Width;\n    pNewFont->mAtlasHeight = (float)TextureDesc.Height;\n    \n    // release the pointers\n    SAFE_RELEASE(pResource);\n    SAFE_RELEASE(p2DTexture);\n\n    // todo: can use the tick marks above each glyph to determine start/stop\n    // But this requires me to be able to map the texture so I can walk it and find the glyph start/stop\n    // points.  Currently we register all textures as immutable, so we can't map the texture. \n    // For now, I have an offline tool generate the mappings found in gFontStartLocations_active[]\n        \n    int index=0;\n    while(-1 != gFontStartLocations_active[index])\n    {\n        // record the start location\n        pNewFont->mpGlyphStarts[index] = gFontStartLocations_active[index];\n\n        // calculate the size of each glyph in pixels\n        pNewFont->mpGlyphSizes[index].width = gFontStartLocations_active[index+1] - gFontStartLocations_active[index];\n        pNewFont->mpGlyphSizes[index].height = gFontHeight-1; // -1 for top line of glyph start marker dots\n\n        // calculate the UV coordinates for the 'enabled' version of this glyph\n        pNewFont->mpGlyphUVCoords[4*index+0] = gFontStartLocations_active[index]/pNewFont->mAtlasWidth;       // u1 - upper left x\n        pNewFont->mpGlyphUVCoords[4*index+1] = 1.0f/pNewFont->mAtlasHeight;                                   // v1 - upper left y\n        pNewFont->mpGlyphUVCoords[4*index+2] = gFontStartLocations_active[index+1]/pNewFont->mAtlasWidth;     // u2 - lower right x\n        pNewFont->mpGlyphUVCoords[4*index+3] = gFontHeight/pNewFont->mAtlasHeight;                            // v2 - lower right y\n\n        // calculate the UV coordinates of the 'disabled'/greyed version of this glyph\n        pNewFont->mpGlyphUVCoordsDisabled[4*index+0] = gFontStartLocations_active[index]/pNewFont->mAtlasWidth;       // u1 - upper left x\n        pNewFont->mpGlyphUVCoordsDisabled[4*index+1] = (gYOffset+1)/pNewFont->mAtlasHeight;                           // v1 - upper left y\n        pNewFont->mpGlyphUVCoordsDisabled[4*index+2] = gFontStartLocations_active[index+1]/pNewFont->mAtlasWidth;     // u2 - lower right x\n        pNewFont->mpGlyphUVCoordsDisabled[4*index+3] = (gFontHeight+gYOffset)/pNewFont->mAtlasHeight;                 // v2 - lower right y\n\n\n        index++;\n    }\n    pNewFont->mNumberOfGlyphsInAtlas = index;\n\n    // add font to the asset library\n    CPUTAssetLibrary::GetAssetLibrary()->AddFont( FontName, pNewFont);\n\n    return pNewFont; \n}\n\n\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTFontDX11::CPUTFontDX11():mpTextAtlas(NULL),\n    mpTextAtlasView(NULL)\n{\n    mDisabledYOffset = 0;\n}\n\n// Destructor\n//-----------------------------------------------------------------------------\nCPUTFontDX11::~CPUTFontDX11()\n{\n    // release the texture atlas\n    SAFE_RELEASE(mpTextAtlasView);\n    SAFE_RELEASE(mpTextAtlas);    \n}\n\n// Return the texture atlas texture\n//-----------------------------------------------------------------------------\nCPUTTextureDX11* CPUTFontDX11::GetAtlasTexture()\n{\n    return mpTextAtlas;\n}\n\n// Return the texture atlas texture resource view\n//-----------------------------------------------------------------------------\nID3D11ShaderResourceView* CPUTFontDX11::GetAtlasTextureResourceView()\n{\n    return mpTextAtlasView;\n}\n\n\n\n// Load glyph mapping file\n// The map file in an ordered list that tells you which glyph in the texture\n// corresponds to the ASCII character value in this file (char->image lookup)\n//--------------------------------------------------------------------------------\nCPUTResult CPUTFontDX11::LoadGlyphMappingFile(const cString fileName)\n{\n    return CPUT_SUCCESS;\n}\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTFontDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTFONTDX11_H__\n#define __CPUTFONTDX11_H__\n\n#include \"CPUT.h\"\n#include \"CPUTRefCount.h\"\n#include \"CPUTFont.h\"\n\nclass CPUTTextureDX11;\n\n\n\nclass CPUTFontDX11 : public CPUTFont\n{\nprotected:\n    ~CPUTFontDX11(); // Destructor is not public.  Must release instead of delete.\n\npublic:\n    CPUTFontDX11();\n    static CPUTFont *CreateFont( cString FontName, cString AbsolutePathAndFilename);\n\n    CPUTTextureDX11 *GetAtlasTexture();\n    ID3D11ShaderResourceView *GetAtlasTextureResourceView();\n\n\nprivate:\n    CPUTTextureDX11            *mpTextAtlas;\n    ID3D11ShaderResourceView   *mpTextAtlasView;\n\n    \n    CPUTResult LoadGlyphMappingFile(const cString fileName);\n\n\n\n    \n\n};\n\n#endif // #ifndef __CPUTFONTDX11_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTFrustum.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTFrustum.h\"\n#include \"CPUTCamera.h\"\n\n//-----------------------------------------------\nvoid CPUTFrustum::InitializeFrustum( CPUTCamera *pCamera )\n{\n    InitializeFrustum(\n        pCamera->GetNearPlaneDistance(),\n        pCamera->GetFarPlaneDistance(),\n        pCamera->GetAspectRatio(),\n        pCamera->GetFov(),\n        pCamera->GetPosition(),\n        pCamera->GetLook(),\n        pCamera->GetUp()\n    );\n}\n\n//-----------------------------------------------\nvoid CPUTFrustum::InitializeFrustum\n(\n    float nearClipDistance,\n    float farClipDistance,\n    float aspectRatio,\n    float fov,\n    const float3 &position,\n    const float3 &look,\n    const float3 &up\n)\n{\n    // ******************************\n    // This function computes the position of each of the frustum's eight points.\n    // It also computes the normal of each of the frustum's six planes.\n    // ******************************\n\n    mNumFrustumVisibleModels = 0;\n    mNumFrustumCulledModels  = 0;\n\n    // We have the camera's up and look, but we also need right.\n    float3 right = cross3( up, look );\n\n    // Compute the position of the center of the near and far clip planes.\n    float3 nearCenter = position + look * nearClipDistance;\n    float3 farCenter  = position + look * farClipDistance;\n\n    // Compute the width and height of the near and far clip planes\n    float tanHalfFov = tanf(0.5f*fov);\n    float halfNearHeight = nearClipDistance * tanHalfFov;\n    float halfNearWidth  = halfNearHeight * aspectRatio;\n\n    float halfFarHeight  = farClipDistance * tanHalfFov;\n    float halfFarWidth   = halfFarHeight  * aspectRatio;\n\n    // Create two vectors each for the near and far clip planes.\n    // These are the scaled up and right vectors.\n    float3 upNear      = up    * halfNearHeight;\n    float3 rightNear   = right * halfNearWidth;\n    float3 upFar       = up    * halfFarHeight;\n    float3 rightFar    = right * halfFarWidth;\n\n    // Use the center positions and the up and right vectors\n    // to compute the positions for the near and far clip plane vertices (four each)\n    mpPosition[0] = nearCenter + upNear - rightNear; // near top left\n    mpPosition[1] = nearCenter + upNear + rightNear; // near top right\n    mpPosition[2] = nearCenter - upNear + rightNear; // near bottom right\n    mpPosition[3] = nearCenter - upNear - rightNear; // near bottom left\n    mpPosition[4] = farCenter  + upFar  - rightFar;  // far top left\n    mpPosition[5] = farCenter  + upFar  + rightFar;  // far top right\n    mpPosition[6] = farCenter  - upFar  + rightFar;  // far bottom right\n    mpPosition[7] = farCenter  - upFar  - rightFar;  // far bottom left\n\n    // Compute some of the frustum's edge vectors.  We will cross these\n    // to get the normals for each of the six planes.\n    float3 nearTop     = mpPosition[1] - mpPosition[0];\n    float3 nearLeft    = mpPosition[3] - mpPosition[0];\n    float3 topLeft     = mpPosition[4] - mpPosition[0];\n    float3 bottomRight = mpPosition[2] - mpPosition[6];\n    float3 farRight    = mpPosition[5] - mpPosition[6];\n    float3 farBottom   = mpPosition[7] - mpPosition[6];\n\n    mpNormal[0] = cross3(nearTop,     nearLeft).normalize();    // near clip plane\n    mpNormal[1] = cross3(nearLeft,    topLeft).normalize();     // left\n    mpNormal[2] = cross3(topLeft,     nearTop).normalize();     // top\n    mpNormal[3] = cross3(farBottom,   bottomRight).normalize(); // bottom\n    mpNormal[4] = cross3(bottomRight, farRight).normalize();    // right\n    mpNormal[5] = cross3(farRight,    farBottom).normalize();   // far clip plane\n}\n\n//-----------------------------------------------\nbool CPUTFrustum::IsVisible(\n    const float3 &center,\n    const float3 &half\n){\n    // TODO:  There are MUCH more efficient ways to do this.\n    float3 pBoundingBoxPosition[8];\n    pBoundingBoxPosition[0] = center + float3(  half.x,  half.y,  half.z );\n    pBoundingBoxPosition[1] = center + float3(  half.x,  half.y, -half.z );\n    pBoundingBoxPosition[2] = center + float3(  half.x, -half.y,  half.z );\n    pBoundingBoxPosition[3] = center + float3(  half.x, -half.y, -half.z );\n    pBoundingBoxPosition[4] = center + float3( -half.x,  half.y,  half.z );\n    pBoundingBoxPosition[5] = center + float3( -half.x,  half.y, -half.z );\n    pBoundingBoxPosition[6] = center + float3( -half.x, -half.y,  half.z );\n    pBoundingBoxPosition[7] = center + float3( -half.x, -half.y, -half.z );\n\n    // Test each bounding box point against each of the six frustum planes.\n    // Note: we need a point on the plane to compute the distance to the plane.\n    // We only need two of our frustum's points to do this.  A corner vertex is on\n    // three of the six planes.  We need two of these corners to have a point\n    // on all six planes.\n    UINT pPointIndex[6] = {0,0,0,6,6,6};\n    UINT ii;\n    for( ii=0; ii<6; ii++ )\n    {\n        bool allEightPointsOutsidePlane = true;\n        float3 *pNormal = &mpNormal[ii];\n        float3 *pPlanePoint = &mpPosition[pPointIndex[ii]];\n        float3 planeToPoint;\n        float distanceToPlane;\n        UINT jj;\n        for( jj=0; jj<8; jj++ )\n        {\n            planeToPoint = pBoundingBoxPosition[jj] - *pPlanePoint;\n            distanceToPlane = dot3( *pNormal, planeToPoint );\n            if( distanceToPlane < 0.0f )\n            {\n                allEightPointsOutsidePlane = false;\n                break; // from for.  No point testing any more points against this plane.\n            }\n        }\n        if( allEightPointsOutsidePlane )\n        {\n            mNumFrustumCulledModels++;\n            return false;\n        }\n    }\n\n    // Tested all eight points against all six planes and none of the planes\n    // had all eight points outside.\n    mNumFrustumVisibleModels++;\n    return true;\n}\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTFrustum.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTFRUSTUM_H\n#define _CPUTFRUSTUM_H\n\n#include \"CPUT.h\"\n#include \"CPUTMath.h\"\n\nclass CPUTCamera;\n\nclass CPUTFrustum\n{\npublic:\n    float3 mpPosition[8];\n    float3 mpNormal[6];\n\n    UINT mNumFrustumVisibleModels;\n    UINT mNumFrustumCulledModels;\n\n    CPUTFrustum(){}\n    ~CPUTFrustum(){}\n\n    void InitializeFrustum\n    (\n        float nearClipDistance,\n        float farClipDistance,\n        float aspectRatio,\n        float fov,\n        const float3 &position,\n        const float3 &look,\n        const float3 &up\n    );\n\n    void InitializeFrustum( CPUTCamera *pCamera );\n\n    bool IsVisible(\n        const float3 &center,\n        const float3 &half\n    );\n\n};\n\n#endif // _CPUTFRUSTUM_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTGeometryShaderDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n\n#include \"CPUTGeometryShaderDX11.h\"\n#include \"CPUTAssetLibraryDX11.h\"\n\nCPUTGeometryShaderDX11 *CPUTGeometryShaderDX11::CreateGeometryShader(\n    const cString        &name,\n    ID3D11Device         *pD3dDevice,\n    const cString        &shaderMain,\n    const cString        &shaderProfile\n)\n{\n    ID3DBlob             *pCompiledBlob = NULL;\n    ID3D11GeometryShader *pNewGeometryShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromFile(name, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling Geometry shader:\\n\\n\") );\n\n    // Create the Geometry shader\n    // TODO: Move to Geometry shader class\n    HRESULT hr = pD3dDevice->CreateGeometryShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewGeometryShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating Geometry shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetGeometryShader \")+name;\n    // CPUTSetDebugName(pNewGeometryShader, DebugName);\n\n    CPUTGeometryShaderDX11 *pNewCPUTGeometryShader = new CPUTGeometryShaderDX11( pNewGeometryShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddGeometryShader(name + shaderMain + shaderProfile, pNewCPUTGeometryShader);\n    // pNewCPUTGeometryShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTGeometryShader;\n}\n\n//--------------------------------------------------------------------------------------\nCPUTGeometryShaderDX11 *CPUTGeometryShaderDX11::CreateGeometryShaderFromMemory(\n    const cString        &name,\n    ID3D11Device         *pD3dDevice,\n    const cString        &shaderMain,\n    const cString        &shaderProfile,\n    const char           *pShaderSource\n)\n{\n    ID3DBlob             *pCompiledBlob = NULL;\n    ID3D11GeometryShader *pNewGeometryShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromMemory(pShaderSource, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error creating Geometry shader:\\n\\n\") );\n\n    // Create the Geometry shader\n    // TODO: Move to Geometry shader class\n    HRESULT hr = pD3dDevice->CreateGeometryShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewGeometryShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error compiling Geometry shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetGeometryShader \")+name;\n    // CPUTSetDebugName(pNewGeometryShader, DebugName);\n\n    CPUTGeometryShaderDX11 *pNewCPUTGeometryShader = new CPUTGeometryShaderDX11( pNewGeometryShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddGeometryShader(name + shaderMain + shaderProfile, pNewCPUTGeometryShader);\n    // pNewCPUTGeometryShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTGeometryShader;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTGeometryShaderDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTGEOMETRYSHADERDX11_H\n#define _CPUTGEOMETRYSHADERDX11_H\n\n#include \"CPUT.h\"\n#include \"CPUTShaderDX11.h\"\n\nclass CPUTGeometryShaderDX11 : public CPUTShaderDX11\n{\nprotected:\n    ID3D11GeometryShader *mpGeometryShader;\n\n    // Destructor is not public.  Must release instead of delete.\n    ~CPUTGeometryShaderDX11(){ SAFE_RELEASE(mpGeometryShader); }\n\npublic:\n    static CPUTGeometryShaderDX11 *CreateGeometryShader(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile\n    );\n    static CPUTGeometryShaderDX11 *CreateGeometryShaderFromMemory(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile,\n        const char           *pShaderSource\n    );\n\n\n    CPUTGeometryShaderDX11() : mpGeometryShader(NULL), CPUTShaderDX11(NULL) {}\n    CPUTGeometryShaderDX11(ID3D11GeometryShader *pD3D11GeometryShader, ID3DBlob *pBlob) : mpGeometryShader(pD3D11GeometryShader), CPUTShaderDX11(pBlob) {}\n    ID3DBlob *GetBlob() { return mpBlob; }\n    ID3D11GeometryShader *GetNativeGeometryShader() { return mpGeometryShader; }\n};\n\n#endif //_CPUTGEOMETRYSHADER_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTGuiController.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTGuiController.h\"\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTGuiController::CPUTGuiController():\n    mControlPanelIDList(NULL),\n    mActiveControlPanelSlotID(CPUT_CONTROL_ID_INVALID),\n    mpHandler(NULL),\n    mpFocusControl(NULL),\n    mbAutoLayout(true),\n    mResourceDirectory(_L(\"./\")),\n    mUberBufferDirty(true),\n    mRecalculateLayout(false)\n{\n    // clear all controls and panel lists\n    DeleteAllControls();\n}\n\n// Destructor\n//-----------------------------------------------------------------------------\nCPUTGuiController::~CPUTGuiController()\n{\n    // cleanup\n    DeleteAllControls();\n}\n\n//CPUTEventHandler members\n\n// Handle mouse events\n// The gui controller dispatches the event to each control until handled or\n// it passes through unhandled\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode CPUTGuiController::HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state)\n{\n    // if there is no active panel, then we just return\n    if(CPUT_CONTROL_ID_INVALID == mActiveControlPanelSlotID)\n    {\n        return CPUT_EVENT_PASSTHROUGH;\n    }\n\n    // walk the list of controls on the screen and see if they are to handle any of these events\n    CPUTEventHandledCode EventResult = CPUT_EVENT_PASSTHROUGH;\n    for(UINT i=0; i<mControlPanelIDList[mActiveControlPanelSlotID]->mControlList.size(); i++)\n    {\n        if(CPUT_EVENT_HANDLED == EventResult)\n        {\n            // walk the rest of the controls, updating them with the event, but with an 'invalid' location\n            // this is a not-so-great but works bug fix for this problem:\n            // If you click on another control besides a dropped-down dropdown, then you get a painting error\n            // You need to send a closed event to any remaining dropdowns...\n            mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[i]->HandleMouseEvent(-1,-1,wheel,state);\n        }\n        else\n        {\n            EventResult = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[i]->HandleMouseEvent(x,y,wheel,state);\n\n            // if the control says it handled this event, do not pass it through to underlying controls\n            // this is important for things like dropdowns that could dynamically overlap other controls\n            if( CPUT_EVENT_HANDLED == EventResult)\n            {\n                mpFocusControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[i];\n                //return EventResult;\n            }\n        }\n    }\n\n    return EventResult; //CPUT_EVENT_PASSTHROUGH;\n}\n\n// Turns on/off automatic arrangement of controls on right side of screen\n//-----------------------------------------------------------------------------\nvoid CPUTGuiController::EnableAutoLayout(bool UseAutoLayout)\n{\n    mbAutoLayout = UseAutoLayout;\n}\n\n// sets the resource directory to use when loading GUI resources\n//-----------------------------------------------------------------------------\nCPUTResult CPUTGuiController::SetResourceDirectory(const cString ResourceDirectory)\n{\n    // check to see if the specified directory is valid\n    CPUTResult result = CPUT_SUCCESS;\n\n    // resolve the directory to a full path\n    cString FullPath;\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    result = pServices->ResolveAbsolutePathAndFilename(ResourceDirectory, &FullPath);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n    // check existence of directory\n    result = pServices->DoesDirectoryExist(FullPath);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n    // set the resource directory (absolute path)\n    mResourceDirectory = FullPath;\n\n    return result;\n}\n\n// gets the resource directory used when loading GUI resources\n//-----------------------------------------------------------------------------\nvoid CPUTGuiController::GetResourceDirectory(cString &ResourceDirectory)\n{\n    ResourceDirectory = mResourceDirectory;\n}\n\n\n\n// Panels\n\n// finds panel with matching ID and sets it as the active one\n// if panelID is CPUT_CONTROL_ID_INVALID - it will disable all panels\n//-----------------------------------------------------------------------------\nCPUTResult CPUTGuiController::SetActivePanel(CPUTControlID panelID)\n{\n    CPUTControlID panelSlotID = FindPanelIDIndex(panelID);\n\n    // if we found it, set it active\n    if(CPUT_CONTROL_ID_INVALID == panelSlotID)\n    {\n        return CPUT_ERROR_NOT_FOUND;\n    }\n\n    // store previously active control\n    mControlPanelIDList[mActiveControlPanelSlotID]->mpFocusControl = mpFocusControl;\n\n    // change the active panel and refresh screen\n    mActiveControlPanelSlotID = panelSlotID;\n    mpFocusControl = mControlPanelIDList[mActiveControlPanelSlotID]->mpFocusControl;\n\n    // trigger refresh\n    if(mbAutoLayout)\n    {\n        Resize();\n    }\n\n    return CPUT_SUCCESS;\n}\n\n// returns the ID of the active panel\n//-----------------------------------------------------------------------------\nCPUTControlID CPUTGuiController::GetActivePanelID()\n{\n    if(CPUT_CONTROL_ID_INVALID == mActiveControlPanelSlotID)\n        return CPUT_CONTROL_ID_INVALID;\n\n    return mControlPanelIDList[mActiveControlPanelSlotID]->mpanelID;\n}\n\n// Get the list of controls currently being displayed\n//-----------------------------------------------------------------------------\nCPUTResult CPUTGuiController::GetActiveControlList(std::vector<CPUTControl*> *ppControlList)\n{\n\tASSERT(ppControlList != NULL, _L(\"CPUTGuiController::GetActiveControlList - pControlList is NULL\"));\n\n    if(CPUT_CONTROL_ID_INVALID == mActiveControlPanelSlotID)\n    {\n        // return CPUT_GUI_INVALID_CONTROL_ID;\n    }\n\n    if(NULL==ppControlList)\n    {\n        return CPUT_ERROR_INVALID_PARAMETER;\n    }\n\n    // todo: make a copy instead to avoid deletion problems?\n    *ppControlList = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList;\n\n    return CPUT_SUCCESS;\n}\n\n\n// removes specified control from the panel (does not delete the control)\n//-----------------------------------------------------------------------------\nCPUTResult CPUTGuiController::RemoveControlFromPanel(CPUTControlID controlID, CPUTControlID panelID)\n{\n    CPUTControlID panelSlotID;\n    if(CPUT_CONTROL_ID_INVALID==panelID)\n    {\n        // use the currently active panel if none specified\n        panelSlotID = mActiveControlPanelSlotID;\n    }\n    else\n    {\n        panelSlotID = FindPanelIDIndex(panelID);\n    }\n\n    // invalid panel\n    //if(CPUT_CONTROL_ID_INVALID == panelSlotID)\n        //return CPUT_ERROR_INVALID_PARAMETER;\n\n    // walk list of controls in the panel and see if control is there\n    for(UINT i=0; i<mControlPanelIDList[panelSlotID]->mControlList.size(); i++)\n    {\n        if( controlID == mControlPanelIDList[panelSlotID]->mControlList[i]->GetControlID() )\n        {\n            mControlPanelIDList[panelSlotID]->mControlList.erase( (mControlPanelIDList[panelSlotID]->mControlList.begin() + i) );\n\n            // trigger refresh\n            if(mbAutoLayout)\n            {\n                Resize();\n            }\n\n            return CPUT_SUCCESS;\n        }\n    }\n    return CPUT_WARNING_NOT_FOUND;\n}\n\n// removes panel and deletes all controls associated with it\n//-----------------------------------------------------------------------------\nCPUTResult CPUTGuiController::DeletePanel(CPUTControlID panelID)\n{\n    // find the panel they specified\n    CPUTControlID panelSlotID = FindPanelIDIndex(panelID);\n\n    // panel not found\n    //if(CPUT_CONTROL_ID_INVALID == panelSlotID)\n        //return CPUT_ERROR_INVALID_PARAMETER;\n\n    // walk the panel and delete all the controls in it\n    for(UINT i=0; i<mControlPanelIDList[panelSlotID]->mControlList.size(); i++)\n    {\n        // delete each control\n        SAFE_DELETE_ARRAY(mControlPanelIDList[panelSlotID]->mControlList[i]);        \n    }\n\n    // remove this panel from the control list\n    mControlPanelIDList.erase(mControlPanelIDList.begin()+panelSlotID);\n\n    // if the panel you delete is the active one, set the active panel to first\n    // or invalid if none are left\n    if(mActiveControlPanelSlotID == panelSlotID)\n    {\n        // set panel to the first panel\n        if(0 == mControlPanelIDList.size())\n            mActiveControlPanelSlotID = CPUT_CONTROL_ID_INVALID;\n        else\n            mActiveControlPanelSlotID = 0;\n    }\n\n\n    // trigger refresh\n    if(mbAutoLayout)\n    {\n        Resize();\n    }\n\n    return CPUT_SUCCESS;\n}\n\n// private: Finds the index of the specified panel ID code in mControlPanelIDList[]\n//-----------------------------------------------------------------------------\nUINT CPUTGuiController::FindPanelIDIndex(CPUTControlID panelID)\n{\n    CPUTControlID foundID = CPUT_CONTROL_ID_INVALID;\n\n    for(UINT i=0; i<mControlPanelIDList.size(); i++)\n    {\n        if(panelID == mControlPanelIDList[i]->mpanelID)\n            return i;\n    }\n\n    return foundID;\n}\n\n// Returns the number of controls in the currently ACTIVE panel\n//-----------------------------------------------------------------------------\nint CPUTGuiController::GetNumberOfControlsInPanel(CPUTControlID panelID)\n{\n    // if not specified, returns count of currently active pane\n    if(-1 == panelID)\n    {\n        if(CPUT_CONTROL_ID_INVALID == mActiveControlPanelSlotID)\n            return 0;\n        return (int) mControlPanelIDList[mActiveControlPanelSlotID]->mControlList.size();\n    }\n\n    // if panelID specified, return that number, or 0 if not found\n    UINT foundID = FindPanelIDIndex(panelID);\n    if(CPUT_CONTROL_ID_INVALID != foundID)\n        return (int) mControlPanelIDList[foundID]->mControlList.size();\n\n    return CPUT_CONTROL_ID_INVALID;\n}\n\n// is the control in the panel?\n//-----------------------------------------------------------------------------\nbool CPUTGuiController::IsControlInPanel(CPUTControlID controlID, CPUTControlID panelID)\n{\n    CPUTControlID panelSlotID;\n    if(-1==panelID)\n    {\n        // use the currently active panel if none specified\n        panelSlotID = mActiveControlPanelSlotID;\n    }\n    else\n    {\n        panelSlotID = FindPanelIDIndex(panelID);\n    }\n\n    // invalid panel\n    if(CPUT_CONTROL_ID_INVALID == panelSlotID)\n        return false;\n\n    // walk list of controls in the panel and see if control is there\n    for(UINT i=0; i<mControlPanelIDList[panelSlotID]->mControlList.size(); i++)\n    {\n        if( controlID == mControlPanelIDList[panelSlotID]->mControlList[i]->GetControlID() )\n            return true;\n    }\n    return false;\n}\n\n// Control management\n\n// Add a control (to a panel)\n//-----------------------------------------------------------------------------\nCPUTResult CPUTGuiController::AddControl(CPUTControl *pControl, CPUTControlID panelID)\n{\n    //if(NULL == pControl)\n        //return CPUT_ERROR_INVALID_PARAMETER;\n\n    // set the global callback handler for this object\n    pControl->SetControlCallback(mpHandler);\n\n    CPUTControlID panelSlotID = FindPanelIDIndex(panelID);\n\n    // if the panel wasn't found, add a new one\n    if(CPUT_CONTROL_ID_INVALID == panelSlotID)\n    {\n        Panel *pNewControlPanel = new Panel();\n        pNewControlPanel->mpanelID = panelID;\n        pNewControlPanel->mControlList.clear();\n        pNewControlPanel->mpFocusControl = NULL;\n\n        mControlPanelIDList.push_back( pNewControlPanel );\n        panelSlotID = (int)mControlPanelIDList.size()-1;\n\n        // make the newly added panel active if none was\n        // active before\n        if(CPUT_CONTROL_ID_INVALID == mActiveControlPanelSlotID)\n            mActiveControlPanelSlotID = panelSlotID;\n    }\n\n    // store the control in the list\n    mControlPanelIDList[panelSlotID]->mControlList.push_back(pControl);\n\n    // trigger a resize to position controls optimally\n    if(mbAutoLayout)\n    {\n        Resize();\n    }\n    return CPUT_SUCCESS;\n}\n\n// returns a pointer to the specified control\n//-----------------------------------------------------------------------------\nCPUTControl* CPUTGuiController::GetControl(CPUTControlID controlID, CPUTResult *pResult)\n{\n\tif (pResult)\n    {\n\t\t*pResult = CPUT_SUCCESS;\n    }\n\n    for(UINT i=0; i<mControlPanelIDList.size(); i++)\n    {\n        for(UINT j=0; j<mControlPanelIDList[i]->mControlList.size(); j++)\n        {\n            if(controlID == mControlPanelIDList[i]->mControlList[j]->GetControlID())\n            {\n                return mControlPanelIDList[i]->mControlList[j];\n            }\n        }\n    }\n\t\n\tif (pResult)\n    {\n\t\t*pResult = CPUT_GUI_INVALID_CONTROL_ID;\n    }\n\treturn NULL;\n}\n\n// Find control and return pointer and panel id for it\n//-----------------------------------------------------------------------------\nCPUTResult CPUTGuiController::FindControl(CPUTControlID controlID, CPUTControl **ppControl, CPUTControlID *pPanelID)\n{\n    //if((NULL==ppControl) || (NULL==pPanelID))\n        //return CPUT_ERROR_INVALID_PARAMETER;\n\n    for(UINT i=0; i<mControlPanelIDList.size(); i++)\n    {\n        for(UINT j=0; j<mControlPanelIDList[i]->mControlList.size(); j++)\n        {\n            if(controlID == mControlPanelIDList[i]->mControlList[j]->GetControlID())\n            {\n                // found it!\n                *pPanelID = mControlPanelIDList[i]->mpanelID;\n                *ppControl = mControlPanelIDList[i]->mControlList[j];\n                return CPUT_SUCCESS;\n            }\n        }\n    }\n    return CPUT_ERROR_NOT_FOUND;\n}\n\n// Delete all the controls in the list\n//-----------------------------------------------------------------------------\nvoid CPUTGuiController::DeleteAllControls()\n{\n    // set active panel to invalid\n    mActiveControlPanelSlotID = CPUT_CONTROL_ID_INVALID;\n\n    // walk list of panels deleting each list of controls\n    int panelCount = (int) mControlPanelIDList.size();\n    for(int i=0; i<panelCount; i++)\n    {\n        int controlListCount = (int)mControlPanelIDList[i]->mControlList.size();\n        for(int j=0; j<controlListCount; j++)\n        {\n            SAFE_DELETE( mControlPanelIDList[i]->mControlList[j] );            \n        }\n\n        // erase this panel's control list\n        mControlPanelIDList[i]->mControlList.clear();\n\n        // delete the panel object\n        SAFE_DELETE( mControlPanelIDList[i] );\n        mControlPanelIDList[i] = NULL;\n    }\n\n    // clear the panel list\n    mControlPanelIDList.clear();\n\n    // trigger refresh\n    if(mbAutoLayout)\n    {\n        Resize();\n    }\n}\n\n// Flag the GUI system that a control has changed shape/size\n// and that it needs to recalculate it's layout on the next render\n//--------------------------------------------------------------------------------\nvoid CPUTGuiController::Resize()\n{\n    mRecalculateLayout = true;\n    mUberBufferDirty = true;\n}\n\n// Re-calculates all the positions of the controls based on their sizes\n// to have a 'pretty' layout\n//--------------------------------------------------------------------------------\nvoid CPUTGuiController::RecalculateLayout()\n{\n    // if we have no valid panel, just return\n    if(CPUT_CONTROL_ID_INVALID == mActiveControlPanelSlotID)\n    {\n        return;\n    }\n\n    // if we don't want the auto-layout feature, just return\n    if(false == mbAutoLayout)\n    {\n        return;\n    }\n\n    // get window size\n    CPUT_RECT windowRect;\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    pServices->GetClientDimensions(&windowRect.x, &windowRect.y, &windowRect.width, &windowRect.height);\n\n    // Build columns of controls right to left\n    int x,y;\n    x=0; y=0;\n\n    // walk list of controls, counting up their *heights*, until the\n    // column is full.  While counting, keep track of the *widest*\n    int width, height;\n    const int GUI_WINDOW_PADDING = 5;\n\n    int numberOfControls = (int) mControlPanelIDList[mActiveControlPanelSlotID]->mControlList.size();\n    int indexStart=0;\n    int indexEnd=0;\n    int columnX = 0;\n    int columnNumber = 1;\n    while(indexEnd < numberOfControls)\n    {\n        int columnWidth=0;\n        y=0;\n        // figure out which controls belong in this column + column width\n        while( indexEnd < numberOfControls )\n        {\n            if(mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[indexEnd]->IsVisible() &&\n                mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[indexEnd]->IsAutoArranged())\n            {\n                mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[indexEnd]->GetDimensions(width, height);\n                if( y + height + GUI_WINDOW_PADDING < (windowRect.height-2*GUI_WINDOW_PADDING))\n                {\n                    y = y + height + GUI_WINDOW_PADDING;\n                    if(columnWidth < width)\n                    {\n                        columnWidth = width;\n                    }\n                    indexEnd++;\n                }\n                else\n                {\n                    // if the window is now so small it won't fit a whole control, just\n                    // draw one anyway and it'll just have to be clipped\n                    if(indexEnd == indexStart)\n                    {\n                        columnWidth = width;\n                        indexEnd++;\n                    }\n                    break;\n                }\n            }\n            else\n            {\n                indexEnd++;\n            }\n        }\n        \n\n        // ok, now re-position each control with x at widest, and y at proper height\n        y=GUI_WINDOW_PADDING;\n        for(int i=indexStart; i<indexEnd; i++)\n        {\n            if(mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[i]->IsVisible() &&\n                mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[i]->IsAutoArranged())\n            {\n                mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[i]->GetDimensions(width, height);\n                x = windowRect.width - columnX - columnWidth - (columnNumber*GUI_WINDOW_PADDING);\n                mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[i]->SetPosition(x,y);\n\n                y = y + height + GUI_WINDOW_PADDING;\n            }\n        }\n        indexStart = indexEnd;\n        columnX+=columnWidth;\n        columnNumber++;\n    }\n        \n    mRecalculateLayout = false;\n}\n\n// Sets the object to call back for all newly created objects\n// if ForceAll=true, then it walks the list of all the registered controls\n// in all the panels and resets their callbacks\n//-----------------------------------------------------------------------------\nvoid CPUTGuiController::SetCallback(CPUTCallbackHandler *pHandler, bool ForceAll)\n{\n    if(true == ForceAll)\n    {\n        // walk list of ALL the controls and reset the callback pointer\n        int panelCount = (int) mControlPanelIDList.size();\n        for(int i=0; i<panelCount; i++)\n        {\n            int controlListCount = (int) mControlPanelIDList[i]->mControlList.size();\n            for(int j=0; j<controlListCount; j++)\n            {\n                mControlPanelIDList[i]->mControlList[j]->SetControlCallback(pHandler);\n            }\n        }\n    }\n    else\n    {\n        // set the callback handler to be used on any NEW controls added\n        mpHandler = pHandler;\n    }\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTGuiController.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTGUICONTROLLER_H__\n#define __CPUTGUICONTROLLER_H__\n\n\n\n#include <stdio.h>\n#include <stdlib.h> // for RAND_MAX\n#include <vector>\n\n#include \"CPUTEventHandler.h\"\n#include \"CPUTControl.h\"\n#include \"CPUTOSServicesWin.h\"\n\n// definition of the vertex used in the GUI shader\nstruct CPUTGUIVertex\n{\n    float3 Pos;\n    float2 UV;\n    CPUTColor4 Color;\n};\n\nclass CPUTGuiController:public CPUTEventHandler\n{\npublic:\n    CPUTGuiController();\n    virtual ~CPUTGuiController();\n\n    // get GUI controller base class\n    static CPUTGuiController *GetController();\n\n    //CPUTEventHandler members\n    virtual CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key) {UNREFERENCED_PARAMETER(key); return CPUT_EVENT_UNHANDLED;}\n    virtual CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n\n    // members\n    void EnableAutoLayout(bool UseAutoLayout);\n    CPUTResult SetResourceDirectory(const cString ResourceDirectory);     // sets the resource directory to use when loading GUI resources\n    void GetResourceDirectory(cString &ResourceDirectory);           // sets the resource directory to use when loading GUI resources\n\n    // Panels\n    CPUTResult      AddControl(CPUTControl *pControl, CPUTControlID panelID);                                // adds a control to the specified panel\n    CPUTResult      FindControl(CPUTControlID controlID, CPUTControl **ppControl, CPUTControlID *pPanelID);  // search all panels to find a control and its panelID\n    CPUTControl    *GetControl(CPUTControlID controlID, CPUTResult *pResult = NULL);            // search all panels to find a control\n    CPUTResult      SetActivePanel(CPUTControlID panelID);                                      // sets the actively displayed panel\n    CPUTControlID   GetActivePanelID();                                                         // returns the ID of the active panel\n    CPUTResult      GetActiveControlList(std::vector<CPUTControl*> *ppControlList);\n    CPUTResult      RemoveControlFromPanel(CPUTControlID controlID, CPUTControlID panelID=-1);  // removes specified control from the panel (does not delete the control)\n    CPUTResult      DeletePanel(CPUTControlID panelID);                                         // removes panel and deletes all controls associated with it\n    void            DeleteAllControls();                                                        // deletes all controls and all panels\n    int             GetNumberOfControlsInPanel(CPUTControlID panelID=-1);                       // returns the number of controls in a specific panel\n    bool            IsControlInPanel(CPUTControlID controlID, CPUTControlID panelID=-1);        // Is specified control in panel?\n    bool            IsRecalculatingLayout() {return mRecalculateLayout;}\n\n    // drawing/callbacks\n    void Resize();  \n    void RecalculateLayout();                                                   // forces a recalculation of control positions\n    void SetCallback(CPUTCallbackHandler *pHandler, bool ForceAll=false);       // sets the event handler callback on all registered controls\n    void ControlIsDirty() {mUberBufferDirty = true;}\n\nprotected:\n    cString     mResourceDirectory;\n    bool        mUberBufferDirty;\n    bool        mRecalculateLayout;\n\n    struct Panel\n    {\n        CPUTControlID mpanelID;\n        CPUTControl *mpFocusControl;\n        std::vector<CPUTControl*> mControlList;\n    };\n\n    // list of panels which have lists of controls associated with it\n    std::vector<Panel*>  mControlPanelIDList;\n\n    // the active panel list\n    CPUTControlID  mActiveControlPanelSlotID;\n    CPUTCallbackHandler *mpHandler;\n\n    // active control\n    CPUTControl *mpFocusControl;\n\n    bool mbAutoLayout;\n\nprivate:\n    bool mbRebuildDrawList;\n    // helper functions\n    UINT FindPanelIDIndex(CPUTControlID panelID);\n\n};\n\n\n\n#endif //#ifndef __CPUTGUICONTROLLER_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTGuiControllerDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTGuiControllerDX11.h\"\n#include \"CPUT_DX11.h\" // for CPUTSetRasterizerState()\n#include \"CPUTTextureDX11.h\"\n#include \"CPUTFontDX11.h\"\n\n\nCPUTGuiControllerDX11* CPUTGuiControllerDX11::mguiController = NULL;\n\n// chained constructor\n//--------------------------------------------------------------------------------\nCPUTGuiControllerDX11::CPUTGuiControllerDX11():CPUTGuiController(),\n    mpGUIVertexShader(NULL),\n    mpGUIPixelShader(NULL),\n    mpConstantBufferVS(NULL),\n    mpVertexLayout(NULL),\n\n    // texture atlas+uber buffer\n    mpControlTextureAtlas(NULL),\n    mpControlTextureAtlasView(NULL),\n    mpUberBuffer(NULL),\n    mpMirrorBuffer(NULL),\n    mUberBufferIndex(0),\n    mUberBufferMax(CPUT_GUI_BUFFER_SIZE),\n    mpFont(NULL),\n    mpTextTextureAtlas(NULL),\n    mpTextTextureAtlasView(NULL),\n    mpTextUberBuffer(NULL),\n    mpTextMirrorBuffer(NULL),\n    mTextUberBufferIndex(0),\n\n    mFocusedControlBufferIndex(0),\n    mpFocusedControlBuffer(NULL),\n    mFocusedControlTextBufferIndex(0),\n    mpFocusedControlTextBuffer(NULL),\n    mpGUIRenderStateBlock(NULL),\n    \n    mbDrawFPS(false),\n    mLastFPS(0),\n    mpFPSCounter(NULL),\n    mpFPSMirrorBuffer(NULL),\n    mFPSBufferIndex(0),\n    mpFPSDirectXBuffer(NULL),\n    mpFPSTimer(NULL)\n{\n    mpMirrorBuffer = new CPUTGUIVertex[CPUT_GUI_BUFFER_SIZE];\n    mpTextMirrorBuffer = new  CPUTGUIVertex[CPUT_GUI_BUFFER_STRING_SIZE];\n\n    mpFocusedControlMirrorBuffer = new CPUTGUIVertex[CPUT_GUI_BUFFER_SIZE];\n    mpFocusedControlTextMirrorBuffer = new CPUTGUIVertex[CPUT_GUI_BUFFER_STRING_SIZE];\n    \n    mpFPSMirrorBuffer = new CPUTGUIVertex[CPUT_GUI_BUFFER_STRING_SIZE];\n    mpFPSTimer = new CPUTTimerWin();\n    \n#ifdef SAVE_RESTORE_DSHSGS_SHADER_STATE\n    mpGeometryShaderState=NULL;\n    mpGeometryShaderClassInstances=NULL;\n    mGeometryShaderNumClassInstances=0;\n\n    mpHullShaderState=NULL;\n    mpHullShaderClassInstances=NULL;\n    UINT mHullShaderNumClassInstance=0;\n\n    mpDomainShaderState=NULL;\n    mpDomainShaderClassIntances=NULL;\n    UINT mDomainShaderNumClassInstances=0;\n#endif\n}\n\n// destructor\n//--------------------------------------------------------------------------------\nCPUTGuiControllerDX11::~CPUTGuiControllerDX11()\n{\n    // delete all the controls under you\n\tReleaseResources();\n    DeleteAllControls();\n\n    // FPS counter\n    SAFE_DELETE(mpFPSCounter);\n    SAFE_DELETE(mpFPSTimer);\n\n    // delete arrays\n    SAFE_DELETE_ARRAY(mpTextMirrorBuffer);\n    SAFE_DELETE_ARRAY(mpMirrorBuffer);\n    SAFE_DELETE_ARRAY(mpFocusedControlMirrorBuffer);\n    SAFE_DELETE_ARRAY(mpFocusedControlTextMirrorBuffer);\n    SAFE_DELETE_ARRAY(mpFPSMirrorBuffer);\n}\n\n// static getter\n//--------------------------------------------------------------------------------\nCPUTGuiControllerDX11* CPUTGuiControllerDX11::GetController()\n{\n    if(NULL==mguiController)\n        mguiController = new CPUTGuiControllerDX11();\n    return mguiController;\n}\n\n\n// Delete the controller\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::DeleteController()\n{\n    SAFE_DELETE(mguiController);\n\n    return CPUT_SUCCESS;\n}\n\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::ReleaseResources()\n{\n\t//Release all allocated resources\n    SAFE_RELEASE(mpGUIVertexShader);\n    SAFE_RELEASE(mpGUIPixelShader);\n    SAFE_RELEASE(mpVertexLayout);\n    SAFE_RELEASE(mpConstantBufferVS);\n\n    // release the texture atlas+buffers\n    SAFE_RELEASE(mpControlTextureAtlasView);\n    SAFE_RELEASE(mpControlTextureAtlas);\n    SAFE_RELEASE(mpUberBuffer);\n    \n//\tSAFE_RELEASE(mpFont->mpTextAtlas);\n    SAFE_RELEASE(mpFont);\n    SAFE_RELEASE(mpTextTextureAtlasView);\n    SAFE_RELEASE(mpTextTextureAtlas);    \n    SAFE_RELEASE(mpTextUberBuffer);\n    \n    SAFE_RELEASE(mpFocusedControlBuffer);\n    SAFE_RELEASE(mpFocusedControlTextBuffer);    \n\n    SAFE_RELEASE(mpGUIRenderStateBlock);\n\n    SAFE_RELEASE(mpFPSDirectXBuffer);\n\n    // tell all controls to unregister all their static resources\n    CPUTText::UnRegisterStaticResources();\n    CPUTButton::UnRegisterStaticResources();\n    CPUTCheckbox::UnRegisterStaticResources();\n    CPUTSlider::UnRegisterStaticResources();\n    CPUTDropdown::UnRegisterStaticResources();\n\n\treturn CPUT_SUCCESS;\n}\n\n// Initialize the GUI controller and all it's static resources\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::Initialize(ID3D11DeviceContext *pImmediateContext, cString &ResourceDirectory)\n{\n    // All the GUI resource files\n    cString VertexShader =      _L(\".//shaders//GUIShaderDX.vs\");\n    cString PixelShader =       _L(\".//shaders//GUIShaderDX.ps\");\n    cString DefaultFontFile =   _L(\".//fonts//font_arial_12.dds\");\n    cString ControlAtlasTexture = _L(\".//controls//atlas.dds\");\n    cString RenderStateFile =   _L(\".//Shaders//GUIRenderState.rs\");\n\n    // store the resource directory to be used by the GUI manager\n    SetResourceDirectory(ResourceDirectory);\n\n    return RegisterGUIResources(pImmediateContext, VertexShader, PixelShader, RenderStateFile, DefaultFontFile, ControlAtlasTexture);\n}\n\n\n// Control creation\n\n// Create a button control and add it to the GUI layout controller\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::CreateButton(const cString ButtonText, CPUTControlID controlID, CPUTControlID panelID, CPUTButton **ppButton)\n{\n    // create the control\n    CPUTButton *pButton = new CPUTButton(ButtonText, controlID, mpFont);\n    ASSERT(NULL != pButton, _L(\"Failed to create control.\") );\n\n    // return control if requested\n    if(NULL!=ppButton)\n    {\n        *ppButton = pButton;\n    }\n\n    // add control to the gui manager\n    return this->AddControl(pButton, panelID);\n\n}\n\n// Create a slider control and add it to the GUI layout controller\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::CreateSlider(const cString SliderText, CPUTControlID controlID, CPUTControlID panelID, CPUTSlider **ppSlider)\n{\n    // create the control\n    CPUTSlider *pSlider = new CPUTSlider(SliderText, controlID, mpFont);\n    ASSERT(NULL!=pSlider, _L(\"Failed creating slider\") );\n\n    // return control if requested\n    if(NULL!=ppSlider)\n    {\n        *ppSlider = pSlider;\n    }\n    \n    // add control to the gui manager\n    return this->AddControl(pSlider, panelID);\n}\n\n// Create a checkbox control and add it to the GUI layout controller\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::CreateCheckbox(const cString CheckboxText, CPUTControlID controlID, CPUTControlID panelID, CPUTCheckbox **ppCheckbox)\n{\n    // create the control\n    CPUTCheckbox *pCheckbox = new CPUTCheckbox(CheckboxText, controlID, mpFont);\n    ASSERT(NULL!=pCheckbox, _L(\"Failed creating checkbox\") );\n\n    // return control if requested\n    if(NULL!=ppCheckbox)\n    {\n        *ppCheckbox = pCheckbox;\n    }\n\n    // add control to the gui manager\n    return this->AddControl(pCheckbox, panelID);\n}\n\n// Create a dropdown control and add it to the GUI layout controller\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::CreateDropdown(const cString SelectionText, CPUTControlID controlID, CPUTControlID panelID, CPUTDropdown **ppDropdown)\n{\n    // create the control\n    CPUTDropdown *pDropdown = new CPUTDropdown(SelectionText, controlID, mpFont);\n    ASSERT(NULL!=pDropdown, _L(\"Failed creating control\") );\n\n    // return control if requested\n    if(NULL!=ppDropdown)\n    {\n        *ppDropdown = pDropdown;\n    }\n\n    // add control to the gui manager\n    CPUTResult result;\n    result = this->AddControl(pDropdown, panelID);\n\n    return result;\n}\n\n// Create a text item (static text)\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::CreateText(const cString Text, CPUTControlID controlID, CPUTControlID panelID, CPUTText **ppStatic)\n{\n    // create the control\n    CPUTText *pStatic=NULL;\n    pStatic = new CPUTText(Text, controlID, mpFont);\n    ASSERT(NULL!=pStatic, _L(\"Failed creating static\") );\n    if(NULL != ppStatic)\n    {\n        *ppStatic = pStatic;\n    }\n\n    // add control to the gui manager\n    return this->AddControl(pStatic, panelID);\n}\n\n// Deletes a control from the GUI manager\n// Will delete all instances of the control no matter which panel(s) it is in and then\n// deallocates the memory for the control\n//--------------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::DeleteControl(CPUTControlID controlID)\n{\n    // look thruogh all the panels and delete the item with this controlID\n    // for each panel\n    std::vector <CPUTControl*> pDeleteList;\n\n    for(UINT i=0; i<mControlPanelIDList.size(); i++)\n    {\n        // walk list of controls\n        for(UINT j=0; j<mControlPanelIDList[i]->mControlList.size(); j++)\n        {\n            if(controlID == mControlPanelIDList[i]->mControlList[j]->GetControlID())\n            {\n                // found an instance of the control we wish to delete\n                // see if it's in the list already\n                bool bFound = false;\n                for(UINT x=0; x<pDeleteList.size(); x++)\n                {\n                    if( mControlPanelIDList[i]->mControlList[j] ==  pDeleteList[x] )\n                    {\n                        bFound = true;\n                        break;\n                    }\n                }\n\n                if(!bFound)\n                {\n                    // store for deleting\n                    pDeleteList.push_back( mControlPanelIDList[i]->mControlList[j] );\n                }\n\n                // remove the control from the container list\n                mControlPanelIDList[i]->mControlList.erase( mControlPanelIDList[i]->mControlList.begin() + j );\n            }\n        }\n    }\n\n    // delete the control(s) we found with this id\n    for(UINT i=0; i<pDeleteList.size(); i++)\n    {\n        SAFE_DELETE( pDeleteList[i] );\n    }\n\n    // force a resize event to recalculate new control locations now that some might have been deleted\n    this->Resize();\n\n    // don't worry about cleaning up std::vector list itself, it'll do so when it falls out of scope\n    return CPUT_SUCCESS;\n}\n\n// DrawFPS - Should the GUI draw the FPS counter in the upper-left?\n//--------------------------------------------------------------------------------\nvoid CPUTGuiControllerDX11::DrawFPS(bool drawfps)\n{\n    mbDrawFPS = drawfps;\n}\n\n// GetFPS - Returns the last frame's FPS value\n//--------------------------------------------------------------------------------\nfloat CPUTGuiControllerDX11::GetFPS()\n{\n    return mLastFPS;\n}\n\n// Draw - must be positioned after all the controls are defined\n//--------------------------------------------------------------------------------\nvoid CPUTGuiControllerDX11::Draw(ID3D11DeviceContext *pImmediateContext)\n{\n    HEAPCHECK;\n\n    if( 0 != GetNumberOfControlsInPanel())\n    {\n        SetGUIDrawingState(pImmediateContext);\n    }\n    else\n    {\n        return;\n    }\n\n    ID3D11VertexShader *pVertexShader = mpGUIVertexShader->GetNativeVertexShader();\n    ID3D11PixelShader  *pPixelShader  = mpGUIPixelShader->GetNativePixelShader();\n\n    // check and see if any of the controls resized themselves\n    int ControlCount=GetNumberOfControlsInPanel();\n    bool ResizingNeeded = false;\n    for(int ii=0; ii<ControlCount; ii++)\n    {\n        CPUTControl *pControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[ii];\n        if(true == pControl->ControlResizedItself())\n        {\n            ResizingNeeded = true;\n            pControl->ControlResizingHandled();\n        }\n    }\n\n    // if any of the controls resized, then re-do the autoarrangment\n    if(true == ResizingNeeded)\n    {\n        this->Resize();\n    }\n\n    // Now check to see if any controls' graphics are dirty\n    for(int ii=0; ii<ControlCount; ii++)\n    {\n        CPUTControl *pControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[ii];\n        if(true == pControl->ControlGraphicsDirty())\n        {\n            mUberBufferDirty = true;\n            break;\n        }\n    }\n\n    // if any of the controls have announced they are dirty, then rebuild the mirror buffer and update the GFX buffer\n    if(mUberBufferDirty)\n    {\n        \n        // if a resize was flagged, do it now.  \n        if(mRecalculateLayout)\n        {\n            RecalculateLayout();\n        }\n\n\n        // 'clear' the buffer by resetting the pointer to the head\n        mUberBufferIndex = 0;\n        mTextUberBufferIndex = 0;\n        mFocusedControlBufferIndex = 0;\n        mFocusedControlTextBufferIndex = 0;\n\n        int ii=0;\n        while(ii<GetNumberOfControlsInPanel())\n        {\n            CPUTControl *pControl = mControlPanelIDList[mActiveControlPanelSlotID]->mControlList[ii];\n\n            // don't draw the focus control - draw it last so it stays on 'top'\n            if(mpFocusControl != pControl)\n            {\n                switch(pControl->GetType())\n                {\n                case CPUT_BUTTON:\n                    ((CPUTButton*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);                    \n                    break;\n                case CPUT_CHECKBOX:\n                    ((CPUTCheckbox*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n                    break;\n                case CPUT_SLIDER:\n                    ((CPUTSlider*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n                    break;\n                case CPUT_DROPDOWN:\n                    ((CPUTDropdown*)pControl)->DrawIntoBuffer(mpMirrorBuffer, &mUberBufferIndex, mUberBufferMax, mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n                    break;\n\n                case CPUT_STATIC:\n                    ((CPUTText*)pControl)->DrawIntoBuffer(mpTextMirrorBuffer, &mTextUberBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n                    break;\n                }\n            }\n            ii++;\n            HEAPCHECK\n        }\n\n        // do the 'focused' control last so it stays on top (i.e. dropdowns)\n        if(mpFocusControl)\n        {\n            switch(mpFocusControl->GetType())\n            {\n            case CPUT_BUTTON:\n                ((CPUTButton*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);                    \n                break;\n            case CPUT_CHECKBOX:\n                ((CPUTCheckbox*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n                break;\n            case CPUT_SLIDER:\n                ((CPUTSlider*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n                break;\n            case CPUT_DROPDOWN:\n                ((CPUTDropdown*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlBufferIndex, mUberBufferMax, mpFocusedControlTextMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n                break;\n            case CPUT_STATIC:\n                ((CPUTText*)mpFocusControl)->DrawIntoBuffer(mpFocusedControlMirrorBuffer, &mFocusedControlTextBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n                break;\n            }\n        }\n        \n                \n        // update the uber-buffers with the control graphics\n        UpdateUberBuffers(pImmediateContext);\n\n        // Clear dirty flag on uberbuffer\n        mUberBufferDirty = false;\n\n    }\n    HEAPCHECK\n\n\n\n    // calculate the fps\n    double elapsed = mpFPSTimer->GetElapsedTime();\n    double fps = 1.0 / elapsed;\n    mLastFPS = (float) fps;\n\n    // if we're drawing the FPS counter - update that\n    // We do this independently of uber-buffer updates since we'll have FPS updates every frame,\n    // but likely not have control updates every frame\n    if(mbDrawFPS)\n    {\n        // calculate the time elapsed since last frame\n        bool UberBufferWasDirty = mUberBufferDirty;\n\n        cString Data;\n        {\n            wchar_t wcstring[CPUT_MAX_STRING_LENGTH];\n            swprintf_s(&wcstring[0], CPUT_MAX_STRING_LENGTH, _L(\"%.2f\"), fps);\n            Data=wcstring;\n        }\n        // build the FPS string\n        cString FPS = _L(\"FPS: \")+Data;\n        mpFPSCounter->SetText(FPS);        \n\n        // 'draw' the string into the buffer\n        mFPSBufferIndex = 0;\n        mpFPSCounter->DrawIntoBuffer(mpFPSMirrorBuffer, &mFPSBufferIndex, CPUT_GUI_BUFFER_STRING_SIZE);\n\n        // update the DirectX vertex buffer\n        ASSERT(CPUT_GUI_BUFFER_STRING_SIZE > mFocusedControlTextBufferIndex, _L(\"CPUT GUI: Too many strings for default-sized uber-buffer.  Increase CPUT_GUI_BUFFER_STRING_SIZE\"));\n        pImmediateContext->UpdateSubresource(mpFPSDirectXBuffer, 0, NULL, mpFPSMirrorBuffer, mFPSBufferIndex*sizeof(CPUTGUIVertex), 0);\n        \n        // start next frame timer\n        mpFPSTimer->StartTimer();\n        if(false == UberBufferWasDirty)\n        {\n            mUberBufferDirty = false;\n        }\n    }\n\n\n    // set up orthographic display\n    int windowWidth, windowHeight;\n    GUIConstantBufferVS ConstantBufferMatrices;\n    float znear = 0.1f;\n    float zfar = 100.0f;\n    XMMATRIX m;\n\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    pServices->GetClientDimensions( &windowWidth, &windowHeight );\n    m = XMMatrixOrthographicOffCenterLH(0, (float)windowWidth, (float)windowHeight, 0, znear, zfar);\n    ConstantBufferMatrices.Projection = XMMatrixTranspose( m );\n\n    // set the vertex shader\n    pImmediateContext->VSSetShader( pVertexShader, NULL, 0 );\n    UINT VertexStride = sizeof(CPUTGUIVertex);\n    UINT VertexOffset = 0;\n    pImmediateContext->IASetVertexBuffers( 0, 1, &mpUberBuffer, &VertexStride, &VertexOffset );\n\n    m = XMMatrixIdentity();\n    ConstantBufferMatrices.Model = XMMatrixTranspose( m );\n    pImmediateContext->UpdateSubresource( mpConstantBufferVS, 0, NULL, &ConstantBufferMatrices, 0, 0 );\n    pImmediateContext->VSSetConstantBuffers( 0, 1, &mpConstantBufferVS );\n\n    // -- draw the normal controls --    \n    // draw the control graphics\n    pImmediateContext->PSSetShader( pPixelShader, NULL, 0 );\n    pImmediateContext->PSSetShaderResources( 0, 1, &mpControlTextureAtlasView );    \n    pImmediateContext->Draw(mUberBufferIndex,0);\n\n    // draw the control's text\n    pImmediateContext->PSSetShaderResources( 0, 1, &mpTextTextureAtlasView );\n    pImmediateContext->IASetVertexBuffers( 0, 1, &mpTextUberBuffer, &VertexStride, &VertexOffset );\n    // draw the text uber-buffer\n    pImmediateContext->Draw(mTextUberBufferIndex,0);\n\n    // draw the FPS counter\n    if(mbDrawFPS)\n    {\n        pImmediateContext->IASetVertexBuffers( 0, 1, &mpFPSDirectXBuffer, &VertexStride, &VertexOffset );\n        pImmediateContext->Draw(mFPSBufferIndex, 0);\n    }\n    \n    // -- draw the focused control --\n    // Draw the focused control's graphics\n    pImmediateContext->PSSetShader( pPixelShader, NULL, 0 );\n    pImmediateContext->PSSetShaderResources( 0, 1, &mpControlTextureAtlasView );\n    pImmediateContext->IASetVertexBuffers( 0, 1, &mpFocusedControlBuffer, &VertexStride, &VertexOffset );\n    // draw the uber-buffer\n    pImmediateContext->Draw(mFocusedControlBufferIndex,0);\n\n\n    // Draw the focused control's text\n    pImmediateContext->PSSetShaderResources( 0, 1, &mpTextTextureAtlasView );\n    pImmediateContext->IASetVertexBuffers( 0, 1, &mpFocusedControlTextBuffer, &VertexStride, &VertexOffset );\n    // draw the text uber-buffer\n    pImmediateContext->Draw(mFocusedControlTextBufferIndex,0);\n\n\n    // restore the drawing state\n    ClearGUIDrawingState(pImmediateContext);\n    HEAPCHECK;\n}\n\n//\n//------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::UpdateUberBuffers(ID3D11DeviceContext *pImmediateContext )\n{\n    ASSERT(pImmediateContext, _L(\"CPUTGuiControllerDX11::UpdateUberBuffers - Context pointer is NULL\"));\n\n    // get the device\n    ID3D11Device *pD3dDevice = NULL;\n    pImmediateContext->GetDevice(&pD3dDevice);\n    \n\n    // Update geometry to draw the control graphics\n    ASSERT(CPUT_GUI_VERTEX_BUFFER_SIZE > mUberBufferIndex, _L(\"CPUT GUI: Too many controls for default-sized uber-buffer.  Increase CPUT_GUI_VERTEX_BUFFER_SIZE\"));\n    pImmediateContext->UpdateSubresource(mpUberBuffer, 0, NULL, (void*) mpMirrorBuffer, sizeof( CPUTGUIVertex )*(mUberBufferIndex+1), 0);\n\n    // Update geometry to draw the controls' text\n    ASSERT(CPUT_GUI_BUFFER_STRING_SIZE > mTextUberBufferIndex, _L(\"CPUT GUI: Too many strings for default-sized uber-buffer.  Increase CPUT_GUI_BUFFER_STRING_SIZE\"));\n    pImmediateContext->UpdateSubresource(mpTextUberBuffer, 0, NULL, (void*) mpTextMirrorBuffer, sizeof( CPUTGUIVertex )*(mTextUberBufferIndex+1), 0);\n    \n    // register the focused control's graphics\n    ASSERT(CPUT_GUI_VERTEX_BUFFER_SIZE > mUberBufferIndex, _L(\"CPUT GUI: Too many controls for default-sized uber-buffer.  Increase CPUT_GUI_VERTEX_BUFFER_SIZE\"));\n    pImmediateContext->UpdateSubresource(mpFocusedControlBuffer, 0, NULL, (void*) mpFocusedControlMirrorBuffer, sizeof( CPUTGUIVertex )*(mFocusedControlBufferIndex+1), 0);\n\n    //register the focused control's text\n    ASSERT(CPUT_GUI_BUFFER_STRING_SIZE > mFocusedControlTextBufferIndex, _L(\"CPUT GUI: Too many strings for default-sized uber-buffer.  Increase CPUT_GUI_BUFFER_STRING_SIZE\"));\n    pImmediateContext->UpdateSubresource(mpFocusedControlTextBuffer, 0, NULL, (void*) mpFocusedControlTextMirrorBuffer, sizeof( CPUTGUIVertex )*(mFocusedControlTextBufferIndex+1), 0);\n\n    // release the device pointer\n    SAFE_RELEASE(pD3dDevice);    \n\n    return CPUT_SUCCESS;\n\n}\n\n// Set the state for drawing the gui\n//-----------------------------------------------------------------------------\nvoid CPUTGuiControllerDX11::SetGUIDrawingState(ID3D11DeviceContext *pImmediateContext)\n{\n    // set the GUI shaders as active\n    ID3D11VertexShader *pVertexShader = mpGUIVertexShader->GetNativeVertexShader();\n    pImmediateContext->VSSetShader( pVertexShader, NULL, 0 );\n    \n    //D3D11_VIEWPORT viewport  = { 0.0f, 0.0f, (float)mWidth, (float)mHeight, 0.0f, 1.0f };\n    //((CPUTRenderParametersDX*)&renderParams)->mpContext->RSSetViewports( 1, &viewport );\n    \n#ifdef SAVE_RESTORE_DS_HS_GS_SHADER_STATE\n    pImmediateContext->GSGetShader(&mpGeometryShaderState, &mpGeometryShaderClassInstances, &mGeometryShaderNumClassInstances);\n    pImmediateContext->HSGetShader(&mpHullShaderState, &mpHullShaderClassInstances, &mHullShaderNumClassInstance);\n    pImmediateContext->DSGetShader(&mpDomainShaderState, &mpDomainShaderClassIntances, &mDomainShaderNumClassInstances);\n#endif\n\n    // set the geometry, hull, and domain shaders to null (in case the user had set them)\n    // since the GUI system doesn't need them\n    pImmediateContext->GSSetShader(NULL, NULL, 0);\n    pImmediateContext->HSSetShader(NULL, NULL, 0);\n    pImmediateContext->DSSetShader(NULL, NULL, 0);\n    \n    // set topology to triangle list\n    pImmediateContext->IAGetPrimitiveTopology(&mTopology);\n    pImmediateContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);\n        \n    // Use CPUTRenderStateBlock to set the render state for GUI drawing\n    CPUTRenderParametersDX renderParams;\n    renderParams.mpContext = pImmediateContext;\n    mpGUIRenderStateBlock->SetRenderStates(renderParams);\n\n    // update the constant buffer matrices\n    // set for orthographic perspective\n    GUIConstantBufferVS cb;\n    cb.Model = XMMatrixIdentity();\n    cb.Projection = XMMatrixIdentity();\n    pImmediateContext->UpdateSubresource( mpConstantBufferVS, 0, NULL, &cb, 0, 0 );\n    pImmediateContext->VSSetConstantBuffers( 0, 1, &mpConstantBufferVS );\n\n    // set the input layout\n    pImmediateContext->IASetInputLayout( mpVertexLayout );\n\n    // set the pixel shader\n    pImmediateContext->PSSetShader( mpGUIPixelShader->GetNativePixelShader(), NULL, 0 );\n\n}\n\n// Restores the previous state\n//-----------------------------------------------------------------------------\nvoid CPUTGuiControllerDX11::ClearGUIDrawingState(ID3D11DeviceContext *pImmediateContext)\n{\n    // restore drawing topology mode that was in use before entering the gui drawing state\n    pImmediateContext->IASetPrimitiveTopology(mTopology);\n\n#ifdef SAVE_RESTORE_DS_HS_GS_SHADER_STATE\n    pImmediateContext->GSSetShader(mpGeometryShaderState, (ID3D11ClassInstance* const*)&mpGeometryShaderClassInstances, mGeometryShaderNumClassInstances);\n    pImmediateContext->HSSetShader(mpHullShaderState, (ID3D11ClassInstance* const*)&mpHullShaderClassInstances, mHullShaderNumClassInstance);\n    pImmediateContext->DSSetShader(mpDomainShaderState, (ID3D11ClassInstance* const*)&mpDomainShaderClassIntances, mDomainShaderNumClassInstances);\n#endif\n\n}\n\n\n// Load and register all the resources needed by the GUI system\n//-----------------------------------------------------------------------------\nCPUTResult CPUTGuiControllerDX11::RegisterGUIResources(ID3D11DeviceContext *pImmediateContext, cString VertexShaderFilename, cString PixelShaderFilename, cString RenderStateFile, cString DefaultFontFilename, cString ControlAtlasTexture)\n{\n    if(NULL==pImmediateContext)\n    {\n        return CPUT_ERROR_INVALID_PARAMETER;\n    }\n    CPUTResult result;\n    HRESULT hr;\n    ID3D11Device *pD3dDevice = NULL;\n    CPUTOSServices *pServices = NULL;\n    CPUTAssetLibraryDX11 *pAssetLibrary = NULL;\n    cString ErrorMessage;\n\n    // Get the services/resource pointers we need\n    pServices = CPUTOSServices::GetOSServices();\n    pImmediateContext->GetDevice(&pD3dDevice);\n    pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary();\n\n    // Get the resource directory\n    cString ResourceDirectory;\n    CPUTGuiControllerDX11::GetController()->GetResourceDirectory(ResourceDirectory);\n\n    // 1. Load the renderstate configuration for the GUI system\n    mpGUIRenderStateBlock = (CPUTRenderStateBlockDX11*) pAssetLibrary->GetRenderStateBlock(ResourceDirectory+RenderStateFile); \n    ASSERT(mpGUIRenderStateBlock, _L(\"Error loading the render state file (.rs) needed for the CPUT GUI system\"));\n    \n\n    // 2. Store the shader path from AssetLibrary, change it to OUR resource directory\n    cString OriginalAssetLibraryDirectory = pAssetLibrary->GetShaderDirectory();\n    pAssetLibrary->SetShaderDirectoryName(ResourceDirectory);\n    \n\n    // 3. load the shaders for gui drawing\n    // Load the GUI Vertex Shader\n    cString FullPath, FinalPath;\n    FullPath = mResourceDirectory + VertexShaderFilename;\n    pServices->ResolveAbsolutePathAndFilename(FullPath, &FinalPath);\n    result = pAssetLibrary->GetVertexShader(FinalPath, pD3dDevice, _L(\"VS\"), _L(\"vs_4_0\"), &mpGUIVertexShader, true);\n    CPUTSetDebugName( mpGUIVertexShader->GetNativeVertexShader(), _L(\"GUIVertexShader\"));\n    if(CPUTFAILED(result))\n    {\n        ASSERT(CPUTSUCCESS(result), _L(\"Error loading the vertex shader needed for the CPUT GUI system.\"));\n    }\n    ID3DBlob *pVertexShaderBlob = mpGUIVertexShader->GetBlob();\n\n    // Load the GUI Pixel Shader\n    FullPath = mResourceDirectory + PixelShaderFilename;\n    pServices->ResolveAbsolutePathAndFilename(FullPath, &FinalPath);\n    result = pAssetLibrary->GetPixelShader(FinalPath, pD3dDevice, _L(\"PS\"), _L(\"ps_4_0\"), &mpGUIPixelShader, true);\n    CPUTSetDebugName( mpGUIPixelShader->GetNativePixelShader(), _L(\"GUIPixelShader\"));\n    if(CPUTFAILED(result))\n    {\n        ASSERT(CPUTSUCCESS(result), _L(\"Error loading the pixel shader needed for the CPUT GUI system.\"));\n    }\n\n    // Restore the previous shader directory\n    pAssetLibrary->SetShaderDirectoryName(OriginalAssetLibraryDirectory);\n    \n\n    // 4. Create the vertex layout description for all the GUI controls we'll draw\n    // set vertex shader as active so we can configure it\n    ID3D11VertexShader *pVertexShader = mpGUIVertexShader->GetNativeVertexShader();\n    pImmediateContext->VSSetShader( pVertexShader, NULL, 0 );\n\n    D3D11_INPUT_ELEMENT_DESC layout[] =\n    {\n        { \"POSITION\", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },\t        \n        { \"TEXCOORD\", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n        { \"COLOR\", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n    };\n    UINT numElements = ARRAYSIZE( layout );\n\n    // Create the input layout\n    hr = pD3dDevice->CreateInputLayout( layout, numElements, pVertexShaderBlob->GetBufferPointer(), pVertexShaderBlob->GetBufferSize(), &mpVertexLayout );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating CPUT GUI system input layout\" ));\n    CPUTSetDebugName( mpVertexLayout, _L(\"CPUT GUI InputLayout object\"));\n    \n\n    // 5. create the vertex shader constant buffer pointers\n    D3D11_BUFFER_DESC bd;\n    ZeroMemory( &bd, sizeof(bd) );\n    bd.Usage = D3D11_USAGE_DEFAULT;\n    bd.ByteWidth = sizeof(GUIConstantBufferVS);\n    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;\n    bd.CPUAccessFlags = 0;\n    hr = pD3dDevice->CreateBuffer( &bd, NULL, &mpConstantBufferVS );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating constant buffer VS\" ));\n    CPUTSetDebugName( mpConstantBufferVS, _L(\"GUI ConstantBuffer\"));\n      \n    // Set the texture directory for loading the control texture atlas\n    pAssetLibrary->SetTextureDirectoryName(ResourceDirectory);\n\n    // load the control atlas\n    mpControlTextureAtlas = (CPUTTextureDX11*) pAssetLibrary->GetTexture(ControlAtlasTexture); \n    if(NULL==mpControlTextureAtlas)\n    {\n        return CPUT_TEXTURE_LOAD_ERROR;\n    }\n    mpControlTextureAtlasView = mpControlTextureAtlas->GetShaderResourceView();\n    mpControlTextureAtlasView->AddRef();\n\n    // restore the asset library's texture directory    \n    pAssetLibrary->SetTextureDirectoryName(OriginalAssetLibraryDirectory);\n    \n\n    // 6. Load the font atlas\n    // store the existing asset library font directory\n    OriginalAssetLibraryDirectory = pAssetLibrary->GetFontDirectory(); \n\n    // set font directory to the resource directory\n    pAssetLibrary->SetFontDirectoryName(ResourceDirectory);\n    mpFont = (CPUTFontDX11*) pAssetLibrary->GetFont(DefaultFontFilename); \n    if(NULL==mpFont)\n    {\n        return CPUT_TEXTURE_LOAD_ERROR;\n    }\n    mpTextTextureAtlas = mpFont->GetAtlasTexture();\n    mpTextTextureAtlas->AddRef();\n    mpTextTextureAtlasView = mpFont->GetAtlasTextureResourceView();\n    mpTextTextureAtlasView->AddRef();    \n\n    // restore the asset library's font directory    \n    pAssetLibrary->SetTextureDirectoryName(OriginalAssetLibraryDirectory);\n    \n    \n    // 7. Set up the DirectX uber-buffers that the controls draw into\n    int maxSize = max(CPUT_GUI_BUFFER_STRING_SIZE, CPUT_GUI_BUFFER_SIZE);\n    maxSize = max(maxSize, CPUT_GUI_VERTEX_BUFFER_SIZE);    \n    maxSize *= sizeof( CPUTGUIVertex );\n    char *pZeroedBuffer= new char[maxSize];\n    memset(pZeroedBuffer, 0, maxSize);\n\n    // set up buffer description\n    ZeroMemory( &bd, sizeof(bd) );\n    bd.Usage = D3D11_USAGE_DEFAULT;\n    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_VERTEX_BUFFER_SIZE; //mUberBufferIndex;\n    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;\n    bd.CPUAccessFlags = 0;\n    // initialization data (all 0's for now)\n    D3D11_SUBRESOURCE_DATA InitData;\n    ZeroMemory( &InitData, sizeof(InitData) );\n    InitData.pSysMem = mpMirrorBuffer;\n\n    // mpUberBuffer\n    SAFE_RELEASE(mpUberBuffer);\n    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpUberBuffer );\n    ASSERT( !FAILED( hr ), _L(\"CPUT GUI FPS counter buffer creation failure\"));\n    CPUTSetDebugName(mpUberBuffer, _L(\"CPUT GUI: Control's main vertex buffer\"));\n\n\n    // mpTextUberBuffer\n    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE;\n    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpTextUberBuffer );\n    ASSERT( !FAILED( hr ), _L(\"CPUT GUI FPS counter buffer creation failure\"));\n    CPUTSetDebugName(mpTextUberBuffer, _L(\"CPUT GUI: control text vertex buffer\"));\n\n\n    // mpFocusedControlBuffer\n    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_VERTEX_BUFFER_SIZE;\n    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFocusedControlBuffer );\n    ASSERT( !FAILED( hr ), _L(\"CPUT GUI FPS counter buffer creation failure\"));\n    CPUTSetDebugName(mpFocusedControlBuffer, _L(\"CPUT GUI: focused control images vertex buffer\"));\n\n    \n    // mpFocusedControlTextBuffer\n    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE; //mFocusedControlTextBufferIndex;\n    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFocusedControlTextBuffer );\n    ASSERT( !FAILED( hr ), _L(\"CPUT GUI FPS counter buffer creation failure\"));\n    CPUTSetDebugName(mpFocusedControlTextBuffer, _L(\"CPUT GUI: focused control text vertex buffer\"));\n\n    // mpFPSDirectXBuffer\n    bd.ByteWidth = sizeof( CPUTGUIVertex ) * CPUT_GUI_BUFFER_STRING_SIZE;\n    hr = pD3dDevice->CreateBuffer( &bd, &InitData, &mpFPSDirectXBuffer );\n    ASSERT( !FAILED( hr ), _L(\"CPUT GUI FPS counter buffer creation failure\"));\n    CPUTSetDebugName(mpFPSDirectXBuffer, _L(\"CPUT GUI: FPS display text\"));\n    \n    // no longer need the device - release it.\n    SAFE_RELEASE(pD3dDevice);\n    SAFE_DELETE_ARRAY(pZeroedBuffer);    \n\n\n    // 8. Register all GUI sub-resources\n    // Walk all the controls/fonts and have them register all their required static resources\n    // Returning errors if you couldn't find your resources\n    result = CPUTText::RegisterStaticResources();\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n    result = CPUTButton::RegisterStaticResources();\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n    result = CPUTCheckbox::RegisterStaticResources();\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n    result = CPUTSlider::RegisterStaticResources();\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n    result = CPUTDropdown::RegisterStaticResources();\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n    // create the FPS CPUTText object for drawing FPS\n    mpFPSCounter = new CPUTText(_L(\"FPS:\"), ID_CPUT_GUI_FPS_COUNTER, mpFont);\n    mpFPSCounter->SetAutoArranged(false);\n    mpFPSCounter->SetPosition(0,0);\n\n    // start the timer\n    mpFPSTimer->StartTimer();\n\n    // done\n    return CPUT_SUCCESS;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTGuiControllerDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTGUICONTROLLERDX11_H__\n#define __CPUTGUICONTROLLERDX11_H__\n\n#include \"CPUTGuiController.h\"\n#include \"CPUTTimerWin.h\"\n\n#include \"CPUTButton.h\"\n#include \"CPUTText.h\"\n#include \"CPUTCheckbox.h\"\n#include \"CPUTSlider.h\"\n#include \"CPUTDropdown.h\"\n#include \"CPUTVertexShaderDX11.h\"\n#include \"CPUTPixelShaderDX11.h\"\n#include \"CPUTRenderStateBlockDX11.h\"\n\n//#define SAVE_RESTORE_DS_HS_GS_SHADER_STATE\n\n// forward declarations\nclass CPUT_DX11;\nclass CPUTButton;\nclass CPUTSlider;\nclass CPUTCheckbox;\nclass CPUTDropdown;\nclass CPUTText;\nclass CPUTTextureDX11;\nclass CPUTFontDX11;\n\nconst unsigned int CPUT_GUI_BUFFER_SIZE = 5000;         // size (in number of verticies) for all GUI control graphics\nconst unsigned int CPUT_GUI_BUFFER_STRING_SIZE = 5000;  // size (in number of verticies) for all GUI string graphics\nconst unsigned int CPUT_GUI_VERTEX_BUFFER_SIZE = 5000;\nconst CPUTControlID ID_CPUT_GUI_FPS_COUNTER = 4000000201;        // pick very random number for FPS counter string ID\n\n#include <d3d11.h>\n#include <xnamath.h> // for xmmatrix/et al\n\n\n// the GUI controller class that dispatches the rendering calls to all the buttons\n//--------------------------------------------------------------------------------\nclass CPUTGuiControllerDX11:public CPUTGuiController\n{ \n    struct GUIConstantBufferVS\n    {\n        XMMATRIX Projection;\n        XMMATRIX Model;\n    };\n\n\npublic:\n    static CPUTGuiControllerDX11 *GetController();\n    static CPUTResult DeleteController();\n\n    // initialization\n    CPUTResult Initialize(ID3D11DeviceContext *pImmediateContext, cString &ResourceDirectory);\n\tCPUTResult ReleaseResources();\n\t\n\n    // Control creation/deletion 'helpers'\n    CPUTResult CreateButton(const cString pButtonText, CPUTControlID controlID, CPUTControlID panelID, CPUTButton **ppButton=NULL);\n    CPUTResult CreateSlider(const cString pSliderText, CPUTControlID controlID, CPUTControlID panelID, CPUTSlider **ppSlider=NULL);\n    CPUTResult CreateCheckbox(const cString pCheckboxText, CPUTControlID controlID, CPUTControlID panelID, CPUTCheckbox **ppCheckbox=NULL);\n    CPUTResult CreateDropdown(const cString pSelectionText, CPUTControlID controlID, CPUTControlID panelID, CPUTDropdown **ppDropdown=NULL);\n    CPUTResult CreateText(const cString Text,  CPUTControlID controlID, CPUTControlID panelID, CPUTText **ppStatic=NULL);    \n    CPUTResult DeleteControl(CPUTControlID controlID);\n\n    // draw routines    \n    void Draw(ID3D11DeviceContext *pImmediateContext);\n    void DrawFPS(bool drawfps);\n    float GetFPS();\n\nprivate:\n    static CPUTGuiControllerDX11 *mguiController; // singleton object\n\n    // DirectX state objects for GUI drawing\n    CPUTVertexShaderDX11 *mpGUIVertexShader;\n    CPUTPixelShaderDX11  *mpGUIPixelShader;\n    ID3D11InputLayout    *mpVertexLayout;\n    ID3D11Buffer         *mpConstantBufferVS;\n    GUIConstantBufferVS   mModelViewMatrices;\n\n    // Texture atlas\n    CPUTTextureDX11            *mpControlTextureAtlas;\n    ID3D11ShaderResourceView   *mpControlTextureAtlasView;\n    ID3D11Buffer               *mpUberBuffer;\n    CPUTGUIVertex              *mpMirrorBuffer;\n    UINT                        mUberBufferIndex;\n    UINT                        mUberBufferMax;\n    \n    // Font atlas\n    CPUTFontDX11               *mpFont;\n    CPUTTextureDX11            *mpTextTextureAtlas;\n    ID3D11ShaderResourceView   *mpTextTextureAtlasView;\n    ID3D11Buffer               *mpTextUberBuffer;\n    CPUTGUIVertex              *mpTextMirrorBuffer;\n    UINT                        mTextUberBufferIndex;\n\n    // Focused control buffers\n    CPUTGUIVertex              *mpFocusedControlMirrorBuffer;\n    UINT                        mFocusedControlBufferIndex;\n    ID3D11Buffer               *mpFocusedControlBuffer;\n    CPUTGUIVertex              *mpFocusedControlTextMirrorBuffer;\n    UINT                        mFocusedControlTextBufferIndex;\n    ID3D11Buffer               *mpFocusedControlTextBuffer;\n\n\n\n    // FPS\n    bool                        mbDrawFPS;\n    float                       mLastFPS;\n    CPUTText                   *mpFPSCounter;\n    // FPS control buffers\n    CPUTGUIVertex              *mpFPSMirrorBuffer;\n    UINT                        mFPSBufferIndex;\n    ID3D11Buffer               *mpFPSDirectXBuffer;\n    CPUTTimerWin               *mpFPSTimer;\n\n    // render state\n    CPUTRenderStateBlockDX11   *mpGUIRenderStateBlock;\n    CPUTResult UpdateUberBuffers(ID3D11DeviceContext *pImmediateContext );\n\n#ifdef SAVE_RESTORE_DS_HS_GS_SHADER_STATE\n    ID3D11GeometryShader   *mpGeometryShaderState;\n    ID3D11ClassInstance    *mpGeometryShaderClassInstances;\n    UINT                    mGeometryShaderNumClassInstances;\n\n    ID3D11HullShader       *mpHullShaderState;\n    ID3D11ClassInstance    *mpHullShaderClassInstances;\n    UINT                    mHullShaderNumClassInstance;\n\n    ID3D11DomainShader     *mpDomainShaderState;\n    ID3D11ClassInstance    *mpDomainShaderClassIntances;\n    UINT                    mDomainShaderNumClassInstances;\n#endif\n\n\n    // members for saving render state before/after drawing gui\n    D3D11_PRIMITIVE_TOPOLOGY    mTopology;\n\n    // helper functions\n    CPUTGuiControllerDX11();    // singleton\n    ~CPUTGuiControllerDX11();\n    CPUTResult RegisterGUIResources(ID3D11DeviceContext *pImmediateContext, cString VertexShaderFilename, cString RenderStateFile, cString PixelShaderFilename, cString DefaultFontFilename, cString ControlTextureAtlas);\n    void SetGUIDrawingState(ID3D11DeviceContext *pImmediateContext);\n    void ClearGUIDrawingState(ID3D11DeviceContext *pImmediateContext);\n};\n\n\n\n\n#endif // #ifndef __CPUTGUICONTROLLERDX11_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTHullShaderDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTHullShaderDX11.h\"\n#include \"CPUTAssetLibraryDX11.h\"\n\nCPUTHullShaderDX11 *CPUTHullShaderDX11::CreateHullShader(\n    const cString     &name,\n    ID3D11Device      *pD3dDevice,\n    const cString     &shaderMain,\n    const cString     &shaderProfile\n)\n{\n    ID3DBlob          *pCompiledBlob = NULL;\n    ID3D11HullShader  *pNewHullShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromFile(name, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling Hull shader:\\n\\n\") );\n\n    // Create the Hull shader\n    // TODO: Move to Hull shader class\n    HRESULT hr = pD3dDevice->CreateHullShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewHullShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating Hull shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetHullShader \")+name;\n    // CPUTSetDebugName(pNewHullShader, DebugName);\n\n    CPUTHullShaderDX11 *pNewCPUTHullShader = new CPUTHullShaderDX11( pNewHullShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddHullShader(name + shaderMain + shaderProfile, pNewCPUTHullShader);\n    // pNewCPUTHullShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTHullShader;\n}\n\n//--------------------------------------------------------------------------------------\nCPUTHullShaderDX11 *CPUTHullShaderDX11::CreateHullShaderFromMemory(\n    const cString     &name,\n    ID3D11Device      *pD3dDevice,\n    const cString     &shaderMain,\n    const cString     &shaderProfile,\n    const char        *pShaderSource\n)\n{\n    ID3DBlob          *pCompiledBlob = NULL;\n    ID3D11HullShader  *pNewHullShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromMemory(pShaderSource, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling Hull shader:\\n\\n\") );\n\n    // Create the Hull shader\n    // TODO: Move to Hull shader class\n    HRESULT hr = pD3dDevice->CreateHullShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewHullShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating Hull shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetHullShader \")+name;\n    // CPUTSetDebugName(pNewHullShader, DebugName);\n\n    CPUTHullShaderDX11 *pNewCPUTHullShader = new CPUTHullShaderDX11( pNewHullShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddHullShader(name + shaderMain + shaderProfile, pNewCPUTHullShader);\n    // pNewCPUTHullShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTHullShader;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTHullShaderDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTHULLSHADERDX11_H\n#define _CPUTHULLSHADERDX11_H\n\n#include \"CPUT.h\"\n#include \"CPUTShaderDX11.h\"\n\nclass CPUTHullShaderDX11 : public CPUTShaderDX11\n{\nprotected:\n    ID3D11HullShader *mpHullShader;\n\n    // Destructor is not public.  Must release instead of delete.\n    ~CPUTHullShaderDX11(){ SAFE_RELEASE(mpHullShader); }\n\npublic:\n    static CPUTHullShaderDX11 *CreateHullShader(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile\n    );\n    static CPUTHullShaderDX11 *CreateHullShaderFromMemory(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile,\n        const char           *pShaderSource\n    );\n\n\n    CPUTHullShaderDX11() : mpHullShader(NULL), CPUTShaderDX11(NULL) {}\n    CPUTHullShaderDX11(ID3D11HullShader *pD3D11HullShader, ID3DBlob *pBlob) : mpHullShader(pD3D11HullShader), CPUTShaderDX11(pBlob) {}\n    ID3DBlob *GetBlob() { return mpBlob; }\n    ID3D11HullShader *GetNativeHullShader() { return mpHullShader; }\n};\n\n#endif //_CPUTHULLSHADER_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTITTTaskMarker.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTITTTaskMarker.h\"\n\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n// Constructor\n// automatically creates an ITT begin marker at the start of this task\n//-----------------------------------------------------------------------------\nCPUTITTTaskMarker::CPUTITTTaskMarker(__itt_domain *pITTDomain, __itt_string_handle *pITTStringHandle)\n{\n    mpITTDomain = pITTDomain;\n    mpITTStringHandle = pITTStringHandle;\n\n    __itt_task_begin(pITTDomain, __itt_null, __itt_null, pITTStringHandle);\n}\n\n\n// Destructor\n// When the class goes out of scope, this marker will automatically be called\n// and the domain 'closed'\n//-----------------------------------------------------------------------------\nCPUTITTTaskMarker::~CPUTITTTaskMarker()\n{\n    __itt_task_end(mpITTDomain);\n}\n#else\n    // This is a bit of a hack to get the compiler not to complain about this being an empty file\n    // during the compilation in any mode that doesn't have CPUT_GPA_INSTRUMENTATION defined\n    #define CPUTITTTaskMarkerNotEmpty()   namespace { char CPUTITTTaskMarkerDummy##__LINE__; }\n    CPUTITTTaskMarkerNotEmpty();\n#endif\n"
  },
  {
    "path": "CPUT/CPUT/CPUTITTTaskMarker.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTITTTASKMARKER_H__\n#define __CPUTITTTASKMARKER_H__\n\n\n\n#include \"CPUT.h\"\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n\n// GPA ITT instrumentation helper class - only available in profile build\n// Automatically open/close marks an ITT marker event for GPA\n//-----------------------------------------------------------------------------\nclass CPUTITTTaskMarker\n{\npublic:\n    CPUTITTTaskMarker(__itt_domain *pITTDomain, __itt_string_handle *pITTStringHandle);\n    ~CPUTITTTaskMarker();\nprivate:\n    __itt_domain *mpITTDomain;\n    __itt_string_handle *mpITTStringHandle;\n};\n\n#endif\n#endif // #ifndef __CPUTITTTASKMARKER_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTInputLayoutCache.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTINPUTLAYOUTMANAGER_H__\n#define __CPUTINPUTLAYOUTMANAGER_H__\n\n#include \"CPUT.h\"\n\nclass CPUTInputLayoutCache\n{\npublic:\n    CPUTInputLayoutCache() {;}\n    virtual ~CPUTInputLayoutCache() {;}\nprivate:\n};\n\n\n#endif //#define __CPUTINPUTLAYOUTMANAGER_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTInputLayoutCacheDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTInputLayoutCacheDX11.h\"\n#include \"CPUTVertexShaderDX11.h\"\n\nextern const cString *gpDXGIFormatNames;\n\nCPUTInputLayoutCacheDX11* CPUTInputLayoutCacheDX11::mpInputLayoutCache = NULL;\n\n//-----------------------------------------------------------------------------\nvoid CPUTInputLayoutCacheDX11::ClearLayoutCache()\n{\n\t// iterate over the entire map - and release each layout object\n    std::map<cString, ID3D11InputLayout*>::iterator mapIterator;\n\n    for(mapIterator = mLayoutList.begin(); mapIterator != mLayoutList.end(); mapIterator++)\n    {\n        mapIterator->second->Release();  // release the ID3D11InputLayout*\n    }\n    mLayoutList.clear();\n}\n\n// singleton retriever\n//-----------------------------------------------------------------------------\nCPUTInputLayoutCacheDX11* CPUTInputLayoutCacheDX11::GetInputLayoutCache()\n{\n    if(NULL == mpInputLayoutCache)\n    {\n        mpInputLayoutCache = new CPUTInputLayoutCacheDX11();\n    }\n    return mpInputLayoutCache;\n}\n\n// singleton destroy routine\n//-----------------------------------------------------------------------------\nCPUTResult CPUTInputLayoutCacheDX11::DeleteInputLayoutCache()\n{\n    if(mpInputLayoutCache)\n    {\n        delete mpInputLayoutCache;\n        mpInputLayoutCache = NULL;\n    }\n    return CPUT_SUCCESS;\n}\n\n// find existing, or create new, ID3D11InputLayout layout\n//-----------------------------------------------------------------------------\nCPUTResult CPUTInputLayoutCacheDX11::GetLayout(\n    ID3D11Device *pDevice,\n    D3D11_INPUT_ELEMENT_DESC *pDXLayout,\n    CPUTVertexShaderDX11 *pVertexShader,\n    ID3D11InputLayout **ppInputLayout\n){\n    // Generate the vertex layout pattern portion of the key\n    cString layoutKey = GenerateLayoutKey(pDXLayout);\n\n    // Append the vertex shader pointer to the key for layout<->vertex shader relationship\n    cString address = ptoc(pVertexShader);\n    layoutKey += address;\n\n    // Do we already have one like this?\n    if( mLayoutList[layoutKey] )\n    {\n        *ppInputLayout = mLayoutList[layoutKey];\n\t\t(*ppInputLayout)->AddRef();\n        return CPUT_SUCCESS;\n    }\n    // Not found, create a new ID3D11InputLayout object\n\n    // How many elements are in the input layout?\n    int numInputLayoutElements=0;\n    while(NULL != pDXLayout[numInputLayoutElements].SemanticName)\n    {\n        numInputLayoutElements++;\n    }\n    // Create the input layout\n    HRESULT hr;\n    ID3DBlob *pBlob = pVertexShader->GetBlob();\n    hr = pDevice->CreateInputLayout( pDXLayout, numInputLayoutElements, pBlob->GetBufferPointer(), pBlob->GetBufferSize(), ppInputLayout );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating input layout.\") );\n\tCPUTSetDebugName( *ppInputLayout, _L(\"CPUTInputLayoutCacheDX11::GetLayout()\") );\n\n    // Store this layout object in our map\n    mLayoutList[layoutKey] = *ppInputLayout;\n\n    // Addref for storing it in our map as well as returning it (count should be = 2 at this point)\n    (*ppInputLayout)->AddRef();\n\n    return CPUT_SUCCESS;\n}\n\n// Generate a string version of the vertex-buffer's layout.  Allows us to search, compare, etc...\n//-----------------------------------------------------------------------------\ncString CPUTInputLayoutCacheDX11::GenerateLayoutKey(D3D11_INPUT_ELEMENT_DESC *pDXLayout)\n{\n    // TODO:  Duh!  We can simply memcmp the DX layouts == use the layout input description directly as the key.\n    //        We just need to know how many elements, or NULL terminate it.\n    //        Uses less memory, faster, etc...\n    //        Duh!\n\n    if( !pDXLayout[0].SemanticName )\n    {\n        return _L(\"\");\n    }\n    // TODO: Use shorter names, etc...\n    ASSERT( (pDXLayout[0].Format>=0) && (pDXLayout[0].Format<=DXGI_FORMAT_BC7_UNORM_SRGB), _L(\"Invalid DXGI Format.\") );\n    // Start first layout entry and no comma.\n    cString layoutKey = s2ws(pDXLayout[0].SemanticName) + _L(\":\") + gpDXGIFormatNames[pDXLayout[0].Format];\n    for( int index=1; NULL != pDXLayout[index].SemanticName; index++ )\n    {\n        ASSERT( (pDXLayout[index].Format>=0) && (pDXLayout[index].Format<=DXGI_FORMAT_BC7_UNORM_SRGB), _L(\"Invalid DXGI Format.\") );\n        // Add a comma and the next layout entry\n        layoutKey = layoutKey + _L(\",\") + s2ws(pDXLayout[index].SemanticName) + _L(\":\") + gpDXGIFormatNames[pDXLayout[index].Format];\n    }\n    return layoutKey;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTInputLayoutCacheDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTINPUTLAYOUTCACHERDX11_H__\n#define __CPUTINPUTLAYOUTCACHERDX11_H__\n\n#include \"CPUTInputLayoutCache.h\"\n#include \"CPUTOSServicesWin.h\"\n#include \"CPUTVertexShaderDX11.h\"\n#include <D3D11.h> // D3D11_INPUT_ELEMENT_DESC\n#include <map>\n\nclass CPUTInputLayoutCacheDX11:public CPUTInputLayoutCache\n{\npublic:\n    ~CPUTInputLayoutCacheDX11()\n    {\n        ClearLayoutCache();\n    }\n    static CPUTInputLayoutCacheDX11 *GetInputLayoutCache();\n    static CPUTResult DeleteInputLayoutCache();\n    CPUTResult GetLayout(ID3D11Device *pDevice, D3D11_INPUT_ELEMENT_DESC *pDXLayout, CPUTVertexShaderDX11 *pVertexShader, ID3D11InputLayout **ppInputLayout);\n\tvoid ClearLayoutCache();\n\nprivate:\n    // singleton\n    CPUTInputLayoutCacheDX11() { mLayoutList.clear(); }\n\n    // convert the D3D11_INPUT_ELEMENT_DESC to string key\n    cString GenerateLayoutKey(D3D11_INPUT_ELEMENT_DESC *pDXLayout);\n\n    CPUTResult VerifyLayoutCompatibility(D3D11_INPUT_ELEMENT_DESC *pDXLayout, ID3DBlob *pVertexShaderBlob);\n\n    static CPUTInputLayoutCacheDX11 *mpInputLayoutCache;\n    std::map<cString, ID3D11InputLayout*> mLayoutList;\n};\n\n#endif //#define __CPUTINPUTLAYOUTCACHERDX11_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTLight.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUT.h\"\n#include \"CPUTLight.h\"\n\n// Read light properties from .set file\n//-----------------------------------------------------------------------------\nCPUTResult CPUTLight::LoadLight(CPUTConfigBlock *pBlock, int *pParentID)\n{\n    ASSERT( (NULL!=pBlock), _L(\"Invalid NULL parameter.\") );\n\n    CPUTResult result = CPUT_SUCCESS;\n\n    // set the null/group node name\n    mName = pBlock->GetValueByName(_L(\"name\"))->ValueAsString();\n\n    // get the parent ID\n    *pParentID = pBlock->GetValueByName(_L(\"parent\"))->ValueAsInt();\n\n    LoadParentMatrixFromParameterBlock( pBlock );\n\n    cString lightType = pBlock->GetValueByName(_L(\"lighttype\"))->ValueAsString();\n    if(lightType.compare(_L(\"spot\")) == 0)\n    {\n        mLightParams.nLightType = CPUT_LIGHT_SPOT;\n    }\n    else if(lightType.compare(_L(\"directional\")) == 0)\n    {\n        mLightParams.nLightType = CPUT_LIGHT_DIRECTIONAL;\n    }\n    else if(lightType.compare(_L(\"point\")) == 0)\n    {\n        mLightParams.nLightType = CPUT_LIGHT_POINT;\n    }\n    else\n    {\n        // ASSERT(0,_L(\"\"));\n        // TODO: why doesn't assert work here?\n    }\n\n    pBlock->GetValueByName(_L(\"Color\"))->ValueAsFloatArray(mLightParams.pColor, 3);\n    mLightParams.fIntensity    = pBlock->GetValueByName(_L(\"Intensity\"))->ValueAsFloat();\n    mLightParams.fHotSpot      = pBlock->GetValueByName(_L(\"HotSpot\"))->ValueAsFloat();\n    mLightParams.fConeAngle    = pBlock->GetValueByName(_L(\"ConeAngle\"))->ValueAsFloat();\n    mLightParams.fDecayStart   = pBlock->GetValueByName(_L(\"DecayStart\"))->ValueAsFloat();\n    mLightParams.bEnableFarAttenuation = pBlock->GetValueByName(_L(\"EnableNearAttenuation\"))->ValueAsBool();\n    mLightParams.bEnableFarAttenuation = pBlock->GetValueByName(_L(\"EnableFarAttenuation\"))->ValueAsBool();\n    mLightParams.fNearAttenuationStart = pBlock->GetValueByName(_L(\"NearAttenuationStart\"))->ValueAsFloat();\n    mLightParams.fNearAttenuationEnd   = pBlock->GetValueByName(_L(\"NearAttenuationEnd\"))->ValueAsFloat();\n    mLightParams.fFarAttenuationStart  = pBlock->GetValueByName(_L(\"FarAttenuationStart\"))->ValueAsFloat();\n    mLightParams.fFarAttenuationEnd    = pBlock->GetValueByName(_L(\"FarAttenuationEnd\"))->ValueAsFloat();\n\n    return result;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTLight.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTLight_H__\n#define __CPUTLight_H__\n\n#include \"CPUT.h\"\n#include \"CPUTRenderNode.h\"\n#include \"CPUTConfigBlock.h\"\n\nenum LightType\n{\n    CPUT_LIGHT_DIRECTIONAL,\n    CPUT_LIGHT_POINT,\n    CPUT_LIGHT_SPOT,\n};\n\nstruct CPUTLightParams\n{\n    LightType   nLightType;\n    float       pColor[3];\n    float       fIntensity;\n    float       fHotSpot;\n    float       fConeAngle;\n    float       fDecayStart;\n    bool        bEnableNearAttenuation;\n    bool        bEnableFarAttenuation;\n    float       fNearAttenuationStart;\n    float       fNearAttenuationEnd;\n    float       fFarAttenuationStart;\n    float       fFarAttenuationEnd;\n};\n\nclass CPUTLight:public CPUTRenderNode\n{\nprotected:\n    CPUTLightParams mLightParams;\npublic:\n    CPUTLight() {}\n    virtual ~CPUTLight() {}\n\n    void             SetLightParameters(CPUTLightParams &lightParams);\n    CPUTLightParams *GetLightParameters() {return &mLightParams; }\n    CPUTResult       LoadLight(CPUTConfigBlock *pBlock, int *pParentID);\n};\n\n#endif //#ifndef __CPUTLight_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTMaterial.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUT.h\"\n#include \"CPUTAssetLibrary.h\"\n\n#ifdef CPUT_FOR_DX11\n#include \"CPUTMaterialDX11.h\"\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n\n\nCPUTMaterial *CPUTMaterial::CreateMaterial( const cString &absolutePathAndFilename, const cString &modelSuffix, const cString &meshSuffix )\n{\n    // material was not in the library, so load it\n#ifdef CPUT_FOR_DX11\n    CPUTMaterial *pMaterial = new CPUTMaterialDX11();\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n    CPUTResult result = pMaterial->LoadMaterial(absolutePathAndFilename, modelSuffix, meshSuffix);\n    ASSERT( CPUTSUCCESS(result), _L(\"\\nError - CPUTAssetLibrary::GetMaterial() - Error in material file: '\")+absolutePathAndFilename+_L(\"'\") );\n\n    // add material to material library list\n    // cString finalName = pMaterial->MaterialRequiresPerModelPayload() ? absolutePathAndFilename +  modelSuffix + meshSuffix : absolutePathAndFilename;\n    // CPUTAssetLibrary::GetAssetLibrary()->AddMaterial( finalName, pMaterial );\n    CPUTAssetLibrary::GetAssetLibrary()->AddMaterial( absolutePathAndFilename, pMaterial );\n\n    return pMaterial;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTMaterial.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTMATERIAL_H__\n#define __CPUTMATERIAL_H__\n\n#include <stdio.h>\n#include \"CPUT.h\"\n#include \"CPUTRefCount.h\"\n#include \"CPUTConfigBlock.h\"\n#include \"CPUTTexture.h\"\n#include \"CPUTRenderStateBlock.h\"\n\nclass CPUTShaderParameters;\n\n// TODO: Where did this number come frome?  It should also be different for each API\n#define CPUT_MATERIAL_MAX_TEXTURE_SLOTS         32\n#define CPUT_MATERIAL_MAX_BUFFER_SLOTS          32\n#define CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS 32\n#define CPUT_MATERIAL_MAX_SRV_SLOTS             32\n\n#if 0 // Need to handle >=DX11 vs. < DX11, where max UAV slots == 1;\n#   define CPUT_MATERIAL_MAX_UAV_SLOTS             7\n#else\n#   define CPUT_MATERIAL_MAX_UAV_SLOTS             1\n#endif\n\nclass CPUTMaterial:public CPUTRefCount\n{\nprotected:\n    cString               mMaterialName;\n    CPUTConfigBlock       mConfigBlock;\n    CPUTRenderStateBlock *mpRenderStateBlock;\n    UINT                  mBufferCount;\n    CPUTTexture          *mpTexture[CPUT_MATERIAL_MAX_TEXTURE_SLOTS];\n\n    // TODO: DX11 has buffers, UAVs, and constant buffers.  Do these belong there?\n    CPUTBuffer           *mpBuffer[CPUT_MATERIAL_MAX_BUFFER_SLOTS];\n    CPUTBuffer           *mpUAV[CPUT_MATERIAL_MAX_UAV_SLOTS];\n    CPUTBuffer           *mpConstantBuffer[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n\n    // Destructor is not public.  Must release instead of delete.\n    virtual ~CPUTMaterial(){\n\t\t// The following are allocated in the derived class.  So, release there too.\n        // for( UINT ii=0; ii<CPUT_MATERIAL_MAX_TEXTURE_SLOTS; ii++ ) { SAFE_RELEASE( mpTexture[ii] ); }\n        // for( UINT ii=0; ii<CPUT_MATERIAL_MAX_BUFFER_SLOTS; ii++ ) { SAFE_RELEASE( mpBuffer[ii] ); }\n        // for( UINT ii=0; ii<CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS; ii++ ) { SAFE_RELEASE( mpConstantBuffer[ii] ); }\n        // SAFE_RELEASE(mpRenderStateBlock);\n    }\n\npublic:\n    static CPUTMaterial *CreateMaterial( const cString &absolutePathAndFilename, const cString &modelSuffix, const cString &meshSuffix );\n    static CPUTConfigBlock mGlobalProperties;\n\n    CPUTMaterial() :\n\t\tmpRenderStateBlock(NULL),\n\t\tmBufferCount(0)\n\t{\n        for( UINT ii=0; ii<CPUT_MATERIAL_MAX_TEXTURE_SLOTS; ii++ )         { mpTexture[ii]       = NULL; }\n        for( UINT ii=0; ii<CPUT_MATERIAL_MAX_BUFFER_SLOTS; ii++ )          { mpBuffer[ii]        = NULL; }\n        for( UINT ii=0; ii<CPUT_MATERIAL_MAX_UAV_SLOTS; ii++ )             { mpUAV[ii]           = NULL; }\n        for( UINT ii=0; ii<CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS; ii++ ) { mpConstantBuffer[ii]= NULL; }\n    };\n\n    void                  SetMaterialName(const cString MaterialName) { mMaterialName = MaterialName; }\n    void                  GetMaterialName(cString &MaterialName)      { MaterialName   = mMaterialName; }\n    virtual CPUTResult    LoadMaterial(const cString &fileName, const cString &modelSuffix, const cString &meshSuffix) = 0;\n    virtual void          ReleaseTexturesAndBuffers() = 0;\n    virtual void          RebindTexturesAndBuffers() = 0;\n    virtual void          SetRenderStates(CPUTRenderParameters &renderParams) { if( mpRenderStateBlock ) { mpRenderStateBlock->SetRenderStates(renderParams); } }\n    virtual bool          MaterialRequiresPerModelPayload() = 0;\n    virtual CPUTMaterial *CloneMaterial( const cString &absolutePathAndFilename, const cString &modelSuffix, const cString &meshSuffix ) = 0;\n};\n\n#endif //#ifndef __CPUTMATERIAL_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTMaterialDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTMaterialDX11.h\"\n#include \"CPUT_DX11.h\"\n#include \"CPUTTextureDX11.h\"\n#include \"CPUTBufferDX11.h\"\n#include \"CPUTVertexShaderDX11.h\"\n#include \"CPUTPixelShaderDX11.h\"\n#include \"CPUTComputeShaderDX11.h\"\n#include \"CPUTGeometryShaderDX11.h\"\n#include \"CPUTDomainShaderDX11.h\"\n#include \"CPUTHullShaderDX11.h\"\n\n#define OUTPUT_BINDING_DEBUG_INFO(x)\n// #define OUTPUT_BINDING_DEBUG_INFO(x) OutputDebugString(x)\n\nCPUTConfigBlock CPUTMaterial::mGlobalProperties;\n\n// Note: These initial values shouldn't really matter.  We call ResetStateTracking() before we render (and it performs these initializations)\nvoid *CPUTMaterialDX11::mpLastVertexShader   = (void*)-1;\nvoid *CPUTMaterialDX11::mpLastPixelShader    = (void*)-1;\nvoid *CPUTMaterialDX11::mpLastComputeShader  = (void*)-1;\nvoid *CPUTMaterialDX11::mpLastGeometryShader = (void*)-1;\nvoid *CPUTMaterialDX11::mpLastHullShader     = (void*)-1;\nvoid *CPUTMaterialDX11::mpLastDomainShader   = (void*)-1;\nvoid *CPUTMaterialDX11::mpLastVertexShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS]                     = {0};\nvoid *CPUTMaterialDX11::mpLastPixelShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS]                      = {0};\nvoid *CPUTMaterialDX11::mpLastComputeShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS]                    = {0};\nvoid *CPUTMaterialDX11::mpLastGeometryShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS]                   = {0};\nvoid *CPUTMaterialDX11::mpLastHullShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS]                       = {0};\nvoid *CPUTMaterialDX11::mpLastDomainShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS]                     = {0};\nvoid *CPUTMaterialDX11::mpLastVertexShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS]   = {0};\nvoid *CPUTMaterialDX11::mpLastPixelShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS]    = {0};\nvoid *CPUTMaterialDX11::mpLastComputeShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS]  = {0};\nvoid *CPUTMaterialDX11::mpLastGeometryShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS] = {0};\nvoid *CPUTMaterialDX11::mpLastHullShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS]     = {0};\nvoid *CPUTMaterialDX11::mpLastDomainShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS]   = {0};\nvoid *CPUTMaterialDX11::mpLastComputeShaderUAVs[CPUT_MATERIAL_MAX_UAV_SLOTS]                         = {0};\nvoid *CPUTMaterialDX11::mpLastRenderStateBlock  = (void*)-1;\n\n//-----------------------------------------------------------------------------\nCPUTShaderParameters::~CPUTShaderParameters()\n{\n    for(int ii=0; ii<CPUT_MATERIAL_MAX_TEXTURE_SLOTS; ii++)\n    {\n        SAFE_RELEASE(mppBindViews[ii]);\n        SAFE_RELEASE(mpTexture[ii]);\n    }\n    for(int ii=0; ii<CPUT_MATERIAL_MAX_BUFFER_SLOTS; ii++)\n    {\n        SAFE_RELEASE(mpBuffer[ii]);\n    }\n    for(int ii=0; ii<CPUT_MATERIAL_MAX_UAV_SLOTS; ii++)\n    {\n        SAFE_RELEASE(mppBindUAVs[ii]);\n        SAFE_RELEASE(mpUAV[ii]);\n    }\n    for(int ii=0; ii<CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS; ii++)\n    {\n        SAFE_RELEASE(mppBindConstantBuffers[ii]);\n        SAFE_RELEASE(mpConstantBuffer[ii]);\n    }\n    SAFE_DELETE_ARRAY(mpTextureParameterName);\n    SAFE_DELETE_ARRAY(mpTextureParameterBindPoint);\n    SAFE_DELETE_ARRAY(mpSamplerParameterName);\n    SAFE_DELETE_ARRAY(mpSamplerParameterBindPoint);\n    SAFE_DELETE_ARRAY(mpBufferParameterName);\n    SAFE_DELETE_ARRAY(mpBufferParameterBindPoint);\n    SAFE_DELETE_ARRAY(mpUAVParameterName);\n    SAFE_DELETE_ARRAY(mpUAVParameterBindPoint);\n    SAFE_DELETE_ARRAY(mpConstantBufferParameterName);\n    SAFE_DELETE_ARRAY(mpConstantBufferParameterBindPoint)\n}\n\n//-----------------------------------------------------------------------------\nCPUTMaterialDX11::CPUTMaterialDX11() :\n    mpPixelShader(NULL),\n    mpComputeShader(NULL),\n    mpVertexShader(NULL),\n    mpGeometryShader(NULL),\n    mpHullShader(NULL),\n    mpDomainShader(NULL)\n{\n    // TODO: Is there a better/safer way to initialize this list?\n    mpShaderParametersList[0] =  &mPixelShaderParameters,\n    mpShaderParametersList[1] =  &mComputeShaderParameters,\n    mpShaderParametersList[2] =  &mVertexShaderParameters,\n    mpShaderParametersList[3] =  &mGeometryShaderParameters,\n    mpShaderParametersList[4] =  &mHullShaderParameters,\n    mpShaderParametersList[5] =  &mDomainShaderParameters,\n    mpShaderParametersList[6] =  NULL;\n}\n\n//-----------------------------------------------------------------------------\nCPUTMaterialDX11::~CPUTMaterialDX11()\n{\n    SAFE_RELEASE(mpPixelShader);\n    SAFE_RELEASE(mpComputeShader);\n    SAFE_RELEASE(mpVertexShader);\n    SAFE_RELEASE(mpGeometryShader);\n    SAFE_RELEASE(mpHullShader);\n    SAFE_RELEASE(mpDomainShader);\n    SAFE_RELEASE(mpRenderStateBlock);\n\n    CPUTMaterial::~CPUTMaterial();\n}\n\n// **********************************\n// **** Set Shader resources if they changed\n// **********************************\n#define SET_SHADER_RESOURCES( SHADER, SHADER_TYPE ) \\\n    /* If the shader changed ... */ \\\n    if( mpLast##SHADER##Shader != mp##SHADER##Shader ) \\\n    { \\\n        mpLast##SHADER##Shader = mp##SHADER##Shader; \\\n        pContext->##SHADER_TYPE##SetShader( mp##SHADER##Shader ? mp##SHADER##Shader->GetNative##SHADER##Shader() : NULL, NULL, 0 ); \\\n    } \\\n    /* Spend time checking shader resources only if a shader is bound ... */ \\\n    if( mp##SHADER##Shader ) \\\n    { \\\n        if( m##SHADER##ShaderParameters.mTextureCount || m##SHADER##ShaderParameters.mBufferCount ) \\\n        { \\\n            same = true; \\\n            /* If all of the texture slots we need are already bound to our textures, then skip setting the SRVs... */\\\n            for( UINT ii=0; ii < m##SHADER##ShaderParameters.mTextureCount; ii++ ) \\\n            { \\\n                UINT bindPoint = m##SHADER##ShaderParameters.mpTextureParameterBindPoint[ii]; \\\n                if(mpLast##SHADER##ShaderViews[bindPoint] != m##SHADER##ShaderParameters.mppBindViews[bindPoint] ) \\\n                { \\\n                    mpLast##SHADER##ShaderViews[bindPoint] = m##SHADER##ShaderParameters.mppBindViews[bindPoint]; \\\n                    same = false; \\\n                } \\\n            } \\\n            for( UINT ii=0; ii < m##SHADER##ShaderParameters.mBufferCount; ii++ ) \\\n            { \\\n                UINT bindPoint = m##SHADER##ShaderParameters.mpBufferParameterBindPoint[ii]; \\\n                if(mpLast##SHADER##ShaderViews[bindPoint] != m##SHADER##ShaderParameters.mppBindViews[bindPoint] ) \\\n                { \\\n                    mpLast##SHADER##ShaderViews[bindPoint] = m##SHADER##ShaderParameters.mppBindViews[bindPoint]; \\\n                    same = false; \\\n                } \\\n            } \\\n            if( !same ) \\\n            { \\\n                int min   = m##SHADER##ShaderParameters.mBindViewMin; \\\n                int max   = m##SHADER##ShaderParameters.mBindViewMax; \\\n                int count = max - min + 1; \\\n                pContext->SHADER_TYPE##SetShaderResources( min, count, &m##SHADER##ShaderParameters.mppBindViews[min] ); \\\n            } \\\n        } \\\n        if( m##SHADER##ShaderParameters.mConstantBufferCount ) \\\n        { \\\n            same = true; \\\n            /* If all of the constant buffer slots we need are already bound to our constant buffers, then skip setting the SRVs... */\\\n            for( UINT ii=0; ii<m##SHADER##ShaderParameters.mConstantBufferCount; ii++ ) \\\n            { \\\n                UINT bindPoint = m##SHADER##ShaderParameters.mpConstantBufferParameterBindPoint[ii]; \\\n                if(mpLast##SHADER##ShaderConstantBuffers[bindPoint] != m##SHADER##ShaderParameters.mppBindConstantBuffers[bindPoint] ) \\\n                { \\\n                    mpLast##SHADER##ShaderConstantBuffers[bindPoint] = m##SHADER##ShaderParameters.mppBindConstantBuffers[bindPoint]; \\\n                    same = false; \\\n                } \\\n            } \\\n            if(!same) \\\n            { \\\n                int min   = m##SHADER##ShaderParameters.mBindConstantBufferMin; \\\n                int max   = m##SHADER##ShaderParameters.mBindConstantBufferMax; \\\n                int count = max - min + 1; \\\n                pContext->SHADER_TYPE##SetConstantBuffers(min, count,    &m##SHADER##ShaderParameters.mppBindConstantBuffers[min] ); \\\n            } \\\n        } \\\n    }\n\n//-----------------------------------------------------------------------------\nvoid CPUTMaterialDX11::SetRenderStates( CPUTRenderParameters &renderParams )\n{\n    ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n    bool same = true;\n\n    SET_SHADER_RESOURCES( Vertex,    VS );\n    SET_SHADER_RESOURCES( Pixel,     PS );\n    SET_SHADER_RESOURCES( Compute,   CS );\n    SET_SHADER_RESOURCES( Geometry,  GS );\n    SET_SHADER_RESOURCES( Hull,      HS );\n    SET_SHADER_RESOURCES( Domain,    DS );\n\n    // Only the compute shader may have UAVs to bind.\n    // Note that pixel shaders can too, but DX requires setting those when setting RTV(s).\n    same = true;\n    for( UINT ii=0; ii<mComputeShaderParameters.mUAVCount; ii++ )\n    {\n        UINT bindPoint = mComputeShaderParameters.mpUAVParameterBindPoint[ii];\n        if(mpLastComputeShaderUAVs[ii] != mComputeShaderParameters.mppBindUAVs[bindPoint] )\n        {\n            mpLastComputeShaderUAVs[ii] = mComputeShaderParameters.mppBindUAVs[bindPoint];\n            same = false;\n        }\n    }\n#if 0\n\tif( mPixelShaderParameters.mUAVCount )\n\t{\n        ID3D11RenderTargetView *pRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];\n        ID3D11DepthStencilView *pDSV;\n        pContext->OMGetRenderTargets( D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, &pRTVs[0], &pDSV );\n        // Count the RTVs\n        UINT rtvCount;\n        for( rtvCount=D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT-1; rtvCount>0; rtvCount-- )\n        {\n            if( 0 != pRTVs[rtvCount] ) break;\n        }\n        rtvCount+=1;\n\t    pContext->OMSetRenderTargetsAndUnorderedAccessViews(\n            rtvCount,\n            pRTVs,\n            pDSV,\n            rtvCount,\n            CPUT_MATERIAL_MAX_UAV_SLOTS-rtvCount,\n            &mPixelShaderParameters.mppBindUAVs[rtvCount],\n            NULL\n        );\n        SAFE_RELEASE(pDSV);\n        for( UINT ii=0; ii<D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; ii++ )\n        {\n            SAFE_RELEASE( pRTVs[ii] );\n        }\n\t}\n#endif\n    if(mComputeShaderParameters.mUAVCount && !same)\n    {\n        int min   = mComputeShaderParameters.mBindUAVMin;\n        int max   = mComputeShaderParameters.mBindUAVMax;\n        int count = max - min + 1;\n        pContext->CSSetUnorderedAccessViews(min, count, &mComputeShaderParameters.mppBindUAVs[min], NULL );\n    }\n\n    // Set the render state block if it changed\n    if( mpLastRenderStateBlock != mpRenderStateBlock )\n    {\n        mpLastRenderStateBlock = mpRenderStateBlock;\n        if( mpRenderStateBlock )\n        {\n            // We know we have a DX11 class.  Does this correctly bypass the virtual?\n            // Should we move it to the DX11 class.\n            ((CPUTRenderStateBlockDX11*)mpRenderStateBlock)->SetRenderStates(renderParams);\n        }\n        else\n        {\n            CPUTRenderStateBlock::GetDefaultRenderStateBlock()->SetRenderStates(renderParams);\n        }\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMaterialDX11::ReadShaderSamplersAndTextures( ID3DBlob *pBlob, CPUTShaderParameters *pShaderParameter )\n{\n    // ***************************\n    // Use shader reflection to get texture and sampler names.  We use them later to bind .mtl texture-specification to shader parameters/variables.\n    // TODO: Currently do this only for PS.  Do for other shader types too.\n    // TODO: Generalize, so easy to call for different shader types\n    // ***************************\n    ID3D11ShaderReflection *pReflector = NULL; \n    D3D11_SHADER_INPUT_BIND_DESC desc;\n\n    D3DReflect( pBlob->GetBufferPointer(), pBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pReflector);\n    // Walk through the shader input bind descriptors.  Find the samplers and textures.\n    int ii=0;\n\tHRESULT hr = pReflector->GetResourceBindingDesc( ii++, &desc );\n\twhile( SUCCEEDED(hr) )\n\t{\n        switch( desc.Type )\n        {\n        case D3D_SIT_TEXTURE:\n            pShaderParameter->mTextureParameterCount++;\n            break;\n        case D3D_SIT_SAMPLER:\n            pShaderParameter->mSamplerParameterCount++;\n            break;\n        case D3D_SIT_CBUFFER:\n            pShaderParameter->mConstantBufferParameterCount++;\n            break;\n\n        case D3D_SIT_TBUFFER:\n        case D3D_SIT_STRUCTURED:\n        case D3D_SIT_BYTEADDRESS:\n            pShaderParameter->mBufferParameterCount++;\n            break;\n\n        case D3D_SIT_UAV_RWTYPED:\n        case D3D_SIT_UAV_RWSTRUCTURED:\n        case D3D_SIT_UAV_RWBYTEADDRESS:\n        case D3D_SIT_UAV_APPEND_STRUCTURED:\n        case D3D_SIT_UAV_CONSUME_STRUCTURED:\n        case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:\n            pShaderParameter->mUAVParameterCount++;\n            break;\n        }\n        hr = pReflector->GetResourceBindingDesc( ii++, &desc );\n    }\n\n    pShaderParameter->mpTextureParameterName              = new cString[pShaderParameter->mTextureParameterCount];\n    pShaderParameter->mpTextureParameterBindPoint         = new UINT[   pShaderParameter->mTextureParameterCount];\n    pShaderParameter->mpSamplerParameterName              = new cString[pShaderParameter->mSamplerParameterCount];\n    pShaderParameter->mpSamplerParameterBindPoint         = new UINT[   pShaderParameter->mSamplerParameterCount];\n    pShaderParameter->mpBufferParameterName               = new cString[pShaderParameter->mBufferParameterCount];\n    pShaderParameter->mpBufferParameterBindPoint          = new UINT[   pShaderParameter->mBufferParameterCount];\n    pShaderParameter->mpUAVParameterName                  = new cString[pShaderParameter->mUAVParameterCount];\n    pShaderParameter->mpUAVParameterBindPoint             = new UINT[   pShaderParameter->mUAVParameterCount];\n    pShaderParameter->mpConstantBufferParameterName       = new cString[pShaderParameter->mConstantBufferParameterCount];\n    pShaderParameter->mpConstantBufferParameterBindPoint  = new UINT[   pShaderParameter->mConstantBufferParameterCount];\n        \n    // Start over.  This time, copy the names.\n    ii=0;\n    UINT textureIndex = 0;\n    UINT samplerIndex = 0;\n    UINT bufferIndex = 0;\n    UINT uavIndex = 0;\n    UINT constantBufferIndex = 0;\n    hr = pReflector->GetResourceBindingDesc( ii++, &desc );\n\n    while( SUCCEEDED(hr) )\n    {\n        switch( desc.Type )\n        {\n        case D3D_SIT_TEXTURE:\n            pShaderParameter->mpTextureParameterName[textureIndex] = s2ws(desc.Name);\n            pShaderParameter->mpTextureParameterBindPoint[textureIndex] = desc.BindPoint;\n            textureIndex++;\n            break;\n        case D3D_SIT_SAMPLER:\n            pShaderParameter->mpSamplerParameterName[samplerIndex] = s2ws(desc.Name);\n            pShaderParameter->mpSamplerParameterBindPoint[samplerIndex] = desc.BindPoint;\n            samplerIndex++;\n            break;\n        case D3D_SIT_CBUFFER:\n            pShaderParameter->mpConstantBufferParameterName[constantBufferIndex] = s2ws(desc.Name);\n            pShaderParameter->mpConstantBufferParameterBindPoint[constantBufferIndex] = desc.BindPoint;\n            constantBufferIndex++;\n            break;\n        case D3D_SIT_TBUFFER:\n        case D3D_SIT_STRUCTURED:\n        case D3D_SIT_BYTEADDRESS:\n            pShaderParameter->mpBufferParameterName[bufferIndex] = s2ws(desc.Name);\n            pShaderParameter->mpBufferParameterBindPoint[bufferIndex] = desc.BindPoint;\n            bufferIndex++;\n            break;\n        case D3D_SIT_UAV_RWTYPED:\n        case D3D_SIT_UAV_RWSTRUCTURED:\n        case D3D_SIT_UAV_RWBYTEADDRESS:\n        case D3D_SIT_UAV_APPEND_STRUCTURED:\n        case D3D_SIT_UAV_CONSUME_STRUCTURED:\n        case D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER:\n            pShaderParameter->mpUAVParameterName[uavIndex] = s2ws(desc.Name);\n            pShaderParameter->mpUAVParameterBindPoint[uavIndex] = desc.BindPoint;\n            uavIndex++;\n            break;\n        }\n        hr = pReflector->GetResourceBindingDesc( ii++, &desc );\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMaterialDX11::BindTextures( CPUTShaderParameters &params, const cString &modelSuffix, const cString &meshSuffix )\n{\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n\n    for(params.mTextureCount=0; params.mTextureCount < params.mTextureParameterCount; params.mTextureCount++)\n    {\n        cString textureName;\n        UINT textureCount = params.mTextureCount;\n        cString tagName = params.mpTextureParameterName[textureCount];\n        CPUTConfigEntry *pValue = mConfigBlock.GetValueByName(tagName);\n        if( !pValue->IsValid() )\n        {\n            // We didn't find our property in the file.  Is it in the global config block?\n            pValue = mGlobalProperties.GetValueByName(tagName);\n        }\n        ASSERT( pValue->IsValid(), L\"Can't find texture '\" + tagName + L\"'.\" ); //  TODO: fix message\n        textureName = pValue->ValueAsString();\n        // If the texture name not specified.  Load default.dds instead\n        if( 0 == textureName.length() ) { textureName = _L(\"default.dds\"); }\n\n        UINT bindPoint = params.mpTextureParameterBindPoint[textureCount]; \n        ASSERT( bindPoint < CPUT_MATERIAL_MAX_TEXTURE_SLOTS, _L(\"Texture bind point out of range.\") );\n\n        params.mBindViewMin = min( params.mBindViewMin, bindPoint );\n        params.mBindViewMax = max( params.mBindViewMax, bindPoint );\n\n        if( textureName[0] == '@' )\n        {\n            // This is a per-mesh value.  Add to per-mesh list.\n            textureName += modelSuffix + meshSuffix;\n        } else if( textureName[0] == '#' )\n        {\n            // This is a per-mesh value.  Add to per-mesh list.\n            textureName += modelSuffix;\n        }\n\n        // Get the sRGB flag (default to true)\n        cString SRGBName = tagName+_L(\"sRGB\");\n        CPUTConfigEntry *pSRGBValue = mConfigBlock.GetValueByName(SRGBName);\n        bool loadAsSRGB = pSRGBValue->IsValid() ?  loadAsSRGB = pSRGBValue->ValueAsBool() : true;\n\n        if( !params.mpTexture[textureCount] )\n        {\n            params.mpTexture[textureCount] = pAssetLibrary->GetTexture( textureName, false, loadAsSRGB );\n            ASSERT( params.mpTexture[textureCount], _L(\"Failed getting texture \") + textureName);\n        }\n\n        // The shader file (e.g. .fx) can specify the texture bind point (e.g., t0).  Those specifications \n        // might not be contiguous, and there might be gaps (bind points without assigned textures)\n        // TODO: Warn about missing bind points?\n        params.mppBindViews[bindPoint] = ((CPUTTextureDX11*)params.mpTexture[textureCount])->GetShaderResourceView();\n        params.mppBindViews[bindPoint]->AddRef();\n\n        OUTPUT_BINDING_DEBUG_INFO( (itoc(bindPoint) + _L(\" : \") + params.mpTexture[textureCount]->GetName() + _L(\"\\n\")).c_str() );\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMaterialDX11::BindBuffers( CPUTShaderParameters &params, const cString &modelSuffix, const cString &meshSuffix )\n{\n    CPUTConfigEntry *pValue;\n    if( !params.mBufferParameterCount ) { return; }\n    OUTPUT_BINDING_DEBUG_INFO( _L(\"Bound Buffers\") );\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    for(params.mBufferCount=0; params.mBufferCount < params.mBufferParameterCount; params.mBufferCount++)\n    {\n        cString bufferName;\n        UINT bufferCount = params.mBufferCount;\n        cString tagName = params.mpBufferParameterName[bufferCount];\n        {\n            pValue = mConfigBlock.GetValueByName(tagName);\n            if( !pValue->IsValid() )\n            {\n                // We didn't find our property in the file.  Is it in the global config block?\n                pValue = mGlobalProperties.GetValueByName(tagName);\n            }\n            ASSERT( pValue->IsValid(), L\"Can't find buffer '\" + tagName + L\"'.\" ); //  TODO: fix message\n            bufferName = pValue->ValueAsString();\n        }\n        UINT bindPoint = params.mpBufferParameterBindPoint[bufferCount]; \n        ASSERT( bindPoint < CPUT_MATERIAL_MAX_BUFFER_SLOTS, _L(\"Buffer bind point out of range.\") );\n\n        params.mBindViewMin = min( params.mBindViewMin, bindPoint );\n        params.mBindViewMax = max( params.mBindViewMax, bindPoint );\n\n        if( bufferName[0] == '@' )\n        {\n            // This is a per-mesh value.  Add to per-mesh list.\n            bufferName += modelSuffix + meshSuffix;\n        } else if( bufferName[0] == '#' )\n        {\n            // This is a per-mesh value.  Add to per-model list.\n            bufferName += modelSuffix;\n        }\n        if( !params.mpBuffer[bufferCount] )\n        {\n            params.mpBuffer[bufferCount] = pAssetLibrary->GetBuffer( bufferName );\n            ASSERT( params.mpBuffer[bufferCount], _L(\"Failed getting buffer \") + bufferName);\n        }\n\n        params.mppBindViews[bindPoint]   = ((CPUTBufferDX11*)params.mpBuffer[bufferCount])->GetShaderResourceView();\n        if( params.mppBindViews[bindPoint] )  { params.mppBindViews[bindPoint]->AddRef();}\n\n        OUTPUT_BINDING_DEBUG_INFO( (itoc(bindPoint) + _L(\" : \") + params.mpBuffer[bufferCount]->GetName() + _L(\"\\n\")).c_str() );\n    }\n    OUTPUT_BINDING_DEBUG_INFO( _L(\"\\n\") );\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMaterialDX11::BindUAVs( CPUTShaderParameters &params, const cString &modelSuffix, const cString &meshSuffix )\n{\n    CPUTConfigEntry *pValue;\n    if( !params.mUAVParameterCount ) { return; }\n    OUTPUT_BINDING_DEBUG_INFO( _L(\"Bound UAVs\") );\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    memset( params.mppBindUAVs, 0, sizeof(params.mppBindUAVs) );\n    for(params.mUAVCount=0; params.mUAVCount < params.mUAVParameterCount; params.mUAVCount++)\n    {\n        cString uavName;\n        UINT uavCount = params.mUAVCount;\n\n        cString tagName = params.mpUAVParameterName[uavCount];\n        {\n            pValue = mConfigBlock.GetValueByName(tagName);\n            if( !pValue->IsValid() )\n            {\n                // We didn't find our property in the file.  Is it in the global config block?\n                pValue = mGlobalProperties.GetValueByName(tagName);\n            }\n            ASSERT( pValue->IsValid(), L\"Can't find UAV '\" + tagName + L\"'.\" ); //  TODO: fix message\n            uavName = pValue->ValueAsString();\n        }\n        UINT bindPoint = params.mpUAVParameterBindPoint[uavCount];\n        ASSERT( bindPoint < CPUT_MATERIAL_MAX_UAV_SLOTS, _L(\"UAV bind point out of range.\") );\n\n        params.mBindUAVMin = min( params.mBindUAVMin, bindPoint );\n        params.mBindUAVMax = max( params.mBindUAVMax, bindPoint );\n\n        if( uavName[0] == '@' )\n        {\n            // This is a per-mesh value.  Add to per-mesh list.\n            uavName += modelSuffix + meshSuffix;\n        } else if( uavName[0] == '#' )\n        {\n            // This is a per-mesh value.  Add to per-model list.\n            uavName += modelSuffix;\n        }\n        if( !params.mpUAV[uavCount] )\n        {\n            params.mpUAV[uavCount] = pAssetLibrary->GetBuffer( uavName );\n            ASSERT( params.mpUAV[uavCount], _L(\"Failed getting UAV \") + uavName);\n        }\n\n        // If has UAV, then add to mppBindUAV\n        params.mppBindUAVs[bindPoint]   = ((CPUTBufferDX11*)params.mpUAV[uavCount])->GetUnorderedAccessView();\n        if( params.mppBindUAVs[bindPoint] )  { params.mppBindUAVs[bindPoint]->AddRef();}\n\n        OUTPUT_BINDING_DEBUG_INFO( (itoc(bindPoint) + _L(\" : \") + params.mpUAV[uavCount]->GetName() + _L(\"\\n\")).c_str() );\n    }\n    OUTPUT_BINDING_DEBUG_INFO( _L(\"\\n\") );\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMaterialDX11::BindConstantBuffers( CPUTShaderParameters &params, const cString &modelSuffix, const cString &meshSuffix )\n{\n    CPUTConfigEntry *pValue;\n    if( !params.mConstantBufferParameterCount ) { return; }\n    OUTPUT_BINDING_DEBUG_INFO( _L(\"Bound Constant Buffers\\n\") );\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    for(params.mConstantBufferCount=0; params.mConstantBufferCount < params.mConstantBufferParameterCount; params.mConstantBufferCount++)\n    {\n        cString constantBufferName;\n        UINT constantBufferCount = params.mConstantBufferCount;\n\n        cString tagName = params.mpConstantBufferParameterName[constantBufferCount];\n        {\n            pValue = mConfigBlock.GetValueByName(tagName);\n            if( !pValue->IsValid() )\n            {\n                // We didn't find our property in the file.  Is it in the global config block?\n                pValue = mGlobalProperties.GetValueByName(tagName);\n            }\n            ASSERT( pValue->IsValid(), L\"Can't find constant buffer '\" + tagName + L\"'.\" ); //  TODO: fix message\n            constantBufferName = pValue->ValueAsString();\n        }\n        UINT bindPoint = params.mpConstantBufferParameterBindPoint[constantBufferCount];\n        ASSERT( bindPoint < CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS, _L(\"Constant buffer bind point out of range.\") );\n\n        params.mBindConstantBufferMin = min( params.mBindConstantBufferMin, bindPoint );\n        params.mBindConstantBufferMax = max( params.mBindConstantBufferMax, bindPoint );\n\n        if( constantBufferName[0] == '@' )\n        {\n            constantBufferName += modelSuffix + meshSuffix;\n        } else if( constantBufferName[0] == '#' )\n        {\n            constantBufferName += modelSuffix;\n        }\n        if( !params.mpConstantBuffer[constantBufferCount] )\n        {\n            params.mpConstantBuffer[constantBufferCount] = pAssetLibrary->GetConstantBuffer( constantBufferName );\n            ASSERT( params.mpConstantBuffer[constantBufferCount], _L(\"Failed getting constant buffer \") + constantBufferName);\n        }\n\n        // If has constant buffer, then add to mppBindConstantBuffer\n        params.mppBindConstantBuffers[bindPoint]   = ((CPUTBufferDX11*)params.mpConstantBuffer[constantBufferCount])->GetNativeBuffer();\n        if( params.mppBindConstantBuffers[bindPoint] )  { params.mppBindConstantBuffers[bindPoint]->AddRef();}\n\n        OUTPUT_BINDING_DEBUG_INFO( (itoc(bindPoint) + _L(\" : \") + params.mpConstantBuffer[constantBufferCount]->GetName() + _L(\"\\n\")).c_str() );\n    }\n    OUTPUT_BINDING_DEBUG_INFO( _L(\"\\n\") );\n}\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTMaterialDX11::LoadMaterial(const cString &fileName, const cString &modelSuffix, const cString &meshSuffix)\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    mMaterialName = fileName;\n\n    // Open/parse the file\n    CPUTConfigFile file;\n    result = file.LoadFile(fileName);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n    // Make a local copy of all the parameters\n\tCPUTConfigBlock *pBlock = file.GetBlock(0);\n    ASSERT( pBlock, _L(\"Error getting parameter block\") );\n    mConfigBlock = *pBlock;\n\n    // get necessary device and AssetLibrary pointers\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n\n    // TODO:  The following code is very repetitive.  Consider generalizing so we can call a function instead.\n    // see if there are any pixel/vertex/geo shaders to load\n    CPUTConfigEntry *pValue, *pEntryPointName, *pProfileName;\n    pValue   = mConfigBlock.GetValueByName(_L(\"VertexShaderFile\"));\n    if( pValue->IsValid() )\n    {\n        pEntryPointName = mConfigBlock.GetValueByName(_L(\"VertexShaderMain\"));\n        pProfileName    = mConfigBlock.GetValueByName(_L(\"VertexShaderProfile\"));\n        pAssetLibrary->GetVertexShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpVertexShader );\n        ReadShaderSamplersAndTextures( mpVertexShader->GetBlob(), &mVertexShaderParameters );\n    }\n\n    // load and store the pixel shader if it was specified\n    pValue  = mConfigBlock.GetValueByName(_L(\"PixelShaderFile\"));\n    if( pValue->IsValid() )\n    {\n        pEntryPointName = mConfigBlock.GetValueByName(_L(\"PixelShaderMain\"));\n        pProfileName    = mConfigBlock.GetValueByName(_L(\"PixelShaderProfile\"));\n        pAssetLibrary->GetPixelShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpPixelShader);\n        ReadShaderSamplersAndTextures( mpPixelShader->GetBlob(), &mPixelShaderParameters );\n    }\n\n    // load and store the compute shader if it was specified\n    pValue = mConfigBlock.GetValueByName(_L(\"ComputeShaderFile\"));\n    if( pValue->IsValid() )\n    {\n        pEntryPointName = mConfigBlock.GetValueByName(_L(\"ComputeShaderMain\"));\n        pProfileName = mConfigBlock.GetValueByName(_L(\"ComputeShaderProfile\"));\n        pAssetLibrary->GetComputeShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpComputeShader);\n        ReadShaderSamplersAndTextures( mpComputeShader->GetBlob(), &mComputeShaderParameters );\n    }\n\n    // load and store the geometry shader if it was specified\n    pValue = mConfigBlock.GetValueByName(_L(\"GeometryShaderFile\"));\n    if( pValue->IsValid() )\n    {\n        pEntryPointName = mConfigBlock.GetValueByName(_L(\"GeometryShaderMain\"));\n        pProfileName = mConfigBlock.GetValueByName(_L(\"GeometryShaderProfile\"));\n        pAssetLibrary->GetGeometryShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpGeometryShader);\n        ReadShaderSamplersAndTextures( mpGeometryShader->GetBlob(), &mGeometryShaderParameters );\n    }\n\n    // load and store the hull shader if it was specified\n    pValue = mConfigBlock.GetValueByName(_L(\"HullShaderFile\"));\n    if( pValue->IsValid() )\n    {\n        pEntryPointName = mConfigBlock.GetValueByName(_L(\"HullShaderMain\"));\n        pProfileName = mConfigBlock.GetValueByName(_L(\"HullShaderProfile\"));\n        pAssetLibrary->GetHullShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpHullShader);\n        ReadShaderSamplersAndTextures( mpHullShader->GetBlob(), &mHullShaderParameters );\n    }\n\n    // load and store the domain shader if it was specified\n    pValue = mConfigBlock.GetValueByName(_L(\"DomainShaderFile\"));\n    if( pValue->IsValid() )\n    {\n        pEntryPointName = mConfigBlock.GetValueByName(_L(\"DomainShaderMain\"));\n        pProfileName = mConfigBlock.GetValueByName(_L(\"DomainShaderProfile\"));\n        pAssetLibrary->GetDomainShader(pValue->ValueAsString(), pD3dDevice, pEntryPointName->ValueAsString(), pProfileName->ValueAsString(), &mpDomainShader);\n        ReadShaderSamplersAndTextures( mpDomainShader->GetBlob(), &mDomainShaderParameters );\n    }\n\n    // load and store the render state file if it was specified\n    pValue = mConfigBlock.GetValueByName(_L(\"RenderStateFile\"));\n    if( pValue->IsValid() )\n    {\n        mpRenderStateBlock = pAssetLibrary->GetRenderStateBlock(pValue->ValueAsString());\n    }\n\n\n    OUTPUT_BINDING_DEBUG_INFO( (_L(\"Bindings for : \") + mMaterialName + _L(\"\\n\")).c_str() );\n    cString pShaderTypeNameList[] = {\n        _L(\"Pixel shader\"),\n        _L(\"Compute shader\"),\n        _L(\"Vertex shader\"),\n        _L(\"Geometry shader\"),\n        _L(\"Hull shader\"),\n        _L(\"Domain shader\"),\n    };\n    cString *pShaderTypeName = pShaderTypeNameList;\n\n    void *pShaderList[] = {\n        mpPixelShader,\n        mpComputeShader,\n        mpVertexShader,\n        mpGeometryShader,\n        mpHullShader,\n        mpDomainShader\n    };\n    void **pShader = pShaderList;\n\n    // For each of the shader stages, bind shaders and buffers\n    for( CPUTShaderParameters **pCur = mpShaderParametersList; *pCur; pCur++ ) // Bind textures and buffersfor each shader stage\n    {\n        if( !*pShader++ )\n        {\n            pShaderTypeName++; // Increment the name pointer to remain coherent.\n            continue;          // This shader not bound.  Don't waste time binding to it.\n        }\n\n        OUTPUT_BINDING_DEBUG_INFO( (*(pShaderTypeName++)  + _L(\"\\n\")).c_str() );\n\n        BindTextures(        **pCur, modelSuffix, meshSuffix );\n        BindBuffers(         **pCur, modelSuffix, meshSuffix );\n        BindUAVs(            **pCur, modelSuffix, meshSuffix );\n        BindConstantBuffers( **pCur, modelSuffix, meshSuffix );\n\n        OUTPUT_BINDING_DEBUG_INFO( _L(\"\\n\") );\n    }\n\n    return result;\n}\n\n//-----------------------------------------------------------------------------\nCPUTMaterial *CPUTMaterialDX11::CloneMaterial(const cString &fileName, const cString &modelSuffix, const cString &meshSuffix)\n{\n    CPUTMaterialDX11 *pMaterial = new CPUTMaterialDX11();\n\n    // TODO: move texture to base class.  All APIs have textures.\n    pMaterial->mpPixelShader    = mpPixelShader;    if(mpPixelShader)    mpPixelShader->AddRef();   \n    pMaterial->mpComputeShader  = mpComputeShader;  if(mpComputeShader)  mpComputeShader->AddRef();\n    pMaterial->mpVertexShader   = mpVertexShader;   if(mpVertexShader)   mpVertexShader->AddRef();\n    pMaterial->mpGeometryShader = mpGeometryShader; if(mpGeometryShader) mpGeometryShader->AddRef();\n    pMaterial->mpHullShader     = mpHullShader;     if(mpHullShader)     mpHullShader->AddRef();\n    pMaterial->mpDomainShader   = mpDomainShader;   if(mpDomainShader)   mpDomainShader->AddRef();\n\n    mPixelShaderParameters.CloneShaderParameters(    &pMaterial->mPixelShaderParameters );\n    mComputeShaderParameters.CloneShaderParameters(  &pMaterial->mComputeShaderParameters );\n    mVertexShaderParameters.CloneShaderParameters(   &pMaterial->mVertexShaderParameters );\n    mGeometryShaderParameters.CloneShaderParameters( &pMaterial->mGeometryShaderParameters );\n    mHullShaderParameters.CloneShaderParameters(     &pMaterial->mHullShaderParameters );\n    mDomainShaderParameters.CloneShaderParameters(   &pMaterial->mDomainShaderParameters );\n\n    pMaterial->mpShaderParametersList[0] =  &pMaterial->mPixelShaderParameters,\n    pMaterial->mpShaderParametersList[1] =  &pMaterial->mComputeShaderParameters,\n    pMaterial->mpShaderParametersList[2] =  &pMaterial->mVertexShaderParameters,\n    pMaterial->mpShaderParametersList[3] =  &pMaterial->mGeometryShaderParameters,\n    pMaterial->mpShaderParametersList[4] =  &pMaterial->mHullShaderParameters,\n    pMaterial->mpShaderParametersList[5] =  &pMaterial->mDomainShaderParameters,\n    pMaterial->mpShaderParametersList[6] =  NULL;\n\n    pMaterial->mpRenderStateBlock = mpRenderStateBlock; if( mpRenderStateBlock ) mpRenderStateBlock->AddRef();\n\n    pMaterial->mMaterialName      = mMaterialName;\n    pMaterial->mConfigBlock       = mConfigBlock;\n\n    // For each of the shader stages, bind shaders and buffers\n    for( CPUTShaderParameters **pCur = pMaterial->mpShaderParametersList; *pCur; pCur++ ) // Bind textures and buffersfor each shader stage\n    {\n        pMaterial->BindTextures(        **pCur, modelSuffix, meshSuffix );\n        pMaterial->BindBuffers(         **pCur, modelSuffix, meshSuffix );\n        pMaterial->BindUAVs(            **pCur, modelSuffix, meshSuffix );\n        pMaterial->BindConstantBuffers( **pCur, modelSuffix, meshSuffix );\n    }\n    return pMaterial;\n}\n\n//-----------------------------------------------------------------------------\nbool CPUTMaterialDX11::MaterialRequiresPerModelPayload()\n{\n    return \n        (mpPixelShader    && mpPixelShader   ->ShaderRequiresPerModelPayload(mConfigBlock))  ||\n        (mpComputeShader  && mpComputeShader ->ShaderRequiresPerModelPayload(mConfigBlock))  ||\n        (mpVertexShader   && mpVertexShader  ->ShaderRequiresPerModelPayload(mConfigBlock))  ||\n        (mpGeometryShader && mpGeometryShader->ShaderRequiresPerModelPayload(mConfigBlock))  ||\n        (mpHullShader     && mpHullShader    ->ShaderRequiresPerModelPayload(mConfigBlock))  ||\n        (mpDomainShader   && mpDomainShader  ->ShaderRequiresPerModelPayload(mConfigBlock));\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMaterialDX11::RebindTexturesAndBuffers()\n{\n    for( CPUTShaderParameters **pCur = mpShaderParametersList; *pCur; pCur++ ) // Rebind textures for each shader stage\n    {\n        for( UINT ii=0; ii<(*pCur)->mTextureCount; ii++ )\n        {\n            if( (*pCur)->mpTexture[ii] )\n            {\n                UINT bindPoint = (*pCur)->mpTextureParameterBindPoint[ii];\n                SAFE_RELEASE((*pCur)->mppBindViews[bindPoint]);\n                (*pCur)->mppBindViews[bindPoint] = ((CPUTTextureDX11*)(*pCur)->mpTexture[ii])->GetShaderResourceView();\n                (*pCur)->mppBindViews[bindPoint]->AddRef();\n            }\n        }\n        for( UINT ii=0; ii<(*pCur)->mBufferCount; ii++ )\n        {\n            if( (*pCur)->mpBuffer[ii] )\n            {\n                UINT bindPoint = (*pCur)->mpBufferParameterBindPoint[ii];\n                SAFE_RELEASE((*pCur)->mppBindViews[bindPoint]);\n                (*pCur)->mppBindViews[bindPoint] = ((CPUTBufferDX11*)(*pCur)->mpBuffer[ii])->GetShaderResourceView();\n                (*pCur)->mppBindViews[bindPoint]->AddRef();\n            }\n        }\n        for( UINT ii=0; ii<(*pCur)->mUAVCount; ii++ )\n        {\n            if( (*pCur)->mpUAV[ii] )\n            {\n                UINT bindPoint = (*pCur)->mpUAVParameterBindPoint[ii];\n                SAFE_RELEASE((*pCur)->mppBindUAVs[bindPoint]);\n                (*pCur)->mppBindUAVs[bindPoint] = ((CPUTBufferDX11*)(*pCur)->mpUAV[ii])->GetUnorderedAccessView();\n\t\t\t    (*pCur)->mppBindUAVs[bindPoint]->AddRef();\n            }\n        }\n        for( UINT ii=0; ii<(*pCur)->mConstantBufferCount; ii++ )\n        {\n            if( (*pCur)->mpConstantBuffer[ii] )\n            {\n                UINT bindPoint = (*pCur)->mpConstantBufferParameterBindPoint[ii];\n                SAFE_RELEASE((*pCur)->mppBindConstantBuffers[bindPoint]);\n                (*pCur)->mppBindConstantBuffers[bindPoint] = ((CPUTBufferDX11*)(*pCur)->mpConstantBuffer[ii])->GetNativeBuffer();\n                (*pCur)->mppBindConstantBuffers[bindPoint]->AddRef();\n            }\n        }\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMaterialDX11::ReleaseTexturesAndBuffers()\n{\n    for( CPUTShaderParameters **pCur = mpShaderParametersList; *pCur; pCur++ ) // Release the buffers and views for each shader stage\n    {\n        if( *pCur )\n        {\n            for( UINT ii=0; ii<CPUT_MATERIAL_MAX_TEXTURE_SLOTS; ii++ )\n            {\n                SAFE_RELEASE((*pCur)->mppBindViews[ii]);\n            }\n            for( UINT ii=0; ii<CPUT_MATERIAL_MAX_UAV_SLOTS; ii++ )\n            {\n                SAFE_RELEASE((*pCur)->mppBindUAVs[ii]);\n            }\n            for( UINT ii=0; ii<CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS; ii++ )\n            {\n                SAFE_RELEASE((*pCur)->mppBindConstantBuffers[ii]);\n            }\n        }\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTShaderParameters::CloneShaderParameters( CPUTShaderParameters *pShaderParameter )\n{\n    pShaderParameter->mpTextureParameterName              = new cString[mTextureParameterCount];\n    pShaderParameter->mpTextureParameterBindPoint         = new UINT[   mTextureParameterCount];\n    pShaderParameter->mpSamplerParameterName              = new cString[mSamplerParameterCount];\n    pShaderParameter->mpSamplerParameterBindPoint         = new UINT[   mSamplerParameterCount];\n    pShaderParameter->mpBufferParameterName               = new cString[mBufferParameterCount];\n    pShaderParameter->mpBufferParameterBindPoint          = new UINT[   mBufferParameterCount];\n    pShaderParameter->mpUAVParameterName                  = new cString[mUAVParameterCount];\n    pShaderParameter->mpUAVParameterBindPoint             = new UINT[   mUAVParameterCount];\n    pShaderParameter->mpConstantBufferParameterName       = new cString[mConstantBufferParameterCount];\n    pShaderParameter->mpConstantBufferParameterBindPoint  = new UINT[   mConstantBufferParameterCount];\n\n    pShaderParameter->mTextureCount                 = mTextureCount;\n    pShaderParameter->mBufferCount                  = mBufferCount;\n    pShaderParameter->mUAVCount                     = mUAVCount;\n    pShaderParameter->mConstantBufferCount          = mConstantBufferCount;\n\n    pShaderParameter->mTextureParameterCount        = mTextureParameterCount;\n    pShaderParameter->mTextureParameterCount        = mTextureParameterCount;\n    pShaderParameter->mBufferParameterCount         = mBufferParameterCount;\n    pShaderParameter->mUAVParameterCount            = mUAVParameterCount;\n    pShaderParameter->mConstantBufferParameterCount = mConstantBufferParameterCount;\n\n    for(UINT ii=0; ii<mTextureParameterCount; ii++ )\n    {\n        pShaderParameter->mpTextureParameterName[ii]      = mpTextureParameterName[ii];\n        pShaderParameter->mpTextureParameterBindPoint[ii] = mpTextureParameterBindPoint[ii];\n    }\n    for(UINT ii=0; ii<mSamplerParameterCount; ii++ )\n    {\n        pShaderParameter->mpSamplerParameterName[ii]      = mpSamplerParameterName[ii];\n        pShaderParameter->mpSamplerParameterBindPoint[ii] = mpSamplerParameterBindPoint[ii];\n    }\n    for(UINT ii=0; ii<mBufferParameterCount; ii++ )\n    {\n        pShaderParameter->mpBufferParameterName[ii]      = mpBufferParameterName[ii];\n        pShaderParameter->mpBufferParameterBindPoint[ii] = mpBufferParameterBindPoint[ii];\n    }\n    for(UINT ii=0; ii<mUAVParameterCount; ii++ )\n    {\n        pShaderParameter->mpUAVParameterName[ii]      = mpUAVParameterName[ii];\n        pShaderParameter->mpUAVParameterBindPoint[ii] = mpUAVParameterBindPoint[ii];\n    }\n    for(UINT ii=0; ii<mConstantBufferParameterCount; ii++ )\n    {\n        pShaderParameter->mpConstantBufferParameterName[ii]      = mpConstantBufferParameterName[ii];\n        pShaderParameter->mpConstantBufferParameterBindPoint[ii] = mpConstantBufferParameterBindPoint[ii];\n    }\n    pShaderParameter->mBindViewMin = mBindViewMin;\n    pShaderParameter->mBindViewMax = mBindViewMax;\n\n    pShaderParameter->mBindUAVMin = mBindUAVMin;\n    pShaderParameter->mBindUAVMax = mBindUAVMax;\n\n    pShaderParameter->mBindConstantBufferMin = mBindConstantBufferMin;\n    pShaderParameter->mBindConstantBufferMax = mBindConstantBufferMax;\n}"
  },
  {
    "path": "CPUT/CPUT/CPUTMaterialDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTMATERIALDX11_H__\n#define __CPUTMATERIALDX11_H__\n\n#include <d3d11.h>\n\n#include \"CPUTMaterial.h\"\nclass CPUTPixelShaderDX11;\nclass CPUTComputeShaderDX11;\nclass CPUTVertexShaderDX11;\nclass CPUTGeometryShaderDX11;\nclass CPUTHullShaderDX11;\nclass CPUTDomainShaderDX11;\n\nclass CPUTShaderParameters\n{\npublic:\n    UINT                       mTextureCount;\n    cString                   *mpTextureParameterName;\n    UINT                      *mpTextureParameterBindPoint;\n    UINT                       mTextureParameterCount;\n    CPUTTexture               *mpTexture[CPUT_MATERIAL_MAX_TEXTURE_SLOTS];\n    CPUTBuffer                *mpBuffer[CPUT_MATERIAL_MAX_BUFFER_SLOTS];\n    CPUTBuffer                *mpUAV[CPUT_MATERIAL_MAX_UAV_SLOTS];\n    CPUTBuffer                *mpConstantBuffer[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n\n    cString                   *mpSamplerParameterName;\n    UINT                      *mpSamplerParameterBindPoint;\n    UINT                       mSamplerParameterCount;\n\n    UINT                       mBufferCount;\n    UINT                       mBufferParameterCount;\n    cString                   *mpBufferParameterName;\n    UINT                      *mpBufferParameterBindPoint;\n\n    UINT                       mUAVCount;\n    UINT                       mUAVParameterCount;\n    cString                   *mpUAVParameterName;\n    UINT                      *mpUAVParameterBindPoint;\n\n    UINT                       mConstantBufferCount;\n    UINT                       mConstantBufferParameterCount;\n    cString                   *mpConstantBufferParameterName;\n    UINT                      *mpConstantBufferParameterBindPoint;\n\n    UINT                       mBindViewMin;\n    UINT                       mBindViewMax;\n\n    UINT                       mBindUAVMin;\n    UINT                       mBindUAVMax;\n\n    UINT                       mBindConstantBufferMin;\n    UINT                       mBindConstantBufferMax;\n\n    ID3D11ShaderResourceView  *mppBindViews[CPUT_MATERIAL_MAX_SRV_SLOTS];\n    ID3D11UnorderedAccessView *mppBindUAVs[CPUT_MATERIAL_MAX_UAV_SLOTS];\n    ID3D11Buffer              *mppBindConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n\n    CPUTShaderParameters() :\n        mTextureCount(0),\n        mTextureParameterCount(0),\n        mpTextureParameterName(NULL),\n        mpTextureParameterBindPoint(NULL),\n        mSamplerParameterCount(0),\n        mpSamplerParameterName(NULL),\n        mpSamplerParameterBindPoint(NULL),\n        mBufferCount(0),\n        mBufferParameterCount(0),\n        mpBufferParameterName(NULL),\n        mpBufferParameterBindPoint(NULL),\n        mUAVCount(0),\n        mUAVParameterCount(0),\n        mpUAVParameterName(NULL),\n        mpUAVParameterBindPoint(NULL),\n        mConstantBufferCount(0),\n        mConstantBufferParameterCount(0),\n        mpConstantBufferParameterName(NULL),\n        mpConstantBufferParameterBindPoint(NULL),\n        mBindViewMin(CPUT_MATERIAL_MAX_SRV_SLOTS),\n        mBindViewMax(0),\n        mBindUAVMin(CPUT_MATERIAL_MAX_UAV_SLOTS),\n        mBindUAVMax(0),\n        mBindConstantBufferMin(CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS),\n        mBindConstantBufferMax(0)\n    {\n        // initialize texture slot list to null\n        for(int ii=0; ii<CPUT_MATERIAL_MAX_TEXTURE_SLOTS; ii++)\n        {\n            mppBindViews[ii] = NULL;\n            mpTexture[ii] = NULL;\n        }\n        for(int ii=0; ii<CPUT_MATERIAL_MAX_BUFFER_SLOTS; ii++)\n        {\n            mpBuffer[ii] = NULL;\n        }\n        for(int ii=0; ii<CPUT_MATERIAL_MAX_UAV_SLOTS; ii++)\n        {\n            mppBindUAVs[ii] = NULL;\n            mpUAV[ii] = NULL;\n        }\n        for(int ii=0; ii<CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS; ii++)\n        {\n            mppBindConstantBuffers[ii] = NULL;\n            mpConstantBuffer[ii] = NULL;\n        }\n    };\n    ~CPUTShaderParameters();\n    void CloneShaderParameters( CPUTShaderParameters *pShaderParameter );\n};\n\nstatic const int CPUT_NUM_SHADER_PARAMETER_LISTS = 7;\nclass CPUTMaterialDX11 : public CPUTMaterial\n{\nprotected:\n    static void *mpLastVertexShader;\n    static void *mpLastPixelShader;\n    static void *mpLastComputeShader;\n    static void *mpLastGeometryShader;\n    static void *mpLastHullShader;\n    static void *mpLastDomainShader;\n\n    static void *mpLastVertexShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS];\n    static void *mpLastPixelShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS];\n    static void *mpLastComputeShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS];\n    static void *mpLastGeometryShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS];\n    static void *mpLastHullShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS];\n    static void *mpLastDomainShaderViews[CPUT_MATERIAL_MAX_TEXTURE_SLOTS];\n\n    static void *mpLastVertexShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n    static void *mpLastPixelShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n    static void *mpLastComputeShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n    static void *mpLastGeometryShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n    static void *mpLastHullShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n    static void *mpLastDomainShaderConstantBuffers[CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS];\n\n    static void *mpLastComputeShaderUAVs[CPUT_MATERIAL_MAX_UAV_SLOTS];\n\n    static void *mpLastRenderStateBlock;\n\n    // Each material references materials.  A multiple-submaterial material leaves these as NULL.\n    CPUTPixelShaderDX11    *mpPixelShader;\n    CPUTComputeShaderDX11  *mpComputeShader; // TODO: Do Compute Shaders belong in material?\n    CPUTVertexShaderDX11   *mpVertexShader;\n    CPUTGeometryShaderDX11 *mpGeometryShader;\n    CPUTHullShaderDX11     *mpHullShader;\n    CPUTDomainShaderDX11   *mpDomainShader;\n\npublic:\n    CPUTShaderParameters    mPixelShaderParameters;\n    CPUTShaderParameters    mComputeShaderParameters;\n    CPUTShaderParameters    mVertexShaderParameters;\n    CPUTShaderParameters    mGeometryShaderParameters;\n    CPUTShaderParameters    mHullShaderParameters;\n    CPUTShaderParameters    mDomainShaderParameters;\n    CPUTShaderParameters   *mpShaderParametersList[CPUT_NUM_SHADER_PARAMETER_LISTS]; // Constructor initializes this as a list of pointers to the above shader parameters.\n\nprotected:\n\n    ~CPUTMaterialDX11();  // Destructor is not public.  Must release instead of delete.\n\n    void ReadShaderSamplersAndTextures(   ID3DBlob *pBlob, CPUTShaderParameters *pShaderParameter );\n\n    void BindTextures(        CPUTShaderParameters &params, const cString &modelSuffix, const cString &meshSuffix );\n    void BindBuffers(         CPUTShaderParameters &params, const cString &modelSuffix, const cString &meshSuffix );\n    void BindUAVs(            CPUTShaderParameters &params, const cString &modelSuffix, const cString &meshSuffix );\n    void BindConstantBuffers( CPUTShaderParameters &params, const cString &modelSuffix, const cString &meshSuffix );\n\npublic:\n    CPUTMaterialDX11();\n\n    CPUTResult    LoadMaterial(const cString &fileName, const cString &modelSuffix, const cString &meshSuffix);\n    void          ReleaseTexturesAndBuffers();\n    void          RebindTexturesAndBuffers();\n    CPUTVertexShaderDX11   *GetVertexShader()   { return mpVertexShader; }\n    CPUTPixelShaderDX11    *GetPixelShader()    { return mpPixelShader; }\n    CPUTGeometryShaderDX11 *GetGeometryShader() { return mpGeometryShader; }\n    CPUTComputeShaderDX11  *GetComputeShader()  { return mpComputeShader; }\n    CPUTDomainShaderDX11   *GetDomainShader()   { return mpDomainShader; }\n    CPUTHullShaderDX11     *GetHullShader()     { return mpHullShader; }\n\n    // Tells material to set the current render state to match the properties, textures,\n    //  shaders, state, etc that this material represents\n    void SetRenderStates( CPUTRenderParameters &renderParams );\n    bool MaterialRequiresPerModelPayload();\n    CPUTMaterial *CloneMaterial( const cString &absolutePathAndFilename, const cString &modelSuffix, const cString &meshSuffix );\n    static void ResetStateTracking()\n    {\n        mpLastVertexShader = (void*)-1;\n        mpLastPixelShader = (void*)-1;\n        mpLastComputeShader = (void*)-1;\n        mpLastGeometryShader = (void*)-1;\n        mpLastHullShader = (void*)-1;\n        mpLastDomainShader = (void*)-1;\n        mpLastRenderStateBlock = (void*)-1;\n        for(UINT ii=0; ii<CPUT_MATERIAL_MAX_TEXTURE_SLOTS; ii++ )\n        {\n            mpLastVertexShaderViews[ii] = (void*)-1;\n            mpLastPixelShaderViews[ii] = (void*)-1;\n            mpLastComputeShaderViews[ii] = (void*)-1;\n            mpLastGeometryShaderViews[ii] = (void*)-1;\n            mpLastHullShaderViews[ii] = (void*)-1;\n            mpLastDomainShaderViews[ii] = (void*)-1;\n        }\n        for(UINT ii=0; ii<CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS; ii++ )\n        {\n            mpLastVertexShaderConstantBuffers[ii]   = (void*)-1;\n            mpLastPixelShaderConstantBuffers[ii]    = (void*)-1;\n            mpLastComputeShaderConstantBuffers[ii]  = (void*)-1;\n            mpLastGeometryShaderConstantBuffers[ii] = (void*)-1;\n            mpLastHullShaderConstantBuffers[ii]     = (void*)-1;\n            mpLastDomainShaderConstantBuffers[ii]   = (void*)-1;\n        }\n        for(UINT ii=0; ii<CPUT_MATERIAL_MAX_UAV_SLOTS; ii++ )\n        {\n            mpLastComputeShaderUAVs[ii] = (void*)-1;\n        }\n    }\n\n};\n\n#endif // #ifndef __CPUTMATERIALDX11_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTMath.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#ifndef __CPUTMath_h__\n#define __CPUTMath_h__\n#include <math.h>\n\n/*\n * Constants\n */\nstatic const float kEpsilon  = 0.00001f;\nstatic const float kPi       = 3.14159265358979323846f;\nstatic const float k2Pi      = kPi*2.0f;\nstatic const float kPiDiv2   = kPi/2.0f;\nstatic const float kInvPi    = 1.0f/kPi;\nstatic const float kDegToRad = (kPi/180.0f);\nstatic const float kRadToDeg = (180.0f/kPi);\nstatic inline float DegToRad( float fDeg ) { return fDeg * kDegToRad; }\nstatic inline float RadToDeg( float fRad ) { return fRad * kRadToDeg; }\n\ntemplate<typename T>\nstatic inline void Swap(T &a, T &b)\n{\n    T t = b;\n    b = a;\n    a = t;\n}\nstruct float2;\nstruct float3;\nstruct float4;\n\n/**************************************\\\nfloat2\n\\**************************************/\nstruct float2\n{\n    union\n    {\n        struct\n        {\n            float x;\n            float y;\n        };\n        float f[2];\n    };\n\n    /***************************************\\\n    |   Constructors                        |\n    \\***************************************/\n    float2() {}\n    explicit float2(float f) : x(f), y(f) { }\n    explicit float2(float _x, float _y) : x(_x), y(_y) { }\n    explicit float2(float* f) : x(f[0]), y(f[1]) { }\n    float2(const float2 &v) : x(v.x), y(v.y) { }\n    const float2 &operator=(const float2 &v)\n    {\n        x = v.x;\n        y = v.y;        \n        return *this;\n    }\n\n    /***************************************\\\n    |   Basic math operations               |\n    \\***************************************/\n    float2 operator+(const float2 &r) const\n    {\n        return float2(x+r.x, y+r.y);\n    }\n    const float2 &operator+=(const float2 &r)\n    {\n        x += r.x;\n        y += r.y;\n        return *this;\n    }\n    float2 operator-(const float2 &r) const\n    {\n        return float2(x-r.x, y-r.y);\n    }\n    const float2 &operator-=(const float2 &r)\n    {\n        x -= r.x;\n        y -= r.y;\n        return *this;\n    }\n    /***************************************\\\n    |   Basic math operations with scalars  |\n    \\***************************************/\n    float2 operator+(float f) const\n    {\n        return float2(x+f, y+f);\n    }\n    const float2 &operator+=(float f)\n    {\n        x += f;\n        y += f;\n        return *this;\n    }\n    float2 operator-(float f) const\n    {\n        return float2(x-f, y-f);\n    }\n    const float2 &operator-=(float f)\n    {\n        x -= f;\n        y -= f;\n        return *this;\n    }\n    float2 operator*(float f) const\n    {\n        return float2(x*f, y*f);\n    }\n    const float2 &operator*=(float f)\n    {\n        x *= f;\n        y *= f;\n        return *this;\n    }\n    float2 operator/(float f) const\n    {\n        return float2(x/f, y/f);\n    }\n    const float2 &operator/=(float f)\n    {\n        x /= f;\n        y /= f;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Other math                          |\n    \\***************************************/\n    // Equality\n    bool operator==(const float2 &r) const\n    {\n        return (x==r.x && y == r.y);\n    }\n    bool operator!=(const float2 &r) const\n    {\n        return !(*this == r);\n    }\n\n    // Hadd\n    float hadd(void) const\n    {\n        return x + y;\n    }\n\n    // Length\n    float lengthSq(void) const\n    {\n        return x*x + y*y;\n    }\n    float length(void) const\n    {\n        return sqrtf(lengthSq());\n    }\n    void normalize(void)\n    {\n        *this /= length();\n    }\n};\n\ninline float dot2(const float2 &l, const float2 &r)\n{\n    return l.x*r.x + l.y*r.y;\n}\n\ninline float2 normalize(const float2 &v)\n{\n    float length = v.length();\n    return v / length;\n}\n\n\n\n\n\n\n\n\n/**************************************\\\nfloat3\n\\**************************************/\nstruct float3\n{\n    union\n    {\n        struct\n        {\n            float x;\n            float y;\n            float z;\n        };\n        float f[3];\n    };\n\n    /***************************************\\\n    |   Constructors                        |\n    \\***************************************/\n    float3() {}\n    explicit float3(float f) : x(f), y(f), z(f) { }\n    explicit float3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) { }\n    explicit float3(float* f) : x(f[0]), y(f[1]), z(f[2]) { }\n    float3(const float3 &v) : x(v.x), y(v.y), z(v.z) { }\n    float3(const float4 &v);\n    const float3 &operator=(const float3 &v)\n    {\n        x = v.x;\n        y = v.y;\n        z = v.z;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Basic math operations               |\n    \\***************************************/\n    float3 operator+(const float3 &r) const\n    {\n        return float3(x+r.x, y+r.y, z+r.z);\n    }\n    const float3 &operator+=(const float3 &r)\n    {\n        x += r.x;\n        y += r.y;\n        z += r.z;\n        return *this;\n    }\n    float3 operator-(const float3 &r) const\n    {\n        return float3(x-r.x, y-r.y, z-r.z);\n    }\n    const float3 &operator-=(const float3 &r)\n    {\n        x -= r.x;\n        y -= r.y;\n        z -= r.z;\n        return *this;\n    }\n    float3 operator*(const float3 &r) const\n    {\n        return float3(x*r.x, y*r.y, z*r.z);\n    }\n    const float3 &operator*=(const float3 &r)\n    {\n        x *= r.x;\n        y *= r.y;\n        z *= r.z;\n        return *this;\n    }\n    float3 operator/(const float3 &r) const\n    {\n        return float3(x/r.x, y/r.y, z/r.z);\n    }\n    const float3 &operator/=(const float3 &r)\n    {\n        x /= r.x;\n        y /= r.y;\n        z /= r.z;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Basic math operations with scalars  |\n    \\***************************************/\n    float3 operator+(float f) const\n    {\n        return float3(x+f, y+f, z+f);\n    }\n    const float3 &operator+=(float f)\n    {\n        x += f;\n        y += f;\n        z += f;\n        return *this;\n    }\n    float3 operator-(float f) const\n    {\n        return float3(x-f, y-f, z-f);\n    }\n    const float3 &operator-=(float f)\n    {\n        x -= f;\n        y -= f;\n        z -= f;\n        return *this;\n    }\n    float3 operator*(float f) const\n    {\n        return float3(x*f, y*f, z*f);\n    }\n    const float3 &operator*=(float f)\n    {\n        x *= f;\n        y *= f;\n        z *= f;\n        return *this;\n    }\n    float3 operator/(float f) const\n    {\n        return float3(x/f, y/f, z/f);\n    }\n    const float3 &operator/=(float f)\n    {\n        x /= f;\n        y /= f;\n        z /= f;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Other math                          |\n    \\***************************************/\n    // Equality\n    bool operator==(const float3 &r) const\n    {\n        return x==r.x &&y == r.y &&z == r.z;\n    }\n    bool operator!=(const float3 &r) const\n    {\n        return !(*this == r);\n    }\n\n    // Hadd\n    float hadd(void) const\n    {\n        return x + y + z;\n    }\n\n    // Length\n    float lengthSq(void) const\n    {\n        return x*x + y*y + z*z;\n    }\n    float length(void) const\n    {\n        return sqrtf(lengthSq());\n    }\n    float3 normalize(void)\n    {\n        return (*this /= length());\n    }\n};\n\ninline float dot3(const float3 &l, const float3 &r)\n{\n    return l.x*r.x + l.y*r.y + l.z*r.z;\n}\ninline float3 cross3(const float3 &l, const float3 &r)\n{\n    return float3(  l.y*r.z-l.z*r.y,\n                    l.z*r.x-l.x*r.z,\n                    l.x*r.y-l.y*r.x);\n}\ninline float3 normalize(const float3 &v)\n{\n    float length = v.length();\n    return v / length;\n}\n\n\n/**************************************\\\nfloat4\n\\**************************************/\n__declspec(align(16)) struct float4\n{\n    union\n    {\n        struct\n        {\n            float x;\n            float y;\n            float z;\n            float w;\n        };\n        float f[4];\n    };\n\n    /***************************************\\\n    |   Constructors                        |\n    \\***************************************/\n    float4() {}\n    explicit float4(float f) : x(f), y(f), z(f), w(f) { }\n    explicit float4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) { }\n    explicit float4(float* f) : x(f[0]), y(f[1]), z(f[2]), w(f[3]) { }\n    float4(const float4 &v) : x(v.x), y(v.y), z(v.z), w(v.w) { }\n    float4(const float3 &v, float _w) : x(v.x), y(v.y), z(v.z), w(_w) { }\n    const float4 &operator=(const float4 &v)\n    {\n        x = v.x;\n        y = v.y;\n        z = v.z;\n        w = v.w;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Basic math operations               |\n    \\***************************************/\n    float4 operator+(const float4 &r) const\n    {\n        return float4(x+r.x, y+r.y, z+r.z, w+r.w);\n    }\n    const float4 &operator+=(const float4 &r)\n    {\n        x += r.x;\n        y += r.y;\n        z += r.z;\n        w += r.w;\n        return *this;\n    }\n    float4 operator-(const float4 &r) const\n    {\n        return float4(x-r.x, y-r.y, z-r.z, w-r.w);\n    }\n    const float4 &operator-=(const float4 &r)\n    {\n        x -= r.x;\n        y -= r.y;\n        z -= r.z;\n        w -= r.w;\n        return *this;\n    }\n    float4 operator*(const float4 &r) const\n    {\n        return float4(x*r.x, y*r.y, z*r.z, w*r.w);\n    }\n    const float4 &operator*=(const float4 &r)\n    {\n        x *= r.x;\n        y *= r.y;\n        z *= r.z;\n        w *= r.w;\n        return *this;\n    }\n    float4 operator/(const float4 &r) const\n    {\n        return float4(x/r.x, y/r.y, z/r.z, w/r.w);\n    }\n    const float4 &operator/=(const float4 &r)\n    {\n        x /= r.x;\n        y /= r.y;\n        z /= r.z;\n        w /= r.w;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Basic math operations with scalars  |\n    \\***************************************/\n    float4 operator+(float f) const\n    {\n        return float4(x+f, y+f, z+f, w+f);\n    }\n    const float4 &operator+=(float f)\n    {\n        x += f;\n        y += f;\n        z += f;\n        return *this;\n    }\n    float4 operator-(float f) const\n    {\n        return float4(x-f, y-f, z-f, w-f);\n    }\n    const float4 &operator-=(float f)\n    {\n        x -= f;\n        y -= f;\n        z -= f;\n        w -= f;\n        return *this;\n    }\n    float4 operator*(float f) const\n    {\n        return float4(x*f, y*f, z*f, w*f);\n    }\n    const float4 &operator*=(float f)\n    {\n        x *= f;\n        y *= f;\n        z *= f;\n        w *= f;\n        return *this;\n    }\n    float4 operator/(float f) const\n    {\n        return float4(x/f, y/f, z/f, w/f);\n    }\n    const float4 &operator/=(float f)\n    {\n        x /= f;\n        y /= f;\n        z /= f;\n        w /= f;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Other math                          |\n    \\***************************************/\n    // Equality\n    bool operator==(const float4 &r) const\n    {\n        return x==r.x && y == r.y && z == r.z && w == r.w;\n    }\n    bool operator!=(const float4 &r) const\n    {\n        return !(*this == r);\n    }\n\n    // Hadd\n    float hadd(void) const\n    {\n        return x + y + z + w;\n    }\n\n    // Length\n    float lengthSq(void) const\n    {\n        return x*x + y*y + z*z + w*w;\n    }\n    float length(void) const\n    {\n        return sqrtf(lengthSq());\n    }\n    void normalize(void)\n    {\n        *this /= length();\n    }\n};\n\ninline float dot4(const float4 &l, const float4 &r)\n{\n    return l.x*r.x + l.y*r.y + l.z*r.z + l.w*r.w;\n}\ninline float4 normalize(const float4 &v)\n{\n    float length = v.length();\n    return v / length;\n}\n\ninline float3::float3(const float4 &v) : x(v.x), y(v.y), z(v.z) { }\n\n\n/**************************************\\\nfloat3x3\n\\**************************************/\nstruct float4x4;\nstruct float3x3\n{\n    struct\n    {\n        float3 r0;\n        float3 r1;\n        float3 r2;\n    };\n\n    /***************************************\\\n    |   Constructors                        |\n    \\***************************************/\n    float3x3() {}\n    explicit float3x3(float f) : r0(f), r1(f), r2(f) { }\n    explicit float3x3(float* f) : r0(f+0), r1(f+3), r2(f+6) { }\n    float3x3(const float3 &_r0, const float3 &_r1, const float3 &_r2) : r0(_r0), r1(_r1), r2(_r2) { }\n    float3x3(float _m00, float _m01, float _m02,\n             float _m10, float _m11, float _m12,\n             float _m20, float _m21, float _m22)\n             : r0(_m00,_m01,_m02)\n             , r1(_m10,_m11,_m12)\n             , r2(_m20,_m21,_m22)\n    {\n    }\n    float3x3(const float4x4 &m);\n    const float3x3 &operator=(const float3x3 &m)\n    {\n        r0 = m.r0;\n        r1 = m.r1;\n        r2 = m.r2;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Basic math operations               |\n    \\***************************************/\n\n    #define MTX3_INDEX(f,r,c) ((f)[(r*3)+c])\n    inline float3x3 operator*(const float3x3 &r) const\n    {\n        float3x3 m(1,0,0,0,1,0,0,0,1);\n\n        const float* left     = (const float*)&this->r0;\n        const float* right    = (const float*)&r.r0;\n        float* result   = (float*)&m;\n\n        int ii, jj, kk;\n        for(ii=0; ii<3; ++ii) /* row */\n        {\n            for(jj=0; jj<3; ++jj) /* column */\n            {\n                float sum = MTX3_INDEX(left,ii,0)*MTX3_INDEX(right,0,jj);\n                for(kk=1; kk<3; ++kk)\n                {\n                    sum += (MTX3_INDEX(left,ii,kk)*MTX3_INDEX(right,kk,jj));\n                }\n                MTX3_INDEX(result,ii,jj) = sum;\n            }\n        }\n        return m;\n    }\n    #undef MTX3_INDEX\n\n    inline float3 operator*(const float3 &v) const\n    {\n        float3 a;\n\n        a.x = (r0*v).hadd();\n        a.y = (r1*v).hadd();\n        a.z = (r2*v).hadd();\n\n        return a;\n    }\n\n    /***************************************\\\n    |   Basic math operations with scalars  |\n    \\***************************************/\n    float3x3 operator+(float f) const\n    {\n        return float3x3(r0+f, r1+f, r2+f);\n    }\n    const float3x3 &operator+=(float f)\n    {\n        r0 += f;\n        r1 += f;\n        r2 += f;\n        return *this;\n    }\n    float3x3 operator-(float f) const\n    {\n        return float3x3(r0-f, r1-f, r2-f);\n    }\n    const float3x3 &operator-=(float f)\n    {\n        r0 -= f;\n        r1 -= f;\n        r2 -= f;\n        return *this;\n    }\n    float3x3 operator*(float f) const\n    {\n        return float3x3(r0*f, r1*f, r2*f);\n    }\n    const float3x3 &operator*=(float f)\n    {\n        r0 *= f;\n        r1 *= f;\n        r2 *= f;\n        return *this;\n    }\n    float3x3 operator/(float f) const\n    {\n        return float3x3(r0/f, r1/f, r2/f);\n    }\n    const float3x3 &operator/=(float f)\n    {\n        r0 /= f;\n        r1 /= f;\n        r2 /= f;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Other math                          |\n    \\***************************************/\n    // Equality\n    bool operator==(const float3x3 &r) const\n    {\n        return r0 == r.r0 && r1 == r.r1 && r2 == r.r2;\n    }\n    bool operator!=(const float3x3 &r) const\n    {\n        return !(*this == r);\n    }\n\n    float determinant() const\n    {\n        float f0 = r0.x *  (r1.y*r2.z-r2.y*r1.z);\n        float f1 = r0.y * -(r1.x*r2.z-r2.x*r1.z);\n        float f2 = r0.z *  (r1.x*r2.y-r2.x*r1.y);\n\n        return f0 + f1 + f2;\n    }\n\n    void transpose(void)\n    {\n        Swap(r0.y, r1.x);\n        Swap(r0.z, r2.x);\n        Swap(r1.z, r2.y);\n    }\n\n    void invert(void)\n    {\n        float det = determinant();\n        float3x3 inv;\n\n        inv.r0.x =   (r1.y*r2.z) - (r1.z*r2.y);\n        inv.r0.y = -((r1.x*r2.z) - (r1.z*r2.x));\n        inv.r0.z =   (r1.x*r2.y) - (r1.y*r2.x);\n\n        inv.r1.x = -((r0.y*r2.z) - (r0.z*r2.y));\n        inv.r1.y =   (r0.x*r2.z) - (r0.z*r2.x);\n        inv.r1.z = -((r0.x*r2.y) - (r0.y*r2.x));\n\n        inv.r2.x =   (r0.y*r1.z) - (r0.z*r1.y);\n        inv.r2.y = -((r0.x*r1.z) - (r0.z*r1.x));\n        inv.r2.z =   (r0.x*r1.y) - (r0.y*r1.x);\n\n        inv.transpose();\n        inv /= det;\n\n        *this = inv;\n    }\n};\ninline float3x3 float3x3Identity(void)\n{\n    return float3x3(1,0,0,\n                    0,1,0,\n                    0,0,1);\n}\ninline float determinant(const float3x3&m)\n{\n    return m.determinant();\n}\n\ninline float3x3 transpose(const float3x3 &m)\n{\n    float3x3 ret = m;\n    ret.transpose();\n    return ret;\n}\n\ninline float3x3 inverse(const float3x3 &m)\n{\n    float3x3 ret = m;\n    ret.invert();\n    return ret;\n}\n\ninline float3x3 float3x3RotationX(float rad)\n{\n    float       c = cosf( rad );\n    float       s = sinf( rad );\n    float3x3     m( 1.0f, 0.0f, 0.0f,\n                    0.0f,    c,    s,\n                    0.0f,   -s,    c );\n    return m;\n}\ninline float3x3 float3x3RotationY(float rad)\n{\n    float       c = cosf( rad );\n    float       s = sinf( rad );\n    float3x3     m(    c, 0.0f,   -s,\n                    0.0f, 1.0f, 0.0f,\n                       s, 0.0f,    c );\n    return m;\n}\ninline float3x3 float3x3RotationZ(float rad)\n{\n\n    float       c = cosf( rad );\n    float       s = sinf( rad );\n    float3x3     m(    c,    s, 0.0f,\n                      -s,    c, 0.0f,\n                    0.0f, 0.0f, 1.0f );\n    return m;\n}\n\ninline float3x3 float3x3RotationAxis(const float3 &axis, float rad )\n{\n    float3 normAxis = normalize(axis);\n    float c = cosf(rad);\n    float s = sinf(rad);\n    float t = 1 - c;\n\n    float x = normAxis.x;\n    float y = normAxis.y;\n    float z = normAxis.z;\n\n    float3x3 m;\n\n    m.r0.x = (t * x * x) + c;\n    m.r0.y = (t * x * y) + s * z;\n    m.r0.z = (t * x * z) - s * y;\n\n    m.r1.x = (t * x * y) - (s * z);\n    m.r1.y = (t * y * y) + c;\n    m.r1.z = (t * y * z) + (s * x);\n\n    m.r2.x = (t * x * z) + (s * y);\n    m.r2.y = (t * y * z) - (s * x);\n    m.r2.z = (t * z * z) + c;\n\n    return m;\n}\n\ninline float3x3 float3x3Scale(float x, float y, float z)\n{\n    return float3x3(x,0,0,\n                    0,y,0,\n                    0,0,z);\n}\n\n/**************************************\\\nfloat4x4\n\\**************************************/\nstruct float4x4\n{\n    struct\n    {\n        float4 r0;\n        float4 r1;\n        float4 r2;\n        float4 r3;\n    };\n\n    /***************************************\\\n    |   Constructors                        |\n    \\***************************************/\n    float4x4() {}\n    explicit float4x4(float f) : r0(f), r1(f), r2(f), r3(f) { }\n    explicit float4x4(float* f) : r0(f+0), r1(f+4), r2(f+8), r3(f+12) { }\n    float4x4(const float4 &_r0, const float4 &_r1, const float4 &_r2, const float4 &_r3) : r0(_r0), r1(_r1), r2(_r2), r3(_r3) { }\n    float4x4(float _m00, float _m01, float _m02, float _m03,\n             float _m10, float _m11, float _m12, float _m13,\n             float _m20, float _m21, float _m22, float _m23,\n             float _m30, float _m31, float _m32, float _m33)\n             : r0(_m00,_m01,_m02,_m03)\n             , r1(_m10,_m11,_m12,_m13)\n             , r2(_m20,_m21,_m22,_m23)\n             , r3(_m30,_m31,_m32,_m33)\n    {\n    }\n    float4x4(const float3x3 &m)\n        : r0(m.r0, 0.0f)\n        , r1(m.r1, 0.0f)\n        , r2(m.r2, 0.0f)\n        , r3(0.0f, 0.0f, 0.0f, 1.0f)\n    {\n    }\n    const float4x4 &operator=(const float4x4 &m)\n    {\n        r0 = m.r0;\n        r1 = m.r1;\n        r2 = m.r2;\n        r3 = m.r3;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Basic math operations               |\n    \\***************************************/\n\n    #define MTX4_INDEX(f,r,c) ((f)[(r*4)+c])\n    inline float4x4 operator*(const float4x4 &r) const\n    {\n        float4x4 m(1,0,0,0,\n                   0,1,0,0,\n                   0,0,1,0,\n                   0,0,0,1);\n\n        const float* left     = (const float*)&this->r0;\n        const float* right    = (const float*)&r.r0;\n        float* result   = (float*)&m;\n\n        int ii, jj, kk;\n        for(ii=0; ii<4; ++ii) /* row */\n        {\n            for(jj=0; jj<4; ++jj) /* column */\n            {\n                float sum = MTX4_INDEX(left,ii,0)*MTX4_INDEX(right,0,jj);\n                for(kk=1; kk<4; ++kk)\n                {\n                    sum += (MTX4_INDEX(left,ii,kk)*MTX4_INDEX(right,kk,jj));\n                }\n                MTX4_INDEX(result,ii,jj) = sum;\n            }\n        }\n        return m;\n    }\n    #undef MTX4_INDEX\n\n    inline float4 operator*(const float4 &v) const\n    {\n        float4 a;\n\n        a.x = (r0*v).hadd();\n        a.y = (r1*v).hadd();\n        a.z = (r2*v).hadd();\n        a.w = (r3*v).hadd();\n\n        return a;\n    }\n\n    /***************************************\\\n    |   Basic math operations with scalars  |\n    \\***************************************/\n    float4x4 operator+(float f) const\n    {\n        return float4x4(r0+f, r1+f, r2+f, r3+f);\n    }\n    const float4x4 &operator+=(float f)\n    {\n        r0 += f;\n        r1 += f;\n        r2 += f;\n        r3 += f;\n        return *this;\n    }\n    float4x4 operator-(float f) const\n    {\n        return float4x4(r0-f, r1-f, r2-f, r3-f);\n    }\n    const float4x4 &operator-=(float f)\n    {\n        r0 -= f;\n        r1 -= f;\n        r2 -= f;\n        r3 -= f;\n        return *this;\n    }\n    float4x4 operator*(float f) const\n    {\n        return float4x4(r0*f, r1*f, r2*f, r3*f);\n    }\n    const float4x4 &operator*=(float f)\n    {\n        r0 *= f;\n        r1 *= f;\n        r2 *= f;\n        r3 *= f;\n        return *this;\n    }\n    float4x4 operator/(float f) const\n    {\n        return float4x4(r0/f, r1/f, r2/f, r3/f);\n    }\n    const float4x4 &operator/=(float f)\n    {\n        r0 /= f;\n        r1 /= f;\n        r2 /= f;\n        r3 /= f;\n        return *this;\n    }\n\n    /***************************************\\\n    |   Other math                          |\n    \\***************************************/\n    // Equality\n    bool operator==(const float4x4 &r) const\n    {\n        return r0 == r.r0 && r1 == r.r1 && r2 == r.r2 && r3 == r.r3;\n    }\n    bool operator!=(const float4x4 &r) const\n    {\n        return !(*this == r);\n    }\n\n    float determinant() const\n    {\n        float det = 0.0f;\n\n        float3x3 a( r1.y,r1.z,r1.w,\n                    r2.y,r2.z,r2.w,\n                    r3.y,r3.z,r3.w);\n\n        float3x3 b( r1.x,r1.z,r1.w,\n                    r2.x,r2.z,r2.w,\n                    r3.x,r3.z,r3.w);\n\n        float3x3 c( r1.x,r1.y,r1.w,\n                    r2.x,r2.y,r2.w,\n                    r3.x,r3.y,r3.w);\n\n        float3x3 d( r1.x,r1.y,r1.z,\n                    r2.x,r2.y,r2.z,\n                    r3.x,r3.y,r3.z);\n\n\n        det += r0.x * a.determinant();\n\n        det -= r0.y * b.determinant();\n\n        det += r0.z * c.determinant();\n\n        det -= r0.w * d.determinant();\n\n        return det;\n    }\n\n    void transpose(void)\n    {\n        Swap(r0.y, r1.x);\n        Swap(r0.z, r2.x);\n        Swap(r0.w, r3.x);\n        Swap(r1.z, r2.y);\n        Swap(r1.w, r3.y);\n        Swap(r2.w, r3.z);\n    }\n\n    void invert(void)\n    {\n        float4x4 ret;\n        float recip;\n\n        /* temp matrices */\n\n        /* row 1 */\n        float3x3 a( r1.y,r1.z,r1.w,\n                    r2.y,r2.z,r2.w,\n                    r3.y,r3.z,r3.w);\n\n        float3x3 b( r1.x,r1.z,r1.w,\n                    r2.x,r2.z,r2.w,\n                    r3.x,r3.z,r3.w);\n\n        float3x3 c( r1.x,r1.y,r1.w,\n                    r2.x,r2.y,r2.w,\n                    r3.x,r3.y,r3.w);\n\n        float3x3 d( r1.x,r1.y,r1.z,\n                    r2.x,r2.y,r2.z,\n                    r3.x,r3.y,r3.z);\n\n        /* row 2 */\n        float3x3 e( r0.y,r0.z,r0.w,\n                    r2.y,r2.z,r2.w,\n                    r3.y,r3.z,r3.w);\n\n        float3x3 f( r0.x,r0.z,r0.w,\n                    r2.x,r2.z,r2.w,\n                    r3.x,r3.z,r3.w);\n\n        float3x3 g( r0.x,r0.y,r0.w,\n                    r2.x,r2.y,r2.w,\n                    r3.x,r3.y,r3.w);\n\n        float3x3 h( r0.x,r0.y,r0.z,\n                    r2.x,r2.y,r2.z,\n                    r3.x,r3.y,r3.z);\n\n\n        /* row 3 */\n        float3x3 i( r0.y,r0.z,r0.w,\n                    r1.y,r1.z,r1.w,\n                    r3.y,r3.z,r3.w);\n\n        float3x3 j( r0.x,r0.z,r0.w,\n                    r1.x,r1.z,r1.w,\n                    r3.x,r3.z,r3.w);\n\n        float3x3 k( r0.x,r0.y,r0.w,\n                    r1.x,r1.y,r1.w,\n                    r3.x,r3.y,r3.w);\n\n        float3x3 l( r0.x,r0.y,r0.z,\n                    r1.x,r1.y,r1.z,\n                    r3.x,r3.y,r3.z);\n\n\n        /* row 4 */\n        float3x3 m( r0.y, r0.z, r0.w,\n                    r1.y, r1.z, r1.w,\n                    r2.y, r2.z, r2.w);\n\n        float3x3 n( r0.x, r0.z, r0.w,\n                    r1.x, r1.z, r1.w,\n                    r2.x, r2.z, r2.w);\n\n        float3x3 o( r0.x,r0.y,r0.w,\n                    r1.x,r1.y,r1.w,\n                    r2.x,r2.y,r2.w);\n\n        float3x3 p( r0.x,r0.y,r0.z,\n                    r1.x,r1.y,r1.z,\n                    r2.x,r2.y,r2.z);\n\n        /* row 1 */\n        ret.r0.x = a.determinant();\n\n        ret.r0.y = -b.determinant();\n\n        ret.r0.z = c.determinant();\n\n        ret.r0.w = -d.determinant();\n\n        /* row 2 */\n        ret.r1.x = -e.determinant();\n\n        ret.r1.y = f.determinant();\n\n        ret.r1.z = -g.determinant();\n\n        ret.r1.w = h.determinant();\n\n        /* row 3 */\n        ret.r2.x = i.determinant();\n\n        ret.r2.y = -j.determinant();\n\n        ret.r2.z = k.determinant();\n\n        ret.r2.w = -l.determinant();\n\n        /* row 4 */\n        ret.r3.x = -m.determinant();\n\n        ret.r3.y = n.determinant();\n\n        ret.r3.z = -o.determinant();\n\n        ret.r3.w = p.determinant();\n\n        ret.transpose();\n        recip = 1.0f/determinant();\n        ret *= recip;\n\n        *this = ret;\n    }\n\n    // Axis access\n    float3 getXAxis(void) const\n    {\n        return r0;\n    }\n    float3 getYAxis(void) const\n    {\n        return r1;\n    }\n    float3 getZAxis(void) const\n    {\n        return r2;\n    }\n    float3 getPosition(void) const\n    {\n        return float3(r3);\n    }\n\n    void orthonormalize(void)\n    {\n        float3 x = getXAxis();\n        float3 y = getYAxis();\n        float3 z;\n\n        x.normalize();\n        z = normalize(cross3(x, y));\n        y = normalize(cross3(z, x));\n\n        r0 = float4(x, 0.0f);\n        r1 = float4(y, 0.0f);\n        r2 = float4(z, 0.0f);\n    }\n};\n\ninline float3x3::float3x3(const float4x4 &m)\n    : r0(m.r0)\n    , r1(m.r1)\n    , r2(m.r2)\n{\n}\ninline float determinant(const float4x4&m)\n{\n    return m.determinant();\n}\ninline float4x4 float4x4Identity(void)\n{\n    return float4x4(1,0,0,0,\n                    0,1,0,0,\n                    0,0,1,0,\n                    0,0,0,1);\n}\ninline float4x4 transpose(const float4x4 &m)\n{\n    float4x4 ret = m;\n    ret.transpose();\n    return ret;\n}\n\ninline float4x4 inverse(const float4x4 &m)\n{\n    float4x4 ret = m;\n    ret.invert();\n    return ret;\n}\n\ninline float4x4 float4x4RotationX(float rad)\n{\n    float       c = cosf( rad );\n    float       s = sinf( rad );\n    float4x4     m( 1.0f, 0.0f, 0.0f, 0.0f,\n                    0.0f,    c,    s, 0.0f,\n                    0.0f,   -s,    c, 0.0f,\n                    0.0f, 0.0f, 0.0f, 1.0f);\n    return m;\n}\ninline float4x4 float4x4RotationY(float rad)\n{\n    float       c = cosf( rad );\n    float       s = sinf( rad );\n    float4x4     m(    c, 0.0f,   -s, 0.0f,\n                    0.0f, 1.0f, 0.0f, 0.0f,\n                       s, 0.0f,    c, 0.0f,\n                    0.0f, 0.0f, 0.0f, 1.0f);\n    return m;\n}\ninline float4x4 float4x4RotationZ(float rad)\n{\n\n    float       c = cosf( rad );\n    float       s = sinf( rad );\n    float4x4     m(    c,    s, 0.0f, 0.0f,\n                      -s,    c, 0.0f, 0.0f,\n                    0.0f, 0.0f, 1.0f, 0.0f,\n                    0.0f, 0.0f, 0.0f, 1.0f);\n    return m;\n}\n\ninline float4x4 float4x4RotationAxis(const float3 &axis, float rad )\n{\n    float3 normAxis = normalize(axis);\n    float c = cosf(rad);\n    float s = sinf(rad);\n    float t = 1 - c;\n\n    float x = normAxis.x;\n    float y = normAxis.y;\n    float z = normAxis.z;\n\n    float4x4 m = float4x4Identity();\n\n    m.r0.x = (t * x * x) + c;\n    m.r0.y = (t * x * y) + s * z;\n    m.r0.z = (t * x * z) - s * y;\n\n    m.r1.x = (t * x * y) - (s * z);\n    m.r1.y = (t * y * y) + c;\n    m.r1.z = (t * y * z) + (s * x);\n\n    m.r2.x = (t * x * z) + (s * y);\n    m.r2.y = (t * y * z) - (s * x);\n    m.r2.z = (t * z * z) + c;\n\n    return m;\n}\n\ninline float4x4 float4x4Scale(float x, float y, float z)\n{\n    return float4x4(x,0,0,0,\n                    0,y,0,0,\n                    0,0,z,0,\n                    0,0,0,1);\n}\n\ninline float4x4 float4x4Translation(float x, float y, float z)\n{\n    float4x4 m = float4x4Identity();\n    m.r3.x = x;\n    m.r3.y = y;\n    m.r3.z = z;\n    return m;\n}\ninline float4x4 float4x4Translation(const float3 &v)\n{\n    return float4x4Translation(v.x, v.y, v.z);\n}\n\ninline float4x4 float4x4PerspectiveFovLH(float fov, float aspect, float nearPlane, float farPlane)\n{\n    float height = tanf(fov * 0.5f);\n    float width  = height * aspect;\n    float diff   = farPlane-nearPlane;\n    float div    = farPlane / diff;\n\n    float4x4 m(\n        1.0f/width,          0.0f,            0.0f,    0.0f,\n              0.0f,   1.0f/height,            0.0f,    0.0f,\n              0.0f,          0.0f,            div,     1.0f,\n              0.0f,          0.0f, -nearPlane*div,     0.0f\n    );\n    return m;\n}\ninline float4x4 float4x4PerspectiveFovRH(float fov, float aspect, float nearPlane, float farPlane)\n{\n    float4x4 m = float4x4Identity();\n\n    float f = tanf(kPiDiv2 - (fov/2.0f));\n    float diff = nearPlane-farPlane;\n    float div = farPlane / diff;\n\n    m.r0.x = f/aspect;\n    m.r1.y = f;\n    m.r2.z = div;\n    m.r2.w = -1;\n    m.r3.z = nearPlane * div;\n    m.r3.w = 0;\n    return m;\n}\ninline float4x4 float4x4PerspectiveLH(float width, float height, float nearPlane, float farPlane)\n{\n    float4x4 m = float4x4Identity();\n\n    m.r0.x = 2*nearPlane/width;\n    m.r1.y = 2*nearPlane/height;\n    m.r2.z = farPlane/(farPlane-nearPlane);\n    m.r2.w = 1;\n    m.r3.z = nearPlane*farPlane/(nearPlane-farPlane);\n    m.r3.w = 0;\n    return m;\n}\ninline float4x4 float4x4PerspectiveRH(float width, float height, float nearPlane, float farPlane)\n{\n    float4x4 m = float4x4Identity();\n\n    m.r0.x = 2*nearPlane/width;\n    m.r1.y = 2*nearPlane/height;\n    m.r2.z = farPlane/(nearPlane-farPlane);\n    m.r2.w = -1;\n    m.r3.z = nearPlane*farPlane/(nearPlane-farPlane);\n    m.r3.w = 0;\n    return m;\n}\ninline float4x4 float4x4OrthographicOffCenterLH(float left, float right, float top, float bottom, float nearPlane, float farPlane)\n{\n    float4x4 m = float4x4Identity();\n\n    float diff = farPlane-nearPlane;\n\n    m.r0.x = 2.0f/(right-left);\n    m.r1.y = 2.0f/(top-bottom);\n    m.r2.z = 1.0f/diff;\n    m.r3.x = -((left+right)/(right-left));\n    m.r3.y = -((top+bottom)/(top-bottom));\n    m.r3.z = -nearPlane/diff;\n\n    return m;\n}\ninline float4x4 float4x4OrthographicOffCenterRH(float left, float right, float top, float bottom, float nearPlane, float farPlane)\n{\n    float4x4 m = float4x4Identity();\n    float diff = nearPlane-farPlane;\n\n    m.r0.x = 2.0f/(right-left);\n    m.r1.y = 2.0f/(top-bottom);\n    m.r2.z = 1.0f/diff;\n    m.r3.x = -((left+right)/(right-left));\n    m.r3.y = -((top+bottom)/(top-bottom));\n    m.r3.z = nearPlane/diff;\n\n    return m;\n}\ninline float4x4 float4x4OrthographicLH(float width, float height, float nearPlane, float farPlane)\n{\n    float halfWidth = width/2.0f;\n    float halfHeight = height/2.0f;\n\n    return float4x4OrthographicOffCenterLH(-halfWidth, halfWidth, halfHeight, -halfHeight, nearPlane, farPlane);\n}\ninline float4x4 float4x4OrthographicRH(float width, float height, float nearPlane, float farPlane)\n{\n    float halfWidth = width/2.0f;\n    float halfHeight = height/2.0f;\n\n    return float4x4OrthographicOffCenterRH(-halfWidth, halfWidth, halfHeight, -halfHeight, nearPlane, farPlane);\n}\n\n/**************************************\\\nQuaternion\n\\**************************************/\nstruct quaternion : public float4\n{\n\n    /***************************************\\\n    |   Constructors                        |\n    \\***************************************/\n    quaternion() {}\n    explicit quaternion(float f) : float4(f) { }\n    explicit quaternion(float _x, float _y, float _z, float _w) : float4(_x,_y,_z,_w) { }\n    explicit quaternion(float* f) : float4(f) { }\n    quaternion(const quaternion &v) : float4(v) { }\n    quaternion(const float3 &v, float _w)\n    {\n        float3  norm = ::normalize(v);\n        float   a = _w*0.5f;\n        float   s = sinf(a);\n        x = norm.x*s;\n        y = norm.y*s;\n        z = norm.z*s;\n        w = cosf(a);\n    }\n    const quaternion &operator=(const quaternion &v)\n    {\n        x = v.x;\n        y = v.y;\n        z = v.z;\n        w = v.w;\n        return *this;\n    }\n\n    /* Methods */\n    float3 getXAxis(void) const\n    {\n        float3 ret( 1-2*(y*y+z*z),\n                      2*(x*y+w*z),\n                      2*(x*z-y*w));\n        return ret;\n    }\n    float3 getYAxis(void) const\n    {\n        float3 ret(   2*(x*y-z*w),\n                    1-2*(x*x+z*z),\n                      2*(y*z+x*w));\n        return ret;\n    }\n    float3 getZAxis(void) const\n    {\n        float3 ret(   2*(x*z+y*w),\n                      2*(y*z-x*w),\n                    1-2*(x*x+y*y));\n        return ret;\n    }\n\n    float3x3 getMatrix(void) const\n    {\n        quaternion q = *this;\n        q.normalize();\n        float xx = q.x * q.x;\n        float yy = q.y * q.y;\n        float zz = q.z * q.z;\n\n        float xy = q.x * q.y;\n        float zw = q.z * q.w;\n        float xz = q.x * q.z;\n        float yw = q.y * q.w;\n        float yz = q.y * q.z;\n        float xw = q.x * q.w;\n\n        float3x3 ret(1 - 2*(yy+zz),     2*(xy+zw),     2*(xz-yw),\n                         2*(xy-zw), 1 - 2*(xx+zz),     2*(yz+xw),\n                         2*(xz+yw),     2*(yz-xw), 1 - 2*(xx+yy) );\n        return ret;\n    }\n\n    quaternion conjugate(void) const\n    {\n        return quaternion(-x, -y, -z, w);\n    }\n    quaternion inverse(void) const\n    {\n        // Note: Only normalized quaternions are supportted at the moment\n        quaternion q = *this;\n        q.normalize();\n        return q.conjugate();\n    }\n};\n\ninline quaternion quaternionMultiply(const quaternion &l, const quaternion &r)\n{\n    quaternion q(   r.w*l.x + r.x*l.w + r.y*l.z - r.z*l.y,\n                    r.w*l.y + r.y*l.w + r.z*l.x - r.x*l.z,\n                    r.w*l.z + r.z*l.w + r.x*l.y - r.y*l.x,\n                    r.w*l.w - r.x*l.x - r.y*l.y - r.z*l.z );\n    return q;\n}\n\ninline quaternion quaternionIdentity(void)\n{\n    return quaternion(0.0f, 0.0f, 0.0f, 1.0f);\n}\n\ninline float3 Min( float3 &v0, float3 &v1 )\n{\n    float3 result;\n    result.x = v0.x < v1.x ? v0.x : v1.x;\n    result.y = v0.y < v1.y ? v0.y : v1.y;\n    result.z = v0.z < v1.z ? v0.z : v1.z;\n    return result;\n}\n\ninline float3 Max( float3 &v0, float3 &v1 )\n{\n    float3 result;\n    result.x = v0.x > v1.x ? v0.x : v1.x;\n    result.y = v0.y > v1.y ? v0.y : v1.y;\n    result.z = v0.z > v1.z ? v0.z : v1.z;\n    return result;\n}\n\ninline float4 Min( float4 &v0, float4 &v1 )\n{\n    float4 result;\n    result.x = v0.x < v1.x ? v0.x : v1.x;\n    result.y = v0.y < v1.y ? v0.y : v1.y;\n    result.z = v0.z < v1.z ? v0.z : v1.z;\n    result.w = v0.w < v1.w ? v0.w : v1.w;\n    return result;\n}\n\ninline float4 Max( float4 &v0, float4 &v1 )\n{\n    float4 result;\n    result.x = v0.x > v1.x ? v0.x : v1.x;\n    result.y = v0.y > v1.y ? v0.y : v1.y;\n    result.z = v0.z > v1.z ? v0.z : v1.z;\n    result.w = v0.w > v1.w ? v0.w : v1.w;\n    return result;\n}\n\ninline float4 operator*(const float4 &v, const float4x4 &m)\n{\n    float4 result;\n\n    result  = m.r0 * v.x;\n    result += m.r1 * v.y;\n    result += m.r2 * v.z;\n    result += m.r3 * v.w;\n\n    return result;\n}\n\n#endif // #ifndef __CPUTMath_h__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTMesh.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTMesh.h\"\n\n//-----------------------------------------------------------------------------\n// Note: The indices of these strings must match the corresponding value in enum CPUT_VERTEX_ELEMENT_SEMANTIC\nconst char *CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[] =\n{\n    \"UNDEFINED\",\n    \"UNDEFINED\", // Note 1 is missing (back compatibility)\n    \"POSITON\",\n    \"NORMAL\",\n    \"TEXTURECOORD\",\n    \"COLOR\",\n    \"TANGENT\",\n    \"BINORMAL\"\n};\n//-----------------------------------------------------------------------------\nvoid CPUTVertexElementDesc::Read(std::ifstream &meshFile)\n{\n    meshFile.read((char*)this, sizeof(*this));\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTRawMeshData::Allocate(__int32 numElements)\n{\n    mVertexCount = numElements;\n    mStride += mPaddingSize; // TODO: move this to stride computation\n    mTotalVerticesSizeInBytes = mVertexCount * mStride;\n    mpVertices = (void*)new char[(UINT)mTotalVerticesSizeInBytes];\n    ::memset( mpVertices, 0, (size_t)mTotalVerticesSizeInBytes );\n}\n\n//-----------------------------------------------------------------------------\nbool CPUTRawMeshData::Read(std::ifstream &modelFile)\n{\n    unsigned __int32 magicCookie;\n    modelFile.read((char*)&magicCookie,sizeof(magicCookie));\n    if( !modelFile.good() ) return false; // TODO: Yuck!  Why do we need to get here to figure out we're done?\n\n    ASSERT( magicCookie == 1234, _L(\"Invalid model file.\") );\n\n    modelFile.read((char*)&mStride,                   sizeof(mStride));\n    modelFile.read((char*)&mPaddingSize,              sizeof(mPaddingSize)); // DWM TODO: What is this?\n    modelFile.read((char*)&mTotalVerticesSizeInBytes, sizeof(mTotalVerticesSizeInBytes));\n    modelFile.read((char*)&mVertexCount,              sizeof(mVertexCount));\n    modelFile.read((char*)&mTopology,                 sizeof(mTopology));\n    modelFile.read((char*)&mBboxCenter,               sizeof(mBboxCenter));\n    modelFile.read((char*)&mBboxHalf,                 sizeof(mBboxHalf));\n\n    // read  format descriptors\n    modelFile.read((char*)&mFormatDescriptorCount, sizeof(mFormatDescriptorCount));\n    ASSERT( modelFile.good(), _L(\"Model file bad\" ) );\n\n    mpElements = new CPUTVertexElementDesc[mFormatDescriptorCount];\n    for( UINT ii=0; ii<mFormatDescriptorCount; ++ii )\n    {\n        mpElements[ii].Read(modelFile);\n    }\n    modelFile.read((char*)&mIndexCount, sizeof(mIndexCount));\n    modelFile.read((char*)&mIndexType, sizeof(mIndexType));\n    ASSERT( modelFile.good(), _L(\"Bad model file(1).\" ) );\n\n    mpIndices = new UINT[mIndexCount];\n    if( mIndexCount != 0 )\n    {\n        modelFile.read((char*)mpIndices, mIndexCount * sizeof(UINT));\n    }\n    modelFile.read((char*)&magicCookie, sizeof(magicCookie));\n    ASSERT( magicCookie == 1234, _L(\"Model file missing magic cookie.\") );\n    ASSERT( modelFile.good(),    _L(\"Bad model file(2).\") );\n\n    if ( 0 != mTotalVerticesSizeInBytes )\n    {\n        Allocate(mVertexCount);  // recalculates some things\n        modelFile.read((char*)(mpVertices), mTotalVerticesSizeInBytes);\n    }\n    modelFile.read((char*)&magicCookie, sizeof(magicCookie));\n    ASSERT( modelFile.good() && magicCookie == 1234, _L(\"Bad model file(3).\") );\n\n    return modelFile.good();\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTMesh.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTMESH_H__\n#define __CPUTMESH_H__\n\n#include \"CPUTRefCount.h\"\n#include <fstream>\n#include \"CPUT.h\"\n\nclass CPUTRenderParameters;\nclass CPUTMaterial;\nclass CPUTModel;\n\n//-----------------------------------------------------------------------------\nenum eCPUT_VERTEX_ELEMENT_SEMANTIC : UINT\n{\n    CPUT_VERTEX_ELEMENT_UNDEFINED    = 0,\n    // Note 1 is missing (back compatibility)\n    CPUT_VERTEX_ELEMENT_POSITON      = 2,\n    CPUT_VERTEX_ELEMENT_NORMAL       = 3,\n    CPUT_VERTEX_ELEMENT_TEXTURECOORD = 4,\n    CPUT_VERTEX_ELEMENT_VERTEXCOLOR  = 5,\n    CPUT_VERTEX_ELEMENT_TANGENT      = 6,\n    CPUT_VERTEX_ELEMENT_BINORMAL     = 7,\n};\n\nconst char *CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[];\n\n//------------------------------------------------------------------------------\n// These are hard coded, so you can add or deprecate, but not reuse them\n// If you change or add anything to this list, be sure to update the\n// CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT\n// struct below as well\nenum eCPUT_VERTEX_ELEMENT_TYPE : UINT\n{\n    tMINTYPE = 1,\n    tINT8,      // 2  int =  1 byte\n    tUINT8,     // 3 UINT, __int8 =  1 byte\n    tINT16,     // 4 __int16 = 2 bytes\n    tUINT16,    // 5 unsigned __int16  =  2 bytes\n    tINT32,     // 6 __int32 = 4 bytes\n    tUINT32,    // 7 unsigned __int32  =  4 bytes\n    tINT64,     // 8 __int64  = 8 bytes\n    tUINT64,    // 9 unsigned __int64 =  8 bytes\n    tBOOL,      // 10 bool  =  1 byte - '0' = false, '1' = true, same as stl bool i/o\n    tCHAR,      // 11 signed char  = 1 byte\n    tUCHAR,     // 12 unsigned char  = 1 byte\n    tWCHAR,     // 13 wchar_t  = 2 bytes\n    tFLOAT,     // 14 float  = 4 bytes\n    tDOUBLE,    // 15 double  = 8 bytes\n\n    // add new ones here\n    tINVALID = 255\n};\n\n//------------------------------------------------------------------------------\n// This map defines how the above eCPUT_VERTEX_ELEMENT_TYPE's map to internal\n// CPUT types.  Be sure to update them at the same time.\nconst CPUT_DATA_FORMAT_TYPE CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT[] =\n{\n    CPUT_UNKNOWN,   // 0\n    CPUT_UNKNOWN,   // 1\n    CPUT_I8,        // 2  int =  1 byte\n    CPUT_U8,        // 3 UINT, __int8 =  1 byte\n    CPUT_I16,       // 4 __int16 = 2 bytes\n    CPUT_U16,       // 5 unsigned __int16  =  2 bytes\n    CPUT_I32,       // 6 __int32 = 4 bytes\n    CPUT_U32,       // 7 unsigned __int32  =  4 bytes\n    CPUT_I64,       // 8 __int64  = 8 bytes\n    CPUT_U64,       // 9 unsigned __int64 =  8 bytes\n    CPUT_BOOL,      // 10 bool  =  1 byte - '0' = false, '1' = true, same as stl bool i/o\n    CPUT_CHAR,      // 11 signed char  = 1 byte\n    CPUT_U8,        // 12 unsigned char  = 1 byte\n    CPUT_U16,       // 13 wchar_t  = 2 bytes\n    CPUT_F32,       // 14 float  = 4 bytes\n    CPUT_DOUBLE,    // 15 double  = 8 bytes     \n};\n\n//-----------------------------------------------------------------------------\nenum eCPUT_MESH_TOPOLOGY : UINT\n{\n    CPUT_TOPOLOGY_POINT_LIST = 1,\n    CPUT_TOPOLOGY_INDEXED_LINE_LIST,\n    CPUT_TOPOLOGY_INDEXED_LINE_STRIP,\n    CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST,\n    CPUT_TOPOLOGY_INDEXED_TRIANGLE_STRIP,\n    CPUT_TOPOLOGY_INDEXED_TRIANGLE_FAN\n    // TODO: What about non-indexed variants\n};\n\n//-----------------------------------------------------------------------------\nstruct CPUTVertexElementDesc\n{\n    eCPUT_VERTEX_ELEMENT_SEMANTIC mVertexElementSemantic;     // what is is , position, UV's, etc.\n    eCPUT_VERTEX_ELEMENT_TYPE     mVertexElementType; // what is the data type, floats, ints, etc.\n    UINT                          mElementSizeInBytes;   // # bytes of this element\n    UINT                          mOffset;   // what is the offset within the vertex data\n\n    void Read(std::ifstream &meshFile);\n};\n\n//-----------------------------------------------------------------------------\nstruct CPUTRawMeshData\n{\n    UINT                       mStride; // how big a \"vertex\" is\n    UINT                       mVertexCount;\n    void                      *mpVertices;\n    UINT                       mIndexCount;\n    UINT                      *mpIndices; // TODO: what about 16-bit indices?  Use void*?\n    UINT                       mFormatDescriptorCount;\n    CPUTVertexElementDesc     *mpElements;\n    unsigned __int64           mTotalVerticesSizeInBytes;\n    eCPUT_MESH_TOPOLOGY        mTopology;\n    float3                     mBboxCenter;\n    float3                     mBboxHalf;\n    eCPUT_VERTEX_ELEMENT_TYPE  mIndexType;\n    UINT                       mPaddingSize;\n\n    CPUTRawMeshData():\n        mStride(0),\n        mVertexCount(0),\n        mpVertices(NULL),\n        mIndexCount(0),\n        mpIndices(NULL),\n        mFormatDescriptorCount(0),\n        mpElements(NULL),\n        mTotalVerticesSizeInBytes(0),\n        mTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST),\n        mBboxCenter(0.0f),\n        mIndexType(tUINT32),\n        mBboxHalf(0.0f),\n        mPaddingSize(0)\n    {\n    }\n    ~CPUTRawMeshData()\n    {\n        delete[] mpVertices;\n        delete[] mpElements;\n        delete[] mpIndices;\n    }\n    void Allocate(__int32 numElements);\n    bool Read(std::ifstream &mdlfile);\n};\n\n//-----------------------------------------------------------------------------\nstruct CPUTBufferInfo\n{\n    const char           *mpSemanticName;\n    int                   mSemanticIndex;\n    CPUT_DATA_FORMAT_TYPE mElementType;\n    int                   mElementComponentCount; // e.g., a float 3 has 3 components\n    UINT                  mElementSizeInBytes;\n    UINT                  mOffset;\n    int                   mElementCount;\n};\n\nstruct D3D11_MAPPED_SUBRESOURCE;\n//-----------------------------------------------------------------------------\nclass CPUTMesh : public CPUTRefCount\n{\nprotected:\n    eCPUT_MESH_TOPOLOGY mMeshTopology;\n\tUINT mInstanceCount;\n\npublic:\n    CPUTMesh() : mInstanceCount(1) {}\n    virtual ~CPUTMesh(){}\n    // TODO: ? Change from virtual to #ifdef-controlled redirect to platform versions?\n    // TODO: Use CPUT_MAPPED_SUBRESOURCE ??\n    virtual D3D11_MAPPED_SUBRESOURCE MapVertices(   CPUTRenderParameters &params, eCPUTMapType type, bool wait=true ) = 0;\n    virtual D3D11_MAPPED_SUBRESOURCE MapIndices(    CPUTRenderParameters &params, eCPUTMapType type, bool wait=true ) = 0;\n    virtual void                     UnmapVertices( CPUTRenderParameters &params ) = 0;\n    virtual void                     UnmapIndices(  CPUTRenderParameters &params ) = 0;\n\n    virtual void SetMeshTopology(const eCPUT_MESH_TOPOLOGY meshTopology) { mMeshTopology = meshTopology; }\n    virtual void BindVertexShaderLayout(CPUTMaterial *pMaterial, CPUTMaterial *pShadowCastMaterial) = 0;\n    virtual CPUTResult CreateNativeResources(\n        CPUTModel      *pModel,\n        UINT            meshIdx,\n        int             vertexDataInfoArraySize,\n        CPUTBufferInfo *pVertexInfo,\n        void           *pVertexData,\n        CPUTBufferInfo *pIndexInfo,\n        void           *pIndex\n    ) = 0;\n\n    virtual void Draw(CPUTRenderParameters &renderParams, CPUTModel *pModel) = 0;\n    virtual void DrawShadow(CPUTRenderParameters &renderParams, CPUTModel *pModel) = 0;\n\tvoid IncrementInstanceCount() { mInstanceCount++; }\n\tvoid DecrementInstanceCount() { mInstanceCount--; }\n};\n\n#endif //__CPUTMESH_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTMeshDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUT_DX11.h\"\n#include \"CPUTMeshDX11.h\"\n#include \"CPUTMaterialDX11.h\"\n#include \"CPUTRenderParamsDX.h\"\n#include \"CPUTBufferDX11.h\"\n\n//-----------------------------------------------------------------------------\nCPUTMeshDX11::CPUTMeshDX11():\n    mVertexStride(0),\n    mVertexBufferOffset(0),\n    mVertexCount(0),\n    mpVertexBuffer(NULL),\n    mpVertexBufferForSRVDX(NULL),\n    mpVertexBufferForSRV(NULL),\n    mpVertexView(NULL),\n    mpStagingVertexBuffer(NULL),\n    mVertexBufferMappedType(CPUT_MAP_UNDEFINED),\n    mIndexBufferMappedType(CPUT_MAP_UNDEFINED),\n    mIndexCount(0),\n    mIndexBufferFormat(DXGI_FORMAT_UNKNOWN),\n    mpIndexBuffer(NULL),\n    mpStagingIndexBuffer(NULL),\n    mpInputLayout(NULL),\n    mpShadowInputLayout(NULL),\n    mNumberOfInputLayoutElements(0),\n    mpLayoutDescription(NULL)\n{\n}\n\n//-----------------------------------------------------------------------------\nCPUTMeshDX11::~CPUTMeshDX11()\n{\n    ClearAllObjects();\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMeshDX11::ClearAllObjects()\n{\n    SAFE_RELEASE(mpStagingIndexBuffer);\n    SAFE_RELEASE(mpIndexBuffer);\n    SAFE_RELEASE(mpStagingVertexBuffer);\n    SAFE_RELEASE(mpVertexBuffer);\n    SAFE_RELEASE(mpVertexBufferForSRVDX);\n    SAFE_RELEASE(mpVertexBufferForSRV);\n    SAFE_RELEASE(mpVertexView);\n    SAFE_RELEASE(mpInputLayout);\n    SAFE_RELEASE(mpShadowInputLayout);\n\n    SAFE_DELETE_ARRAY(mpLayoutDescription);\n}\n\n// Create the DX vertex/index buffers and D3D11_INPUT_ELEMENT_DESC\n//-----------------------------------------------------------------------------\nCPUTResult CPUTMeshDX11::CreateNativeResources(\n    CPUTModel       *pModel,\n    UINT             meshIdx,\n    int              vertexDataInfoArraySize,\n    CPUTBufferInfo  *pVertexDataInfo,\n    void            *pVertexData,\n    CPUTBufferInfo  *pIndexDataInfo,\n    void            *pIndexData\n){\n\n    CPUTResult result = CPUT_SUCCESS;\n    HRESULT hr;\n\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n\n    // Release the layout, offset, stride, and vertex buffer structure objects\n    ClearAllObjects();\n\n    // allocate the layout, offset, stride, and vertex buffer structure objects\n    mpLayoutDescription = new D3D11_INPUT_ELEMENT_DESC[vertexDataInfoArraySize+1];\n\n    // Create the index buffer\n    D3D11_SUBRESOURCE_DATA resourceData;\n    if(NULL!=pIndexData)\n    {\n        mIndexCount = pIndexDataInfo->mElementCount;\n\n        // set the data format info\n        ZeroMemory( &mIndexBufferDesc, sizeof(mIndexBufferDesc) );\n        mIndexBufferDesc.Usage = D3D11_USAGE_DEFAULT;\n        mIndexBufferDesc.ByteWidth = mIndexCount * pIndexDataInfo->mElementSizeInBytes;\n        mIndexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;\n        mIndexBufferDesc.CPUAccessFlags = 0;  // default to no cpu access for speed\n\n        // create the buffer\n        ZeroMemory( &resourceData, sizeof(resourceData) );\n        resourceData.pSysMem = pIndexData;\n        hr = pD3dDevice->CreateBuffer( &mIndexBufferDesc, &resourceData, &mpIndexBuffer );\n        ASSERT(!FAILED(hr), _L(\"Failed creating index buffer\") );\n        CPUTSetDebugName( mpIndexBuffer, _L(\"Index buffer\") );\n\n        // set the DX index buffer format\n        mIndexBufferFormat = ConvertToDirectXFormat(pIndexDataInfo->mElementType, pIndexDataInfo->mElementComponentCount);\n    }\n\n    // set up data format info\n    mVertexCount = pVertexDataInfo[0].mElementCount;\n\n    ZeroMemory( &mVertexBufferDesc, sizeof(mVertexBufferDesc) );\n    mVertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;\n    // set the stride for one 'element' block of verts\n\tmVertexStride = pVertexDataInfo[vertexDataInfoArraySize-1].mOffset + pVertexDataInfo[vertexDataInfoArraySize-1].mElementSizeInBytes; // size in bytes of a single vertex block\n    mVertexBufferDesc.ByteWidth = mVertexCount * mVertexStride; // size in bytes of entire buffer\n    mVertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;\n    mVertexBufferDesc.CPUAccessFlags = 0;  // default to no cpu access for speed\n\n    // create the buffer\n    ZeroMemory( &resourceData, sizeof(resourceData) );\n    resourceData.pSysMem = pVertexData;\n    hr = pD3dDevice->CreateBuffer( &mVertexBufferDesc, &resourceData, &mpVertexBuffer );\n    ASSERT( !FAILED(hr), _L(\"Failed creating vertex buffer\") );\n    CPUTSetDebugName( mpVertexBuffer, _L(\"Vertex buffer\") );\n\n    // create the buffer for the shader resource view\n    D3D11_BUFFER_DESC desc;\n    ZeroMemory( &desc, sizeof(desc) );\n    desc.Usage = D3D11_USAGE_DEFAULT;\n    // set the stride for one 'element' block of verts\n\tmVertexStride           = pVertexDataInfo[vertexDataInfoArraySize-1].mOffset + pVertexDataInfo[vertexDataInfoArraySize-1].mElementSizeInBytes; // size in bytes of a single vertex block\n    desc.ByteWidth           = mVertexCount * mVertexStride; // size in bytes of entire buffer\n    desc.BindFlags           = D3D11_BIND_SHADER_RESOURCE;\n    desc.CPUAccessFlags      = 0;\n    desc.MiscFlags           = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;\n    desc.StructureByteStride = mVertexStride;\n\n    hr = pD3dDevice->CreateBuffer( &desc, &resourceData, &mpVertexBufferForSRVDX );\n    ASSERT( !FAILED(hr), _L(\"Failed creating vertex buffer for SRV\") );\n    //CPUTSetDebugName( mpVertexBuffer, _L(\"Vertex buffer for SRV\") );\n\n    // Create the shader resource view\n    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;  \n    ZeroMemory( &srvDesc, sizeof(srvDesc) );  \n    srvDesc.Format = DXGI_FORMAT_UNKNOWN;  \n    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;  \n    srvDesc.Buffer.ElementOffset = 0;  \n    srvDesc.Buffer.NumElements = mVertexCount;\n\n    hr = pD3dDevice->CreateShaderResourceView( mpVertexBufferForSRVDX, &srvDesc, &mpVertexView );\n    ASSERT( !FAILED(hr), _L(\"Failed creating vertex buffer SRV\") );\n\n    cString name = _L(\"@VertexBuffer\") + ptoc(pModel) + itoc(meshIdx);\n    mpVertexBufferForSRV = new CPUTBufferDX11( name, mpVertexBufferForSRVDX, mpVertexView );\n    CPUTAssetLibrary::GetAssetLibrary()->AddBuffer( name, mpVertexBufferForSRV );\n\n    // build the layout object\n    int currentByteOffset=0;\n    mNumberOfInputLayoutElements = vertexDataInfoArraySize;\n    for(int ii=0; ii<vertexDataInfoArraySize; ii++)\n    {\n        mpLayoutDescription[ii].SemanticName  = pVertexDataInfo[ii].mpSemanticName; // string name that matches\n        mpLayoutDescription[ii].SemanticIndex = pVertexDataInfo[ii].mSemanticIndex; // if we have more than one\n        mpLayoutDescription[ii].Format = ConvertToDirectXFormat(pVertexDataInfo[ii].mElementType, pVertexDataInfo[ii].mElementComponentCount);\n        mpLayoutDescription[ii].InputSlot = 0; // TODO: We support only a single stream now.  Support multiple streams.\n        mpLayoutDescription[ii].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;\n        mpLayoutDescription[ii].InstanceDataStepRate = 0;\n        mpLayoutDescription[ii].AlignedByteOffset = currentByteOffset;\n        currentByteOffset += pVertexDataInfo[ii].mElementSizeInBytes;\n    }\n    // set the last 'dummy' element to null.  Not sure if this is required, as we also pass in count when using this list.\n    memset( &mpLayoutDescription[vertexDataInfoArraySize], 0, sizeof(D3D11_INPUT_ELEMENT_DESC) );\n\n    return result;\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMeshDX11::Draw(CPUTRenderParameters &renderParams, CPUTModel *pModel, ID3D11InputLayout *pInputLayout )\n{\n    // Skip empty meshes.\n    if( !mIndexCount ) { return; }\n\n    ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n    pContext->IASetPrimitiveTopology( mD3DMeshTopology );\n    pContext->IASetVertexBuffers(0, 1, &mpVertexBuffer, &mVertexStride, &mVertexBufferOffset);\n    pContext->IASetIndexBuffer(mpIndexBuffer, mIndexBufferFormat, 0);\n\n    pContext->IASetInputLayout( pInputLayout );\n\n    pContext->DrawIndexed( mIndexCount, 0, 0 );\n}\n\n// Sets the mesh topology, and converts it to it's DX format\n//-----------------------------------------------------------------------------\nvoid CPUTMeshDX11::SetMeshTopology(const eCPUT_MESH_TOPOLOGY meshTopology)\n{\n    ASSERT( meshTopology > 0 && meshTopology <= 5, _L(\"\") );\n    CPUTMesh::SetMeshTopology(meshTopology);\n    // The CPUT enum has the same values as the D3D enum.  Will likely need an xlation on OpenGL.\n    mD3DMeshTopology = (D3D_PRIMITIVE_TOPOLOGY)meshTopology;\n}\n\n// Translate an internal CPUT data type into it's equivalent DirectX type\n//-----------------------------------------------------------------------------\nDXGI_FORMAT CPUTMeshDX11::ConvertToDirectXFormat(CPUT_DATA_FORMAT_TYPE dataFormatType, int componentCount)\n{\n    ASSERT( componentCount>0 && componentCount<=4, _L(\"Invalid vertex element count.\") );\n    switch( dataFormatType )\n    {\n    case CPUT_F32:\n    {\n        const DXGI_FORMAT componentCountToFormat[4] = {\n            DXGI_FORMAT_R32_FLOAT,\n            DXGI_FORMAT_R32G32_FLOAT,\n            DXGI_FORMAT_R32G32B32_FLOAT,\n            DXGI_FORMAT_R32G32B32A32_FLOAT\n        };\n        return componentCountToFormat[componentCount-1];\n    }\n    case CPUT_U32:\n    {\n        const DXGI_FORMAT componentCountToFormat[4] = {\n            DXGI_FORMAT_R32_UINT,\n            DXGI_FORMAT_R32G32_UINT,\n            DXGI_FORMAT_R32G32B32_UINT,\n            DXGI_FORMAT_R32G32B32A32_UINT\n        };\n        return componentCountToFormat[componentCount-1];\n        break;\n    }\n    case CPUT_U16:\n    {\n        ASSERT( 3 != componentCount, _L(\"Invalid vertex element count.\") );\n        const DXGI_FORMAT componentCountToFormat[4] = {\n            DXGI_FORMAT_R16_UINT,\n            DXGI_FORMAT_R16G16_UINT,\n            DXGI_FORMAT_UNKNOWN, // Count of 3 is invalid for 16-bit type\n            DXGI_FORMAT_R16G16B16A16_UINT\n        };\n        return componentCountToFormat[componentCount-1];\n    }\n    default:\n    {\n        // todo: add all the other data types you want to support\n        ASSERT(0,_L(\"Unsupported vertex element type\"));\n    }\n    return DXGI_FORMAT_UNKNOWN;\n    }\n} // CPUTMeshDX11::ConvertToDirectXFormat()\n\n// Finds a layout that matches the materials vertex shader and the mesh's\n// vertex buffer layout by using the InputLayoutCache\n//-----------------------------------------------------------------------------\nvoid CPUTMeshDX11::BindVertexShaderLayout( CPUTMaterial *pMaterial, CPUTMaterial *pShadowCastMaterial )\n{\n    ID3D11Device *pDevice = CPUT_DX11::GetDevice();\n\n    if( pMaterial )\n    {\n        // Get the vertex layout for this shader/format comb\n        // If already exists, then GetLayout() returns the existing layout for reuse.\n        CPUTVertexShaderDX11 *pVertexShader = ((CPUTMaterialDX11*)pMaterial)->GetVertexShader();\n\t    SAFE_RELEASE(mpInputLayout);\n        CPUTInputLayoutCacheDX11::GetInputLayoutCache()->GetLayout(pDevice, mpLayoutDescription, pVertexShader, &mpInputLayout);\n    }\n    if( pShadowCastMaterial )\n    {\n        CPUTVertexShaderDX11 *pVertexShader = ((CPUTMaterialDX11*)pShadowCastMaterial)->GetVertexShader();\n\t    SAFE_RELEASE(mpShadowInputLayout);\n        CPUTInputLayoutCacheDX11::GetInputLayoutCache()->GetLayout(pDevice, mpLayoutDescription, pVertexShader, &mpShadowInputLayout);\n    }\n}\n\n//-----------------------------------------------------------------------------\nD3D11_MAPPED_SUBRESOURCE CPUTMeshDX11::Map(\n    UINT                   count,\n    ID3D11Buffer          *pBuffer,\n    D3D11_BUFFER_DESC     &bufferDesc,\n    ID3D11Buffer         **pStagingBuffer,\n    eCPUTMapType          *pMappedType,\n    CPUTRenderParameters  &params,\n    eCPUTMapType           type,\n    bool                   wait\n)\n{\n    // Mapping for DISCARD requires dynamic buffer.  Create dynamic copy?\n    // Could easily provide input flag.  But, where would we specify? Don't like specifying in the .set file\n    // Because mapping is something the application wants to do - it isn't inherent in the data.\n    // Could do Clone() and pass dynamic flag to that.\n    // But, then we have two.  Could always delete the other.\n    // Could support programatic flag - apply to all loaded models in the .set\n    // Could support programatic flag on model.  Load model first, then load set.\n    // For now, simply support CopyResource mechanism.\n    HRESULT hr;\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    if( !*pStagingBuffer )\n    {\n        D3D11_BUFFER_DESC desc = bufferDesc;\n        // First time.  Create the staging resource\n        desc.Usage = D3D11_USAGE_STAGING;\n        switch( type )\n        {\n        case CPUT_MAP_READ:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n            desc.BindFlags = 0;\n            break;\n        case CPUT_MAP_READ_WRITE:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n            desc.BindFlags = 0;\n            break;\n        case CPUT_MAP_WRITE:\n        case CPUT_MAP_WRITE_DISCARD:\n        case CPUT_MAP_NO_OVERWRITE:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n            desc.BindFlags = 0;\n            break;\n        };\n        hr = pD3dDevice->CreateBuffer( &desc, NULL, pStagingBuffer );\n        ASSERT( SUCCEEDED(hr), _L(\"Failed to create staging buffer\") );\n        CPUTSetDebugName( *pStagingBuffer, _L(\"Mesh Staging buffer\") );\n    }\n    else\n    {\n        ASSERT( *pMappedType == type, _L(\"Mapping with a different CPU access than creation parameter.\") );\n    }\n\n    D3D11_MAPPED_SUBRESOURCE info;\n    switch( type )\n    {\n    case CPUT_MAP_READ:\n    case CPUT_MAP_READ_WRITE:\n        // TODO: Copying and immediately mapping probably introduces a stall.\n        // Expose the copy externally?\n        // TODO: copy only if vb has changed?\n        // Copy only first time?\n        // Copy the GPU version before we read from it.\n        pContext->CopyResource( *pStagingBuffer, pBuffer );\n        break;\n    };\n    hr = pContext->Map( *pStagingBuffer, wait ? 0 : D3D11_MAP_FLAG_DO_NOT_WAIT, (D3D11_MAP)type, 0, &info );\n    *pMappedType = type;\n    return info;\n} // CPUTMeshDX11::Map()\n\n//-----------------------------------------------------------------------------\nvoid  CPUTMeshDX11::Unmap(\n    ID3D11Buffer         *pBuffer,\n    ID3D11Buffer         *pStagingBuffer,\n    eCPUTMapType         *pMappedType,\n    CPUTRenderParameters &params\n)\n{\n    ASSERT( *pMappedType != CPUT_MAP_UNDEFINED, _L(\"Can't unmap a buffer that isn't mapped.\") );\n\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    pContext->Unmap( pStagingBuffer, 0 );\n\n    // If we were mapped for write, then copy staging buffer to GPU\n    switch( *pMappedType )\n    {\n    case CPUT_MAP_READ:\n        break;\n    case CPUT_MAP_READ_WRITE:\n    case CPUT_MAP_WRITE:\n    case CPUT_MAP_WRITE_DISCARD:\n    case CPUT_MAP_NO_OVERWRITE:\n        pContext->CopyResource( pBuffer, pStagingBuffer );\n        break;\n    };\n\n    // *pMappedType = CPUT_MAP_UNDEFINED; // TODO: Just commented this out.  Otherwise, assert in Map() fails.  Verify.\n} // CPUTMeshDX11::Unmap()\n\n\n//-----------------------------------------------------------------------------\nD3D11_MAPPED_SUBRESOURCE CPUTMeshDX11::MapVertices( CPUTRenderParameters &params, eCPUTMapType type, bool wait )\n{\n    return Map(\n        mVertexCount,\n        mpVertexBuffer,\n        mVertexBufferDesc,\n       &mpStagingVertexBuffer,\n       &mVertexBufferMappedType,\n        params,\n        type,\n        wait\n    );\n}\n\n//-----------------------------------------------------------------------------\nD3D11_MAPPED_SUBRESOURCE CPUTMeshDX11::MapIndices( CPUTRenderParameters &params, eCPUTMapType type, bool wait )\n{\n    return Map(\n        mIndexCount,\n        mpIndexBuffer,\n        mIndexBufferDesc,\n       &mpStagingIndexBuffer,\n       &mIndexBufferMappedType,\n        params,\n        type,\n        wait\n    );\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMeshDX11::UnmapVertices( CPUTRenderParameters &params )\n{\n    Unmap( mpVertexBuffer, mpStagingVertexBuffer, &mVertexBufferMappedType, params );\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTMeshDX11::UnmapIndices( CPUTRenderParameters &params )\n{\n    Unmap( mpIndexBuffer, mpStagingIndexBuffer, &mIndexBufferMappedType, params );\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTMeshDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTMESHDX11_H__\n#define __CPUTMESHDX11_H__\n\n#pragma once\n\n#include \"CPUTMesh.h\"\n#include \"CPUTRenderParamsDX.h\"\n#include \"CPUTInputLayoutCacheDX11.h\"\n#include \"CPUT.h\"\n#include \"CPUTOSServicesWin.h\"\n\nclass CPUTMaterial;\nclass CPUTMaterialDX11;\nclass CPUTBufferDX11;\nclass CPUTComputeShaderDX11;\nclass CPUTModelDX11;\n\n//-----------------------------------------------------------------------------\nclass CPUTMeshDX11 : public CPUTMesh\n{protected:\n    D3D_PRIMITIVE_TOPOLOGY    mD3DMeshTopology;\n    D3D11_INPUT_ELEMENT_DESC *mpLayoutDescription;\n    int                       mNumberOfInputLayoutElements;\n    ID3D11InputLayout        *mpInputLayout;\n    ID3D11InputLayout        *mpShadowInputLayout;\n    UINT                      mVertexStride;\n\n    D3D11_BUFFER_DESC         mVertexBufferDesc;\n    UINT                      mVertexBufferOffset;\n    UINT                      mVertexCount;\n    ID3D11Buffer             *mpVertexBuffer;\n    ID3D11Buffer             *mpStagingVertexBuffer;\n    eCPUTMapType              mVertexBufferMappedType;\n    ID3D11Buffer             *mpVertexBufferForSRVDX; // Need SRV, but _real_ DX won't allow for _real_ VB\n    ID3D11ShaderResourceView *mpVertexView;\n    CPUTBufferDX11           *mpVertexBufferForSRV;\n\n\n    UINT                      mIndexCount;\n    DXGI_FORMAT               mIndexBufferFormat;\n    ID3D11Buffer             *mpIndexBuffer;\n    D3D11_BUFFER_DESC         mIndexBufferDesc;\n    ID3D11Buffer             *mpStagingIndexBuffer;\n    eCPUTMapType              mIndexBufferMappedType;\n\npublic:\n    CPUTMeshDX11();\n    virtual ~CPUTMeshDX11();\n\n    D3D11_INPUT_ELEMENT_DESC *GetLayoutDescription() { return mpLayoutDescription; }\n    ID3D11Buffer             *GetIndexBuffer()  { return mpIndexBuffer; }\n    ID3D11Buffer             *GetVertexBuffer() { return mpVertexBuffer; }\n    void                      SetMeshTopology(const eCPUT_MESH_TOPOLOGY eDrawTopology);\n    CPUTResult                CreateNativeResources( CPUTModel *pModel, UINT meshIdx, int vertexDataInfoArraySize, CPUTBufferInfo *pVertexInfo, void *pVertexData, CPUTBufferInfo *pIndexInfo, void *pIndex );\n    void                      BindVertexShaderLayout(CPUTMaterial *pMaterial, CPUTMaterial *pShadowCastMaterial);\n    void                      Draw(CPUTRenderParameters &renderParams, CPUTModel *pModel)       { Draw(renderParams, pModel, mpInputLayout);}\n    void                      DrawShadow(CPUTRenderParameters &renderParams, CPUTModel *pModel) { Draw(renderParams, pModel, mpShadowInputLayout);}\n    void                      Draw(CPUTRenderParameters &renderParams, CPUTModel *pModel, ID3D11InputLayout *pLayout);\n\n    D3D11_MAPPED_SUBRESOURCE  MapVertices(   CPUTRenderParameters &params, eCPUTMapType type, bool wait=true );\n    D3D11_MAPPED_SUBRESOURCE  MapIndices(    CPUTRenderParameters &params, eCPUTMapType type, bool wait=true );\n    void                      UnmapVertices( CPUTRenderParameters &params );\n    void                      UnmapIndices(  CPUTRenderParameters &params );\n    UINT                      GetTriangleCount() { return mIndexCount/3; }\n    UINT                      GetVertexCount() { return mVertexCount; }\n    UINT                      GetIndexCount()  { return mIndexCount; }\n\nprotected:\n    // Mapping vertex and index buffers is very similar.  This internal function does both\n    D3D11_MAPPED_SUBRESOURCE Map(\n        UINT                   count,\n        ID3D11Buffer          *pBuffer,\n        D3D11_BUFFER_DESC     &bufferDesc,\n        ID3D11Buffer         **pStagingBuffer,\n        eCPUTMapType          *pMappedType,\n        CPUTRenderParameters  &params,\n        eCPUTMapType           type,\n        bool                   wait = true\n    );\n    void  Unmap(\n        ID3D11Buffer         *pBuffer,\n        ID3D11Buffer         *pStagingBuffer,\n        eCPUTMapType         *pMappedType,\n        CPUTRenderParameters &params\n    );\n    void ClearAllObjects(); // delete all allocations held by this object\n    DXGI_FORMAT ConvertToDirectXFormat(CPUT_DATA_FORMAT_TYPE DataFormatElementType, int NumberDataFormatElements);\n};\n\n#endif // __CPUTMESHDX11_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTModel.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTModel.h\"\n#include \"CPUTMaterial.h\"\n#include \"CPUTMesh.h\"\n#include \"CPUTAssetLibrary.h\"\n\n//-----------------------------------------------------------------------------\nCPUTModel::~CPUTModel()\n{\n    // TODO: Do we need a shadowCastMaterial per mesh?  What happens if the meshes have different layouts?\n    SAFE_RELEASE(mpShadowCastMaterial);\n    for( UINT ii=0; ii<mMeshCount; ii++ )\n    {\n        SAFE_RELEASE(mpMaterial[ii]);\n        HEAPCHECK;\n\t\tif( mpMesh[ii] )\n\t\t{\n\t\t\tmpMesh[ii]->DecrementInstanceCount();\n\t\t}\n        SAFE_RELEASE(mpMesh[ii]);\n        HEAPCHECK;\n    }\n    SAFE_RELEASE(mpBoundingBoxMesh);\n    SAFE_RELEASE(mpBoundingBoxMaterial);\n    SAFE_DELETE_ARRAY(mpMaterial);\n    SAFE_DELETE_ARRAY(mpMesh);\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTModel::GetBoundsObjectSpace(float3 *pCenter, float3 *pHalf)\n{\n    *pCenter = mBoundingBoxCenterObjectSpace;\n    *pHalf   = mBoundingBoxHalfObjectSpace;\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTModel::GetBoundsWorldSpace(float3 *pCenter, float3 *pHalf)\n{\n    *pCenter = mBoundingBoxCenterWorldSpace;\n    *pHalf   = mBoundingBoxHalfWorldSpace;\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTModel::UpdateBoundsWorldSpace()\n{\n    // If an object is rigid, then it's object-space bounding box doesn't change.\n    // However, if it moves, then it's world-space bounding box does change.\n    // Call this function when the model moves\n\n    float4x4 *pWorld =  GetWorldMatrix();\n    float4 center    =  float4(mBoundingBoxCenterObjectSpace, 1.0f); // W = 1 because we want the xlation (i.e., center is a position)\n    float4 half      =  float4(mBoundingBoxHalfObjectSpace,   0.0f); // W = 0 because we don't want xlation (i.e., half is a direction)\n\n    // TODO: optimize this\n    float4 positions[8] = {\n        center + float4( 1.0f, 1.0f, 1.0f, 0.0f ) * half,\n        center + float4( 1.0f, 1.0f,-1.0f, 0.0f ) * half,\n        center + float4( 1.0f,-1.0f, 1.0f, 0.0f ) * half,\n        center + float4( 1.0f,-1.0f,-1.0f, 0.0f ) * half,\n        center + float4(-1.0f, 1.0f, 1.0f, 0.0f ) * half,\n        center + float4(-1.0f, 1.0f,-1.0f, 0.0f ) * half,\n        center + float4(-1.0f,-1.0f, 1.0f, 0.0f ) * half,\n        center + float4(-1.0f,-1.0f,-1.0f, 0.0f ) * half\n    };\n\n    float4 minPosition( FLT_MAX,  FLT_MAX,  FLT_MAX, 1.0f );\n    float4 maxPosition(-FLT_MAX, -FLT_MAX, -FLT_MAX, 1.0f );\n    for( UINT ii=0; ii<8; ii++ )\n    {\n        float4 position = positions[ii] * *pWorld;\n        minPosition = Min( minPosition, position );\n        maxPosition = Max( maxPosition, position );\n    }\n    mBoundingBoxCenterWorldSpace = (maxPosition + minPosition) * 0.5f;\n    mBoundingBoxHalfWorldSpace   = (maxPosition - minPosition) * 0.5f;\n}\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTModel::LoadModelPayload(const cString &File)\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    std::ifstream file(File.c_str(), std::ios::in | std::ios::binary);\n    ASSERT( !file.fail(), _L(\"CPUTModelDX11::LoadModelPayload() - Could not find binary model file: \") + File );\n\n    // set up for mesh creation loop\n    UINT meshIndex = 0;\n    while(file.good() && !file.eof())\n    {\n        // TODO: rearrange while() to avoid if(eof).  Should perform only one branch per loop iteration, not two\n        CPUTRawMeshData vertexFormatDesc;\n        vertexFormatDesc.Read(file);\n        if(file.eof())\n        {\n            // TODO:  Wtf?  Why would we get here?  We check eof at the top of loop.  If it isn't eof there, why is it eof here?\n            break;\n        }\n        ASSERT( meshIndex < mMeshCount, _L(\"Actual mesh count doesn't match stated mesh count\"));\n\n        // create the mesh.\n        CPUTMesh *pMesh = mpMesh[meshIndex];\n\n        // always a triangle list (at this point)\n        pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_TRIANGLE_LIST);\n\n        // get number of data blocks in the vertex element (pos,norm,uv,etc)\n        // YUCK! TODO: Use fixed-size array of elements\n        CPUTBufferInfo *pVertexElementInfo = new CPUTBufferInfo[vertexFormatDesc.mFormatDescriptorCount];\n        // pMesh->SetBounds(vertexFormatDesc.mBboxCenter, vertexFormatDesc.mBboxHalf);\n\n        // running count of each type of  element\n        int positionStreamCount=0;\n        int normalStreamCount=0;\n        int texCoordStreamCount=0;\n        int tangentStreamCount=0;\n        int binormalStreamCount=0;\n        int colorStreamCount=0;\n\n        int RunningOffset = 0;\n        for(UINT ii=0; ii<vertexFormatDesc.mFormatDescriptorCount; ii++)\n        {\n            // lookup the CPUT data type equivalent\n            pVertexElementInfo[ii].mElementType = CPUT_FILE_ELEMENT_TYPE_TO_CPUT_TYPE_CONVERT[vertexFormatDesc.mpElements[ii].mVertexElementType];\n            ASSERT((pVertexElementInfo[ii].mElementType !=CPUT_UNKNOWN ) , _L(\".MDL file load error.  This model file has an unknown data type in it's model data.\"));\n            // calculate the number of elements in this stream block (i.e. F32F32F32 = 3xF32)\n            pVertexElementInfo[ii].mElementComponentCount = vertexFormatDesc.mpElements[ii].mElementSizeInBytes/CPUT_DATA_FORMAT_SIZE[pVertexElementInfo[ii].mElementType];\n            // store the size of each element type in bytes (i.e. 3xF32, each element = F32 = 4 bytes)\n            pVertexElementInfo[ii].mElementSizeInBytes = vertexFormatDesc.mpElements[ii].mElementSizeInBytes;\n            // store the number of elements (i.e. 3xF32, 3 elements)\n            pVertexElementInfo[ii].mElementCount = vertexFormatDesc.mVertexCount;\n            // calculate the offset from the first element of the stream - assumes all blocks appear in the vertex stream as the order that appears here\n            pVertexElementInfo[ii].mOffset = RunningOffset;\n            RunningOffset = RunningOffset + pVertexElementInfo[ii].mElementSizeInBytes;\n\n            // extract the name of stream\n            pVertexElementInfo[ii].mpSemanticName = CPUT_VERTEX_ELEMENT_SEMANTIC_AS_STRING[ii];\n\n            switch(vertexFormatDesc.mpElements[ii].mVertexElementSemantic)\n            {\n            case CPUT_VERTEX_ELEMENT_POSITON:\n                pVertexElementInfo[ii].mpSemanticName = \"POSITION\";\n                pVertexElementInfo[ii].mSemanticIndex = positionStreamCount++;\n                break;\n            case CPUT_VERTEX_ELEMENT_NORMAL:\n                pVertexElementInfo[ii].mpSemanticName = \"NORMAL\";\n                pVertexElementInfo[ii].mSemanticIndex = normalStreamCount++;\n                break;\n            case CPUT_VERTEX_ELEMENT_TEXTURECOORD:\n                pVertexElementInfo[ii].mpSemanticName = \"TEXCOORD\";\n                pVertexElementInfo[ii].mSemanticIndex = texCoordStreamCount++;\n                break;\n            case CPUT_VERTEX_ELEMENT_TANGENT:\n                pVertexElementInfo[ii].mpSemanticName = \"TANGENT\";\n                pVertexElementInfo[ii].mSemanticIndex = tangentStreamCount++;\n                break;\n            case CPUT_VERTEX_ELEMENT_BINORMAL:\n                pVertexElementInfo[ii].mpSemanticName = \"BINORMAL\";\n                pVertexElementInfo[ii].mSemanticIndex = binormalStreamCount++;\n                break;\n            case CPUT_VERTEX_ELEMENT_VERTEXCOLOR:\n                pVertexElementInfo[ii].mpSemanticName = \"COLOR\";\n                pVertexElementInfo[ii].mSemanticIndex = colorStreamCount++;\n                break;\n            default:\n                cString errorString = _L(\"Invalid vertex semantic in: '\")+File+_L(\"'\\n\");\n                TRACE(errorString.c_str());\n                ASSERT(0, errorString);\n            }\n        }\n\n        // Index buffer\n        CPUTBufferInfo indexDataInfo;\n        indexDataInfo.mElementType           = (vertexFormatDesc.mIndexType == tUINT32) ? CPUT_U32 : CPUT_U16;\n        indexDataInfo.mElementComponentCount = 1;\n        indexDataInfo.mElementSizeInBytes    = (vertexFormatDesc.mIndexType == tUINT32) ? sizeof(UINT32) : sizeof(UINT16);\n        indexDataInfo.mElementCount          = vertexFormatDesc.mIndexCount;\n        indexDataInfo.mOffset                = 0;\n        indexDataInfo.mSemanticIndex         = 0;\n        indexDataInfo.mpSemanticName         = NULL;\n\n        if( pVertexElementInfo->mElementCount && indexDataInfo.mElementCount )\n        {\n            result = pMesh->CreateNativeResources(\n                this,\n                meshIndex,\n                vertexFormatDesc.mFormatDescriptorCount,\n                pVertexElementInfo,\n                (void*)vertexFormatDesc.mpVertices,\n                &indexDataInfo,\n                &vertexFormatDesc.mpIndices[0]\n            );\n            if(CPUTFAILED(result))\n            {\n                return result;\n            }\n        }\n        delete [] pVertexElementInfo;\n        pVertexElementInfo = NULL;\n        ++meshIndex;\n    }\n    ASSERT( file.eof(), _L(\"\") );\n\n    // close file\n    file.close();\n\n    return result;\n}\n\n// Set the material associated with this mesh and create/re-use a\n//-----------------------------------------------------------------------------\nvoid CPUTModel::SetMaterial(UINT ii, CPUTMaterial *pMaterial)\n{\n    // TODO: ASSSERT that ii is in range\n\n    // release old material pointer\n    SAFE_RELEASE( mpMaterial[ii] );\n\n    mpMaterial[ii] = pMaterial;\n    if(mpMaterial[ii])\n    {\n        mpMaterial[ii]->AddRef();\n    }\n}\n\n\n#ifdef SUPPORT_DRAWING_BOUNDING_BOXES\n// TODO:  We create a native mesh below.  Best way to do this?  Move the whole thing to CPUTModelDX11?  Add CPUTMesh::CreateNativeMesh() or equiv?\n// Note that we only need one of these.  We don't need to re-create it for every model.\n#include \"CPUTMeshDX11.h\"\n//-----------------------------------------------------------------------------\nvoid CPUTModel::CreateBoundingBoxMesh()\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    float3 pVertices[8] = {\n        float3(  1.0f,  1.0f,  1.0f ), // 0\n        float3(  1.0f,  1.0f, -1.0f ), // 1\n        float3( -1.0f,  1.0f,  1.0f ), // 2\n        float3( -1.0f,  1.0f, -1.0f ), // 3\n        float3(  1.0f, -1.0f,  1.0f ), // 4\n        float3(  1.0f, -1.0f, -1.0f ), // 5\n        float3( -1.0f, -1.0f,  1.0f ), // 6\n        float3( -1.0f, -1.0f, -1.0f )  // 7\n    };\n    USHORT pIndices[24] = {\n       0,1,  1,3,  3,2,  2,0,  // Top\n       4,5,  5,7,  7,6,  6,4,  // Bottom\n       0,4,  1,5,  2,6,  3,7   // Verticals\n    };\n    CPUTVertexElementDesc pVertexElements[] = {\n        { CPUT_VERTEX_ELEMENT_POSITON, tFLOAT, 12, 0 },\n    };\n\n    CPUTMesh *pMesh = mpBoundingBoxMesh = new CPUTMeshDX11();\n    pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_LINE_LIST);\n\n    CPUTBufferInfo vertexElementInfo;\n    vertexElementInfo.mpSemanticName         = \"POSITION\";\n    vertexElementInfo.mSemanticIndex         = 0;\n    vertexElementInfo.mElementType           = CPUT_F32;\n    vertexElementInfo.mElementComponentCount = 3;\n    vertexElementInfo.mElementSizeInBytes    = 12;\n    vertexElementInfo.mElementCount          = 8;\n    vertexElementInfo.mOffset                = 0;\n\n    CPUTBufferInfo indexDataInfo;\n    indexDataInfo.mElementType           = CPUT_U16;\n    indexDataInfo.mElementComponentCount = 1;\n    indexDataInfo.mElementSizeInBytes    = sizeof(UINT16);\n    indexDataInfo.mElementCount          = 24; // 12 lines, 2 verts each\n    indexDataInfo.mOffset                = 0;\n    indexDataInfo.mSemanticIndex         = 0;\n    indexDataInfo.mpSemanticName         = NULL;\n\n    result = pMesh->CreateNativeResources(\n        1,                    // vertexFormatDesc.mFormatDescriptorCount,\n        &vertexElementInfo,\n        pVertices,            // (void*)vertexFormatDesc.mpVertices,\n        &indexDataInfo,\n        pIndices              // &vertexFormatDesc.mpIndices[0]\n    );\n    ASSERT( CPUTSUCCESS(result), _L(\"Failed building bounding box mesh\") );\n\n    mpBoundingBoxMaterial = CPUTAssetLibrary::GetAssetLibrary()->GetMaterial(_L(\"BoundingBox\") );\n    pMesh->BindVertexShaderLayout( mpBoundingBoxMaterial );\n}\n#endif\n"
  },
  {
    "path": "CPUT/CPUT/CPUTModel.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTMODEL_H__\n#define __CPUTMODEL_H__\n\n// Define the following to support drawing bounding boxes.\n// Note that you also need bounding-box materials and shaders.  TODO: Include them in the exe.\n// #define SUPPORT_DRAWING_BOUNDING_BOXES 1\n\n#include \"CPUTRenderNode.h\"\n#include \"CPUTMath.h\"\n#include \"CPUTConfigBlock.h\"\n#include \"CPUTMesh.h\"\n\nclass CPUTMaterial;\nclass CPUTMesh;\n\n//-----------------------------------------------------------------------------\nclass CPUTModel : public CPUTRenderNode\n{\nprotected:  \n    CPUTMesh     **mpMesh;\n    CPUTMaterial **mpMaterial;\n    CPUTMaterial  *mpShadowCastMaterial;\n\n\n    UINT           mMeshCount;\n    bool           mIsRenderable;\n    float3         mBoundingBoxCenterObjectSpace;\n    float3         mBoundingBoxHalfObjectSpace;\n    float3         mBoundingBoxCenterWorldSpace;\n    float3         mBoundingBoxHalfWorldSpace;\n    CPUTMesh      *mpBoundingBoxMesh;\n    CPUTMaterial  *mpBoundingBoxMaterial;\n\npublic:\n    CPUTModel():\n        mMeshCount(0),\n        mpMesh(NULL),\n        mIsRenderable(true),\n        mBoundingBoxCenterObjectSpace(0.0f),\n        mBoundingBoxHalfObjectSpace(0.0f),\n        mBoundingBoxCenterWorldSpace(0.0f),\n        mBoundingBoxHalfWorldSpace(0.0f),\n        mpBoundingBoxMesh(NULL),\n        mpBoundingBoxMaterial(NULL),\n        mpShadowCastMaterial(NULL)\n    {}\n    virtual ~CPUTModel();\n\n    bool               IsRenderable() { return mIsRenderable; }\n    void               SetRenderable(bool isRenderable) { mIsRenderable = isRenderable; }\n    virtual bool       IsModel() { return true; }\n    void               GetBoundsObjectSpace(float3 *pCenter, float3 *pHalf);\n    void               GetBoundsWorldSpace(float3 *pCenter, float3 *pHalf);\n    void               UpdateBoundsWorldSpace();\n    int                GetMeshCount() const { return mMeshCount; }\n    CPUTMesh          *GetMesh( UINT ii ) { return mpMesh[ii]; }\n    virtual CPUTResult LoadModel(CPUTConfigBlock *pBlock, int *pParentID, CPUTModel *pMasterModel=NULL) = 0;\n    CPUTResult         LoadModelPayload(const cString &File);\n    virtual void       SetMaterial(UINT ii, CPUTMaterial *pMaterial);\n#ifdef SUPPORT_DRAWING_BOUNDING_BOXES\n    virtual void       DrawBoundingBox(CPUTRenderParameters &renderParams) = 0;\n    void               CreateBoundingBoxMesh();\n#endif\n\n    void GetBoundingBoxRecursive( float3 *pCenter, float3 *pHalf)\n    {\n        if( *pHalf == float3(0.0f) )\n        {\n            *pCenter = mBoundingBoxCenterWorldSpace;\n            *pHalf   = mBoundingBoxHalfWorldSpace;\n        }\n        else\n        {\n            float3 minExtent = *pCenter - *pHalf;\n            float3 maxExtent = *pCenter + *pHalf;\n            minExtent = Min( (mBoundingBoxCenterWorldSpace - mBoundingBoxHalfWorldSpace), minExtent );\n            maxExtent = Max( (mBoundingBoxCenterWorldSpace + mBoundingBoxHalfWorldSpace), maxExtent );\n            *pCenter = (minExtent + maxExtent) * 0.5f;\n            *pHalf   = (maxExtent - minExtent) * 0.5f;\n        }\n        if(mpChild)   { mpChild->GetBoundingBoxRecursive(   pCenter, pHalf ); }\n        if(mpSibling) { mpSibling->GetBoundingBoxRecursive( pCenter, pHalf ); }\n    }\n\n};\n#endif // __CPUTMODEL_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTModelDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTModelDX11.h\"\n#include \"CPUTMaterialDX11.h\"\n#include \"CPUTRenderParamsDX.h\"\n#include \"CPUTFrustum.h\"\n#include \"CPUTTextureDX11.h\"\n#include \"CPUTBufferDX11.h\"\n\n// Return the mesh at the given index (cast to the GFX api version of CPUTMeshDX11)\n//-----------------------------------------------------------------------------\nCPUTMeshDX11* CPUTModelDX11::GetMesh(const UINT index) const\n{\n    return ( 0==mMeshCount || index > mMeshCount) ? NULL : (CPUTMeshDX11*)mpMesh[index];\n}\n\nfloat3 gLightDir = float3(0.7f, -0.5f, -0.1f);\n\n// Set the render state before drawing this object\n//-----------------------------------------------------------------------------\nvoid CPUTModelDX11::SetRenderStates(CPUTRenderParameters &renderParams)\n{\n    // TODO: need to update the constant buffer only when the model moves.\n    // But, requires individual, per-model constant buffers\n    ID3D11DeviceContext *pContext  = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n    CPUTModelConstantBuffer *pCb;\n\n    // update parameters of constant buffer\n    D3D11_MAPPED_SUBRESOURCE mapInfo;\n    pContext->Map( mpModelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo );\n    {\n        // TODO: remove construction of XMM type\n        XMMATRIX    world((float*)GetWorldMatrix());\n        XMVECTOR    determinant = XMMatrixDeterminant(world);\n        CPUTCamera *pCamera     = gpSample->GetCamera();\n        XMMATRIX    view((float*)pCamera->GetViewMatrix());\n        XMMATRIX    projection((float*)pCamera->GetProjectionMatrix());\n        float      *pCameraPos = (float*)&pCamera->GetPosition();\n        XMVECTOR    cameraPos = XMLoadFloat3(&XMFLOAT3( pCameraPos[0], pCameraPos[1], pCameraPos[2] ));\n\n        pCb = (CPUTModelConstantBuffer*)mapInfo.pData;\n        pCb->World               = world;\n        pCb->ViewProjection      = view  *projection;\n        pCb->WorldViewProjection = world  *pCb->ViewProjection;\n        pCb->InverseWorld        = XMMatrixInverse(&determinant, XMMatrixTranspose(world));\n        // pCb->LightDirection      = XMVector3Transform(gLightDir, pCb->InverseWorld );\n        // pCb->EyePosition         = XMVector3Transform(cameraPos, pCb->InverseWorld );\n        // TODO: Tell the lights to set their render states\n\n        XMVECTOR lightDirection = XMLoadFloat3(&XMFLOAT3( gLightDir.x, gLightDir.y, gLightDir.z ));\n        pCb->LightDirection      = XMVector3Normalize(lightDirection);\n        pCb->EyePosition         = cameraPos;\n        float *bbCWS = (float*)&mBoundingBoxCenterWorldSpace;\n        float *bbHWS = (float*)&mBoundingBoxHalfWorldSpace;\n        float *bbCOS = (float*)&mBoundingBoxCenterObjectSpace;\n        float *bbHOS = (float*)&mBoundingBoxHalfObjectSpace;\n        pCb->BoundingBoxCenterWorldSpace  = XMLoadFloat3(&XMFLOAT3( bbCWS[0], bbCWS[1], bbCWS[2] )); ;\n        pCb->BoundingBoxHalfWorldSpace    = XMLoadFloat3(&XMFLOAT3( bbHWS[0], bbHWS[1], bbHWS[2] )); ;\n        pCb->BoundingBoxCenterObjectSpace = XMLoadFloat3(&XMFLOAT3( bbCOS[0], bbCOS[1], bbCOS[2] )); ;\n        pCb->BoundingBoxHalfObjectSpace   = XMLoadFloat3(&XMFLOAT3( bbHOS[0], bbHOS[1], bbHOS[2] )); ;\n\n        // Shadow camera\n        XMMATRIX    shadowView, shadowProjection;\n        CPUTCamera *pShadowCamera = gpSample->GetShadowCamera();\n        if( pShadowCamera )\n        {\n            shadowView = XMMATRIX((float*)pShadowCamera->GetViewMatrix());\n            shadowProjection = XMMATRIX((float*)pShadowCamera->GetProjectionMatrix());\n            pCb->LightWorldViewProjection = world * shadowView * shadowProjection;\n        }\n    }\n    pContext->Unmap(mpModelConstantBuffer,0);\n}\n\n// Render - render this model (only)\n//-----------------------------------------------------------------------------\nvoid CPUTModelDX11::Render(CPUTRenderParameters &renderParams)\n{\n    CPUTRenderParametersDX *pParams = (CPUTRenderParametersDX*)&renderParams;\n    CPUTCamera             *pCamera = pParams->mpCamera;\n\n#ifdef SUPPORT_DRAWING_BOUNDING_BOXES \n    if( renderParams.mShowBoundingBoxes && (!pCamera || pCamera->mFrustum.IsVisible( mBoundingBoxCenterWorldSpace, mBoundingBoxHalfWorldSpace )))\n    {\n        DrawBoundingBox( renderParams );\n    }\n#endif\n    if( !renderParams.mDrawModels ) { return; }\n\n    // TODO: add world-space bounding box to model so we don't need to do that work every frame\n    if( !pParams->mRenderOnlyVisibleModels || !pCamera || pCamera->mFrustum.IsVisible( mBoundingBoxCenterWorldSpace, mBoundingBoxHalfWorldSpace ) )\n    {\n        // loop over all meshes in this model and draw them\n        for(UINT ii=0; ii<mMeshCount; ii++)\n        {\n            CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)(mpMaterial[ii]);\n            pMaterial->SetRenderStates(renderParams);\n\n            // We would like to set the model's render states only once (and then iterate over materials)\n            // But, the material resource lists leave holes for per-model resources (e.g., constant buffers)\n            // We need to 'fixup' the bound resources.  The material sets some to 0, and the model overwrites them with the correct values.\n            SetRenderStates(renderParams);\n\n            // Potentially need to use a different vertex-layout object!\n            CPUTVertexShaderDX11 *pVertexShader = pMaterial->GetVertexShader();\n            ((CPUTMeshDX11*)mpMesh[ii])->Draw(renderParams, this);\n        }\n    }\n}\n\n// Render - render this model (only)\n//-----------------------------------------------------------------------------\nvoid CPUTModelDX11::RenderShadow(CPUTRenderParameters &renderParams)\n{\n    CPUTRenderParametersDX *pParams = (CPUTRenderParametersDX*)&renderParams;\n    CPUTCamera             *pCamera = pParams->mpCamera;\n\n#ifdef SUPPORT_DRAWING_BOUNDING_BOXES \n    if( renderParams.mShowBoundingBoxes && (!pCamera || pCamera->mFrustum.IsVisible( mBoundingBoxCenterWorldSpace, mBoundingBoxHalfWorldSpace )))\n    {\n        DrawBoundingBox( renderParams );\n    }\n#endif\n    if( !renderParams.mDrawModels ) { return; }\n\n    // TODO: add world-space bounding box to model so we don't need to do that work every frame\n    if( !pParams->mRenderOnlyVisibleModels || !pCamera || pCamera->mFrustum.IsVisible( mBoundingBoxCenterWorldSpace, mBoundingBoxHalfWorldSpace ) )\n    {\n        // loop over all meshes in this model and draw them\n        for(UINT ii=0; ii<mMeshCount; ii++)\n        {\n            CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)(mpShadowCastMaterial);\n            pMaterial->SetRenderStates(renderParams);\n\n            // We would like to set the model's render states only once (and then iterate over materials)\n            // But, the material resource lists leave holes for per-model resources (e.g., constant buffers)\n            // We need to 'fixup' the bound resources.  The material sets some to 0, and the model overwrites them with the correct values.\n            SetRenderStates(renderParams);\n\n            // Potentially need to use a different vertex-layout object!\n            CPUTVertexShaderDX11 *pVertexShader = pMaterial->GetVertexShader();\n            ((CPUTMeshDX11*)mpMesh[ii])->DrawShadow(renderParams, this);\n        }\n    }\n}\n\n\n\n\n#ifdef SUPPORT_DRAWING_BOUNDING_BOXES\n//-----------------------------------------------------------------------------\nvoid CPUTModelDX11::DrawBoundingBox(CPUTRenderParameters &renderParams)\n{\n    SetRenderStates(renderParams);\n    CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)mpBoundingBoxMaterial;\n\n    mpBoundingBoxMaterial->SetRenderStates(renderParams);\n    ((CPUTMeshDX11*)mpBoundingBoxMesh)->Draw(renderParams, this);\n}\n#endif\n\n// Load the set file definition of this object\n// 1. Parse the block of name/parent/transform info for model block\n// 2. Load the model's binary payload (i.e., the meshes)\n// 3. Assert the # of meshes matches # of materials\n// 4. Load each mesh's material\n//-----------------------------------------------------------------------------\nCPUTResult CPUTModelDX11::LoadModel(CPUTConfigBlock *pBlock, int *pParentID, CPUTModel *pMasterModel)\n{\n    CPUTResult result = CPUT_SUCCESS;\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n\n    cString modelSuffix = ptoc(this);\n\n    // set the model's name\n    mName = pBlock->GetValueByName(_L(\"name\"))->ValueAsString();\n    mName = mName + _L(\".mdl\");\n\n    // resolve the full path name\n    cString modelLocation;\n    cString resolvedPathAndFile;\n    modelLocation = ((CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary())->GetModelDirectory();\n    modelLocation = modelLocation+mName;\n    CPUTOSServices::GetOSServices()->ResolveAbsolutePathAndFilename(modelLocation, &resolvedPathAndFile);\t\n\n    // Get the parent ID.  Note: the caller will use this to set the parent.\n    *pParentID = pBlock->GetValueByName(_L(\"parent\"))->ValueAsInt();\n\n    LoadParentMatrixFromParameterBlock( pBlock );\n\n    // Get the bounding box information\n\tfloat3 center(0.0f), half(0.0f);\n    pBlock->GetValueByName(_L(\"BoundingBoxCenter\"))->ValueAsFloatArray(center.f, 3);\n\tpBlock->GetValueByName(_L(\"BoundingBoxHalf\"))->ValueAsFloatArray(half.f, 3);\n    mBoundingBoxCenterObjectSpace = center;\n    mBoundingBoxHalfObjectSpace   = half;\n\n    // the # of meshes in the binary file better match the number of meshes in the .set file definition\n    mMeshCount = pBlock->GetValueByName(_L(\"meshcount\"))->ValueAsInt();\n    mpMesh     = new CPUTMesh*[mMeshCount];\n    mpMaterial = new CPUTMaterial*[mMeshCount];\n    memset( mpMaterial, 0, mMeshCount * sizeof(CPUTMaterial*) );\n    \n    // get the material names, load them, and match them up with each mesh\n    cString materialName;\n    char pNumber[4];\n    cString materialValueName;\n\n    CPUTModelDX11 *pMasterModelDX = (CPUTModelDX11*)pMasterModel;\n\n    for(UINT ii=0; ii<mMeshCount; ii++)\n    {\n        if(pMasterModelDX)\n        {\n            // Reference the master model's mesh.  Don't create a new one.\n            mpMesh[ii] = pMasterModelDX->mpMesh[ii];\n            mpMesh[ii]->AddRef();\n        }\n        else\n        {\n            mpMesh[ii] = new CPUTMeshDX11();\n        }\n    }\n    if( !pMasterModelDX )\n    {\n        // Not a clone/instance.  So, load the model's binary payload (i.e., vertex and index buffers)\n        // TODO: Change to use GetModel()\n        result = LoadModelPayload(resolvedPathAndFile);\n        ASSERT( CPUTSUCCESS(result), _L(\"Failed loading model\") );\n    }\n    // Create the model constant buffer.\n    HRESULT hr;\n    D3D11_BUFFER_DESC bd = {0};\n    bd.ByteWidth = sizeof(CPUTModelConstantBuffer);\n    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;\n    bd.Usage = D3D11_USAGE_DYNAMIC;\n    bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n    hr = (CPUT_DX11::GetDevice())->CreateBuffer( &bd, NULL, &mpModelConstantBuffer );\n    ASSERT( !FAILED( hr ), _L(\"Error creating constant buffer.\") );\n    CPUTSetDebugName( mpModelConstantBuffer, _L(\"Model Constant buffer\") );\n    cString pModelSuffix = ptoc(this);\n    cString name = _L(\"#cbPerModelValues\") + pModelSuffix;\n    CPUTBufferDX11 *pBuffer = new CPUTBufferDX11(name, mpModelConstantBuffer);\n    pAssetLibrary->AddConstantBuffer( name, pBuffer );\n    pBuffer->Release(); // We're done with it.  We added it to the library.  Release our reference.\n\n    cString assetSetDirectoryName = pAssetLibrary->GetAssetSetDirectoryName();\n    cString modelDirectory        = pAssetLibrary->GetModelDirectory();\n    cString materialDirectory     = pAssetLibrary->GetMaterialDirectory();\n    cString textureDirectory      = pAssetLibrary->GetTextureDirectory();\n    cString shaderDirectory       = pAssetLibrary->GetShaderDirectory();\n    cString fontDirectory         = pAssetLibrary->GetFontDirectory();\n    cString up2MediaDirName       = assetSetDirectoryName + _L(\"..\\\\..\\\\\");\n    pAssetLibrary->SetMediaDirectoryName( up2MediaDirName );\n    mpShadowCastMaterial = pAssetLibrary->GetMaterial( _L(\"shadowCast\"), false, modelSuffix );\n    pAssetLibrary->SetAssetSetDirectoryName( assetSetDirectoryName );\n    pAssetLibrary->SetModelDirectoryName( modelDirectory ); \n    pAssetLibrary->SetMaterialDirectoryName( materialDirectory );\n    pAssetLibrary->SetTextureDirectoryName( textureDirectory );\n    pAssetLibrary->SetShaderDirectoryName( shaderDirectory );\n    pAssetLibrary->SetFontDirectoryName( fontDirectory );\n\n    for(UINT ii=0; ii<mMeshCount; ii++)\n    {\n        // get the right material number ('material0', 'material1', 'material2', etc)\n        materialValueName = _L(\"material\");\n        _itoa_s(ii, pNumber, 4, 10);\n        materialValueName.append(s2ws(pNumber));\n        materialName = pBlock->GetValueByName(materialValueName)->ValueAsString();\n\n        // Get/load material for this mesh\n        cString meshSuffix  = itoc(ii);\n        CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)pAssetLibrary->GetMaterial(materialName, false, modelSuffix, meshSuffix);\n        ASSERT( pMaterial, _L(\"Couldn't find material.\") );\n\n        // set the material on this mesh\n        // TODO: Model owns the materials.  That allows different models to share meshes (aka instancing) that have different materials\n        SetMaterial(ii, pMaterial);\n\n        // Release the extra refcount we're holding from the GetMaterial operation earlier\n        // now the asset library, and this model have the only refcounts on that material\n        pMaterial->Release();\n\n        // Create two ID3D11InputLayout objects, one for each material.\n        mpMesh[ii]->BindVertexShaderLayout( mpMaterial[ii], mpShadowCastMaterial);\n        // mpShadowCastMaterial->Release()\n    }\n\n\n    return result;\n}\n\n// Set the material associated with this mesh and create/re-use a\n//-----------------------------------------------------------------------------\nvoid CPUTModelDX11::SetMaterial(UINT ii, CPUTMaterial *pMaterial)\n{\n    CPUTModel::SetMaterial(ii, pMaterial);\n\n    // Can't bind the layout if we haven't loaded the mesh yet.\n    CPUTMeshDX11 *pMesh = (CPUTMeshDX11*)mpMesh[ii];\n    D3D11_INPUT_ELEMENT_DESC *pDesc = pMesh->GetLayoutDescription();\n    if( pDesc )\n    {\n        pMesh->BindVertexShaderLayout(pMaterial, mpMaterial[ii]);\n    }\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTModelDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTMODELDX11_H__\n#define __CPUTMODELDX11_H__\n\n#include \"CPUTModel.h\"\n#include \"CPUT_DX11.h\"\n\nclass CPUTMeshDX11;\nclass CPUTRenderParametersDX;\nclass CPUTMaterialDX11;\n\n//--------------------------------------------------------------------------------------\nstruct CPUTModelConstantBuffer\n{\n    XMMATRIX  World;\n\tXMMATRIX  WorldViewProjection;\n    XMMATRIX  InverseWorld;\n    XMVECTOR  LightDirection;\n    XMVECTOR  EyePosition;\n    XMMATRIX  LightWorldViewProjection;\n    XMMATRIX  ViewProjection;\n    XMVECTOR  BoundingBoxCenterWorldSpace;\n    XMVECTOR  BoundingBoxHalfWorldSpace;\n    XMVECTOR  BoundingBoxCenterObjectSpace;\n    XMVECTOR  BoundingBoxHalfObjectSpace;\n};\n\n//--------------------------------------------------------------------------------------\nclass CPUTModelDX11 : public CPUTModel\n{\nprotected:\n    ID3D11Buffer      *mpModelConstantBuffer;\n\n    // Destructor is not public.  Must release instead of delete.\n    ~CPUTModelDX11(){ SAFE_RELEASE(mpModelConstantBuffer); }\n\npublic:\n    CPUTModelDX11() :\n        mpModelConstantBuffer(NULL)\n    {}\n\n    CPUTMeshDX11 *GetMesh(const UINT index) const;\n    CPUTResult    LoadModel(CPUTConfigBlock *pBlock, int *pParentID, CPUTModel *pMasterModel=NULL);\n    void          SetRenderStates(CPUTRenderParameters &renderParams);\n    void          Render(CPUTRenderParameters &renderParams);\n    void          RenderShadow(CPUTRenderParameters &renderParams);\n    void          SetMaterial(UINT ii, CPUTMaterial *pMaterial);\n    void          DrawBoundingBox(CPUTRenderParameters &renderParams);\n};\n\n\n#endif // __CPUTMODELDX11_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTNullNode.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTNullNode.h\"\n#include \"CPUTOSServicesWin.h\" // FOR TCHAR\n#include \"CPUTConfigBlock.h\"\n#include \"CPUTAssetLibrary.h\"\n\n// Parse the information in the .set file for this type of node\n//-----------------------------------------------------------------------------\nCPUTResult CPUTNullNode::LoadNullNode(CPUTConfigBlock *pBlock, int *pParentID)\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    // set the null/group node name\n    mName = pBlock->GetValueByName(_L(\"name\"))->ValueAsString();\n\n    // get the parent ID\n    *pParentID = pBlock->GetValueByName(_L(\"parent\"))->ValueAsInt();\n\n    LoadParentMatrixFromParameterBlock( pBlock );\n\n    return result;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTNullNode.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTNULLNODE_H__\n#define __CPUTNULLNODE_H__\n\n#include \"CPUTRenderNode.h\"\n\nclass CPUTConfigBlock;\n\nclass CPUTNullNode:public CPUTRenderNode\n{\npublic:\n    CPUTNullNode(){}\n    ~CPUTNullNode(){}\n    CPUTResult LoadNullNode(CPUTConfigBlock *pBlock, int *pParentID);\n};\n\n#endif // #ifndef __CPUTNULLNODE_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTOSServicesWin.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTOSServicesWin.h\"\n#include \"tchar.h\"\nCPUTOSServices* CPUTOSServices::mpOSServices = NULL;\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTOSServices::CPUTOSServices():mhWnd(NULL)\n{\n    //mCPUTMediaDirectory.clear();\n    mCPUTResourceDirectory.clear();\n}\n\n// Destructor\n//-----------------------------------------------------------------------------\nCPUTOSServices::~CPUTOSServices()\n{\n    //mCPUTMediaDirectory.clear();\n    mCPUTResourceDirectory.clear();\n}\n\n// Singleton GetOSServices()\n//-----------------------------------------------------------------------------\nCPUTOSServices* CPUTOSServices::GetOSServices()\n{\n    if(NULL==mpOSServices)\n        mpOSServices = new CPUTOSServices();\n    return mpOSServices;\n}\n\n// Singleton destroyer\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::DeleteOSServices()\n{\n    if(mpOSServices)\n    {\n        delete mpOSServices;\n        mpOSServices = NULL;\n    }\n\n    return CPUT_SUCCESS;\n}\n\n// Get the OS window dimensions\n//-----------------------------------------------------------------------------\nvoid CPUTOSServices::GetClientDimensions(int *pX, int *pY, int *pWidth, int *pHeight)\n{\n    RECT windowRect;\n    if(0==GetClientRect(mhWnd, &windowRect))\n    {\n        return;\n    }\n    *pX      = windowRect.left;\n    *pY      = windowRect.top;\n    *pWidth  = windowRect.right - windowRect.left;\n    *pHeight = windowRect.bottom - windowRect.top;\n}\n\n// Get the OS window client area dimensions\n//-----------------------------------------------------------------------------\nvoid CPUTOSServices::GetClientDimensions(int *pWidth, int *pHeight)\n{\n    RECT windowRect;\n    if(0==GetClientRect(mhWnd, &windowRect))\n    {\n        return;\n    }\n    *pWidth  = windowRect.right - windowRect.left;\n    *pHeight = windowRect.bottom - windowRect.top;\n}\n\n// Get the desktop dimensions\n//-----------------------------------------------------------------------------\nvoid CPUTOSServices::GetDesktopDimensions(int *pWidth, int *pHeight)\n{\n    *pWidth  = GetSystemMetrics(SM_CXFULLSCREEN);  // alternate method: GetSystemMetrics(SM_CXSCREEN);\n    *pHeight = GetSystemMetrics(SM_CYFULLSCREEN);  // alternate method: GetSystemMetrics(SM_CYSCREEN);\n}\n\n\n// Returns true if the window is currently maximized\n//-----------------------------------------------------------------------------\nbool CPUTOSServices::IsWindowMaximized()\n{\n    WINDOWPLACEMENT WindowPlacement;\n    WindowPlacement.length = sizeof(WindowPlacement);\n    GetWindowPlacement(mhWnd,  &WindowPlacement);\n\n    if(SW_SHOWMAXIMIZED == WindowPlacement.showCmd)\n    {\n        return true;\n    }\n    \n    return false;\n}\n\n// Returns true if the window is currently minimized\n//-----------------------------------------------------------------------------\nbool CPUTOSServices::IsWindowMinimized()\n{\n    WINDOWPLACEMENT WindowPlacement;\n    WindowPlacement.length = sizeof(WindowPlacement);\n    GetWindowPlacement(mhWnd,  &WindowPlacement);\n\n    if(SW_SHOWMAXIMIZED == WindowPlacement.showCmd)\n    {\n        return true;\n    }\n    \n    return false;\n}\n\n// Returns true if the CPUT window is currently the 'focused' window on the \n// desktop\n//-----------------------------------------------------------------------------\nbool CPUTOSServices::DoesWindowHaveFocus()\n{\n    HWND hFocusedWindow = GetActiveWindow();\n    if(mhWnd == hFocusedWindow)\n    {\n        return true;\n    }\n    return false;\n}\n\n// Retrieves the current working directory\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::GetWorkingDirectory(cString *pPath)\n{\n    TCHAR pPathAsTchar[CPUT_MAX_PATH];\n    DWORD result = GetCurrentDirectory(CPUT_MAX_PATH, pPathAsTchar);\n    ASSERT( result, _L(\"GetCurrentDirectory returned 0.\") );\n    *pPath = pPathAsTchar;\n    return CPUT_SUCCESS;\n}\n\n// Sets the current working directory\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::SetWorkingDirectory(const cString &path)\n{\n    BOOL result = SetCurrentDirectory(path.c_str());\n    ASSERT( 0 != result, _L(\"Error setting current directory.\") );\n    return CPUT_SUCCESS;\n}\n\n// Gets the location of the executable's directory\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::GetExecutableDirectory(cString *pExecutableDir)\n{\n    TCHAR   pFilename[CPUT_MAX_PATH];\n    DWORD result = GetModuleFileName(NULL, pFilename, CPUT_MAX_PATH);\n    ASSERT( 0 != result, _L(\"Unable to get executable's working directory.\"));\n\n    // strip off the executable name+ext\n    cString ResolvedPathAndFilename;\n    ResolveAbsolutePathAndFilename(pFilename, &ResolvedPathAndFilename);\n    cString Drive, Dir, Filename, Ext;\n    SplitPathAndFilename(ResolvedPathAndFilename, &Drive, &Dir, &Filename, &Ext);\n\n    // store and return\n    *pExecutableDir = Drive + Dir;\n\n    return CPUT_SUCCESS;\n}\n\n// Split up the supplied path+fileName into its constituent parts\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::SplitPathAndFilename(const cString &sourceFilename, cString *pDrive, cString *pDir, cString *pFileName, cString *pExtension)\n{\n    TCHAR pSplitDrive[CPUT_MAX_PATH];\n    TCHAR pSplitDirs[CPUT_MAX_PATH];\n    TCHAR pSplitFile[CPUT_MAX_PATH];\n    TCHAR pSplitExt[CPUT_MAX_PATH];\n#if defined (UNICODE) || defined(_UNICODE)\n    #define SPLITPATH _wsplitpath_s\n#else\n    #define SPLITPATH _splitpath_s\n#endif\n    errno_t result = SPLITPATH(sourceFilename.c_str(), pSplitDrive, CPUT_MAX_PATH, pSplitDirs, CPUT_MAX_PATH, pSplitFile, CPUT_MAX_PATH, pSplitExt, CPUT_MAX_PATH);\n    ASSERT( 0 == result, _L(\"Error splitting path\") );\n\n    // return the items the user wants\n    *pDrive     = pSplitDrive;\n    *pDir       = pSplitDirs;\n    *pFileName  = pSplitFile;\n    *pExtension = pSplitExt;\n\n    return CPUT_SUCCESS;\n}\n\n// Takes a relative/full path+fileName and returns the absolute path with drive\n// letter, absolute path, fileName and extension of this file.\n// Truncates total path/file length to CPUT_MAX_PATH\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::ResolveAbsolutePathAndFilename(const cString &fileName, cString *pResolvedPathAndFilename)\n{\n    TCHAR pFullPathAndFilename[CPUT_MAX_PATH];\n    DWORD result = GetFullPathName(fileName.c_str(), CPUT_MAX_PATH, pFullPathAndFilename, NULL);\n    ASSERT( 0 != result, _L(\"Error getting full path name\") );\n    *pResolvedPathAndFilename = pFullPathAndFilename;\n\n    return CPUT_SUCCESS;\n}\n\n// Verifies that file exists at specified path\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::DoesFileExist(const cString &pathAndFilename)\n{\n    // check for file existence\n    // attempt to open it where they said it was\n    FILE *pFile = NULL;\n#if defined (UNICODE) || defined(_UNICODE)\n    errno_t err = _wfopen_s(&pFile, pathAndFilename.c_str(), _L(\"r\"));\n#else\n    errno_t err = fopen_s(&pFile, pathAndFilename.c_str(), _L(\"r\"));\n#endif\n    if(0 == err)\n    {\n        // yep - file exists\n        fclose(pFile);\n        return CPUT_SUCCESS;\n    }\n\n    // not found, translate the file error and return it\n    return TranslateFileError(err);\n}\n\n// Verifies that directory exists.\n// Returns success if the directory exists and is readable (failure may mean\n// it's busy or permissions denied on win32)\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::DoesDirectoryExist(const cString &path)\n{\n    DWORD fileAttribs;\n#if defined (UNICODE) || defined(_UNICODE)\n    fileAttribs = GetFileAttributesW(path.c_str());\n#else\n    fileAttribs = GetFileAttributesA(path.c_str());\n#endif\n    ASSERT( INVALID_FILE_ATTRIBUTES != fileAttribs, _L(\"Failed getting file attributes\") );\n    return CPUT_SUCCESS;\n}\n\n// Open a file and return file pointer to it\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::OpenFile(const cString &fileName, FILE **ppFilePointer)\n{\n#if defined (UNICODE) || defined(_UNICODE)\n    errno_t err = _wfopen_s(ppFilePointer, fileName.c_str(), _L(\"r\"));\n#else\n    errno_t err = fopen_s(ppFilePointer, fileName.c_str(), \"r\");\n#endif\n\n    return TranslateFileError(err);\n}\n\n// Read the entire contents of a file and return a pointer/size to it\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::ReadFileContents(const cString &fileName, UINT *pSizeInBytes, void **ppData)\n{\n    FILE *pFile = NULL;\n#if defined (UNICODE) || defined(_UNICODE)\n    errno_t err = _wfopen_s(&pFile, fileName.c_str(), _L(\"r\"));\n#else\n    errno_t err = fopen_s(&pFile, fileName.c_str(), \"r\");\n#endif\n    if(0 == err)\n    {\n        // get file size\n        fseek(pFile, 0, SEEK_END);\n\t    *pSizeInBytes = ftell(pFile);\n        fseek (pFile, 0, SEEK_SET);\n\n        // allocate buffer\n        *ppData = (void*) new char[*pSizeInBytes];\n        ASSERT( ppData, _L(\"Out of memory\") );\n\n        // read it all in\n        UINT numBytesRead = (UINT) fread(*ppData, sizeof(char), *pSizeInBytes, pFile);\n        ASSERT( numBytesRead == *pSizeInBytes, _L(\"File read byte count mismatch.\") );\n\n        // close and return\n        fclose(pFile);\n        return CPUT_SUCCESS;\n    }\n\n    // some kind of file error, translate the error code and return it\n    return TranslateFileError(err);\n}\n\n// Open the OS's 'open a file' dialog box\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::OpenFileDialog(const cString &filter, cString *pfileName)\n{\n    OPENFILENAME ofn;       // common dialog box structure\n    TCHAR szFile[260];       // buffer for file name\n\n    // Initialize OPENFILENAME\n    UNREFERENCED_PARAMETER(filter);\n    ZeroMemory(&ofn, sizeof(ofn));\n    ofn.lStructSize = sizeof(ofn);\n    ofn.hwndOwner = mhWnd;\n    ofn.lpstrFilter = _L(\"All\\0*.*\\0Text\\0*.TXT\\0\\0\");//Filter.c_str(); //\"All\\0*.*\\0Text\\0*.TXT\\0\";\n    ofn.lpstrFile = szFile;\n    // Set lpstrFile[0] to '\\0' so that GetOpenFileName does not\n    // use the contents of szFile to initialize itself.\n    ofn.lpstrFile[0] = '\\0';\n    ofn.nMaxFile = sizeof(szFile);\n    ofn.nFilterIndex = 1;\n    ofn.lpstrFileTitle = NULL;\n    ofn.nMaxFileTitle = 0;\n    ofn.lpstrInitialDir = NULL;\n    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;\n\n    if(0==GetOpenFileName(&ofn))\n    {\n        return CPUT_WARNING_CANCELED;\n    }\n\n    *pfileName = szFile;\n    return CPUT_SUCCESS;\n}\n\n// Open a system dialog box\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::OpenMessageBox(cString title, cString text)\n{\n\t::MessageBox(NULL, text.c_str(), title.c_str(), MB_OK);\n\n    return CPUT_SUCCESS;\n}\n\n// Returns whether the specified control key is pressed or not\n//-----------------------------------------------------------------------------\nbool CPUTOSServices::ControlKeyPressed(CPUTKey &key)\n{\n    int nVirtKey;\n\n    switch(key)\n    {\n    case KEY_LEFT_SHIFT:\n        nVirtKey = VK_LSHIFT;\n        break;\n    case KEY_RIGHT_SHIFT:\n        nVirtKey = VK_RSHIFT;\n        break;\n    case KEY_LEFT_CTRL:\n        nVirtKey = VK_LCONTROL;\n        break;\n    case KEY_RIGHT_CTRL:\n        nVirtKey = VK_RCONTROL;\n        break;\n    case KEY_LEFT_ALT:\n        nVirtKey = VK_LMENU;\n        break;\n    case KEY_RIGHT_ALT:\n        nVirtKey = VK_RMENU;\n        break;\n    default:\n        return false;\n    };\n\n    SHORT result = GetKeyState(nVirtKey);\n\n    // return true/false if handled\n    return (result & 0x8000)!=0;\n}\n\n// mouse\n// this function 'captures' the mouse and makes it ONLY available to this app\n// User cannot click on any other app until you call ReleaseMouse, so use this\n// carefully\n//-----------------------------------------------------------------------------\nvoid CPUTOSServices::CaptureMouse()\n{\n    SetCapture(mhWnd);\n}\n\n// Releases a captured mouse\n//-----------------------------------------------------------------------------\nvoid CPUTOSServices::ReleaseMouse()\n{\n    ReleaseCapture();\n}\n\n// outputs a string to the debug out.\n// In Visual Studio - this is the Output pane\n//-----------------------------------------------------------------------------\nvoid CPUTOSServices::OutputConsoleString(cString &OutputString)\n{\n    OutputDebugString(OutputString.c_str());\n}\n\n// Did file open error indicate a returnable file/system problem? (or just not found)\n//-----------------------------------------------------------------------------\nbool CPUTOSServices::FileFoundButWithError(CPUTResult result)\n{\n    bool IsError = false;\n\n    // Is the result a file error code?\n    switch(result)\n    {\n    case CPUT_ERROR_FILE_IO_ERROR:\n    case CPUT_ERROR_FILE_NOT_ENOUGH_MEMORY:\n    case CPUT_ERROR_FILE_PERMISSION_DENIED:\n    case CPUT_ERROR_FILE_DEVICE_OR_RESOURCE_BUSY:\n    case CPUT_ERROR_FILE_IS_A_DIRECTORY:\n    case CPUT_ERROR_FILE_TOO_MANY_OPEN_FILES:\n    case CPUT_ERROR_FILE_TOO_LARGE:\n    case CPUT_ERROR_FILE_FILENAME_TOO_LONG:\n        IsError = true;\n        break;\n\n    default:\n        // nope - good to go\n        IsError = false;\n    }\n\n    return IsError;\n}\n\n// Translate a file operation error code\n//-----------------------------------------------------------------------------\nCPUTResult CPUTOSServices::TranslateFileError(errno_t err)\n{\n    if(0==err)\n    {\n        return CPUT_SUCCESS;\n    }\n\n    // see: http://msdn.microsoft.com/en-us/library/t3ayayh1.aspx\n    // for list of all error codes\n    CPUTResult result = CPUT_ERROR_FILE_ERROR;\n\n    switch(err)\n    {\n    case ENOENT: result = CPUT_ERROR_FILE_NOT_FOUND;                 break; // file/dir not found\n    case EIO:    result = CPUT_ERROR_FILE_IO_ERROR;                  break;\n    case ENXIO:  result = CPUT_ERROR_FILE_NO_SUCH_DEVICE_OR_ADDRESS; break;\n    case EBADF:  result = CPUT_ERROR_FILE_BAD_FILE_NUMBER;           break;\n    case ENOMEM: result = CPUT_ERROR_FILE_NOT_ENOUGH_MEMORY;         break;\n    case EACCES: result = CPUT_ERROR_FILE_PERMISSION_DENIED;         break;\n    case EBUSY:  result = CPUT_ERROR_FILE_DEVICE_OR_RESOURCE_BUSY;   break;\n    case EEXIST: result = CPUT_ERROR_FILE_EXISTS;                    break;\n    case EISDIR: result = CPUT_ERROR_FILE_IS_A_DIRECTORY;            break;\n    case ENFILE: result = CPUT_ERROR_FILE_TOO_MANY_OPEN_FILES;       break;\n    case EFBIG:  result = CPUT_ERROR_FILE_TOO_LARGE;                 break;\n    case ENOSPC: result = CPUT_ERROR_FILE_DEVICE_FULL;               break;\n    case ENAMETOOLONG: result = CPUT_ERROR_FILE_FILENAME_TOO_LONG;   break;\n    default:\n        // unknown file error type - assert so you can add it to the list\n        ASSERT(0,_L(\"Unkown error code\"));\n    }\n    return result;\n}\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n// Allows you to get the global/domain-wide instrumentation markers needed\n// to mark events in GPA\n//-----------------------------------------------------------------------------\nvoid CPUTOSServices::GetInstrumentationPointers(__itt_domain **ppGPADomain, CPUT_GPA_INSTRUMENTATION_STRINGS eString, __itt_string_handle **ppGPAStringHandle)\n{\n    *ppGPADomain = mpGPADomain;\n    *ppGPAStringHandle = mppGPAStringHandles[eString];\n}\n\n// Set the global/domain-wide instrumtation markers needed to mark events\n// in GPA\n//-----------------------------------------------------------------------------\nvoid CPUTOSServices::SetInstrumentationPointers(__itt_domain *pGPADomain, CPUT_GPA_INSTRUMENTATION_STRINGS eString, __itt_string_handle *pGPAStringHandle)\n{\n    mpGPADomain = pGPADomain;\n    mppGPAStringHandles[eString] = pGPAStringHandle;\n}\n#endif\n"
  },
  {
    "path": "CPUT/CPUT/CPUTOSServicesWin.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTOSServicesWin_H__\n#define __CPUTOSServicesWin_H__\n\n\n\n#include \"CPUT.h\"\n\n// OS includes\n#include <windows.h>\n#include <errno.h>  // file open error codes\n#include <string>   // wstring\n\n\n\nclass CPUTOSServices\n{\npublic:\n    static CPUTOSServices* GetOSServices();\n    static CPUTResult DeleteOSServices();\n\n    // screen/window dimensions\n    void GetClientDimensions( int *pWidth, int *pHeight);\n    void GetClientDimensions( int *pX, int *pY, int *pWidth, int *pHeight);\n    void GetDesktopDimensions(int *pWidth, int *pHeight);\n    bool IsWindowMaximized();\n    bool IsWindowMinimized();\n    bool DoesWindowHaveFocus();\n\n    // Mouse capture - 'binds'/releases all mouse input to this window\n    void CaptureMouse();\n    void ReleaseMouse();\n    \n\n    //Working directory manipulation\n    CPUTResult GetWorkingDirectory(cString *pPath);\n    CPUTResult SetWorkingDirectory(const cString &path);\n    CPUTResult GetExecutableDirectory(cString *pExecutableDir);\n\n    // Path helpers\n    CPUTResult ResolveAbsolutePathAndFilename(const cString &fileName, cString *pResolvedPathAndFilename);\n    CPUTResult SplitPathAndFilename(const cString &sourceFilename, cString *pDrive, cString *pDir, cString *pfileName, cString *pExtension);\n\n    // file handling\n    CPUTResult DoesFileExist(const cString &pathAndFilename);\n    CPUTResult DoesDirectoryExist(const cString &path);\n    CPUTResult OpenFile(const cString &fileName, FILE **pFilePointer);\n    CPUTResult ReadFileContents(const cString &fileName, UINT *psizeInBytes, void **ppData);\n\n    // File dialog box\n    CPUTResult OpenFileDialog(const cString &filter, cString *pfileName);\n\n    // Informational Message box\n    CPUTResult OpenMessageBox(cString title, cString text);\n\n    // error handling\n    inline void Assert(bool bCondition) {assert(bCondition);}\n    void OutputConsoleString(cString &outputString);\n    CPUTResult TranslateFileError(errno_t err);\n\n    // hwnd setup\n    inline void SethWnd(const HWND hWnd) { mhWnd = hWnd; };\n    inline void GetWindowHandle(HWND *phWnd) { *phWnd = mhWnd; };\n\n    // special keys\n    bool ControlKeyPressed(CPUTKey &key);\n\n\n\nprivate:\n    CPUTOSServices();\n     ~CPUTOSServices();\n    static CPUTOSServices *mpOSServices;   // singleton object\n    HWND                   mhWnd;\n    cString                mCPUTResourceDirectory;\n    bool                   FileFoundButWithError(CPUTResult result);\n\n#ifdef CPUT_GPA_INSTRUMENTATION\npublic:\n    // GPA instrumentation (only available in Profile build)\n    void GetInstrumentationPointers(__itt_domain **ppGPADomain, CPUT_GPA_INSTRUMENTATION_STRINGS eString, __itt_string_handle **ppGPAStringHandle);\n    void SetInstrumentationPointers(__itt_domain *pGPADomain, CPUT_GPA_INSTRUMENTATION_STRINGS eString, __itt_string_handle *pGPAStringHandle);\n\nprivate:\n    // GPA instrumentation member variables\n    __itt_domain *mpGPADomain;\n    __itt_string_handle *mppGPAStringHandles[GPA_HANDLE_STRING_ENUMS_SIZE];\n#endif\n\n};\n#endif // __CPUTOSServicesWin_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTPerfTaskMarker.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTPerfTaskMarker.h\"\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n// constructor\n// automatically creates an ITT begin marker at the start of this task\n//-----------------------------------------------------------------------------\nCPUTPerfTaskMarker::CPUTPerfTaskMarker(DWORD color, wchar_t *pString)\n{\n    D3DPERF_BeginEvent(color, pString);\n}\n\n// destructor\n// when class goes out of scope, this marker will automatically be called\n//-----------------------------------------------------------------------------\nCPUTPerfTaskMarker::~CPUTPerfTaskMarker()\n{\n    D3DPERF_EndEvent();\n}\n#else\n    // This is a bit of a hack to get the compiler not to complain about this being an empty file\n    // during the compilation in any mode that doesn't have CPUT_GPA_INSTRUMENTATION defined\n    #define CPUTPerfTaskMarkerNotEmpty()   namespace { char CPUTPerfTaskMarkerDummy##__LINE__; }\n    CPUTPerfTaskMarkerNotEmpty();\n#endif\n"
  },
  {
    "path": "CPUT/CPUT/CPUTPerfTaskMarker.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTPERFTASKMARKER_H__\n#define __CPUTPERFTASKMARKER_H__\n\n\n\n#include \"CPUT.h\"\n\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n\n// GPA instrumentation helper class - only available in profile build\n// Allows you to easily add 'task markers' to certain events\n//-----------------------------------------------------------------------------\nclass CPUTPerfTaskMarker\n{\npublic:\n    CPUTPerfTaskMarker(DWORD color, wchar_t *pString);\n    ~CPUTPerfTaskMarker();\nprivate:\n\n};\n#endif\n\n#endif // #ifndef __CPUTPERFTASKMARKER_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTPixelShaderDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTPixelShaderDX11.h\"\n#include \"CPUTAssetLibraryDX11.h\"\n#include \"D3DCompiler.h\"\n\nCPUTPixelShaderDX11 *CPUTPixelShaderDX11::CreatePixelShader(\n    const cString      &name,\n    ID3D11Device       *pD3dDevice,\n    const cString      &shaderMain,\n    const cString      &shaderProfile\n)\n{\n    ID3DBlob           *pCompiledBlob = NULL;\n    ID3D11PixelShader  *pNewPixelShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromFile(name, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling pixel shader:\\n\\n\") );\n\n    // Create the pixel shader\n    // TODO: Move to pixel shader class\n    HRESULT hr = pD3dDevice->CreatePixelShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewPixelShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating pixel shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetPixelShader \")+name;\n    // CPUTSetDebugName(pNewPixelShader, DebugName);\n\n    CPUTPixelShaderDX11 *pNewCPUTPixelShader = new CPUTPixelShaderDX11( pNewPixelShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddPixelShader(name + shaderMain + shaderProfile, pNewCPUTPixelShader);\n    // pNewCPUTPixelShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTPixelShader;\n}\n\n//--------------------------------------------------------------------------------------\nCPUTPixelShaderDX11 *CPUTPixelShaderDX11::CreatePixelShaderFromMemory(\n    const cString      &name,\n    ID3D11Device       *pD3dDevice,\n    const cString      &shaderMain,\n    const cString      &shaderProfile,\n    const char         *pShaderSource\n)\n{\n    ID3DBlob           *pCompiledBlob = NULL;\n    ID3D11PixelShader  *pNewPixelShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromMemory(pShaderSource, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling pixel shader:\\n\\n\") );\n\n    // Create the pixel shader\n    // TODO: Move to pixel shader class\n    HRESULT hr = pD3dDevice->CreatePixelShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewPixelShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating pixel shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetPixelShader \")+name;\n    // CPUTSetDebugName(pNewPixelShader, DebugName);\n\n    CPUTPixelShaderDX11 *pNewCPUTPixelShader = new CPUTPixelShaderDX11( pNewPixelShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddPixelShader(name + shaderMain + shaderProfile, pNewCPUTPixelShader);\n    // pNewCPUTPixelShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTPixelShader;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTPixelShaderDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTPIXELSHADERDX11_H\n#define _CPUTPIXELSHADERDX11_H\n\n#include \"CPUT.h\"\n#include \"CPUTShaderDX11.h\"\n\nclass CPUTPixelShaderDX11 : public CPUTShaderDX11\n{\nprotected:\n    ID3D11PixelShader *mpPixelShader;\n\n     // Destructor is not public.  Must release instead of delete.\n    ~CPUTPixelShaderDX11(){ SAFE_RELEASE(mpPixelShader); }\n\npublic:\n    static CPUTPixelShaderDX11 *CreatePixelShader(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile\n    );\n\n    static CPUTPixelShaderDX11 *CreatePixelShaderFromMemory(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile,\n        const char           *pShaderSource\n    );\n\n    CPUTPixelShaderDX11() : mpPixelShader(NULL), CPUTShaderDX11(NULL) {}\n    CPUTPixelShaderDX11(ID3D11PixelShader *pD3D11PixelShader, ID3DBlob *pBlob) : mpPixelShader(pD3D11PixelShader), CPUTShaderDX11(pBlob) {}\n    ID3D11PixelShader *GetNativePixelShader() { return mpPixelShader; }\n};\n\n#endif //_CPUTPIXELSHADER_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTPostProcess.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUT_DX11.h\"\n#include \"CPUTPostProcess.h\"\n#include \"CPUTRenderTarget.h\"\n#include \"CPUTAssetLibrary.h\"\n#include \"CPUTMaterial.h\"\n#include \"CPUTSprite.h\"\n\n//-----------------------------------------\nCPUTPostProcess::~CPUTPostProcess() {\n    SAFE_DELETE( mpFullScreenSprite );\n\n    SAFE_RELEASE( mpMaterialComposite );\n    SAFE_RELEASE( mpMaterialBlurVertical );\n    SAFE_RELEASE( mpMaterialBlurHorizontal );\n    SAFE_RELEASE( mpMaterialDownSampleLogLum );\n    SAFE_RELEASE( mpMaterialDownSample4x4Alpha );\n    SAFE_RELEASE( mpMaterialDownSample4x4 );\n    SAFE_RELEASE( mpMaterialDownSampleBackBuffer4x4 );\n    SAFE_RELEASE( mpMaterialSpriteNoAlpha );\n\n    SAFE_DELETE(mpRT1x1 );\n    SAFE_DELETE(mpRT4x4 );\n    SAFE_DELETE(mpRT64x64 );\n    SAFE_DELETE(mpRTDownSample4x4PingPong );\n    SAFE_DELETE(mpRTDownSample4x4 );\n    // SAFE_DELETE(mpRTSourceRenderTarget ); // We don't allocate this.  Don't delete it.\n}\n\n//-----------------------------------------\nvoid CPUTPostProcess::CreatePostProcess(\n    CPUTRenderTargetColor *pSourceRenderTarget\n){\n    mpRTSourceRenderTarget    = pSourceRenderTarget;\n\n    DXGI_FORMAT sourceFormat  = mpRTSourceRenderTarget->GetColorFormat();\n    UINT sourceWidth          = mpRTSourceRenderTarget->GetWidth();\n    UINT sourceHeight         = mpRTSourceRenderTarget->GetHeight();\n\n    mpRTDownSample4x4         = new CPUTRenderTargetColor();\n    mpRTDownSample4x4PingPong = new CPUTRenderTargetColor();\n    mpRT64x64                 = new CPUTRenderTargetColor();\n    mpRT4x4                   = new CPUTRenderTargetColor();\n    mpRT1x1                   = new CPUTRenderTargetColor();\n\n    mpRTDownSample4x4->CreateRenderTarget(         _L(\"$PostProcessDownsample4x4\"),         sourceWidth/4, sourceHeight/4,          sourceFormat );\n    mpRTDownSample4x4PingPong->CreateRenderTarget( _L(\"$PostProcessDownsample4x4PingPong\"), sourceWidth/4, sourceHeight/4,          sourceFormat );\n    mpRT64x64->CreateRenderTarget(                 _L(\"$PostProcessRT64x64\"),                          64,             64, DXGI_FORMAT_R32_FLOAT ); \n    mpRT4x4->CreateRenderTarget(                   _L(\"$PostProcessRT4x4\"),                             8,              8, DXGI_FORMAT_R32_FLOAT ); \n    mpRT1x1->CreateRenderTarget(                   _L(\"$PostProcessRT1x1\"),                             1,              1, DXGI_FORMAT_R32_FLOAT );\n\n    CPUTAssetLibrary *pLibrary = CPUTAssetLibrary::GetAssetLibrary();\n    mpMaterialDownSampleBackBuffer4x4 = pLibrary->GetMaterial(_L(\"PostProcess/DownSampleBackBuffer4x4\"));\n    mpMaterialDownSample4x4           = pLibrary->GetMaterial(_L(\"PostProcess/DownSample4x4\"));\n    mpMaterialDownSample4x4Alpha      = pLibrary->GetMaterial(_L(\"PostProcess/DownSample4x4Alpha\"));\n    mpMaterialDownSampleLogLum        = pLibrary->GetMaterial(_L(\"PostProcess/DownSampleLogLum\"));\n    mpMaterialBlurHorizontal          = pLibrary->GetMaterial(_L(\"PostProcess/BlurHorizontal\"));\n    mpMaterialBlurVertical            = pLibrary->GetMaterial(_L(\"PostProcess/BlurVertical\"));\n    mpMaterialComposite               = pLibrary->GetMaterial(_L(\"PostProcess/Composite\"));\n    mpMaterialSpriteNoAlpha           = pLibrary->GetMaterial(_L(\"PostProcess/Sprite\"));\n\n    mpFullScreenSprite = new CPUTSprite();\n    mpFullScreenSprite->CreateSprite( -1.0f, -1.0f, 2.0f, 2.0f, _L(\"Sprite\") );\n}\n\nUINT gPostProcessingMode = 0;\n//-----------------------------------------\nvoid CPUTPostProcess::PerformPostProcess( CPUTRenderParameters &renderParams )\n{\n    mpRTDownSample4x4->SetRenderTarget( renderParams);\n    mpFullScreenSprite->DrawSprite( renderParams, *mpMaterialDownSampleBackBuffer4x4 );\n    mpRTDownSample4x4->RestoreRenderTarget( renderParams );\n\n    // Compute average of log of luminance by downsampling log to 64x64, then 4x4, then 1x1\n    mpRT64x64->SetRenderTarget(renderParams);\n    mpFullScreenSprite->DrawSprite(renderParams, *mpMaterialDownSampleLogLum);\n    mpRT64x64->RestoreRenderTarget( renderParams );\n\n    mpRT4x4->SetRenderTarget(renderParams);\n    mpFullScreenSprite->DrawSprite(renderParams, *mpMaterialDownSample4x4);\n    mpRT4x4->RestoreRenderTarget( renderParams );\n\n    mpRT1x1->SetRenderTarget(renderParams);\n    mpFullScreenSprite->DrawSprite( renderParams, *mpMaterialDownSample4x4Alpha ); // Partially blend with previous to smooth result over time\n    mpRT1x1->RestoreRenderTarget( renderParams );\n\n    // Better blur for bloom\n    UINT ii;\n    UINT numBlurs = 1; // TODO: expose as a config param\n    for( ii=0; ii<numBlurs; ii++ )\n    {\n        mpRTDownSample4x4PingPong->SetRenderTarget(renderParams);\n        mpFullScreenSprite->DrawSprite( renderParams, *mpMaterialBlurHorizontal );\n        mpRTDownSample4x4PingPong->RestoreRenderTarget( renderParams );\n\n        mpRTDownSample4x4->SetRenderTarget( renderParams);\n        mpFullScreenSprite->DrawSprite( renderParams, *mpMaterialBlurVertical );\n        mpRTDownSample4x4->RestoreRenderTarget( renderParams );\n    }\n    mpFullScreenSprite->DrawSprite(renderParams, *mpMaterialComposite);\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTPostProcess.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTPOSTPROCESS_H\n#define _CPUTPOSTPROCESS_H\n\nclass CPUTRenderTargetColor;\nclass CPUTMaterial;\nclass CPUTRenderParameters;\nclass CPUTSprite;\n\nclass CPUTPostProcess\n{\nprotected:\n    CPUTRenderTargetColor *mpRTSourceRenderTarget;\n    CPUTRenderTargetColor *mpRTDownSample4x4;\n    CPUTRenderTargetColor *mpRTDownSample4x4PingPong;\n    CPUTRenderTargetColor *mpRT64x64;\n    CPUTRenderTargetColor *mpRT4x4;\n    CPUTRenderTargetColor *mpRT1x1;\n\n    CPUTMaterial *mpMaterialSpriteNoAlpha;\n    CPUTMaterial *mpMaterialDownSampleBackBuffer4x4;\n    CPUTMaterial *mpMaterialDownSample4x4;\n    CPUTMaterial *mpMaterialDownSample4x4Alpha;\n    CPUTMaterial *mpMaterialDownSampleLogLum;\n    CPUTMaterial *mpMaterialBlurHorizontal;\n    CPUTMaterial *mpMaterialBlurVertical;\n    CPUTMaterial *mpMaterialComposite;\n\n    CPUTSprite   *mpFullScreenSprite;\n\npublic:\n    CPUTPostProcess() :\n        mpRTSourceRenderTarget(NULL),\n        mpRTDownSample4x4(NULL),\n        mpRTDownSample4x4PingPong(NULL),\n        mpRT64x64(NULL),\n        mpRT4x4(NULL),\n        mpRT1x1(NULL),\n        mpMaterialSpriteNoAlpha(NULL),\n        mpMaterialDownSampleBackBuffer4x4(NULL),\n        mpMaterialDownSample4x4(NULL),\n        mpMaterialDownSample4x4Alpha(NULL),\n        mpMaterialDownSampleLogLum(NULL),\n        mpMaterialBlurHorizontal(NULL),\n        mpMaterialBlurVertical(NULL),\n        mpMaterialComposite(NULL),\n        mpFullScreenSprite(NULL)\n    {}\n    ~CPUTPostProcess();\n\n    void CreatePostProcess( CPUTRenderTargetColor *pSourceRenderTarget );\n    void PerformPostProcess(CPUTRenderParameters &renderParams);\n};\n\n#endif // _CPUTPOSTPROCESS_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRefCount.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTREFCOUNT_H__\n#define __CPUTREFCOUNT_H__\n\n#include \"CPUT.h\"\n\n// Reference counting class\n//-----------------------------------------------------------------------------\nclass CPUTRefCount\n{\nprivate:\n    mutable UINT mRefCount;\n\nprotected:\n    virtual ~CPUTRefCount(){} // Destructor is not public.  Must release instead of delete.\n\npublic:\n    CPUTRefCount():mRefCount(1){}\n    int AddRef() const { return ++mRefCount; }\n    int GetRefCount() const { return mRefCount; }\n    int Release() const\n    {\n        UINT u = --mRefCount;\n        if(0==mRefCount)\n        {\n            delete this;\n        }\n        return u;\n    }\n};\n\n#endif // __CPUTREFCOUNT_H__\n\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderNode.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTRenderNode.h\"\n\n#include \"CPUTOSServicesWin.h\" // for OutputDebugString();\n\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTRenderNode::CPUTRenderNode():\n    mpParent(NULL),\n    mpChild(NULL),\n    mpSibling(NULL)\n{\n    // set transform to identity\n    mWorldMatrix  = float4x4Identity();\n    mParentMatrix = float4x4Identity();\n\n    // always create with everything dirty\n    mWorldMatrixDirty = true;\n}\n\n// Destructor\n//-----------------------------------------------------------------------------\nCPUTRenderNode::~CPUTRenderNode()\n{\n    SAFE_RELEASE(mpParent);\n    SAFE_RELEASE(mpChild);\n    SAFE_RELEASE(mpSibling);\n}\n\n//-----------------------------------------------------------------------------\nint CPUTRenderNode::ReleaseRecursive()\n{\n// #define OUTPUT_DEBUG_INFO\n#ifdef OUTPUT_DEBUG_INFO\n    char pRefCountString[64];\n    sprintf_s( pRefCountString, 64, \"(%d):\", GetRefCount()-1 );\n    OutputDebugStringA( pRefCountString );\n    cString msg = GetName() + _L(\"\\n\");\n    OutputDebugString( msg.c_str() );\n\n    if( mpParent )\n    {\n        OutputDebugString( _L(\"Parent: \") );\n        sprintf_s( pRefCountString, 64, \"(%d):\", mpParent->GetRefCount()-1  );\n        OutputDebugStringA( pRefCountString );\n        cString msg =  (mpParent ? mpParent->GetName() : _L(\"NULL\\n\")) + _L(\"\\n\");\n        OutputDebugString( msg.c_str() );\n    }\n#endif\n    // Release the parent.  Note: we don't want to recursively release it, or it would release us = infinite loop.\n    SAFE_RELEASE(mpParent);\n\n    // Recursively release our children and siblings\n    if( mpChild )\n    {\n#ifdef OUTPUT_DEBUG_INFO\n        OutputDebugString( _L(\"Child\") ); \n#endif\n        if( !mpChild->ReleaseRecursive() )\n        {\n            mpChild = NULL;\n        }\n    }\n    if( mpSibling )\n    {\n#ifdef OUTPUT_DEBUG_INFO\n        OutputDebugString( _L(\"Sibling:\") );\n#endif\n        int refCount = mpSibling->ReleaseRecursive();\n        if( !refCount )\n        {\n            mpSibling = NULL;\n        }\n    }\n    return CPUTRefCount::Release();\n}\n\n// parent/child/sibling\n//-----------------------------------------------------------------------------\nvoid CPUTRenderNode::SetParent(CPUTRenderNode *pParent)\n{\n    SAFE_RELEASE(mpParent);\n    if(NULL!=pParent)\n    {\n        pParent->AddRef();\n    }\n    mpParent = pParent;\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTRenderNode::AddChild(CPUTRenderNode *pNode )\n{\n    ASSERT( NULL != pNode, _L(\"Can't add NULL node.\") );\n    if( mpChild )\n    {\n        mpChild->AddSibling( pNode );\n    }\n    else\n    {\n        pNode->AddRef();\n        mpChild = pNode;\n    }\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTRenderNode::AddSibling(CPUTRenderNode *pNode )\n{\n    ASSERT( NULL != pNode, _L(\"Can't add NULL node.\") );\n\n    if( mpSibling )\n    {\n        mpSibling->AddSibling( pNode );\n    }\n    else\n    {\n        mpSibling = pNode;\n        pNode->AddRef();\n    }\n}\n\n// Return the model's cumulative transform\n//-----------------------------------------------------------------------------\nfloat4x4* CPUTRenderNode::GetWorldMatrix()\n{\n    if(mWorldMatrixDirty)\n    {\n        if(NULL!=mpParent)\n        {\n            float4x4 *pParentWorldMatrix = mpParent->GetWorldMatrix();\n            mWorldMatrix = mParentMatrix * *pParentWorldMatrix;\n        }\n        else\n        {\n            mWorldMatrix = mParentMatrix;\n        }\n       mWorldMatrixDirty = false;\n    }\n\n    // copy it\n    return &mWorldMatrix;\n}\n\n// Recursively visit all sub-nodes in breadth-first mode and mark their\n// cumulative transforms as dirty\n//-----------------------------------------------------------------------------\nvoid CPUTRenderNode::MarkDirty()\n{\n    mWorldMatrixDirty = true;\n\n    if(mpSibling)\n    {\n        mpSibling->MarkDirty();\n    }\n\n    if(mpChild)\n    {\n        mpChild->MarkDirty();\n    }\n}\n\n// Update - recursively visit all sub-nodes in breadth-first mode\n// Likely used for animation with a frame# or timestamp passed in\n// so that the update routine would calculate the new transforms\n// and called before Render() function\n//-----------------------------------------------------------------------------\nvoid CPUTRenderNode::UpdateRecursive( float deltaSeconds )\n{\n    // TODO: Need to Update this node first.\n    Update(deltaSeconds);\n\n    if(mpSibling)\n    {\n        mpSibling->UpdateRecursive(deltaSeconds);\n    }\n    if(mpChild)\n    {\n        mpChild->UpdateRecursive(deltaSeconds);\n    }\n}\n\n// RenderRecursive - recursively visit all sub-nodes in breadth-first mode\n//-----------------------------------------------------------------------------\nvoid CPUTRenderNode::RenderRecursive(CPUTRenderParameters &renderParams)\n{\n    Render(renderParams);\n\n    if(mpChild)\n    {\n        mpChild->RenderRecursive(renderParams);\n        CPUTRenderNode *pNode = mpChild->GetSibling();\n        while(pNode)\n        {\n            pNode->RenderRecursive(renderParams);\n            pNode = pNode->GetSibling();\n        }\n    }\n}\n\n// RenderRecursive - recursively visit all sub-nodes in breadth-first mode\n//-----------------------------------------------------------------------------\nvoid CPUTRenderNode::RenderShadowRecursive(CPUTRenderParameters &renderParams)\n{\n    RenderShadow(renderParams);\n\n    if(mpChild)\n    {\n        mpChild->RenderShadowRecursive(renderParams);\n        CPUTRenderNode *pNode = mpChild->GetSibling();\n        while(pNode)\n        {\n            pNode->RenderShadowRecursive(renderParams);\n            pNode = pNode->GetSibling();\n        }\n    }\n}\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderNode.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTRENDERNODE_H__\n#define __CPUTRENDERNODE_H__\n\n#include \"CPUTRenderParams.h\"\n#include \"CPUTRefCount.h\"\n#include \"CPUTMath.h\"\n#include \"CPUTConfigBlock.h\"\n\n// forward declarations\nclass CPUTCamera;\n\nclass CPUTRenderNode : public CPUTRefCount\n{\nprotected:\n    cString             mName;\n    CPUTRenderNode     *mpParent;\n    CPUTRenderNode     *mpChild;\n    CPUTRenderNode     *mpSibling;\n    bool                mWorldMatrixDirty;\n    float4x4            mWorldMatrix; // transform of this object combined with it's parent(s) transform(s)\n    float4x4            mParentMatrix;   // transform of this object relative to it's parent\n    cString             mPrefix;\n    ~CPUTRenderNode(); // Destructor is not public.  Must release instead of delete.\n\npublic:\n    CPUTRenderNode();\n\n    void Scale(float xx, float yy, float zz)\n    {\n        float4x4 scale(\n              xx, 0.0f, 0.0f, 0.0f,\n            0.0f,   yy, 0.0f, 0.0f,\n            0.0f, 0.0f,   zz, 0.0f,\n            0.0f, 0.0f, 0.0f,    1\n        );\n        mParentMatrix = mParentMatrix * scale;\n        MarkDirty();\n    }\n    void Scale(float xx)\n    {\n        float4x4 scale(\n           xx, 0.0f, 0.0f, 0.0f,\n         0.0f,   xx, 0.0f, 0.0f,\n         0.0f, 0.0f,   xx, 0.0f,\n         0.0f, 0.0f, 0.0f,    1\n        );\n        mParentMatrix = mParentMatrix * scale;\n        MarkDirty();\n    }\n    void SetPosition(float x, float y, float z)\n    {\n        mParentMatrix.r3.x = x;\n        mParentMatrix.r3.y = y;\n        mParentMatrix.r3.z = z;\n        MarkDirty();\n    }\n    void SetPosition(float3 &position)\n    {\n        mParentMatrix.r3.x = position.x;\n        mParentMatrix.r3.y = position.y;\n        mParentMatrix.r3.z = position.z;\n        MarkDirty();\n    }\n    void GetPosition(float *pX, float *pY, float *pZ)\n    {\n        *pX = mParentMatrix.r3.x;\n        *pY = mParentMatrix.r3.y;\n        *pZ = mParentMatrix.r3.z;\n    }\n    void GetPosition(float3 *pPosition)\n    {\n        pPosition->x = mParentMatrix.r3.x;\n        pPosition->y = mParentMatrix.r3.y;\n        pPosition->z = mParentMatrix.r3.z;\n    }\n    float3 GetPosition()\n    {\n        float3 ret = float3( mParentMatrix.r3.x, mParentMatrix.r3.y, mParentMatrix.r3.z);\n        return ret;\n    }\n    float3 GetLook()\n    {\n        return mParentMatrix.getZAxis();\n    }\n    float3 GetUp()\n    {\n        return mParentMatrix.getYAxis();\n    }\n    float3 GetLook( float *pX, float *pY, float *pZ )\n    {\n        float3 look = mParentMatrix.getZAxis();\n        *pX = look.x;\n        *pY = look.y;\n        *pZ = look.z;\n    }\n\n    virtual int      ReleaseRecursive();\n    void             SetName(const cString &name) { mName = name;};\n    void             SetParent(CPUTRenderNode *pParent);\n    CPUTRenderNode  *GetParent()       { return mpParent; }\n    CPUTRenderNode  *GetChild()        { return mpChild; }\n    CPUTRenderNode  *GetSibling()      { return mpSibling; }\n    cString         &GetName()         { return mName;};\n    cString         &GetPrefix()       { return mPrefix; }\n    void             SetPrefix( cString &prefix ) { mPrefix = prefix; }\n    virtual bool     IsModel()         { return false; }\n    float4x4        *GetParentMatrix() { return &mParentMatrix; }\n    float4x4        *GetWorldMatrix();\n    void             MarkDirty();\n    void             AddChild(CPUTRenderNode *pNode);\n    void             AddSibling(CPUTRenderNode *pNode);\n    virtual void     Update( float deltaSeconds = 0.0f ){}\n    virtual void     UpdateRecursive( float deltaSeconds );\n    virtual void     Render(CPUTRenderParameters &renderParams){}\n    virtual void     RenderShadow(CPUTRenderParameters &renderParams){}\n    virtual void     RenderRecursive(CPUTRenderParameters &renderParams);\n    virtual void     RenderShadowRecursive(CPUTRenderParameters &renderParams);\n    void             SetParentMatrix(const float4x4 &parentMatrix)\n    {\n        mParentMatrix = parentMatrix;\n        MarkDirty();\n    }\n    void LoadParentMatrixFromParameterBlock( CPUTConfigBlock *pBlock )\n    {\n        // get and set the transform\n        float pMatrix[4][4];\n        CPUTConfigEntry *pColumn = pBlock->GetValueByName(_L(\"matrixColumn0\"));\n        CPUTConfigEntry *pRow    = pBlock->GetValueByName(_L(\"matrixRow0\"));\n        float4x4 parentMatrix;\n        if( pColumn->IsValid() )\n        {\n            pBlock->GetValueByName(_L(\"matrixColumn0\"))->ValueAsFloatArray(&pMatrix[0][0], 4);\n            pBlock->GetValueByName(_L(\"matrixColumn1\"))->ValueAsFloatArray(&pMatrix[1][0], 4);\n            pBlock->GetValueByName(_L(\"matrixColumn2\"))->ValueAsFloatArray(&pMatrix[2][0], 4);\n            pBlock->GetValueByName(_L(\"matrixColumn3\"))->ValueAsFloatArray(&pMatrix[3][0], 4);\n            parentMatrix = float4x4((float*)&pMatrix[0][0]);\n            parentMatrix.transpose(); // Matrices are specified column-major, but consumed row-major.\n        } else if( pRow->IsValid() )\n        {\n            pBlock->GetValueByName(_L(\"matrixRow0\"))->ValueAsFloatArray(&pMatrix[0][0], 4);\n            pBlock->GetValueByName(_L(\"matrixRow1\"))->ValueAsFloatArray(&pMatrix[1][0], 4);\n            pBlock->GetValueByName(_L(\"matrixRow2\"))->ValueAsFloatArray(&pMatrix[2][0], 4);\n            pBlock->GetValueByName(_L(\"matrixRow3\"))->ValueAsFloatArray(&pMatrix[3][0], 4);\n            parentMatrix = float4x4((float*)&pMatrix[0][0]);\n        } else\n        {\n            float identity[16] = { 1.f, 0.f, 0.f, 0.f,   0.f, 1.f, 0.f, 0.f,   0.f, 0.f, 1.f, 0.f,    0.f, 0.f, 0.f, 1.f };\n            parentMatrix = float4x4(identity);\n        }\n        SetParentMatrix(parentMatrix);   // set the relative transform, marking child transform's dirty\n    }\n    virtual void GetBoundingBoxRecursive( float3 *pCenter, float3 *pHalf)\n    {\n        if(mpChild)   { mpChild->GetBoundingBoxRecursive(   pCenter, pHalf ); }\n        if(mpSibling) { mpSibling->GetBoundingBoxRecursive( pCenter, pHalf ); }\n    }\n};\n\n#endif // #ifndef __CPUTRENDERNODE_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderParams.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTRENDERPARAMS_H__\n#define __CPUTRENDERPARAMS_H__\n\n// TODO:  Change name to CPUTRenderContext?\nclass CPUTCamera;\n\nclass CPUTRenderParameters\n{\npublic:\n    bool         mShowBoundingBoxes;\n    bool         mDrawModels;\n    bool         mRenderOnlyVisibleModels;\n    CPUTCamera  *mpCamera;\n\n    CPUTRenderParameters() :\n        mShowBoundingBoxes(false),\n        mDrawModels(true),\n        mRenderOnlyVisibleModels(true),\n        mpCamera(0)\n    {}\n    ~CPUTRenderParameters(){}\nprivate:\n};\n\n#endif // __CPUTRENDERPARAMS_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderParamsDX.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTRENDERPARAMSDX_H__\n#define __CPUTRENDERPARAMSDX_H__\n\n#include \"CPUT.h\"\n#include <d3d11.h>\n#include <xnamath.h>\n#include \"CPUTRenderParams.h\"\n\nclass CPUTRenderParametersDX : public CPUTRenderParameters\n{\npublic:\n    ID3D11DeviceContext *mpContext;\n\npublic:\n    CPUTRenderParametersDX(): mpContext(NULL){}\n    CPUTRenderParametersDX( ID3D11DeviceContext *pContext, bool drawModels=true, bool renderOnlyVisibleModels=true, bool showBoundingBoxes=false )\n        : mpContext(pContext)\n    {\n        mShowBoundingBoxes       = showBoundingBoxes;\n        mDrawModels              = drawModels;\n        mRenderOnlyVisibleModels = renderOnlyVisibleModels;\n    }\n    ~CPUTRenderParametersDX(){}\n};\n\n#endif // #ifndef __CPUTRENDERPARAMSDX_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderStateBlock.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTAssetLibrary.h\"\n\n#ifdef CPUT_FOR_DX11\n#include \"CPUTRenderStateBlockDX11.h\"\n#else\n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n\n\nCPUTRenderStateBlock *CPUTRenderStateBlock::mpDefaultRenderStateBlock = NULL;\n\nCPUTRenderStateBlock *CPUTRenderStateBlock::CreateRenderStateBlock( const cString &name, const cString &absolutePathAndFilename )\n{\n    // TODO: Make this DX/OGL-API independent.  How to choose which one gets created?  Remember, we eventually want to support both in one app (to compare them with a keyboard toggle)\n#ifdef CPUT_FOR_DX11\n    CPUTRenderStateBlock *pRenderStateBlock = new CPUTRenderStateBlockDX11();\n#else\n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n    pRenderStateBlock->LoadRenderStateBlock( absolutePathAndFilename );\n\n    // add to library\n    CPUTAssetLibrary::GetAssetLibrary()->AddRenderStateBlock( absolutePathAndFilename, pRenderStateBlock );\n\n    return pRenderStateBlock;\n}"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderStateBlock.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTRENDERSTATEBLOCK_H\n#define _CPUTRENDERSTATEBLOCK_H\n\n#include \"CPUT.h\"\n#include \"CPUTRefCount.h\"\n\nclass CPUTRenderParameters;\n\nclass CPUTRenderStateBlock : public CPUTRefCount\n{\nprotected:\n    static CPUTRenderStateBlock *mpDefaultRenderStateBlock;\n\n    cString mMaterialName;\n    \n    ~CPUTRenderStateBlock(){} // Destructor is not public.  Must release instead of delete.\n\npublic:\n    static CPUTRenderStateBlock *CreateRenderStateBlock( const cString &name, const cString &absolutePathAndFilename );\n    static CPUTRenderStateBlock *GetDefaultRenderStateBlock() { return mpDefaultRenderStateBlock; }\n    static void SetDefaultRenderStateBlock( CPUTRenderStateBlock *pBlock ) { SAFE_RELEASE( mpDefaultRenderStateBlock ); mpDefaultRenderStateBlock = pBlock; }\n\n\n    CPUTRenderStateBlock(){}\n    virtual CPUTResult LoadRenderStateBlock(const cString &fileName) = 0;\n    virtual void SetRenderStates(CPUTRenderParameters &renderParams) = 0;\n    virtual void CreateNativeResources() = 0;\n};\n\n#endif // _CPUTRENDERSTATEBLOCK_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderStateBlockDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUT_DX11.h\"\n#include \"CPUTRenderStateBlockDX11.h\"\n#include \"CPUTRenderStateMapsDX11.h\"\n\n//-----------------------------------------------------------------------------\nvoid CPUTRenderStateBlockDX11::ReadValue( CPUTConfigEntry *pValue, const CPUTRenderStateMapEntry *pRenderStateList, void *pDest )\n{\n    cString lowerCaseName = pValue->NameAsString();\n\n    bool found = false;\n    // Find it in the map.  TODO: could use a real map.  Maybe with a binary search, lexical storage, etc.\n    for( CPUTRenderStateMapEntry const *pCur = pRenderStateList; pCur->name.compare(_L(\"\")); pCur++ )\n    {\n        found = 0 == _wcsicmp( lowerCaseName.data(), pCur->name.data() );\n        if( found )\n        {\n            // We found it.  Now convert it from the text file's string to its internal representation\n\n            // There must be a more-generic way to do the following.  write( void*, void*, type ).\n            // Use function pointer array to ValueAsInt() and similar, so we can call them without the switch?\n            // Might require they all have same signature ==> use void pointers, and cast internally?\n            switch( pCur->type )\n            {\n            case ePARAM_TYPE_TYPELESS: ASSERT(0,_L(\"\")); break; // Should not get here.\n            case ePARAM_TYPE_INT:     *(int*)&((char*)pDest)[pCur->offset]  = pValue->ValueAsInt();   break;\n            case ePARAM_TYPE_UINT:   *(UINT*)&((char*)pDest)[pCur->offset]  = pValue->ValueAsUint();  break;\n            case ePARAM_TYPE_BOOL:   *(bool*)&((char*)pDest)[pCur->offset]  = pValue->ValueAsBool();  break;\n            case ePARAM_TYPE_FLOAT: *(float*)&((char*)pDest)[pCur->offset]  = pValue->ValueAsFloat(); break;\n            case ePARAM_TYPE_SHORT: *(short*)&((char*)pDest)[pCur->offset]  = pValue->ValueAsInt();   break;\n            case ePARAM_TYPE_CHAR:            ((char*)pDest)[pCur->offset]  = pValue->ValueAsInt();   break;\n            case ePARAM_TYPE_UCHAR:           ((UCHAR*)pDest)[pCur->offset] = pValue->ValueAsUint();  break;\n            case ePARAM_TYPE_STRING: break; // Not sure how to deal with this yet.  Strings can have different sizes\n                // The following types must be converted from string to enum.  They achieve this with a translation map\n            case ePARAM_TYPE_D3D11_BLEND:      found = pBlendMap->FindMapEntryByName(          (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            case ePARAM_TYPE_D3D11_BLEND_OP:   found = pBlendOpMap->FindMapEntryByName(        (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            case ePARAM_TYPE_DEPTH_WRITE_MASK: found = pDepthWriteMaskMap->FindMapEntryByName( (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            case ePARAM_TYPE_D3D11_STENCIL_OP: found = pStencilOpMap->FindMapEntryByName(      (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            case ePARAM_TYPE_D3D11_FILL_MODE:  found = pFillModeMap->FindMapEntryByName(       (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            case ePARAM_TYPE_D3D11_CULL_MODE:  found = pCullModeMap->FindMapEntryByName(       (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            case ePARAM_TYPE_D3D11_FILTER:     found = pFilterMap->FindMapEntryByName(         (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            case ePARAM_TYPE_D3D11_COMPARISON_FUNC:      found = pComparisonMap->FindMapEntryByName(     (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            case ePARAM_TYPE_D3D11_TEXTURE_ADDRESS_MODE: found = pTextureAddressMap->FindMapEntryByName( (int*)&((char*)pDest)[pCur->offset], pValue->ValueAsString() ); break;\n            }\n            break; // From for.  We found it, so we're done.\n        }\n    }\n    ASSERT( found, _L( \"Unkown render state: '\") + pValue->NameAsString() + _L(\"'.\") );\n} // CPUTRenderStateBlockDX11::ReadValue()\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTRenderStateBlockDX11::ReadProperties(\n    CPUTConfigFile                &file,\n    const cString                 &blockName,\n    const CPUTRenderStateMapEntry *pMap,\n    void                          *pDest\n)\n{\n    CPUTConfigBlock *pProperties = file.GetBlockByName(blockName);\n    if( !pProperties )\n    {\n        // Note: We choose not to assert here.  The nature of the parameter block is that\n        // only the values that deviate from default need to be present.  It is very\n        // common that blocks will be missing\n        return CPUT_ERROR_PARAMETER_BLOCK_NOT_FOUND;\n    }\n\n    UINT count = pProperties->ValueCount();\n    for( UINT ii=0; ii<count; ii++ )\n    {\n        // Get the next property\n        CPUTConfigEntry *pValue = pProperties->GetValue(ii);\n        ASSERT( pValue->IsValid(), _L(\"Invalid Value: '\")+pValue->NameAsString()+_L(\"'.\") );\n        ReadValue( pValue, pMap, pDest );\n    }\n    return CPUT_SUCCESS;\n} // CPUTRenderStateBlockDX11::ReadProperties()\n\n//-----------------------------------------------------------------------------\nvoid CPUTRenderStateDX11::SetDefaults()\n{\n    // TODO: it would be nice if we could just initialize this with struct initialization.\n    UINT ii;\n    BlendDesc.AlphaToCoverageEnable = FALSE;\n    BlendDesc.IndependentBlendEnable = FALSE;\n    for( ii=0; ii<8; ii++ )\n        {\n        BlendDesc.RenderTarget[ii].BlendEnable    = FALSE;\n        BlendDesc.RenderTarget[ii].SrcBlend       = D3D11_BLEND_ONE;\n        BlendDesc.RenderTarget[ii].DestBlend      = D3D11_BLEND_ZERO;\n        BlendDesc.RenderTarget[ii].BlendOp        = D3D11_BLEND_OP_ADD;\n        BlendDesc.RenderTarget[ii].SrcBlendAlpha  = D3D11_BLEND_ONE;\n        BlendDesc.RenderTarget[ii].DestBlendAlpha = D3D11_BLEND_ZERO;\n        BlendDesc.RenderTarget[ii].BlendOpAlpha   = D3D11_BLEND_OP_ADD;\n        BlendDesc.RenderTarget[ii].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;\n    }\n\n    BlendFactor[0] = BlendFactor[1] = BlendFactor[2] = BlendFactor[3] = 1.0f;\n    SampleMask = 0xFFFFFFFF;\n\n    DepthStencilDesc.DepthEnable                  = TRUE;\n    DepthStencilDesc.DepthWriteMask               = D3D11_DEPTH_WRITE_MASK_ALL;\n    DepthStencilDesc.DepthFunc                    = D3D11_COMPARISON_GREATER_EQUAL;\n    DepthStencilDesc.StencilEnable                = FALSE;\n    DepthStencilDesc.StencilReadMask              = D3D11_DEFAULT_STENCIL_READ_MASK;\n    DepthStencilDesc.StencilWriteMask             = D3D11_DEFAULT_STENCIL_WRITE_MASK;\n    DepthStencilDesc.FrontFace.StencilFunc        = D3D11_COMPARISON_ALWAYS;\n    DepthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;\n    DepthStencilDesc.FrontFace.StencilPassOp      = D3D11_STENCIL_OP_KEEP;\n    DepthStencilDesc.FrontFace.StencilFailOp      = D3D11_STENCIL_OP_KEEP;\n    DepthStencilDesc.BackFace.StencilFunc         = D3D11_COMPARISON_ALWAYS;\n    DepthStencilDesc.BackFace.StencilDepthFailOp  = D3D11_STENCIL_OP_KEEP;\n    DepthStencilDesc.BackFace.StencilPassOp       = D3D11_STENCIL_OP_KEEP;\n    DepthStencilDesc.BackFace.StencilFailOp       = D3D11_STENCIL_OP_KEEP;\n\n    RasterizerDesc.FillMode                       = D3D11_FILL_SOLID;\n    RasterizerDesc.CullMode                       = D3D11_CULL_BACK;\n    RasterizerDesc.FrontCounterClockwise          = FALSE;\n    RasterizerDesc.DepthBias                      = 0;\n    RasterizerDesc.SlopeScaledDepthBias           = 0.0f;\n    RasterizerDesc.DepthBiasClamp                 = 0.0f;\n    RasterizerDesc.DepthClipEnable                = TRUE;\n    RasterizerDesc.ScissorEnable                  = FALSE;\n    RasterizerDesc.MultisampleEnable              = TRUE;\n    RasterizerDesc.AntialiasedLineEnable          = FALSE;\n\n    for( ii=0; ii<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ii++ )\n    {\n        SamplerDesc[ii].Filter                    = D3D11_FILTER_MIN_MAG_MIP_LINEAR;\n        SamplerDesc[ii].AddressU                  = D3D11_TEXTURE_ADDRESS_WRAP; // Note that these are different from DX default (*CLAMP)\n        SamplerDesc[ii].AddressV                  = D3D11_TEXTURE_ADDRESS_WRAP;\n        SamplerDesc[ii].AddressW                  = D3D11_TEXTURE_ADDRESS_WRAP;\n        SamplerDesc[ii].MipLODBias                = 0;\n        SamplerDesc[ii].MaxAnisotropy             = 1;\n        SamplerDesc[ii].ComparisonFunc            = D3D11_COMPARISON_NEVER;\n        SamplerDesc[ii].BorderColor[0]            = 0.0f;\n        SamplerDesc[ii].BorderColor[1]            = 0.0f;\n        SamplerDesc[ii].BorderColor[2]            = 0.0f;\n        SamplerDesc[ii].BorderColor[3]            = 0.0f;\n        SamplerDesc[ii].MinLOD                    = -FLT_MAX;\n        SamplerDesc[ii].MaxLOD                    = FLT_MAX;\n    }\n} // CPUTRenderStateDX11::SetDefaults()\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTRenderStateBlockDX11::LoadRenderStateBlock(const cString &fileName)\n{\n    // TODO: If already loaded, then Release() all the old members\n\n    // use the fileName for now, maybe we'll add names later?\n    mMaterialName = fileName;\n\n    // Open/parse the file\n    CPUTConfigFile file;\n    CPUTResult result = file.LoadFile(fileName);\n    ASSERT( !FAILED(result), _L(\"Failed loading file: '\") + fileName + _L(\"'.\") );\n\n    // Note: We ignore \"not found error\" results for ReadProperties() calls.\n    // These blocks are optional.\n    UINT ii;\n    for( ii=0; ii<8; ii++ )\n    {\n        wchar_t pBlockName[64];\n        wsprintf( pBlockName, _L(\"RenderTargetBlendStateDX11_%d\"), ii+1 );\n        ReadProperties( file, cString(pBlockName), pRenderTargetBlendDescMap, &mStateDesc.BlendDesc.RenderTarget[ii] );\n    }\n    ReadProperties( file, _L(\"BlendStateDX11\"),        pBlendDescMap,        &mStateDesc.BlendDesc );\n    ReadProperties( file, _L(\"DepthStencilStateDX11\"), pDepthStencilDescMap, &mStateDesc.DepthStencilDesc);\n    ReadProperties( file, _L(\"RasterizerStateDX11\"),   pRasterizerDescMap,   &mStateDesc.RasterizerDesc);\n\n    mNumSamplers = 0;\n    for( ii=0; ii<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ii++ )\n    {\n        // TODO: Use sampler names from .fx file.  Already did this for texture names.\n        // The challenge is that the renderstate file is independent from the material (and the shaders).\n        // Another feature is that the artists don't name the samplers (in the CPUTSL source).  Though, arbitrary .fx files can.\n        // TODO: Add sampler-state properties to CPUTSL source (e.g., filter modes).  Then, have ShaderGenerator output a .rs file.\n        wchar_t pBlockName[64];\n        wsprintf( pBlockName, _L(\"SamplerDX11_%d\"), ii+1 );\n        CPUTResult result = ReadProperties( file, cString(pBlockName), pSamplerDescMap, &mStateDesc.SamplerDesc[ii] );\n        if( CPUT_SUCCESS != result )\n        {\n            break; // Reached last sampler spec\n        }\n        ++mNumSamplers;\n    }\n    CreateNativeResources();\n\n    return CPUT_SUCCESS;\n} // CPUTRenderStateBlockDX11::LoadRenderStateBlock()\n\n//-----------------------------------------------------------------------------\nvoid CPUTRenderStateBlockDX11::CreateNativeResources()\n{\n    // Now, create the DX render state items\n    ID3D11Device *pDevice = CPUT_DX11::GetDevice();\n    HRESULT hr;\n    hr = pDevice->CreateBlendState( &mStateDesc.BlendDesc, &mpBlendState );\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to create blend state.\") );\n\n    hr = pDevice->CreateDepthStencilState( &mStateDesc.DepthStencilDesc, &mpDepthStencilState );\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to create depth stencil state.\") );\n\n    hr = pDevice->CreateRasterizerState( &mStateDesc.RasterizerDesc, &mpRasterizerState );\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to create rasterizer state.\") );\n\n    // TODO: how to map samplers to shaders?\n    // Each type can have different samplers assigned (VS, PS, GS, etc.)\n    // How does DX treat them?  16 unified?  or 16 each?\n    // For now, just read 16 samplers, and set to all stages\n\n    for( UINT ii=0; ii<mNumSamplers; ii++ )\n    {\n        hr = pDevice->CreateSamplerState( &mStateDesc.SamplerDesc[ii], &mpSamplerState[ii] );\n        ASSERT( SUCCEEDED(hr), _L(\"Failed to create sampler state.\") );\n    }\n} // CPUTRenderStateBlockDX11::CreateDXResources()\n\n//-----------------------------------------------------------------------------\nvoid CPUTRenderStateBlockDX11::SetRenderStates( CPUTRenderParameters &renderParams )\n{\n    ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n    pContext->OMSetBlendState( mpBlendState, mStateDesc.BlendFactor, mStateDesc.SampleMask );\n    pContext->OMSetDepthStencilState( mpDepthStencilState, 0 ); // TODO: read stecil ref from config file\n    pContext->RSSetState( mpRasterizerState );\n    pContext->PSSetSamplers( 0, mNumSamplers, mpSamplerState );\n    pContext->VSSetSamplers( 0, mNumSamplers, mpSamplerState );\n    pContext->GSSetSamplers( 0, mNumSamplers, mpSamplerState );\n} // CPUTRenderStateBlockDX11::SetRenderState()\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderStateBlockDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTRENDERSTATEBLOCKDX11_H\n#define _CPUTRENDERSTATEBLOCKDX11_H\n\n#include \"CPUTRenderStateBlock.h\"\n#include \"CPUTConfigBlock.h\"\n\n// include all DX11 headers needed\n#include <d3d11.h>\n#include <d3DX11.h>\n\nstruct CPUTRenderStateMapEntry;\nclass CPUTRenderParameters;\n\n//-----------------------------------------------------------------------------\n// TODO: Move to own file\nclass CPUTRenderStateDX11\n{\npublic:\n    D3D11_BLEND_DESC         BlendDesc;\n    D3D11_DEPTH_STENCIL_DESC DepthStencilDesc;\n    D3D11_RASTERIZER_DESC    RasterizerDesc;\n    D3D11_SAMPLER_DESC       SamplerDesc[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];\n    float                    BlendFactor[4];\n    UINT                     SampleMask;\n\n    CPUTRenderStateDX11() { SetDefaults(); }\n    ~CPUTRenderStateDX11() {} // Destructor is not public.  Must release instead of delete.\n    void SetDefaults();\n};\n\n//-----------------------------------------------------------------------------\nclass CPUTRenderStateBlockDX11:public CPUTRenderStateBlock\n{\nprotected:\n    // The state descriptor describes all of the states.\n    // We read it in when creating assets.  We keep it around in case we need to adjust and recreate.\n    CPUTRenderStateDX11        mStateDesc;\n\n    // Each of the native state objects.\n    ID3D11BlendState           *mpBlendState;\n    ID3D11DepthStencilState    *mpDepthStencilState;\n    ID3D11RasterizerState      *mpRasterizerState;\n    ID3D11SamplerState         *mpSamplerState[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];\n    UINT                        mNumSamplers;\n\n     // Destructor is not public.  Must release instead of delete.\n    ~CPUTRenderStateBlockDX11()\n    {\n        SAFE_RELEASE( mpBlendState );\n        SAFE_RELEASE( mpDepthStencilState );\n        SAFE_RELEASE( mpRasterizerState );\n        for( UINT ii=0; ii<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ii++ )\n        {\n            SAFE_RELEASE( mpSamplerState[ii] );\n        }\n    }\n\npublic:\n    // constructor\n    CPUTRenderStateBlockDX11():\n        mpBlendState(NULL),\n        mpDepthStencilState(NULL),\n        mpRasterizerState(NULL),\n        mNumSamplers(D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT) // Default to all.  Set to actual count when loading\n    {\n        for( UINT ii=0; ii<D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ii++ )\n        {\n            mpSamplerState[ii] = NULL;\n        }\n    }\n    CPUTResult ReadProperties(\n        CPUTConfigFile                &file,\n        const cString                 &blockName,\n        const CPUTRenderStateMapEntry *pMap,\n        void                          *pDest\n    );\n    void               ReadValue( CPUTConfigEntry *pValue, const CPUTRenderStateMapEntry *pRenderStateList, void *pDest );\n    virtual CPUTResult LoadRenderStateBlock(const cString &fileName);\n    virtual void       CreateNativeResources();\n    void               SetRenderStates(CPUTRenderParameters &renderParams);\n    CPUTRenderStateDX11 *GetState() {return &mStateDesc;}\n};\n\n//-----------------------------------------------------------------------------\nenum CPUT_PARAM_TYPE{\n    ePARAM_TYPE_TYPELESS,\n    ePARAM_TYPE_INT,\n    ePARAM_TYPE_UINT,\n    ePARAM_TYPE_FLOAT,\n    ePARAM_TYPE_BOOL,\n    ePARAM_TYPE_SHORT,\n    ePARAM_TYPE_CHAR,\n    ePARAM_TYPE_UCHAR,\n    ePARAM_TYPE_STRING, // Does string make sense?  Could copy it.\n    ePARAM_TYPE_D3D11_BLEND,\n    ePARAM_TYPE_D3D11_BLEND_OP,\n    ePARAM_TYPE_DEPTH_WRITE_MASK,\n    ePARAM_TYPE_D3D11_COMPARISON_FUNC,\n    ePARAM_TYPE_D3D11_STENCIL_OP,\n    ePARAM_TYPE_D3D11_FILL_MODE,\n    ePARAM_TYPE_D3D11_CULL_MODE,\n    ePARAM_TYPE_D3D11_FILTER,\n    ePARAM_TYPE_D3D11_TEXTURE_ADDRESS_MODE\n};\n\n//-----------------------------------------------------------------------------\nstruct CPUTRenderStateMapEntry\n{\n    cString         name;\n    CPUT_PARAM_TYPE type;\n    UINT            offset;\n};\n\n//-----------------------------------------------------------------------------\nclass StringToIntMapEntry\n{\npublic:\n    cString mName;\n    int     mValue;\n\n    bool FindMapEntryByName( int *pValue, const cString name ) const{\n        StringToIntMapEntry const *pstart = this;\n        for( StringToIntMapEntry const *pEntry = pstart; pEntry->mName.length() > 0; pEntry++ ){\n            if( 0 == _wcsicmp( pEntry->mName.data(), name.data() ) ){\n                *pValue = pEntry->mValue;\n                return true;\n            }\n        }\n        return false;\n    }\n};\n\n#endif // _CPUTRENDERSTATEBLOCKDX11_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderStateMapsDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#ifndef _CPUTRENDERSTATEMAPSDX11_H\n#define _CPUTRENDERSTATEMAPSDX11_H\n\n// TODO: Should this be in a cpp file instead of an h file?\n//       We just put it here to get it out of the way\n//       in the implementation file (CPUTRenderStateBlockDX11.cpp)\n\n//-----------------------------------------------------------------------------\nstatic const CPUTRenderStateMapEntry pBlendDescMap[] =\n{\n    { _L(\"alphatocoverageenable\"),  ePARAM_TYPE_BOOL,  (UINT)offsetof(D3D11_BLEND_DESC, AlphaToCoverageEnable)},\n    { _L(\"independentblendenable\"), ePARAM_TYPE_BOOL,  (UINT)offsetof(D3D11_BLEND_DESC, IndependentBlendEnable)},\n    { _L(\"blendfactor1\"),           ePARAM_TYPE_FLOAT, (UINT)offsetof(CPUTRenderStateDX11, BlendFactor[0] )},\n    { _L(\"blendfactor2\"),           ePARAM_TYPE_FLOAT, (UINT)offsetof(CPUTRenderStateDX11, BlendFactor[1] )},\n    { _L(\"blendfactor3\"),           ePARAM_TYPE_FLOAT, (UINT)offsetof(CPUTRenderStateDX11, BlendFactor[2] )},\n    { _L(\"blendfactor4\"),           ePARAM_TYPE_FLOAT, (UINT)offsetof(CPUTRenderStateDX11, BlendFactor[3] )},\n    { _L(\"samplemask\"),             ePARAM_TYPE_UINT,  (UINT)offsetof(CPUTRenderStateDX11, SampleMask )},\n    { _L(\"\"), ePARAM_TYPE_TYPELESS, 0}\n};\n\n//-----------------------------------------------------------------------------\nstatic const CPUTRenderStateMapEntry pRenderTargetBlendDescMap[] =\n{\n    { _L(\"blendenable\"),           ePARAM_TYPE_BOOL,           (UINT)offsetof(D3D11_RENDER_TARGET_BLEND_DESC, BlendEnable )},\n    { _L(\"srcblend\"),              ePARAM_TYPE_D3D11_BLEND,    (UINT)offsetof(D3D11_RENDER_TARGET_BLEND_DESC, SrcBlend )},\n    { _L(\"destblend\"),             ePARAM_TYPE_D3D11_BLEND,    (UINT)offsetof(D3D11_RENDER_TARGET_BLEND_DESC, DestBlend )},\n    { _L(\"blendop\"),               ePARAM_TYPE_D3D11_BLEND_OP, (UINT)offsetof(D3D11_RENDER_TARGET_BLEND_DESC, BlendOp )},\n    { _L(\"srcblendalpha\"),         ePARAM_TYPE_D3D11_BLEND,    (UINT)offsetof(D3D11_RENDER_TARGET_BLEND_DESC, SrcBlendAlpha )},\n    { _L(\"destblendalpha\"),        ePARAM_TYPE_D3D11_BLEND,    (UINT)offsetof(D3D11_RENDER_TARGET_BLEND_DESC, DestBlendAlpha )},\n    { _L(\"blendopalpha\"),          ePARAM_TYPE_D3D11_BLEND_OP, (UINT)offsetof(D3D11_RENDER_TARGET_BLEND_DESC, BlendOpAlpha )},\n    { _L(\"rendertargetwritemask\"), ePARAM_TYPE_UCHAR,          (UINT)offsetof(D3D11_RENDER_TARGET_BLEND_DESC, RenderTargetWriteMask )},\n    { _L(\"\"), ePARAM_TYPE_TYPELESS, 0}\n};\n\n//-----------------------------------------------------------------------------\nstatic const CPUTRenderStateMapEntry pDepthStencilDescMap[] =\n{\n    { _L(\"depthenable\"),                 ePARAM_TYPE_BOOL,                  (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, DepthEnable)},\n    { _L(\"depthwritemask\"),              ePARAM_TYPE_DEPTH_WRITE_MASK,      (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, DepthWriteMask)},\n    { _L(\"depthfunc\"),                   ePARAM_TYPE_D3D11_COMPARISON_FUNC, (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, DepthFunc)},\n    { _L(\"StencilEnable\"),               ePARAM_TYPE_BOOL,                  (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, StencilEnable)},\n    { _L(\"StencilReadMask\"),             ePARAM_TYPE_UCHAR,                 (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, StencilWriteMask)},\n    { _L(\"StencilWriteMask\"),            ePARAM_TYPE_UCHAR,                 (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, DepthWriteMask)},\n    { _L(\"FrontFaceStencilFailOp\"),      ePARAM_TYPE_D3D11_STENCIL_OP,      (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, FrontFace.StencilFailOp )},\n    { _L(\"FrontFaceStencilDepthFailOp\"), ePARAM_TYPE_D3D11_STENCIL_OP,      (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, FrontFace.StencilDepthFailOp)},\n    { _L(\"FrontFaceStencilPassOp\"),      ePARAM_TYPE_D3D11_STENCIL_OP,      (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, FrontFace.StencilPassOp)},\n    { _L(\"FrontFaceStencilFunc\"),        ePARAM_TYPE_D3D11_COMPARISON_FUNC, (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, FrontFace.StencilFunc)},\n    { _L(\"BackFaceStencilFailOp\"),       ePARAM_TYPE_D3D11_STENCIL_OP,      (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, BackFace.StencilDepthFailOp)},\n    { _L(\"BackFaceStencilDepthFailOp\"),  ePARAM_TYPE_D3D11_STENCIL_OP,      (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, BackFace.StencilDepthFailOp)},\n    { _L(\"BackFaceStencilPassOp\"),       ePARAM_TYPE_D3D11_STENCIL_OP,      (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, BackFace.StencilPassOp)},\n    { _L(\"BackFaceStencilFunc\"),         ePARAM_TYPE_D3D11_COMPARISON_FUNC, (UINT)offsetof(D3D11_DEPTH_STENCIL_DESC, BackFace.StencilFunc)},\n    { _L(\"\"), ePARAM_TYPE_TYPELESS, 0}\n};\n\n//-----------------------------------------------------------------------------\nstatic const CPUTRenderStateMapEntry pRasterizerDescMap[] =\n{\n    { _L(\"FillMode\"),              ePARAM_TYPE_D3D11_FILL_MODE, (UINT)offsetof(D3D11_RASTERIZER_DESC, FillMode)},\n    { _L(\"CullMode\"),              ePARAM_TYPE_D3D11_CULL_MODE, (UINT)offsetof(D3D11_RASTERIZER_DESC, CullMode)},\n    { _L(\"FrontCounterClockwise\"), ePARAM_TYPE_BOOL,            (UINT)offsetof(D3D11_RASTERIZER_DESC, FrontCounterClockwise)},\n    { _L(\"DepthBias\"),             ePARAM_TYPE_INT,             (UINT)offsetof(D3D11_RASTERIZER_DESC, DepthBias)},\n    { _L(\"DepthBiasClamp\"),        ePARAM_TYPE_FLOAT,           (UINT)offsetof(D3D11_RASTERIZER_DESC, DepthBiasClamp)},\n    { _L(\"SlopeScaledDepthBias\"),  ePARAM_TYPE_FLOAT,           (UINT)offsetof(D3D11_RASTERIZER_DESC, SlopeScaledDepthBias)},\n    { _L(\"DepthClipEnable\"),       ePARAM_TYPE_BOOL,            (UINT)offsetof(D3D11_RASTERIZER_DESC, DepthClipEnable)},\n    { _L(\"ScissorEnable\"),         ePARAM_TYPE_BOOL,            (UINT)offsetof(D3D11_RASTERIZER_DESC, ScissorEnable)},\n    { _L(\"MultisampleEnable\"),     ePARAM_TYPE_BOOL,            (UINT)offsetof(D3D11_RASTERIZER_DESC, MultisampleEnable)},\n    { _L(\"AntialiasedLineEnable\"), ePARAM_TYPE_BOOL,            (UINT)offsetof(D3D11_RASTERIZER_DESC, AntialiasedLineEnable)},\n    { _L(\"\"), ePARAM_TYPE_TYPELESS, 0}\n};\n\n//-----------------------------------------------------------------------------\nstatic const CPUTRenderStateMapEntry pSamplerDescMap[] =\n{\n    { _L(\"Filter\"),         ePARAM_TYPE_D3D11_FILTER,               (UINT)offsetof(D3D11_SAMPLER_DESC, Filter)},\n    { _L(\"AddressU\"),       ePARAM_TYPE_D3D11_TEXTURE_ADDRESS_MODE, (UINT)offsetof(D3D11_SAMPLER_DESC, AddressU)},\n    { _L(\"AddressV\"),       ePARAM_TYPE_D3D11_TEXTURE_ADDRESS_MODE, (UINT)offsetof(D3D11_SAMPLER_DESC, AddressV)},\n    { _L(\"AddressW\"),       ePARAM_TYPE_D3D11_TEXTURE_ADDRESS_MODE, (UINT)offsetof(D3D11_SAMPLER_DESC, AddressW)},\n    { _L(\"MipLODBias\"),     ePARAM_TYPE_FLOAT,                      (UINT)offsetof(D3D11_SAMPLER_DESC, MipLODBias)},\n    { _L(\"MaxAnisotropy\"),  ePARAM_TYPE_UINT,                       (UINT)offsetof(D3D11_SAMPLER_DESC, MaxAnisotropy)},\n    { _L(\"ComparisonFunc\"), ePARAM_TYPE_D3D11_COMPARISON_FUNC,      (UINT)offsetof(D3D11_SAMPLER_DESC, ComparisonFunc)},\n    { _L(\"BorderColor0\"),   ePARAM_TYPE_FLOAT,                      (UINT)offsetof(D3D11_SAMPLER_DESC, BorderColor[0])},\n    { _L(\"BorderColor1\"),   ePARAM_TYPE_FLOAT,                      (UINT)offsetof(D3D11_SAMPLER_DESC, BorderColor[1])},\n    { _L(\"BorderColor2\"),   ePARAM_TYPE_FLOAT,                      (UINT)offsetof(D3D11_SAMPLER_DESC, BorderColor[2])},\n    { _L(\"BorderColor3\"),   ePARAM_TYPE_FLOAT,                      (UINT)offsetof(D3D11_SAMPLER_DESC, BorderColor[3])},\n    { _L(\"MinLOD\"),         ePARAM_TYPE_FLOAT,                      (UINT)offsetof(D3D11_SAMPLER_DESC, MinLOD)},\n    { _L(\"MaxLOD\"),         ePARAM_TYPE_FLOAT,                      (UINT)offsetof(D3D11_SAMPLER_DESC, MaxLOD)},\n    { _L(\"\"), ePARAM_TYPE_TYPELESS, 0}\n};\n\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pBlendMap[] = {\n    { _L(\"d3d11_blend_zero\"),             D3D11_BLEND_ZERO },\n    { _L(\"d3d11_blend_one\"),              D3D11_BLEND_ONE },\n    { _L(\"d3d11_blend_src_color\"),        D3D11_BLEND_SRC_COLOR },\n    { _L(\"d3d11_blend_inv_src_color\"),    D3D11_BLEND_INV_SRC_COLOR },\n    { _L(\"d3d11_blend_src_alpha\"),        D3D11_BLEND_SRC_ALPHA },\n    { _L(\"d3d11_blend_inv_src_alpha\"),    D3D11_BLEND_INV_SRC_ALPHA },\n    { _L(\"d3d11_blend_dest_alpha\"),       D3D11_BLEND_DEST_ALPHA },\n    { _L(\"d3d11_blend_inv_dest_alpha\"),   D3D11_BLEND_INV_DEST_ALPHA },\n    { _L(\"d3d11_blend_dest_color\"),       D3D11_BLEND_DEST_COLOR },\n    { _L(\"d3d11_blend_inv_dest_color\"),   D3D11_BLEND_INV_DEST_COLOR },\n    { _L(\"d3d11_blend_src_alpha_sat\"),    D3D11_BLEND_SRC_ALPHA_SAT },\n    { _L(\"d3d11_blend_blend_factor\"),     D3D11_BLEND_BLEND_FACTOR },\n    { _L(\"d3d11_blend_inv_blend_factor\"), D3D11_BLEND_INV_BLEND_FACTOR },\n    { _L(\"d3d11_blend_src1_color\"),       D3D11_BLEND_SRC1_COLOR },\n    { _L(\"d3d11_blend_inv_src1_color\"),   D3D11_BLEND_INV_SRC1_COLOR },\n    { _L(\"d3d11_blend_src1_alpha\"),       D3D11_BLEND_SRC1_ALPHA },\n    { _L(\"d3d11_blend_inv_src1_alpha\"),   D3D11_BLEND_INV_SRC1_ALPHA },\n    { _L(\"\"), -1 }\n};\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pBlendOpMap[] = {\n    { _L(\"d3d11_blend_op_add\"),          D3D11_BLEND_OP_ADD },\n    { _L(\"d3d11_blend_op_subtract\"),     D3D11_BLEND_OP_SUBTRACT },\n    { _L(\"d3d11_blend_op_rev_subtract\"), D3D11_BLEND_OP_REV_SUBTRACT },\n    { _L(\"d3d11_blend_op_min\"),          D3D11_BLEND_OP_MIN },\n    { _L(\"d3d11_blend_op_max\"),          D3D11_BLEND_OP_MAX },\n    { _L(\"\"), -1 }\n};\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pDepthWriteMaskMap[] = {\n    { _L(\"D3D11_DEPTH_WRITE_MASK_ZERO\"), D3D11_DEPTH_WRITE_MASK_ZERO },\n    { _L(\"D3D11_DEPTH_WRITE_MASK_ALL\"),  D3D11_DEPTH_WRITE_MASK_ALL },\n    { _L(\"\"), -1 }\n};\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pComparisonMap[] = {\n    { _L(\"D3D11_COMPARISON_NEVER\"),         D3D11_COMPARISON_NEVER },\n    { _L(\"D3D11_COMPARISON_LESS\"),          D3D11_COMPARISON_LESS },\n    { _L(\"D3D11_COMPARISON_EQUAL\"),         D3D11_COMPARISON_EQUAL },\n    { _L(\"D3D11_COMPARISON_LESS_EQUAL\"),    D3D11_COMPARISON_LESS_EQUAL },\n    { _L(\"D3D11_COMPARISON_GREATER\"),       D3D11_COMPARISON_GREATER },\n    { _L(\"D3D11_COMPARISON_NOT_EQUAL\"),     D3D11_COMPARISON_NOT_EQUAL},\n    { _L(\"D3D11_COMPARISON_GREATER_EQUAL\"), D3D11_COMPARISON_GREATER_EQUAL},\n    { _L(\"D3D11_COMPARISON_ALWAYS\"),        D3D11_COMPARISON_ALWAYS},\n    { _L(\"\"), -1 }\n};\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pStencilOpMap[] = {\n    { _L(\"D3D11_STENCIL_OP_KEEP\"),     D3D11_STENCIL_OP_KEEP },\n    { _L(\"D3D11_STENCIL_OP_ZERO\"),     D3D11_STENCIL_OP_ZERO },\n    { _L(\"D3D11_STENCIL_OP_REPLACE\"),  D3D11_STENCIL_OP_REPLACE },\n    { _L(\"D3D11_STENCIL_OP_INCR_SAT\"), D3D11_STENCIL_OP_INCR_SAT },\n    { _L(\"D3D11_STENCIL_OP_DECR_SAT\"), D3D11_STENCIL_OP_DECR_SAT },\n    { _L(\"D3D11_STENCIL_OP_INVERT\"),   D3D11_STENCIL_OP_INVERT },\n    { _L(\"D3D11_STENCIL_OP_INCR\"),     D3D11_STENCIL_OP_INCR },\n    { _L(\"D3D11_STENCIL_OP_DECR\"),     D3D11_STENCIL_OP_DECR },\n    { _L(\"\"), -1 }\n};\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pFillModeMap[] = {\n    { _L(\"D3D11_FILL_WIREFRAME\"),      D3D11_FILL_WIREFRAME },\n    { _L(\"D3D11_FILL_SOLID\"),          D3D11_FILL_SOLID },\n    { _L(\"\"), -1 }\n};\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pCullModeMap[] = {\n    { _L(\"D3D11_CULL_NONE\"),           D3D11_CULL_NONE },\n    { _L(\"D3D11_CULL_FRONT\"),          D3D11_CULL_FRONT },\n    { _L(\"D3D11_CULL_BACK\"),           D3D11_CULL_BACK },\n    { _L(\"\"), -1 }\n};\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pFilterMap[] = {\n    { _L(\"D3D11_FILTER_MIN_MAG_MIP_POINT\"),                          D3D11_FILTER_MIN_MAG_MIP_POINT },\n    { _L(\"D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR\"),                   D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR },\n    { _L(\"D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT\"),             D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT },\n    { _L(\"D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR\"),                   D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR },\n    { _L(\"D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT\"),                   D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT },\n    { _L(\"D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR\"),            D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR },\n    { _L(\"D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT\"),                   D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT },\n    { _L(\"D3D11_FILTER_MIN_MAG_MIP_LINEAR\"),                         D3D11_FILTER_MIN_MAG_MIP_LINEAR },\n    { _L(\"D3D11_FILTER_ANISOTROPIC\"),                                D3D11_FILTER_ANISOTROPIC },\n    { _L(\"D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT\"),               D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT },\n    { _L(\"D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR\"),        D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR },\n    { _L(\"D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT\"),  D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT },\n    { _L(\"D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR\"),        D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR },\n    { _L(\"D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT\"),        D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT },\n    { _L(\"D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR\"), D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR },\n    { _L(\"D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT\"),        D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT },\n    { _L(\"D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR\"),              D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR },\n    { _L(\"D3D11_FILTER_COMPARISON_ANISOTROPIC\"),                     D3D11_FILTER_COMPARISON_ANISOTROPIC },\n    // { _L(\"D3D11_FILTER_TEXT_1BIT\"),                                  D3D11_FILTER_TEXT_1BIT }, // DX docs list this, but not in actual structure\n    { _L(\"\"), -1 }\n};\n\n//-----------------------------------------------------------------------------\nstatic const StringToIntMapEntry pTextureAddressMap[] = {\n    { _L(\"D3D11_TEXTURE_ADDRESS_WRAP\"),        D3D11_TEXTURE_ADDRESS_WRAP },\n    { _L(\"D3D11_TEXTURE_ADDRESS_MIRROR\"),      D3D11_TEXTURE_ADDRESS_MIRROR },\n    { _L(\"D3D11_TEXTURE_ADDRESS_CLAMP\"),       D3D11_TEXTURE_ADDRESS_CLAMP },\n    { _L(\"D3D11_TEXTURE_ADDRESS_BORDER\"),      D3D11_TEXTURE_ADDRESS_BORDER },\n    { _L(\"D3D11_TEXTURE_ADDRESS_MIRROR_ONCE\"), D3D11_TEXTURE_ADDRESS_MIRROR_ONCE },\n    { _L(\"\"), -1 }\n};\n\n#endif //_CPUTRENDERSTATEMAPSDX11_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderTarget.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUT_DX11.h\"\n#include \"CPUTRenderTarget.h\"\n#include \"CPUTAssetLibrary.h\"\n#include \"CPUTMaterialDX11.h\"\n#include \"CPUTTextureDX11.h\"\n#include \"CPUTBufferDX11.h\"\n\nUINT CPUTRenderTargetColor::sCurrentWidth   = 0;\nUINT CPUTRenderTargetColor::sCurrentHeight  = 0;\nUINT CPUTRenderTargetDepth::sCurrentWidth   = 0;\nUINT CPUTRenderTargetDepth::sCurrentHeight  = 0;\n\nID3D11RenderTargetView *CPUTRenderTargetColor::spActiveRenderTargetView = NULL;\nID3D11DepthStencilView *CPUTRenderTargetDepth::spActiveDepthStencilView = NULL;\n\n//-----------------------------------------------\nCPUTRenderTargetColor::~CPUTRenderTargetColor()\n{\n    SAFE_RELEASE( mpColorTexture );\n    SAFE_RELEASE( mpColorUAV );\n    SAFE_RELEASE( mpColorBuffer );\n    SAFE_RELEASE( mpColorTextureDX );\n    SAFE_RELEASE( mpColorTextureDXMSAA );\n    SAFE_RELEASE( mpColorSRV );\n    SAFE_RELEASE( mpColorRenderTargetView );\n\n    SAFE_RELEASE( mpColorTextureMSAA );\n    SAFE_RELEASE( mpColorTextureDXMSAA );\n    SAFE_RELEASE( mpColorSRVMSAA );\n    SAFE_RELEASE( mpColorTextureDXStaging );\n}\n\n//-----------------------------------------------\nCPUTRenderTargetDepth::~CPUTRenderTargetDepth()\n{\n    SAFE_RELEASE( mpDepthTexture );\n    SAFE_RELEASE( mpDepthTextureDX );\n    SAFE_RELEASE( mpDepthResourceView );\n    SAFE_RELEASE( mpDepthStencilView );\n}\n\n//-----------------------------------------------\nHRESULT CPUTRenderTargetColor::CreateRenderTarget(\n    cString     textureName,\n    UINT        width,\n    UINT        height,\n    DXGI_FORMAT colorFormat,\n    UINT        multiSampleCount,\n    bool        createUAV,\n    bool        recreate\n)\n{\n    HRESULT result;\n\n    mName             = textureName;\n    mWidth            = width;\n    mHeight           = height;\n    mColorFormat      = colorFormat;\n    mMultiSampleCount = multiSampleCount;\n\n    CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();\n    CPUTOSServices   *pServices     = CPUTOSServices::GetOSServices();\n\n    // Create the color texture\n    mColorDesc = CD3D11_TEXTURE2D_DESC(\n        colorFormat,\n        width,\n        height,\n        1, // Array Size\n        1, // MIP Levels\n        D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS,\n        D3D11_USAGE_DEFAULT,\n        0,\n        mMultiSampleCount, 0\n    );\n\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n\n    // If MSAA enabled, then create MSAA texture\n    if( mMultiSampleCount>1 )\n    {\n        result = pD3dDevice->CreateTexture2D( &mColorDesc, NULL, &mpColorTextureDXMSAA );\n        ASSERT( SUCCEEDED(result), _L(\"Failed creating MSAA render target texture\") );\n\n        D3D11_SHADER_RESOURCE_VIEW_DESC srDesc = { colorFormat, D3D11_SRV_DIMENSION_TEXTURE2DMS, 0 };\n        srDesc.Texture2D.MipLevels = 1;\n        result = pD3dDevice->CreateShaderResourceView( mpColorTextureDXMSAA, &srDesc, &mpColorSRVMSAA );\n        ASSERT( SUCCEEDED(result), _L(\"Failed creating MSAA render target shader resource view\") );\n\t\tCPUTSetDebugName( mpColorSRVMSAA, textureName + _L(\" ColorMSAA\") );\n\n        if( !recreate )\n        {\n            cString msaaName = mName + _L(\"_MSAA\");\n            mpColorTextureMSAA = new CPUTTextureDX11( msaaName );\n\n            // If the name starts with a '$', then its an internal texture (has no filesystem path).\n            // Otherwise, its a file, so prepend filesystem path\n            CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();\n            cString finalName;\n            if( mName.at(0) == '$' )\n            {\n                finalName = msaaName;\n            }else\n            {\n                pServices->ResolveAbsolutePathAndFilename( (pAssetLibrary->GetTextureDirectory() + msaaName), &finalName);\n            }\n            pAssetLibrary->AddTexture( finalName, mpColorTextureMSAA );\n        }\n        ((CPUTTextureDX11*)mpColorTextureMSAA)->SetTextureAndShaderResourceView( mpColorTextureDXMSAA, mpColorSRVMSAA );\n    }\n    \n    // Create non-MSAA texture.  If we're MSAA, then we'll resolve into this.  If not, then we'll render directly to this one.\n    mColorDesc.SampleDesc.Count = 1;\n    result = pD3dDevice->CreateTexture2D( &mColorDesc, NULL, &mpColorTextureDX );\n    ASSERT( SUCCEEDED(result), _L(\"Failed creating render target texture\") );\n\n    // Create the shader-resource view from the non-MSAA texture\n    D3D11_SHADER_RESOURCE_VIEW_DESC srDesc = { colorFormat, D3D11_SRV_DIMENSION_TEXTURE2D, 0 };\n    srDesc.Texture2D.MipLevels = 1;\n    result = pD3dDevice->CreateShaderResourceView( mpColorTextureDX, &srDesc, &mpColorSRV );\n    ASSERT( SUCCEEDED(result), _L(\"Failed creating render target shader resource view\") );\n\tCPUTSetDebugName( mpColorSRV, textureName + _L(\" Color\") );\n\n    mHasUav = createUAV; // Remember, so we know to recreate it (or not) on RecreateRenderTarget()\n    if( createUAV )\n    {\n        // D3D11_SHADER_RESOURCE_VIEW_DESC srDesc = { colorFormat, D3D_SRV_DIMENSION_BUFFER, 0 };\n        D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;\n        memset( &uavDesc, 0, sizeof(uavDesc) );\n        uavDesc.Format = colorFormat;\n        uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;\n        uavDesc.Texture2D.MipSlice = 0;\n        result = pD3dDevice->CreateUnorderedAccessView( mpColorTextureDX, &uavDesc, &mpColorUAV );\n        ASSERT( SUCCEEDED(result), _L(\"Failed creating render target buffer shader resource view\") );\n\t    CPUTSetDebugName( mpColorUAV, textureName + _L(\" Color Buffer\") );\n    }\n    if( !recreate )\n    {\n        mpColorTexture = new CPUTTextureDX11(mName);\n        pAssetLibrary->AddTexture( mName, mpColorTexture );\n\n        mpColorBuffer = new CPUTBufferDX11(mName, NULL, mpColorUAV); // We don't have an ID3D11Buffer, but we want to track this UAV as if the texture was a buffer.\n        pAssetLibrary->AddBuffer( mName, mpColorBuffer );\n    }\n    ((CPUTTextureDX11*)mpColorTexture)->SetTextureAndShaderResourceView( mpColorTextureDX, mpColorSRV);\n\n    // Choose our render target.  If MSAA, then use the MSAA texture, and use resolve to fill the non-MSAA texture.\n    ID3D11Texture2D *pColorTexture = (mMultiSampleCount>1) ? mpColorTextureDXMSAA : mpColorTextureDX;\n    result = pD3dDevice->CreateRenderTargetView( pColorTexture, NULL, &mpColorRenderTargetView );\n    ASSERT( SUCCEEDED(result), _L(\"Failed creating render target view\") );\n\tCPUTSetDebugName( mpColorRenderTargetView, mName );\n\n    return S_OK;\n}\n\n//-----------------------------------------------\nHRESULT CPUTRenderTargetColor::RecreateRenderTarget(\n    UINT        width,\n    UINT        height,\n    DXGI_FORMAT colorFormat,\n    UINT        multiSampleCount\n)\n{\n    // We don't release these.  Instead, we release their resource views, and change them to the newly-created versions.\n    // SAFE_RELEASE( mpColorTexture );\n    SAFE_RELEASE( mpColorTextureDX );\n    SAFE_RELEASE( mpColorSRV );\n    SAFE_RELEASE( mpColorRenderTargetView );\n    SAFE_RELEASE( mpColorTextureDXMSAA );\n    SAFE_RELEASE( mpColorSRVMSAA );\n\n    // TODO: Complete buffer changes by including them here.\n\n\n    // Do not release saved resource views since they are not addreff'ed\n    //SAFE_RELEASE( mpSavedColorRenderTargetView );\n    //SAFE_RELEASE( mpSavedDepthStencilView );\n\n    return CreateRenderTarget( mName, width, height, (DXGI_FORMAT_UNKNOWN != colorFormat) ? colorFormat : mColorFormat, multiSampleCount, mHasUav, true );\n}\n\n//-----------------------------------------------\nHRESULT CPUTRenderTargetDepth::CreateRenderTarget(\n    cString     textureName,\n    UINT        width,\n    UINT        height,\n    DXGI_FORMAT depthFormat,\n    UINT        multiSampleCount,\n    bool        recreate\n)\n{\n    HRESULT result;\n\n    mName             = textureName;\n    mWidth            = width;\n    mHeight           = height;\n    mDepthFormat      = depthFormat;\n    mMultiSampleCount = multiSampleCount;\n\n\n    // NOTE: The following doesn't work for DX10.0 devices.\n    // They don't support binding an MSAA depth texture as \n\n    // If we have a DX 10.1 or no MSAA, then create a shader resource view, and add a CPUTTexture to the AssetLibrary\n    D3D_FEATURE_LEVEL featureLevel = gpSample->GetFeatureLevel();\n    bool supportsResourceView = ( featureLevel >= D3D_FEATURE_LEVEL_10_1) || (mMultiSampleCount==1);\n\n    D3D11_TEXTURE2D_DESC depthDesc = {\n        width,\n        height,\n        1, // MIP Levels\n        1, // Array Size\n        DXGI_FORMAT(depthFormat - 1), //  DXGI_FORMAT_R32_TYPELESS\n        mMultiSampleCount, 0,\n        D3D11_USAGE_DEFAULT,\n        D3D11_BIND_DEPTH_STENCIL | (supportsResourceView ? D3D11_BIND_SHADER_RESOURCE : 0),\n        0, // CPU Access flags\n        0 // Misc flags\n    };\n\n    // Create either a Texture2D, or Texture2DMS, depending on multisample count.\n    D3D11_DSV_DIMENSION dsvDimension = (mMultiSampleCount>1) ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D;\n\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n    result = pD3dDevice->CreateTexture2D( &depthDesc, NULL, &mpDepthTextureDX );\n    ASSERT( SUCCEEDED(result), _L(\"Failed creating depth texture.\\nAre you using MSAA with a DX10.0 GPU?\\nOnly DX10.1 and above can create a shader resource view for an MSAA depth texture.\") );\n\n    D3D11_DEPTH_STENCIL_VIEW_DESC dsvd = { depthFormat, dsvDimension, 0 };\n    result = pD3dDevice->CreateDepthStencilView( mpDepthTextureDX, &dsvd, &mpDepthStencilView );\n    ASSERT( SUCCEEDED(result), _L(\"Failed creating depth stencil view\") );\n\tCPUTSetDebugName( mpDepthStencilView, mName );\n\n    if( supportsResourceView )\n    {\n        D3D11_SRV_DIMENSION srvDimension = (mMultiSampleCount>1) ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;\n        // Create the shader-resource view\n        D3D11_SHADER_RESOURCE_VIEW_DESC depthRsDesc =\n        {\n            DXGI_FORMAT(depthFormat + 1),\n            srvDimension,\n            0\n        };\n        // TODO: Support optionally creating MIP chain.  Then, support MIP generation (e.g., GenerateMIPS()).\n        depthRsDesc.Texture2D.MipLevels = 1;\n\n        result = pD3dDevice->CreateShaderResourceView( mpDepthTextureDX, &depthRsDesc, &mpDepthResourceView );\n        ASSERT( SUCCEEDED(result), _L(\"Failed creating render target shader resource view\") );\n\t\tCPUTSetDebugName( mpDepthResourceView, textureName + _L(\" Depth\") );\n\n        if( !recreate )\n        {\n            CPUTAssetLibrary *pAssetLibrary = CPUTAssetLibrary::GetAssetLibrary();\n\n            mpDepthTexture = new CPUTTextureDX11(mName);\n            pAssetLibrary->AddTexture( mName, mpDepthTexture );\n        }\n        ((CPUTTextureDX11*)mpDepthTexture)->SetTextureAndShaderResourceView(mpDepthTextureDX, mpDepthResourceView);\n    }\n    return S_OK;\n}\n\n//-----------------------------------------------\nHRESULT CPUTRenderTargetDepth::RecreateRenderTarget(\n    UINT        width,\n    UINT        height,\n    DXGI_FORMAT depthFormat,\n    UINT        multiSampleCount\n)\n{\n    // We don't release these.  Instead, we release their resource views, and change them to the newly-created versions.\n    //SAFE_RELEASE( mpDepthTexture );\n    SAFE_RELEASE( mpDepthTextureDX );\n    SAFE_RELEASE( mpDepthResourceView );\n    SAFE_RELEASE( mpDepthStencilView );\n    // Do not release saved resource views since they are not addreff'ed\n    //SAFE_RELEASE( mpSavedColorRenderTargetView );\n    //SAFE_RELEASE( mpSavedDepthStencilView );\n\n    return CreateRenderTarget( mName, width, height, (DXGI_FORMAT_UNKNOWN != depthFormat) ? depthFormat : mDepthFormat, multiSampleCount, true );\n}\n\n//-----------------------------------------------\nvoid CPUTRenderTargetColor::SetRenderTarget(\n    CPUTRenderParameters   &renderParams,\n    CPUTRenderTargetDepth  *pDepthBuffer,\n    DWORD                   renderTargetIndex,\n    const float            *pClearColor,\n    bool                    clear,\n    float                   zClearVal\n)\n{\n    // ****************************\n    // Save the current render target \"state\" so we can restore it later.\n    // ****************************\n    mSavedWidth   = CPUTRenderTargetColor::sCurrentWidth;\n    mSavedHeight  = CPUTRenderTargetColor::sCurrentHeight;\n\n    // Save the render target view so we can restore it later.\n    mpSavedColorRenderTargetView = CPUTRenderTargetColor::GetActiveRenderTargetView();\n    mpSavedDepthStencilView      = CPUTRenderTargetDepth::GetActiveDepthStencilView();\n\n    CPUTRenderTargetColor::SetActiveWidthHeight( mWidth, mHeight );\n    CPUTRenderTargetDepth::SetActiveWidthHeight( mWidth, mHeight );\n\n    // TODO: support multiple render target views (i.e., MRT)\n    ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n    // Make sure this render target isn't currently bound as a texture.\n    static ID3D11ShaderResourceView *pSRV[16] = {0};\n    pContext->PSSetShaderResources( 0, 16, pSRV );\n\n    // Clear the shader resources to avoid a hazard warning\n    ID3D11ShaderResourceView *pNullResources[16] = {0};\n    pContext->PSSetShaderResources(0, 16, pNullResources );\n    pContext->VSSetShaderResources(0, 16, pNullResources );\n\n    // ****************************\n    // Set the new render target states\n    // ****************************\n    ID3D11DepthStencilView *pDepthStencilView = pDepthBuffer ? pDepthBuffer->GetDepthBufferView() : NULL;\n    pContext->OMSetRenderTargets( 1, &mpColorRenderTargetView, pDepthStencilView );\n\n    CPUTRenderTargetColor::SetActiveRenderTargetView(mpColorRenderTargetView);\n    CPUTRenderTargetDepth::SetActiveDepthStencilView(pDepthStencilView);\n\n    if( clear )\n    {\n        pContext->ClearRenderTargetView( mpColorRenderTargetView, pClearColor );\n        if( pDepthStencilView )\n        {\n            pContext->ClearDepthStencilView( pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, zClearVal, 0 );\n        }\n    }\n    D3D11_VIEWPORT viewport  = { 0.0f, 0.0f, (float)mWidth, (float)mHeight, 0.0f, 1.0f };\n    ((CPUTRenderParametersDX*)&renderParams)->mpContext->RSSetViewports( 1, &viewport );\n\n    mRenderTargetSet = true;\n\n    CPUTMaterialDX11::ResetStateTracking();\n} // CPUTRenderTargetColor::SetRenderTarget()\n\n//-----------------------------------------------\nvoid CPUTRenderTargetDepth::SetRenderTarget(\n    CPUTRenderParameters   &renderParams,\n    DWORD                   renderTargetIndex,\n    float                   zClearVal,\n    bool                    clear\n)\n{\n    // ****************************\n    // Save the current render target \"state\" so we can restore it later.\n    // ****************************\n    mSavedWidth   = CPUTRenderTargetDepth::GetActiveWidth();\n    mSavedHeight  = CPUTRenderTargetDepth::GetActiveHeight();\n\n    CPUTRenderTargetColor::SetActiveWidthHeight( mWidth, mHeight );\n    CPUTRenderTargetDepth::SetActiveWidthHeight( mWidth, mHeight );\n\n    // TODO: support multiple render target views (i.e., MRT)\n    ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n    // Make sure this render target isn't currently bound as a texture.\n    static ID3D11ShaderResourceView *pSRV[16] = {0};\n    pContext->PSSetShaderResources( 0, 16, pSRV );\n\n    // Save the color and depth views so we can restore them later.\n    mpSavedColorRenderTargetView = CPUTRenderTargetColor::GetActiveRenderTargetView();\n    mpSavedDepthStencilView      = CPUTRenderTargetDepth::GetActiveDepthStencilView();\n\n    // Clear the shader resources to avoid a hazard warning\n    ID3D11ShaderResourceView *pNullResources[16] = {0};\n    pContext->PSSetShaderResources(0, 16, pNullResources );\n    pContext->VSSetShaderResources(0, 16, pNullResources );\n\n    // ****************************\n    // Set the new render target states\n    // ****************************\n    ID3D11RenderTargetView *pView[1] = {NULL};\n    pContext->OMSetRenderTargets( 1, pView, mpDepthStencilView );\n\n    CPUTRenderTargetColor::SetActiveRenderTargetView( NULL );\n    CPUTRenderTargetDepth::SetActiveDepthStencilView( mpDepthStencilView );\n\n    if( clear )\n    {\n        pContext->ClearDepthStencilView( mpDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, zClearVal, 0 );\n    }\n    D3D11_VIEWPORT viewport  = { 0.0f, 0.0f, (float)mWidth, (float)mHeight, 0.0f, 1.0f };\n    ((CPUTRenderParametersDX*)&renderParams)->mpContext->RSSetViewports( 1, &viewport );\n\n    mRenderTargetSet = true;\n} // CPUTRenderTargetDepth::SetRenderTarget()\n\n//-----------------------------------------\nvoid CPUTRenderTargetColor::Resolve( CPUTRenderParameters &renderParams )\n{\n    ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n    pContext->ResolveSubresource( mpColorTextureDX,  0, mpColorTextureDXMSAA, 0, mColorFormat);\n}\n\n//-----------------------------------------\nvoid CPUTRenderTargetColor::RestoreRenderTarget( CPUTRenderParameters &renderParams )\n{\n    ASSERT( mRenderTargetSet, _L(\"Render target restored without calling SetRenderTarget()\"));\n\n    if( mMultiSampleCount>1 )\n    {\n        Resolve( renderParams );\n    }\n\n    ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n    pContext->OMSetRenderTargets( 1, &mpSavedColorRenderTargetView, mpSavedDepthStencilView );\n\n    CPUTRenderTargetColor::SetActiveWidthHeight( mSavedWidth, mSavedHeight );\n    CPUTRenderTargetDepth::SetActiveWidthHeight( mSavedWidth, mSavedHeight );\n    CPUTRenderTargetColor::SetActiveRenderTargetView( mpSavedColorRenderTargetView );\n    CPUTRenderTargetDepth::SetActiveDepthStencilView( mpSavedDepthStencilView );\n\n    // TODO: save/restore original VIEWPORT settings, not assume full-screen viewport.\n    D3D11_VIEWPORT viewport  = { 0.0f, 0.0f, (float)mSavedWidth, (float)mSavedHeight, 0.0f, 1.0f };\n    ((CPUTRenderParametersDX*)&renderParams)->mpContext->RSSetViewports( 1, &viewport );\n\n    mRenderTargetSet = false;\n} // CPUTRenderTarget::RestoreRenderTarget()\n\n//-----------------------------------------\n// TODO: This function is exactly the same as the RestoreRenderTargetColor().\nvoid CPUTRenderTargetDepth::RestoreRenderTarget( CPUTRenderParameters &renderParams )\n{\n    ASSERT( mRenderTargetSet, _L(\"Render target restored without calling SetRenderTarget()\"));\n\n    ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n    pContext->OMSetRenderTargets( 1, &mpSavedColorRenderTargetView, mpSavedDepthStencilView );\n\n    CPUTRenderTargetColor::SetActiveWidthHeight( mSavedWidth, mSavedHeight );\n    CPUTRenderTargetDepth::SetActiveWidthHeight( mSavedWidth, mSavedHeight );\n    CPUTRenderTargetColor::SetActiveRenderTargetView( mpSavedColorRenderTargetView );\n    CPUTRenderTargetDepth::SetActiveDepthStencilView( mpSavedDepthStencilView );\n\n    // TODO: save/restore original VIEWPORT settings, not assume full-screen viewport.\n    D3D11_VIEWPORT viewport  = { 0.0f, 0.0f, (float)mSavedWidth, (float)mSavedHeight, 0.0f, 1.0f };\n    ((CPUTRenderParametersDX*)&renderParams)->mpContext->RSSetViewports( 1, &viewport );\n\n    mRenderTargetSet = false;\n} // CPUTRenderTarget::RestoreRenderTarget()\n\n\n//-----------------------------------------------------------------------------\nD3D11_MAPPED_SUBRESOURCE CPUTRenderTargetColor::MapRenderTarget( CPUTRenderParameters &params, eCPUTMapType type, bool wait )\n{\n    // Mapping for DISCARD requires dynamic buffer.  Create dynamic copy?\n    // Could easily provide input flag.  But, where would we specify? Don't like specifying in the .set file\n    // Because mapping is something the application wants to do - it isn't inherent in the data.\n    // Could do Clone() and pass dynamic flag to that.\n    // But, then we have two.  Could always delete the other.\n    // Could support programatic flag - apply to all loaded models in the .set\n    // Could support programatic flag on model.  Load model first, then load set.\n    // For now, simply support CopyResource mechanism.\n    HRESULT hr;\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    if( !mpColorTextureDXStaging )\n    {\n        CD3D11_TEXTURE2D_DESC desc = mColorDesc;\n        // First time.  Create the staging resource\n        desc.Usage = D3D11_USAGE_STAGING;\n        switch( type )\n        {\n        case CPUT_MAP_READ:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n            desc.BindFlags = 0;\n            break;\n        case CPUT_MAP_READ_WRITE:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n            desc.BindFlags = 0;\n            break;\n        case CPUT_MAP_WRITE:\n        case CPUT_MAP_WRITE_DISCARD:\n        case CPUT_MAP_NO_OVERWRITE:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n            desc.BindFlags = 0;\n            break;\n        };\n        HRESULT hr = pD3dDevice->CreateTexture2D( &desc, NULL, &mpColorTextureDXStaging );\n        ASSERT( SUCCEEDED(hr), _L(\"Failed to create staging texture\") );\n        CPUTSetDebugName( mpColorTextureDXStaging, _L(\"Staging buffer\") );\n    }\n    else\n    {\n        ASSERT( mMappedType == type, _L(\"Mapping with a different CPU access than creation parameter.\") );\n    }\n\n    D3D11_MAPPED_SUBRESOURCE info;\n    switch( type )\n    {\n    case CPUT_MAP_READ:\n    case CPUT_MAP_READ_WRITE:\n        // TODO: Copying and immediately mapping probably introduces a stall.\n        // Expose the copy externally?\n        // TODO: copy only if vb has changed?\n        // Copy only first time?\n        // Copy the GPU version before we read from it.\n        pContext->CopyResource( mpColorTextureDXStaging, (mMultiSampleCount>1) ? mpColorTextureDXMSAA : mpColorTextureDX);\n        break;\n    };\n    hr = pContext->Map( mpColorTextureDXStaging, wait ? 0 : D3D11_MAP_FLAG_DO_NOT_WAIT, (D3D11_MAP)type, 0, &info );\n    mMappedType = type;\n    return info;\n} // CPUTRenderTargetColor::Map()\n\n//-----------------------------------------------------------------------------\nvoid CPUTRenderTargetColor::UnmapRenderTarget( CPUTRenderParameters &params )\n{\n    ASSERT( mMappedType != CPUT_MAP_UNDEFINED, _L(\"Can't unmap a render target that isn't mapped.\") );\n\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    pContext->Unmap( mpColorTextureDXStaging, 0 );\n\n    // If we were mapped for write, then copy staging buffer to GPU\n    switch( mMappedType )\n    {\n    case CPUT_MAP_READ:\n        break;\n    case CPUT_MAP_READ_WRITE:\n    case CPUT_MAP_WRITE:\n    case CPUT_MAP_WRITE_DISCARD:\n    case CPUT_MAP_NO_OVERWRITE:\n        pContext->CopyResource( mpColorTextureDX, mpColorTextureDXStaging );\n        break;\n    };\n\n    // mMappedType = CPUT_MAP_UNDEFINED;\n} // CPUTRenderTargetColor::Unmap()\n\n//-----------------------------------------------------------------------------\nD3D11_MAPPED_SUBRESOURCE CPUTRenderTargetDepth::MapRenderTarget( CPUTRenderParameters &params, eCPUTMapType type, bool wait )\n{\n    // Mapping for DISCARD requires dynamic buffer.  Create dynamic copy?\n    // Could easily provide input flag.  But, where would we specify? Don't like specifying in the .set file\n    // Because mapping is something the application wants to do - it isn't inherent in the data.\n    // Could do Clone() and pass dynamic flag to that.\n    // But, then we have two.  Could always delete the other.\n    // Could support programatic flag - apply to all loaded models in the .set\n    // Could support programatic flag on model.  Load model first, then load set.\n    // For now, simply support CopyResource mechanism.\n    HRESULT hr;\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    if( !mpDepthTextureDXStaging )\n    {\n        CD3D11_TEXTURE2D_DESC desc = mDepthDesc;\n        // First time.  Create the staging resource\n        desc.Usage = D3D11_USAGE_STAGING;\n        switch( type )\n        {\n        case CPUT_MAP_READ:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n            desc.BindFlags = 0;\n            break;\n        case CPUT_MAP_READ_WRITE:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n            desc.BindFlags = 0;\n            break;\n        case CPUT_MAP_WRITE:\n        case CPUT_MAP_WRITE_DISCARD:\n        case CPUT_MAP_NO_OVERWRITE:\n            desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n            desc.BindFlags = 0;\n            break;\n        };\n        HRESULT hr = pD3dDevice->CreateTexture2D( &desc, NULL, &mpDepthTextureDXStaging );\n        ASSERT( SUCCEEDED(hr), _L(\"Failed to create staging texture\") );\n        CPUTSetDebugName( mpDepthTextureDXStaging, _L(\"Staging buffer\") );\n    }\n    else\n    {\n        ASSERT( mMappedType == type, _L(\"Mapping with a different CPU access than creation parameter.\") );\n    }\n\n    D3D11_MAPPED_SUBRESOURCE info;\n    switch( type )\n    {\n    case CPUT_MAP_READ:\n    case CPUT_MAP_READ_WRITE:\n        // TODO: Copying and immediately mapping probably introduces a stall.\n        // Expose the copy externally?\n        // TODO: copy only if vb has changed?\n        // Copy only first time?\n        // Copy the GPU version before we read from it.\n        // pContext->CopyResource( mpDepthTextureDXStaging, (mMultiSampleCount>1) ? mpDepthTextureDXMSAA : mpDepthTextureDX);\n        // TODO: Do we (can we) support MSAA depth\n        pContext->CopyResource( mpDepthTextureDXStaging, mpDepthTextureDX );\n        break;\n    };\n    hr = pContext->Map( mpDepthTextureDXStaging, wait ? 0 : D3D11_MAP_FLAG_DO_NOT_WAIT, (D3D11_MAP)type, 0, &info );\n    mMappedType = type;\n    return info;\n} // CPUTRenderTargetDepth::Map()\n\n//-----------------------------------------------------------------------------\nvoid CPUTRenderTargetDepth::UnmapRenderTarget( CPUTRenderParameters &params )\n{\n    ASSERT( mMappedType != CPUT_MAP_UNDEFINED, _L(\"Can't unmap a render target that isn't mapped.\") );\n\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    pContext->Unmap( mpDepthTextureDXStaging, 0 );\n\n    // If we were mapped for write, then copy staging buffer to GPU\n    switch( mMappedType )\n    {\n    case CPUT_MAP_READ:\n        break;\n    case CPUT_MAP_READ_WRITE:\n    case CPUT_MAP_WRITE:\n    case CPUT_MAP_WRITE_DISCARD:\n    case CPUT_MAP_NO_OVERWRITE:\n        pContext->CopyResource( mpDepthTextureDX, mpDepthTextureDXStaging );\n        break;\n    };\n\n    // mMappedType = CPUT_MAP_UNDEFINED;\n} // CPUTRenderTargetDepth::Unmap()\n"
  },
  {
    "path": "CPUT/CPUT/CPUTRenderTarget.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTRENDERTARGET_H\n#define _CPUTRENDERTARGET_H\n\n#include \"CPUT.h\"\n#include \"d3d11.h\"\n\nclass CPUTMaterial;\nclass CPUTRenderParameters;\nclass CPUTTexture;\nclass CPUTBuffer;\nclass CPUTRenderTargetDepth;\n\nclass CPUTRenderTargetColor\n{\npublic:\n    static ID3D11RenderTargetView *GetActiveRenderTargetView() { return spActiveRenderTargetView; }\n    static void                    SetActiveRenderTargetView(ID3D11RenderTargetView *pView) { spActiveRenderTargetView = pView; }\n    static void                    SetActiveWidthHeight( UINT width, UINT height ) {sCurrentWidth = width; sCurrentHeight=height; }\n    static UINT                    GetActiveWidth()  {return sCurrentWidth; }\n    static UINT                    GetActiveHeight() {return sCurrentHeight; }\n\nprotected:\n    static UINT                    sCurrentWidth;\n    static UINT                    sCurrentHeight;\n    static ID3D11RenderTargetView *spActiveRenderTargetView;\n\n    cString                        mName;\n    UINT                           mWidth;\n    UINT                           mHeight;\n    bool                           mRenderTargetSet;\n    bool                           mHasUav;\n                                  \n    DXGI_FORMAT                    mColorFormat;\n    UINT                           mMultiSampleCount;\n                                  \n    CD3D11_TEXTURE2D_DESC          mColorDesc;\n    CPUTTexture                   *mpColorTexture;\n    CPUTBuffer                    *mpColorBuffer;\n    ID3D11Texture2D               *mpColorTextureDX;\n    ID3D11ShaderResourceView      *mpColorSRV;\n    ID3D11UnorderedAccessView     *mpColorUAV;\n    ID3D11RenderTargetView        *mpColorRenderTargetView;\n\n    CPUTTexture                   *mpColorTextureMSAA;\n    ID3D11Texture2D               *mpColorTextureDXMSAA;\n    ID3D11ShaderResourceView      *mpColorSRVMSAA;\n\n    ID3D11Texture2D               *mpColorTextureDXStaging;\n    eCPUTMapType                   mMappedType;\n\n    UINT                           mSavedWidth;\n    UINT                           mSavedHeight;\n    ID3D11RenderTargetView        *mpSavedColorRenderTargetView;\n    ID3D11DepthStencilView        *mpSavedDepthStencilView;\n\npublic:\n    CPUTRenderTargetColor() :\n        mWidth(0),\n        mHeight(0),\n        mRenderTargetSet(false),\n        mHasUav(false),\n        mColorFormat(DXGI_FORMAT_UNKNOWN),\n        mMultiSampleCount(1),\n        mpColorTexture(NULL),\n        mpColorBuffer(NULL),\n        mpColorTextureDX(NULL),\n        mpColorTextureDXMSAA(NULL),\n        mpColorTextureMSAA(NULL),\n        mpColorSRV(NULL),\n        mpColorUAV(NULL),\n        mpColorSRVMSAA(NULL),\n        mpColorTextureDXStaging(NULL),\n        mpColorRenderTargetView(NULL),\n        mSavedWidth(0),\n        mSavedHeight(0),\n        mpSavedColorRenderTargetView(NULL),\n        mpSavedDepthStencilView(NULL)\n    {\n    }\n\n    ~CPUTRenderTargetColor();\n\n    HRESULT CreateRenderTarget(\n        cString     textureName,\n        UINT        width,\n        UINT        height,\n        DXGI_FORMAT colorFormat,\n        UINT        multiSampleCount = 1,\n        bool        createUAV = false,\n        bool        recreate = false\n    );\n\n    HRESULT RecreateRenderTarget(\n        UINT        width,\n        UINT        height,\n        DXGI_FORMAT colorFormat = DXGI_FORMAT_UNKNOWN,\n        UINT        multiSampleCount = 1\n    );\n\n    void SetRenderTarget(\n        CPUTRenderParameters &renderParams,\n        CPUTRenderTargetDepth *pDepthBuffer = NULL,\n        DWORD renderTargetIndex=0,\n        const float *pClearColor=NULL,\n        bool  clear = false,\n        float zClearVal = 0.0f\n    );\n\n    void RestoreRenderTarget( CPUTRenderParameters &renderParams );\n    void Resolve( CPUTRenderParameters &renderParams );\n\n    CPUTTexture               *GetColorTexture()            { return mpColorTexture; }\n    CPUTBuffer                *GetColorBuffer()             { return mpColorBuffer; }\n    ID3D11ShaderResourceView  *GetColorResourceView()       { return mpColorSRV; }\n    ID3D11UnorderedAccessView *GetColorUAV()                { return mpColorUAV; }\n    UINT                       GetWidth()                   { return mWidth; }\n    UINT                       GetHeight()                  { return mHeight; }\n    DXGI_FORMAT                GetColorFormat()             { return mColorFormat; }\n\n    D3D11_MAPPED_SUBRESOURCE  MapRenderTarget(   CPUTRenderParameters &params, eCPUTMapType type, bool wait=true );\n    void                      UnmapRenderTarget( CPUTRenderParameters &params );\n};\n\n//--------------------------------------------------------------------------------------\nclass CPUTRenderTargetDepth\n{\npublic:\n    static ID3D11DepthStencilView *GetActiveDepthStencilView() { return spActiveDepthStencilView; }\n    static void                    SetActiveDepthStencilView(ID3D11DepthStencilView *pView) { spActiveDepthStencilView = pView; }\n    static void                    SetActiveWidthHeight( UINT width, UINT height ) {sCurrentWidth = width; sCurrentHeight=height; }\n    static UINT                    GetActiveWidth()  {return sCurrentWidth; }\n    static UINT                    GetActiveHeight() {return sCurrentHeight; }\n\nprotected:\n    static UINT                    sCurrentWidth;\n    static UINT                    sCurrentHeight;\n    static ID3D11DepthStencilView *spActiveDepthStencilView;\n\n    cString                        mName;\n    UINT                           mWidth;\n    UINT                           mHeight;\n    bool                           mRenderTargetSet;\n                                  \n    DXGI_FORMAT                    mDepthFormat;\n    UINT                           mMultiSampleCount;\n                                                                 \n    CD3D11_TEXTURE2D_DESC          mDepthDesc;\n    CPUTTexture                   *mpDepthTexture;\n    ID3D11Texture2D               *mpDepthTextureDX;\n    ID3D11ShaderResourceView      *mpDepthResourceView;\n    ID3D11DepthStencilView        *mpDepthStencilView;\n\n    ID3D11Texture2D               *mpDepthTextureDXStaging;\n    eCPUTMapType                   mMappedType;\n\n    UINT                           mSavedWidth;\n    UINT                           mSavedHeight;\n    ID3D11RenderTargetView        *mpSavedColorRenderTargetView;\n    ID3D11DepthStencilView        *mpSavedDepthStencilView;\n\npublic:\n    CPUTRenderTargetDepth() :\n        mWidth(0),\n        mHeight(0),\n        mRenderTargetSet(false),\n        mDepthFormat(DXGI_FORMAT_UNKNOWN),\n        mMultiSampleCount(1),\n        mpDepthTexture(NULL),\n        mpDepthTextureDX(NULL),\n        mpDepthResourceView(NULL),\n        mpDepthStencilView(NULL),\n        mpDepthTextureDXStaging(NULL),\n        mSavedWidth(0),\n        mSavedHeight(0),\n        mpSavedColorRenderTargetView(NULL),\n        mpSavedDepthStencilView(NULL)\n    {\n    }\n    ~CPUTRenderTargetDepth();\n\n    HRESULT CreateRenderTarget(\n        cString     textureName,\n        UINT        width,\n        UINT        height,\n        DXGI_FORMAT depthFormat,\n        UINT        multiSampleCount = 1,\n        bool        recreate = false\n    );\n\n    HRESULT RecreateRenderTarget(\n        UINT        width,\n        UINT        height,\n        DXGI_FORMAT depthFormat = DXGI_FORMAT_UNKNOWN,\n        UINT        multiSampleCount = 1\n    );\n\n    void SetRenderTarget(\n        CPUTRenderParameters &renderParams,\n        DWORD renderTargetIndex = 0,\n        float zClearVal = 0.0f,\n        bool  clear = false\n    );\n\n    void RestoreRenderTarget( CPUTRenderParameters &renderParams );\n\n    ID3D11DepthStencilView   *GetDepthBufferView()   { return mpDepthStencilView; }\n    ID3D11ShaderResourceView *GetDepthResourceView() { return mpDepthResourceView; }\n    UINT                      GetWidth()             { return mWidth; }\n    UINT                      GetHeight()            { return mHeight; }\n\n    D3D11_MAPPED_SUBRESOURCE  MapRenderTarget(   CPUTRenderParameters &params, eCPUTMapType type, bool wait=true );\n    void                      UnmapRenderTarget( CPUTRenderParameters &params );\n};\n\n#endif // _CPUTRENDERTARGET_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTResource.h",
    "content": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by test.rc\n//\n#define IDC_MYICON                      2\n#define IDD_TEST_DIALOG                 102\n#define IDS_APP_TITLE                   103\n#define IDD_ABOUTBOX                    103\n#define IDM_ABOUT                       104\n#define IDM_EXIT                        105\n#define IDI_TEST                        107\n#define IDI_SMALL                       108\n#define IDC_TEST                        109\n#define IDR_MAINFRAME                   128\n#define IDI_ICON1                       129\n#define IDC_STATIC                      -1\n\n// Next default values for new objects\n// \n#ifdef APSTUDIO_INVOKED\n#ifndef APSTUDIO_READONLY_SYMBOLS\n#define _APS_NO_MFC                     1\n#define _APS_NEXT_RESOURCE_VALUE        130\n#define _APS_NEXT_COMMAND_VALUE         32771\n#define _APS_NEXT_CONTROL_VALUE         1000\n#define _APS_NEXT_SYMED_VALUE           110\n#endif\n#endif\n"
  },
  {
    "path": "CPUT/CPUT/CPUTShaderDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTShaderDX11.h\"\n#include \"D3DCompiler.h\"\n#include \"CPUTConfigBlock.h\"\n#include \"CPUTMaterial.h\"\n\n//-----------------------------------------------------------------------------\nbool CPUTShaderDX11::ShaderRequiresPerModelPayload( CPUTConfigBlock &properties )\n{\n    ID3D11ShaderReflection *pReflector = NULL;\n\n    D3DReflect( mpBlob->GetBufferPointer(), mpBlob->GetBufferSize(), IID_ID3D11ShaderReflection, (void**)&pReflector);\n    // Walk through the shader input bind descriptors.\n    // If any of them begin with '@', then we need a unique material per model (i.e., we need to clone the material).\n    int ii=0;\n    D3D11_SHADER_INPUT_BIND_DESC desc;\n\tHRESULT hr = pReflector->GetResourceBindingDesc( ii++, &desc );\n\twhile( SUCCEEDED(hr) )\n\t{\n        cString tagName = s2ws(desc.Name);\n        CPUTConfigEntry *pValue = properties.GetValueByName(tagName);\n        if( !pValue->IsValid() )\n        {\n            // We didn't find our property in the file.  Is it in the global config block?\n            pValue = CPUTMaterial::mGlobalProperties.GetValueByName(tagName);\n        }\n        cString boundName = pValue->ValueAsString();\n        if( (boundName.length() > 0) && ((boundName[0] == '@') || (boundName[0] == '#')) )\n        {\n            return true;\n        }\n        hr = pReflector->GetResourceBindingDesc( ii++, &desc );\n    }\n    return false;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTShaderDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTSHADERDX11_H\n#define _CPUTSHADERDX11_H\n\n#include \"CPUT.h\"\n#include \"CPUTRefCount.h\"\n\nclass CPUTConfigBlock;\n\nclass CPUTShaderDX11 : public CPUTRefCount\n{\nprotected:\n    ID3DBlob          *mpBlob;\n\n     // Destructor is not public.  Must release instead of delete.\n    ~CPUTShaderDX11(){ SAFE_RELEASE(mpBlob); }\n\npublic:\n    CPUTShaderDX11() : mpBlob(NULL) {}\n    CPUTShaderDX11(ID3DBlob *pBlob) : mpBlob(pBlob) {}\n    ID3DBlob *GetBlob() { return mpBlob; }\n\n    bool ShaderRequiresPerModelPayload( CPUTConfigBlock &properties );\n};\n\n#endif //_CPUTPIXELSHADER_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTSlider.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTSlider.h\"\n#include \"CPUTText.h\"\n#include <math.h> // for fmod\n#include <string.h>\n\n// static initializers\nCPUT_SIZE CPUTSlider::mpActiveImageSizeList[] = { {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, };\nCPUT_SIZE CPUTSlider::mpPressedImageSizeList[] = { {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, };\nCPUT_SIZE CPUTSlider::mpDisabledImageSizeList[] = { {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, };\n\n// texture atlas information\nfloat gAtlasWidthSlider = 256.0f;\nfloat gAtlasHeightSlider= 64.0f;\n\n// Texture atlas coordinates of the active-idle button image\nint gUVLocationsSlider_active[] = { \n    141,0, 152,18,  // neutral nub    \n    170,5, 171,9,   // tick \n    175,7, 178,11,  // left tray end\n    183,7, 184,11,  // tray \n    188,7, 190,11,  // right tray end\n};\n\n// Texture atlas coordinates of the pressed button image\nint gUVLocationsSlider_pressed[] = { \n    154,0, 165,18,  // grabbed nub\n    170,5, 171,9,   // tick \n    175,7, 178,11,  // left tray end\n    183,7, 184,11,  // tray \n    188,7, 190,11,  // right tray end\n};\n\n// Texture atlas coordinates of the disabled button image\nint gUVLocationsSlider_disabled[] = { \n    193,0, 204,18,  // neutral nub    \n    217,7, 218,11,   // tick\n    206,7, 209,11,  // left tray end\n    211,7, 212,11,  // tray \n    214,7, 216,11,  // right tray end \n};\n\nfloat3 mpUVCoordsSlider_active[10];\nfloat3 mpUVCoordsSlider_pressed[10];\nfloat3 mpUVCoordsSlider_disabled[10];\n\nconst int Grip = 0;\nconst int Tick = 1;\nconst int TrayLeftCap = 2;\nconst int Tray = 3;\nconst int TrayRightCap = 4;\n\nconst int NumQuadsinSlider = 5;\n\n\n// Constructor\n//------------------------------------------------------------------------------\nCPUTSlider::CPUTSlider(const cString ControlText, CPUTControlID id, CPUTFont *pFont):    mpControlText(NULL),\n    mpMirrorBufferActive(NULL),\n    mpMirrorBufferPressed(NULL),\n    mpMirrorBufferDisabled(NULL),\n    mSliderNubTickLocation(0),\n    mSliderNubLocation(0.0f),\n    mbMouseInside(false),\n    mbStartedClickInside(false),\n    mbDrawTicks(true),\n    mpFont(pFont)\n{\n    // initialize the state variables\n    InitialStateSet();\n\n    // save the control ID for callbacks\n    mcontrolID = id;\n\n    // set as enabled\n    CPUTControl::SetEnable(true);\n\n    // default to an active control\n    mControlState = CPUT_CONTROL_ACTIVE;\n\n    // save the control ID\n    mcontrolID = id;\n\n    // set the string to display with the slider\n    mpControlText = new CPUTText(mpFont);\n    mpControlText->SetText(ControlText);\n   \n    // set default scale/start/end values\n    SetScale(mSliderStartValue, mSliderEndValue, mSliderNumberOfSteps);\n\n}\n\n// Initial state of the control's member variables\n//------------------------------------------------------------------------------\nvoid CPUTSlider::InitialStateSet()\n{\n    mcontrolType = CPUT_SLIDER;\n    mControlState = CPUT_CONTROL_ACTIVE;\n    mSliderState = CPUT_SLIDER_NIB_UNPRESSED;\n\n    mControlDimensions.x=0; mControlDimensions.y=0; mControlDimensions.width=0; mControlDimensions.height=0;\n\n    // slider state/range\n    mSliderStartValue = 1.0f;\n    mSliderEndValue = 10.0f;\n    mSliderNumberOfSteps = 10;\n    mSliderNumberOfTicks = mSliderNumberOfSteps;\n    mCurrentSliderValue = 1;\n}\n\n// destructor\n//------------------------------------------------------------------------------\nCPUTSlider::~CPUTSlider()\n{\n    UnRegisterInstanceResources();\n}\n\n//CPUTSlider\n\n// Returns the number of quads needed to draw this control\n//--------------------------------------------------------------------------------\nunsigned int CPUTSlider::GetOutputVertexCount()\n{\n    // The base slider is made of:\n    // 3 quads for the sliding 'tray'\n    // 1 for the nub\n    // 1 quad for each slider tick displayed\n    //\n    //   ---+------------------+---\n    //  | 0 |         1        | 2 |              \n    //   ---+------------------+--- \n\n    // Calculation:\n    // 3 verticies/triangle * 2 triangles/quad * (3 + 1 + (1 * number of slider ticks) )\n    if(false == mbDrawTicks)\n    {\n        return (3 * 2) * (3 + 1); \n    }\n    return ( 3 * 2 ) * (3 + 1 + (1 * mSliderNumberOfTicks)); \n}\n\n\n\n\n//\n//--------------------------------------------------------------------------------\nvoid CPUTSlider::SetPosition(int x, int y)\n{\n    mControlDimensions.x = x;\n    mControlDimensions.y = y;\n\n    Recalculate();\n\n    // text is always in the upper-left corner of the control\n    mpControlText->SetPosition(x,y);\n}\n\n// Register all resources shared by every slider control\n//--------------------------------------------------------------------------------\nCPUTResult CPUTSlider::RegisterStaticResources()\n{    \n    // calculate the UV coordinates of each of the images that\n    // make up the slider.  Do this for the active, pressed, and disabled states.\n    for(int ii=0; ii<10; ii++)\n    {\n        mpUVCoordsSlider_active[ii].x = gUVLocationsSlider_active[2*ii]/gAtlasWidthSlider;\n        mpUVCoordsSlider_active[ii].y = gUVLocationsSlider_active[2*ii+1]/gAtlasHeightSlider;\n\n        mpUVCoordsSlider_pressed[ii].x = gUVLocationsSlider_pressed[2*ii]/gAtlasWidthSlider;\n        mpUVCoordsSlider_pressed[ii].y = gUVLocationsSlider_pressed[2*ii+1]/gAtlasHeightSlider;\n\n        mpUVCoordsSlider_disabled[ii].x = gUVLocationsSlider_disabled[2*ii]/gAtlasWidthSlider;\n        mpUVCoordsSlider_disabled[ii].y = gUVLocationsSlider_disabled[2*ii+1]/gAtlasHeightSlider;\n    }\n    \n\n    // calculate the width/height in pixels of each of the 5 image slices\n    // that makes up the slider\n    int QuadIndex=0;\n    for(int ii=0; ii<NumQuadsinSlider*4; ii+=4)\n    {\n        mpActiveImageSizeList[QuadIndex].width = gUVLocationsSlider_active[ii+2] - gUVLocationsSlider_active[ii+0];\n        mpActiveImageSizeList[QuadIndex].height = gUVLocationsSlider_active[ii+3] - gUVLocationsSlider_active[ii+1];\n        \n        mpPressedImageSizeList[QuadIndex].width = gUVLocationsSlider_pressed[ii+2] - gUVLocationsSlider_pressed[ii+0];\n        mpPressedImageSizeList[QuadIndex].height = gUVLocationsSlider_pressed[ii+3] - gUVLocationsSlider_pressed[ii+1];\n\n        mpDisabledImageSizeList[QuadIndex].width = gUVLocationsSlider_disabled[ii+2] - gUVLocationsSlider_disabled[ii+0];\n        mpDisabledImageSizeList[QuadIndex].height = gUVLocationsSlider_disabled[ii+3] - gUVLocationsSlider_disabled[ii+1];\n        QuadIndex++;\n    }\n\n    return CPUT_SUCCESS;\n}\n\n// Unregister all the shared slider controls resources\n// only call this when NO more slider controls are left\n//--------------------------------------------------------------------------------\nCPUTResult CPUTSlider::UnRegisterStaticResources()\n{\n    return CPUT_SUCCESS;\n}\n\n\n\n//\n//--------------------------------------------------------------------------------\nCPUTResult CPUTSlider::RegisterInstanceResources()\n{\n    // clear any previously allocated buffers\n    SAFE_DELETE_ARRAY(mpMirrorBufferActive);\n    SAFE_DELETE_ARRAY(mpMirrorBufferPressed);\n    SAFE_DELETE_ARRAY(mpMirrorBufferDisabled);\n\n    // allocate the per-instance sizes (each button will have different dimensions)\n    mpMirrorBufferActive = new CPUTGUIVertex[6*(NumQuadsinSlider+mSliderNumberOfSteps)]; // 50 tick marks\n    mpMirrorBufferPressed = new CPUTGUIVertex[6*(NumQuadsinSlider+mSliderNumberOfSteps)];\n    mpMirrorBufferDisabled = new CPUTGUIVertex[6*(NumQuadsinSlider+mSliderNumberOfSteps)]; \n\n    return CPUT_SUCCESS;\n}\n\n//\n//--------------------------------------------------------------------------------\nCPUTResult CPUTSlider::UnRegisterInstanceResources()\n{\n    // delete the static text object\n    SAFE_DELETE(mpControlText);\n    \n    // clear vertex mirror buffers\n    SAFE_DELETE_ARRAY(mpMirrorBufferActive);\n    SAFE_DELETE_ARRAY(mpMirrorBufferPressed);\n    SAFE_DELETE_ARRAY(mpMirrorBufferDisabled);\n\n    return CPUT_SUCCESS;\n}\n\n// Handle mouse events\n//--------------------------------------------------------------------------------\nCPUTEventHandledCode CPUTSlider::HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state)\n{\n    CPUTEventHandledCode handledCode = CPUT_EVENT_UNHANDLED;\n    UNREFERENCED_PARAMETER(wheel);\n\n    // just return if the control is disabled or invisible\n    if((CPUT_CONTROL_INACTIVE == mControlState) || (false == mControlVisible) )\n    {\n        mbMouseInside = false;\n        mbStartedClickInside = false;\n        return handledCode;\n    }\n\n    // if we're continuing to be pressed, move around with the mouse movement\n    //CPUT_CONTROL_PRESSED == mControlState\n    if( (CPUT_SLIDER_NIB_PRESSED == mSliderState) && (CPUT_MOUSE_LEFT_DOWN == state) && (true == mbStartedClickInside ))\n    {\n        mSliderNubLocation = (float)x-mControlDimensions.x-mpActiveImageSizeList[Grip].width/2;\n\n        // are they dragging off the left side?\n        if(mSliderNubLocation < 0.0f)\n        {\n            mSliderNubLocation = 0.0f;\n        }\n\n        // are they dragging off the right side?\n        float TrayIndent = mpActiveImageSizeList[Grip].width / 2.0f;\n        float ExtentX = (float)(TrayIndent + mpActiveImageSizeList[TrayLeftCap].width + CPUT_DEFAULT_TRAY_WIDTH + mpActiveImageSizeList[TrayRightCap].width - mpActiveImageSizeList[Grip].width+2);\n\n        if(mSliderNubLocation > ExtentX)\n        {\n            mSliderNubLocation = ExtentX;\n        }\n\n        // recalculate the location of the items\n        Recalculate();\n\n\n        handledCode = CPUT_EVENT_HANDLED;\n        return handledCode;\n    }\n\n    // did the slider just get released?\n    if( (CPUT_SLIDER_NIB_PRESSED == mSliderState) && (CPUT_MOUSE_LEFT_DOWN != state) && (true == mbStartedClickInside ))\n    {\n        //mControlState = CPUT_CONTROL_ACTIVE;\n        mSliderState = CPUT_SLIDER_NIB_UNPRESSED;\n        SnapToNearestTick();\n        handledCode = CPUT_EVENT_HANDLED;\n\n        // trigger the user's callback\n        mpCallbackHandler->HandleCallbackEvent(1, mcontrolID, (CPUTControl*) this);\n\n        // recalculate the location of the items\n        Recalculate();\n\n        // reset flags\n        mbStartedClickInside = false;\n        return CPUT_EVENT_HANDLED;\n    }\n\n    // handle the initial grabbing of the nub\n    if(ContainsPoint(x,y))\n    {\n        handledCode = CPUT_EVENT_HANDLED;\n\n        if(CPUT_MOUSE_LEFT_DOWN == state)\n        {\n            if(!PointingAtNub(x,y))\n            {\n                mbMouseInside = false;\n                mbStartedClickInside = false;\n                //mControlState = CPUT_CONTROL_ACTIVE;\n                mSliderState = CPUT_SLIDER_NIB_UNPRESSED;\n                handledCode = CPUT_EVENT_UNHANDLED;\n            }\n            else\n            {\n                if(true == mbMouseInside)\n                {\n                    mbStartedClickInside = true;\n                    //mControlState = CPUT_CONTROL_PRESSED;\n                    mSliderState =  CPUT_SLIDER_NIB_PRESSED;\n                }\n                else\n                {\n                    // ignore\n                    return CPUT_EVENT_UNHANDLED;\n                }\n            }\n        }\n        else\n        {\n            if(PointingAtNub(x,y))\n            {\n                mbMouseInside = true;\n            }\n            else\n            {\n                //mControlState = CPUT_CONTROL_ACTIVE;\n                mSliderState = CPUT_SLIDER_NIB_UNPRESSED;\n                handledCode = CPUT_EVENT_UNHANDLED;\n                mbStartedClickInside = false;\n                mbMouseInside = false;\n            }\n        }\n\n\n    }\n    else\n    {\n        mbMouseInside = false;\n        mbStartedClickInside = false;\n    }\n\n    return handledCode;\n}\n\n// Calculate important size info used by most of the system\n//--------------------------------------------------------------------------------\nvoid CPUTSlider::CalculateLocationGuides(LocationGuides& guides)\n{\n    CPUT_RECT rect;\n    mpControlText->GetDimensions(rect.width, rect.height);\n    guides.TickIndent = mpActiveImageSizeList[0].width / 2.0f;  // cgrip\n    guides.TextDownIndent = (float)(rect.height+2);\n    guides.GripDownIndent = guides.TextDownIndent + mpActiveImageSizeList[1].height/2.0f; // CTick\n    guides.TrayDownIndent =  guides.TextDownIndent +  (mpActiveImageSizeList[0].height / 2.0f) + mpActiveImageSizeList[1].height/2.0f; // CGrip CTick\n    guides.TickSpacing = ( CPUT_DEFAULT_TRAY_WIDTH/(float)(mSliderNumberOfTicks-1));\n    guides.StepSpacing = ( CPUT_DEFAULT_TRAY_WIDTH/(float)(mSliderNumberOfSteps-1));\n    guides.TotalWidth = guides.TickIndent + mpActiveImageSizeList[2].width + CPUT_DEFAULT_TRAY_WIDTH + mpActiveImageSizeList[4].width; // CTrayLeftCap CTrayRightCap\n    guides.TotalHeight = ( guides.TextDownIndent + guides.GripDownIndent + mpActiveImageSizeList[0].height); // CGrip\n}\n\n\n// return screen-space width/height of the control\n//--------------------------------------------------------------------------------\nvoid CPUTSlider::GetDimensions(int &width, int &height)\n{\n    LocationGuides guides;\n    CalculateLocationGuides(guides);\n\n    width=(int)guides.TotalWidth;\n    height=(int)guides.TotalHeight;\n}\n\n// return the x/y window position of the control\n//--------------------------------------------------------------------------------\nvoid CPUTSlider::GetPosition(int &x, int &y)\n{\n    x = mControlDimensions.x;\n    y = mControlDimensions.y;\n}\n\n//\n//--------------------------------------------------------------------------------\nbool CPUTSlider::ContainsPoint(int x, int y)\n{\n    // calculate all the locations we'll need for drawing\n    LocationGuides guides;\n    CalculateLocationGuides(guides);\n\n    if( (x > ( mControlDimensions.x + guides.TotalWidth )) ||\n        (x < mControlDimensions.x) ||\n        (y < mControlDimensions.y) ||\n        (y > (mControlDimensions.y + guides.TotalHeight)) )\n    {\n        return false;\n    }\n\n    return true;\n}\n\n//\n//--------------------------------------------------------------------------------\nbool CPUTSlider::PointingAtNub(int x, int y)\n{\n    // calculate all the locations we'll need for drawing\n    LocationGuides guides;\n    CalculateLocationGuides(guides);\n\n    // locate the grabber coordinates\n    float UpperLeftX=mSliderNubLocation+mControlDimensions.x;\n    float UpperLeftY=(float)(mControlDimensions.y + guides.GripDownIndent);\n    float LowerRightX = UpperLeftX + mpActiveImageSizeList[Grip].width;\n    float LowerRightY = UpperLeftY + mpActiveImageSizeList[Grip].height;\n\n    if( (x>LowerRightX) || (x<UpperLeftX) ||\n        (y<UpperLeftY) || (y>LowerRightY ) )\n    {\n        return false;\n    }\n\n    return true;\n}\n\n//\n//--------------------------------------------------------------------------------\nvoid CPUTSlider::SnapToNearestTick()\n{\n    LocationGuides guides;\n    CalculateLocationGuides(guides);\n\n\n    float locationOnTray = mSliderNubLocation;\n\n    int index = (int) (locationOnTray/guides.StepSpacing);\n    float remainder = locationOnTray - index*guides.StepSpacing;\n    if(remainder > (guides.StepSpacing/2.0f))\n    {\n        if(index<(mSliderNumberOfSteps-1))\n        {\n            // snap to next higher spot\n            index++;\n        }\n        \n        // on really large scales (tiny step sizes)\n        // you can actually get over by a pixel \n        if(index>mSliderNumberOfSteps)\n        {\n            index = mSliderNumberOfSteps;\n        }\n    }\n\n    // calculate the tick mark to align with\n    mSliderNubLocation = (float)(guides.TickIndent  + (index*guides.StepSpacing) - (mpActiveImageSizeList[Grip].width/2.0f));\n   \n    Recalculate();\n\n}\n\n// Once we get above a certain number of ticks - the ticks overlap and are \n// useless, look jenky, and \n//------------------------------------------------------------------------------\nvoid CPUTSlider::ClampTicks()\n{\n    // This number is somewhat arbitrary, but visually pleasing based on current\n    // default GUI graphics.  If you change the graphics, you might want to\n    // change this number based on size of the tick, default slider size, etc\n    if(mSliderNumberOfTicks > 100)\n    {\n        mSliderNumberOfTicks = 100;\n    }    \n}\n\n// Set the string that sits above the actual slider bar\n//------------------------------------------------------------------------------\nvoid CPUTSlider::SetText(const cString ControlText)\n{\n    mpControlText->SetText(ControlText);\n\n    Recalculate();\n\n    // position or size may move - force a recalculation of this control's location\n    // if it is managed by the auto-arrange function\n    if(this->IsAutoArranged())\n    {\n        mControlNeedsArrangmentResizing = true;\n    }\n    else\n    {\n        mControlGraphicsDirty = true;\n    }\n}\n\n// Enable/disable the control\n//--------------------------------------------------------------------------------\nvoid CPUTSlider::SetEnable(bool in_bEnabled)\n{\n    if(in_bEnabled)\n    {\n        mControlState = CPUT_CONTROL_ACTIVE;\n    }\n    else\n    {\n        mControlState = CPUT_CONTROL_INACTIVE;\n    }\n\n    // set the control's text to match\n    mpControlText->SetEnable(in_bEnabled);\n\n    // recalculate control's quads \n    Recalculate();\n}\n\n// Enable the drawing of the ticks\n//------------------------------------------------------------------------------\nvoid CPUTSlider::SetTickDrawing(bool DrawTicks)\n{\n    mbDrawTicks = DrawTicks;\n    Recalculate();\n}\n\n//CPUTSlider\n\n// Set the Scale\n//--------------------------------------------------------------------------------\nCPUTResult CPUTSlider::SetScale(float StartValue, float EndValue, int NumberOfSteps)\n{\n    ASSERT( StartValue < EndValue, _L(\"Slider start greater or equal to slider end\") );\n    ASSERT( NumberOfSteps > 1 , _L(\"Slider must have more than 2 steps from start to end value\") );\n\n    mSliderStartValue = StartValue;\n    mSliderEndValue = EndValue;\n    mSliderNumberOfSteps = NumberOfSteps;\n    mSliderNumberOfTicks = mSliderNumberOfSteps;\n\n    // re-sizes the mirror buffers to accomidate the new items\n    RegisterInstanceResources();\n\n    // to avoid the problem of changing the scale and having the gripper be\n    // out of that range, setScale always sets the gripper to the start\n    // value when re-ranging the control\n    SetValue(StartValue);\n\n    // Did we calculate a reasonable number of ticks?  Or should we clamp them to a \n    // visibly pleasing amount?\n    ClampTicks();\n\n    // we've likely moved things, so re-calculate the vertex buffer\n    Recalculate();\n\n    return CPUT_SUCCESS;\n}\n\n//--------------------------------------------------------------------------------\nCPUTResult CPUTSlider::SetNumberOfTicks(int NumberOfTicks)\n{\n    // you cannot have more ticks than there are steps\n    if(mSliderNumberOfSteps < NumberOfTicks)\n    {\n        return CPUT_ERROR_INVALID_PARAMETER;\n    }\n\n    mSliderNumberOfTicks = NumberOfTicks;\n\n    // Did we calculate a reasonable number of ticks?  Or should we clamp them to a \n    // visibly pleasing amount?\n    ClampTicks();\n\n    // sometimes indent changes due to resetting, \n    // so recalculate\n    SnapToNearestTick();\n\n    return CPUT_SUCCESS;\n}\n\n// Get's the value the slider is current positioned at\n//--------------------------------------------------------------------------------\nCPUTResult CPUTSlider::GetValue(float & fValue)\n{\n    LocationGuides guides;\n    CalculateLocationGuides(guides);\n  \n    float fractpart, intpart;\n    fractpart = modf((mSliderNubLocation/guides.StepSpacing) , &intpart);\n    int index = (int) intpart;\n    if(fractpart>=0.5f)\n        index++;\n\n    float stepSizeValue = (mSliderEndValue - mSliderStartValue)/(float)(mSliderNumberOfSteps-1);\n\n    // calculate the slider location's value\n    fValue = mSliderStartValue + stepSizeValue*index;\n\n    // In extreme range cases, the calculated value might be off by a fractional amount\n    // prevent the slider from returning an above/below start/end value\n    if(fValue > mSliderEndValue)\n    {\n        fValue = mSliderEndValue;\n    }\n    if(fValue < mSliderStartValue)\n    {\n        fValue = mSliderStartValue;\n    }\n\n    return CPUT_SUCCESS;\n}\n\n// Moves the slider gripper to the specified value on the slider\n//--------------------------------------------------------------------------------\nCPUTResult CPUTSlider::SetValue(float fValue)\n{\n    if(fValue>mSliderEndValue)\n    {\n        fValue = mSliderEndValue;\n    }\n    else if(fValue<mSliderStartValue)\n    {\n        fValue = mSliderStartValue;\n    }\n\n    LocationGuides guides;\n    CalculateLocationGuides(guides);\n\n    //+ guides.TickIndent ) + (i*guides.TickSpacing);\n    float percentValue = (fValue-mSliderStartValue)/(mSliderEndValue-mSliderStartValue);\n    float locationOnTray = guides.TotalWidth  *percentValue;\n\n    int index = (int) (locationOnTray/guides.StepSpacing);\n    float remainder = locationOnTray - index*guides.StepSpacing;\n    if(remainder > (guides.StepSpacing/2.0f))\n    {\n        // snap to next higher spot\n        index++;\n    }\n\n    float stepSizeValue = (mSliderEndValue - mSliderStartValue)/(mSliderNumberOfSteps-1);\n    float remainderValue = (fValue-mSliderStartValue) - index*stepSizeValue;\n\n    float remainderPercent = remainderValue/stepSizeValue;\n    float remainderPixels = remainderPercent*guides.StepSpacing;\n    mSliderNubLocation = (float)(guides.TickIndent  + (index*guides.StepSpacing) + remainderPixels - (mpActiveImageSizeList[Grip].width/2.0f));\n\n    Recalculate();\n\n    return CPUT_SUCCESS;\n}\n\n// 'Draw' this control into the supplied vertex buffer object\n//--------------------------------------------------------------------------------\nvoid CPUTSlider::DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize, CPUTGUIVertex *pTextVertexBufferMirror, UINT *pTextInsertIndex, UINT MaxTextVertexBufferSize)\n{\n    // don't bother drawing if control is invisible, bad buffer pointers, etc\n    if(!mControlVisible)\n    {\n        return;\n    }\n    if((NULL==pVertexBufferMirror) || (NULL==pInsertIndex))\n    {\n        return;\n    }\n    if(!mpMirrorBufferActive || !mpMirrorBufferPressed)\n    {\n        return;\n    }\n    \n    // Do we have enough room to put this control into the output buffer?\n    int VertexCopyCount = GetOutputVertexCount();\n    ASSERT( (pMaxBufferSize >= *pInsertIndex + VertexCopyCount), _L(\"Too many CPUT GUI controls for allocated GUI buffer. Allocated GUI vertex buffer is too small.\\n\\nIncrease CPUT_GUI_BUFFER_SIZE size.\") );\n\n    switch(mControlState)\n    {\n    case CPUT_CONTROL_ACTIVE:\n        // copy the active+idle button into the stream\n        if(CPUT_SLIDER_NIB_PRESSED == mSliderState)\n        {\n            memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferPressed, sizeof(CPUTGUIVertex)*VertexCopyCount);\n        }        \n        else\n        {\n            memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferActive, sizeof(CPUTGUIVertex)*VertexCopyCount);\n        }\n        \n        break;\n    case CPUT_CONTROL_INACTIVE:\n        // copy the inactive button into the stream\n        memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBufferDisabled, sizeof(CPUTGUIVertex)*VertexCopyCount);\n        break;\n\n    default:\n        // error! unknown state\n        ASSERT(0,_L(\"CPUTCheckbox: Control is in unknown state\"));\n        return;\n    }\n\n    // move the uber-buffer index the tail of what we just added\n    // each new quad has 6 verts in it (and each vert has 3+2 floats in it).\n    *pInsertIndex+=VertexCopyCount;\n\n\n    // now do the text\n    // draw the text\n    if(mpControlText)\n    {\n        mpControlText->DrawIntoBuffer((CPUTGUIVertex*) pTextVertexBufferMirror, pTextInsertIndex, MaxTextVertexBufferSize);\n    }\n\n    // we'll mark the control as no longer being 'dirty'\n    mControlGraphicsDirty = false;\n}\n\n// This function re-calculates the positions of the various items in the control\n//------------------------------------------------------------------------\nvoid CPUTSlider::Recalculate()\n{\n    LocationGuides guides;\n    CalculateLocationGuides(guides);\n\n    // left tray cap\n    float TrayX=(float)(mControlDimensions.x + guides.TickIndent/2.0f);\n    float TrayY=(float)(mControlDimensions.y + guides.TrayDownIndent);\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive,\n                            0*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpActiveImageSizeList[TrayLeftCap].width, (float) mpActiveImageSizeList[TrayLeftCap].height, \n                            mpUVCoordsSlider_active[TrayLeftCap*2+0], mpUVCoordsSlider_active[TrayLeftCap*2+1]\n                        );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferPressed,\n                            0*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpActiveImageSizeList[TrayLeftCap].width, (float) mpActiveImageSizeList[TrayLeftCap].height, \n                            mpUVCoordsSlider_active[TrayLeftCap*2+0], mpUVCoordsSlider_active[TrayLeftCap*2+1]\n                        );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled,\n                            0*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpDisabledImageSizeList[TrayLeftCap].width, (float) mpDisabledImageSizeList[TrayLeftCap].height, \n                            mpUVCoordsSlider_disabled[TrayLeftCap*2+0], mpUVCoordsSlider_disabled[TrayLeftCap*2+1]\n                        );\n\n    // tray\n    TrayX=(float)(mControlDimensions.x + guides.TickIndent/2.0f + mpActiveImageSizeList[2].width); // +tray cap left\n    TrayY=(float)(mControlDimensions.y + guides.TrayDownIndent);\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive,\n                            1*6,\n                            (float) TrayX, (float) TrayY,\n                            //(float) mpActiveImageSizeList[3].width+50,\n                            (CPUT_DEFAULT_TRAY_WIDTH+guides.TickIndent/2.0f), (float) mpActiveImageSizeList[Tray].height, \n                            mpUVCoordsSlider_active[Tray*2+0], mpUVCoordsSlider_active[Tray*2+1]\n                        );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferPressed,\n                            1*6,\n                            (float) TrayX, (float) TrayY,\n                            //(float) mpActiveImageSizeList[3].width+50,\n                            (CPUT_DEFAULT_TRAY_WIDTH+guides.TickIndent/2.0f), (float) mpActiveImageSizeList[Tray].height, \n                            mpUVCoordsSlider_active[Tray*2+0], mpUVCoordsSlider_active[Tray*2+1]\n                        );  \n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled,\n                            1*6,\n                            (float) TrayX, (float) TrayY,\n                            //(float) mpActiveImageSizeList[3].width+50,\n                            (CPUT_DEFAULT_TRAY_WIDTH+guides.TickIndent/2.0f), (float) mpDisabledImageSizeList[Tray].height, \n                            mpUVCoordsSlider_disabled[Tray*2+0], mpUVCoordsSlider_disabled[Tray*2+1]\n                        );  \n\n    // right tray cap\n    TrayX=(float)(mControlDimensions.x  + guides.TickIndent/2.0f + mpActiveImageSizeList[3].width + CPUT_DEFAULT_TRAY_WIDTH + guides.TickIndent/2.0f + 1.0);\n    TrayY=(float)(mControlDimensions.y + guides.TrayDownIndent);\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive,\n                            2*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpActiveImageSizeList[TrayRightCap].width, (float) mpActiveImageSizeList[TrayRightCap].height, \n                            mpUVCoordsSlider_active[TrayRightCap*2+0], mpUVCoordsSlider_active[TrayRightCap*2+1]\n                        );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferPressed,\n                            2*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpActiveImageSizeList[TrayRightCap].width, (float) mpActiveImageSizeList[TrayRightCap].height, \n                            mpUVCoordsSlider_active[TrayRightCap*2+0], mpUVCoordsSlider_active[TrayRightCap*2+1]\n                        );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled,\n                            2*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpDisabledImageSizeList[TrayRightCap].width, (float) mpDisabledImageSizeList[TrayRightCap].height, \n                            mpUVCoordsSlider_disabled[TrayRightCap*2+0], mpUVCoordsSlider_disabled[TrayRightCap*2+1]\n                        );\n    \n    // nub\n    TrayX = mControlDimensions.x + mSliderNubLocation;\n    TrayY=(float)(mControlDimensions.y + guides.GripDownIndent);\n    AddQuadIntoMirrorBuffer(mpMirrorBufferActive,\n                            3*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpActiveImageSizeList[Grip].width, (float) mpActiveImageSizeList[Grip].height, \n                            mpUVCoordsSlider_active[Grip*2+0], mpUVCoordsSlider_active[Grip*2+1]\n                        );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferPressed,\n                            3*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpPressedImageSizeList[Grip].width, (float) mpPressedImageSizeList[Grip].height, \n                            mpUVCoordsSlider_pressed[Grip*2+0], mpUVCoordsSlider_pressed[Grip*2+1]\n                        );\n    AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled,\n                            3*6,\n                            (float) TrayX, (float) TrayY,\n                            (float) mpDisabledImageSizeList[Grip].width, (float) mpDisabledImageSizeList[Grip].height, \n                            mpUVCoordsSlider_disabled[Grip*2+0], mpUVCoordsSlider_disabled[Grip*2+1]\n                        );\n\n\n    if(mbDrawTicks)\n    {\n        // ticks\n        int uberBufferIndex=4;\n        for(int i=0; i<mSliderNumberOfTicks; i++)\n        {\n            TrayX=(float)(mControlDimensions.x  + guides.TickIndent ) + (i*guides.TickSpacing);\n            TrayY=(float)(mControlDimensions.y + guides.TextDownIndent);\n            AddQuadIntoMirrorBuffer(mpMirrorBufferActive,\n                uberBufferIndex*6,\n                (float) TrayX, (float) TrayY,\n                (float) mpActiveImageSizeList[Tick].width, (float) mpActiveImageSizeList[Tick].height, \n                mpUVCoordsSlider_active[Tick*2+0], mpUVCoordsSlider_active[Tick*2+1]\n            );\n            AddQuadIntoMirrorBuffer(mpMirrorBufferPressed,\n                uberBufferIndex*6,\n                (float) TrayX, (float) TrayY,\n                (float) mpActiveImageSizeList[Tick].width, (float) mpActiveImageSizeList[Tick].height, \n                mpUVCoordsSlider_active[Tick*2+0], mpUVCoordsSlider_active[Tick*2+1]\n            );\n            AddQuadIntoMirrorBuffer(mpMirrorBufferDisabled,\n                uberBufferIndex*6,\n                (float) TrayX, (float) TrayY,\n                (float) mpDisabledImageSizeList[Tick].width, (float) mpDisabledImageSizeList[Tick].height, \n                mpUVCoordsSlider_disabled[Tick*2+0], mpUVCoordsSlider_disabled[Tick*2+1]\n            );\n            uberBufferIndex++;\n        }\n    }\n\n    // control graphics are dirty\n    mControlGraphicsDirty = true;\n}\n\n\n\n// This generates a quad with the supplied coordinates/uv's/etc.\n//------------------------------------------------------------------------\nvoid CPUTSlider::AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer, \n    int index, \n    float x, \n    float y, \n    float w, \n    float h, \n    float3 uv1, \n    float3 uv2 )\n{\n    CPUTColor4 color;\n    color.r = 1.0f;color.g = 1.0f;color.b = 1.0f;color.a = 1.0f;\n\n    pMirrorBuffer[index+0].Pos = float3( x + 0.0f, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+0].UV = float2(uv1.x, uv1.y);\n    pMirrorBuffer[index+0].Color = color;\n\n    pMirrorBuffer[index+1].Pos = float3( x + w, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+1].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[index+1].Color = color;\n\n    pMirrorBuffer[index+2].Pos = float3( x + 0.0f, y + h, 1.0f);\n    pMirrorBuffer[index+2].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[index+2].Color = color;\n\n    pMirrorBuffer[index+3].Pos = float3( x + w, y + 0.0f, 1.0f);\n    pMirrorBuffer[index+3].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[index+3].Color = color;\n\n    pMirrorBuffer[index+4].Pos = float3( x + w, y + h, 1.0f);\n    pMirrorBuffer[index+4].UV = float2(uv2.x, uv2.y);\n    pMirrorBuffer[index+4].Color = color;\n\n    pMirrorBuffer[index+5].Pos = float3( x + 0.0f, y +h, 1.0f);\n    pMirrorBuffer[index+5].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[index+5].Color = color;\n}\n\n\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTSlider.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTSLIDER_H__\n#define __CPUTSLIDER_H__\n\n#include \"CPUTControl.h\"\n\nstruct CPUTGUIVertex;\nclass CPUTFont;\nclass CPUTText;\n\ntypedef enum CPUTSliderState\n{\n    CPUT_SLIDER_NIB_UNPRESSED,\n    CPUT_SLIDER_NIB_PRESSED,\n}CPUTSliderState;\n\n#define CPUT_NUM_IMAGES_IN_SLIDER_ARRAY 6\n#define CPUT_NUM_QUADS_IN_SLIDER_ARRAY 6\n#define CPUT_DEFAULT_TRAY_WIDTH 198\n\n// Button base - common functionality for all the controls\n//-----------------------------------------------------------------------------\nclass CPUTSlider:public CPUTControl\n{\nprotected:\n    // control position/location/dimensionss\n    CPUT_RECT mControlDimensions;\n\n    // slider state/range\n    float     mSliderStartValue;\n    float     mSliderEndValue;\n    int       mSliderNumberOfSteps;\n    int       mSliderNumberOfTicks;\n    float     mCurrentSliderValue;\n\n    // others\n    CPUTSliderState mSliderState;\n\n    void   InitialStateSet();\n\npublic:\n    // button should self-register with the GuiController on create\n    CPUTSlider(CPUTSlider &copy);\n    CPUTSlider(const cString ControlText, CPUTControlID id, CPUTFont *pFont);\n\n    virtual ~CPUTSlider();\n\n    //CPUTEventHandler\n    virtual CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key){UNREFERENCED_PARAMETER(key); return CPUT_EVENT_UNHANDLED;}\n    virtual CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n\n    // CPUTControl  &graphical manipulation\n    void GetPosition(int &x, int &y);\n    void GetDimensions(int &width, int &height);\n    void SetPosition(int x, int y);\n    virtual bool ContainsPoint(int x, int y);\n    void SetText(const cString ControlText);\n    virtual void SetEnable(bool in_bEnabled);\n    virtual unsigned int GetOutputVertexCount();\n\n    //CPUTSlider\n    CPUTResult SetScale(float StartValue, float EndValue, int NumberOfSteps);\n    CPUTResult SetNumberOfTicks(int NumberOfTicks);\n    CPUTResult GetValue(float  &fValue);\n    CPUTResult SetValue(float fValue);\n    void SetTickDrawing(bool DrawTicks);\n\n    // Register assets\n    static CPUTResult RegisterStaticResources();\n    static CPUTResult UnRegisterStaticResources();\n\n    CPUTResult RegisterInstanceResources();\n    CPUTResult UnRegisterInstanceResources();\n    \n    // draw\n    void DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize, CPUTGUIVertex *pTextVertexBufferMirror, UINT *pTextInsertIndex, UINT MaxTextVertexBufferSize);\n\n\nprotected:\n        struct LocationGuides\n    {\n        float TickIndent;\n        float TextDownIndent;\n        float GripDownIndent;\n        float TrayDownIndent;\n        float TickSpacing;\n        float StepSpacing;\n        float TotalWidth;\n        float TotalHeight;\n    };\n\n    CPUTText *mpControlText;\n    CPUTFont *mpFont;\n    int mSliderNubTickLocation;\n    float mSliderNubLocation;\n    bool mbDrawTicks;\n\n    // events\n    bool mbMouseInside;\n    bool mbStartedClickInside;\n    \n\n\n    // uberbuffer    \n    static CPUT_SIZE mpActiveImageSizeList[CPUT_NUM_IMAGES_IN_SLIDER_ARRAY];\n    static CPUT_SIZE mpPressedImageSizeList[CPUT_NUM_IMAGES_IN_SLIDER_ARRAY];\n    static CPUT_SIZE mpDisabledImageSizeList[CPUT_NUM_IMAGES_IN_SLIDER_ARRAY];\n\n    CPUTGUIVertex *mpMirrorBufferActive;\n    CPUTGUIVertex *mpMirrorBufferPressed;\n    CPUTGUIVertex *mpMirrorBufferDisabled;\n    void Recalculate();\n    void AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer, int index, float x, float y, float w, float h, float3 uv1, float3 uv2 );    \n\n    // helper functions\n    bool PointingAtNub(int x, int y);\n    void CalculateLocationGuides(LocationGuides &guides);\n    void SnapToNearestTick(); \n    void ClampTicks();\n\n};\n\n\n#endif //#ifndef __CPUTSLIDER_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTSprite.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUT_DX11.h\"\n#include \"CPUTSprite.h\"\n#include \"CPUTAssetLibrary.h\"\n#include \"CPUTMaterialDX11.h\"\n#include \"CPUTTextureDX11.h\"\n\nclass SpriteVertex\n{\npublic:\n    float mpPos[3];\n    float mpUV[2];\n};\n\n//-----------------------------------------------\nCPUTSprite::~CPUTSprite()\n{\n    SAFE_RELEASE( mpVertexBuffer );\n    SAFE_RELEASE( mpMaterial );\n    SAFE_RELEASE( mpInputLayout );\n}\n\n//-----------------------------------------------\nHRESULT CPUTSprite::CreateSprite(\n    float          spriteX,\n    float          spriteY,\n    float          spriteWidth,\n    float          spriteHeight,\n    const cString &spriteMaterialName\n)\n{\n    HRESULT result;\n\n    // Create resources so we can draw a sprite using the render target as a texture\n    mpMaterial = CPUTAssetLibrary::GetAssetLibrary()->GetMaterial( spriteMaterialName, false );\n\n    // Define the input layout\n    D3D11_INPUT_ELEMENT_DESC pLayout[] =\n    {\n        { \"POSITION\", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n        { \"TEXCOORD\", 0, DXGI_FORMAT_R32G32_FLOAT,    0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n        {0}\n    };\n    CPUTVertexShaderDX11 *pVertexShader = ((CPUTMaterialDX11*)mpMaterial)->GetVertexShader();\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n    CPUTInputLayoutCacheDX11::GetInputLayoutCache()->GetLayout( pD3dDevice, pLayout, pVertexShader, &mpInputLayout);\n\n    // ***************************************************\n    // Create Vertex Buffers\n    // ***************************************************\n    D3D11_BUFFER_DESC bd;\n    bd.Usage = D3D11_USAGE_DYNAMIC;\n    bd.ByteWidth = sizeof(SpriteVertex) * 6; // 2 tris, 3 verts each vertices\n    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;\n    bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n    bd.MiscFlags = 0;\n\n    const float top    = -spriteY; //-1.0f;\n    const float bottom = -spriteY - spriteHeight; // 1.0f;\n    const float left   =  spriteX; //-1.0f;\n    const float right  =  spriteX + spriteWidth; // 1.0f;\n    SpriteVertex pVertices[] = {\n        {  left,    top, 1.0f,   0.0f, 0.0f },\n        { right,    top, 1.0f,   1.0f, 0.0f },\n        {  left, bottom, 1.0f,   0.0f, 1.0f },\n\n        { right,    top, 1.0f,   1.0f, 0.0f },\n        { right, bottom, 1.0f,   1.0f, 1.0f },\n        {  left, bottom, 1.0f,   0.0f, 1.0f }\n    };\n    D3D11_SUBRESOURCE_DATA initialData;\n    initialData.pSysMem = pVertices;\n    initialData.SysMemPitch = sizeof( SpriteVertex );\n    initialData.SysMemSlicePitch = 0;\n\n    result = pD3dDevice->CreateBuffer( &bd, &initialData, &mpVertexBuffer );\n    ASSERT( SUCCEEDED(result), _L(\"Failed creating render target debug-sprite vertex buffer\") );\n    CPUTSetDebugName( mpVertexBuffer, _L(\"CPUTSprite vertex buffer\") );\n\n    return S_OK;\n} // CPUTSprite::CreateSprite()\n\n//-----------------------------------------\nvoid CPUTSprite::DrawSprite(\n    CPUTRenderParameters &renderParams,\n    CPUTMaterial         &material\n)\n{\n    // TODO: Should we warn here?\n    // If it doesn't draw, make sure you created it with createDebugSprite == true\n    if( mpVertexBuffer )\n    {\n        ID3D11DeviceContext *pContext = ((CPUTRenderParametersDX*)&renderParams)->mpContext;\n\n        material.SetRenderStates(renderParams);\n\n        UINT stride = sizeof( SpriteVertex );\n        UINT offset = 0;\n        pContext->IASetVertexBuffers( 0, 1, &mpVertexBuffer, &stride, &offset );\n\n        // Set the input layout\n        pContext->IASetInputLayout( mpInputLayout );\n\n        // Set primitive topology\n        pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );\n\n        pContext->Draw( 6, 0 );\n    }\n} // CPUTSprite::DrawSprite()\n\n\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTSprite.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTSPRITE_H\n#define _CPUTSPRITE_H\n\n#include \"CPUT.h\"\n#include \"d3d11.h\"\n\nclass CPUTMaterial;\nclass CPUTRenderParameters;\nclass CPUTTexture;\n\nclass CPUTSprite\n{\nprotected:\n    class SpriteVertex\n    {\n    public:\n        float mpPos[3];\n        float mpUV[2];\n    };\n\n    ID3D11Buffer      *mpVertexBuffer;\n    CPUTMaterial      *mpMaterial;\n    ID3D11InputLayout *mpInputLayout;\n\npublic:\n    CPUTSprite() :\n        mpInputLayout(NULL),\n        mpVertexBuffer(NULL),\n        mpMaterial(NULL)\n    {\n    }\n    ~CPUTSprite();\n    HRESULT CreateSprite(\n        float          spriteX = -1.0f,\n        float          spriteY = -1.0f,\n        float          spriteWidth  = 2.0f,\n        float          spriteHeight = 2.0f,\n        const cString &materialName = cString(_L(\"Sprite\"))\n    );\n    void DrawSprite( CPUTRenderParameters &renderParams ) { DrawSprite( renderParams, *mpMaterial ); }\n    void DrawSprite( CPUTRenderParameters &renderParams, CPUTMaterial &material );\n};\n\n#endif // _CPUTSPRITE_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTText.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTText.h\"\n#include \"CPUTFont.h\"\n#include <string.h>\n\n// texture atlas information\nfloat gTextAtlasWidth = 750.0f;\nfloat gTextAtlasHeight = 12.0f;\n\n// Constructor\n//------------------------------------------------------------------------------\nCPUTText::CPUTText(CPUTFont *pFont):mVertexStride(0),\n    mVertexOffset(0),\n    mpMirrorBuffer(NULL),\n    mNumCharsInString(0),\n    mZDepth(1.0f),\n    mpFont(pFont)\n{\n    // initialize the state variables\n    InitialStateSet();\n\n    mQuadSize.height=0; mQuadSize.width=0;\n    mPosition.x=0; mPosition.y=0;\n    mStaticText.clear();\n\n}\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTText::CPUTText(const cString String, CPUTControlID id, CPUTFont *pFont):mVertexStride(0),\n    mVertexOffset(0),\n    mpMirrorBuffer(NULL),\n    mNumCharsInString(0),\n    mZDepth(1.0f),\n    mpFont(pFont)\n{\n    // initialize the state variables\n    InitialStateSet();\n\n    // save the control ID for callbacks\n    mcontrolID = id;\n\n    // set as enabled\n    CPUTControl::SetEnable(true);\n\n    // reset position/sizes\n    mQuadSize.height=0; mQuadSize.width=0;\n    mPosition.x=0; mPosition.y=0;\n\n    // set the text\n    SetText(String);\n\n    // store the control id\n    mcontrolID = id;\n\n}\n\n// Initial state of the control's member variables\n//-----------------------------------------------------------------------------\nvoid CPUTText::InitialStateSet()\n{\n    mcontrolType = CPUT_STATIC;\n    mStaticState = CPUT_CONTROL_ACTIVE;\n\n    mPosition.x=0; mPosition.y=0;\n    mQuadSize.width=0; mQuadSize.height=0;\n    mDimensions.x=0; mDimensions.y=0; mDimensions.width=0; mDimensions.height=0;\n\n    // set default text color\n    mColor.r=1.0; mColor.g=1.0; mColor.b=1.0; mColor.a=1.0; \n}\n\n// Destructor\n//------------------------------------------------------------------------------\nCPUTText::~CPUTText()\n{\n    ReleaseInstanceData();\n}\n\n\n\n// Return the dimensions of this static text object (in pixels)\n//--------------------------------------------------------------------------------\nvoid CPUTText::GetDimensions(int &width, int &height)\n{\n    width = mQuadSize.width;\n    height = mQuadSize.height;\n}\n\n// Return the screen position of this static text object (in pixels)\n//--------------------------------------------------------------------------------\nvoid CPUTText::GetPosition(int &x, int &y)\n{\n    x = mPosition.x;\n    y = mPosition.y;\n}\n\n\n// fills user defined buffer with static string\n//--------------------------------------------------------------------------------\nvoid CPUTText::GetString(cString &ButtonText)\n{\n\n    // fill user defined buffer with the string\n    ButtonText = mStaticText;\n}\n\n\n// Enable/disable the text\n//--------------------------------------------------------------------------------\nvoid CPUTText::SetEnable(bool in_bEnabled) \n{\n    // set as enabled\n    CPUTControl::SetEnable(in_bEnabled);\n\n    // recalculate\n    Recalculate();\n    \n    // position or size may move - force a recalculation of this control's location\n    // if it is managed by the auto-arrange function\n    if(this->IsAutoArranged())\n    {\n        mControlNeedsArrangmentResizing = true;    \n    }\n}\n\n\n\n\n// Release all instance data\n//--------------------------------------------------------------------------------\nvoid CPUTText::ReleaseInstanceData()\n{\n    SAFE_DELETE_ARRAY(mpMirrorBuffer);\n}\n\n//--------------------------------------------------------------------------------\nCPUTResult CPUTText::RegisterInstanceData()\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    // ping the font system and tell it to load this font - or add GetFont() to the AssetLibrary(!?)\n\n    // get the pertinent mapping data back for that font\n\n    // calculate the uv's/etc for each character\n\n    // hold onto a retrievable copy of the texture text atlas that can be returned with this object/or make a function that sets that map (material?)\n\n    return result;\n}\n\n\n// Register all static assets (used by all CPUTText objects)\n//--------------------------------------------------------------------------------\nCPUTResult CPUTText::RegisterStaticResources()\n{\n    return CPUT_SUCCESS;\n}\n\n//\n//--------------------------------------------------------------------------------\nCPUTResult CPUTText::UnRegisterStaticResources()\n{\n    // todo: Release font?\n    //CPUTFontLibraryDX11::GetFontLibrary()->DeleteFont( mFontID );\n    return CPUT_SUCCESS;\n}\n\n//\n//--------------------------------------------------------------------------------\nvoid CPUTText::SetPosition(int x, int y)\n{\n    mPosition.x = x;\n    mPosition.y = y;\n\n    Recalculate();\n}\n\n\n//--------------------------------------------------------------------------------\nvoid CPUTText::DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize)\n{\n    if(!mControlVisible)\n    {\n        return;\n    }\n\n    if((NULL==pVertexBufferMirror) || (NULL==pInsertIndex))\n    {\n        return;\n    }\n\n    if(!mpMirrorBuffer) //  || !mpMirrorBufferDisabled)\n    {\n        return;\n    }\n\n    // Do we have enough room to put the text vertexes into the output buffer?\n    int VertexCopyCount = GetOutputVertexCount();\n    ASSERT( (pMaxBufferSize >= *pInsertIndex + VertexCopyCount), _L(\"Too many characters to fit in allocated GUI string vertex buffer.\\n\\nIncrease CPUT_GUI_BUFFER_STRING_SIZE size.\") );\n    \n    // copy the string quads into the target buffer\n    memcpy(&pVertexBufferMirror[*pInsertIndex], mpMirrorBuffer, sizeof(CPUTGUIVertex)*6*mNumCharsInString);\n    *pInsertIndex+=6*mNumCharsInString;\n\n    // we'll mark the control as no longer being 'dirty'\n    mControlGraphicsDirty = false;\n}\n\n\n// Calculate the number of verticies will be needed to display this string\n// \n//--------------------------------------------------------------------------------\nint CPUTText::GetOutputVertexCount()\n{\n    // A string is made of one quad per character (including spaces)\n    //\n    //   ---\n    //  | 1 | \n    //   ---\n\n    //\n    // calculation: (number of characters in string) * 3 verticies/triangle * 2 triangles/quad * 1 quad/character\n    return mNumCharsInString * (2*3);\n}\n\n// using the supplied font, build up a quad for each character in the string\n// and assemble the quads into a vertex buffer ready for drawing/memcpy\n//--------------------------------------------------------------------------------\nvoid CPUTText::Recalculate()\n{\n    SAFE_DELETE_ARRAY(mpMirrorBuffer);\n\n    mNumCharsInString = (int) mStaticText.size();\n    mpMirrorBuffer = new CPUTGUIVertex[(mNumCharsInString+1)*6];\n\n    bool Enabled = false;\n    if(CPUT_CONTROL_ACTIVE == mControlState)\n    {\n        Enabled = true;\n    }\n\n    // walk each character and build a quad from it\n    float characterPosition=0;\n    for(int ii=0; ii<mNumCharsInString; ii++)\n    {\n        // todo: unsafe cast from wchar_t to char!  Some other way???\n        char character = (char) mStaticText[ii];\n        float3 UV1, UV2;\n        CPUT_SIZE size = mpFont->GetGlyphSize(character);\n        mpFont->GetGlyphUVS(character, Enabled, UV1, UV2);\n        if('\\t'!=character)\n        {\n            AddQuadIntoMirrorBuffer(mpMirrorBuffer, ii*6, (float)mPosition.x+characterPosition, (float)mPosition.y, (float)size.width, (float)size.height, UV1, UV2);\n        }\n        else\n        {   \n            // calculate tab width = # pixels to get to next tabstop\n            // Tabs are relative from BEGINNNING of the string, not absolute based on x-position of string.  So in order for columns to line\n            // up, you need the starts of the strings to line up too.\n            // If you want 'absolute' x alignment behavior, use this:\n            //size.width = size.width - ((mPosition.x+characterPosition) % size.width);\n\n            // simply skip the amount of space indicated in the font's tab slot\n            int CurrentPositionForNextGlyph = (int) characterPosition;\n            size.width = size.width - (CurrentPositionForNextGlyph % size.width);  \n            AddQuadIntoMirrorBuffer(mpMirrorBuffer, ii*6, (float)mPosition.x+characterPosition, (float)mPosition.y, (float)size.width, (float)size.height, UV1, UV2);\n        }\n        \n        // store the max height of the string\n        mQuadSize.height = max(mQuadSize.height, size.height);\n\n        // step to next X location for next character\n        characterPosition+=size.width;\n    }\n\n    // store the total width of the string \n    mQuadSize.width = (int)characterPosition;   // width of string in pixels\n\n    // tell gui system this control image is now dirty\n    // and needs to rebuild it's draw list\n    mControlGraphicsDirty = true;\n\n    // position or size may move - force a recalculation of this control's location\n    // if it is managed by the auto-arrange function\n    if(this->IsAutoArranged())\n    {\n        mControlNeedsArrangmentResizing = true;\n    }\n}\n\n// Register quad for drawing string on\n//--------------------------------------------------------------------------------\nCPUTResult CPUTText::SetText(const cString String, float depth)\n{    \n    HEAPCHECK;\n\n    mStaticText = String;\n    mZDepth = depth;\n    \n    // call recalculate function to generate new quad\n    // list to display this text\n    Recalculate();\n     \n    HEAPCHECK;\n    return CPUT_SUCCESS;\n}\n\n// This generates a quad with the supplied coordinates/uv's/etc.\n//------------------------------------------------------------------------\nvoid CPUTText::AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer,\n    int index,\n    float x, \n    float y, \n    float w, \n    float h, \n    float3 uv1, \n    float3 uv2 )\n{\n    pMirrorBuffer[index+0].Pos = float3( x + 0.0f, y + 0.0f, mZDepth);\n    pMirrorBuffer[index+0].UV = float2(uv1.x, uv1.y);\n    pMirrorBuffer[index+0].Color = mColor;\n\n    pMirrorBuffer[index+1].Pos = float3( x + w, y + 0.0f, mZDepth);\n    pMirrorBuffer[index+1].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[index+1].Color = mColor;\n\n    pMirrorBuffer[index+2].Pos = float3( x + 0.0f, y + h, mZDepth);\n    pMirrorBuffer[index+2].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[index+2].Color = mColor;\n\n    pMirrorBuffer[index+3].Pos = float3( x + w, y + 0.0f, mZDepth);\n    pMirrorBuffer[index+3].UV = float2(uv2.x, uv1.y);\n    pMirrorBuffer[index+3].Color = mColor;\n\n    pMirrorBuffer[index+4].Pos = float3( x + w, y + h, mZDepth);\n    pMirrorBuffer[index+4].UV = float2(uv2.x, uv2.y);\n    pMirrorBuffer[index+4].Color = mColor;\n\n    pMirrorBuffer[index+5].Pos = float3( x + 0.0f, y +h, mZDepth);\n    pMirrorBuffer[index+5].UV = float2(uv1.x, uv2.y);\n    pMirrorBuffer[index+5].Color = mColor;\n}\n\n//------------------------------------------------------------------------\nCPUTResult CPUTText::SetColor(float r, float g, float b, float a)\n{\n    CPUTColor4 color;\n    color.r = r; \n    color.g = g;\n    color.b = b;\n    color.a = a;\n    return SetColor(color);\n\n}\n\n//------------------------------------------------------------------------\nCPUTResult CPUTText::SetColor(CPUTColor4 color)\n{\n    if(color != mColor)\n    {\n        mColor = color;\n\n        // dirty\n        Recalculate();\n    }\n\n    return CPUT_SUCCESS;\n}\n\n//------------------------------------------------------------------------\nCPUTColor4 CPUTText::GetColor()\n{    return mColor;\n    \n}"
  },
  {
    "path": "CPUT/CPUT/CPUTText.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTTEXT_H__\n#define __CPUTTEXT_H__\n\n#include \"CPUTControl.h\"\n#include \"CPUTGuiController.h\"\n\nclass CPUTFont;\n\n// Button base - common functionality for all the controls\n//-----------------------------------------------------------------------------\nclass CPUTText:public CPUTControl\n{\npublic:\n    // button should self-register with the GuiController on create\n    CPUTText(CPUTFont *pFont);\n    CPUTText(CPUTText& copy);\n    CPUTText(const cString String, CPUTControlID id, CPUTFont *pFont);\n\n    virtual ~CPUTText();\n\n    //Management\n    virtual void GetString(cString &ButtonText);\n\n    //CPUTEventHandler\n    virtual CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key){UNREFERENCED_PARAMETER(key); return CPUT_EVENT_UNHANDLED;}\n    virtual CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state){UNREFERENCED_PARAMETER(x);UNREFERENCED_PARAMETER(y);UNREFERENCED_PARAMETER(wheel);UNREFERENCED_PARAMETER(state);return CPUT_EVENT_UNHANDLED;}\n    \n    //CPUTControl\n    void GetDimensions(int &width, int &height);\n    void GetPosition(int &x, int &y);    \n\n    // CPUTControl\n    virtual void SetPosition(int x, int y);\n    void SetEnable(bool in_bEnabled);\n    bool ContainsPoint(int x, int y) {UNREFERENCED_PARAMETER(x);UNREFERENCED_PARAMETER(y);return false;}\n\n    // CPUTText\n    CPUTResult SetText(const cString String, float depth=0.5f);\n    CPUTResult SetColor(float r, float g, float b, float a);\n    CPUTResult SetColor(CPUTColor4 color);\n    CPUTColor4 GetColor();\n    int GetOutputVertexCount();\n\n    // Register assets\n    CPUTResult RegisterInstanceData();\n    static CPUTResult RegisterStaticResources();\n    static CPUTResult UnRegisterStaticResources();\n\n    // draw\n    void DrawIntoBuffer(CPUTGUIVertex *pVertexBufferMirror, UINT *pInsertIndex, UINT pMaxBufferSize);\n\n\nprotected:\n    // instance variables\n    CPUT_POINT          mPosition;\n    CPUT_RECT           mDimensions;\n    CPUT_SIZE           mQuadSize;\n    CPUTGUIControlState mStaticState;\n    CPUTColor4          mColor;\n        \n    UINT mVertexStride;\n    UINT mVertexOffset;\n    CPUTFont           *mpFont;\n\n    // uber-buffer\n    cString mStaticText;\n    float mZDepth;\n    CPUTGUIVertex *mpMirrorBuffer;\n    int mNumCharsInString;\n    static CPUT_SIZE mpStaticIdleImageSizeList[500]; // todo: size for #chars in font\n    static CPUT_SIZE mpStaticDisabledImageSizeList[500]; // todo: size for #chars in font\n    \n\n    // helper functions\n    void InitialStateSet();\n    void ReleaseInstanceData();\n    void Recalculate();\n    void AddQuadIntoMirrorBuffer(CPUTGUIVertex *pMirrorBuffer, int index, float x, float y, float w, float h, float3 uv1, float3 uv2 );\n\n};\n\n\n\n\n#endif //#ifndef __CPUTTEXT_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTTexture.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTTexture.h\"\n#ifdef CPUT_FOR_DX11\n#include \"CPUTTextureDX11.h\"\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n\n\nCPUTTexture *CPUTTexture::CreateTexture( const cString &name, const cString absolutePathAndFilename, bool loadAsSRGB )\n{\n    // TODO: accept DX11/OGL param to control which platform we generate.\n    // TODO: be sure to support the case where we want to support only one of them\n#ifdef CPUT_FOR_DX11\n    return CPUTTextureDX11::CreateTexture( name, absolutePathAndFilename, loadAsSRGB );\n#else    \n    #error You must supply a target graphics API (ex: #define CPUT_FOR_DX11), or implement the target API for this file.\n#endif\n    \n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTTexture.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTTEXTURE_H\n#define _CPUTTEXTURE_H\n\n#include \"CPUT.h\"\n#include \"CPUTRefCount.h\"\n\nclass CPUTTexture : public CPUTRefCount\n{\nprotected:\n    cString       mName;\n    eCPUTMapType  mMappedType;\n\n    ~CPUTTexture(){} // Destructor is not public.  Must release instead of delete.\n\npublic:\n    CPUTTexture()              : mMappedType(CPUT_MAP_UNDEFINED) {}\n\tCPUTTexture(cString &name) : mMappedType(CPUT_MAP_UNDEFINED), mName(name) {}\n    static CPUTTexture *CreateTexture( const cString &name, const cString absolutePathAndFilename, bool loadAsSRGB );\n    virtual D3D11_MAPPED_SUBRESOURCE  MapTexture(   CPUTRenderParameters &params, eCPUTMapType type, bool wait=true ) = 0;\n    virtual void                      UnmapTexture( CPUTRenderParameters &params ) =0; // TODO: Store params on Map() and don't require here.\n};\n\n#endif //_CPUTTEXTURE_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTTextureDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTTextureDX11.h\"\n\n// TODO: Would be nice to find a better place for this decl.  But, not another file just for this.\nconst cString gDXGIFormatNames[] =\n{\n    _L(\"DXGI_FORMAT_UNKNOWN\t\"),\n    _L(\"DXGI_FORMAT_R32G32B32A32_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R32G32B32A32_FLOAT\"),\n    _L(\"DXGI_FORMAT_R32G32B32A32_UINT\"),\n    _L(\"DXGI_FORMAT_R32G32B32A32_SINT\"),\n    _L(\"DXGI_FORMAT_R32G32B32_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R32G32B32_FLOAT\"),\n    _L(\"DXGI_FORMAT_R32G32B32_UINT\"),\n    _L(\"DXGI_FORMAT_R32G32B32_SINT\"),\n    _L(\"DXGI_FORMAT_R16G16B16A16_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R16G16B16A16_FLOAT\"),\n    _L(\"DXGI_FORMAT_R16G16B16A16_UNORM\"),\n    _L(\"DXGI_FORMAT_R16G16B16A16_UINT\"),\n    _L(\"DXGI_FORMAT_R16G16B16A16_SNORM\"),\n    _L(\"DXGI_FORMAT_R16G16B16A16_SINT\"),\n    _L(\"DXGI_FORMAT_R32G32_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R32G32_FLOAT\"),\n    _L(\"DXGI_FORMAT_R32G32_UINT\"),\n    _L(\"DXGI_FORMAT_R32G32_SINT\"),\n    _L(\"DXGI_FORMAT_R32G8X24_TYPELESS\"),\n    _L(\"DXGI_FORMAT_D32_FLOAT_S8X24_UINT\"),\n    _L(\"DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS\"),\n    _L(\"DXGI_FORMAT_X32_TYPELESS_G8X24_UINT\"),\n    _L(\"DXGI_FORMAT_R10G10B10A2_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R10G10B10A2_UNORM\"),\n    _L(\"DXGI_FORMAT_R10G10B10A2_UINT\"),\n    _L(\"DXGI_FORMAT_R11G11B10_FLOAT\"),\n    _L(\"DXGI_FORMAT_R8G8B8A8_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R8G8B8A8_UNORM\"),\n    _L(\"DXGI_FORMAT_R8G8B8A8_UNORM_SRGB\"),\n    _L(\"DXGI_FORMAT_R8G8B8A8_UINT\"),\n    _L(\"DXGI_FORMAT_R8G8B8A8_SNORM\"),\n    _L(\"DXGI_FORMAT_R8G8B8A8_SINT\"),\n    _L(\"DXGI_FORMAT_R16G16_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R16G16_FLOAT\"),\n    _L(\"DXGI_FORMAT_R16G16_UNORM\"),\n    _L(\"DXGI_FORMAT_R16G16_UINT\"),\n    _L(\"DXGI_FORMAT_R16G16_SNORM\"),\n    _L(\"DXGI_FORMAT_R16G16_SINT\"),\n    _L(\"DXGI_FORMAT_R32_TYPELESS\"),\n    _L(\"DXGI_FORMAT_D32_FLOAT\"),\n    _L(\"DXGI_FORMAT_R32_FLOAT\"),\n    _L(\"DXGI_FORMAT_R32_UINT\"),\n    _L(\"DXGI_FORMAT_R32_SINT\"),\n    _L(\"DXGI_FORMAT_R24G8_TYPELESS\"),\n    _L(\"DXGI_FORMAT_D24_UNORM_S8_UINT\"),\n    _L(\"DXGI_FORMAT_R24_UNORM_X8_TYPELESS\"),\n    _L(\"DXGI_FORMAT_X24_TYPELESS_G8_UINT\"),\n    _L(\"DXGI_FORMAT_R8G8_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R8G8_UNORM\"),\n    _L(\"DXGI_FORMAT_R8G8_UINT\"),\n    _L(\"DXGI_FORMAT_R8G8_SNORM\"),\n    _L(\"DXGI_FORMAT_R8G8_SINT\"),\n    _L(\"DXGI_FORMAT_R16_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R16_FLOAT\"),\n    _L(\"DXGI_FORMAT_D16_UNORM\"),\n    _L(\"DXGI_FORMAT_R16_UNORM\"),\n    _L(\"DXGI_FORMAT_R16_UINT\"),\n    _L(\"DXGI_FORMAT_R16_SNORM\"),\n    _L(\"DXGI_FORMAT_R16_SINT\"),\n    _L(\"DXGI_FORMAT_R8_TYPELESS\"),\n    _L(\"DXGI_FORMAT_R8_UNORM\"),\n    _L(\"DXGI_FORMAT_R8_UINT\"),\n    _L(\"DXGI_FORMAT_R8_SNORM\"),\n    _L(\"DXGI_FORMAT_R8_SINT\"),\n    _L(\"DXGI_FORMAT_A8_UNORM\"),\n    _L(\"DXGI_FORMAT_R1_UNORM\"),\n    _L(\"DXGI_FORMAT_R9G9B9E5_SHAREDEXP\"),\n    _L(\"DXGI_FORMAT_R8G8_B8G8_UNORM\"),\n    _L(\"DXGI_FORMAT_G8R8_G8B8_UNORM\"),\n    _L(\"DXGI_FORMAT_BC1_TYPELESS\"),\n    _L(\"DXGI_FORMAT_BC1_UNORM\"),\n    _L(\"DXGI_FORMAT_BC1_UNORM_SRGB\"),\n    _L(\"DXGI_FORMAT_BC2_TYPELESS\"),\n    _L(\"DXGI_FORMAT_BC2_UNORM\"),\n    _L(\"DXGI_FORMAT_BC2_UNORM_SRGB\"),\n    _L(\"DXGI_FORMAT_BC3_TYPELESS\"),\n    _L(\"DXGI_FORMAT_BC3_UNORM\"),\n    _L(\"DXGI_FORMAT_BC3_UNORM_SRGB\"),\n    _L(\"DXGI_FORMAT_BC4_TYPELESS\"),\n    _L(\"DXGI_FORMAT_BC4_UNORM\"),\n    _L(\"DXGI_FORMAT_BC4_SNORM\"),\n    _L(\"DXGI_FORMAT_BC5_TYPELESS\"),\n    _L(\"DXGI_FORMAT_BC5_UNORM\"),\n    _L(\"DXGI_FORMAT_BC5_SNORM\"),\n    _L(\"DXGI_FORMAT_B5G6R5_UNORM\"),\n    _L(\"DXGI_FORMAT_B5G5R5A1_UNORM\"),\n    _L(\"DXGI_FORMAT_B8G8R8A8_UNORM\"),\n    _L(\"DXGI_FORMAT_B8G8R8X8_UNORM\"),\n    _L(\"DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM\"),\n    _L(\"DXGI_FORMAT_B8G8R8A8_TYPELESS\"),\n    _L(\"DXGI_FORMAT_B8G8R8A8_UNORM_SRGB\"),\n    _L(\"DXGI_FORMAT_B8G8R8X8_TYPELESS\"),\n    _L(\"DXGI_FORMAT_B8G8R8X8_UNORM_SRGB\"),\n    _L(\"DXGI_FORMAT_BC6H_TYPELESS\"),\n    _L(\"DXGI_FORMAT_BC6H_UF16\"),\n    _L(\"DXGI_FORMAT_BC6H_SF16\"),\n    _L(\"DXGI_FORMAT_BC7_TYPELESS\"),\n    _L(\"DXGI_FORMAT_BC7_UNORM\"),\n    _L(\"DXGI_FORMAT_BC7_UNORM_SRGB\")\n};\nconst cString *gpDXGIFormatNames = gDXGIFormatNames;\n\n//-----------------------------------------------------------------------------\nCPUTTexture *CPUTTextureDX11::CreateTexture( const cString &name, const cString &absolutePathAndFilename, bool loadAsSRGB )\n{\n    // TODO:  Delegate to derived class.  We don't currently have CPUTTextureDX11\n    ID3D11ShaderResourceView *pShaderResourceView = NULL;\n    ID3D11Resource *pTexture = NULL;\n    ID3D11Device *pD3dDevice= CPUT_DX11::GetDevice();\n    CPUTResult result = CreateNativeTexture( pD3dDevice, absolutePathAndFilename, &pShaderResourceView, &pTexture, loadAsSRGB );\n    ASSERT( CPUTSUCCESS(result), _L(\"Error loading texture: '\")+absolutePathAndFilename );\n\n    CPUTTextureDX11 *pNewTexture = new CPUTTextureDX11();\n    pNewTexture->mName = name;\n    pNewTexture->SetTextureAndShaderResourceView( pTexture, pShaderResourceView );\n    pTexture->Release();\n    pShaderResourceView->Release();\n\n    CPUTAssetLibrary::GetAssetLibrary()->AddTexture( absolutePathAndFilename, pNewTexture);\n\n    return pNewTexture;\n}\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTTextureDX11::CreateNativeTexture(\n    ID3D11Device *pD3dDevice,\n    const cString &fileName,\n    ID3D11ShaderResourceView **ppShaderResourceView,\n    ID3D11Resource **ppTexture,\n    bool ForceLoadAsSRGB\n){\n    CPUTResult result;\n    HRESULT hr;\n\n    // Set up loading structure\n    //\n    // Indicate all texture parameters should come from the file\n    D3DX11_IMAGE_LOAD_INFO LoadInfo;\n    ZeroMemory(&LoadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO));\n    LoadInfo.Width          = D3DX11_FROM_FILE;\n    LoadInfo.Height         = D3DX11_FROM_FILE;\n    LoadInfo.Depth          = D3DX11_FROM_FILE;\n    LoadInfo.FirstMipLevel  = D3DX11_FROM_FILE;\n    LoadInfo.MipLevels      = D3DX11_FROM_FILE;\n    // LoadInfo.Usage          = D3D11_USAGE_IMMUTABLE; // TODO: maintain a \"mappable\" flag?  Set immutable if not mappable?\n    LoadInfo.Usage          = D3D11_USAGE_DEFAULT;\n    LoadInfo.BindFlags      = D3D11_BIND_SHADER_RESOURCE;\n    LoadInfo.CpuAccessFlags = 0;\n    LoadInfo.MiscFlags      = 0;\n    LoadInfo.MipFilter      = D3DX11_FROM_FILE;\n    LoadInfo.pSrcInfo       = NULL;\n    LoadInfo.Format         = (DXGI_FORMAT) D3DX11_FROM_FILE;\n    LoadInfo.Filter         = D3DX11_FILTER_NONE;\n\n    // if we're 'forcing' load of sRGB data, we need to verify image is sRGB\n    // or determine image format that best matches the non-sRGB source format in hopes that the conversion will be faster\n    // and data preserved\n    if(true == ForceLoadAsSRGB)\n    {\n        // get the source image info\n        D3DX11_IMAGE_INFO SrcInfo;\n        hr = D3DX11GetImageInfoFromFile(fileName.c_str(), NULL, &SrcInfo, NULL);\n        ASSERT( SUCCEEDED(hr), _L(\" - Error loading texture '\")+fileName+_L(\"'.\") );\n\n        // find a closest equivalent sRGB format\n        result = GetSRGBEquivalent(SrcInfo.Format, LoadInfo.Format);\n        ASSERT( CPUTSUCCESS(result), _L(\"Error loading texture '\")+fileName+_L(\"'.  It is specified this texture must load as sRGB, but the source image is in a format that cannot be converted to sRGB.\\n\") );\n\n        // set filtering mode to interpret 'in'-coming data as sRGB, and storing it 'out' on an sRGB surface\n        //\n        // As it stands, we don't have any tools that support sRGB output in DXT compressed textures.\n        // If we later support a format that does provide sRGB, then the filter 'in' flag will need to be removed\n        LoadInfo.Filter = D3DX11_FILTER_NONE | D3DX11_FILTER_SRGB_IN | D3DX11_FILTER_SRGB_OUT;\n#if 0\n        // DWM: TODO:  We want to catch the cases where the loader needs to do work.\n        // This happens if the texture's pixel format isn't supported by DXGI.\n        // TODO: how to determine?\n\n        // if a runtime conversion must happen report a performance warning error.\n        // Note: choosing not to assert here, as this will be a common issue.\n        if( SrcInfo.Format != LoadInfo.Format)\n        {\n            cString dxgiName = GetDXGIFormatString(SrcInfo.Format);\n            cString errorString = _T(__FUNCTION__);\n            errorString += _L(\"- PERFORMANCE WARNING: '\") + fileName\n            +_L(\"' has an image format \")+dxgiName\n            +_L(\" but must be run-time converted to \")+GetDXGIFormatString(LoadInfo.Format)\n            +_L(\" based on requested sRGB target buffer.\\n\");\n            TRACE( errorString.c_str() );\n        }\n#endif\n    }\n    hr = D3DX11CreateTextureFromFile( pD3dDevice, fileName.c_str(), &LoadInfo, NULL, ppTexture, NULL );\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to load texture: \") + fileName );\n    CPUTSetDebugName( *ppTexture, fileName );\n\n    hr = pD3dDevice->CreateShaderResourceView( *ppTexture, NULL, ppShaderResourceView );\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to create texture shader resource view.\") );\n    CPUTSetDebugName( *ppShaderResourceView, fileName );\n\n    return CPUT_SUCCESS;\n}\n\n//-----------------------------------------------------------------------------\nCPUTResult CPUTTextureDX11::GetSRGBEquivalent(DXGI_FORMAT inFormat, DXGI_FORMAT& sRGBFormat)\n{\n    switch( inFormat )\n    {\n        case DXGI_FORMAT_R8G8B8A8_UNORM:\n        case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:\n            sRGBFormat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;\n            return CPUT_SUCCESS;\n        case DXGI_FORMAT_B8G8R8X8_UNORM:\n        case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:\n            sRGBFormat = DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;\n            return CPUT_SUCCESS;\n        case DXGI_FORMAT_BC1_UNORM:\n        case DXGI_FORMAT_BC1_UNORM_SRGB:\n            sRGBFormat = DXGI_FORMAT_BC1_UNORM_SRGB;\n            return CPUT_SUCCESS;\n        case DXGI_FORMAT_BC2_UNORM:\n        case DXGI_FORMAT_BC2_UNORM_SRGB:\n            sRGBFormat = DXGI_FORMAT_BC2_UNORM_SRGB;\n            return CPUT_SUCCESS;\n        case DXGI_FORMAT_BC3_UNORM:\n        case DXGI_FORMAT_BC3_UNORM_SRGB:\n            sRGBFormat = DXGI_FORMAT_BC3_UNORM_SRGB;\n            return CPUT_SUCCESS;\n        case DXGI_FORMAT_BC7_UNORM:\n        case DXGI_FORMAT_BC7_UNORM_SRGB:\n            sRGBFormat = DXGI_FORMAT_BC7_UNORM_SRGB;\n            return CPUT_SUCCESS;\n    };\n    return CPUT_ERROR_UNSUPPORTED_SRGB_IMAGE_FORMAT;\n}\n\n// This function returns the DXGI string equivalent of the DXGI format for\n// error reporting/display purposes\n//-----------------------------------------------------------------------------\nconst cString &CPUTTextureDX11::GetDXGIFormatString(DXGI_FORMAT format)\n{\n    ASSERT( (format>=0) && (format<=DXGI_FORMAT_BC7_UNORM_SRGB), _L(\"Invalid DXGI Format.\") );\n    return gpDXGIFormatNames[format];\n}\n\n// Given a certain DXGI texture format, does it even have an equivalent sRGB one\n//-----------------------------------------------------------------------------\nbool CPUTTextureDX11::DoesExistEquivalentSRGBFormat(DXGI_FORMAT inFormat)\n{\n    DXGI_FORMAT outFormat;\n\n    if( CPUT_ERROR_UNSUPPORTED_SRGB_IMAGE_FORMAT == GetSRGBEquivalent(inFormat, outFormat) )\n    {\n        return false;\n    }\n    return true;\n}\n\n//-----------------------------------------------------------------------------\nD3D11_MAPPED_SUBRESOURCE CPUTTextureDX11::MapTexture( CPUTRenderParameters &params, eCPUTMapType type, bool wait )\n{\n    // Mapping for DISCARD requires dynamic buffer.  Create dynamic copy?\n    // Could easily provide input flag.  But, where would we specify? Don't like specifying in the .set file\n    // Because mapping is something the application wants to do - it isn't inherent in the data.\n    // Could do Clone() and pass dynamic flag to that.\n    // But, then we have two.  Could always delete the other.\n    // Could support programatic flag - apply to all loaded models in the .set\n    // Could support programatic flag on model.  Load model first, then load set.\n    // For now, simply support CopyResource mechanism.\n    HRESULT hr;\n    ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice();\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    if( !mpTextureStaging )\n    {\n        // Annoying.  We need to create the texture differently, based on dimension.\n        D3D11_RESOURCE_DIMENSION dimension;\n        mpTexture->GetType(&dimension);\n        switch( dimension )\n        {\n        case D3D11_RESOURCE_DIMENSION_TEXTURE1D:\n            {\n                D3D11_TEXTURE1D_DESC desc;\n                ((ID3D11Texture1D*)mpTexture)->GetDesc( &desc );\n                desc.Usage = D3D11_USAGE_STAGING;\n                switch( type )\n                {\n                case CPUT_MAP_READ:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n                    desc.BindFlags = 0;\n                    break;\n                case CPUT_MAP_READ_WRITE:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n                    desc.BindFlags = 0;\n                    break;\n                case CPUT_MAP_WRITE:\n                case CPUT_MAP_WRITE_DISCARD:\n                case CPUT_MAP_NO_OVERWRITE:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n                    desc.BindFlags = 0;\n                    break;\n                };\n                hr = pD3dDevice->CreateTexture1D( &desc, NULL, (ID3D11Texture1D**)&mpTextureStaging );\n                ASSERT( SUCCEEDED(hr), _L(\"Failed to create staging texture\") );\n                break;\n            }\n        case D3D11_RESOURCE_DIMENSION_TEXTURE2D:\n            {\n                D3D11_TEXTURE2D_DESC desc;\n                ((ID3D11Texture2D*)mpTexture)->GetDesc( &desc );\n                desc.Usage = D3D11_USAGE_STAGING;\n                switch( type )\n                {\n                case CPUT_MAP_READ:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n                    desc.BindFlags = 0;\n                    break;\n                case CPUT_MAP_READ_WRITE:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n                    desc.BindFlags = 0;\n                    break;\n                case CPUT_MAP_WRITE:\n                case CPUT_MAP_WRITE_DISCARD:\n                case CPUT_MAP_NO_OVERWRITE:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n                    desc.BindFlags = 0;\n                    break;\n                };\n                hr = pD3dDevice->CreateTexture2D( &desc, NULL, (ID3D11Texture2D**)&mpTextureStaging );\n                ASSERT( SUCCEEDED(hr), _L(\"Failed to create staging texture\") );\n                break;\n            }\n        case D3D11_RESOURCE_DIMENSION_TEXTURE3D:\n            {\n                D3D11_TEXTURE3D_DESC desc;\n                ((ID3D11Texture3D*)mpTexture)->GetDesc( &desc );\n                desc.Usage = D3D11_USAGE_STAGING;\n                switch( type )\n                {\n                case CPUT_MAP_READ:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n                    desc.BindFlags = 0;\n                    break;\n                case CPUT_MAP_READ_WRITE:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n                    desc.BindFlags = 0;\n                    break;\n                case CPUT_MAP_WRITE:\n                case CPUT_MAP_WRITE_DISCARD:\n                case CPUT_MAP_NO_OVERWRITE:\n                    desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n                    desc.BindFlags = 0;\n                    break;\n                };\n                hr = pD3dDevice->CreateTexture3D( &desc, NULL, (ID3D11Texture3D**)&mpTextureStaging );\n                ASSERT( SUCCEEDED(hr), _L(\"Failed to create staging texture\") );\n                break;\n            }\n        default:\n            ASSERT(0, _L(\"Unkown texture dimension\") );\n            break;\n        }\n    }\n    else\n    {\n        ASSERT( mMappedType == type, _L(\"Mapping with a different CPU access than creation parameter.\") );\n    }\n    D3D11_MAPPED_SUBRESOURCE info;\n    switch( type )\n    {\n    case CPUT_MAP_READ:\n    case CPUT_MAP_READ_WRITE:\n        // TODO: Copying and immediately mapping probably introduces a stall.\n        // Expose the copy externally?\n        // TODO: copy only if changed?\n        // Copy only first time?\n        // Copy the GPU version before we read from it.\n        pContext->CopyResource( mpTextureStaging, mpTexture );\n        break;\n    };\n    hr = pContext->Map( mpTextureStaging, wait ? 0 : D3D11_MAP_FLAG_DO_NOT_WAIT, (D3D11_MAP)type, 0, &info );\n    mMappedType = type;\n    return info;\n} // CPUTTextureDX11::Map()\n\n//-----------------------------------------------------------------------------\nvoid CPUTTextureDX11::UnmapTexture( CPUTRenderParameters &params )\n{\n    ASSERT( mMappedType != CPUT_MAP_UNDEFINED, _L(\"Can't unmap a render target that isn't mapped.\") );\n\n    CPUTRenderParametersDX *pParamsDX11 = (CPUTRenderParametersDX*)&params;\n    ID3D11DeviceContext *pContext = pParamsDX11->mpContext;\n\n    pContext->Unmap( mpTextureStaging, 0 );\n\n    // If we were mapped for write, then copy staging buffer to GPU\n    switch( mMappedType )\n    {\n    case CPUT_MAP_READ:\n        break;\n    case CPUT_MAP_READ_WRITE:\n    case CPUT_MAP_WRITE:\n    case CPUT_MAP_WRITE_DISCARD:\n    case CPUT_MAP_NO_OVERWRITE:\n        pContext->CopyResource( mpTexture, mpTextureStaging );\n        break;\n    };\n} // CPUTTextureDX11::Unmap()\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTTextureDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTTEXTUREDX11_H\n#define _CPUTTEXTUREDX11_H\n\n#include \"CPUTTexture.h\"\n#include \"CPUT_DX11.h\"\n#include <d3d11.h>\n#include <d3DX11.h>\n\nclass CPUTTextureDX11 : public CPUTTexture\n{\nprivate:\n    // resource view pointer\n    CD3D11_TEXTURE2D_DESC     mDesc;\n    ID3D11ShaderResourceView *mpShaderResourceView;\n    ID3D11Resource           *mpTexture;\n    ID3D11Resource           *mpTextureStaging;\n\n    // Destructor is not public.  Must release instead of delete.\n    ~CPUTTextureDX11() {\n        SAFE_RELEASE( mpShaderResourceView );\n        SAFE_RELEASE( mpTexture );\n        SAFE_RELEASE( mpTextureStaging );\n    }\n\npublic:\n    static const cString &GetDXGIFormatString(DXGI_FORMAT Format);\n    static CPUTResult     GetSRGBEquivalent(DXGI_FORMAT inFormat, DXGI_FORMAT& sRGBFormat);\n    static bool           DoesExistEquivalentSRGBFormat(DXGI_FORMAT inFormat);\n    static CPUTTexture   *CreateTexture( const cString &name, const cString &absolutePathAndFilename, bool loadAsSRGB );\n    static CPUTResult     CreateNativeTexture(\n                              ID3D11Device *pD3dDevice,\n                              const cString &fileName,\n                              ID3D11ShaderResourceView **ppShaderResourceView,\n                              ID3D11Resource **ppTexture,\n                              bool forceLoadAsSRGB\n                          );\n\n    CPUTTextureDX11() :\n        mpShaderResourceView(NULL),\n        mpTexture(NULL),\n        mpTextureStaging(NULL)\n    {}\n    CPUTTextureDX11(cString &name) :\n        mpShaderResourceView(NULL),\n        mpTexture(NULL),\n        mpTextureStaging(NULL),\n        CPUTTexture(name)\n    {}\n    CPUTTextureDX11(cString &name, ID3D11Resource *pTextureResource, ID3D11ShaderResourceView *pSrv ) :\n        mpTextureStaging(NULL),\n        CPUTTexture(name)\n    {\n        mpShaderResourceView = pSrv;\n        if(mpShaderResourceView) pSrv->AddRef();\n        mpTexture = pTextureResource;\n        if(mpTexture) mpTexture->AddRef();\n    }\n\n    void ReleaseTexture()\n    {\n        SAFE_RELEASE(mpShaderResourceView);\n        SAFE_RELEASE(mpTexture);\n    }\n    void SetTexture(ID3D11Resource *pTextureResource, ID3D11ShaderResourceView *pSrv )\n    {\n        mpShaderResourceView = pSrv;\n        if(mpShaderResourceView) pSrv->AddRef();\n\n        mpTexture = pTextureResource;\n        if(mpTexture) mpTexture->AddRef();\n    }\n\n    ID3D11ShaderResourceView* GetShaderResourceView()\n    {\n        return mpShaderResourceView;\n    }\n\n    void SetTextureAndShaderResourceView(ID3D11Resource *pTexture, ID3D11ShaderResourceView *pShaderResourceView)\n    {\n        // release any resources we might already be pointing too\n        SAFE_RELEASE( mpTexture );\n        SAFE_RELEASE( mpTextureStaging ); // Now out-of sync.  Will be recreated on next Map().\n        SAFE_RELEASE( mpShaderResourceView );\n        mpTexture = pTexture;\n        if( mpTexture ) mpTexture->AddRef();\n        mpShaderResourceView = pShaderResourceView;\n        mpShaderResourceView->AddRef();\n    }\n    D3D11_MAPPED_SUBRESOURCE  MapTexture(   CPUTRenderParameters &params, eCPUTMapType type, bool wait=true );\n    void                      UnmapTexture( CPUTRenderParameters &params );\n};\n\n#endif //_CPUTTEXTUREDX11_H\n\n"
  },
  {
    "path": "CPUT/CPUT/CPUTTimer.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef CPUTTIMER_H\n#define CPUTTIMER_H\n\nclass CPUTTimer\n{\npublic:\n\tvirtual void   StartTimer()     = 0;\n    virtual double StopTimer()      = 0;\n\tvirtual double GetTotalTime()   = 0; // In seconds\n\tvirtual double GetElapsedTime() = 0; // In seconds\n    virtual void   ResetTimer()     = 0;\n\tvirtual        ~CPUTTimer() {};\n};\n\n#endif CPUTTIMER_H"
  },
  {
    "path": "CPUT/CPUT/CPUTTimerWin.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTTimerWin.h\"\n\n//\n// Timer is initially not running and set to a zero state.\n// Performance counter frequency is obtained.\n//\nCPUTTimerWin::CPUTTimerWin():mbCounting(false)\n{\n    ResetTimer();\n\n\t//\n\t// Frequency only needs to be collected once.\n\t//\n\tQueryPerformanceFrequency(&mlFrequency);\n}\n\n//\n// Reset timer to zero\n//\nvoid CPUTTimerWin::ResetTimer()\n{\n    mlStartCount.QuadPart   = 0;\n    mlLastMeasured.QuadPart = 0;\n    mbCounting              = false;\n}\n\n//\n// Starts timer and resets everything. If timer is already running,\n// nothing happens.\n//\nvoid CPUTTimerWin::StartTimer()\n{\n    if(!mbCounting)\n    {\n        ResetTimer();\n        mbCounting = true;\n        QueryPerformanceCounter(&mlLastMeasured);\n        mlStartCount = mlLastMeasured;\n    }\n}\n\n//\n// If the timer is running, stops the timer and returns the time in seconds since StartTimer() was called.\n//\n// If the timer is not running, returns the time in seconds between the\n// last start/stop pair.\n//\ndouble CPUTTimerWin::StopTimer()\n{\n    if(mbCounting)\n    {\n\t\tmbCounting = false;\n        QueryPerformanceCounter(&mlLastMeasured);\n\t}\n\n\treturn (((double)(mlLastMeasured.QuadPart - mlStartCount.QuadPart)) / ((double)(mlFrequency.QuadPart)));\n}\n\n//\n// If the timer is running, returns the total time in seconds since StartTimer was called.\n//\n// If the timer is not running, returns the time in seconds between the\n// last start/stop pair.\n//\ndouble CPUTTimerWin::GetTotalTime()\n{\n\tLARGE_INTEGER temp;\n\n\tif (mbCounting) {\n\t\tQueryPerformanceCounter(&temp);\n\t\treturn ((double)(temp.QuadPart - mlStartCount.QuadPart) / (double)(mlFrequency.QuadPart));\n\t}\n\n\treturn ((double)(mlLastMeasured.QuadPart - mlStartCount.QuadPart) / (double)(mlFrequency.QuadPart));\n}\n\n//\n// If the timer is running, returns the total time in seconds that the timer\n// has run since it was last started or elapsed time was read from. Updates last measured time.\n//\n// If the timer is not running, returns 0.\n//\ndouble CPUTTimerWin::GetElapsedTime()\n{\n\tLARGE_INTEGER temp;\n\tLARGE_INTEGER elapsedTime;\n\telapsedTime.QuadPart = 0;\n\n\tif (mbCounting) {\n\t\tQueryPerformanceCounter(&temp);\n\t\telapsedTime.QuadPart = temp.QuadPart - mlLastMeasured.QuadPart;\n\t\tmlLastMeasured = temp;\n\t}\n\n\treturn ((double)elapsedTime.QuadPart / (double)mlFrequency.QuadPart);\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTTimerWin.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUTTIMER_H__\n#define __CPUTTIMER_H__\n\n\n\n#include \"CPUT.h\"\n#include \"Windows.h\"\n#include \"CPUTTimer.h\"\n\n// Simple QueryPerformanceCounter()-based timer class\n//-----------------------------------------------------------------------------\nclass CPUTTimerWin : CPUTTimer\n{\npublic:\n    CPUTTimerWin();\n    virtual void   StartTimer();\n    virtual double StopTimer();\n\tvirtual double GetTotalTime();\n\tvirtual double GetElapsedTime();\n    virtual void   ResetTimer();\n\nprivate:\n    bool mbCounting;\n    LARGE_INTEGER mlStartCount;\n    LARGE_INTEGER mlLastMeasured;\n    LARGE_INTEGER mlFrequency;\n};\n\n\n#endif // #ifndef __CPUTTIMER_H__"
  },
  {
    "path": "CPUT/CPUT/CPUTVertexShaderDX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"CPUTVertexShaderDX11.h\"\n#include \"CPUTAssetLibraryDX11.h\"\n\nCPUTVertexShaderDX11 *CPUTVertexShaderDX11::CreateVertexShader(\n    const cString        &name,\n    ID3D11Device         *pD3dDevice,\n    const cString        &shaderMain,\n    const cString        &shaderProfile\n)\n{\n    ID3DBlob            *pCompiledBlob = NULL;\n    ID3D11VertexShader  *pNewVertexShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromFile(name, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling vertex shader:\\n\\n\") );\n\n    // Create the vertex shader\n    // TODO: Move to vertex shader class\n    HRESULT hr = pD3dDevice->CreateVertexShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewVertexShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating vertex shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetVertexShader \")+name;\n    // CPUTSetDebugName(pNewVertexShader, DebugName);\n\n    CPUTVertexShaderDX11 *pNewCPUTVertexShader = new CPUTVertexShaderDX11( pNewVertexShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddVertexShader(name + shaderMain + shaderProfile, pNewCPUTVertexShader);\n    // pNewCPUTVertexShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTVertexShader;\n}\n\n//--------------------------------------------------------------------------------------\nCPUTVertexShaderDX11 *CPUTVertexShaderDX11::CreateVertexShaderFromMemory(\n    const cString      &name,\n    ID3D11Device       *pD3dDevice,\n    const cString      &shaderMain,\n    const cString      &shaderProfile,\n    const char         *pShaderSource\n)\n{\n    ID3DBlob           *pCompiledBlob = NULL;\n    ID3D11VertexShader *pNewVertexShader = NULL;\n\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary();\n    CPUTResult result = pAssetLibrary->CompileShaderFromMemory(pShaderSource, shaderMain, shaderProfile, &pCompiledBlob);\n    ASSERT( CPUTSUCCESS(result), _L(\"Error compiling vertex shader:\\n\\n\") );\n\n    // Create the vertex shader\n    // TODO: Move to vertex shader class\n    HRESULT hr = pD3dDevice->CreateVertexShader( pCompiledBlob->GetBufferPointer(), pCompiledBlob->GetBufferSize(), NULL, &pNewVertexShader );\n    ASSERT( SUCCEEDED(hr), _L(\"Error creating vertex shader:\\n\\n\") );\n    // cString DebugName = _L(\"CPUTAssetLibraryDX11::GetVertexShader \")+name;\n    // CPUTSetDebugName(pNewVertexShader, DebugName);\n\n    CPUTVertexShaderDX11 *pNewCPUTVertexShader = new CPUTVertexShaderDX11( pNewVertexShader, pCompiledBlob );\n\n    // add shader to library\n    pAssetLibrary->AddVertexShader(name + shaderMain + shaderProfile, pNewCPUTVertexShader);\n    // pNewCPUTVertexShader->Release(); // We've added it to the library, so release our reference\n\n    // return the shader (and blob)\n    return pNewCPUTVertexShader;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTVertexShaderDX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef _CPUTVERTEXSHADERDX11_H\n#define _CPUTVERTEXSHADERDX11_H\n\n#include \"CPUT.h\"\n#include \"CPUTShaderDX11.h\"\n\nclass CPUTVertexShaderDX11 : public CPUTShaderDX11\n{\nprotected:\n    ID3D11VertexShader *mpVertexShader;\n\n    // Destructor is not public.  Must release instead of delete.\n    ~CPUTVertexShaderDX11(){ SAFE_RELEASE(mpVertexShader) }\n\npublic:\n    static CPUTVertexShaderDX11 *CreateVertexShader(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile\n    );\nstatic CPUTVertexShaderDX11 *CreateVertexShaderFromMemory(\n        const cString        &name,\n        ID3D11Device         *pD3dDevice,\n        const cString        &shaderMain,\n        const cString        &shaderProfile,\n        const char           *pShaderSource\n    );\n\n    CPUTVertexShaderDX11() : mpVertexShader(NULL), CPUTShaderDX11(NULL) {}\n    CPUTVertexShaderDX11(ID3D11VertexShader *pD3D11VertexShader, ID3DBlob *pBlob) : mpVertexShader(pD3D11VertexShader), CPUTShaderDX11(pBlob) {}\n    ID3D11VertexShader *GetNativeVertexShader() { return mpVertexShader; }\n};\n\n#endif //_CPUTVERTEXSHADER_H\n"
  },
  {
    "path": "CPUT/CPUT/CPUTWindowWin.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUTWindowWin.h\"\n\n#ifdef _DEBUG\n\nTCHAR lpMsgBuf[100]; // declare global in case error is about lack of resources\n_inline void HandleWin32Error()\n{\n\t\n\tDWORD err = GetLastError();\n\tFormatMessage(\n\t\tFORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\n\t\tNULL,\n\t\terr,\n\t\tMAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n\t\tlpMsgBuf,\n\t\t100,\n\t\tNULL );\n\tASSERT(false, lpMsgBuf);\n\t\n}\n#else\n_inline void HandleWin32Error() {}\n#endif\n\n// static initializers\nCPUT* CPUTWindowWin::mCPUT=NULL;\nbool CPUTWindowWin::mbMaxMinFullScreen=false;\n\n// Constructor\n//-----------------------------------------------------------------------------\nCPUTWindowWin::CPUTWindowWin():mhInst(0),\n    mhWnd(0),\n    mAppClosedReturnCode(0)\n{\n    mAppTitle.clear();\n}\n\n// Destructor\n//-----------------------------------------------------------------------------\nCPUTWindowWin::~CPUTWindowWin()\n{\n    mAppTitle.clear();\n}\n\n// Create window\n//-----------------------------------------------------------------------------\nCPUTResult CPUTWindowWin::Create(CPUT* cput, const cString WindowTitle, const int windowWidth, const int windowHeight, int windowX, int windowY)\n{\n    if(mhWnd)\n    {\n        return CPUT_ERROR_WINDOW_ALREADY_EXISTS;\n    }\n\n    ASSERT( (windowX < GetSystemMetrics(SM_CXFULLSCREEN) && (windowX>=-1)), _L(\"You are attempting to create a window outside the desktop coordinates.  Check your CPUTWindowCreationParams\"));\n    ASSERT( (windowY < GetSystemMetrics(SM_CYFULLSCREEN) && (windowY>=-1)), _L(\"You are attempting to create a window outside the desktop coordinates.  Check your CPUTWindowCreationParams\"));\n\n    // get the hInstance of this executable\n    mhInst = GetModuleHandle(NULL);\n    if(NULL==mhInst)\n    {\n        return CPUT_ERROR_CANNOT_GET_WINDOW_INSTANCE;\n    }\n\n    // set up app title (if not specified)\n    mAppTitle = WindowTitle;\n\n    if(0==mAppTitle.compare(_L(\"\")))\n    {\n        mAppTitle = _L(\"CPUT Sample\");\n    }\n\n    // Register the Win32 class for this app\n    WNDCLASS wc;\n    if(TRUE == GetClassInfo(mhInst, mAppTitle.c_str(), &wc))\n    {\n        // point to the existing one\n        mhInst = wc.hInstance;\n    }\n    else\n    {\n        // register a new windows class\n        ATOM classID;\n        classID = MyRegisterClass(mhInst);\n        if(0==classID)\n        {\n\t\t\tHandleWin32Error();\n            return CPUT_ERROR_WINDOW_CANNOT_REGISTER_APP;\n        }\n    }\n\n\n\t// Perform Win32 instance initialization\n    const int nCmdShow = SW_SHOWNORMAL;\n\tif (false == InitInstance(nCmdShow, windowWidth, windowHeight, windowX, windowY))\n\t{\n\t\treturn CPUT_ERROR_CANNOT_GET_WINDOW_INSTANCE;\n\t}\n\n    // store the CPUT pointer\n    mCPUT = (CPUT*) cput;\n\n    return CPUT_SUCCESS;\n}\n\n\n\n// Destroy window\n//-----------------------------------------------------------------------------\nint CPUTWindowWin::Destroy()\n{\n\tDestroyWindow(mhWnd);\n\tmCPUT = NULL;\n    return true;\n}\n\n\n// Window return code on close\n//-----------------------------------------------------------------------------\nint CPUTWindowWin::ReturnCode()\n{\n    return mAppClosedReturnCode;\n}\n\n//  Register window class\n//-----------------------------------------------------------------------------\nATOM CPUTWindowWin::MyRegisterClass(HINSTANCE hInstance)\n{\n\tWNDCLASSEX wcex;\n\n\twcex.cbSize = sizeof(WNDCLASSEX);\n\n    // load icon from resource file\n    LPCTSTR iconPathName= L\"CPUT.ico\";\n    UINT icon_flags = LR_LOADFROMFILE | LR_DEFAULTSIZE;\n    HANDLE hIcon = LoadImage(hInstance, iconPathName, IMAGE_ICON, 0, 0, icon_flags);\n\n    // set up RegisterClass struct\n    wcex.style\t\t\t= CS_OWNDC | CS_HREDRAW | CS_VREDRAW;\n\twcex.lpfnWndProc\t= WndProc;\n\twcex.cbClsExtra\t\t= 0;\n\twcex.cbWndExtra\t\t= 0;\n\twcex.hInstance\t\t= hInstance;\n\twcex.hIcon\t\t\t= (HICON) hIcon; //LoadIcon(hInstance, iconSTR);\n\twcex.hCursor\t\t= LoadCursor(NULL, IDC_ARROW);\n\twcex.hbrBackground\t= (HBRUSH)(COLOR_WINDOW+1);\n\twcex.lpszMenuName\t= NULL;\n    wcex.lpszClassName\t= mAppTitle.c_str();\n\twcex.hIconSm\t\t= NULL; // LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); // no small icon for now\n\n    // register the window class\n\treturn RegisterClassEx(&wcex);\n}\n\n\n\n// InitInstance\n// Saves the windows instance handle, creates, and displays the main program\n// window\n//-----------------------------------------------------------------------------\nBOOL CPUTWindowWin::InitInstance(int nCmdShow, int windowWidth, int windowHeight, int windowX, int windowY)\n{\n    // assure we have a valid hInstance\n    ASSERT(NULL!=mhInst, _L(\"\"));\n\n   // zero sized windows means - you choose the size. :)\n   if( (0==windowWidth) || (0==windowHeight) )\n   {\n       CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n       pServices->GetDesktopDimensions(&windowWidth, &windowHeight);\n\n       // default window size 1280x720\n       // but if screen is smaller than 1280x720, then pick 1/3 the screen size \n       // so that it doesn't appear off the edges\n       if(1280>windowWidth)\n       {\n           windowWidth = (2*windowWidth)/3;\n           windowHeight = (2*windowHeight)/3;\n       }\n       else\n       {\n        \n        windowWidth=1280;\n        windowHeight=720;\n       }\n   }\n\n   // set up size structure\n   RECT rc = { 0, 0, windowWidth, windowHeight };\n   AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );\n\n   // if x = -1, then let windows decide where to put it\n   if(-1==windowX)\n   {\n       windowX = CW_USEDEFAULT;\n   }\n\n   // create the window\n   mhWnd = CreateWindow(mAppTitle.c_str(), mAppTitle.c_str(),\n       WS_OVERLAPPEDWINDOW,\n       windowX, //CW_USEDEFAULT,\n       windowY, //CW_USEDEFAULT,\n       rc.right - rc.left,\n       rc.bottom - rc.top,\n       NULL,\n       NULL,\n       mhInst,\n       NULL);\n\n   if (!mhWnd)\n   {\n      return FALSE;\n   }\n\n   ShowWindow(mhWnd, nCmdShow);\n   UpdateWindow(mhWnd);\n\n   // initialize the OS services with the hWND so you can make\n   // reference to this object\n   CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n   pServices->SethWnd(mhWnd);\n\n   return TRUE;\n}\n\n\n//\n// WndProc\n// Handles the main message loop's events/messages\n//-----------------------------------------------------------------------------\nLRESULT CALLBACK CPUTWindowWin::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\n{\n    CPUTEventHandledCode handledCode = CPUT_EVENT_UNHANDLED;\n    LRESULT res;\n\n    switch (message)\n\t{\n\tcase WM_COMMAND:\n        int     wmId, wmEvent;\n\t\twmId    = LOWORD(wParam);\n\t\twmEvent = HIWORD(wParam);\n\n        // handle any menu item events here\n        // see reference code in file history for examples\n\t\tbreak;\n\n    case WM_KEYDOWN:\n        if(mCPUT)\n        {\n            CPUTKey key = ConvertSpecialKeyCode(wParam, lParam);\n            if(KEY_NONE!=key)\n            {\n                handledCode = mCPUT->CPUTHandleKeyboardEvent( key );\n            }\n        }\n        break;\n\n    case WM_CHAR: // WM_KEYDOWN: gives you EVERY key - including shifts/etc\n        if(mCPUT)\n        {\n            CPUTKey key = ConvertKeyCode(wParam, lParam);\n            if(KEY_NONE!=key)\n            {\n                handledCode = mCPUT->CPUTHandleKeyboardEvent( key );\n            }\n        }\n        break;\n\n    case WM_LBUTTONDBLCLK:\n    case WM_MBUTTONDBLCLK:\n    case WM_RBUTTONDBLCLK:\n        // handle double-click events\n        break;\n\n    case WM_LBUTTONDOWN:\n    case WM_LBUTTONUP:\n    case WM_MBUTTONDOWN:\n    case WM_MBUTTONUP:\n    case WM_RBUTTONDOWN:\n    case WM_RBUTTONUP:\n    case WM_MOUSEMOVE:\n        if(mCPUT)\n        {\n            CPUTMouseState state = ConvertMouseState(wParam);\n\n            short xPos = LOWORD(lParam);\n            short yPos = HIWORD(lParam);\n\n            handledCode = mCPUT->CPUTHandleMouseEvent(xPos, yPos, 0, state);\n        }\n        break;\n\n    case WM_MOUSEWHEEL:\n        if(mCPUT)\n        {\n            // get mouse position\n            short xPos = LOWORD(lParam);\n            short yPos = HIWORD(lParam);\n\n            // get wheel delta\n            int wheel = GET_WHEEL_DELTA_WPARAM(wParam);  // one 'click'\n\n            handledCode = mCPUT->CPUTHandleMouseEvent(xPos, yPos, wheel, CPUT_MOUSE_WHEEL);\n        }\n        return 0;\n        break;\n\n\tcase WM_PAINT:\n\t    PAINTSTRUCT ps;\n\t    HDC hdc;\n\t\thdc = BeginPaint(hWnd, &ps);\n        EndPaint(hWnd, &ps);\n        break;\n\n    case WM_SIZING:\n    case WM_MOVING:\n    case WM_ERASEBKGND:\n        // overriding this to do nothing avoids flicker and\n        // the expense of re-creating tons of gfx contexts as it resizes\n        break;\n\n    //case WM_ACTIVATE:\n        // check for maximize/minimize\n      //  break;\n\n    case WM_SIZE:\n        int width, height;\n        height = HIWORD(lParam);\n        width  = LOWORD(lParam);\n            \n        RECT windowRect;\n        if(0==GetClientRect(hWnd, &windowRect)) // this gets the client area inside the window frame *excluding* frames/menu bar/etc\n            break;\n        width = windowRect.right - windowRect.left;        \n        height = windowRect.bottom - windowRect.top;\n\n        // if we have shrunk to 0 width/height - do not pass on this kind of resize - leads to \n        // various render target resizing warnings\n        if(0==width || 0==height)\n            break;\n\n        if(mCPUT)\n        {\n            // maximize/minimize effect\n            if( (SIZE_MAXIMIZED == wParam) ) \n            {\n                // resize for new max/min size\n                mCPUT->ResizeWindow(width,height);\n                mbMaxMinFullScreen = true;\n            }\n            else if(SIZE_RESTORED == wParam)\n            {\n                if(true == mbMaxMinFullScreen)\n                {\n                    // resize for new max/min size\n                    mCPUT->ResizeWindow(width,height);\n                    mbMaxMinFullScreen = false;\n                }\n                else\n                {\n                    // do a stretch-blit while actively sizing by just rendering to un-resized back buffer\n                    mCPUT->ResizeWindowSoft(width, height);\n                }\n            }\n        }\n        break;\n    \n    case WM_EXITSIZEMOVE:\n        // update the system's size and make callback\n        if(mCPUT)\n        {\n            RECT windowRect;\n            if(0==GetClientRect(hWnd, &windowRect)) // this gets the client area inside the window frame *excluding* frames/menu bar/etc\n                break;\n\n            width = windowRect.right - windowRect.left;\n            height = windowRect.bottom - windowRect.top;\n\n            // if we have shrunk to 0 width/height - do not pass on this kind of resize - leads to \n            // various render target resizing warnings\n            if(0==width || 0==height)\n                break;\n\n            mCPUT->ResizeWindow(width,height);\n        }\n        break;\n\n\n    case WM_DESTROY:\n        // time to shut down the system\n        PostQuitMessage(0);\n        break;\n\n\tdefault:\n        // we don't handle it - pass it on thru to parent\n        res = DefWindowProc(hWnd, message, wParam, lParam);\n        return res;\n\t}\n\n    // translate handled code\n    if(CPUT_EVENT_HANDLED == handledCode)\n    {\n        return 1;\n    }\n\n\treturn 0;\n}\n\n\n// Convert OS specific key events to CPUT events\n//-----------------------------------------------------------------------------da\nCPUTKey CPUTWindowWin::ConvertKeyCode(WPARAM wParam, LPARAM lParam)\n{\n    UNREFERENCED_PARAMETER(wParam);\n    UNREFERENCED_PARAMETER(lParam);\n    switch(wParam)\n    {\n    case 'a':\n    case 'A':\n        return KEY_A;\n    case 'b':\n    case 'B':\n        return KEY_B;\n    case 'c':\n    case 'C':\n        return KEY_C;\n    case 'd':\n    case 'D':\n        return KEY_D;\n    case 'e':\n    case 'E':\n        return KEY_E;\n    case 'f':\n    case 'F':\n        return KEY_F;\n    case 'g':\n    case 'G':\n        return KEY_G;\n    case 'h':\n    case 'H':\n        return KEY_H;\n    case 'i':\n    case 'I':\n        return KEY_I;\n    case 'j':\n    case 'J':\n        return KEY_J;\n    case 'k':\n    case 'K':\n        return KEY_K;\n    case 'l':\n    case 'L':\n        return KEY_L;\n    case 'm':\n    case 'M':\n        return KEY_M;\n    case 'n':\n    case 'N':\n        return KEY_N;\n    case 'o':\n    case 'O':\n        return KEY_O;\n    case 'p':\n    case 'P':\n        return KEY_P;\n    case 'Q':\n    case 'q':\n        return KEY_Q;\n    case 'r':\n    case 'R':\n        return KEY_R;\n    case 's':\n    case 'S':\n        return KEY_S;\n    case 't':\n    case 'T':\n        return KEY_T;\n    case 'u':\n    case 'U':\n        return KEY_U;\n    case 'v':\n    case 'V':\n        return KEY_V;\n    case 'w':\n    case 'W':\n        return KEY_W;\n    case 'x':\n    case 'X':\n        return KEY_X;\n    case 'y':\n    case 'Y':\n        return KEY_Y;\n    case 'z':\n    case 'Z':\n        return KEY_Z;\n\n\n        // number keys\n    case '1':\n        return KEY_1;\n    case '2':\n        return KEY_2;\n    case '3':\n        return KEY_3;\n    case '4':\n        return KEY_4;\n    case '5':\n        return KEY_5;\n    case '6':\n        return KEY_6;\n    case '7':\n        return KEY_7;\n    case '8':\n        return KEY_8;\n    case '9':\n        return KEY_9;\n    case '0':\n        return KEY_0;\n\n\n    // symbols\n    case ' ':\n        return KEY_SPACE;\n    case '`':\n        return KEY_BACKQUOTE;\n    case '~':\n        return KEY_TILDE;\n    case '!':\n        return KEY_EXCLAMATION;\n    case '@':\n        return KEY_AT;\n    case '#':\n        return KEY_HASH;\n    case '$':\n        return KEY_$;\n    case '%':\n        return KEY_PERCENT;\n    case '^':\n        return KEY_CARROT;\n    case '&':\n        return KEY_ANDSIGN;\n    case '*':\n        return KEY_STAR;\n    case '(':\n        return KEY_OPENPAREN;\n    case ')':\n        return KEY_CLOSEPARN;\n    case '_':\n        return KEY__;\n    case '-':\n        return KEY_MINUS;\n    case '+':\n        return KEY_PLUS;\n    case '[':\n        return KEY_OPENBRACKET;\n    case ']':\n        return KEY_CLOSEBRACKET;\n    case '{':\n        return KEY_OPENBRACE;\n    case '}':\n        return KEY_CLOSEBRACE;\n    case '\\\\':\n        return KEY_BACKSLASH;\n    case '|':\n        return KEY_PIPE;\n    case ';':\n        return KEY_SEMICOLON;\n    case ':':\n        return KEY_COLON;\n    case '\\'':\n        return KEY_SINGLEQUOTE;\n    case '\\\"':\n        return KEY_QUOTE;\n    case ',':\n        return KEY_COMMA;\n    case '.':\n        return KEY_PERIOD;\n    case '/':\n        return KEY_SLASH;\n    case '<':\n        return KEY_LESS;\n    case '>':\n        return KEY_GREATER;\n    case '?':\n        return KEY_QUESTION;\n    }\n\n    return KEY_NONE;\n}\n\n// Convert extended key events to CPUT events\n//-----------------------------------------------------------------------------\nCPUTKey CPUTWindowWin::ConvertSpecialKeyCode(WPARAM wParam, LPARAM lParam)\n{\n    UNREFERENCED_PARAMETER(lParam);\n    switch(wParam)\n    {\n    // function keys\n    case VK_F1:\n        return KEY_F1;\n    case VK_F2:\n        return KEY_F2;\n    case VK_F3:\n        return KEY_F3;\n    case VK_F4:\n        return KEY_F4;\n    case VK_F5:\n        return KEY_F5;\n    case VK_F6:\n        return KEY_F6;\n    case VK_F7:\n        return KEY_F7;\n    case VK_F8:\n        return KEY_F8;\n    case VK_F9:\n        return KEY_F9;\n    case VK_F10:\n        return KEY_F10;\n    case VK_F11:\n        return KEY_F11;\n    case VK_F12:\n        return KEY_F12;\n\n\n    // special keys\n    case VK_HOME:\n        return KEY_HOME;\n    case VK_END:\n        return KEY_END;\n    case VK_PRIOR:\n        return KEY_PAGEUP;\n    case VK_NEXT:\n        return KEY_PAGEDOWN;\n    case VK_INSERT:\n        return KEY_INSERT;\n    case VK_DELETE:\n        return KEY_DELETE;\n\n    case VK_BACK:\n        return KEY_BACKSPACE;\n    case VK_TAB:\n        return KEY_TAB;\n    case VK_RETURN:\n        return KEY_ENTER;\n\n    case VK_PAUSE:\n        return KEY_PAUSE;\n    case VK_CAPITAL:\n        return KEY_CAPSLOCK;\n    case VK_ESCAPE:\n        return KEY_ESCAPE;\n\n    case VK_UP:\n        return KEY_UP;\n    case VK_DOWN:\n        return KEY_DOWN;\n    case VK_LEFT:\n        return KEY_LEFT;\n    case VK_RIGHT:\n        return KEY_RIGHT;\n    }\n\n    return KEY_NONE;\n}\n\n// Convert mouse state to CPUT state\n//-----------------------------------------------------------------------------\nCPUTMouseState CPUTWindowWin::ConvertMouseState(WPARAM wParam)\n{\n    CPUTMouseState eState=CPUT_MOUSE_NONE;\n\n    if( wParam & MK_CONTROL)\n        eState = (CPUTMouseState) (eState | static_cast<int>(CPUT_MOUSE_CTRL_DOWN));\n\n    if( wParam & MK_SHIFT)\n        eState = (CPUTMouseState) (eState | static_cast<int>(CPUT_MOUSE_SHIFT_DOWN));\n\n    if( wParam & MK_LBUTTON)\n        eState = (CPUTMouseState) (eState | static_cast<int>(CPUT_MOUSE_LEFT_DOWN));\n\n    if( wParam & MK_MBUTTON)\n        eState = (CPUTMouseState) (eState | static_cast<int>(CPUT_MOUSE_MIDDLE_DOWN));\n\n    if( wParam & MK_RBUTTON)\n        eState = (CPUTMouseState) (eState | static_cast<int>(CPUT_MOUSE_RIGHT_DOWN));\n\n\n    return eState;\n}\n\n// Main message pump\n//-----------------------------------------------------------------------------\nint CPUTWindowWin::StartMessageLoop()\n{\n\t//\n\t// Message pump\n\t//\n    MSG msg = { 0 };\n\tbool fRunning = true;\n    while(fRunning)\n    {\n        // PeekMessage() is a passthru on no events\n        // so it allows us to render while no events are present\n        if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )\n        {\n\t\t\tif (msg.message == WM_QUIT)\n\t\t\t{\n\t\t\t\tPostQuitMessage(0);\n\t\t\t\tfRunning = false;\n\t\t\t}\n            TranslateMessage( &msg );\n            DispatchMessage( &msg );\n        } else\n\t\t{\n            // trigger render and other calls\n            mCPUT->InnerExecutionLoop();\n        }\n    }\n\t\n\t//\n\t// Drain out the rest of the message queue.\n\t//\n\twhile( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )\n\t{\n\t\tTranslateMessage( &msg );\n\t\tDispatchMessage( &msg );\n\t}\n\n\tif (UnregisterClass(mAppTitle.c_str(), mhInst) == 0) {\n\t\tHandleWin32Error();\n\t}\n\n\t//\n\t// Set the window handle to NULL to indicate window shutdown is complete\n\t//\n\tmhWnd = NULL;\n\n    // return code\n    mAppClosedReturnCode =  (int) msg.wParam;\n\treturn mAppClosedReturnCode;\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUTWindowWin.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __WINDOWWIN_H__\n#define __WINDOWWIN_H__\n\n#include \"CPUT.h\"\n#include \"CPUTOSServicesWin.h\"\n#include \"CPUTResource.h\" // win resource.h customized for CPUT\n\n#include <windows.h>\n#include <winuser.h> // for character codes\n#include <cstringt.h> // for CString class\n#include <atlstr.h> // CString class\n\n// Forward declarations\nclass CPUT;\n\n// OS-specific window class\n//-----------------------------------------------------------------------------\nclass CPUTWindowWin\n{\npublic:\n    // construction\n    CPUTWindowWin();\n    ~CPUTWindowWin();\n\n    // Creates a graphics-context friendly window\n    CPUTResult Create(CPUT* cput, const cString WindowTitle, const int windowWidth, const int windowHeight, int windowX, int windowY);\n\n    // Main windows message loop that handles and dispatches messages\n    int StartMessageLoop();\n    int Destroy();\n    int ReturnCode();\n\n    // return the HWND/Window handle for the created window\n    HWND GetHWnd() { return mhWnd;};\n\nprotected:\n    HINSTANCE           mhInst;\t\t\t\t\t// current instance\n    HWND                mhWnd;                     // window handle\n    int                 mAppClosedReturnCode;      // windows OS return code\n    cString             mAppTitle;                 // title put at top of window\n    static CPUT*        mCPUT;                     // CPUT reference for callbacks\n\n    static bool         mbMaxMinFullScreen;\n\n    // Window creation helper functions\n    ATOM MyRegisterClass(HINSTANCE hInstance);\n    BOOL InitInstance(int nCmdShow, int windowWidth, int windowHeight, int windowX, int windowY);\n    static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\n\n    // CPUT conversion helper functions\n    static CPUTMouseState ConvertMouseState(WPARAM wParam);\n    static CPUTKey ConvertKeyCode(WPARAM wParam, LPARAM lParam);\n    static CPUTKey ConvertSpecialKeyCode(WPARAM wParam, LPARAM lParam);\n};\n\n\n#endif //#ifndef __WINDOWWIN_H__\n"
  },
  {
    "path": "CPUT/CPUT/CPUT_DX11.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"CPUT_DX11.h\"\n#include \"CPUTRenderStateBlockDX11.h\"\n#include \"CPUTBufferDX11.h\"\n#include \"CPUTTextureDX11.h\"\n\n// static initializers\nID3D11Device* CPUT_DX11::mpD3dDevice = NULL;\nCPUT_DX11 *gpSample;\n\n// Destructor\n//-----------------------------------------------------------------------------\nCPUT_DX11::~CPUT_DX11()\n{\n    // all previous shutdown tasks should have happened in CPUTShutdown()\n\n    // We created the default renderstate block, we release it.\n    \n    CPUTRenderStateBlock *pRenderState = CPUTRenderStateBlock::GetDefaultRenderStateBlock();\n    SAFE_RELEASE(pRenderState);\n    SAFE_RELEASE(mpPerFrameConstantBuffer);\n    SAFE_RELEASE(mpBackBufferSRV);\n    SAFE_RELEASE(mpBackBufferUAV);\n    SAFE_RELEASE(mpBackBuffer);\n    SAFE_RELEASE(mpDepthBuffer);\n\tSAFE_RELEASE(mpBackBufferTexture);\n    SAFE_RELEASE(mpDepthBufferTexture);\n\n\n    SAFE_RELEASE(mpDepthStencilSRV);\n\n    // destroy the window\n    if(mpWindow)\n    {\n        delete mpWindow;\n        mpWindow = NULL;\n    }\n\n\tSAFE_DELETE(mpTimer);\n    DestroyDXContext();\n}\n\n// initialize the CPUT system\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::CPUTInitialize(const cString pCPUTResourcePath)\n{\n    // set where CPUT will look for it's button images, fonts, etc\n    return SetCPUTResourceDirectory(pCPUTResourcePath);\n}\n\n\n// Set where CPUT will look for it's button images, fonts, etc\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::SetCPUTResourceDirectory(const cString ResourceDirectory)\n{\n    // check to see if the specified directory is valid\n    CPUTResult result = CPUT_SUCCESS;\n\n    // resolve the directory to a full path\n    cString fullPath;\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    result = pServices->ResolveAbsolutePathAndFilename(ResourceDirectory, &fullPath);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n    // check existence of directory\n    result = pServices->DoesDirectoryExist(fullPath);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n    // set the resource directory (absolute path)\n    mResourceDirectory = fullPath;\n\n    // tell the gui system where to look for it's resources\n    // todo: do we want to force a flush/reload of all resources (i.e. change control graphics)\n    result = CPUTGuiControllerDX11::GetController()->SetResourceDirectory(ResourceDirectory);\n\n    return result;\n}\n\n// Handle keyboard events\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode CPUT_DX11::CPUTHandleKeyboardEvent(CPUTKey key)\n{\n    // dispatch event to GUI to handle GUI triggers (if any)\n    CPUTEventHandledCode handleCode = CPUTGuiControllerDX11::GetController()->HandleKeyboardEvent(key);\n\n    // dispatch event to users HandleMouseEvent() method\n    HEAPCHECK;\n    handleCode = HandleKeyboardEvent(key);\n    HEAPCHECK;\n\n    return handleCode;\n}\n\n// Handle mouse events\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode CPUT_DX11::CPUTHandleMouseEvent(int x, int y, int wheel, CPUTMouseState state)\n{\n    // dispatch event to GUI to handle GUI triggers (if any)\n    CPUTEventHandledCode handleCode = CPUTGuiControllerDX11::GetController()->HandleMouseEvent(x,y,wheel,state);\n\n    // dispatch event to users HandleMouseEvent() method if it wasn't consumed by the GUI\n    if(CPUT_EVENT_HANDLED != handleCode)\n    {\n        HEAPCHECK;\n        handleCode = HandleMouseEvent(x,y,wheel,state);\n        HEAPCHECK;\n    }\n\n    return handleCode;\n}\n\n\n// Call appropriate OS create window call\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::MakeWindow(const cString WindowTitle, int windowWidth, int windowHeight, int windowX, int windowY)\n{\n    CPUTResult result;\n\n    HEAPCHECK;\n\n    // if we have a window, destroy it\n    if(mpWindow)\n    {\n        delete mpWindow;\n        mpWindow = NULL;\n    }\n\n    HEAPCHECK;\n\n    // create the OS window\n    mpWindow = new CPUTWindowWin();\n\n    result = mpWindow->Create((CPUT*)this, WindowTitle, windowWidth, windowHeight, windowX, windowY);\n\n    HEAPCHECK;\n\n    return result;\n}\n\n// Return the current GUI controller\n//-----------------------------------------------------------------------------\nCPUTGuiControllerDX11* CPUT_DX11::CPUTGetGuiController()\n{\n    return CPUTGuiControllerDX11::GetController();\n}\n\n\n// Create a DX11 context\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::CreateDXContext(CPUTWindowCreationParams params)\n{\n\n    HRESULT hr = S_OK;\n    CPUTResult result = CPUT_SUCCESS;\n\n    // window params\n    RECT rc;\n    HWND hWnd = mpWindow->GetHWnd();\n    GetClientRect( hWnd, &rc );\n    UINT width = rc.right - rc.left;\n    UINT height = rc.bottom - rc.top;\n\n    // set up DirectX creation parameters\n    mdriverType = D3D_DRIVER_TYPE_NULL;\n    mfeatureLevel = D3D_FEATURE_LEVEL_11_0;\n    mpD3dDevice = NULL;\n    mpContext = NULL;\n    mpSwapChain = NULL;\n    mSwapChainBufferCount = params.deviceParams.swapChainBufferCount;\n    mpBackBufferRTV = NULL;\n    UINT createDeviceFlags = 0;\n#ifdef _DEBUG\n    createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;\n#endif\n\n    D3D_DRIVER_TYPE driverTypes[] =\n    {\n        D3D_DRIVER_TYPE_HARDWARE,\n        D3D_DRIVER_TYPE_WARP,\n        D3D_DRIVER_TYPE_REFERENCE,\n    };\n    UINT numDriverTypes = ARRAYSIZE( driverTypes );\n\n    // SRV's (shader resource views) require Structured Buffer\n    // usage (D3D11_RESOURCE_MISC_BUFFER_STRUCTURED) which was \n    // introduced in shader model 5 (directx 11.0)\n    //\n    D3D_FEATURE_LEVEL featureLevels[] =\n    {\n        D3D_FEATURE_LEVEL_11_0,\n        D3D_FEATURE_LEVEL_10_1,\n        D3D_FEATURE_LEVEL_10_0\n    };\n    UINT numFeatureLevels = ARRAYSIZE( featureLevels );\n\n    // swap chain information\n    DXGI_SWAP_CHAIN_DESC sd;\n    ZeroMemory( &sd, sizeof( sd ) );\n    sd.BufferCount = mSwapChainBufferCount;\n    sd.BufferDesc.Width = width;\n    sd.BufferDesc.Height = height;\n\n    mSwapChainFormat = params.deviceParams.swapChainFormat;\n    sd.BufferDesc.Format = params.deviceParams.swapChainFormat;\n    sd.BufferDesc.RefreshRate.Numerator = params.deviceParams.refreshRate;\n    sd.BufferDesc.RefreshRate.Denominator = 1;\n    sd.BufferUsage = params.deviceParams.swapChainUsage;\n    sd.OutputWindow = hWnd;\n    sd.SampleDesc.Count = 1;  // Number of MSAA samples\n    sd.SampleDesc.Quality = 0;\n    sd.Windowed = !params.startFullscreen;\n    sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;\n\n    // set the vsync parameter\n    mSyncInterval = (0 != params.deviceParams.refreshRate)? 1 : 0;\n\n    // walk devices and create device and swap chain on best matching piece of hardware\n    bool functionalityTestPassed = false;\n    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )\n    {\n        mdriverType = driverTypes[driverTypeIndex];\n        hr = D3D11CreateDeviceAndSwapChain(\n            NULL,\n            mdriverType,\n            NULL,\n            createDeviceFlags,\n            featureLevels,\n            numFeatureLevels,\n            D3D11_SDK_VERSION,\n            &sd,\n            &mpSwapChain,\n            &mpD3dDevice,\n            &mfeatureLevel,\n            &mpContext\n        );\n        if( SUCCEEDED( hr ) )\n        {\n            functionalityTestPassed = TestContextForRequiredFeatures();\n            if(true == functionalityTestPassed)\n            {\n                break;\n            }\n            else\n            {\n                // context was created, but failed to have required features\n                // release and destroy this context and created resources\n                SAFE_RELEASE(mpSwapChain);\n                SAFE_RELEASE(mpContext);\n                SAFE_RELEASE(mpD3dDevice);\n            }\n        }\n    }\n    ASSERT( (SUCCEEDED(hr) && (true==functionalityTestPassed)), _L(\"Failed creating device and swap chain.\") );\n    if(!SUCCEEDED(hr) || !functionalityTestPassed)\n    {\n        CPUTOSServices::GetOSServices()->OpenMessageBox(_L(\"Required DirectX hardware support not present\"), _L(\"Your system does not support the DirectX feature levels required for this sample.\"));\n        exit(1); // exit app directly\n    }\n   \n    // If the WARP or Reference rasterizer is being used, the performance is probably terrible.\n    // we throw up a dialog right after drawing the loading screen in CPUTCreateWindowAndContext\n    // warning about that perf problem\n\n    // call the DeviceCreated callback/backbuffer/etc creation\n    result = CreateContext();\n\n    CPUTRenderStateBlock *pBlock = new CPUTRenderStateBlockDX11();\n    pBlock->CreateNativeResources();\n    CPUTRenderStateBlock::SetDefaultRenderStateBlock( pBlock );\n\n    // Create the per-frame constant buffer.\n    D3D11_BUFFER_DESC bd = {0};\n    bd.ByteWidth = sizeof(CPUTFrameConstantBuffer);\n    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;\n    bd.Usage = D3D11_USAGE_DYNAMIC;\n    bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n\n    ID3D11Buffer *pPerFrameConstantBuffer;\n    hr = (CPUT_DX11::GetDevice())->CreateBuffer( &bd, NULL, &pPerFrameConstantBuffer );\n    ASSERT( !FAILED( hr ), _L(\"Error creating constant buffer.\") );\n    CPUTSetDebugName( pPerFrameConstantBuffer, _L(\"Per-Frame Constant buffer\") );\n    cString name = _L(\"$cbPerFrameValues\");\n    mpPerFrameConstantBuffer = new CPUTBufferDX11( name, pPerFrameConstantBuffer );\n    CPUTAssetLibrary::GetAssetLibrary()->AddConstantBuffer( name, mpPerFrameConstantBuffer );\n    SAFE_RELEASE(pPerFrameConstantBuffer); // We're done with it.  The CPUTBuffer now owns it.\n\n    return result;\n}\n\n// This function tests a created DirectX context for specific features required for\n// the framework, and possibly sample.  If your sample has specific hw features\n// you wish to check for at creation time, you can add them here and have them\n// tested at startup time.  If no contexts support your desired features, then\n// the system will revert to the DX reference rasterizer, or barring that, \n// pop up a dialog and exit.\n//-----------------------------------------------------------------------------\nbool CPUT_DX11::TestContextForRequiredFeatures()\n{\n    // D3D11_RESOURCE_MISC_BUFFER_STRUCTURED check\n    // attempt to create a \n    // create the buffer for the shader resource view\n    D3D11_BUFFER_DESC desc;\n    ZeroMemory( &desc, sizeof(desc) );\n    desc.Usage = D3D11_USAGE_DEFAULT;\n    // set the stride for one 'element' block of verts\n    UINT m_VertexStride      = 4*sizeof(float);                 // size in bytes of a single element - this test case we'll use 4 floats \n    desc.ByteWidth           = 1 * m_VertexStride;              // size in bytes of entire buffer - this test case uses just one element\n    desc.BindFlags           = D3D11_BIND_SHADER_RESOURCE;\n    desc.CPUAccessFlags      = 0;\n    desc.MiscFlags           = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;\n    desc.StructureByteStride = m_VertexStride;\n\n    ID3D11Buffer *pVertexBufferForSRV=NULL;\n    D3D11_SUBRESOURCE_DATA resourceData;\n    float pData[4] ={ 0.0f, 0.0f, 0.0f, 0.0f };\n\n    ZeroMemory( &resourceData, sizeof(resourceData) );\n    resourceData.pSysMem = pData;\n    HRESULT hr = mpD3dDevice->CreateBuffer( &desc, &resourceData, &pVertexBufferForSRV );\n    SAFE_RELEASE(pVertexBufferForSRV);\n    if(!SUCCEEDED(hr))\n    {\n        // failed the feature test\n        return false;\n    }\n\n    // add other required features here\n\n    return true;\n}\n\n// Return the active D3D device used to create the context\n//-----------------------------------------------------------------------------\nID3D11Device* CPUT_DX11::GetDevice()\n{\n    return mpD3dDevice;\n}\n\n// Default creation routine for making the back/stencil buffers\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::CreateContext()\n{\n    HRESULT hr;\n    CPUTResult result;\n    RECT rc;\n    HWND hWnd = mpWindow->GetHWnd();\n\n    GetClientRect( hWnd, &rc );\n    UINT width = rc.right - rc.left;\n    UINT height = rc.bottom - rc.top;\n\n    // Create a render target view\n    ID3D11Texture2D *pBackBuffer = NULL;\n    hr = mpSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );\n    ASSERT( SUCCEEDED(hr), _L(\"Failed getting back buffer.\") );\n\n    hr = mpD3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &mpBackBufferRTV );\n    pBackBuffer->Release();\n    ASSERT( SUCCEEDED(hr), _L(\"Failed creating render target view.\") );\n    CPUTSetDebugName( mpBackBufferRTV, _L(\"BackBufferView\") );\n\n    // create depth/stencil buffer\n    result = CreateAndBindDepthBuffer(width, height);\n    ASSERT( SUCCEEDED(hr), _L(\"Failed creating and binding depth buffer.\") );\n\n    // Setup the viewport\n    D3D11_VIEWPORT vp;\n    vp.Width = (FLOAT)width;\n    vp.Height = (FLOAT)height;\n    vp.MinDepth = 0.0f;\n    vp.MaxDepth = 1.0f;\n    vp.TopLeftX = 0;\n    vp.TopLeftY = 0;\n    mpContext->RSSetViewports( 1, &vp );\n\n    return CPUT_SUCCESS;\n}\n\n// destroy the DX context and release all resources\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::DestroyDXContext()\n{\n    if (mpContext) {\n        mpContext->ClearState();\n        mpContext->Flush();\n    }\n\n    SAFE_RELEASE( mpBackBufferRTV );\n    SAFE_RELEASE( mpDepthStencilBuffer );\n    SAFE_RELEASE( mpDepthStencilState );\n    SAFE_RELEASE( mpDepthStencilView );\n    SAFE_RELEASE( mpContext );\n    SAFE_RELEASE( mpD3dDevice );\n    SAFE_RELEASE( mpSwapChain );\n\n    return CPUT_SUCCESS;\n}\n\n// Toggle the fullscreen mode\n// This routine keeps the current desktop resolution.  DougB suggested allowing\n// one to go fullscreen in a different resolution\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::CPUTToggleFullScreenMode()\n{    \n    // get the current fullscreen state\n    bool bIsFullscreen = CPUTGetFullscreenState();\n     \n    // toggle the state\n    bIsFullscreen = !bIsFullscreen;\n\n    // set the fullscreen state\n    HRESULT hr = mpSwapChain->SetFullscreenState(bIsFullscreen, NULL);\n    ASSERT( SUCCEEDED(hr), _L(\"Failed toggling full screen mode.\") );\n\n    // trigger resize event so that all buffers can resize\n    int x,y,width,height;\n    CPUTOSServices::GetOSServices()->GetClientDimensions(&x, &y, &width, &height);\n    ResizeWindow(width,height);\n\n    // trigger a fullscreen mode change call if the sample has decided to handle the mode change\n    FullscreenModeChange( bIsFullscreen );\n\n    return CPUT_SUCCESS;\n}\n\n// Set the fullscreen mode to a desired state\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::CPUTSetFullscreenState(bool bIsFullscreen)\n{\n    // get the current fullscreen state\n    bool bCurrentFullscreenState = CPUTGetFullscreenState();\n    if((bool)bCurrentFullscreenState == bIsFullscreen)\n    {\n        // no need to call expensive state change, full screen state is already\n        // in desired state\n        return;\n    }\n\n    // set the fullscreen state\n    HRESULT hr = mpSwapChain->SetFullscreenState(bIsFullscreen, NULL);\n    ASSERT( SUCCEEDED(hr), _L(\"Failed toggling full screen mode.\") );\n\n    // trigger resize event so that all buffers can resize\n    int x,y,width,height;\n    CPUTOSServices::GetOSServices()->GetClientDimensions(&x, &y, &width, &height);\n    ResizeWindow(width,height);\n\n    // trigger a fullscreen mode change call if the sample has decided to handle the mode change\n    FullscreenModeChange( bIsFullscreen );\n}\n\n// Get a bool indicating whether the system is in full screen mode or not\n//-----------------------------------------------------------------------------\nbool CPUT_DX11::CPUTGetFullscreenState()\n{\n    // get the current fullscreen state\n    BOOL bCurrentlyFullscreen;\n    IDXGIOutput *pSwapTarget=NULL;\n    mpSwapChain->GetFullscreenState(&bCurrentlyFullscreen, &pSwapTarget);\n    SAFE_RELEASE(pSwapTarget);\n    if(TRUE == bCurrentlyFullscreen )\n    {\n        return true;\n    }\n    return false;\n}\n\n// Create the depth buffer\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::CreateAndBindDepthBuffer(int width, int height)\n{\n    HRESULT hr;\n\n    // Clamp to minimum size of 1x1 pixel\n    width  = max( width, 1 );\n    height = max( height, 1 );\n\n    // ---- DEPTH BUFFER ---\n    // 1. Initialize the description of the depth buffer.\n    D3D11_TEXTURE2D_DESC depthBufferDesc;\n    ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));\n\n    // Set up the description of the depth buffer.\n    depthBufferDesc.Width = width;\n    depthBufferDesc.Height = height;\n    depthBufferDesc.MipLevels = 1;\n    depthBufferDesc.ArraySize = 1;\n    depthBufferDesc.Format = DXGI_FORMAT_R32_TYPELESS;\n    depthBufferDesc.SampleDesc.Count = 1;\n    depthBufferDesc.SampleDesc.Quality = 0;\n    depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;\n    depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;\n    depthBufferDesc.CPUAccessFlags = 0;\n    depthBufferDesc.MiscFlags = 0;\n\n    // Create the texture for the depth buffer using the filled out description.\n    hr = mpD3dDevice->CreateTexture2D(&depthBufferDesc, NULL, &mpDepthStencilBuffer);\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to create texture.\") );\n    CPUTSetDebugName( mpDepthStencilBuffer, _L(\"DepthBufferTexture\") );\n\n    // 2. Initialize the description of the stencil state.\n    D3D11_DEPTH_STENCIL_DESC depthStencilDesc;\t\n    ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));\n\n    // Set up the description of the stencil state.\n    depthStencilDesc.DepthEnable = true;\n    depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;\n    depthStencilDesc.DepthFunc = D3D11_COMPARISON_GREATER_EQUAL;\n\n    depthStencilDesc.StencilEnable = true;\n    depthStencilDesc.StencilReadMask = 0xFF;\n    depthStencilDesc.StencilWriteMask = 0xFF;\n\n    // Stencil operations if pixel is front-facing.\n    depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;\n    depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;\n    depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;\n    depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;\n\n    // Stencil operations if pixel is back-facing.\n    depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;\n    depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;\n    depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;\n    depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;\n\n    // Create the depth stencil state.\n    hr = mpD3dDevice->CreateDepthStencilState(&depthStencilDesc, &mpDepthStencilState);\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to create depth-stencil state.\") );\n    mpContext->OMSetDepthStencilState(mpDepthStencilState, 1);\n\n    // Create shader resource view\n    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;\n    ZeroMemory(&srvDesc, sizeof(srvDesc));\n    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;\n    srvDesc.Texture2D.MipLevels = 1;\n    srvDesc.Format = DXGI_FORMAT_R32_FLOAT;\n    hr = mpD3dDevice->CreateShaderResourceView(mpDepthStencilBuffer, &srvDesc, &mpDepthStencilSRV);\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to create depth-stencil SRV.\") );\n    CPUTSetDebugName( mpDepthStencilSRV, _L(\"DepthStencilSRV\") );\n\n    // Create the depth stencil view.\n    D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;\n    ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));\n    depthStencilViewDesc.Format = DXGI_FORMAT_D32_FLOAT;\n    depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;\n    depthStencilViewDesc.Texture2D.MipSlice = 0;\n    hr = mpD3dDevice->CreateDepthStencilView(mpDepthStencilBuffer, &depthStencilViewDesc, &mpDepthStencilView);\n    ASSERT( SUCCEEDED(hr), _L(\"Failed to create depth-stencil view.\") );\n    CPUTSetDebugName( mpDepthStencilView, _L(\"DepthStencilView\") );\n\n    // Bind the render target view and depth stencil buffer to the output render pipeline.\n    mpContext->OMSetRenderTargets(1, &mpBackBufferRTV, mpDepthStencilView);\n\n    CPUTRenderTargetColor::SetActiveRenderTargetView( mpBackBufferRTV );\n    CPUTRenderTargetDepth::SetActiveDepthStencilView( mpDepthStencilView );\n\n    return CPUT_SUCCESS;\n}\n\n// incoming resize event to be handled and translated\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::ResizeWindow(UINT width, UINT height)\n{\n    HRESULT hr;\n    CPUTResult result;\n    CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibraryDX11::GetAssetLibrary();\n\n    // TODO: Making the back and depth buffers into CPUTRenderTargets should simplify this (CPUTRenderTarget* manages RTV, SRV, UAV, etc.)\n    if( mpBackBuffer )         ((CPUTBufferDX11*)mpBackBuffer)->ReleaseBuffer();\n    if( mpDepthBuffer )        ((CPUTBufferDX11*)mpDepthBuffer)->ReleaseBuffer();\n    if( mpBackBufferTexture )  ((CPUTTextureDX11*)mpBackBufferTexture)->ReleaseTexture();\n    if( mpDepthBufferTexture ) ((CPUTTextureDX11*)mpDepthBufferTexture)->ReleaseTexture();\n\n    // Make sure we don't have any buffers bound.\n    mpContext->ClearState();\n    Present();\n    mpContext->Flush();\n\n    SAFE_RELEASE(mpBackBufferRTV);\n    SAFE_RELEASE(mpBackBufferSRV);\n    SAFE_RELEASE(mpBackBufferUAV);\n    SAFE_RELEASE(mpDepthStencilSRV);\n\n    CPUT::ResizeWindow( width, height );\n\n    // Call the sample's clean up code if present.\n    ReleaseSwapChain();\n\n    // handle the internals of a resize\n    int windowWidth, windowHeight;\n    CPUTOSServices *pServices = CPUTOSServices::GetOSServices();\n    pServices->GetClientDimensions( &windowWidth, &windowHeight);\n\n    // resize the swap chain\n    hr = mpSwapChain->ResizeBuffers(mSwapChainBufferCount, windowWidth, windowHeight, mSwapChainFormat, 0);\n    ASSERT( SUCCEEDED(hr), _L(\"Error resizing swap chain\") );\n\n    // re-create the render-target view\n    ID3D11Texture2D *pSwapChainBuffer = NULL;\n    hr = mpSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), (LPVOID*) (&pSwapChainBuffer));\n    ASSERT(SUCCEEDED(hr), _L(\"\"));\n    hr = mpD3dDevice->CreateRenderTargetView( pSwapChainBuffer, NULL, &mpBackBufferRTV);\n    ASSERT(SUCCEEDED(hr), _L(\"\"));\n    hr = mpD3dDevice->CreateShaderResourceView( pSwapChainBuffer, NULL, &mpBackBufferSRV);\n    ASSERT(SUCCEEDED(hr), _L(\"\"));\n#ifdef CREATE_SWAP_CHAIN_UAV\n\t// Not every DXGI format supports UAV.  So, create UAV only if sample chooses to do so.\n    hr = mpD3dDevice->CreateUnorderedAccessView( pSwapChainBuffer, NULL, &mpBackBufferUAV);\n    ASSERT(SUCCEEDED(hr), _L(\"\"));\n#endif\n    // Add the back buffer to the asset library.  Create CPUTBuffer and a CPUTTexture forms and add them.\n    if( mpBackBuffer )\n    {\n        ((CPUTBufferDX11*)mpBackBuffer)->SetBufferAndViews( NULL, mpBackBufferSRV, mpBackBufferUAV );\n    }\n    else\n    {\n        cString backBufferName = _L(\"$BackBuffer\"); \n        mpBackBuffer  = new CPUTBufferDX11( backBufferName,  NULL, mpBackBufferUAV );\n        pAssetLibrary->AddBuffer( backBufferName, mpBackBuffer );\n    }\n    if( mpBackBufferTexture )\n    {\n        ((CPUTTextureDX11*)mpBackBufferTexture)->SetTextureAndShaderResourceView( NULL, mpBackBufferSRV );\n    }\n    else\n    {\n        cString backBufferName = _L(\"$BackBuffer\"); \n        mpBackBufferTexture  = new CPUTTextureDX11( backBufferName, NULL, mpBackBufferSRV );\n        pAssetLibrary->AddTexture( backBufferName, mpBackBufferTexture );\n    }\n\n    // release the old depth buffer objects\n    // release the temporary swap chain buffer\n    SAFE_RELEASE(pSwapChainBuffer);\n    SAFE_RELEASE(mpDepthStencilBuffer);\n    SAFE_RELEASE(mpDepthStencilState);\n    SAFE_RELEASE(mpDepthStencilView);\n\n    result = CreateAndBindDepthBuffer(windowWidth, windowHeight);\n    if(CPUTFAILED(result))\n    {\n        // depth buffer creation error\n        ASSERT(0,_L(\"\"));\n    }\n\n    if( mpDepthBuffer )\n    {\n        ((CPUTBufferDX11*)mpDepthBuffer)->SetBufferAndViews( NULL, mpDepthStencilSRV, NULL );\n    }\n    else\n    {\n        cString depthBufferName = _L(\"$DepthBuffer\"); \n        mpDepthBuffer  = new CPUTBufferDX11( depthBufferName, NULL, mpDepthStencilSRV );\n        pAssetLibrary->AddBuffer( depthBufferName, mpDepthBuffer );\n    }\n    if( mpDepthBufferTexture )\n    {\n        ((CPUTTextureDX11*)mpDepthBufferTexture)->SetTextureAndShaderResourceView( NULL, mpDepthStencilSRV );\n    }\n    else\n    {\n        cString DepthBufferName = _L(\"$DepthBuffer\"); \n        mpDepthBufferTexture  = new CPUTTextureDX11( DepthBufferName, NULL, mpDepthStencilSRV );\n        pAssetLibrary->AddTexture( DepthBufferName, mpDepthBufferTexture );\n    }\n\n    // Release our extra reference to each view.\n    // if(mpBackBufferSRV)   mpBackBufferSRV->Release();\n    // if(mpBackBufferUAV)   mpBackBufferUAV->Release();\n    // if(mpDepthStencilSRV) mpDepthStencilSRV->Release();;\n\n    // set the viewport\n    D3D11_VIEWPORT vp;\n    vp.Width = (FLOAT) windowWidth;\n    vp.Height = (FLOAT)windowHeight;\n    vp.MinDepth = 0.0f;\n    vp.MaxDepth = 1.0f;\n    vp.TopLeftX = 0;\n    vp.TopLeftY = 0;\n    mpContext->RSSetViewports( 1, &vp );\n\n    // trigger the GUI manager to resize\n    CPUTGuiControllerDX11::GetController()->Resize();\n}\n\n// 'soft' resize - just stretch-blit\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::ResizeWindowSoft(UINT width, UINT height)\n{\n    UNREFERENCED_PARAMETER(width);\n    UNREFERENCED_PARAMETER(height);\n    // trigger the GUI manager to resize\n    CPUTGuiControllerDX11::GetController()->Resize();\n\n    InnerExecutionLoop();\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::SetPerFrameConstantBuffer( double totalSeconds )\n{\n    if( mpPerFrameConstantBuffer )\n    {\n        ID3D11Buffer *pBuffer = mpPerFrameConstantBuffer->GetNativeBuffer();\n\n        // update parameters of constant buffer\n        D3D11_MAPPED_SUBRESOURCE mapInfo;\n        mpContext->Map( pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo );\n        {\n            // TODO: remove construction of XMM type\n            CPUTFrameConstantBuffer *pCb = (CPUTFrameConstantBuffer*)mapInfo.pData;\n            CPUTCamera *pCamera     = gpSample->GetCamera();\n            if( pCamera )\n            {\n                pCb->View               = XMMATRIX((float*)pCamera->GetViewMatrix());\n                pCb->Projection         = XMMATRIX((float*)pCamera->GetProjectionMatrix());\n            }\n            pCb->LightColor         = XMLoadFloat3(&XMFLOAT3((float*)&mLightColor)); // TODO: Get from light\n            float totalSecondsFloat = (float)totalSeconds;\n            pCb->TotalSeconds       = XMLoadFloat(&totalSecondsFloat);\n            pCb->AmbientColor       = XMLoadFloat3(&XMFLOAT3((float*)&mAmbientColor));\n        }\n        mpContext->Unmap(pBuffer,0);\n    }\n}\n\n// Call the user's Render() callback (if it exists)\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::InnerExecutionLoop()\n{\n#ifdef CPUT_GPA_INSTRUMENTATION\n    D3DPERF_BeginEvent(D3DCOLOR(0xff0000), L\"CPUT User's Render() \");\n#endif\n    if(!mbShutdown)\n    {\n\t\tif( mpSwapChain )\n\t\t{\n\t\t\tdouble deltaSeconds = mpTimer->GetElapsedTime();\n\t\t\tUpdate(deltaSeconds);\n\t\t\tPresent(); // Note: Presenting immediately before Rendering minimizes CPU stalls (i.e., execute Update() before Present() stalls)\n\n\t\t\tdouble totalSeconds = mpTimer->GetTotalTime();\n\t\t\tSetPerFrameConstantBuffer(totalSeconds);\n\t\t\tCPUTMaterialDX11::ResetStateTracking();\n\t\t\tRender(deltaSeconds);\n\t\t}\n        if(!CPUTOSServices::GetOSServices()->DoesWindowHaveFocus())\n        {\n            Sleep(100);\n        }\n    }\n    else\n    {\n#ifndef _DEBUG\n        exit(0);\n#endif\n        Present(); // Need to present, or will leak all references held by previous Render()!\n        ShutdownAndDestroy();\n    }\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n    D3DPERF_EndEvent();\n#endif\n}\n\n// draw all the GUI controls\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::CPUTDrawGUI()\n{\n#ifdef CPUT_GPA_INSTRUMENTATION\n    D3DPERF_BeginEvent(D3DCOLOR(0xff0000), L\"CPUT Draw GUI\");\n#endif\n\n    // draw all the Gui controls\n    HEAPCHECK;\n        CPUTGuiControllerDX11::GetController()->Draw(mpContext);\n    HEAPCHECK;\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n        D3DPERF_EndEvent();\n#endif\n}\n\n// Parse the command line for the parameters\n// Only parameters that are specified on the command line are updated, if there\n// are no parameters for a value, the previous WindowParams settings passed in\n// are preserved\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::CPUTParseCommandLine(cString commandLine, CPUTWindowCreationParams *pWindowParams, cString *pFilename)\n{\n    ASSERT( (NULL!=pWindowParams), _L(\"Required command line parsing parameter is NULL\"));\n    ASSERT( (NULL!=pFilename), _L(\"Required command line parsing parameter is NULL\"));\n   \n    // there are no command line parameters, just return\n    if(0==commandLine.size())\n    {\n        return CPUT_SUCCESS;\n    }\n\n    // we do have parameters, so parse them.\n#if defined (UNICODE) || defined(_UNICODE)\n    // convert command line to lowercase version\n    cString CommandLineParams(commandLine);        \n    std::transform(CommandLineParams.begin(), CommandLineParams.end(), CommandLineParams.begin(), ::tolower);\n\n    // special case - double-clicked on a file\n    // In the case someone has associated .set files with CPUT, then the target set file comes in surrounded\n    // by quote marks (i.e. \"c:\\mySample\\Asset\\City.set\").  If the first char is a quote mark, we're in this\n    // special case\n    if('\"' == CommandLineParams[0])\n    {\n        pFilename->assign(&CommandLineParams[1]);   // remove the leading \" char\n        (*pFilename)[pFilename->size()-1] = '\\0';   // remove the trailing \" char\n        return CPUT_SUCCESS;\n    }\n\n    wchar_t separators[]   = L\" \\t\\n\";\n    wchar_t* nextToken = NULL;\n    wchar_t* token = wcstok_s((wchar_t*)CommandLineParams.c_str(), separators, &nextToken);\n    while(token) \n    {\n        if('-' == token[0])\n        {\n            // parameter - get next token for which one\n            cString ParameterName(&token[1]);\n            if(0!=ParameterName.size())\n            {\n                if(0==ParameterName.compare(_L(\"width\")))\n                {\n                    // get the next value\n                    token = wcstok_s(NULL, separators, &nextToken); \n                    ASSERT(token, _L(\"-width command line parameter missing required numerical value\"));\n                    pWindowParams->windowWidth = _wtoi(token);\n                }\n                else if(0==ParameterName.compare(_L(\"height\")))\n                {\n                    // get the next value\n                    token = wcstok_s(NULL, separators, &nextToken); \n                    ASSERT(token, _L(\"-height command line parameter missing required numerical value\"));\n                    pWindowParams->windowHeight = _wtoi(token);\n                }\n                else if(0==ParameterName.compare(_L(\"fullscreen\")))\n                {\n                    // get the bool \n                    token = wcstok_s(NULL, separators, &nextToken); \n                    cString boolString(token);\n                    if(0==boolString.compare(_L(\"true\")))\n                    {\n                        pWindowParams->startFullscreen = true;\n                    }\n                }\n                else if(0==ParameterName.compare(_L(\"vsync\")))\n                {\n                    // get the bool \n                    token = wcstok_s(NULL, separators, &nextToken); \n                    cString boolString(token);\n                    if( (0==boolString.compare(_L(\"on\"))) || (0==boolString.compare(_L(\"true\"))) )\n                    {\n                        // vsync set to 30 FPS\n                        pWindowParams->deviceParams.refreshRate = 30;\n                    }\n\t\t\t\t\tif( (0==boolString.compare(_L(\"off\"))) || (0==boolString.compare(_L(\"false\"))) )\n\t\t\t\t\t{\n\t\t\t\t\t\tpWindowParams->deviceParams.refreshRate = 0;\n\t\t\t\t\t}\n                }\n                else if(0==ParameterName.compare(_L(\"xpos\")))\n                {\n                    // get the next value\n                    token = wcstok_s(NULL, separators, &nextToken); \n                    ASSERT(token, _L(\"-xpos command line parameter missing required numerical value\"));\n                    pWindowParams->windowPositionX = _wtoi(token);\n                }\n                else if(0==ParameterName.compare(_L(\"ypos\")))\n                {\n                    // get the next value\n                    token = wcstok_s(NULL, separators, &nextToken); \n                    ASSERT(token, _L(\"-ypos command line parameter missing required numerical value\"));\n                    pWindowParams->windowPositionY = _wtoi(token);\n                }\n                else if(0==ParameterName.compare(_L(\"file\")))\n                {\n                    // get the filename \n                    token = wcstok_s(NULL, separators, &nextToken);\n                    pFilename->assign(token);\n                }\n                else\n                {\n                    // we don't know what the string was, but all specified ones should be of the form\n                    // '-<keyword> <value>' \n                    // so skip over the <value> part\n                    token = wcstok_s(NULL, separators, &nextToken); \n                }\n                \n                // we don't know what this parameter is, let user parse it\n            }\n        }\n        \n        // advance to next token\n        token = wcstok_s(NULL, separators, &nextToken);\n    }\n#else\n    ASSERT(false, _L(\"CPUT_DX11::CPUTParseCommandLine non-UNICODE version not written yet - need to write if we want to support multi-byte\"));\n#endif     \n    \n    return CPUT_SUCCESS;\n}\n\n// Create a window context\n//-----------------------------------------------------------------------------\nCPUTResult CPUT_DX11::CPUTCreateWindowAndContext(const cString WindowTitle, CPUTWindowCreationParams windowParams)\n{\n    CPUTResult result = CPUT_SUCCESS;\n\n    HEAPCHECK;\n\n\t// create the window\n    result = MakeWindow(WindowTitle, windowParams.windowWidth, windowParams.windowHeight, windowParams.windowPositionX, windowParams.windowPositionY);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n    HEAPCHECK;\n\n    // create the DX context\n    result = CreateDXContext(windowParams);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n\n    HEAPCHECK;\n#define ENABLE_GUI\n#ifdef ENABLE_GUI\n    // initialize the gui controller \n    // Use the ResourceDirectory that was given during the Initialize() function\n    // to locate the GUI+font resources\n    CPUTGuiControllerDX11 *pGUIController = CPUTGuiControllerDX11::GetController();\n    cString ResourceDirectory = GetCPUTResourceDirectory();\n    result = pGUIController->Initialize(mpContext, ResourceDirectory);\n    if(CPUTFAILED(result))\n    {\n        return result;\n    }\n    // register the callback object for GUI events as our sample\n    CPUTGuiControllerDX11::GetController()->SetCallback(this);\n#endif\n    HEAPCHECK;\n    DrawLoadingFrame();\n    HEAPCHECK;\n    \n    // warn the user they are using the software rasterizer\n    if((D3D_DRIVER_TYPE_REFERENCE == mdriverType) || (D3D_DRIVER_TYPE_WARP == mdriverType))\n    {\n        CPUTOSServices::GetOSServices()->OpenMessageBox(_L(\"Performance warning\"), _L(\"Your graphics hardware does not support the DirectX features required by this sample. The sample is now running using the DirectX software rasterizer.\"));\n    }\n\n\n    // trigger a post-create user callback event\n    HEAPCHECK;\n    Create();\n    HEAPCHECK;\n\n\t//\n\t// Start the timer after everything is initialized and assets have been loaded\n\t//\n\tmpTimer->StartTimer();\n\n    // if someone triggers the shutdown routine in on-create, exit\n    if(mbShutdown)\n    {\n        return result;\n    }\n\n    // fill first frame with clear values so render order later is ok\n    const float srgbClearColor[] = { 0.0993f, 0.0993f, 0.0993f, 1.0f };\n    mpContext->ClearRenderTargetView( mpBackBufferRTV, srgbClearColor );\n    mpContext->ClearDepthStencilView(mpDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0);\n\n    // trigger a 'resize' event\n    int x,y,width,height;\n    CPUTOSServices::GetOSServices()->GetClientDimensions(&x, &y, &width, &height);\n    ResizeWindow(width,height);\n\n    return result;\n}\n\n// Pop up a message box with specified title/text\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::DrawLoadingFrame()\n{\n    // fill first frame with clear values so render order later is ok\n    const float srgbClearColor[] = { 0.0993f, 0.0993f, 0.0993f, 1.0f };\n    mpContext->ClearRenderTargetView( mpBackBufferRTV, srgbClearColor );\n    mpContext->ClearDepthStencilView(mpDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0);\n\n    // get center\n    int x,y,width,height;\n    CPUTOSServices::GetOSServices()->GetClientDimensions(&x, &y, &width, &height);\n\n    // draw \"loading...\" text\n    CPUTGuiControllerDX11 *pGUIController = CPUTGuiControllerDX11::GetController();\n    CPUTText *pText = NULL;\n    pGUIController->CreateText(_L(\"Just a moment, now loading...\"), 999, 0, &pText);\n    pGUIController->EnableAutoLayout(false);\n    int textWidth, textHeight;\n    pText->GetDimensions(textWidth, textHeight);\n    pText->SetPosition(width/2-textWidth/2, height/2);\n\n    pGUIController->Draw(mpContext);\n    pGUIController->DeleteAllControls();\n    pGUIController->EnableAutoLayout(true);\n    \n    // present loading screen\n    mpSwapChain->Present( mSyncInterval, 0 );\n}\n\n// Pop up a message box with specified title/text\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::CPUTMessageBox(const cString DialogBoxTitle, const cString DialogMessage)\n{\n    CPUTOSServices::GetOSServices()->OpenMessageBox(DialogBoxTitle.c_str(), DialogMessage.c_str());\n}\n\n// start main message loop\n//-----------------------------------------------------------------------------\nint CPUT_DX11::CPUTMessageLoop()\n{\n#ifdef CPUT_GPA_INSTRUMENTATION\n    D3DPERF_BeginEvent(D3DCOLOR(0xff0000), L\"CPUTMessageLoop\");\n#endif\n\n    return mpWindow->StartMessageLoop();\n\n#ifdef CPUT_GPA_INSTRUMENTATION\n    D3DPERF_EndEvent();\n#endif\n}\n\n// Window is closing. Shut the system to shut down now, not later.\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::DeviceShutdown()\n{\n    if(mpSwapChain)\n    {\n        // DX requires setting fullscreenstate to false before exit.\n        mpSwapChain->SetFullscreenState(false, NULL);\n    }\n    if(false == mbShutdown)\n    {\n        mbShutdown = true;\n        ShutdownAndDestroy();\n    }\n}\n\n// Shutdown the CPUT system\n// Destroy all 'global' resource handling objects, all asset handlers,\n// the DX context, and everything EXCEPT the window\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::Shutdown()\n{\n    // release the lock on the mouse (if there was one)\n    CPUTOSServices::GetOSServices()->ReleaseMouse();\n    mbShutdown = true;\n}\n\n// Frees all resources and removes all assets from asset library\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::RestartCPUT()\n{\n    //\n    // Clear out all CPUT resources\n    //\n    CPUTInputLayoutCacheDX11::GetInputLayoutCache()->ClearLayoutCache();\n    CPUTAssetLibrary::GetAssetLibrary()->ReleaseAllLibraryLists();\n\tCPUTGuiControllerDX11::GetController()->DeleteAllControls();\n\tCPUTGuiControllerDX11::GetController()->ReleaseResources();\n\n    //\n    // Clear out all DX resources and contexts\n    //\n    DestroyDXContext();\n\n    //\n    // Signal the window to close\n    //\n    mpWindow->Destroy();\n\t\n\t//\n\t// Clear out the timer\n\t//\n\tmpTimer->StopTimer();\n\tmpTimer->ResetTimer();\n    \n    HEAPCHECK;\n}\n// Actually destroy all 'global' resource handling objects, all asset handlers,\n// the DX context, and everything EXCEPT the window\n//-----------------------------------------------------------------------------\nvoid CPUT_DX11::ShutdownAndDestroy()\n{\n    // make sure no more rendering can happen\n    mbShutdown = true;\n\n    // call the user's OnShutdown code\n    Shutdown();\n    CPUTInputLayoutCacheDX11::DeleteInputLayoutCache();\n    CPUTAssetLibraryDX11::DeleteAssetLibrary();\n    CPUTGuiControllerDX11::DeleteController();\n\n// #ifdef _DEBUG\n#if 0\n    ID3D11Debug *pDebug;\n    mpD3dDevice->QueryInterface(IID_ID3D11Debug, (VOID**)(&pDebug));\n    if( pDebug )\n    {\n        pDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);\n        pDebug->Release();\n    }\n#endif\n    CPUTOSServices::DeleteOSServices();\n\n    // Tell the window layer to post a close-window message to OS\n    // and stop the message pump\n    mpWindow->Destroy();\n\n    HEAPCHECK;\n}\n\n//-----------------------------------------------------------------------------\nvoid CPUTSetDebugName( void *pResource, cString name )\n{\n#ifdef _DEBUG\n    char pCharString[CPUT_MAX_STRING_LENGTH];\n    const wchar_t *pWideString = name.c_str();\n    UINT ii;\n    UINT length = min( (UINT)name.length(), (CPUT_MAX_STRING_LENGTH-1));\n    for(ii=0; ii<length; ii++)\n    {\n        pCharString[ii] = (char)pWideString[ii];\n    }\n    pCharString[ii] = 0; // Force NULL termination\n    ((ID3D11DeviceChild*)pResource)->SetPrivateData( WKPDID_D3DDebugObjectName, (UINT)name.length(), pCharString );\n#endif // _DEBUG\n}\n"
  },
  {
    "path": "CPUT/CPUT/CPUT_DX11.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#ifndef __CPUT_DX11_H__\n#define __CPUT_DX11_H__\n\n#include <stdio.h>\n\n// include base headers we'll need\n#include \"CPUTWindowWin.h\"\n#include \"CPUT.h\"\n#include \"CPUTMath.h\"\n#include \"CPUTEventHandler.h\"\n#include \"CPUTGuiControllerDX11.h\"\n\n// CPUT objects\n#include \"CPUTMeshDX11.h\"\n#include \"CPUTModelDX11.h\"\n#include \"CPUTAssetSetDX11.h\"\n#include \"CPUTAssetLibraryDX11.h\"\n#include \"CPUTCamera.h\"\n#include \"CPUTLight.h\"\n#include \"CPUTMaterialDX11.h\"\n\n// include all DX11 headers needed\n#include <d3d11.h>\n#include <d3DX11.h>\n#include <D3DX11async.h>    // for D3DX11CompileFromFile()\n#include <D3DCompiler.h>    // for D3DReflect() / D3DX11Refection - IMPORTANT NOTE: include directories MUST list DX SDK include path BEFORE\n// Windows include paths or you'll get compile errors with D3DShader.h\n\n// context creation parameters\nstruct CPUTContextCreation\n{\n    int refreshRate;\n    int swapChainBufferCount;\n    DXGI_FORMAT swapChainFormat;\n    DXGI_USAGE swapChainUsage;\n};\n\n// window creation parameters\nstruct CPUTWindowCreationParams\n{\n    bool startFullscreen;\n    int windowWidth;\n    int windowHeight;\n    int windowPositionX;\n    int windowPositionY;\n    CPUTContextCreation deviceParams;\n    CPUTWindowCreationParams() : startFullscreen(false), windowWidth(1280), windowHeight(720), windowPositionX(0), windowPositionY(0) {}\n};\n\n// Types of message boxes you can create\nenum CPUT_MESSAGE_BOX_TYPE\n{\n    CPUT_MB_OK = MB_OK | MB_ICONINFORMATION,\n    CPUT_MB_ERROR = MB_OK | MB_ICONEXCLAMATION,\n    CPUT_MB_WARNING = MB_OK | MB_ICONWARNING\n};\n\n//--------------------------------------------------------------------------------------\nstruct CPUTFrameConstantBuffer\n{\n    XMMATRIX  View;\n    XMMATRIX  Projection;\n    XMVECTOR  AmbientColor;\n    XMVECTOR  LightColor;\n    XMVECTOR  TotalSeconds;\n};\n\n// DirectX 11 CPUT layer\n//-----------------------------------------------------------------------------\nclass CPUT_DX11;\nextern CPUT_DX11 *gpSample;\n\nclass CPUT_DX11:public CPUT\n{\nprotected:\n    static ID3D11Device *mpD3dDevice;\n\npublic:\n    static ID3D11Device *GetDevice();\n\nprotected:\n    CPUTWindowWin             *mpWindow;\n    bool                       mbShutdown;\n    cString                    mResourceDirectory;\n\n    D3D_DRIVER_TYPE            mdriverType;\n    D3D_FEATURE_LEVEL          mfeatureLevel;\n    ID3D11DeviceContext       *mpContext;\n    IDXGISwapChain            *mpSwapChain;\n    UINT                       mSwapChainBufferCount;\n    ID3D11RenderTargetView    *mpBackBufferRTV;\n    ID3D11ShaderResourceView  *mpBackBufferSRV;\n    ID3D11UnorderedAccessView *mpBackBufferUAV;\n    DXGI_FORMAT                mSwapChainFormat;\n\n    ID3D11Texture2D           *mpDepthStencilBuffer;\n    ID3D11DepthStencilState   *mpDepthStencilState;\n    ID3D11DepthStencilView    *mpDepthStencilView; // was in protected\n    ID3D11ShaderResourceView  *mpDepthStencilSRV;\n\n    UINT                       mSyncInterval; // used for vsync\n    CPUTBufferDX11            *mpPerFrameConstantBuffer;\n\npublic:\n    CPUT_DX11():mpWindow(NULL),\n        mpContext(NULL),\n        mpSwapChain(NULL),\n        mSwapChainBufferCount(1),\n        mpBackBufferRTV(NULL),\n        mpBackBufferSRV(NULL),\n        mpBackBufferUAV(NULL),\n        mpDepthStencilBuffer(NULL),\n        mpDepthStencilState(NULL),\n        mpDepthStencilView(NULL),\n        mpDepthStencilSRV(NULL),\n        mSwapChainFormat(DXGI_FORMAT_UNKNOWN),\n        mbShutdown(false),\n        mSyncInterval(0),    // start with vsync off\n        mpPerFrameConstantBuffer(NULL)\n    {\n\t\tmpTimer = (CPUTTimer*) new CPUTTimerWin();\n        gpSample = this;\n    }\n    virtual ~CPUT_DX11();\n\n    // context creation/destruction routines\n    CPUTResult CPUTInitialize(const cString ResourceDirectory);\n    CPUTResult SetCPUTResourceDirectory(const cString ResourceDirectory);\n    cString GetCPUTResourceDirectory() { return mResourceDirectory; }\n    CPUTResult CPUTParseCommandLine(cString commandLine, CPUTWindowCreationParams *pWindowParams, cString *pFilename);\n    D3D_FEATURE_LEVEL GetFeatureLevel() { return mfeatureLevel; }\n\n    int CPUTMessageLoop();\n    CPUTResult CPUTCreateWindowAndContext(const cString WindowTitle, CPUTWindowCreationParams windowParams);\n\n    // CPUT interfaces\n    virtual void ResizeWindow(UINT width, UINT height);\n    virtual void ResizeWindowSoft(UINT width, UINT height);\n    void DeviceShutdown();\n\tvoid RestartCPUT();\n\n    void SetPerFrameConstantBuffer( double totalSeconds );\n    void InnerExecutionLoop();\n\n    // events\n    virtual void Update(double deltaSeconds) {}\n    virtual void Present() { mpSwapChain->Present( mSyncInterval, 0 ); }\n    virtual void Render(double deltaSeconds) = 0;\n    virtual void Create()=0;\n    virtual void Shutdown();\n    virtual void FullscreenModeChange(bool bFullscreen) {UNREFERENCED_PARAMETER(bFullscreen);} // fires when CPUT changes to/from fullscreen mode\n    virtual void ReleaseSwapChain() {}\n    // virtual void ResizeWindow(UINT width, UINT height){UNREFERENCED_PARAMETER(width);UNREFERENCED_PARAMETER(height);}\n    virtual CPUTResult CreateContext();\n\n    // GUI\n    void CPUTDrawGUI();\n\n    // Event Handling\n    CPUTEventHandledCode CPUTHandleKeyboardEvent(CPUTKey key);\n    CPUTEventHandledCode CPUTHandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n\n    // Utility functions for the sample developer\n    CPUTResult CPUTToggleFullScreenMode();\n    void CPUTSetFullscreenState(bool bIsFullscreen);\n    bool CPUTGetFullscreenState();\n    CPUTGuiControllerDX11* CPUTGetGuiController();\n\n    // Message boxes\n    void CPUTMessageBox(const cString DialogBoxTitle, const cString DialogMessage);\n\nprotected:\n    // private helper functions\n    bool TestContextForRequiredFeatures();\n    void ShutdownAndDestroy();\n    virtual CPUTResult CreateDXContext(CPUTWindowCreationParams params);   // allow user to override DirectX context creation\n    virtual CPUTResult DestroyDXContext();  // allow user to override DirectX context destruction\n    CPUTResult         MakeWindow(const cString WindowTitle, int windowWidth, int windowHeight, int windowX, int windowY);\n    CPUTResult         CreateAndBindDepthBuffer(int width, int height);\n    void               DrawLoadingFrame();\n\n    // TODO: Put this somewhere else\n    bool               FindMatchingInputSlot(const char *pInputSlotName, const ID3DBlob *pVertexShaderBlob);\n};\n\n#endif //#ifndef __CPUT_DX11_H__\n"
  },
  {
    "path": "CPUT/CPUT-DX11.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"CPUT-DX11\", \"CPUT-DX11.vcxproj\", \"{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Win32 = Debug|Win32\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|Win32 = Release|Win32\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|x64.Build.0 = Debug|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|Win32.Build.0 = Release|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|x64.ActiveCfg = Release|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "CPUT/CPUT-DX11.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Profile|Win32\">\n      <Configuration>Profile</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Profile|x64\">\n      <Configuration>Profile</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}</ProjectGuid>\n    <RootNamespace>CPUTDX11</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IncludePath>$(DXSDK_DIR)Include;$(IncludePath);</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x64;</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_64D</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IncludePath>$(DXSDK_DIR)Include;$(IncludePath);</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">\n    <IncludePath>$(DXSDK_DIR)Include;$(IncludePath);</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LibraryPath>$(LibraryPath);$(LibraryPath);$(DXSDK_DIR)Lib\\x64;</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_64R</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">\n    <LibraryPath>$(LibraryPath);$(LibraryPath);$(DXSDK_DIR)Lib\\x64;</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_64R</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IncludePath>$(DXSDK_DIR)Include;$(IncludePath);</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x86;</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_32D</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IncludePath>$(DXSDK_DIR)Include;$(IncludePath);</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">\n    <IncludePath>$(DXSDK_DIR)Include;$(IncludePath);</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x86;</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_32R</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x86;</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_32R</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <ExceptionHandling>Sync</ExceptionHandling>\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Full</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n      <StringPooling>true</StringPooling>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <BrowseInformation>true</BrowseInformation>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"CPUT\\CPUTAssetLibrary.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTAssetLibraryDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTAssetSet.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTAssetSetDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTBuffer.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTBufferDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTButton.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTCheckbox.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTComputeShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTControl.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTDomainShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTDropdown.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTFont.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTFontDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTFrustum.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTGeometryShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTGuiController.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTGuiControllerDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTHullShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTITTTaskMarker.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTMaterial.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTMaterialDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTMeshDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTModel.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTModelDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTNullNode.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTConfigBlock.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTPerfTaskMarker.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTPixelShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTPostProcess.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTRenderNode.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTRenderStateBlock.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTRenderStateBlockDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTOSServicesWin.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTCamera.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTLight.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTRenderTarget.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTSlider.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTSprite.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTText.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTTexture.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTTextureDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTTimerWin.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTInputLayoutCacheDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTMesh.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTVertexShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUT_DX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTWindowWin.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"CPUT\\CPUTAssetLibrary.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetLibraryDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetSet.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetSetDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUT.h\" />\n    <ClInclude Include=\"CPUT\\CPUTBuffer.h\" />\n    <ClInclude Include=\"CPUT\\CPUTBufferDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTButton.h\" />\n    <ClInclude Include=\"CPUT\\CPUTCallbackHandler.h\" />\n    <ClInclude Include=\"CPUT\\CPUTCheckbox.h\" />\n    <ClInclude Include=\"CPUT\\CPUTComputeShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTControl.h\" />\n    <ClInclude Include=\"CPUT\\CPUTDomainShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTDropdown.h\" />\n    <ClInclude Include=\"CPUT\\CPUTEventHandler.h\" />\n    <ClInclude Include=\"CPUT\\CPUTFont.h\" />\n    <ClInclude Include=\"CPUT\\CPUTFontDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTFrustum.h\" />\n    <ClInclude Include=\"CPUT\\CPUTGeometryShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTGuiController.h\" />\n    <ClInclude Include=\"CPUT\\CPUTGuiControllerDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTHullShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTITTTaskMarker.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMaterial.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMaterialDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMath.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMesh.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMeshDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTModel.h\" />\n    <ClInclude Include=\"CPUT\\CPUTModelDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTNullNode.h\" />\n    <ClInclude Include=\"CPUT\\CPUTConfigBlock.h\" />\n    <ClInclude Include=\"CPUT\\CPUTPerfTaskMarker.h\" />\n    <ClInclude Include=\"CPUT\\CPUTPixelShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTPostProcess.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRefCount.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderNode.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderParams.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderParamsDX.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderStateBlock.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderStateBlockDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderStateMapsDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTOSServicesWin.h\" />\n    <ClInclude Include=\"CPUT\\CPUTCamera.h\" />\n    <ClInclude Include=\"CPUT\\CPUTLight.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderTarget.h\" />\n    <ClInclude Include=\"CPUT\\CPUTShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTSlider.h\" />\n    <ClInclude Include=\"CPUT\\CPUTSprite.h\" />\n    <ClInclude Include=\"CPUT\\CPUTText.h\" />\n    <ClInclude Include=\"CPUT\\CPUTTexture.h\" />\n    <ClInclude Include=\"CPUT\\CPUTTextureDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTTimer.h\" />\n    <ClInclude Include=\"CPUT\\CPUTTimerWin.h\" />\n    <ClInclude Include=\"CPUT\\CPUTInputLayoutCache.h\" />\n    <ClInclude Include=\"CPUT\\CPUTInputLayoutCacheDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTVertexShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUT_DX11.h\" />\n    <ClInclude Include=\"CPUT\\CRTMemoryDebug.h\" />\n    <ClInclude Include=\"CPUT\\CPUTWindowWin.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "CPUT/CPUT-DX11.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Asset\">\n      <UniqueIdentifier>{ec1f83ec-dbc4-4148-be0b-3d90f8e36a1b}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"GUI\">\n      <UniqueIdentifier>{3eb25951-0f7f-4d1a-abc3-b1b8abbfa219}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Models\">\n      <UniqueIdentifier>{2deb5dac-e9a1-42dc-9767-12d8f3a3ec47}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"System\">\n      <UniqueIdentifier>{376a6f7e-4f24-414c-91ec-2c4c17feff31}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\">\n      <UniqueIdentifier>{5bc7d424-d8fb-484a-9bf3-24461d8f96f6}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\\Shaders\">\n      <UniqueIdentifier>{31852ab3-f1df-435c-9e12-ba47e47e0b7e}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\\Textures\">\n      <UniqueIdentifier>{263c2361-b0f5-40e2-a2f2-5642f0208830}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\\RenderStates\">\n      <UniqueIdentifier>{b112b9da-1a18-4eab-b53b-0b2c29094928}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Asset\\CamerasLights\">\n      <UniqueIdentifier>{e9cd7379-7d27-4ddf-b87f-88a608940e77}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"RenderSystems\">\n      <UniqueIdentifier>{1e07919a-0326-4ce5-a15a-b06d16643b14}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\\Buffers\">\n      <UniqueIdentifier>{ff805aa1-d1b9-4eb4-b408-9599923770fe}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"CPUT\\CPUT_DX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTAssetLibraryDX11.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTAssetSetDX11.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTNullNode.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTRenderNode.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTControl.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTGuiControllerDX11.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTMeshDX11.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTModelDX11.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTITTTaskMarker.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTPerfTaskMarker.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTTimerWin.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTAssetLibrary.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTAssetSet.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTModel.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTButton.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTCheckbox.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTDropdown.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTGuiController.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTMaterialDX11.cpp\">\n      <Filter>Materials</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTCamera.cpp\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTLight.cpp\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTOSServicesWin.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTMesh.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTMaterial.cpp\">\n      <Filter>Materials</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTWindowWin.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTConfigBlock.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTPostProcess.cpp\">\n      <Filter>RenderSystems</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTFont.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTFontDX11.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTSlider.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTText.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTFrustum.cpp\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTComputeShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTDomainShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTGeometryShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTHullShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTPixelShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTTexture.cpp\">\n      <Filter>Materials\\Textures</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTTextureDX11.cpp\">\n      <Filter>Materials\\Textures</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTRenderStateBlock.cpp\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTRenderStateBlockDX11.cpp\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTRenderTarget.cpp\">\n      <Filter>RenderSystems</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTSprite.cpp\">\n      <Filter>RenderSystems</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTVertexShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTInputLayoutCacheDX11.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTBuffer.cpp\">\n      <Filter>Materials\\Buffers</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTBufferDX11.cpp\">\n      <Filter>Materials\\Buffers</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"CPUT\\CPUT_DX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetLibraryDX11.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTAssetSetDX11.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTNullNode.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderNode.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderParams.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderParamsDX.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTCallbackHandler.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTControl.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTEventHandler.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTGuiControllerDX11.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMeshDX11.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTModelDX11.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTITTTaskMarker.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTPerfTaskMarker.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRefCount.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTTimerWin.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CRTMemoryDebug.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMath.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetLibrary.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTAssetSet.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMesh.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTModel.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTButton.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTCheckbox.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTDropdown.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTGuiController.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMaterial.h\">\n      <Filter>Materials</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMaterialDX11.h\">\n      <Filter>Materials</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTCamera.h\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTLight.h\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTOSServicesWin.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUT.h\" />\n    <ClInclude Include=\"CPUT\\CPUTWindowWin.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTConfigBlock.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTPostProcess.h\">\n      <Filter>RenderSystems</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTFont.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTFontDX11.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTSlider.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTText.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTTimer.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTFrustum.h\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTHullShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTComputeShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTDomainShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTGeometryShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTPixelShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTTextureDX11.h\">\n      <Filter>Materials\\Textures</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTTexture.h\">\n      <Filter>Materials\\Textures</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderStateMapsDX11.h\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderStateBlock.h\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderStateBlockDX11.h\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTSprite.h\">\n      <Filter>RenderSystems</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderTarget.h\">\n      <Filter>RenderSystems</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTVertexShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTInputLayoutCache.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTInputLayoutCacheDX11.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTBuffer.h\">\n      <Filter>Materials\\Buffers</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTBufferDX11.h\">\n      <Filter>Materials\\Buffers</Filter>\n    </ClInclude>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "CPUT/CPUT-DX11_2012.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Profile|Win32\">\n      <Configuration>Profile</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Profile|x64\">\n      <Configuration>Profile</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}</ProjectGuid>\n    <RootNamespace>CPUTDX11</RootNamespace>\n    <ProjectName>CPUT-DX11</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\" Label=\"Configuration\">\n    <ConfigurationType>StaticLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IncludePath>$(IncludePath);$(DXSDK_DIR)Include;</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LibraryPath>$(DXSDK_DIR)Lib\\x64;$(LibraryPath);</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_64D</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IncludePath>$(IncludePath);$(DXSDK_DIR)Include;</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">\n    <IncludePath>$(IncludePath);$(DXSDK_DIR)Include;</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LibraryPath>$(DXSDK_DIR)Lib\\x64;$(LibraryPath);</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_64R</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">\n    <LibraryPath>$(DXSDK_DIR)Lib\\x64;$(LibraryPath);</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_64R</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IncludePath>$(IncludePath);$(DXSDK_DIR)Include;</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LibraryPath>$(DXSDK_DIR)Lib\\x86;$(LibraryPath);</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_32D</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IncludePath>$(IncludePath);$(DXSDK_DIR)Include;</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">\n    <IncludePath>$(IncludePath);$(DXSDK_DIR)Include;</IncludePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LibraryPath>$(DXSDK_DIR)Lib\\x86;$(LibraryPath);</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_32R</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">\n    <LibraryPath>$(DXSDK_DIR)Lib\\x86;$(LibraryPath);</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\lib\\</OutDir>\n    <TargetName>$(ProjectName)_32R</TargetName>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <ExceptionHandling>Sync</ExceptionHandling>\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>true</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Full</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n      <StringPooling>true</StringPooling>\n      <BufferSecurityCheck>false</BufferSecurityCheck>\n      <FloatingPointExceptions>false</FloatingPointExceptions>\n      <BrowseInformation>true</BrowseInformation>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <MultiProcessorCompilation>true</MultiProcessorCompilation>\n      <ProgramDataBaseFileName>$(IntDir)vc$(PlatformToolsetVersion).pdb</ProgramDataBaseFileName>\n      <RuntimeTypeInfo>false</RuntimeTypeInfo>\n      <OpenMPSupport>false</OpenMPSupport>\n    </ClCompile>\n    <Link>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n    </Link>\n    <Lib>\n      <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\n    </Lib>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"CPUT\\CPUTAssetLibrary.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTAssetLibraryDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTAssetSet.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTAssetSetDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTBuffer.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTBufferDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTButton.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTCheckbox.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTComputeShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTControl.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTDomainShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTDropdown.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTFont.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTFontDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTFrustum.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTGeometryShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTGuiController.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTGuiControllerDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTHullShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTITTTaskMarker.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTMaterial.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTMaterialDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTMeshDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTModel.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTModelDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTNullNode.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTConfigBlock.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTPerfTaskMarker.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTPixelShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTPostProcess.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTRenderNode.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTRenderStateBlock.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTRenderStateBlockDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTOSServicesWin.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTCamera.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTLight.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTRenderTarget.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTSlider.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTSprite.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTText.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTTexture.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTTextureDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTTimerWin.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTInputLayoutCacheDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTMesh.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTVertexShaderDX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUT_DX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTWindowWin.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"CPUT\\CPUTAssetLibrary.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetLibraryDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetSet.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetSetDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUT.h\" />\n    <ClInclude Include=\"CPUT\\CPUTBuffer.h\" />\n    <ClInclude Include=\"CPUT\\CPUTBufferDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTButton.h\" />\n    <ClInclude Include=\"CPUT\\CPUTCallbackHandler.h\" />\n    <ClInclude Include=\"CPUT\\CPUTCheckbox.h\" />\n    <ClInclude Include=\"CPUT\\CPUTComputeShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTControl.h\" />\n    <ClInclude Include=\"CPUT\\CPUTDomainShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTDropdown.h\" />\n    <ClInclude Include=\"CPUT\\CPUTEventHandler.h\" />\n    <ClInclude Include=\"CPUT\\CPUTFont.h\" />\n    <ClInclude Include=\"CPUT\\CPUTFontDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTFrustum.h\" />\n    <ClInclude Include=\"CPUT\\CPUTGeometryShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTGuiController.h\" />\n    <ClInclude Include=\"CPUT\\CPUTGuiControllerDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTHullShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTITTTaskMarker.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMaterial.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMaterialDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMath.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMesh.h\" />\n    <ClInclude Include=\"CPUT\\CPUTMeshDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTModel.h\" />\n    <ClInclude Include=\"CPUT\\CPUTModelDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTNullNode.h\" />\n    <ClInclude Include=\"CPUT\\CPUTConfigBlock.h\" />\n    <ClInclude Include=\"CPUT\\CPUTPerfTaskMarker.h\" />\n    <ClInclude Include=\"CPUT\\CPUTPixelShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTPostProcess.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRefCount.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderNode.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderParams.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderParamsDX.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderStateBlock.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderStateBlockDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderStateMapsDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTOSServicesWin.h\" />\n    <ClInclude Include=\"CPUT\\CPUTCamera.h\" />\n    <ClInclude Include=\"CPUT\\CPUTLight.h\" />\n    <ClInclude Include=\"CPUT\\CPUTRenderTarget.h\" />\n    <ClInclude Include=\"CPUT\\CPUTShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTSlider.h\" />\n    <ClInclude Include=\"CPUT\\CPUTSprite.h\" />\n    <ClInclude Include=\"CPUT\\CPUTText.h\" />\n    <ClInclude Include=\"CPUT\\CPUTTexture.h\" />\n    <ClInclude Include=\"CPUT\\CPUTTextureDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTTimer.h\" />\n    <ClInclude Include=\"CPUT\\CPUTTimerWin.h\" />\n    <ClInclude Include=\"CPUT\\CPUTInputLayoutCache.h\" />\n    <ClInclude Include=\"CPUT\\CPUTInputLayoutCacheDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTVertexShaderDX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUT_DX11.h\" />\n    <ClInclude Include=\"CPUT\\CRTMemoryDebug.h\" />\n    <ClInclude Include=\"CPUT\\CPUTWindowWin.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "CPUT/CPUT-DX11_2012.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Asset\">\n      <UniqueIdentifier>{ec1f83ec-dbc4-4148-be0b-3d90f8e36a1b}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"GUI\">\n      <UniqueIdentifier>{3eb25951-0f7f-4d1a-abc3-b1b8abbfa219}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Models\">\n      <UniqueIdentifier>{2deb5dac-e9a1-42dc-9767-12d8f3a3ec47}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"System\">\n      <UniqueIdentifier>{376a6f7e-4f24-414c-91ec-2c4c17feff31}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\">\n      <UniqueIdentifier>{5bc7d424-d8fb-484a-9bf3-24461d8f96f6}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\\Shaders\">\n      <UniqueIdentifier>{31852ab3-f1df-435c-9e12-ba47e47e0b7e}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\\Textures\">\n      <UniqueIdentifier>{263c2361-b0f5-40e2-a2f2-5642f0208830}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\\RenderStates\">\n      <UniqueIdentifier>{b112b9da-1a18-4eab-b53b-0b2c29094928}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Asset\\CamerasLights\">\n      <UniqueIdentifier>{e9cd7379-7d27-4ddf-b87f-88a608940e77}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"RenderSystems\">\n      <UniqueIdentifier>{1e07919a-0326-4ce5-a15a-b06d16643b14}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Materials\\Buffers\">\n      <UniqueIdentifier>{ff805aa1-d1b9-4eb4-b408-9599923770fe}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"CPUT\\CPUT_DX11.cpp\" />\n    <ClCompile Include=\"CPUT\\CPUTAssetLibraryDX11.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTAssetSetDX11.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTNullNode.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTRenderNode.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTControl.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTGuiControllerDX11.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTMeshDX11.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTModelDX11.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTITTTaskMarker.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTPerfTaskMarker.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTTimerWin.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTAssetLibrary.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTAssetSet.cpp\">\n      <Filter>Asset</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTModel.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTButton.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTCheckbox.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTDropdown.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTGuiController.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTMaterialDX11.cpp\">\n      <Filter>Materials</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTCamera.cpp\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTLight.cpp\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTOSServicesWin.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTMesh.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTMaterial.cpp\">\n      <Filter>Materials</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTWindowWin.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTConfigBlock.cpp\">\n      <Filter>System</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTPostProcess.cpp\">\n      <Filter>RenderSystems</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTFont.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTFontDX11.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTSlider.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTText.cpp\">\n      <Filter>GUI</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTFrustum.cpp\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTComputeShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTDomainShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTGeometryShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTHullShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTPixelShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTTexture.cpp\">\n      <Filter>Materials\\Textures</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTTextureDX11.cpp\">\n      <Filter>Materials\\Textures</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTRenderStateBlock.cpp\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTRenderStateBlockDX11.cpp\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTRenderTarget.cpp\">\n      <Filter>RenderSystems</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTSprite.cpp\">\n      <Filter>RenderSystems</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTVertexShaderDX11.cpp\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTInputLayoutCacheDX11.cpp\">\n      <Filter>Models</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTBuffer.cpp\">\n      <Filter>Materials\\Buffers</Filter>\n    </ClCompile>\n    <ClCompile Include=\"CPUT\\CPUTBufferDX11.cpp\">\n      <Filter>Materials\\Buffers</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"CPUT\\CPUT_DX11.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetLibraryDX11.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTAssetSetDX11.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTNullNode.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderNode.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderParams.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderParamsDX.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTCallbackHandler.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTControl.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTEventHandler.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTGuiControllerDX11.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMeshDX11.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTModelDX11.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTITTTaskMarker.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTPerfTaskMarker.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRefCount.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTTimerWin.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CRTMemoryDebug.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMath.h\" />\n    <ClInclude Include=\"CPUT\\CPUTAssetLibrary.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTAssetSet.h\">\n      <Filter>Asset</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMesh.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTModel.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTButton.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTCheckbox.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTDropdown.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTGuiController.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMaterial.h\">\n      <Filter>Materials</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTMaterialDX11.h\">\n      <Filter>Materials</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTCamera.h\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTLight.h\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTOSServicesWin.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUT.h\" />\n    <ClInclude Include=\"CPUT\\CPUTWindowWin.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTConfigBlock.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTPostProcess.h\">\n      <Filter>RenderSystems</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTFont.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTFontDX11.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTSlider.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTText.h\">\n      <Filter>GUI</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTTimer.h\">\n      <Filter>System</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTFrustum.h\">\n      <Filter>Asset\\CamerasLights</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTHullShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTComputeShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTDomainShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTGeometryShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTPixelShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTTextureDX11.h\">\n      <Filter>Materials\\Textures</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTTexture.h\">\n      <Filter>Materials\\Textures</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderStateMapsDX11.h\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderStateBlock.h\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderStateBlockDX11.h\">\n      <Filter>Materials\\RenderStates</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTSprite.h\">\n      <Filter>RenderSystems</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTRenderTarget.h\">\n      <Filter>RenderSystems</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTVertexShaderDX11.h\">\n      <Filter>Materials\\Shaders</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTInputLayoutCache.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTInputLayoutCacheDX11.h\">\n      <Filter>Models</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTBuffer.h\">\n      <Filter>Materials\\Buffers</Filter>\n    </ClInclude>\n    <ClInclude Include=\"CPUT\\CPUTBufferDX11.h\">\n      <Filter>Materials\\Buffers</Filter>\n    </ClInclude>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "CPUT/resources/controls/atlas/atlas.cmd",
    "content": "-fbx:atlas.fbx -outputdir:../CPRT/atlas/ "
  },
  {
    "path": "CPUT/resources/controls/atlas/atlas.set",
    "content": "[node 0]\ntype = model\nname = polySurface1\nparent = -1\nmatrixColumn0 = 1 0 -0 0\nmatrixColumn1 = 0 1 -0 0\nmatrixColumn2 = -0 -0 1 -0\nmatrixColumn3 = 0 0 0 1\nBoundingBoxCenter = 0.0527344 0 -0 \nBoundingBoxHalf = 0.0527344 0 0 \nmeshcount = 1 \nmaterial0 = lambert1\n"
  },
  {
    "path": "CPUT/resources/controls/atlas/lambert1.mtl",
    "content": "shadingmodel = lambert\nAmbientColor = 0 0 0 \nAmbientFactor = 1 \nBump = 0 0 0 \nBumpFactor = 1 \nDiffuseColor = 0.5 0.5 0.5 \nDiffuseFactor = 0.8 \nDisplacementColor = 0 0 0 \nDisplacementFactor = 1 \nEmissiveColor = 0 0 0 \nEmissiveFactor = 1 \nTransparentColor = 0 0 0 \nTransparencyFactor = 1 \nVertexShaderFile = vertexShaderDX11\nVertexShaderMain = VS\nVertexShaderProfile = vs_4_0\nPixelShaderFile = pixelShaderDX11\nPixelShaderMain = PS\nPixelShaderProfile = ps_4_0\n"
  },
  {
    "path": "CPUT/resources/shaders/GUIRenderState.rs",
    "content": "[DepthStencilStateDX11]\nDepthEnable = false\n\n[RasterizerStateDX11]\nFillMode = D3D11_FILL_SOLID\nCullMode = D3D11_CULL_BACK\nFrontCounterClockwise = false\nDepthBias = 0.0\nDepthBiasClamp = 0.0\nSlopeScaledDepthBias = 0.0\nDepthClipEnable = true\nScissorEnable = false\nMultisampleEnable = false\nAntialiasedLineEnable = false\n\n[RenderTargetBlendStateDX11_1]\nblendenable = true\nsrcblend = D3D11_BLEND_SRC_ALPHA\ndestblend = D3D11_BLEND_INV_SRC_ALPHA\nsrcblendalpha = D3D11_BLEND_ONE\ndestblendalpha = D3D11_BLEND_ONE\nblendop = D3D11_BLEND_OP_ADD\nblendopalpha = D3D11_BLEND_OP_ADD\nrendertargetwritemask = 15 // D3D11_COLOR_WRITE_ENABLE_ALL\n\n[BlendStateDX11]\nalphatocoverageenable = false\nindependentblendenable = false;\n\n[SamplerDX11_1]\nfilter = D3D11_FILTER_MIN_MAG_MIP_POINT\nAddressU = D3D11_TEXTURE_ADDRESS_CLAMP\nAddressV = D3D11_TEXTURE_ADDRESS_CLAMP\nAddressW = D3D11_TEXTURE_ADDRESS_CLAMP\nMipLODBias = 0\nMaxAnisotropy = 0\nComparisonFunc = D3D11_COMPARISON_NEVER\nBorderColor0 = 0\nBorderColor1 = 0\nBorderColor2 = 0\nBorderColor3 = 0\nMinLOD = 0\nMaxLOD = 3.402823466e+38f // D3D11_FLOAT32_MAX\n"
  },
  {
    "path": "CPUT/resources/shaders/GUIShaderDX.ps",
    "content": "//--------------------------------------------------------------------------------------\n// Pixel Shader\n//--------------------------------------------------------------------------------------\n\nTexture2D txDiffuse : register( t0 );\nSamplerState samLinear : register( s0 );\n\nstruct PS_INPUT\n{ \n    float4 Pos : SV_POSITION;    \n    float2 Tex : TEXCOORD;\n    float4 Color: COLOR;\n};\n\n// alpha blended texture modulated by vertex color\nfloat4 PS( PS_INPUT input) : SV_Target\n{\n    return txDiffuse.Sample( samLinear, input.Tex ) * input.Color;  \n}\n\n\n"
  },
  {
    "path": "CPUT/resources/shaders/GUIShaderDX.vs",
    "content": "//--------------------------------------------------------------------------------------\n// Vertex Shader\n//--------------------------------------------------------------------------------------\nTexture2D txDiffuse : register( t0 );\nSamplerState samLinear : register( s0 );\n\nstruct VS_INPUT\n{\n    float4 Pos\t: POSITION;\n    float2 Tex\t: TEXCOORD;\n    float4 Color: COLOR;    \n};\n\nstruct PS_INPUT\n{\n    float4 Pos : SV_POSITION;\n    float2 Tex : TEXCOORD;\n    float4 Color: COLOR;\n};\n\ncbuffer ConstantBuffer : register( cb0 )\n{    \t\n     matrix  projectionMatrix;\n     matrix  modelMatrix;\n};\n\nPS_INPUT VS( VS_INPUT input )\n{\n    PS_INPUT output = (PS_INPUT)0;\n\n    input.Pos.w = 1.0f;\n\t\n    output.Pos = mul( input.Pos, modelMatrix );\n    output.Pos = mul( output.Pos, projectionMatrix );\n \n    output.Tex = input.Tex;\n\n    output.Color = input.Color;\n    \n    return output;\n}\n"
  },
  {
    "path": "Default_Config.txt",
    "content": "RawDEMDataFile = media\\Terrain\\HeightMap.tif\nMaterialMaskFile = media\\Terrain\\Mask.png\nTexturingMode = MaterialMaskNM\nElevationSamplingInterval = 32\nScalingFactor = 10\nRingDimension = 65\nNumRings = 15\nColOffset = 1356\nRowOffset = 924\nTileTexture0 = media\\tiles\\gravel_DM.dds\nTileTexture1 = media\\tiles\\grass_DM.dds\nTileTexture2 = media\\tiles\\cliff_DM.dds\nTileTexture3 = media\\tiles\\snow_DM.dds\nTileTexture4 = media\\tiles\\grassDark_DM.dds\nTileNormalMap0 = media\\tiles\\gravel_NM.dds\nTileNormalMap1 = media\\tiles\\grass_NM.dds\nTileNormalMap2 = media\\tiles\\cliff_NM.dds\nTileNormalMap3 = media\\tiles\\Snow_NM.jpg\nTileNormalMap4 = media\\tiles\\grass_NM.dds\nTilingScale0 = 200\nTilingScale1 = 500\nTilingScale2 = 800\nTilingScale3 = 80\nTilingScale4 = 80\nAnimateSun = false"
  },
  {
    "path": "LightSctrPostProcess.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"StdAfx.h\"\n#include \"LightSctrPostProcess.h\"\n#include <atlcomcli.h>\n#include <cassert>\n#include <stdio.h>\n#include \"ShaderMacroHelper.h\"\n\n#define _USE_MATH_DEFINES\n#include <math.h>\n\n#ifndef V\n#define V(x)           { hr = (x); assert( SUCCEEDED(hr) ); }\n#endif\n#ifndef V_RETURN\n#define V_RETURN(x)    { hr = (x); assert( SUCCEEDED(hr) ); if( FAILED(hr) ) { return hr; } }\n#endif\n\nCLightSctrPostProcess :: CLightSctrPostProcess() : \n    m_uiSampleRefinementCSThreadGroupSize(0),\n    // Using small group size is inefficient because a lot of SIMD lanes become idle\n    m_uiSampleRefinementCSMinimumThreadGroupSize(128),// Must be greater than 32\n    m_fTurbidity(1.02f),\n    m_strEffectPath( L\"fx\\\\LightScattering.fx\" ),\n    m_bUseCombinedMinMaxTexture(false)\n{\n    ComputeScatteringCoefficients();\n}\n\nCLightSctrPostProcess :: ~CLightSctrPostProcess()\n{\n\n}\n\nHRESULT CLightSctrPostProcess :: OnCreateDevice(ID3D11Device* in_pd3dDevice, \n                                                ID3D11DeviceContext *in_pd3dDeviceContext)\n{\n    \n\n    HRESULT hr;\n\n\n    // Create depth stencil states\n\n    D3D11_DEPTH_STENCIL_DESC EnableDepthTestDSDesc;\n    ZeroMemory(&EnableDepthTestDSDesc, sizeof(EnableDepthTestDSDesc));\n    EnableDepthTestDSDesc.DepthEnable = TRUE;\n    EnableDepthTestDSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;\n    EnableDepthTestDSDesc.DepthFunc = D3D11_COMPARISON_EQUAL;\n    V_RETURN( in_pd3dDevice->CreateDepthStencilState(  &EnableDepthTestDSDesc, &m_pEnableDepthCmpEqDS) );\n    \n    // Disable depth testing\n    D3D11_DEPTH_STENCIL_DESC DisableDepthTestDSDesc;\n    ZeroMemory(&DisableDepthTestDSDesc, sizeof(DisableDepthTestDSDesc));\n    DisableDepthTestDSDesc.DepthEnable = FALSE;\n    DisableDepthTestDSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;\n    V_RETURN( in_pd3dDevice->CreateDepthStencilState(  &DisableDepthTestDSDesc, &m_pDisableDepthTestDS) );\n    \n    // Disable depth testing and always increment stencil value\n    // This depth stencil state is used to mark samples which will undergo further processing\n    // Pixel shader discards pixels which should not be further processed, thus keeping the\n    // stencil value untouched\n    // For instance, pixel shader performing epipolar coordinates generation discards all \n    // sampes, whoose coordinates are outside the screen [-1,1]x[-1,1] area\n    D3D11_DEPTH_STENCIL_DESC DisbaleDepthIncrStencilDSSDesc = DisableDepthTestDSDesc;\n    DisbaleDepthIncrStencilDSSDesc.StencilEnable = TRUE;\n    DisbaleDepthIncrStencilDSSDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;\n    DisbaleDepthIncrStencilDSSDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_INCR;\n    DisbaleDepthIncrStencilDSSDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;\n    DisbaleDepthIncrStencilDSSDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;\n    DisbaleDepthIncrStencilDSSDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;\n    DisbaleDepthIncrStencilDSSDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_INCR;\n    DisbaleDepthIncrStencilDSSDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;\n    DisbaleDepthIncrStencilDSSDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;\n    DisbaleDepthIncrStencilDSSDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;\n    DisbaleDepthIncrStencilDSSDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;\n    V_RETURN( in_pd3dDevice->CreateDepthStencilState(  &DisbaleDepthIncrStencilDSSDesc, &m_pDisableDepthTestIncrStencilDS) );\n\n\n    // Disable depth testing, stencil testing function equal, increment stencil\n    // This state is used to process only these pixels that were marked at the previous pass\n    // All pixels whith different stencil value are discarded from further processing as well\n    // as some pixels can also be discarded during the draw call\n    // For instance, pixel shader marking ray marching samples processes only these pixels which are inside\n    // the screen. It also discards all but these samples which are interpolated from themselves\n    D3D11_DEPTH_STENCIL_DESC DisbaleDepthStencilEqualIncrStencilDSSDesc = DisbaleDepthIncrStencilDSSDesc;\n    DisbaleDepthStencilEqualIncrStencilDSSDesc.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL;\n    DisbaleDepthStencilEqualIncrStencilDSSDesc.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL;\n    V_RETURN( in_pd3dDevice->CreateDepthStencilState(  &DisbaleDepthStencilEqualIncrStencilDSSDesc, &m_pNoDepth_StEqual_IncrStencilDS) );\n\n    D3D11_DEPTH_STENCIL_DESC DisbaleDepthStencilEqualKeepStencilDSSDesc = DisbaleDepthStencilEqualIncrStencilDSSDesc;\n    DisbaleDepthStencilEqualKeepStencilDSSDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;\n    DisbaleDepthStencilEqualKeepStencilDSSDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;\n    V_RETURN( in_pd3dDevice->CreateDepthStencilState(  &DisbaleDepthStencilEqualKeepStencilDSSDesc, &m_pNoDepth_StEqual_KeepStencilDS) );\n    \n\n    // Create rasterizer state\n    D3D11_RASTERIZER_DESC SolidFillNoCullRSDesc;\n    ZeroMemory(&SolidFillNoCullRSDesc, sizeof(SolidFillNoCullRSDesc));\n    SolidFillNoCullRSDesc.FillMode = D3D11_FILL_SOLID;\n    SolidFillNoCullRSDesc.CullMode = D3D11_CULL_NONE;\n    V_RETURN( in_pd3dDevice->CreateRasterizerState( &SolidFillNoCullRSDesc, &m_pSolidFillNoCullRS) );\n\n    // Create default blend state\n    D3D11_BLEND_DESC DefaultBlendStateDesc;\n    ZeroMemory(&DefaultBlendStateDesc, sizeof(DefaultBlendStateDesc));\n    DefaultBlendStateDesc.IndependentBlendEnable = FALSE;\n    for(int i=0; i< _countof(DefaultBlendStateDesc.RenderTarget); i++)\n        DefaultBlendStateDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;\n    V_RETURN( in_pd3dDevice->CreateBlendState( &DefaultBlendStateDesc, &m_pDefaultBS) );\n\n    D3D11_BLEND_DESC AdditiveBlendStateDesc;\n    ZeroMemory(&AdditiveBlendStateDesc, sizeof(AdditiveBlendStateDesc));\n    AdditiveBlendStateDesc.IndependentBlendEnable = FALSE;\n    for(int i=0; i< _countof(AdditiveBlendStateDesc.RenderTarget); i++)\n        AdditiveBlendStateDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;\n    AdditiveBlendStateDesc.RenderTarget[0].BlendEnable = TRUE;\n    AdditiveBlendStateDesc.RenderTarget[0].BlendOp     = D3D11_BLEND_OP_ADD;\n    AdditiveBlendStateDesc.RenderTarget[0].BlendOpAlpha= D3D11_BLEND_OP_ADD;\n    AdditiveBlendStateDesc.RenderTarget[0].DestBlend   = D3D11_BLEND_ONE;\n    AdditiveBlendStateDesc.RenderTarget[0].DestBlendAlpha= D3D11_BLEND_ONE;\n    AdditiveBlendStateDesc.RenderTarget[0].SrcBlend     = D3D11_BLEND_ONE;\n    AdditiveBlendStateDesc.RenderTarget[0].SrcBlendAlpha= D3D11_BLEND_ONE;\n    V_RETURN( in_pd3dDevice->CreateBlendState( &AdditiveBlendStateDesc, &m_pAdditiveBlendBS) );\n\n    D3D11_BLEND_DESC AlphaBlendStateDesc = AdditiveBlendStateDesc;\n    AlphaBlendStateDesc.RenderTarget[0].SrcBlend      = D3D11_BLEND_SRC_ALPHA;\n    AlphaBlendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;\n    AlphaBlendStateDesc.RenderTarget[0].DestBlend      = D3D11_BLEND_INV_SRC_ALPHA;\n    AlphaBlendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;\n    V_RETURN( in_pd3dDevice->CreateBlendState( &AlphaBlendStateDesc, &m_pAlphaBlendBS) );\n    \n\n    \n\n    // Create samplers\n\n    D3D11_SAMPLER_DESC SamLinearBorder0Desc = \n    {\n        D3D11_FILTER_MIN_MAG_MIP_LINEAR,\n        D3D11_TEXTURE_ADDRESS_BORDER,\n        D3D11_TEXTURE_ADDRESS_BORDER,\n        D3D11_TEXTURE_ADDRESS_BORDER,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_NEVER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    V_RETURN( in_pd3dDevice->CreateSamplerState( &SamLinearBorder0Desc, &m_psamLinearBorder0) );\n\n    D3D11_SAMPLER_DESC SamLinearClampDesc = \n    {\n        D3D11_FILTER_MIN_MAG_MIP_LINEAR,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_NEVER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    V_RETURN( in_pd3dDevice->CreateSamplerState( &SamLinearClampDesc, &m_psamLinearClamp) );\n\n    D3D11_SAMPLER_DESC SamPointClampDesc = SamLinearClampDesc;\n    SamPointClampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;\n    V_RETURN( in_pd3dDevice->CreateSamplerState( &SamPointClampDesc, &m_psamPointClamp) );\n\n    D3D11_SAMPLER_DESC SamComparisonDesc = \n    {\n        D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT,\n        D3D11_TEXTURE_ADDRESS_BORDER,\n        D3D11_TEXTURE_ADDRESS_BORDER,\n        D3D11_TEXTURE_ADDRESS_BORDER,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_GREATER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    V_RETURN( in_pd3dDevice->CreateSamplerState( &SamComparisonDesc, &m_psamComparison) );\n\n\n    \n    // Create constant buffers\n\n    D3D11_BUFFER_DESC CBDesc = \n    {\n        sizeof(SCameraAttribs),\n        D3D11_USAGE_DYNAMIC,\n        D3D11_BIND_CONSTANT_BUFFER,\n        D3D11_CPU_ACCESS_WRITE, //UINT CPUAccessFlags\n        0, //UINT MiscFlags;\n        0, //UINT StructureByteStride;\n    };\n    V_RETURN( in_pd3dDevice->CreateBuffer( &CBDesc, NULL, &m_pcbCameraAttribs) );\n\n    //CBDesc.ByteWidth = sizeof(SLightAttribs);\n    //V_RETURN( in_pd3dDevice->CreateBuffer( &CBDesc, NULL, &m_pcbLightAttribs) );\n\n    CBDesc.ByteWidth = sizeof(SPostProcessingAttribs);\n    V_RETURN( in_pd3dDevice->CreateBuffer( &CBDesc, NULL, &m_pcbPostProcessingAttribs) );\n\n    CBDesc.ByteWidth = sizeof(SMiscDynamicParams);\n    V_RETURN( in_pd3dDevice->CreateBuffer( &CBDesc, NULL, &m_pcbMiscParams) );\n\n    CBDesc.ByteWidth = sizeof(SAirScatteringAttribs);\n    CBDesc.Usage = D3D11_USAGE_DEFAULT;\n    CBDesc.CPUAccessFlags = 0;\n    D3D11_SUBRESOURCE_DATA InitData = \n    {\n        &m_MediaParams,\n        0, // UINT SysMemPitch\n        0  // UINT SysMemSlicePitch\n    };\n    V_RETURN( in_pd3dDevice->CreateBuffer( &CBDesc, &InitData, &m_pcbMediaAttribs) );\n\n    CRenderTechnique GenerateScreenSizeQuadTech;\n    GenerateScreenSizeQuadTech.SetDeviceAndContext( in_pd3dDevice, in_pd3dDeviceContext );\n    V( GenerateScreenSizeQuadTech.CreateVertexShaderFromFile(m_strEffectPath, \"GenerateScreenSizeQuadVS\", NULL ) );\n    m_pGenerateScreenSizeQuadVS = GenerateScreenSizeQuadTech.GetVS();\n\n    CreatePrecomputedOpticalDepthTexture(in_pd3dDevice, in_pd3dDeviceContext);\n\n    return S_OK;\n}\n\nvoid CLightSctrPostProcess :: OnDestroyDevice()\n{\n    m_ptex2DSliceEndpointsSRV.Release();\n    m_ptex2DSliceEndpointsRTV.Release();\n    m_ptex2DCoordinateTextureSRV.Release();\n    m_ptex2DCoordinateTextureRTV.Release();\n    m_ptex2DEpipolarImageDSV.Release();\n    m_ptex2DInterpolationSourcesSRV.Release();\n    m_ptex2DInterpolationSourcesUAV.Release();\n    m_ptex2DEpipolarCamSpaceZSRV.Release();\n    m_ptex2DEpipolarCamSpaceZRTV.Release();\n    m_ptex2DEpipolarInscatteringSRV.Release();\n    m_ptex2DEpipolarInscatteringRTV.Release();\n    m_ptex2DEpipolarExtinctionSRV.Release();\n    m_ptex2DEpipolarExtinctionRTV.Release();\n    m_ptex2DInitialScatteredLightSRV.Release();\n    m_ptex2DInitialScatteredLightRTV.Release();\n    m_ptex2DScreenSizeDSV.Release();\n    m_ptex2DCameraSpaceZRTV.Release();\n    m_ptex2DCameraSpaceZSRV.Release();\n    for(int i=0; i < _countof(m_ptex2DMinMaxShadowMapSRV); ++i)\n        m_ptex2DMinMaxShadowMapSRV[i].Release();\n    for(int i=0; i < _countof(m_ptex2DMinMaxShadowMapRTV); ++i)\n        m_ptex2DMinMaxShadowMapRTV[i].Release();\n    m_ptex2DSliceUVDirAndOriginSRV.Release();\n    m_ptex2DSliceUVDirAndOriginRTV.Release();\n\n    m_ptex2DOccludedNetDensityToAtmTopSRV.Release();\n    m_ptex2DOccludedNetDensityToAtmTopRTV.Release();\n    m_ptex3DSingleScatteringSRV.Release();\n    m_ptex3DHighOrderScatteringSRV.Release();\n    m_ptex3DMultipleScatteringSRV.Release();\n    \n    m_ptex2DLowResLuminanceSRV.Release();\n    m_ptex2DLowResLuminanceRTV.Release();\n    m_ptex2DAverageLuminanceRTV.Release();\n    m_ptex2DAverageLuminanceSRV.Release();\n\n    m_ptex2DAmbientSkyLightRTV.Release();\n    m_ptex2DAmbientSkyLightSRV.Release();\n\n    m_ptex2DSphereRandomSamplingSRV.Release();\n\n    m_psamLinearClamp.Release();\n    m_psamLinearBorder0.Release();\n    m_psamComparison.Release();\n    m_psamPointClamp.Release();\n\n    m_ReconstrCamSpaceZTech.Release();\n    m_RendedSliceEndpointsTech.Release();\n    m_RendedCoordTexTech.Release();\n    m_RefineSampleLocationsTech.Release();\n    m_RenderCoarseUnshadowedInsctrTech.Release();\n    m_MarkRayMarchingSamplesInStencilTech.Release();\n    m_RenderSliceUVDirInSMTech.Release();\n    m_InitializeMinMaxShadowMapTech.Release();\n    m_ComputeMinMaxSMLevelTech.Release();\n    m_DoRayMarchTech[0].Release();\n    m_DoRayMarchTech[1].Release();\n    m_InterpolateIrradianceTech.Release();\n    m_UnwarpEpipolarSctrImgTech.Release();\n    m_UnwarpAndRenderLuminanceTech.Release();\n    m_UpdateAverageLuminanceTech.Release();\n    for(size_t i=0; i<_countof(m_FixInsctrAtDepthBreaksTech); ++i)\n        m_FixInsctrAtDepthBreaksTech[i].Release();\n    m_RenderSampleLocationsTech.Release();\n    m_RenderSunTech.Release();\n    m_PrecomputeSingleSctrTech.Release();\n    m_ComputeSctrRadianceTech.Release();\n    m_ComputeScatteringOrderTech.Release();\n    m_AddScatteringOrderTech.Release();\n\n    m_pGenerateScreenSizeQuadVS.Release();\n\n    m_pEnableDepthCmpEqDS.Release();\n    m_pDisableDepthTestDS.Release();\n    m_pDisableDepthTestIncrStencilDS.Release();\n    m_pNoDepth_StEqual_IncrStencilDS.Release();\n    m_pNoDepth_StEqual_KeepStencilDS.Release();\n\n    m_pSolidFillNoCullRS.Release();\n\n    m_pDefaultBS.Release();\n    m_pAdditiveBlendBS.Release();\n    m_pAlphaBlendBS.Release();\n\n    m_pcbCameraAttribs.Release();\n    //m_pcbLightAttribs.Release();\n    m_pcbPostProcessingAttribs.Release();\n    m_pcbMediaAttribs.Release();\n    m_pcbMiscParams.Release();\n}\n\nHRESULT CLightSctrPostProcess :: OnResizedSwapChain(ID3D11Device* pd3dDevice, UINT uiBackBufferWidth, UINT uiBackBufferHeight)\n{\n    m_uiBackBufferWidth = uiBackBufferWidth;\n    m_uiBackBufferHeight = uiBackBufferHeight;\n    D3D11_TEXTURE2D_DESC ScreenSizeDepthStencilTexDesc = \n    {\n        uiBackBufferWidth,                  //UINT Width;\n        uiBackBufferHeight,                 //UINT Height;\n        1,                                  //UINT MipLevels;\n        1,                                  //UINT ArraySize;\n        DXGI_FORMAT_D24_UNORM_S8_UINT,      //DXGI_FORMAT Format;\n        {1,0},                              //DXGI_SAMPLE_DESC SampleDesc;\n        D3D11_USAGE_DEFAULT,                //D3D11_USAGE Usage;\n        D3D11_BIND_DEPTH_STENCIL,           //UINT BindFlags;\n        0,                                  //UINT CPUAccessFlags;\n        0,                                  //UINT MiscFlags;\n    };\n\n    m_ptex2DScreenSizeDSV.Release();\n    CComPtr<ID3D11Texture2D> ptex2DScreenSizeDepthStencil;\n    // Create 2-D texture, shader resource and target view buffers on the device\n    HRESULT hr;\n    V_RETURN( pd3dDevice->CreateTexture2D( &ScreenSizeDepthStencilTexDesc, NULL, &ptex2DScreenSizeDepthStencil) );\n    V_RETURN( pd3dDevice->CreateDepthStencilView( ptex2DScreenSizeDepthStencil, NULL, &m_ptex2DScreenSizeDSV)  );\n\n    m_ptex2DCameraSpaceZRTV.Release();\n    m_ptex2DCameraSpaceZSRV.Release();\n    D3D11_TEXTURE2D_DESC CamSpaceZTexDesc = ScreenSizeDepthStencilTexDesc;\n    CamSpaceZTexDesc.Format = DXGI_FORMAT_R32_FLOAT;\n    CamSpaceZTexDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;\n    CComPtr<ID3D11Texture2D> ptex2DCamSpaceZ;\n    V_RETURN( pd3dDevice->CreateTexture2D( &CamSpaceZTexDesc, NULL, &ptex2DCamSpaceZ) );\n    V_RETURN( pd3dDevice->CreateShaderResourceView( ptex2DCamSpaceZ, NULL, &m_ptex2DCameraSpaceZSRV)  );\n    V_RETURN( pd3dDevice->CreateRenderTargetView( ptex2DCamSpaceZ, NULL, &m_ptex2DCameraSpaceZRTV)  );\n\n    m_RendedSliceEndpointsTech.Release();\n    m_RendedCoordTexTech.Release();\n    m_RenderSliceUVDirInSMTech.Release();\n    m_RenderSampleLocationsTech.Release();\n    m_UnwarpEpipolarSctrImgTech.Release();\n    m_UnwarpAndRenderLuminanceTech.Release();\n    return S_OK;\n}\n\nstatic void UnbindResources(ID3D11DeviceContext *pDeviceCtx)\n{\n    ID3D11ShaderResourceView *pDummySRVs[12]={NULL};\n    ID3D11UnorderedAccessView *pDummyUAVs[8]={NULL};\n    pDeviceCtx->PSSetShaderResources(0, _countof(pDummySRVs), pDummySRVs);\n    pDeviceCtx->VSSetShaderResources(0, _countof(pDummySRVs), pDummySRVs);\n    pDeviceCtx->GSSetShaderResources(0, _countof(pDummySRVs), pDummySRVs);\n    pDeviceCtx->CSSetShaderResources(0, _countof(pDummySRVs), pDummySRVs);\n    pDeviceCtx->CSSetUnorderedAccessViews(0, _countof(pDummyUAVs), pDummyUAVs, NULL);\n}\n\nstatic void RenderQuad(ID3D11DeviceContext *pd3dDeviceCtx, \n                       CRenderTechnique &State, \n                       int iWidth = 0, int iHeight = 0,\n                       int iTopLeftX = 0, int iTopLeftY = 0,\n                       int iNumInstances = 1)\n{\n    // Initialize the viewport\n    if( !iWidth && !iHeight )\n    {\n        assert( iTopLeftX == 0 && iTopLeftY == 0 );\n        CComPtr<ID3D11RenderTargetView> pRTV;\n        pd3dDeviceCtx->OMGetRenderTargets(1, &pRTV, NULL);\n        CComPtr<ID3D11Resource> pDstTex;\n        pRTV->GetResource( &pDstTex );\n        D3D11_TEXTURE2D_DESC DstTexDesc;\n        CComQIPtr<ID3D11Texture2D>(pDstTex)->GetDesc( &DstTexDesc );\n        iWidth = DstTexDesc.Width;\n        iHeight = DstTexDesc.Height;\n    }\n    \n    D3D11_VIEWPORT NewViewPort;\n    NewViewPort.TopLeftX = static_cast<float>( iTopLeftX );\n    NewViewPort.TopLeftY = static_cast<float>( iTopLeftY );\n    NewViewPort.Width  = static_cast<float>( iWidth );\n    NewViewPort.Height = static_cast<float>( iHeight );\n    NewViewPort.MinDepth = 0;\n    NewViewPort.MaxDepth = 1;\n    // Set the viewport\n    pd3dDeviceCtx->RSSetViewports(1, &NewViewPort);  \n\n    UINT offset[1] = {0};\n    UINT stride[1] = {0};\n    ID3D11Buffer *ppBuffers[1] = {0};\n    pd3dDeviceCtx->IASetVertexBuffers(0, 1, ppBuffers, stride, offset);\n    // There is no input-layout object and the primitive topology is triangle strip\n    pd3dDeviceCtx->IASetInputLayout(NULL);\n    pd3dDeviceCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);\n    State.Apply();\n    if( iNumInstances == 1 )\n    {\n        // Draw 4 vertices (two triangles )\n        pd3dDeviceCtx->Draw(4, 0);\n    }\n    else\n    {\n        // Draw 4 vertices (two triangles ) x number of instances\n        pd3dDeviceCtx->DrawInstanced(4, iNumInstances, 0, 0);\n    }\n    \n    // Unbind resources\n    UnbindResources( pd3dDeviceCtx );\n}\n\nvoid CLightSctrPostProcess :: DefineMacros(class CD3DShaderMacroHelper &Macros)\n{\n    Macros.AddShaderMacro(\"NUM_EPIPOLAR_SLICES\", m_PostProcessingAttribs.m_uiNumEpipolarSlices);\n    Macros.AddShaderMacro(\"MAX_SAMPLES_IN_SLICE\", m_PostProcessingAttribs.m_uiMaxSamplesInSlice);\n    Macros.AddShaderMacro(\"OPTIMIZE_SAMPLE_LOCATIONS\", m_PostProcessingAttribs.m_bOptimizeSampleLocations);\n    Macros.AddShaderMacro(\"USE_COMBINED_MIN_MAX_TEXTURE\", m_bUseCombinedMinMaxTexture );\n    Macros.AddShaderMacro(\"EXTINCTION_EVAL_MODE\", m_PostProcessingAttribs.m_uiExtinctionEvalMode );\n    Macros.AddShaderMacro(\"ENABLE_LIGHT_SHAFTS\", m_PostProcessingAttribs.m_bEnableLightShafts);\n    Macros.AddShaderMacro(\"MULTIPLE_SCATTERING_MODE\", m_PostProcessingAttribs.m_uiMultipleScatteringMode);\n    Macros.AddShaderMacro(\"SINGLE_SCATTERING_MODE\", m_PostProcessingAttribs.m_uiSingleScatteringMode);\n    \n    {\n        std::stringstream ss;\n        ss<<\"float2(\"<<m_uiBackBufferWidth<<\",\"<<m_uiBackBufferHeight<<\")\";\n        Macros.AddShaderMacro(\"SCREEN_RESLOUTION\", ss.str());\n    }\n\n    {\n        std::stringstream ss;\n        ss<<\"float4(\"<<sm_iPrecomputedSctrUDim<<\",\"\n                     <<sm_iPrecomputedSctrVDim<<\",\"\n                     <<sm_iPrecomputedSctrWDim<<\",\"\n                     <<sm_iPrecomputedSctrQDim<<\")\";\n        Macros.AddShaderMacro(\"PRECOMPUTED_SCTR_LUT_DIM\", ss.str());\n    }\n\n    Macros.AddShaderMacro(\"EARTH_RADIUS\",   m_MediaParams.fEarthRadius);\n    Macros.AddShaderMacro(\"ATM_TOP_HEIGHT\", m_MediaParams.fAtmTopHeight);\n    Macros.AddShaderMacro(\"ATM_TOP_RADIUS\", m_MediaParams.fAtmTopRadius);\n    \n    {\n        std::stringstream ss;\n        ss<<\"float2(\"<<m_MediaParams.f2ParticleScaleHeight.x<<\",\"<<m_MediaParams.f2ParticleScaleHeight.y<<\")\";\n        Macros.AddShaderMacro(\"PARTICLE_SCALE_HEIGHT\", ss.str());\n    }\n}\n\nHRESULT CLightSctrPostProcess::CreatePrecomputedOpticalDepthTexture(ID3D11Device* in_pd3dDevice, \n                                                                    ID3D11DeviceContext *in_pd3dDeviceContext)\n{\n    HRESULT hr;\n\n    CRenderTechnique PrecomputeNetDensityToAtmTopTech;\n    PrecomputeNetDensityToAtmTopTech.SetDeviceAndContext(in_pd3dDevice, in_pd3dDeviceContext);\n    CD3DShaderMacroHelper Macros;\n    Macros.Finalize();\n    PrecomputeNetDensityToAtmTopTech.CreatePixelShaderFromFile( m_strEffectPath, \"PrecomputeNetDensityToAtmTopPS\", Macros );\n    PrecomputeNetDensityToAtmTopTech.SetVS( m_pGenerateScreenSizeQuadVS );\n    PrecomputeNetDensityToAtmTopTech.SetDS( m_pDisableDepthTestDS, 0 );\n    PrecomputeNetDensityToAtmTopTech.SetRS( m_pSolidFillNoCullRS );\n    PrecomputeNetDensityToAtmTopTech.SetBS( m_pDefaultBS );\n\n    D3D11_TEXTURE2D_DESC NetDensityToAtmTopTexDesc = \n    {\n        sm_iNumPrecomputedHeights,                              //UINT Width;\n        sm_iNumPrecomputedAngles,                               //UINT Height;\n        1,                                                      //UINT MipLevels;\n        1,                                                      //UINT ArraySize;\n        DXGI_FORMAT_R32G32_FLOAT,                               //DXGI_FORMAT Format;\n        {1,0},                                                  //DXGI_SAMPLE_DESC SampleDesc;\n        D3D11_USAGE_DEFAULT,                                    //D3D11_USAGE Usage;\n        D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,  //UINT BindFlags;\n        0,                                                      //UINT CPUAccessFlags;\n        0,                                                      //UINT MiscFlags;\n    };\n\n    m_ptex2DOccludedNetDensityToAtmTopSRV.Release();\n    m_ptex2DOccludedNetDensityToAtmTopRTV.Release();\n\n    CComPtr<ID3D11Texture2D> ptex2DOccludedNetDensityToAtmTop;\n    V_RETURN( in_pd3dDevice->CreateTexture2D( &NetDensityToAtmTopTexDesc, NULL, &ptex2DOccludedNetDensityToAtmTop) );\n    V_RETURN( in_pd3dDevice->CreateShaderResourceView( ptex2DOccludedNetDensityToAtmTop, NULL, &m_ptex2DOccludedNetDensityToAtmTopSRV)  );\n    V_RETURN( in_pd3dDevice->CreateRenderTargetView( ptex2DOccludedNetDensityToAtmTop, NULL, &m_ptex2DOccludedNetDensityToAtmTopRTV)  );\n\n    ID3D11RenderTargetView *pRTVs[] = { m_ptex2DOccludedNetDensityToAtmTopRTV };\n    in_pd3dDeviceContext->OMSetRenderTargets(_countof(pRTVs), pRTVs, NULL);\n\n    ID3D11Buffer *pCBs[] = {m_pcbMediaAttribs};\n    in_pd3dDeviceContext->PSSetConstantBuffers(1, _countof(pCBs), pCBs);\n\n    RenderQuad(in_pd3dDeviceContext, PrecomputeNetDensityToAtmTopTech);\n    \n    in_pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n\n    return S_OK;\n}\n\nvoid CLightSctrPostProcess :: CreateRandomSphereSamplingTexture(ID3D11Device *pDevice)\n{\n    D3D11_TEXTURE2D_DESC RandomSphereSamplingTexDesc = \n    {\n        sm_iNumRandomSamplesOnSphere,   //UINT Width;\n        1,                              //UINT Height;\n        1,                              //UINT MipLevels;\n        1,                              //UINT ArraySize;\n        DXGI_FORMAT_R32G32B32A32_FLOAT, //DXGI_FORMAT Format;\n        {1,0},                          //DXGI_SAMPLE_DESC SampleDesc;\n        D3D11_USAGE_IMMUTABLE,          //D3D11_USAGE Usage;\n        D3D11_BIND_SHADER_RESOURCE,     //UINT BindFlags;\n        0,                              //UINT CPUAccessFlags;\n        0,                              //UINT MiscFlags;\n    };\n    std::vector<D3DXVECTOR4> SphereSampling(sm_iNumRandomSamplesOnSphere);\n    for(int iSample = 0; iSample < sm_iNumRandomSamplesOnSphere; ++iSample)\n    {\n        D3DXVECTOR4 &f4Sample = SphereSampling[iSample];\n        f4Sample.z = ((float)rand()/(float)RAND_MAX) * 2.f - 1.f;\n        float t = ((float)rand()/(float)RAND_MAX) * 2.f * PI;\n        float r = sqrt( max(1 - f4Sample.z*f4Sample.z, 0.f) );\n        f4Sample.x = r * cos(t);\n        f4Sample.y = r * sin(t);\n        f4Sample.w = 0;\n    }\n    D3D11_SUBRESOURCE_DATA InitData = \n    {\n        &SphereSampling[0],\n        sm_iNumRandomSamplesOnSphere*sizeof(D3DXVECTOR4), // UINT SysMemPitch\n        0  // UINT SysMemSlicePitch\n    };\n    HRESULT hr;\n    CComPtr<ID3D11Texture2D> ptex2DSphereRandomSampling;\n    V( pDevice->CreateTexture2D( &RandomSphereSamplingTexDesc, &InitData, &ptex2DSphereRandomSampling) );\n    V( pDevice->CreateShaderResourceView( ptex2DSphereRandomSampling, NULL, &m_ptex2DSphereRandomSamplingSRV) );\n}\n\nHRESULT CLightSctrPostProcess :: CreatePrecomputedScatteringLUT(ID3D11Device *pDevice, ID3D11DeviceContext *pContext)\n{\n    HRESULT hr;\n\n    if( !m_PrecomputeSingleSctrTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n        m_PrecomputeSingleSctrTech.SetDeviceAndContext(pDevice, pContext);\n        m_PrecomputeSingleSctrTech.CreatePixelShaderFromFile( m_strEffectPath, \"PrecomputeSingleScatteringPS\", Macros );\n        m_PrecomputeSingleSctrTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_PrecomputeSingleSctrTech.SetDS( m_pDisableDepthTestDS );\n        m_PrecomputeSingleSctrTech.SetRS( m_pSolidFillNoCullRS );\n        m_PrecomputeSingleSctrTech.SetBS( m_pDefaultBS );\n    }\n    \n    if( !m_ComputeSctrRadianceTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.AddShaderMacro( \"NUM_RANDOM_SPHERE_SAMPLES\", sm_iNumRandomSamplesOnSphere );\n        Macros.Finalize();\n        m_ComputeSctrRadianceTech.SetDeviceAndContext(pDevice, pContext);\n        m_ComputeSctrRadianceTech.CreatePixelShaderFromFile( m_strEffectPath, \"ComputeSctrRadiancePS\", Macros );\n        m_ComputeSctrRadianceTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_ComputeSctrRadianceTech.SetDS( m_pDisableDepthTestDS );\n        m_ComputeSctrRadianceTech.SetRS( m_pSolidFillNoCullRS );\n        m_ComputeSctrRadianceTech.SetBS( m_pDefaultBS );\n    }\n    \n    if( !m_ComputeScatteringOrderTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n        m_ComputeScatteringOrderTech.SetDeviceAndContext(pDevice, pContext);\n        m_ComputeScatteringOrderTech.CreatePixelShaderFromFile( m_strEffectPath, \"ComputeScatteringOrderPS\", Macros );\n        m_ComputeScatteringOrderTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_ComputeScatteringOrderTech.SetDS( m_pDisableDepthTestDS );\n        m_ComputeScatteringOrderTech.SetRS( m_pSolidFillNoCullRS );\n        m_ComputeScatteringOrderTech.SetBS( m_pDefaultBS );\n    }\n\n    if( !m_AddScatteringOrderTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n        m_AddScatteringOrderTech.SetDeviceAndContext(pDevice, pContext);\n        m_AddScatteringOrderTech.CreatePixelShaderFromFile( m_strEffectPath, \"AddScatteringOrderPS\", Macros );\n        m_AddScatteringOrderTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_AddScatteringOrderTech.SetDS( m_pDisableDepthTestDS );\n        m_AddScatteringOrderTech.SetRS( m_pSolidFillNoCullRS );\n        m_AddScatteringOrderTech.SetBS( m_pAdditiveBlendBS );\n    }\n        \n\n    if( !m_ptex2DSphereRandomSamplingSRV )\n        CreateRandomSphereSamplingTexture(pDevice);\n\n    m_ptex3DSingleScatteringSRV.Release();\n    m_ptex3DHighOrderScatteringSRV.Release();\n    m_ptex3DMultipleScatteringSRV.Release();\n\n    D3D11_TEXTURE3D_DESC PrecomputedSctrTexDesc = \n    {\n        sm_iPrecomputedSctrUDim, //UINT Width;\n        sm_iPrecomputedSctrVDim, //UINT Height;\n        sm_iPrecomputedSctrWDim * sm_iPrecomputedSctrQDim, //UINT Depth;\n        1, //UINT MipLevels;\n        DXGI_FORMAT_R16G16B16A16_FLOAT,//DXGI_FORMAT Format;\n        D3D11_USAGE_DEFAULT, //D3D11_USAGE Usage;\n        D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,//UINT BindFlags;\n        0,//UINT CPUAccessFlags;\n        0//UINT MiscFlags;\n    };\n\n    CComPtr<ID3D11Texture3D> ptex3DSingleSctr, ptex3DHighOrderSctr, ptex3DMultipleSctr;\n    V_RETURN(pDevice->CreateTexture3D(&PrecomputedSctrTexDesc, NULL, &ptex3DSingleSctr));\n    V_RETURN(pDevice->CreateShaderResourceView(ptex3DSingleSctr, NULL, &m_ptex3DSingleScatteringSRV));\n    V_RETURN(pDevice->CreateTexture3D(&PrecomputedSctrTexDesc, NULL, &ptex3DHighOrderSctr));\n    V_RETURN(pDevice->CreateShaderResourceView(ptex3DHighOrderSctr, NULL, &m_ptex3DHighOrderScatteringSRV));\n    V_RETURN(pDevice->CreateTexture3D(&PrecomputedSctrTexDesc, NULL, &ptex3DMultipleSctr));\n    V_RETURN(pDevice->CreateShaderResourceView(ptex3DMultipleSctr, NULL, &m_ptex3DMultipleScatteringSRV));\n    std::vector< CComPtr<ID3D11RenderTargetView> > ptex3DHighOrderSctrRTVs(PrecomputedSctrTexDesc.Depth);\n    std::vector< CComPtr<ID3D11RenderTargetView> > ptex3DMultipleSctrRTVs(PrecomputedSctrTexDesc.Depth);\n\n    // Precompute single scattering\n    for(UINT uiDepthSlice = 0; uiDepthSlice < PrecomputedSctrTexDesc.Depth; ++uiDepthSlice)\n    {\n        D3D11_RENDER_TARGET_VIEW_DESC CurrSliceRTVDesc;\n        CurrSliceRTVDesc.Format = PrecomputedSctrTexDesc.Format;\n        CurrSliceRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;\n        CurrSliceRTVDesc.Texture3D.MipSlice = 0;\n        CurrSliceRTVDesc.Texture3D.FirstWSlice = uiDepthSlice;\n        CurrSliceRTVDesc.Texture3D.WSize = 1;\n\n        CComPtr<ID3D11RenderTargetView> ptex3DCurrDepthSliceRTV;\n        V_RETURN(pDevice->CreateRenderTargetView(ptex3DSingleSctr, &CurrSliceRTVDesc, &ptex3DCurrDepthSliceRTV));\n        \n        V_RETURN(pDevice->CreateRenderTargetView(ptex3DHighOrderSctr, &CurrSliceRTVDesc, &ptex3DHighOrderSctrRTVs[uiDepthSlice]));\n        float Zero[] = {0.f, 0.f, 0.f, 0.f};\n        pContext->ClearRenderTargetView(ptex3DHighOrderSctrRTVs[uiDepthSlice].p, Zero);\n\n        V_RETURN(pDevice->CreateRenderTargetView(ptex3DMultipleSctr, &CurrSliceRTVDesc, &ptex3DMultipleSctrRTVs[uiDepthSlice]));\n\n        pContext->OMSetRenderTargets(1, &ptex3DCurrDepthSliceRTV.p, NULL);\n\n        ID3D11ShaderResourceView *pSRVs[] = \n        {\n            m_ptex2DOccludedNetDensityToAtmTopSRV  // Texture2D<float2> g_tex2DOccludedNetDensityToAtmTop : register( t5 );\n        };\n        pContext->PSSetShaderResources(5, _countof(pSRVs), pSRVs);\n\n        // Set sun zenith and sun view angles\n        SMiscDynamicParams MiscDynamicParams = {NULL};\n        UINT uiW = uiDepthSlice % sm_iPrecomputedSctrWDim;\n        UINT uiQ = uiDepthSlice / sm_iPrecomputedSctrWDim;\n        MiscDynamicParams.f2WQ.x = ((float)uiW + 0.5f) / (float)sm_iPrecomputedSctrWDim;\n        assert(0 < MiscDynamicParams.f2WQ.x && MiscDynamicParams.f2WQ.x < 1);\n        MiscDynamicParams.f2WQ.y = ((float)uiQ + 0.5f) / (float)sm_iPrecomputedSctrQDim;\n        assert(0 < MiscDynamicParams.f2WQ.y && MiscDynamicParams.f2WQ.y < 1);\n        UpdateConstantBuffer(pContext, m_pcbMiscParams, &MiscDynamicParams, sizeof(MiscDynamicParams));\n        //cbuffer cbMiscDynamicParams : register( b4 )\n        pContext->PSSetConstantBuffers(4, 1, &m_pcbMiscParams.p);\n\n        RenderQuad( pContext, \n                    m_PrecomputeSingleSctrTech,\n                    PrecomputedSctrTexDesc.Width, PrecomputedSctrTexDesc.Height );\n    }\n\n    // Precompute multiple scattering\n    // We need higher precision to store intermediate data\n    PrecomputedSctrTexDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;\n    CComPtr<ID3D11Texture3D> ptex3DSctrRadiance, ptex3DInsctrOrder;\n    CComPtr<ID3D11ShaderResourceView> ptex3DSctrRadianceSRV, ptex3DInsctrOrderSRV;\n    V_RETURN(pDevice->CreateTexture3D(&PrecomputedSctrTexDesc, NULL, &ptex3DSctrRadiance));\n    V_RETURN(pDevice->CreateTexture3D(&PrecomputedSctrTexDesc, NULL, &ptex3DInsctrOrder));\n    V_RETURN(pDevice->CreateShaderResourceView(ptex3DSctrRadiance, NULL, &ptex3DSctrRadianceSRV));\n    V_RETURN(pDevice->CreateShaderResourceView(ptex3DInsctrOrder, NULL, &ptex3DInsctrOrderSRV));\n\n    std::vector< CComPtr<ID3D11RenderTargetView> > ptex3DSctrRadianceRTVs(PrecomputedSctrTexDesc.Depth), ptex3DInsctrOrderRTVs(PrecomputedSctrTexDesc.Depth);\n    for(UINT uiDepthSlice = 0; uiDepthSlice < PrecomputedSctrTexDesc.Depth; ++uiDepthSlice)\n    {\n        D3D11_RENDER_TARGET_VIEW_DESC CurrSliceRTVDesc;\n        CurrSliceRTVDesc.Format = PrecomputedSctrTexDesc.Format;\n        CurrSliceRTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;\n        CurrSliceRTVDesc.Texture3D.MipSlice = 0;\n        CurrSliceRTVDesc.Texture3D.FirstWSlice = uiDepthSlice;\n        CurrSliceRTVDesc.Texture3D.WSize = 1;\n\n        V_RETURN(pDevice->CreateRenderTargetView(ptex3DSctrRadiance, &CurrSliceRTVDesc, &ptex3DSctrRadianceRTVs[uiDepthSlice]));\n        V_RETURN(pDevice->CreateRenderTargetView(ptex3DInsctrOrder, &CurrSliceRTVDesc, &ptex3DInsctrOrderRTVs[uiDepthSlice]));\n    }\n\n    const int iNumScatteringOrders = 4;\n    for(int iSctrOrder = 1; iSctrOrder < iNumScatteringOrders; ++iSctrOrder)\n    {\n        for(int iPass = 0; iPass < 3; ++iPass)\n        {\n            pContext->OMSetRenderTargets(0, NULL, NULL);\n            // Pass 0: compute differential in-scattering\n            // Pass 1: integrate differential in-scattering\n            // Pass 2: accumulate total multiple scattering\n\n            ID3D11ShaderResourceView *pSRVs[2] = {nullptr};\n            \n            CRenderTechnique *pRenderTech = nullptr;\n            std::vector< CComPtr<ID3D11RenderTargetView> > *pRTVs;\n            switch(iPass)\n            {\n                case 0:\n                    // Pre-compute the radiance of light scattered at a given point in given direction.\n                    pRenderTech = &m_ComputeSctrRadianceTech; \n                    pRTVs = &ptex3DSctrRadianceRTVs;\n                    pSRVs[0] = (iSctrOrder == 1) ? m_ptex3DSingleScatteringSRV : ptex3DInsctrOrderSRV;\n                    pSRVs[1] = m_ptex2DSphereRandomSamplingSRV;\n                    break;\n\n                case 1:\n                    // Compute in-scattering order for a given point and direction\n                    pRenderTech = &m_ComputeScatteringOrderTech; \n                    pRTVs = &ptex3DInsctrOrderRTVs;\n                    pSRVs[0] = ptex3DSctrRadianceSRV;\n                    break;\n\n                case 2:\n                    // Accumulate in-scattering\n                    pRenderTech = &m_AddScatteringOrderTech; \n                    pRTVs = &ptex3DHighOrderSctrRTVs;\n                    pSRVs[0] = ptex3DInsctrOrderSRV;\n                    break;\n            }\n            \n            for(UINT uiDepthSlice = 0; uiDepthSlice < PrecomputedSctrTexDesc.Depth; ++uiDepthSlice)\n            {\n                pContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n\n                // Set sun zenith and sun view angles\n                SMiscDynamicParams MiscDynamicParams = {NULL};\n                MiscDynamicParams.uiDepthSlice = uiDepthSlice;\n                UINT uiW = uiDepthSlice % sm_iPrecomputedSctrWDim;\n                UINT uiQ = uiDepthSlice / sm_iPrecomputedSctrWDim;\n                MiscDynamicParams.f2WQ.x = ((float)uiW + 0.5f) / (float)sm_iPrecomputedSctrWDim;\n                assert(0 < MiscDynamicParams.f2WQ.x && MiscDynamicParams.f2WQ.x < 1);\n                MiscDynamicParams.f2WQ.y = ((float)uiQ + 0.5f) / (float)sm_iPrecomputedSctrQDim;\n                assert(0 < MiscDynamicParams.f2WQ.y && MiscDynamicParams.f2WQ.y < 1);\n                UpdateConstantBuffer(pContext, m_pcbMiscParams, &MiscDynamicParams, sizeof(MiscDynamicParams));\n                //cbuffer cbMiscDynamicParams : register( b4 )\n                pContext->PSSetConstantBuffers(4, 1, &m_pcbMiscParams.p);\n\n                auto *pRTV = (ID3D11RenderTargetView*)(*pRTVs)[uiDepthSlice];\n                pContext->OMSetRenderTargets(1, &pRTV, NULL);\n                \n                RenderQuad( pContext, \n                            *pRenderTech,\n                            PrecomputedSctrTexDesc.Width, PrecomputedSctrTexDesc.Height );\n            }\n        }\n    }\n    pContext->OMSetRenderTargets(0, NULL, NULL);\n\n    // Combine single scattering and higher order scattering into single texture\n    pContext->CopyResource(ptex3DMultipleSctr, ptex3DSingleSctr);\n    for(UINT uiDepthSlice = 0; uiDepthSlice < PrecomputedSctrTexDesc.Depth; ++uiDepthSlice)\n    {\n        ID3D11ShaderResourceView *pSRVs[1] = {m_ptex3DHighOrderScatteringSRV};\n        pContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n\n        SMiscDynamicParams MiscDynamicParams = {NULL};\n        MiscDynamicParams.uiDepthSlice = uiDepthSlice;\n        UpdateConstantBuffer(pContext, m_pcbMiscParams, &MiscDynamicParams, sizeof(MiscDynamicParams));\n        //cbuffer cbMiscDynamicParams : register( b4 )\n        pContext->PSSetConstantBuffers(4, 1, &m_pcbMiscParams.p);\n\n        auto *pRTV = (ID3D11RenderTargetView*)ptex3DMultipleSctrRTVs[uiDepthSlice];\n        pContext->OMSetRenderTargets(1, &pRTV, NULL);\n                \n        RenderQuad( pContext, \n                    m_AddScatteringOrderTech,\n                    PrecomputedSctrTexDesc.Width, PrecomputedSctrTexDesc.Height );\n    }\n\n    pContext->OMSetRenderTargets(0, NULL, NULL);\n\n    return S_OK;\n}\n\nvoid CLightSctrPostProcess :: ReconstructCameraSpaceZ(SFrameAttribs &FrameAttribs)\n{\n    if( !m_ReconstrCamSpaceZTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n        m_ReconstrCamSpaceZTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_ReconstrCamSpaceZTech.CreatePixelShaderFromFile( m_strEffectPath, \"ReconstructCameraSpaceZPS\", Macros );\n        m_ReconstrCamSpaceZTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_ReconstrCamSpaceZTech.SetDS( m_pDisableDepthTestDS );\n        m_ReconstrCamSpaceZTech.SetRS( m_pSolidFillNoCullRS );\n        m_ReconstrCamSpaceZTech.SetBS( m_pDefaultBS );\n    }\n\n    // Depth buffer is non-linear and cannot be interpolated directly\n    // We have to reconstruct camera space z to be able to use bilinear filtering\n    \n    // Set render target first, because depth buffer is still bound on output and it must be unbound \n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(1, &m_ptex2DCameraSpaceZRTV.p, NULL);\n    // Texture2D<float> g_tex2DCamSpaceZ : register( t0 );\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(0, 1, &FrameAttribs.ptex2DSrcDepthBufferSRV);\n    RenderQuad( FrameAttribs.pd3dDeviceContext, \n                m_ReconstrCamSpaceZTech,\n                m_uiBackBufferWidth, m_uiBackBufferHeight );\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: RenderSliceEndpoints(SFrameAttribs &FrameAttribs)\n{\n    if( !m_RendedSliceEndpointsTech.IsValid() )\n    {\n        m_RendedSliceEndpointsTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n        m_RendedSliceEndpointsTech.CreatePixelShaderFromFile( m_strEffectPath, \"GenerateSliceEndpointsPS\", Macros );\n        m_RendedSliceEndpointsTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_RendedSliceEndpointsTech.SetDS( m_pDisableDepthTestDS );\n        m_RendedSliceEndpointsTech.SetRS( m_pSolidFillNoCullRS );\n        m_RendedSliceEndpointsTech.SetBS( m_pDefaultBS );\n    }\n    ID3D11RenderTargetView *ppRTVs[] = {m_ptex2DSliceEndpointsRTV};\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(_countof(ppRTVs), ppRTVs, NULL);\n\n    RenderQuad( FrameAttribs.pd3dDeviceContext, m_RendedSliceEndpointsTech,\n                m_PostProcessingAttribs.m_uiNumEpipolarSlices, 1 );\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: RenderCoordinateTexture(SFrameAttribs &FrameAttribs)\n{\n    if( !m_RendedCoordTexTech.IsValid() )\n    {\n        m_RendedCoordTexTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n        m_RendedCoordTexTech.CreatePixelShaderFromFile( m_strEffectPath, \"GenerateCoordinateTexturePS\", Macros );\n        m_RendedCoordTexTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_RendedCoordTexTech.SetDS( m_pDisableDepthTestIncrStencilDS );\n        m_RendedCoordTexTech.SetRS( m_pSolidFillNoCullRS );\n        m_RendedCoordTexTech.SetBS( m_pDefaultBS );\n    }\n    // Coordinate texture is a texture with dimensions [Total Samples X Num Slices]\n    // Texel t[i,j] contains projection-space screen cooridantes of the i-th sample in j-th epipolar slice\n    ID3D11RenderTargetView *ppRTVs[] = {m_ptex2DCoordinateTextureRTV, m_ptex2DEpipolarCamSpaceZRTV};\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(_countof(ppRTVs), ppRTVs, m_ptex2DEpipolarImageDSV);\n\n    static const float fInvalidCoordinate = -1e+30f; // Both coord texture and epipolar CamSpaceZ are 32-bit float\n    float InvalidCoords[] = {fInvalidCoordinate, fInvalidCoordinate, fInvalidCoordinate, fInvalidCoordinate};\n    // Clear both render targets with values that can't be correct projection space coordinates and camera space Z:\n    FrameAttribs.pd3dDeviceContext->ClearRenderTargetView(m_ptex2DCoordinateTextureRTV, InvalidCoords);\n    FrameAttribs.pd3dDeviceContext->ClearRenderTargetView(m_ptex2DEpipolarCamSpaceZRTV, InvalidCoords);\n    // Clear depth stencil view. Since we use stencil part only, there is no need to clear depth\n    // Set stencil value to 0\n    FrameAttribs.pd3dDeviceContext->ClearDepthStencilView(m_ptex2DEpipolarImageDSV, D3D11_CLEAR_STENCIL, 1.0f, 0);\n\n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        m_ptex2DCameraSpaceZSRV,           // Texture2D<float>  g_tex2DCamSpaceZ              : register( t0 );\n        NULL,                              // Unused                                          : register( t1 )\n        NULL,                              // Unused                                          : register( t2 )\n        NULL,                              // Unused                                          : register( t3 )\n        m_ptex2DSliceEndpointsSRV,         // Texture2D<float4> g_tex2DSliceEndPoints         : register( t4 );\n    };\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n\n    // Depth stencil state is configured to always increment stencil value. If coordinates are outside the screen,\n    // the pixel shader discards the pixel and stencil value is left untouched. All such pixels will be skipped from\n    // further processing\n    RenderQuad( FrameAttribs.pd3dDeviceContext, m_RendedCoordTexTech,\n                m_PostProcessingAttribs.m_uiMaxSamplesInSlice, m_PostProcessingAttribs.m_uiNumEpipolarSlices );\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: RenderCoarseUnshadowedInctr(SFrameAttribs &FrameAttribs)\n{\n    if( !m_RenderCoarseUnshadowedInsctrTech.IsValid() )\n    {\n        m_RenderCoarseUnshadowedInsctrTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n       \n        m_RenderCoarseUnshadowedInsctrTech.CreatePixelShaderFromFile( m_strEffectPath, \"RenderCoarseUnshadowedInsctrPS\", Macros );\n        m_RenderCoarseUnshadowedInsctrTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_RenderCoarseUnshadowedInsctrTech.SetDS( m_pNoDepth_StEqual_KeepStencilDS, 1);\n        m_RenderCoarseUnshadowedInsctrTech.SetRS( m_pSolidFillNoCullRS );\n        m_RenderCoarseUnshadowedInsctrTech.SetBS( m_pDefaultBS );\n    }\n\n    if( m_PostProcessingAttribs.m_uiExtinctionEvalMode == EXTINCTION_EVAL_MODE_EPIPOLAR && \n        !m_ptex2DEpipolarExtinctionSRV )\n    {\n        D3D11_TEXTURE2D_DESC EpipolarExtinctionTexDesc = \n        {\n            m_PostProcessingAttribs.m_uiMaxSamplesInSlice,          //UINT Width;\n            m_PostProcessingAttribs.m_uiNumEpipolarSlices,          //UINT Height;\n            1,                                                     //UINT MipLevels;\n            1,                                                     //UINT ArraySize;\n            DXGI_FORMAT_R8G8B8A8_UNORM,                              //DXGI_FORMAT Format;\n            {1,0},                                                 //DXGI_SAMPLE_DESC SampleDesc;\n            D3D11_USAGE_DEFAULT,                                   //D3D11_USAGE Usage;\n            D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, //UINT BindFlags;\n            0,                                                     //UINT CPUAccessFlags;\n            0,                                                     //UINT MiscFlags;\n        };\n\n        CComPtr<ID3D11Texture2D> ptex2DEpipolarExtinction;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        HRESULT hr;\n        V( FrameAttribs.pd3dDevice->CreateTexture2D( &EpipolarExtinctionTexDesc, NULL, &ptex2DEpipolarExtinction) );\n        V( FrameAttribs.pd3dDevice->CreateShaderResourceView( ptex2DEpipolarExtinction, NULL, &m_ptex2DEpipolarExtinctionSRV)  );\n        V( FrameAttribs.pd3dDevice->CreateRenderTargetView( ptex2DEpipolarExtinction, NULL, &m_ptex2DEpipolarExtinctionRTV)  );\n    }\n\n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        m_ptex2DCoordinateTextureSRV,  //Texture2D<float2> g_tex2DCoordinates       : register( t1 );\n        m_ptex2DEpipolarCamSpaceZSRV,  //Texture2D<float> g_tex2DEpipolarCamSpaceZ  : register( t2 );\n        nullptr,                       // t3\n        nullptr,                       // t4\n        m_ptex2DOccludedNetDensityToAtmTopSRV,  // Texture2D<float2> g_tex2DOccludedNetDensityToAtmTop : register( t5 );\n        nullptr,                             // t6 \n        m_ptex3DSingleScatteringSRV,         // Texture3D<float3> g_tex3DSingleSctrLUT      : register( t7 );\n        m_ptex3DHighOrderScatteringSRV,      // Texture3D<float3> g_tex3DHighOrderSctrLUT   : register( t8 );\n        m_ptex3DMultipleScatteringSRV        // Texture3D<float3> g_tex3DMultipleSctrLUT    : register( t9 );\n    };\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(1, _countof(pSRVs), pSRVs);\n    \n    float flt16max = 65504.f; // Epipolar Inscattering is 16-bit float\n    const float InvalidInsctr[] = {-flt16max, -flt16max, -flt16max, -flt16max};\n    if( m_ptex2DEpipolarInscatteringRTV )\n        FrameAttribs.pd3dDeviceContext->ClearRenderTargetView(m_ptex2DEpipolarInscatteringRTV, InvalidInsctr);\n    const float One[] = {1, 1, 1, 1};\n    if( m_ptex2DEpipolarExtinctionRTV )\n        FrameAttribs.pd3dDeviceContext->ClearRenderTargetView(m_ptex2DEpipolarExtinctionRTV, One);\n    ID3D11RenderTargetView *pRTVs[] = {m_ptex2DEpipolarInscatteringRTV, m_ptex2DEpipolarExtinctionRTV};\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(_countof(pRTVs),pRTVs, m_ptex2DEpipolarImageDSV);\n\n    RenderQuad( FrameAttribs.pd3dDeviceContext, \n                m_RenderCoarseUnshadowedInsctrTech,\n                m_PostProcessingAttribs.m_uiMaxSamplesInSlice, m_PostProcessingAttribs.m_uiNumEpipolarSlices );\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: RefineSampleLocations(SFrameAttribs &FrameAttribs)\n{\n    if( !m_RefineSampleLocationsTech.IsValid() )\n    {\n        m_RefineSampleLocationsTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        \n        // Thread group size must be at least as large as initial sample step\n        m_uiSampleRefinementCSThreadGroupSize = max( m_uiSampleRefinementCSMinimumThreadGroupSize, m_PostProcessingAttribs.m_uiInitialSampleStepInSlice );\n        // Thread group size cannot be larger than the total number of samples in slice\n        m_uiSampleRefinementCSThreadGroupSize = min( m_uiSampleRefinementCSThreadGroupSize, m_PostProcessingAttribs.m_uiMaxSamplesInSlice );\n\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.AddShaderMacro(\"INITIAL_SAMPLE_STEP\", m_PostProcessingAttribs.m_uiInitialSampleStepInSlice);\n        Macros.AddShaderMacro(\"THREAD_GROUP_SIZE\"  , m_uiSampleRefinementCSThreadGroupSize );\n        Macros.AddShaderMacro(\"REFINEMENT_CRITERION\", m_PostProcessingAttribs.m_uiRefinementCriterion );\n        Macros.AddShaderMacro(\"AUTO_EXPOSURE\",        m_PostProcessingAttribs.m_bAutoExposure);\n        Macros.Finalize();\n\n        m_RefineSampleLocationsTech.CreateComputeShaderFromFile( L\"fx\\\\RefineSampleLocations.fx\", \"RefineSampleLocationsCS\", Macros );\n    }\n\n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        m_ptex2DCoordinateTextureSRV,  //Texture2D<float2> g_tex2DCoordinates       : register( t1 );\n        m_ptex2DEpipolarCamSpaceZSRV,  //Texture2D<float> g_tex2DEpipolarCamSpaceZ  : register( t2 );\n        m_ptex2DEpipolarInscatteringSRV,        // Texture2D<float3> g_tex2DScatteredColor   : register( t3 );\n        nullptr,                                // t4\n        nullptr,                                // t5\n        nullptr,                                // t6\n        nullptr,                                // t7\n        nullptr,                                // t8\n        nullptr,                                // t9\n        m_ptex2DAverageLuminanceSRV             // Texture2D<float>  g_tex2DAverageLuminance  : register( t10 );\n    };\n    FrameAttribs.pd3dDeviceContext->CSSetShaderResources(1, _countof(pSRVs), pSRVs);\n    FrameAttribs.pd3dDeviceContext->CSSetUnorderedAccessViews(0, 1, &m_ptex2DInterpolationSourcesUAV.p, NULL);\n    // Using small group size is inefficient since a lot of SIMD lanes become idle\n    m_RefineSampleLocationsTech.Apply();\n    FrameAttribs.pd3dDeviceContext->Dispatch( m_PostProcessingAttribs.m_uiMaxSamplesInSlice/m_uiSampleRefinementCSThreadGroupSize,\n                                              m_PostProcessingAttribs.m_uiNumEpipolarSlices,\n                                              1);\n    UnbindResources( FrameAttribs.pd3dDeviceContext );\n}\n\nvoid CLightSctrPostProcess :: MarkRayMarchingSamples(SFrameAttribs &FrameAttribs)\n{\n    if( !m_MarkRayMarchingSamplesInStencilTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n\n        m_MarkRayMarchingSamplesInStencilTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_MarkRayMarchingSamplesInStencilTech.CreatePixelShaderFromFile( m_strEffectPath, \"MarkRayMarchingSamplesInStencilPS\", Macros );\n        m_MarkRayMarchingSamplesInStencilTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_MarkRayMarchingSamplesInStencilTech.SetDS( m_pNoDepth_StEqual_IncrStencilDS, 1 );\n        m_MarkRayMarchingSamplesInStencilTech.SetRS( m_pSolidFillNoCullRS );\n        m_MarkRayMarchingSamplesInStencilTech.SetBS( m_pDefaultBS );\n    }\n\n    // Mark ray marching samples in the stencil\n    // The depth stencil state is configured to pass only pixels, whose stencil value equals 1. Thus all epipolar samples with \n    // coordinates outsied the screen (generated on the previous pass) are automatically discarded. The pixel shader only\n    // passes samples which are interpolated from themselves, the rest are discarded. Thus after this pass all ray\n    // marching samples will be marked with 2 in stencil\n    ID3D11RenderTargetView *pDummyRTV = NULL;\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(1, &pDummyRTV, m_ptex2DEpipolarImageDSV);\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(6, 1, &m_ptex2DInterpolationSourcesSRV.p); // Texture2D<uint2> g_tex2DInterpolationSource : register( t6 );\n    RenderQuad( FrameAttribs.pd3dDeviceContext, \n                m_MarkRayMarchingSamplesInStencilTech,\n                m_PostProcessingAttribs.m_uiMaxSamplesInSlice, m_PostProcessingAttribs.m_uiNumEpipolarSlices );\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: RenderSliceUVDirAndOrig(SFrameAttribs &FrameAttribs)\n{\n    if( !m_RenderSliceUVDirInSMTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n\n        m_RenderSliceUVDirInSMTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_RenderSliceUVDirInSMTech.CreatePixelShaderFromFile( m_strEffectPath, \"RenderSliceUVDirInShadowMapTexturePS\", Macros );\n        m_RenderSliceUVDirInSMTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_RenderSliceUVDirInSMTech.SetDS( m_pDisableDepthTestDS );\n        m_RenderSliceUVDirInSMTech.SetRS( m_pSolidFillNoCullRS );\n        m_RenderSliceUVDirInSMTech.SetBS( m_pDefaultBS );\n    }\n\n    if( !m_ptex2DSliceUVDirAndOriginRTV || !m_ptex2DSliceUVDirAndOriginSRV )\n    {\n        D3D11_TEXTURE2D_DESC SliceUVDirAndOriginDesc = \n        {\n            m_PostProcessingAttribs.m_uiNumEpipolarSlices,         //UINT Width;\n            m_PostProcessingAttribs.m_iNumCascades,                //UINT Height;\n            1,                                                     //UINT MipLevels;\n            1,                                                     //UINT ArraySize;\n            DXGI_FORMAT_R32G32B32A32_FLOAT,                        //DXGI_FORMAT Format;\n            {1,0},                                                 //DXGI_SAMPLE_DESC SampleDesc;\n            D3D11_USAGE_DEFAULT,                                   //D3D11_USAGE Usage;\n            D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, //UINT BindFlags;\n            0,                                                     //UINT CPUAccessFlags;\n            0,                                                     //UINT MiscFlags;\n        };\n\n        CComPtr<ID3D11Texture2D> ptex2DSliceUVDirInShadowMap;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        HRESULT hr;\n        V( FrameAttribs.pd3dDevice->CreateTexture2D( &SliceUVDirAndOriginDesc, NULL, &ptex2DSliceUVDirInShadowMap) );\n        V( FrameAttribs.pd3dDevice->CreateShaderResourceView( ptex2DSliceUVDirInShadowMap, NULL, &m_ptex2DSliceUVDirAndOriginSRV)  );\n        V( FrameAttribs.pd3dDevice->CreateRenderTargetView( ptex2DSliceUVDirInShadowMap, NULL, &m_ptex2DSliceUVDirAndOriginRTV)  );\n    }\n    // Render [Num Slices x 1] texture containing slice direction in shadow map UV space\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets( 1, &m_ptex2DSliceUVDirAndOriginRTV.p, NULL);\n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        m_ptex2DCameraSpaceZSRV,            // Texture2D<float>  g_tex2DCamSpaceZ              : register( t0 );\n        NULL,                               // Unused                                          : register( t1 )\n        NULL,                               // Unused                                          : register( t2 )\n        NULL,                               // Unused                                          : register( t3 )\n        m_ptex2DSliceEndpointsSRV,          // Texture2D<float4> g_tex2DSliceEndPoints         : register( t4 );\n    };\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n\n    RenderQuad( FrameAttribs.pd3dDeviceContext, \n                m_RenderSliceUVDirInSMTech,\n                m_PostProcessingAttribs.m_uiNumEpipolarSlices, m_PostProcessingAttribs.m_iNumCascades - m_PostProcessingAttribs.m_iFirstCascade,\n                0, m_PostProcessingAttribs.m_iFirstCascade);\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: Build1DMinMaxMipMap(SFrameAttribs &FrameAttribs, \n                                                  int iCascadeIndex)\n{\n    if( !m_InitializeMinMaxShadowMapTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.AddShaderMacro(\"IS_32BIT_MIN_MAX_MAP\", m_PostProcessingAttribs.m_bIs32BitMinMaxMipMap);\n        Macros.Finalize();\n\n        m_InitializeMinMaxShadowMapTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_InitializeMinMaxShadowMapTech.CreatePixelShaderFromFile( m_strEffectPath, \"InitializeMinMaxShadowMapPS\", Macros );\n        m_InitializeMinMaxShadowMapTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_InitializeMinMaxShadowMapTech.SetDS( m_pDisableDepthTestDS );\n        m_InitializeMinMaxShadowMapTech.SetRS( m_pSolidFillNoCullRS );\n        m_InitializeMinMaxShadowMapTech.SetBS( m_pDefaultBS );\n    }\n\n    if( !m_ComputeMinMaxSMLevelTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n\n        m_ComputeMinMaxSMLevelTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_ComputeMinMaxSMLevelTech.CreatePixelShaderFromFile( m_strEffectPath, \"ComputeMinMaxShadowMapLevelPS\", Macros );\n        m_ComputeMinMaxSMLevelTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_ComputeMinMaxSMLevelTech.SetDS( m_pDisableDepthTestDS );\n        m_ComputeMinMaxSMLevelTech.SetRS( m_pSolidFillNoCullRS );\n        m_ComputeMinMaxSMLevelTech.SetBS( m_pDefaultBS );\n    }\n        \n    int iMinMaxTexHeight = m_PostProcessingAttribs.m_uiNumEpipolarSlices;\n    if( m_bUseCombinedMinMaxTexture )\n        iMinMaxTexHeight *= (m_PostProcessingAttribs.m_iNumCascades - m_PostProcessingAttribs.m_iFirstCascade);\n\n    // Computing min/max mip map using compute shader is much slower because a lot of threads are idle\n    UINT uiXOffset = 0;\n    UINT uiPrevXOffset = 0;\n    UINT uiParity = 0;\n    CComPtr<ID3D11Resource> presMinMaxShadowMap0, presMinMaxShadowMap1;\n    m_ptex2DMinMaxShadowMapRTV[0]->GetResource(&presMinMaxShadowMap0);\n    m_ptex2DMinMaxShadowMapRTV[1]->GetResource(&presMinMaxShadowMap1);\n#ifdef _DEBUG\n    {\n        D3D11_TEXTURE2D_DESC MinMaxShadowMapTexDesc;\n        CComQIPtr<ID3D11Texture2D>(presMinMaxShadowMap0)->GetDesc(&MinMaxShadowMapTexDesc);\n        assert( MinMaxShadowMapTexDesc.Width == m_PostProcessingAttribs.m_uiMinMaxShadowMapResolution );\n        assert( MinMaxShadowMapTexDesc.Height == iMinMaxTexHeight );\n    }\n#endif\n    // Note that we start rendering min/max shadow map from step == 2\n    for(UINT iStep = 2; iStep <= (UINT)m_PostProcessingAttribs.m_fMaxShadowMapStep; iStep *=2, uiParity = (uiParity+1)%2 )\n    {\n        // Use two buffers which are in turn used as the source and destination\n        FrameAttribs.pd3dDeviceContext->OMSetRenderTargets( 1, &m_ptex2DMinMaxShadowMapRTV[uiParity].p, NULL);\n\n        // Set source and destination min/max data offsets:\n        SMiscDynamicParams MiscDynamicParams = {NULL};\n        MiscDynamicParams.ui4SrcMinMaxLevelXOffset = uiPrevXOffset;\n        MiscDynamicParams.ui4DstMinMaxLevelXOffset = uiXOffset;\n        MiscDynamicParams.fCascadeInd = static_cast<float>(iCascadeIndex);\n        UpdateConstantBuffer(FrameAttribs.pd3dDeviceContext, m_pcbMiscParams, &MiscDynamicParams, sizeof(MiscDynamicParams));\n        //cbuffer cbMiscDynamicParams : register( b4 )\n        FrameAttribs.pd3dDeviceContext->PSSetConstantBuffers(4, 1, &m_pcbMiscParams.p);\n\n        if( iStep == 2 )\n        {\n            // At the initial pass, the shader gathers 8 depths which will be used for\n            // PCF filtering at the sample location and its next neighbor along the slice \n            // and outputs min/max depths\n\n            ID3D11ShaderResourceView *pSRVs[] = \n            {\n                FrameAttribs.ptex2DShadowMapSRV, // Texture2D<float2> g_tex2DLightSpaceDepthMap    : register( t3 );\n                nullptr,                         // t4\n                nullptr,                         // t5\n                m_ptex2DSliceUVDirAndOriginSRV   // Texture2D<float4> g_tex2DSliceUVDirAndOrigin   : register( t6 );\n            };\n            FrameAttribs.pd3dDeviceContext->PSSetShaderResources( 3, _countof(pSRVs), pSRVs );\n        }\n        else\n        {\n            // At the subsequent passes, the shader loads two min/max values from the next finer level \n            // to compute next level of the binary tree\n\n            // Texture2D<float2> g_tex2DMinMaxLightSpaceDepth  : register( t4 );\n            FrameAttribs.pd3dDeviceContext->PSSetShaderResources( 4, 1, &m_ptex2DMinMaxShadowMapSRV[ (uiParity+1)%2 ].p );\n        }\n            \n\n        RenderQuad( FrameAttribs.pd3dDeviceContext, \n                    (iStep>2) ? m_ComputeMinMaxSMLevelTech : m_InitializeMinMaxShadowMapTech,\n                    m_PostProcessingAttribs.m_uiMinMaxShadowMapResolution / iStep, iMinMaxTexHeight, \n                    uiXOffset, 0 );\n\n        // All the data must reside in 0-th texture, so copy current level, if necessary, from 1-st texture\n        if( uiParity == 1 )\n        {\n            D3D11_BOX SrcBox;\n            SrcBox.left = uiXOffset;\n            SrcBox.right = uiXOffset + m_PostProcessingAttribs.m_uiMinMaxShadowMapResolution / iStep;\n            SrcBox.top = 0;\n            SrcBox.bottom = iMinMaxTexHeight;\n            SrcBox.front = 0;\n            SrcBox.back = 1;\n            FrameAttribs.pd3dDeviceContext->CopySubresourceRegion(presMinMaxShadowMap0, 0, uiXOffset, 0, 0,\n                                                                    presMinMaxShadowMap1, 0, &SrcBox);\n        }\n\n        uiPrevXOffset = uiXOffset;\n        uiXOffset += m_PostProcessingAttribs.m_uiMinMaxShadowMapResolution / iStep;\n    }\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: DoRayMarching(SFrameAttribs &FrameAttribs, \n                                            UINT uiMaxStepsAlongRay, \n                                            const SShadowMapAttribs &SMAttribs, \n                                            int iCascadeIndex)\n{\n    CRenderTechnique &DoRayMarchTech = m_DoRayMarchTech[m_PostProcessingAttribs.m_bUse1DMinMaxTree ? 1 : 0];\n    if( !DoRayMarchTech.IsValid()  )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.AddShaderMacro(\"CASCADE_PROCESSING_MODE\", m_PostProcessingAttribs.m_uiCascadeProcessingMode);\n        Macros.Finalize();\n\n        DoRayMarchTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        DoRayMarchTech.CreatePixelShaderFromFile( m_strEffectPath, m_PostProcessingAttribs.m_bUse1DMinMaxTree ? \"RayMarchMinMaxOptPS\" : \"RayMarchPS\", Macros );\n        DoRayMarchTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        // Sample locations for which ray marching should be performed will be marked in stencil with 2\n        DoRayMarchTech.SetDS( m_pNoDepth_StEqual_KeepStencilDS, 2 );\n        DoRayMarchTech.SetRS( m_pSolidFillNoCullRS );\n        DoRayMarchTech.SetBS( m_pAdditiveBlendBS );\n    }\n\n    //float BlackColor[] = {0,0,0,0};\n    // NOTE: this is for debug purposes only:\n    //FrameAttribs.pd3dDeviceContext->ClearRenderTargetView(m_ptex2DInitialScatteredLightRTV, BlackColor);\n    ID3D11RenderTargetView *pRTVs[] = {m_ptex2DInitialScatteredLightRTV};\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(_countof(pRTVs), pRTVs, m_ptex2DEpipolarImageDSV);\n\n    SMiscDynamicParams MiscDynamicParams = {NULL};\n    MiscDynamicParams.fMaxStepsAlongRay = static_cast<float>( uiMaxStepsAlongRay );\n    MiscDynamicParams.fCascadeInd = static_cast<float>(iCascadeIndex);\n    UpdateConstantBuffer(FrameAttribs.pd3dDeviceContext, m_pcbMiscParams, &MiscDynamicParams, sizeof(MiscDynamicParams));\n    //cbuffer cbMiscDynamicParams : register( b4 )\n    FrameAttribs.pd3dDeviceContext->PSSetConstantBuffers(4, 1, &m_pcbMiscParams.p);\n\n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        m_ptex2DCameraSpaceZSRV,            // Texture2D<float>  g_tex2DCamSpaceZ              : register( t0 );\n        m_ptex2DCoordinateTextureSRV,       // Texture2D<float2> g_tex2DCoordinates            : register( t1 );\n        m_ptex2DEpipolarCamSpaceZSRV,       //Texture2D<float> g_tex2DEpipolarCamSpaceZ        : register( t2 );\n        FrameAttribs.ptex2DShadowMapSRV,    // Texture2D<float>  g_tex2DLightSpaceDepthMap     : register( t3 );\n        m_ptex2DMinMaxShadowMapSRV[0],      // Texture2D<float2> g_tex2DMinMaxLightSpaceDepth  : register( t4 );\n        m_ptex2DOccludedNetDensityToAtmTopSRV, // Texture2D<float2> g_tex2DOccludedNetDensityToAtmTop : register( t5 );\n        m_ptex2DSliceUVDirAndOriginSRV,      // Texture2D<float4> g_tex2DSliceUVDirAndOrigin    : register( t6 );\n        m_ptex3DSingleScatteringSRV,         // Texture3D<float3> g_tex3DSingleSctrLUT          : register( t7 );\n        m_ptex3DHighOrderScatteringSRV,      // Texture3D<float3> g_tex3DHighOrderSctrLUT       : register( t8 );\n        m_ptex3DMultipleScatteringSRV        // Texture3D<float3> g_tex3DMultipleSctrLUT        : register( t9 );\n    };\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n    \n    int iNumInst = 0;\n    if( m_PostProcessingAttribs.m_bEnableLightShafts )\n    {\n        switch(m_PostProcessingAttribs.m_uiCascadeProcessingMode)\n        {\n            case CASCADE_PROCESSING_MODE_SINGLE_PASS:\n            case CASCADE_PROCESSING_MODE_MULTI_PASS: \n                iNumInst = 1; \n                break;\n            case CASCADE_PROCESSING_MODE_MULTI_PASS_INST: \n                iNumInst = m_PostProcessingAttribs.m_iNumCascades - m_PostProcessingAttribs.m_iFirstCascade; \n                break;\n        }\n    }\n    else\n    {\n        iNumInst = 1;\n    }\n\n    // Depth stencil view now contains 2 for these pixels, for which ray marchings is to be performed\n    // Depth stencil state is configured to pass only these pixels and discard the rest\n    RenderQuad( FrameAttribs.pd3dDeviceContext,\n                DoRayMarchTech,\n                m_PostProcessingAttribs.m_uiMaxSamplesInSlice, m_PostProcessingAttribs.m_uiNumEpipolarSlices,\n                0,0,\n                iNumInst);\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: InterpolateInsctrIrradiance(SFrameAttribs &FrameAttribs)\n{\n    if( !m_InterpolateIrradianceTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n               \n        m_InterpolateIrradianceTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_InterpolateIrradianceTech.CreatePixelShaderFromFile( m_strEffectPath, \"InterpolateIrradiancePS\", Macros );\n        m_InterpolateIrradianceTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_InterpolateIrradianceTech.SetDS( m_pDisableDepthTestDS );\n        m_InterpolateIrradianceTech.SetRS( m_pSolidFillNoCullRS );\n        m_InterpolateIrradianceTech.SetBS( m_pDefaultBS );\n    }\n    ID3D11RenderTargetView *pRTVs[] = {m_ptex2DEpipolarInscatteringRTV};\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(_countof(pRTVs), pRTVs, m_ptex2DEpipolarImageDSV);\n    \n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        m_ptex2DInitialScatteredLightSRV,   // Texture2D<uint2>  g_tex2DInitialInsctrIrradiance: register( t5 );\n        m_ptex2DInterpolationSourcesSRV     // Texture2D<float3> g_tex2DInterpolationSource    : register( t6 );\n    };\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(5, _countof(pSRVs), pSRVs);\n    RenderQuad( FrameAttribs.pd3dDeviceContext,\n                m_InterpolateIrradianceTech,\n                m_PostProcessingAttribs.m_uiMaxSamplesInSlice, m_PostProcessingAttribs.m_uiNumEpipolarSlices );\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: CreateLowResLuminanceTexture(ID3D11Device *pDevice)\n{\n    D3D11_TEXTURE2D_DESC LowResLuminanceTexDesc = \n    {\n        1 << (sm_iLowResLuminanceMips-1),   //UINT Width;\n        1 << (sm_iLowResLuminanceMips-1),   //UINT Height;\n        sm_iLowResLuminanceMips,            //UINT MipLevels;\n        1,                                  //UINT ArraySize;\n        DXGI_FORMAT_R16_FLOAT,              //DXGI_FORMAT Format;\n        {1,0},                              //DXGI_SAMPLE_DESC SampleDesc;\n        D3D11_USAGE_DEFAULT,                //D3D11_USAGE Usage;\n        D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,           //UINT BindFlags;\n        0,                                  //UINT CPUAccessFlags;\n        D3D11_RESOURCE_MISC_GENERATE_MIPS                                  //UINT MiscFlags;\n    };\n\n    CComPtr<ID3D11Texture2D> ptex2DLowResLuminance;\n    // Create 2-D texture, shader resource and target view buffers on the device\n    HRESULT hr;\n    V( pDevice->CreateTexture2D( &LowResLuminanceTexDesc, NULL, &ptex2DLowResLuminance) );\n    V( pDevice->CreateShaderResourceView( ptex2DLowResLuminance, NULL, &m_ptex2DLowResLuminanceSRV) );\n    V( pDevice->CreateRenderTargetView( ptex2DLowResLuminance, NULL, &m_ptex2DLowResLuminanceRTV) );\n\n    // Create 2-D texture, shader resource and target view buffers on the device\n    LowResLuminanceTexDesc.Width = 1;\n    LowResLuminanceTexDesc.Height = 1;\n    LowResLuminanceTexDesc.MipLevels = 1;\n    LowResLuminanceTexDesc.MiscFlags = 0;\n    int Zero = 0;\n    D3D11_SUBRESOURCE_DATA InitData = {&Zero, 2, 0};\n    CComPtr<ID3D11Texture2D> ptex2DAverageLuminance;\n    V( pDevice->CreateTexture2D( &LowResLuminanceTexDesc, &InitData, &ptex2DAverageLuminance) );\n    V( pDevice->CreateShaderResourceView( ptex2DAverageLuminance, NULL, &m_ptex2DAverageLuminanceSRV) );\n    V( pDevice->CreateRenderTargetView( ptex2DAverageLuminance, NULL, &m_ptex2DAverageLuminanceRTV) );\n}\n\nvoid CLightSctrPostProcess :: UnwarpEpipolarScattering(SFrameAttribs &FrameAttribs, bool bRenderLuminance)\n{\n    if( !m_UnwarpEpipolarSctrImgTech.IsValid()  )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.AddShaderMacro(\"PERFORM_TONE_MAPPING\", true);\n        Macros.AddShaderMacro(\"AUTO_EXPOSURE\", m_PostProcessingAttribs.m_bAutoExposure);\n        Macros.AddShaderMacro(\"TONE_MAPPING_MODE\", m_PostProcessingAttribs.m_uiToneMappingMode);\n        Macros.AddShaderMacro(\"CORRECT_INSCATTERING_AT_DEPTH_BREAKS\", m_PostProcessingAttribs.m_bCorrectScatteringAtDepthBreaks);\n        Macros.Finalize();\n        \n        m_UnwarpEpipolarSctrImgTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_UnwarpEpipolarSctrImgTech.CreatePixelShaderFromFile( m_strEffectPath, \"ApplyInscatteredRadiancePS\", Macros );\n        m_UnwarpEpipolarSctrImgTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_UnwarpEpipolarSctrImgTech.SetDS( m_pDisableDepthTestIncrStencilDS );\n        m_UnwarpEpipolarSctrImgTech.SetRS( m_pSolidFillNoCullRS );\n        m_UnwarpEpipolarSctrImgTech.SetBS( m_pDefaultBS );\n    }\n\n    if( !m_UnwarpAndRenderLuminanceTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.AddShaderMacro(\"PERFORM_TONE_MAPPING\", false);\n        Macros.AddShaderMacro(\"CORRECT_INSCATTERING_AT_DEPTH_BREAKS\", false);\n        Macros.Finalize();\n        \n        m_UnwarpAndRenderLuminanceTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_UnwarpAndRenderLuminanceTech.CreatePixelShaderFromFile( m_strEffectPath, \"ApplyInscatteredRadiancePS\", Macros );\n        m_UnwarpAndRenderLuminanceTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        // Do not use stencil\n        m_UnwarpAndRenderLuminanceTech.SetDS( m_pDisableDepthTestDS );\n        m_UnwarpAndRenderLuminanceTech.SetRS( m_pSolidFillNoCullRS );\n        m_UnwarpAndRenderLuminanceTech.SetBS( m_pDefaultBS );\n    }\n\n    CRenderTechnique &Tech = bRenderLuminance ? m_UnwarpAndRenderLuminanceTech : m_UnwarpEpipolarSctrImgTech;\n\n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        m_ptex2DCameraSpaceZSRV,                // Texture2D<float>  g_tex2DCamSpaceZ              : register( t0 );\n        FrameAttribs.ptex2DSrcColorBufferSRV,   // Texture2D<float4> g_tex2DColorBuffer            : register( t1 );\n        m_ptex2DEpipolarCamSpaceZSRV,           // Texture2D<float>  g_tex2DEpipolarCamSpaceZ      : register( t2 );\n        m_ptex2DEpipolarInscatteringSRV,        // Texture2D<float3> g_tex2DScatteredColor         : register( t3 );\n        m_ptex2DSliceEndpointsSRV,              // Texture2D<float4> g_tex2DSliceEndPoints         : register( t4 );\n        m_ptex2DOccludedNetDensityToAtmTopSRV,  // Texture2D<float2> g_tex2DOccludedNetDensityToAtmTop : register( t5 );\n        m_ptex2DEpipolarExtinctionSRV,          // Texture2D<float3> g_tex2DEpipolarExtinction     : register( t6 );\n        nullptr,                                // t7\n        nullptr,                                // t8\n        nullptr,                                // t9\n        m_ptex2DAverageLuminanceSRV             // Texture2D<float>  g_tex2DAverageLuminance       : register( t10 );\n    };\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n\n    // Unwarp inscattering image and apply it to attenuated backgorund\n    RenderQuad( FrameAttribs.pd3dDeviceContext, Tech );\n}\n\nvoid CLightSctrPostProcess :: UpdateAverageLuminance(SFrameAttribs &FrameAttribs)\n{\n    if( !m_UpdateAverageLuminanceTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.AddShaderMacro( \"LIGHT_ADAPTATION\", m_PostProcessingAttribs.m_bLightAdaptation );\n        Macros.AddShaderMacro(\"LOW_RES_LUMINANCE_MIPS\", sm_iLowResLuminanceMips);\n        Macros.Finalize();\n        \n        m_UpdateAverageLuminanceTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_UpdateAverageLuminanceTech.CreatePixelShaderFromFile( m_strEffectPath, \"UpdateAverageLuminancePS\", Macros );\n        m_UpdateAverageLuminanceTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        m_UpdateAverageLuminanceTech.SetDS( m_pDisableDepthTestDS );\n        m_UpdateAverageLuminanceTech.SetRS( m_pSolidFillNoCullRS );\n        m_UpdateAverageLuminanceTech.SetBS( m_pAlphaBlendBS );\n    }\n\n    ID3D11RenderTargetView *pRTVs[] = {m_ptex2DAverageLuminanceRTV};\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(_countof(pRTVs), pRTVs, nullptr);\n\n    ID3D11ShaderResourceView *pSRVs[] = {m_ptex2DLowResLuminanceSRV};\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n\n    SMiscDynamicParams MiscDynamicParams = {NULL};\n    MiscDynamicParams.fElapsedTime = (float)FrameAttribs.dElapsedTime;\n    UpdateConstantBuffer(FrameAttribs.pd3dDeviceContext, m_pcbMiscParams, &MiscDynamicParams, sizeof(MiscDynamicParams));\n    //cbuffer cbMiscDynamicParams : register( b4 )\n    FrameAttribs.pd3dDeviceContext->PSSetConstantBuffers(4, 1, &m_pcbMiscParams.p);\n\n    // Update average luminance\n    RenderQuad( FrameAttribs.pd3dDeviceContext, m_UpdateAverageLuminanceTech, 1, 1 );\n}\n\nvoid CLightSctrPostProcess :: FixInscatteringAtDepthBreaks(SFrameAttribs &FrameAttribs, \n                                                           UINT uiMaxStepsAlongRay, \n                                                           const SShadowMapAttribs &SMAttribs,\n                                                           bool bRenderLuminance)\n{\n    bool bApplBG = true;\n    auto &FixInsctrAtDepthBreaksTech = m_FixInsctrAtDepthBreaksTech[(bApplBG ? 1 : 0) + (bRenderLuminance ? 2 : 0)];\n    if( !FixInsctrAtDepthBreaksTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.AddShaderMacro(\"CASCADE_PROCESSING_MODE\", CASCADE_PROCESSING_MODE_SINGLE_PASS);\n        Macros.AddShaderMacro(\"PERFORM_TONE_MAPPING\", !bRenderLuminance);\n        Macros.AddShaderMacro(\"AUTO_EXPOSURE\", m_PostProcessingAttribs.m_bAutoExposure);\n        Macros.AddShaderMacro(\"TONE_MAPPING_MODE\", m_PostProcessingAttribs.m_uiToneMappingMode);\n        Macros.Finalize();\n        FixInsctrAtDepthBreaksTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        FixInsctrAtDepthBreaksTech.CreatePixelShaderFromFile( m_strEffectPath, bApplBG ? \"FixAndApplyInscatteredRadiancePS\" : \"FixInscatteredRadiancePS\", Macros );\n        FixInsctrAtDepthBreaksTech.SetVS( m_pGenerateScreenSizeQuadVS );\n        // If rendering luminance only, disable depth and stencil tests to render all pixels\n        FixInsctrAtDepthBreaksTech.SetDS( bRenderLuminance ? m_pDisableDepthTestDS : m_pNoDepth_StEqual_KeepStencilDS, 0 );\n        FixInsctrAtDepthBreaksTech.SetRS( m_pSolidFillNoCullRS );\n        // If rendering luminance only, use default blend state to overwrite old luminance values\n        FixInsctrAtDepthBreaksTech.SetBS( bRenderLuminance ? m_pDefaultBS : m_pAdditiveBlendBS );\n    }\n\n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        m_ptex2DCameraSpaceZSRV,                // Texture2D<float>  g_tex2DCamSpaceZ              : register( t0 );\n        FrameAttribs.ptex2DSrcColorBufferSRV,   // Texture2D<float4> g_tex2DColorBuffer            : register( t1 );\n        m_ptex2DEpipolarCamSpaceZSRV,           // Texture2D<float> g_tex2DEpipolarCamSpaceZ       : register( t2 );\n        FrameAttribs.ptex2DShadowMapSRV,        // Texture2D<float>  g_tex2DLightSpaceDepthMap     : register( t3 );\n        m_ptex2DMinMaxShadowMapSRV[0],          // Texture2D<float2> g_tex2DMinMaxLightSpaceDepth  : register( t4 );\n        m_ptex2DOccludedNetDensityToAtmTopSRV,  // Texture2D<float2> g_tex2DOccludedNetDensityToAtmTop : register( t5 );\n        m_ptex2DSliceUVDirAndOriginSRV,         // Texture2D<float4> g_tex2DSliceUVDirAndOrigin    : register( t6 );\n        m_ptex3DSingleScatteringSRV,            // Texture3D<float3> g_tex3DSingleSctrLUT          : register( t7 );\n        m_ptex3DHighOrderScatteringSRV,         // Texture3D<float3> g_tex3DHighOrderSctrLUT       : register( t8 );\n        m_ptex3DMultipleScatteringSRV,          // Texture3D<float3> g_tex3DMultipleSctrLUT        : register( t9  );\n        m_ptex2DAverageLuminanceSRV             // Texture2D<float>  g_tex2DAverageLuminance       : register( t10 );\n    };\n    FrameAttribs.pd3dDeviceContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n    \n    SMiscDynamicParams MiscDynamicParams = {NULL};\n    MiscDynamicParams.fMaxStepsAlongRay = static_cast<float>( uiMaxStepsAlongRay );\n    MiscDynamicParams.fCascadeInd = static_cast<float>(m_PostProcessingAttribs.m_iFirstCascade);\n    UpdateConstantBuffer(FrameAttribs.pd3dDeviceContext, m_pcbMiscParams, &MiscDynamicParams, sizeof(MiscDynamicParams));\n    //cbuffer cbMiscDynamicParams : register( b4 )\n    FrameAttribs.pd3dDeviceContext->PSSetConstantBuffers(4, 1, &m_pcbMiscParams.p);\n        \n    RenderQuad( FrameAttribs.pd3dDeviceContext, FixInsctrAtDepthBreaksTech);\n}\n\nvoid CLightSctrPostProcess :: RenderSampleLocations(SFrameAttribs &FrameAttribs)\n{\n    if( !m_RenderSampleLocationsTech.IsValid() )\n    {\n        CD3DShaderMacroHelper Macros;\n        DefineMacros(Macros);\n        Macros.Finalize();\n        m_RenderSampleLocationsTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_RenderSampleLocationsTech.CreateVGPShadersFromFile( m_strEffectPath, \"PassThroughVS\", \"RenderSamplePositionsGS\", \"RenderSampleLocationsPS\", Macros );\n        m_RenderSampleLocationsTech.SetDS( m_pDisableDepthTestDS );\n        m_RenderSampleLocationsTech.SetRS( m_pSolidFillNoCullRS );\n        D3D11_BLEND_DESC OverBlendStateDesc;\n        ZeroMemory(&OverBlendStateDesc, sizeof(OverBlendStateDesc));\n        OverBlendStateDesc.IndependentBlendEnable = FALSE;\n        OverBlendStateDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;\n        OverBlendStateDesc.RenderTarget[0].BlendEnable    = TRUE;\n        OverBlendStateDesc.RenderTarget[0].BlendOp        = D3D11_BLEND_OP_ADD;\n        OverBlendStateDesc.RenderTarget[0].BlendOpAlpha   = D3D11_BLEND_OP_ADD;\n        OverBlendStateDesc.RenderTarget[0].DestBlend      = D3D11_BLEND_INV_SRC_ALPHA;\n        OverBlendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;\n        OverBlendStateDesc.RenderTarget[0].SrcBlend       = D3D11_BLEND_SRC_ALPHA;\n        OverBlendStateDesc.RenderTarget[0].SrcBlendAlpha  = D3D11_BLEND_ONE;\n        CComPtr<ID3D11BlendState> pOverBS;\n        HRESULT hr;\n        V( FrameAttribs.pd3dDevice->CreateBlendState( &OverBlendStateDesc, &pOverBS) );\n        m_RenderSampleLocationsTech.SetBS( pOverBS );\n    }\n\n    ID3D11ShaderResourceView *pSRVs[] = \n    {\n        NULL,\n        m_ptex2DCoordinateTextureSRV,               // Texture2D<float2> g_tex2DCoordinates            : register( t1 );\n        NULL,                                       // t2\n        NULL,                                       // t3\n        NULL,                                       // t4\n        NULL,                                       // t5\n        m_ptex2DInterpolationSourcesSRV,            // Texture2D<uint2>  g_tex2DInterpolationSource    : register( t6 );\n    };\n    FrameAttribs.pd3dDeviceContext->GSSetShaderResources(0, _countof(pSRVs), pSRVs);\n\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(1, &FrameAttribs.pDstRTV, NULL);\n    FrameAttribs.pd3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);\n    UINT offset[1] = {0};\n    UINT stride[1] = {0};\n    ID3D11Buffer *ppBuffers[1] = {0};\n    // Set the device's first and only vertex buffer with zero stride and offset\n    FrameAttribs.pd3dDeviceContext->IASetVertexBuffers(0,1,ppBuffers,stride,offset);\n    // There is no input-layout object and the primitive topology is triangle strip\n    FrameAttribs.pd3dDeviceContext->IASetInputLayout(NULL);\n    m_RenderSampleLocationsTech.Apply();\n    FrameAttribs.pd3dDeviceContext->Draw(m_PostProcessingAttribs.m_uiMaxSamplesInSlice * m_PostProcessingAttribs.m_uiNumEpipolarSlices,0);\n    UnbindResources( FrameAttribs.pd3dDeviceContext );\n}\n\nvoid CLightSctrPostProcess :: PerformPostProcessing(SFrameAttribs &FrameAttribs,\n                                                    SPostProcessingAttribs &PPAttribs)\n{\n    HRESULT hr;\n\n    if( GetAsyncKeyState(VK_F8) )\n    {\n        m_ReconstrCamSpaceZTech.Release();\n        m_RendedSliceEndpointsTech.Release();\n        m_RendedCoordTexTech.Release();\n        m_RefineSampleLocationsTech.Release();\n        m_RenderCoarseUnshadowedInsctrTech.Release();\n        m_MarkRayMarchingSamplesInStencilTech.Release();\n        m_RenderSliceUVDirInSMTech.Release();\n        m_InitializeMinMaxShadowMapTech.Release();\n        m_ComputeMinMaxSMLevelTech.Release();\n        for(size_t i=0; i<_countof(m_DoRayMarchTech); ++i)\n            m_DoRayMarchTech[i].Release();\n        m_InterpolateIrradianceTech.Release();\n        m_UnwarpEpipolarSctrImgTech.Release();\n        m_UnwarpAndRenderLuminanceTech.Release();\n        m_UpdateAverageLuminanceTech.Release();\n        for(size_t i=0; i<_countof(m_FixInsctrAtDepthBreaksTech); ++i)\n            m_FixInsctrAtDepthBreaksTech[i].Release();\n        m_RenderSampleLocationsTech.Release();\n        m_RenderSunTech.Release();\n        m_PrecomputeSingleSctrTech.Release();\n        m_ComputeSctrRadianceTech.Release();\n        m_ComputeScatteringOrderTech.Release();\n        m_AddScatteringOrderTech.Release();\n    }\n    bool bUseCombinedMinMaxTexture = PPAttribs.m_uiCascadeProcessingMode == CASCADE_PROCESSING_MODE_SINGLE_PASS ||\n                                     PPAttribs.m_uiCascadeProcessingMode == CASCADE_PROCESSING_MODE_MULTI_PASS_INST ||\n                                     PPAttribs.m_bCorrectScatteringAtDepthBreaks || \n                                     PPAttribs.m_uiLightSctrTechnique == LIGHT_SCTR_TECHNIQUE_BRUTE_FORCE;\n\n    if( PPAttribs.m_uiNumEpipolarSlices != m_PostProcessingAttribs.m_uiNumEpipolarSlices || \n        PPAttribs.m_uiMaxSamplesInSlice != m_PostProcessingAttribs.m_uiMaxSamplesInSlice ||\n        PPAttribs.m_bOptimizeSampleLocations != m_PostProcessingAttribs.m_bOptimizeSampleLocations )\n        m_RendedSliceEndpointsTech.Release();\n    \n    if( PPAttribs.m_uiMaxSamplesInSlice != m_PostProcessingAttribs.m_uiMaxSamplesInSlice )\n        m_RendedCoordTexTech.Release();\n\n    if( PPAttribs.m_uiMaxSamplesInSlice != m_PostProcessingAttribs.m_uiMaxSamplesInSlice ||\n        PPAttribs.m_uiInitialSampleStepInSlice != m_PostProcessingAttribs.m_uiInitialSampleStepInSlice ||\n        PPAttribs.m_uiRefinementCriterion != m_PostProcessingAttribs.m_uiRefinementCriterion ||\n        PPAttribs.m_bAutoExposure != m_PostProcessingAttribs.m_bAutoExposure )\n        m_RefineSampleLocationsTech.Release();\n\n    if( PPAttribs.m_bUse1DMinMaxTree != m_PostProcessingAttribs.m_bUse1DMinMaxTree ||\n        bUseCombinedMinMaxTexture != m_bUseCombinedMinMaxTexture ||\n        PPAttribs.m_uiNumEpipolarSlices != m_PostProcessingAttribs.m_uiNumEpipolarSlices ||\n        PPAttribs.m_bIs32BitMinMaxMipMap != m_PostProcessingAttribs.m_bIs32BitMinMaxMipMap )\n    {\n        m_InitializeMinMaxShadowMapTech.Release();\n    }\n\n    if( PPAttribs.m_bUse1DMinMaxTree != m_PostProcessingAttribs.m_bUse1DMinMaxTree ||\n        PPAttribs.m_uiCascadeProcessingMode != m_PostProcessingAttribs.m_uiCascadeProcessingMode ||\n        bUseCombinedMinMaxTexture != m_bUseCombinedMinMaxTexture ||\n        PPAttribs.m_bEnableLightShafts != m_PostProcessingAttribs.m_bEnableLightShafts ||\n        PPAttribs.m_uiMultipleScatteringMode != m_PostProcessingAttribs.m_uiMultipleScatteringMode ||\n        PPAttribs.m_uiSingleScatteringMode != m_PostProcessingAttribs.m_uiSingleScatteringMode)\n    {\n        for(int i=0; i<_countof(m_DoRayMarchTech); ++i)\n            m_DoRayMarchTech[i].Release();\n    }\n\n    if( PPAttribs.m_uiNumEpipolarSlices != m_PostProcessingAttribs.m_uiNumEpipolarSlices ||\n        PPAttribs.m_uiMaxSamplesInSlice != m_PostProcessingAttribs.m_uiMaxSamplesInSlice )\n    {\n        m_UnwarpEpipolarSctrImgTech.Release();\n        m_UnwarpAndRenderLuminanceTech.Release();\n    }\n\n    if( PPAttribs.m_bAutoExposure != m_PostProcessingAttribs.m_bAutoExposure || \n        PPAttribs.m_uiToneMappingMode != m_PostProcessingAttribs.m_uiToneMappingMode ||\n        PPAttribs.m_bCorrectScatteringAtDepthBreaks != m_PostProcessingAttribs.m_bCorrectScatteringAtDepthBreaks )\n    {\n        m_UnwarpEpipolarSctrImgTech.Release();\n    }\n\n    if( PPAttribs.m_bLightAdaptation != m_PostProcessingAttribs.m_bLightAdaptation )\n    {\n        m_UpdateAverageLuminanceTech.Release();\n    }\n\n    if( PPAttribs.m_uiCascadeProcessingMode != m_PostProcessingAttribs.m_uiCascadeProcessingMode ||\n        bUseCombinedMinMaxTexture != m_bUseCombinedMinMaxTexture ||\n        PPAttribs.m_bEnableLightShafts != m_PostProcessingAttribs.m_bEnableLightShafts ||\n        PPAttribs.m_uiMultipleScatteringMode != m_PostProcessingAttribs.m_uiMultipleScatteringMode  ||\n        PPAttribs.m_uiSingleScatteringMode != m_PostProcessingAttribs.m_uiSingleScatteringMode ||\n        PPAttribs.m_bAutoExposure != m_PostProcessingAttribs.m_bAutoExposure || \n        PPAttribs.m_uiToneMappingMode != m_PostProcessingAttribs.m_uiToneMappingMode)\n    {\n        for(size_t i=0; i<_countof(m_FixInsctrAtDepthBreaksTech); ++i)\n            m_FixInsctrAtDepthBreaksTech[i].Release();\n    }\n    \n    if( PPAttribs.m_uiMaxSamplesInSlice != m_PostProcessingAttribs.m_uiMaxSamplesInSlice || \n        PPAttribs.m_uiNumEpipolarSlices != m_PostProcessingAttribs.m_uiNumEpipolarSlices )\n    {\n        m_ptex2DCoordinateTextureRTV.Release();\n        m_ptex2DCoordinateTextureSRV.Release();\n    }\n    \n    if( PPAttribs.m_uiMinMaxShadowMapResolution != m_PostProcessingAttribs.m_uiMinMaxShadowMapResolution || \n        PPAttribs.m_uiNumEpipolarSlices != m_PostProcessingAttribs.m_uiNumEpipolarSlices ||\n        PPAttribs.m_bUse1DMinMaxTree != m_PostProcessingAttribs.m_bUse1DMinMaxTree ||\n        PPAttribs.m_bIs32BitMinMaxMipMap != m_PostProcessingAttribs.m_bIs32BitMinMaxMipMap ||\n        bUseCombinedMinMaxTexture != m_bUseCombinedMinMaxTexture ||\n        bUseCombinedMinMaxTexture && \n            (PPAttribs.m_iFirstCascade != m_PostProcessingAttribs.m_iFirstCascade || \n             PPAttribs.m_iNumCascades  != m_PostProcessingAttribs.m_iNumCascades) )\n    {\n        for(int i=0; i < _countof(m_ptex2DMinMaxShadowMapSRV); ++i)\n            m_ptex2DMinMaxShadowMapSRV[i].Release();\n        for(int i=0; i < _countof(m_ptex2DMinMaxShadowMapRTV); ++i)\n            m_ptex2DMinMaxShadowMapRTV[i].Release();\n    }\n\n    if( PPAttribs.m_iNumCascades != m_PostProcessingAttribs.m_iNumCascades )\n    {\n        m_ptex2DSliceUVDirAndOriginSRV.Release();\n        m_ptex2DSliceUVDirAndOriginRTV.Release();\n    }\n\n    if( PPAttribs.m_uiCascadeProcessingMode != m_PostProcessingAttribs.m_uiCascadeProcessingMode )\n    {\n        m_ComputeMinMaxSMLevelTech.Release();\n    }\n    \n    if( PPAttribs.m_uiExtinctionEvalMode != m_PostProcessingAttribs.m_uiExtinctionEvalMode )\n    {\n        m_ptex2DEpipolarExtinctionRTV.Release();\n        m_ptex2DEpipolarExtinctionSRV.Release();\n        m_UnwarpEpipolarSctrImgTech.Release();\n        m_UnwarpAndRenderLuminanceTech.Release();\n        m_RenderCoarseUnshadowedInsctrTech.Release();\n    }\n\n    if( PPAttribs.m_uiSingleScatteringMode != m_PostProcessingAttribs.m_uiSingleScatteringMode ||\n        PPAttribs.m_uiMultipleScatteringMode != m_PostProcessingAttribs.m_uiMultipleScatteringMode )\n        m_RenderCoarseUnshadowedInsctrTech.Release();\n\n    bool bRecomputeSctrCoeffs = m_PostProcessingAttribs.m_bUseCustomSctrCoeffs != PPAttribs.m_bUseCustomSctrCoeffs ||\n                                m_PostProcessingAttribs.m_fAerosolDensityScale != PPAttribs.m_fAerosolDensityScale ||\n                                m_PostProcessingAttribs.m_fAerosolAbsorbtionScale != PPAttribs.m_fAerosolAbsorbtionScale ||\n                                PPAttribs.m_bUseCustomSctrCoeffs && \n                                    ( m_PostProcessingAttribs.m_f4CustomRlghBeta != PPAttribs.m_f4CustomRlghBeta ||\n                                      m_PostProcessingAttribs.m_f4CustomMieBeta  != PPAttribs.m_f4CustomMieBeta );\n\n    m_PostProcessingAttribs = PPAttribs;\n    m_bUseCombinedMinMaxTexture = bUseCombinedMinMaxTexture;\n\n    if( bRecomputeSctrCoeffs )\n    {\n        m_ptex2DOccludedNetDensityToAtmTopSRV.Release();\n        m_ptex2DOccludedNetDensityToAtmTopRTV.Release();\n        m_ptex3DSingleScatteringSRV.Release();\n        m_ptex2DAmbientSkyLightRTV.Release();\n        m_ptex2DAmbientSkyLightSRV.Release();\n        ComputeScatteringCoefficients(FrameAttribs.pd3dDeviceContext);\n    }\n\n    if( !m_ptex2DCoordinateTextureRTV || !m_ptex2DCoordinateTextureSRV )\n    {\n        V( CreateTextures(FrameAttribs.pd3dDevice) );\n    }\n\n    if( !m_ptex2DMinMaxShadowMapSRV[0] && m_PostProcessingAttribs.m_bUse1DMinMaxTree )\n    {\n        V( CreateMinMaxShadowMap(FrameAttribs.pd3dDevice) );\n    }\n\n    SLightAttribs &LightAttribs = *FrameAttribs.pLightAttribs;\n    const SCameraAttribs &CamAttribs = FrameAttribs.CameraAttribs;\n\n    // Note that in fact the outermost visible screen pixels do not lie exactly on the boundary (+1 or -1), but are biased by\n    // 0.5 screen pixel size inwards. Using these adjusted boundaries improves precision and results in\n    // smaller number of pixels which require inscattering correction\n    assert( LightAttribs.bIsLightOnScreen == (abs(FrameAttribs.pLightAttribs->f4LightScreenPos.x) <= 1.f - 1.f/(float)m_uiBackBufferWidth && \n                                              abs(FrameAttribs.pLightAttribs->f4LightScreenPos.y) <= 1.f - 1.f/(float)m_uiBackBufferHeight) );\n\n    const auto &SMAttribs = FrameAttribs.pLightAttribs->ShadowAttribs;\n\n    UpdateConstantBuffer(FrameAttribs.pd3dDeviceContext, m_pcbCameraAttribs, &CamAttribs, sizeof(CamAttribs));\n    //UpdateConstantBuffer(FrameAttribs.pd3dDeviceContext, m_pcbLightAttribs, &LightAttribs, sizeof(LightAttribs));\n    UpdateConstantBuffer(FrameAttribs.pd3dDeviceContext, m_pcbPostProcessingAttribs, &m_PostProcessingAttribs, sizeof(m_PostProcessingAttribs));\n    \n    // Set constant buffers that will be used by all pixel shaders and compute shader\n    ID3D11Buffer *pCBs[] = {m_pcbPostProcessingAttribs, m_pcbMediaAttribs, m_pcbCameraAttribs, FrameAttribs.pcbLightAttribs};\n    FrameAttribs.pd3dDeviceContext->VSSetConstantBuffers(0, _countof(pCBs), pCBs);\n    FrameAttribs.pd3dDeviceContext->GSSetConstantBuffers(0, _countof(pCBs), pCBs);\n    FrameAttribs.pd3dDeviceContext->PSSetConstantBuffers(0, _countof(pCBs), pCBs);\n    FrameAttribs.pd3dDeviceContext->CSSetConstantBuffers(0, _countof(pCBs), pCBs);\n        \n\n    ID3D11SamplerState *pSamplers[] = { m_psamLinearClamp, m_psamLinearBorder0, m_psamComparison, m_psamPointClamp };\n    FrameAttribs.pd3dDeviceContext->PSSetSamplers(0, _countof(pSamplers), pSamplers);\n    FrameAttribs.pd3dDeviceContext->CSSetSamplers(0, 1, pSamplers);\n\n    D3D11_VIEWPORT OrigViewPort;\n    UINT iNumOldViewports = 1;\n    FrameAttribs.pd3dDeviceContext->RSGetViewports(&iNumOldViewports, &OrigViewPort);\n\n    if( !m_ptex2DOccludedNetDensityToAtmTopSRV )\n    {\n        CreatePrecomputedOpticalDepthTexture(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n    }\n    \n    if( (m_PostProcessingAttribs.m_uiMultipleScatteringMode > MULTIPLE_SCTR_MODE_NONE ||\n         PPAttribs.m_uiSingleScatteringMode == SINGLE_SCTR_MODE_LUT) &&\n        !m_ptex3DSingleScatteringSRV )\n    {\n        CreatePrecomputedScatteringLUT(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n    }\n\n    if( m_PostProcessingAttribs.m_bAutoExposure && !m_ptex2DLowResLuminanceRTV )\n    {\n        CreateLowResLuminanceTexture(FrameAttribs.pd3dDevice);\n    }\n\n    float Zero[4]={0,0,0,0};\n    FrameAttribs.pd3dDeviceContext->ClearRenderTargetView(FrameAttribs.pDstRTV, Zero);\n\n    RenderSun(FrameAttribs);\n\n    ReconstructCameraSpaceZ(FrameAttribs);\n\n    if( m_PostProcessingAttribs.m_uiLightSctrTechnique == LIGHT_SCTR_TECHNIQUE_EPIPOLAR_SAMPLING )\n    {\n        \n        RenderSliceEndpoints(FrameAttribs);\n\n        // Render coordinate texture and camera space z for epipolar location\n        RenderCoordinateTexture(FrameAttribs);\n\n        if( m_PostProcessingAttribs.m_uiRefinementCriterion == REFINEMENT_CRITERION_INSCTR_DIFF || \n            m_PostProcessingAttribs.m_uiExtinctionEvalMode == EXTINCTION_EVAL_MODE_EPIPOLAR )\n        {\n            RenderCoarseUnshadowedInctr(FrameAttribs);\n        }\n\n        // Refine initial ray marching samples\n        RefineSampleLocations(FrameAttribs);\n\n        // Mark all ray marching samples in stencil\n        MarkRayMarchingSamples( FrameAttribs );\n\n        if( m_PostProcessingAttribs.m_bEnableLightShafts && m_PostProcessingAttribs.m_bUse1DMinMaxTree )\n        {\n            RenderSliceUVDirAndOrig(FrameAttribs);\n        }\n\n        FrameAttribs.pd3dDeviceContext->ClearRenderTargetView(m_ptex2DInitialScatteredLightRTV, Zero);\n        int iLastCascade = (m_PostProcessingAttribs.m_bEnableLightShafts && m_PostProcessingAttribs.m_uiCascadeProcessingMode == CASCADE_PROCESSING_MODE_MULTI_PASS) ? m_PostProcessingAttribs.m_iNumCascades - 1 : m_PostProcessingAttribs.m_iFirstCascade;\n        for(int iCascadeInd = m_PostProcessingAttribs.m_iFirstCascade; iCascadeInd <= iLastCascade; ++iCascadeInd)\n        {\n            // Build min/max mip map\n            if( m_PostProcessingAttribs.m_bEnableLightShafts && m_PostProcessingAttribs.m_bUse1DMinMaxTree )\n            {\n                Build1DMinMaxMipMap(FrameAttribs, iCascadeInd);\n            }\n\n            // Perform ray marching for selected samples\n            DoRayMarching(FrameAttribs, m_PostProcessingAttribs.m_uiShadowMapResolution, SMAttribs, iCascadeInd);\n        }\n\n        // Interpolate ray marching samples onto the rest of samples\n        InterpolateInsctrIrradiance(FrameAttribs);\n\n        const UINT uiMaxStepsAlongRayAtDepthBreak0 = min(m_PostProcessingAttribs.m_uiShadowMapResolution/4, 256);\n        const UINT uiMaxStepsAlongRayAtDepthBreak1 = min(m_PostProcessingAttribs.m_uiShadowMapResolution/8, 128);\n        \n        ID3D11DepthStencilView *pDSV = m_ptex2DScreenSizeDSV;\n        ID3D11RenderTargetView *pRTV[] = { FrameAttribs.pDstRTV };\n        FrameAttribs.pd3dDeviceContext->ClearDepthStencilView(pDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0, 0);\n        \n        if( m_PostProcessingAttribs.m_bAutoExposure )\n        {\n            // Render scene luminance to low-resolution texture\n            FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(1, &m_ptex2DLowResLuminanceRTV.p, nullptr);\n            UnwarpEpipolarScattering(FrameAttribs, true);\n            FrameAttribs.pd3dDeviceContext->GenerateMips(m_ptex2DLowResLuminanceSRV);\n\n            UpdateAverageLuminance(FrameAttribs);\n        }\n        // Transform inscattering irradiance from epipolar coordinates back to rectangular\n        FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(1, pRTV, pDSV);\n        UnwarpEpipolarScattering(FrameAttribs, false);\n    \n        // Correct inscattering for pixels, for which no suitable interpolation sources were found\n        if( m_PostProcessingAttribs.m_bCorrectScatteringAtDepthBreaks )\n        {\n            FixInscatteringAtDepthBreaks(FrameAttribs, uiMaxStepsAlongRayAtDepthBreak0, SMAttribs, false);\n        }\n\n        if( m_PostProcessingAttribs.m_bShowSampling )\n        {\n            RenderSampleLocations(FrameAttribs);\n        }\n    }\n    else if(m_PostProcessingAttribs.m_uiLightSctrTechnique == LIGHT_SCTR_TECHNIQUE_BRUTE_FORCE )\n    {\n        if( m_PostProcessingAttribs.m_bAutoExposure )\n        {\n            // Render scene luminance to low-resolution texture\n            FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(1, &m_ptex2DLowResLuminanceRTV.p, nullptr);\n            FixInscatteringAtDepthBreaks(FrameAttribs, m_PostProcessingAttribs.m_uiShadowMapResolution, SMAttribs, true);\n            FrameAttribs.pd3dDeviceContext->GenerateMips(m_ptex2DLowResLuminanceSRV);\n\n            UpdateAverageLuminance(FrameAttribs);\n        }\n\n        FrameAttribs.pd3dDeviceContext->ClearDepthStencilView(m_ptex2DScreenSizeDSV, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0, 0);\n        FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(1, &FrameAttribs.pDstRTV, m_ptex2DScreenSizeDSV);\n        FixInscatteringAtDepthBreaks(FrameAttribs, m_PostProcessingAttribs.m_uiShadowMapResolution, SMAttribs, false);\n    }\n}\n\nHRESULT CLightSctrPostProcess :: CreateTextures(ID3D11Device* pd3dDevice)\n{\n    HRESULT hr;\n\n    D3D11_TEXTURE2D_DESC CoordinateTexDesc = \n    {\n        m_PostProcessingAttribs.m_uiMaxSamplesInSlice,         //UINT Width;\n        m_PostProcessingAttribs.m_uiNumEpipolarSlices,         //UINT Height;\n        1,                                                     //UINT MipLevels;\n        1,                                                     //UINT ArraySize;\n        DXGI_FORMAT_R32G32_FLOAT,                              //DXGI_FORMAT Format;\n        {1,0},                                                 //DXGI_SAMPLE_DESC SampleDesc;\n        D3D11_USAGE_DEFAULT,                                   //D3D11_USAGE Usage;\n        D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, //UINT BindFlags;\n        0,                                                     //UINT CPUAccessFlags;\n        0,                                                     //UINT MiscFlags;\n    };\n\n    {\n        CComPtr<ID3D11Texture2D> ptex2DCoordinateTexture;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        V_RETURN( pd3dDevice->CreateTexture2D( &CoordinateTexDesc, NULL, &ptex2DCoordinateTexture) );\n        V_RETURN( pd3dDevice->CreateShaderResourceView( ptex2DCoordinateTexture, NULL, &m_ptex2DCoordinateTextureSRV)  );\n        V_RETURN( pd3dDevice->CreateRenderTargetView( ptex2DCoordinateTexture, NULL, &m_ptex2DCoordinateTextureRTV)  );\n    }\n    \n    {\n        m_ptex2DSliceEndpointsSRV.Release();\n        m_ptex2DSliceEndpointsRTV.Release();\n        D3D11_TEXTURE2D_DESC InterpolationSourceTexDesc = CoordinateTexDesc;\n        InterpolationSourceTexDesc.Width = m_PostProcessingAttribs.m_uiNumEpipolarSlices;\n        InterpolationSourceTexDesc.Height = 1;\n        InterpolationSourceTexDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;\n        InterpolationSourceTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;\n        CComPtr<ID3D11Texture2D> ptex2DSliceEndpoints;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        V_RETURN( pd3dDevice->CreateTexture2D( &InterpolationSourceTexDesc, NULL, &ptex2DSliceEndpoints) );\n        V_RETURN( pd3dDevice->CreateShaderResourceView( ptex2DSliceEndpoints, NULL, &m_ptex2DSliceEndpointsSRV)  );\n        V_RETURN( pd3dDevice->CreateRenderTargetView( ptex2DSliceEndpoints, NULL, &m_ptex2DSliceEndpointsRTV)  );\n    }\n\n    {\n        m_ptex2DInterpolationSourcesSRV.Release();\n        m_ptex2DInterpolationSourcesUAV.Release();\n        D3D11_TEXTURE2D_DESC InterpolationSourceTexDesc = CoordinateTexDesc;\n        InterpolationSourceTexDesc.Format = DXGI_FORMAT_R16G16_UINT;\n        InterpolationSourceTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;\n        CComPtr<ID3D11Texture2D> ptex2DInterpolationSource;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        V_RETURN( pd3dDevice->CreateTexture2D( &InterpolationSourceTexDesc, NULL, &ptex2DInterpolationSource) );\n        V_RETURN( pd3dDevice->CreateShaderResourceView( ptex2DInterpolationSource, NULL, &m_ptex2DInterpolationSourcesSRV)  );\n        V_RETURN( pd3dDevice->CreateUnorderedAccessView( ptex2DInterpolationSource, NULL, &m_ptex2DInterpolationSourcesUAV)  );\n    }\n\n    {\n        m_ptex2DEpipolarCamSpaceZSRV.Release();\n        m_ptex2DEpipolarCamSpaceZRTV.Release();\n        D3D11_TEXTURE2D_DESC EpipolarCamSpaceZTexDesc = CoordinateTexDesc;\n        EpipolarCamSpaceZTexDesc.Format = DXGI_FORMAT_R32_FLOAT;\n        EpipolarCamSpaceZTexDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;\n        CComPtr<ID3D11Texture2D> ptex2DEpipolarCamSpace;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        V_RETURN( pd3dDevice->CreateTexture2D( &EpipolarCamSpaceZTexDesc, NULL, &ptex2DEpipolarCamSpace) );\n        V_RETURN( pd3dDevice->CreateShaderResourceView( ptex2DEpipolarCamSpace, NULL, &m_ptex2DEpipolarCamSpaceZSRV)  );\n        V_RETURN( pd3dDevice->CreateRenderTargetView( ptex2DEpipolarCamSpace, NULL, &m_ptex2DEpipolarCamSpaceZRTV)  );\n    }\n\n    {\n        m_ptex2DEpipolarInscatteringSRV.Release();\n        m_ptex2DEpipolarInscatteringRTV.Release();\n        D3D11_TEXTURE2D_DESC ScatteredLightTexDesc = CoordinateTexDesc;\n        // R8G8B8A8_UNORM texture does not provide sufficient precision which causes \n        // interpolation artifacts especially noticeable in low intensity regions\n        ScatteredLightTexDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;\n        CComPtr<ID3D11Texture2D> ptex2DEpipolarInscattering;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        V_RETURN( pd3dDevice->CreateTexture2D( &ScatteredLightTexDesc, NULL, &ptex2DEpipolarInscattering) );\n        V_RETURN( pd3dDevice->CreateShaderResourceView( ptex2DEpipolarInscattering, NULL, &m_ptex2DEpipolarInscatteringSRV)  );\n        V_RETURN( pd3dDevice->CreateRenderTargetView( ptex2DEpipolarInscattering, NULL, &m_ptex2DEpipolarInscatteringRTV)  );\n\n        m_ptex2DInitialScatteredLightSRV.Release();\n        m_ptex2DInitialScatteredLightRTV.Release();\n        CComPtr<ID3D11Texture2D> ptex2DInitialScatteredLight;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        V_RETURN( pd3dDevice->CreateTexture2D( &ScatteredLightTexDesc, NULL, &ptex2DInitialScatteredLight) );\n        V_RETURN( pd3dDevice->CreateShaderResourceView( ptex2DInitialScatteredLight, NULL, &m_ptex2DInitialScatteredLightSRV)  );\n        V_RETURN( pd3dDevice->CreateRenderTargetView( ptex2DInitialScatteredLight, NULL, &m_ptex2DInitialScatteredLightRTV)  );\n\n        // Release extinction texture so that it is re-created when first needed\n        m_ptex2DEpipolarExtinctionSRV.Release();\n        m_ptex2DEpipolarExtinctionRTV.Release();\n    }\n\n    {\n        m_ptex2DEpipolarImageDSV.Release();\n        D3D11_TEXTURE2D_DESC EpipolarDeptTexDesc = CoordinateTexDesc;\n        EpipolarDeptTexDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;\n        EpipolarDeptTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;\n        CComPtr<ID3D11Texture2D> ptex2DEpipolarImage;\n        V_RETURN( pd3dDevice->CreateTexture2D( &EpipolarDeptTexDesc, NULL, &ptex2DEpipolarImage) );\n        V_RETURN( pd3dDevice->CreateDepthStencilView( ptex2DEpipolarImage, NULL, &m_ptex2DEpipolarImageDSV) );\n    }\n\n    {\n        m_ptex2DSliceUVDirAndOriginSRV.Release();\n        m_ptex2DSliceUVDirAndOriginRTV.Release();\n    }\n        \n    return S_OK;\n}\n\nHRESULT CLightSctrPostProcess :: CreateMinMaxShadowMap(ID3D11Device* pd3dDevice)\n{\n    D3D11_TEXTURE2D_DESC MinMaxShadowMapTexDesc = \n    {\n        // Min/max shadow map does not contain finest resolution level of the shadow map\n        m_PostProcessingAttribs.m_uiMinMaxShadowMapResolution, //UINT Width;\n        m_PostProcessingAttribs.m_uiNumEpipolarSlices,         //UINT Height;\n        1,                                                     //UINT MipLevels;\n        1,                                                     //UINT ArraySize;\n        m_PostProcessingAttribs.m_bIs32BitMinMaxMipMap ? DXGI_FORMAT_R32G32_FLOAT : DXGI_FORMAT_R16G16_UNORM, //DXGI_FORMAT Format;\n        {1,0},                                                 //DXGI_SAMPLE_DESC SampleDesc;\n        D3D11_USAGE_DEFAULT,                                   //D3D11_USAGE Usage;\n        D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, //UINT BindFlags;\n        0,                                                     //UINT CPUAccessFlags;\n        0,                                                     //UINT MiscFlags;\n    };\n\n    if( m_bUseCombinedMinMaxTexture )\n    {\n        MinMaxShadowMapTexDesc.Height *= (m_PostProcessingAttribs.m_iNumCascades - m_PostProcessingAttribs.m_iFirstCascade);\n    }\n    \n    HRESULT hr;\n    for(int i=0; i < 2; ++i)\n    {\n        m_ptex2DMinMaxShadowMapSRV[i].Release();\n        m_ptex2DMinMaxShadowMapRTV[i].Release();\n\n        CComPtr<ID3D11Texture2D> ptex2DMinMaxShadowMap;\n        // Create 2-D texture, shader resource and target view buffers on the device\n        V_RETURN( pd3dDevice->CreateTexture2D( &MinMaxShadowMapTexDesc, NULL, &ptex2DMinMaxShadowMap) );\n        V_RETURN( pd3dDevice->CreateShaderResourceView( ptex2DMinMaxShadowMap, NULL, &m_ptex2DMinMaxShadowMapSRV[i])  );\n        V_RETURN( pd3dDevice->CreateRenderTargetView( ptex2DMinMaxShadowMap, NULL, &m_ptex2DMinMaxShadowMapRTV[i])  );\n    }\n\n    return S_OK;\n}\n\n\n\n\nD3DXVECTOR2 exp(const D3DXVECTOR2 &fX){ return D3DXVECTOR2(exp(fX.x), exp(fX.y)); }\nD3DXVECTOR3 exp(const D3DXVECTOR3 &fX){ return D3DXVECTOR3(exp(fX.x), exp(fX.y), exp(fX.z)); }\nD3DXVECTOR2 operator * (const D3DXVECTOR2 &fX, const D3DXVECTOR2 &fY){ return D3DXVECTOR2(fX.x*fY.x, fX.y*fY.y); }\nD3DXVECTOR3 operator * (const D3DXVECTOR3 &fX, const D3DXVECTOR3 &fY){ return D3DXVECTOR3(fX.x*fY.x, fX.y*fY.y, fX.z*fY.z); }\nD3DXVECTOR2 operator / (const D3DXVECTOR2 &fX, const D3DXVECTOR2 &fY){ return D3DXVECTOR2(fX.x/fY.x, fX.y/fY.y); }\n\n// fCosChi = Pi/2\nD3DXVECTOR2 ChapmanOrtho(const D3DXVECTOR2 &f2x)\n{\n    static const float fConst = static_cast<float>( sqrt(D3DX_PI / 2) );\n    D3DXVECTOR2 f2SqrtX = D3DXVECTOR2( sqrt(f2x.x), sqrt(f2x.y) );\n    return fConst * ( D3DXVECTOR2(1.f,1.f) / (2.f * f2SqrtX) + f2SqrtX );\n}\n\n// |fCosChi| < Pi/2\nD3DXVECTOR2 f2ChapmanRising(const D3DXVECTOR2 &f2X, float fCosChi)\n{\n    D3DXVECTOR2 f2ChOrtho = ChapmanOrtho(f2X);\n    return f2ChOrtho / ((f2ChOrtho-D3DXVECTOR2(1,1))*fCosChi + D3DXVECTOR2(1,1));\n}\n\nD3DXVECTOR2 GetDensityIntegralFromChapmanFunc(float fHeightAboveSurface,\n                                         const D3DXVECTOR3 &f3EarthCentreToPointDir,\n                                         const D3DXVECTOR3 &f3RayDir,\n                                         const SAirScatteringAttribs &SctrMediaAttribs)\n{\n    // Note: there is no intersection test with the Earth. However,\n    // optical depth through the Earth is large, which effectively\n    // occludes the light\n    float fCosChi = D3DXVec3Dot(&f3EarthCentreToPointDir, &f3RayDir);\n    D3DXVECTOR2 f2x = (fHeightAboveSurface + SctrMediaAttribs.fEarthRadius) * D3DXVECTOR2(1.f / SctrMediaAttribs.f2ParticleScaleHeight.x, 1.f / SctrMediaAttribs.f2ParticleScaleHeight.y);\n    D3DXVECTOR2 f2VerticalAirMass = SctrMediaAttribs.f2ParticleScaleHeight * exp(-D3DXVECTOR2(fHeightAboveSurface,fHeightAboveSurface)/SctrMediaAttribs.f2ParticleScaleHeight);\n    if( fCosChi >= 0.f )\n    {\n        return f2VerticalAirMass * f2ChapmanRising(f2x, fCosChi);\n    }\n    else\n    {\n        float fSinChi = sqrt(1.f - fCosChi*fCosChi);\n        float fh0 = (fHeightAboveSurface + SctrMediaAttribs.fEarthRadius) * fSinChi - SctrMediaAttribs.fEarthRadius;\n        D3DXVECTOR2 f2VerticalAirMass0 = SctrMediaAttribs.f2ParticleScaleHeight * exp(-D3DXVECTOR2(fh0,fh0)/SctrMediaAttribs.f2ParticleScaleHeight);\n        D3DXVECTOR2 f2x0 = D3DXVECTOR2(fh0 + SctrMediaAttribs.fEarthRadius,fh0 + SctrMediaAttribs.fEarthRadius)/SctrMediaAttribs.f2ParticleScaleHeight;\n        D3DXVECTOR2 f2ChOrtho_x0 = ChapmanOrtho(f2x0);\n        D3DXVECTOR2 f2Ch = f2ChapmanRising(f2x, -fCosChi);\n        return f2VerticalAirMass0 * (2.f * f2ChOrtho_x0) - f2VerticalAirMass*f2Ch;\n    }\n}\n\nvoid CLightSctrPostProcess :: ComputeSunColor( const D3DXVECTOR3 &vDirectionOnSun,\n                                               const D3DXVECTOR4 &f4ExtraterrestrialSunColor,\n                                               D3DXVECTOR4 &f4SunColorAtGround,\n                                               D3DXVECTOR4 &f4AmbientLight)\n{\n\n    // Compute the ambient light values\n    float zenithFactor = min( max(vDirectionOnSun.y, 0.0f), 1.0f);\n    f4AmbientLight.x = zenithFactor*0.15f;\n    f4AmbientLight.y = zenithFactor*0.1f;\n    f4AmbientLight.z = max(0.005f, zenithFactor*0.25f);\n    f4AmbientLight.w = 0.0f;\n\n    D3DXVECTOR2 f2NetParticleDensityToAtmTop = GetDensityIntegralFromChapmanFunc(0, D3DXVECTOR3(0,1,0), vDirectionOnSun, m_MediaParams);\n\n\n    D3DXVECTOR3 f3RlghExtCoeff;\n    D3DXVec3Maximize(&f3RlghExtCoeff, (D3DXVECTOR3*)&m_MediaParams.f4RayleighExtinctionCoeff, &D3DXVECTOR3(1e-8f,1e-8f,1e-8f));\n    D3DXVECTOR3 f3RlghOpticalDepth = f3RlghExtCoeff * f2NetParticleDensityToAtmTop.x;\n    D3DXVECTOR3 f3MieExtCoeff;\n    D3DXVec3Maximize(&f3MieExtCoeff, (D3DXVECTOR3*)&m_MediaParams.f4MieExtinctionCoeff, &D3DXVECTOR3(1e-8f,1e-8f,1e-8f));\n    D3DXVECTOR3 f3MieOpticalDepth  = f3MieExtCoeff * f2NetParticleDensityToAtmTop.y;\n    D3DXVECTOR3 f3TotalExtinction = exp( -(f3RlghOpticalDepth + f3MieOpticalDepth ) );\n    const float fEarthReflectance = 0.1f;// See [BN08]\n    (D3DXVECTOR3&)f4SunColorAtGround = ((D3DXVECTOR3&)f4ExtraterrestrialSunColor) * f3TotalExtinction * fEarthReflectance;\n}\n\nvoid CLightSctrPostProcess :: ComputeScatteringCoefficients(ID3D11DeviceContext *pDeviceCtx)\n{\n    // For details, see \"A practical Analytic Model for Daylight\" by Preetham & Hoffman, p.23\n\n    // Wave lengths\n    // [BN08] follows [REK04] and gives the following values for Rayleigh scattering coefficients:\n    // RayleighBetha(lambda = (680nm, 550nm, 440nm) ) = (5.8, 13.5, 33.1)e-6\n    static const double dWaveLengths[] = \n    {\n        680e-9,     // red\n        550e-9,     // green\n        440e-9      // blue\n    }; \n        \n    // Calculate angular and total scattering coefficients for Rayleigh scattering:\n    {\n        D3DXVECTOR4 &f4AngularRayleighSctrCoeff = m_MediaParams.f4AngularRayleighSctrCoeff;\n        D3DXVECTOR4 &f4TotalRayleighSctrCoeff = m_MediaParams.f4TotalRayleighSctrCoeff;\n        D3DXVECTOR4 &f4RayleighExtinctionCoeff = m_MediaParams.f4RayleighExtinctionCoeff;\n    \n        double n = 1.0003;    // - Refractive index of air in the visible spectrum\n        double N = 2.545e+25; // - Number of molecules per unit volume\n        double Pn = 0.035;    // - Depolarization factor for air which exoresses corrections \n                              //   due to anisotropy of air molecules\n\n        double dRayleighConst = 8.0*D3DX_PI*D3DX_PI*D3DX_PI * (n*n - 1.0) * (n*n - 1.0) / (3.0 * N) * (6.0 + 3.0*Pn) / (6.0 - 7.0*Pn);\n        for(int WaveNum = 0; WaveNum < 3; WaveNum++)\n        {\n            double dSctrCoeff;\n            if( m_PostProcessingAttribs.m_bUseCustomSctrCoeffs )\n                dSctrCoeff = f4TotalRayleighSctrCoeff[WaveNum] = m_PostProcessingAttribs.m_f4CustomRlghBeta[WaveNum];\n            else\n            {\n                double Lambda2 = dWaveLengths[WaveNum] * dWaveLengths[WaveNum];\n                double Lambda4 = Lambda2 * Lambda2;\n                dSctrCoeff = dRayleighConst / Lambda4;\n                // Total Rayleigh scattering coefficient is the integral of angular scattering coefficient in all directions\n                f4TotalRayleighSctrCoeff[WaveNum] = static_cast<float>( dSctrCoeff );\n            }\n            // Angular scattering coefficient is essentially volumetric scattering coefficient multiplied by the\n            // normalized phase function\n            // p(Theta) = 3/(16*Pi) * (1 + cos^2(Theta))\n            // f4AngularRayleighSctrCoeff contains all the terms exepting 1 + cos^2(Theta):\n            f4AngularRayleighSctrCoeff[WaveNum] = static_cast<float>( 3.0 / (16.0*D3DX_PI) * dSctrCoeff );\n            // f4AngularRayleighSctrCoeff[WaveNum] = f4TotalRayleighSctrCoeff[WaveNum] * p(Theta)\n        }\n        // Air molecules do not absorb light, so extinction coefficient is only caused by out-scattering\n        f4RayleighExtinctionCoeff = f4TotalRayleighSctrCoeff;\n    }\n\n    // Calculate angular and total scattering coefficients for Mie scattering:\n    {\n        D3DXVECTOR4 &f4AngularMieSctrCoeff = m_MediaParams.f4AngularMieSctrCoeff;\n        D3DXVECTOR4 &f4TotalMieSctrCoeff = m_MediaParams.f4TotalMieSctrCoeff;\n        D3DXVECTOR4 &f4MieExtinctionCoeff = m_MediaParams.f4MieExtinctionCoeff;\n        \n        if( m_PostProcessingAttribs.m_bUseCustomSctrCoeffs )\n        {\n            f4TotalMieSctrCoeff = m_PostProcessingAttribs.m_f4CustomMieBeta * m_PostProcessingAttribs.m_fAerosolDensityScale;\n        }\n        else\n        {\n            const bool bUsePreethamMethod = false;\n            if( bUsePreethamMethod )\n            {\n                // Values for K came from the table 2 in the \"A practical Analytic Model \n                // for Daylight\" by Preetham & Hoffman, p.28\n                double K[] = \n                { \n                    0.68455,                //  K[650nm]\n                    0.678781,               //  K[570nm]\n                    (0.668532+0.669765)/2.0 // (K[470nm]+K[480nm])/2\n                };\n\n                assert( m_MediaParams.fTurbidity >= 1.f );\n        \n                // Beta is an Angstrom's turbidity coefficient and is approximated by:\n                //float beta = 0.04608365822050f * m_fTurbidity - 0.04586025928522f; ???????\n\n                double c = (0.6544*m_MediaParams.fTurbidity - 0.6510)*1E-16; // concentration factor\n                const double v = 4; // Junge's exponent\n        \n                double dTotalMieBetaTerm = 0.434 * c * D3DX_PI * pow(2.0*D3DX_PI, v-2);\n\n                for(int WaveNum = 0; WaveNum < 3; WaveNum++)\n                {\n                    double Lambdav_minus_2 = pow( dWaveLengths[WaveNum], v-2);\n                    double dTotalMieSctrCoeff = dTotalMieBetaTerm * K[WaveNum] / Lambdav_minus_2;\n                    f4TotalMieSctrCoeff[WaveNum]   = static_cast<float>( dTotalMieSctrCoeff );\n                }\n            \n                //AtmScatteringAttribs.f4AngularMieSctrCoeff *= 0.02f;\n                //AtmScatteringAttribs.f4TotalMieSctrCoeff *= 0.02f;\n            }\n            else\n            {\n                // [BN08] uses the following value (independent of wavelength) for Mie scattering coefficient: 2e-5\n                // For g=0.76 and MieBetha=2e-5 [BN08] was able to reproduce the same luminance as given by the \n                // reference CIE sky light model \n                const float fMieBethaBN08 = 2e-5f * m_PostProcessingAttribs.m_fAerosolDensityScale;\n                m_MediaParams.f4TotalMieSctrCoeff = D3DXVECTOR4(fMieBethaBN08, fMieBethaBN08, fMieBethaBN08, 0);\n            }\n        }\n\n        for(int WaveNum = 0; WaveNum < 3; WaveNum++)\n        {\n            // Normalized to unity Cornette-Shanks phase function has the following form:\n            // F(theta) = 1/(4*PI) * 3*(1-g^2) / (2*(2+g^2)) * (1+cos^2(theta)) / (1 + g^2 - 2g*cos(theta))^(3/2)\n            // The angular scattering coefficient is the volumetric scattering coefficient multiplied by the phase \n            // function. 1/(4*PI) is baked into the f4AngularMieSctrCoeff, the other terms are baked into f4CS_g\n            f4AngularMieSctrCoeff[WaveNum] = f4TotalMieSctrCoeff[WaveNum]  / static_cast<float>(4.0 * D3DX_PI);\n            // [BN08] also uses slight absorption factor which is 10% of scattering\n            f4MieExtinctionCoeff[WaveNum] = f4TotalMieSctrCoeff[WaveNum] * (1.f + m_PostProcessingAttribs.m_fAerosolAbsorbtionScale);\n        }\n    }\n    \n    {\n        // For g=0.76 and MieBetha=2e-5 [BN08] was able to reproduce the same luminance as is given by the \n        // reference CIE sky light model \n        // Cornette phase function (see Nishita et al. 93):\n        // F(theta) = 1/(4*PI) * 3*(1-g^2) / (2*(2+g^2)) * (1+cos^2(theta)) / (1 + g^2 - 2g*cos(theta))^(3/2)\n        // 1/(4*PI) is baked into the f4AngularMieSctrCoeff\n        D3DXVECTOR4 &f4CS_g = m_MediaParams.f4CS_g;\n        float f_g = m_MediaParams.m_fAerosolPhaseFuncG;\n        f4CS_g.x = 3*(1.f - f_g*f_g) / ( 2*(2.f + f_g*f_g) );\n        f4CS_g.y = 1.f + f_g*f_g;\n        f4CS_g.z = -2.f*f_g;\n        f4CS_g.w = 1.f;\n    }\n\n    m_MediaParams.f4TotalExtinctionCoeff = m_MediaParams.f4RayleighExtinctionCoeff + m_MediaParams.f4MieExtinctionCoeff;\n\n    if( pDeviceCtx && m_pcbMediaAttribs )\n    {\n        pDeviceCtx->UpdateSubresource(m_pcbMediaAttribs, 0, NULL, &m_MediaParams, 0, 0);\n    }\n}\n\nvoid CLightSctrPostProcess :: RenderSun(SFrameAttribs &FrameAttribs)\n{\n    if( FrameAttribs.pLightAttribs->f4LightScreenPos.w <= 0 )\n        return;\n\n    if( !m_RenderSunTech.IsValid() )\n    {\n        m_RenderSunTech.SetDeviceAndContext(FrameAttribs.pd3dDevice, FrameAttribs.pd3dDeviceContext);\n        m_RenderSunTech.CreateVGPShadersFromFile( m_strEffectPath, \"SunVS\", nullptr, \"SunPS\", nullptr );\n        m_RenderSunTech.SetDS( m_pEnableDepthCmpEqDS );\n        m_RenderSunTech.SetRS( m_pSolidFillNoCullRS );\n        m_RenderSunTech.SetBS( m_pDefaultBS );\n    }\n\n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(1, &FrameAttribs.ptex2DSrcColorBufferRTV, FrameAttribs.ptex2DSrcDepthBufferDSV);\n    RenderQuad( FrameAttribs.pd3dDeviceContext, m_RenderSunTech);\n    \n    FrameAttribs.pd3dDeviceContext->OMSetRenderTargets(0, NULL, NULL);\n}\n\nvoid CLightSctrPostProcess :: CreateAmbientSkyLightTexture(ID3D11Device *pDevice, ID3D11DeviceContext *pContext)\n{\n    CRenderTechnique PrecomputeAmbientSkyLightTech;\n    PrecomputeAmbientSkyLightTech.SetDeviceAndContext(pDevice, pContext);\n    CD3DShaderMacroHelper Macros;\n    Macros.AddShaderMacro( \"NUM_RANDOM_SPHERE_SAMPLES\", sm_iNumRandomSamplesOnSphere );\n    Macros.Finalize();\n    PrecomputeAmbientSkyLightTech.CreatePixelShaderFromFile( m_strEffectPath, \"PrecomputeAmbientSkyLightPS\", Macros );\n    PrecomputeAmbientSkyLightTech.SetVS( m_pGenerateScreenSizeQuadVS );\n    PrecomputeAmbientSkyLightTech.SetDS( m_pDisableDepthTestDS, 0 );\n    PrecomputeAmbientSkyLightTech.SetRS( m_pSolidFillNoCullRS );\n    PrecomputeAmbientSkyLightTech.SetBS( m_pDefaultBS );\n\n    D3D11_TEXTURE2D_DESC AmbientSkyLightTexDesc = \n    {\n        sm_iAmbientSkyLightTexDim,          //UINT Width;\n        1,                                  //UINT Height;\n        1,                                  //UINT MipLevels;\n        1,                                  //UINT ArraySize;\n        DXGI_FORMAT_R16G16B16A16_FLOAT,     //DXGI_FORMAT Format;\n        {1,0},                              //DXGI_SAMPLE_DESC SampleDesc;\n        D3D11_USAGE_DEFAULT,                //D3D11_USAGE Usage;\n        D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,           //UINT BindFlags;\n        0,                                  //UINT CPUAccessFlags;\n        0,                                  //UINT MiscFlags;\n    };\n\n    m_ptex2DAmbientSkyLightSRV.Release();\n    m_ptex2DAmbientSkyLightRTV.Release();\n    CComPtr<ID3D11Texture2D> ptex2DAmbientSkyLight;\n    // Create 2-D texture, shader resource and target view buffers on the device\n    HRESULT hr;\n    V( pDevice->CreateTexture2D( &AmbientSkyLightTexDesc, NULL, &ptex2DAmbientSkyLight) );\n    V( pDevice->CreateShaderResourceView( ptex2DAmbientSkyLight, NULL, &m_ptex2DAmbientSkyLightSRV)  );\n    V( pDevice->CreateRenderTargetView( ptex2DAmbientSkyLight, NULL, &m_ptex2DAmbientSkyLightRTV)  );\n    \n    CComPtr<ID3D11RenderTargetView> pOrigRTV;\n    CComPtr<ID3D11DepthStencilView> pOrigDSV;\n    pContext->OMGetRenderTargets(1, &pOrigRTV, &pOrigDSV);\n\n    D3D11_VIEWPORT OrigViewPort;\n    UINT iNumOldViewports = 1;\n    pContext->RSGetViewports(&iNumOldViewports, &OrigViewPort);\n\n    ID3D11Buffer *pCBs[] = {m_pcbPostProcessingAttribs, m_pcbMediaAttribs};\n    pContext->VSSetConstantBuffers(0, _countof(pCBs), pCBs);\n    pContext->PSSetConstantBuffers(0, _countof(pCBs), pCBs);\n\n    ID3D11SamplerState *pSamplers[] = { m_psamLinearClamp, m_psamLinearBorder0, m_psamComparison, m_psamPointClamp };\n    pContext->PSSetSamplers(0, _countof(pSamplers), pSamplers);\n\n    if( !m_ptex2DOccludedNetDensityToAtmTopSRV )\n    {\n        CreatePrecomputedOpticalDepthTexture(pDevice, pContext);\n    }\n    \n    if( !m_ptex3DSingleScatteringSRV )\n    {\n        CreatePrecomputedScatteringLUT(pDevice, pContext);\n    }\n\n    ID3D11ShaderResourceView *pSRVs[2] = {m_ptex3DMultipleScatteringSRV, m_ptex2DSphereRandomSamplingSRV};\n    pContext->PSSetShaderResources(0, _countof(pSRVs), pSRVs);            \n\n    pContext->OMSetRenderTargets(1, &m_ptex2DAmbientSkyLightRTV.p, nullptr);\n    RenderQuad( pContext, PrecomputeAmbientSkyLightTech, sm_iAmbientSkyLightTexDim, 1);\n\n    pContext->RSSetViewports(iNumOldViewports, &OrigViewPort);\n    pContext->OMSetRenderTargets(1, &pOrigRTV.p, pOrigDSV);\n}\n\nID3D11ShaderResourceView* CLightSctrPostProcess :: GetAmbientSkyLightSRV(ID3D11Device *pDevice, ID3D11DeviceContext *pContext)\n{\n    if( !m_ptex2DAmbientSkyLightSRV )\n    {\n        CreateAmbientSkyLightTexture(pDevice, pContext);\n    }\n\n    return m_ptex2DAmbientSkyLightSRV;\n}\n"
  },
  {
    "path": "LightSctrPostProcess.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#pragma once\n\n#include <D3DX11.h>\n#include <D3DX10math.h>\n\n#include \"RenderTechnique.h\"\n\n#include \"structures.fxh\"\nstruct SFrameAttribs\n{\n    ID3D11Device *pd3dDevice;\n    ID3D11DeviceContext *pd3dDeviceContext;\n    \n    double dElapsedTime;\n\n    SLightAttribs *pLightAttribs;\n    ID3D11Buffer *pcbLightAttribs;\n\n    SCameraAttribs CameraAttribs;\n    \n    ID3D11ShaderResourceView *ptex2DSrcColorBufferSRV;\n    ID3D11RenderTargetView   *ptex2DSrcColorBufferRTV;\n    ID3D11DepthStencilView   *ptex2DSrcDepthBufferDSV;\n    ID3D11ShaderResourceView *ptex2DSrcDepthBufferSRV;\n    ID3D11ShaderResourceView *ptex2DShadowMapSRV;\n    ID3D11RenderTargetView *pDstRTV;\n};\n\n#undef float4\n#undef float3\n#undef float2\n\n#include <atlcomcli.h>\n\nclass CLightSctrPostProcess\n{\npublic:\n    CLightSctrPostProcess();\n    ~CLightSctrPostProcess();\n\n    HRESULT OnCreateDevice(ID3D11Device* in_pd3dDevice, \n                           ID3D11DeviceContext *in_pd3dDeviceContext);\n    void OnDestroyDevice();\n\n\n    HRESULT OnResizedSwapChain(ID3D11Device* pd3dDevice, UINT uiBackBufferWidth, UINT uiBackBufferHeight);\n\n    void PerformPostProcessing(SFrameAttribs &FrameAttribs,\n                               SPostProcessingAttribs &PPAttribs);\n\n    void ComputeSunColor(const D3DXVECTOR3 &vDirectionOnSun,\n                         const D3DXVECTOR4 &f4ExtraterrestrialSunColor,\n                         D3DXVECTOR4 &f4SunColorAtGround,\n                         D3DXVECTOR4 &f4AmbientLight);\n    \n    void RenderSun(SFrameAttribs &FrameAttribs);\n    ID3D11Buffer *GetMediaAttribsCB(){return m_pcbMediaAttribs;}\n    ID3D11ShaderResourceView* GetPrecomputedNetDensitySRV(){return m_ptex2DOccludedNetDensityToAtmTopSRV;}\n    ID3D11ShaderResourceView* GetAmbientSkyLightSRV(ID3D11Device *pDevice, ID3D11DeviceContext *pContext);\n\nprivate:\n    void ReconstructCameraSpaceZ(SFrameAttribs &FrameAttribs);\n    void RenderSliceEndpoints(SFrameAttribs &FrameAttribs);\n    void RenderCoordinateTexture(SFrameAttribs &FrameAttribs);\n    void RenderCoarseUnshadowedInctr(SFrameAttribs &FrameAttribs);\n    void RefineSampleLocations(SFrameAttribs &FrameAttribs);\n    void MarkRayMarchingSamples(SFrameAttribs &FrameAttribs);\n    void RenderSliceUVDirAndOrig(SFrameAttribs &FrameAttribs);\n    void Build1DMinMaxMipMap(SFrameAttribs &FrameAttribs, int iCascadeIndex);\n    void DoRayMarching(SFrameAttribs &FrameAttribs, UINT uiMaxStepsAlongRay, const SShadowMapAttribs &SMAttribs, int iCascadeIndex);\n    void InterpolateInsctrIrradiance(SFrameAttribs &FrameAttribs);\n    void UnwarpEpipolarScattering(SFrameAttribs &FrameAttribs, bool bRenderLuminance);\n    void UpdateAverageLuminance(SFrameAttribs &FrameAttribs);\n    void FixInscatteringAtDepthBreaks(SFrameAttribs &FrameAttribs, UINT uiMaxStepsAlongRay, const SShadowMapAttribs &SMAttribs, bool bRenderLuminance);\n    void RenderSampleLocations(SFrameAttribs &FrameAttribs);\n    HRESULT CreatePrecomputedOpticalDepthTexture(ID3D11Device *pDevice, ID3D11DeviceContext *pContext);\n    HRESULT CreatePrecomputedScatteringLUT(ID3D11Device *pDevice, ID3D11DeviceContext *pContext);\n    void CreateRandomSphereSamplingTexture(ID3D11Device *pDevice);\n    void CreateLowResLuminanceTexture(ID3D11Device *pDevice);\n    void CreateAmbientSkyLightTexture(ID3D11Device *pDevice, ID3D11DeviceContext *pContext);\n\n    void DefineMacros(class CD3DShaderMacroHelper &Macros);\n    \n    SPostProcessingAttribs m_PostProcessingAttribs;\n    bool m_bUseCombinedMinMaxTexture;\n    UINT m_uiSampleRefinementCSThreadGroupSize;\n    UINT m_uiSampleRefinementCSMinimumThreadGroupSize;\n\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DSliceEndpointsSRV;\n    CComPtr<ID3D11RenderTargetView> m_ptex2DSliceEndpointsRTV;\n\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DCoordinateTextureSRV;\n    CComPtr<ID3D11RenderTargetView> m_ptex2DCoordinateTextureRTV;\n    CComPtr<ID3D11DepthStencilView> m_ptex2DEpipolarImageDSV;\n\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DEpipolarCamSpaceZSRV;\n    CComPtr<ID3D11RenderTargetView> m_ptex2DEpipolarCamSpaceZRTV;\n\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DInterpolationSourcesSRV;\n    CComPtr<ID3D11UnorderedAccessView> m_ptex2DInterpolationSourcesUAV;\n\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DInitialScatteredLightSRV;\n    CComPtr<ID3D11RenderTargetView> m_ptex2DInitialScatteredLightRTV;\n\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DEpipolarInscatteringSRV, m_ptex2DEpipolarExtinctionSRV;\n    CComPtr<ID3D11RenderTargetView> m_ptex2DEpipolarInscatteringRTV, m_ptex2DEpipolarExtinctionRTV;\n\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DCameraSpaceZSRV;\n    CComPtr<ID3D11RenderTargetView> m_ptex2DCameraSpaceZRTV;\n    \n    CComPtr<ID3D11ShaderResourceView> m_ptex2DSliceUVDirAndOriginSRV;\n    CComPtr<ID3D11RenderTargetView> m_ptex2DSliceUVDirAndOriginRTV;\n\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DMinMaxShadowMapSRV[2];\n    CComPtr<ID3D11RenderTargetView> m_ptex2DMinMaxShadowMapRTV[2];\n\n    static const int sm_iNumPrecomputedHeights = 1024;\n    static const int sm_iNumPrecomputedAngles = 1024;\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DOccludedNetDensityToAtmTopSRV;\n    CComPtr<ID3D11RenderTargetView>   m_ptex2DOccludedNetDensityToAtmTopRTV;\n\n    \n    static const int sm_iPrecomputedSctrUDim = 32;\n    static const int sm_iPrecomputedSctrVDim = 128;\n    static const int sm_iPrecomputedSctrWDim = 64;\n    static const int sm_iPrecomputedSctrQDim = 16;\n    CComPtr<ID3D11ShaderResourceView> m_ptex3DSingleScatteringSRV;\n    CComPtr<ID3D11ShaderResourceView> m_ptex3DHighOrderScatteringSRV;\n    CComPtr<ID3D11ShaderResourceView> m_ptex3DMultipleScatteringSRV;\n    \n    static const int sm_iNumRandomSamplesOnSphere = 128;\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DSphereRandomSamplingSRV;\n\n    HRESULT CreateTextures(ID3D11Device* pd3dDevice);\n    HRESULT CreateMinMaxShadowMap(ID3D11Device* pd3dDevice);\n    CComPtr<ID3D11DepthStencilView> m_ptex2DScreenSizeDSV;\n\n    static const int sm_iLowResLuminanceMips = 7; // 64x64\n    CComPtr<ID3D11RenderTargetView> m_ptex2DLowResLuminanceRTV;\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DLowResLuminanceSRV;\n    \n    CComPtr<ID3D11RenderTargetView> m_ptex2DAverageLuminanceRTV;\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DAverageLuminanceSRV;\n\n    static const int sm_iAmbientSkyLightTexDim = 1024;\n    CComPtr<ID3D11RenderTargetView> m_ptex2DAmbientSkyLightRTV;\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DAmbientSkyLightSRV;\n\n    UINT m_uiBackBufferWidth, m_uiBackBufferHeight;\n\n    LPCTSTR m_strEffectPath;\n\n    CComPtr<ID3D11VertexShader> m_pGenerateScreenSizeQuadVS;\n\n    CRenderTechnique m_ReconstrCamSpaceZTech;\n    CRenderTechnique m_RendedSliceEndpointsTech;\n    CRenderTechnique m_RendedCoordTexTech;\n    CRenderTechnique m_RefineSampleLocationsTech;\n    CRenderTechnique m_RenderCoarseUnshadowedInsctrTech;\n    CRenderTechnique m_MarkRayMarchingSamplesInStencilTech;\n    CRenderTechnique m_RenderSliceUVDirInSMTech;\n    CRenderTechnique m_InitializeMinMaxShadowMapTech;\n    CRenderTechnique m_ComputeMinMaxSMLevelTech;\n    CRenderTechnique m_DoRayMarchTech[2]; // 0 - min/max optimization disabled; 1 - min/max optimization enabled\n    CRenderTechnique m_InterpolateIrradianceTech;\n    CRenderTechnique m_UnwarpEpipolarSctrImgTech;\n    CRenderTechnique m_UnwarpAndRenderLuminanceTech;\n    CRenderTechnique m_UpdateAverageLuminanceTech;\n    CRenderTechnique m_FixInsctrAtDepthBreaksTech[4]; // bit 0: 0 - perform ray marching, 1 - perform ray marching and attenuate background\n                                                      // bit 1: 0 - perform tone mapping, 1 - render luminance only\n    CRenderTechnique m_RenderSampleLocationsTech;\n    CRenderTechnique m_RenderSunTech;\n    CRenderTechnique m_PrecomputeSingleSctrTech;\n    CRenderTechnique m_ComputeSctrRadianceTech;\n    CRenderTechnique m_ComputeScatteringOrderTech;\n    CRenderTechnique m_AddScatteringOrderTech;\n\n    CComPtr<ID3D11SamplerState> m_psamLinearClamp;\n    CComPtr<ID3D11SamplerState> m_psamLinearBorder0;\n    CComPtr<ID3D11SamplerState> m_psamComparison;\n    CComPtr<ID3D11SamplerState> m_psamPointClamp;\n\n    CComPtr<ID3D11DepthStencilState> m_pEnableDepthCmpEqDS;\n    CComPtr<ID3D11DepthStencilState> m_pDisableDepthTestDS;\n    CComPtr<ID3D11DepthStencilState> m_pDisableDepthTestIncrStencilDS;\n    CComPtr<ID3D11DepthStencilState> m_pNoDepth_StEqual_IncrStencilDS;\n    CComPtr<ID3D11DepthStencilState> m_pNoDepth_StEqual_KeepStencilDS;\n\n    CComPtr<ID3D11RasterizerState> m_pSolidFillNoCullRS;\n\n    CComPtr<ID3D11BlendState> m_pDefaultBS, m_pAdditiveBlendBS, m_pAlphaBlendBS;\n\n    void ComputeScatteringCoefficients(ID3D11DeviceContext *pDeviceCtx = NULL);\n    \n    const float m_fTurbidity;\n    SAirScatteringAttribs m_MediaParams;\n\n    CComPtr<ID3D11Buffer> m_pcbCameraAttribs;\n    CComPtr<ID3D11Buffer> m_pcbPostProcessingAttribs;\n    CComPtr<ID3D11Buffer> m_pcbMediaAttribs;\n    CComPtr<ID3D11Buffer> m_pcbMiscParams;\n};\n"
  },
  {
    "path": "OutdoorLightScattering.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"stdafx.h\"\n#include \"OutdoorLightScattering.h\"\n#include \"LightSctrPostProcess.h\"\n#include <iomanip>\n#include \"CPUTBufferDX11.h\"\n#include <Commdlg.h>\n\n// important to use the right CPUT namespace\n\nvoid UpdateConstantBuffer(ID3D11DeviceContext *pDeviceCtx, ID3D11Buffer *pCB, const void *pData, size_t DataSize);\n\nclass CParallelLightCamera : public CPUTCamera\n{\npublic:\n    virtual void Update( float deltaSeconds=0.0f ) {\n        mView = inverse(*GetWorldMatrix());\n    };\n};\n\n// Constructor\n//-----------------------------------------------------------------------------\nCOutdoorLightScatteringSample::COutdoorLightScatteringSample() : \n    mpCameraController(NULL),\n    m_pLightController(NULL),\n    m_uiShadowMapResolution( 1024 ),\n    m_fCascadePartitioningFactor(0.95f),\n    m_bEnableLightScattering(true),\n    m_bAnimateSun(false),\n    m_pOffscreenRenderTarget(NULL),\n    m_pOffscreenDepth(NULL),\n    m_fScatteringScale(0.5f),\n    m_f4LightColor(1.f, 1.f, 1.f, 1.f),\n    m_iGUIMode(1),\n    m_uiBackBufferWidth(0), \n    m_uiBackBufferHeight(0),\n    m_uiSelectedPanelInd(0),\n    m_CameraPos(0,0,0)\n{\n    m_pLightSctrPP = new CLightSctrPostProcess;\n}\n\n// Destructor\n//-----------------------------------------------------------------------------\nCOutdoorLightScatteringSample::~COutdoorLightScatteringSample()\n{\n    Destroy();\n\n    SAFE_DELETE( m_pLightSctrPP );\n}\n\nvoid COutdoorLightScatteringSample::Destroy()\n{\n    m_EarthHemisphere.OnD3D11DestroyDevice();\n\n    ReleaseShadowMap();\n    ReleaseTmpBackBuffAndDepthBuff();\n\n    m_pLightSctrPP->OnDestroyDevice();\n\n    SAFE_RELEASE(m_pDirectionalLightCamera);\n    SAFE_RELEASE(m_pDirLightOrienationCamera);\n    \n    SAFE_RELEASE(mpCamera);\n    SAFE_DELETE( mpCameraController);\n\n    SAFE_DELETE( m_pLightController);\n    m_pcbLightAttribs.Release();\n}\n\n// Handle keyboard events\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode COutdoorLightScatteringSample::HandleKeyboardEvent(CPUTKey key)\n{\n    CPUTEventHandledCode    handled = CPUT_EVENT_UNHANDLED;\n    CPUTGuiControllerDX11*      pGUI = CPUTGetGuiController(); \n    cString filename;\n\n    switch(key)\n    {\n    case KEY_F1:\n        ++m_iGUIMode;\n        if( m_iGUIMode>2 )\n            m_iGUIMode = 0;\n        if(m_iGUIMode==1)\n            pGUI->SetActivePanel(CONTROL_PANEL_IDS[m_uiSelectedPanelInd]);\n        else if(m_iGUIMode==2)\n            pGUI->SetActivePanel(ID_HELP_TEXT_PANEL);\n        handled = CPUT_EVENT_HANDLED;\n        break;\n    \n    case KEY_ESCAPE:\n        handled = CPUT_EVENT_HANDLED;\n        Shutdown();\n        break;\n    }\n\n    if((handled == CPUT_EVENT_UNHANDLED) && mpCameraController)\n    {\n        handled = mpCameraController->HandleKeyboardEvent(key);\n    }\n\n    if((handled == CPUT_EVENT_UNHANDLED) && m_pLightController)\n    {\n        handled = m_pLightController->HandleKeyboardEvent(key);\n    }\n\n    return handled;\n}\n\n// Handle mouse events\n//-----------------------------------------------------------------------------\nCPUTEventHandledCode COutdoorLightScatteringSample::HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state)\n{\n    CPUTEventHandledCode handled = CPUT_EVENT_UNHANDLED;\n    if( mpCameraController )\n    {\n        handled = mpCameraController->HandleMouseEvent(x,y,wheel, state);\n    }\n    if( (handled == CPUT_EVENT_UNHANDLED) && m_pLightController )\n    {\n        handled = m_pLightController->HandleMouseEvent(x,y,wheel, state);\n    }\n    return handled;\n}\n\nbool SelectColor(D3DXVECTOR4 &f4Color)\n{\n    // Create an initial color from the current value\n    COLORREF InitColor = RGB( f4Color.x * 255.f, f4Color.y * 255.f, f4Color.z * 255.f );\n    COLORREF CustomColors[16];\n    // Now create a choose color structure with the original color as the default\n    CHOOSECOLOR ChooseColorInitStruct;\n    ZeroMemory( &ChooseColorInitStruct, sizeof(ChooseColorInitStruct));\n    CPUTOSServices::GetOSServices()->GetWindowHandle( &ChooseColorInitStruct.hwndOwner );\n    ChooseColorInitStruct.lStructSize = sizeof(ChooseColorInitStruct);\n    ChooseColorInitStruct.rgbResult = InitColor;\n    ChooseColorInitStruct.Flags = CC_ANYCOLOR | CC_FULLOPEN | CC_RGBINIT;\n    ChooseColorInitStruct.lpCustColors = CustomColors;\n    // Display a color selection dialog box and if the user does not cancel, select a color\n    if( ChooseColor( &ChooseColorInitStruct ) && ChooseColorInitStruct.rgbResult != 0)\n    {\n        // Get the new color\n        COLORREF NewColor = ChooseColorInitStruct.rgbResult;\n        f4Color.x = (float)(NewColor&0x0FF) / 255.f;\n        f4Color.y = (float)((NewColor>>8)&0x0FF) / 255.f;\n        f4Color.z = (float)((NewColor>>16)&0x0FF) / 255.f;\n        f4Color.w = 0;\n        return true;\n    }\n\n    return false;\n}\n\n// Handle any control callback events\n//-----------------------------------------------------------------------------\nvoid COutdoorLightScatteringSample::HandleCallbackEvent( CPUTEventID Event, CPUTControlID ControlID, CPUTControl* pControl )\n{\n    cString SelectedItem;\n    CPUTGuiControllerDX11*  pGUI            = CPUTGetGuiController();   \n    switch(ControlID)\n    {\n    case ID_SELECT_PANEL_COMBO:\n        {\n            CPUTDropdown* pDropDown = static_cast<CPUTDropdown*>(pControl);\n            pDropDown->GetSelectedItem(m_uiSelectedPanelInd);\n            for(int i = 0; i < _countof(m_pSelectPanelDropDowns); ++i)\n                m_pSelectPanelDropDowns[i]->SetSelectedItem(m_uiSelectedPanelInd+1);\n            pGUI->SetActivePanel(CONTROL_PANEL_IDS[m_uiSelectedPanelInd]);\n            break;\n        }\n\n    case ID_FULLSCREEN_BUTTON:\n        CPUTToggleFullScreenMode();\n        pGUI->GetControl(ID_RLGH_COLOR_BTN)->SetEnable(!CPUTGetFullscreenState() && m_PPAttribs.m_bUseCustomSctrCoeffs);\n        pGUI->GetControl(ID_MIE_COLOR_BTN)->SetEnable(!CPUTGetFullscreenState() && m_PPAttribs.m_bUseCustomSctrCoeffs);\n        break;\n    \n    case ID_ENABLE_VSYNC:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            mSyncInterval = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED ? 1 : 0;\n            break;\n        }\n    \n    case ID_ENABLE_LIGHT_SCATTERING:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_bEnableLightScattering = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_ANIMATE_SUN:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_bAnimateSun = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_ENABLE_LIGHT_SHAFTS:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bEnableLightShafts = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            pGUI->GetControl(ID_NUM_INTEGRATION_STEPS)->SetEnable(!m_PPAttribs.m_bEnableLightShafts && m_PPAttribs.m_uiSingleScatteringMode == SINGLE_SCTR_MODE_INTEGRATION);\n            break;\n        }\n\n    case ID_LIGHT_SCTR_TECHNIQUE:\n        {\n            CPUTDropdown* pDropDown = static_cast<CPUTDropdown*>(pControl);\n            UINT uiSelectedItem;\n            pDropDown->GetSelectedItem(uiSelectedItem);\n            m_PPAttribs.m_uiLightSctrTechnique = uiSelectedItem;\n            bool bIsEpipolarSampling = m_PPAttribs.m_uiLightSctrTechnique == LIGHT_SCTR_TECHNIQUE_EPIPOLAR_SAMPLING;\n            pGUI->GetControl(ID_NUM_EPIPOLAR_SLICES)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_NUM_SAMPLES_IN_EPIPOLAR_SLICE)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_INITIAL_SAMPLE_STEP_IN_EPIPOLAR_SLICE)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_EPIPOLE_SAMPLING_DENSITY_FACTOR)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_REFINEMENT_THRESHOLD)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_MIN_MAX_SHADOW_MAP_OPTIMIZATION)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_OPTIMIZE_SAMPLE_LOCATIONS)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_SHOW_SAMPLING)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_CORRECT_SCATTERING_AT_DEPTH_BREAKS)->SetEnable(bIsEpipolarSampling);\n            pGUI->GetControl(ID_SHOW_DEPTH_BREAKS)->SetEnable(bIsEpipolarSampling);\n            break;\n        }\n\n    case ID_SHADOW_MAP_RESOLUTION:\n        {\n            CPUTDropdown* pDropDown = static_cast<CPUTDropdown*>(pControl);\n            UINT uiSelectedItem;\n            pDropDown->GetSelectedItem(uiSelectedItem);\n            // uiSelectedItem is 1-based\n            m_uiShadowMapResolution = 512 << uiSelectedItem;\n            CreateShadowMap(mpD3dDevice);\n            break;\n        }\n\n    case ID_NUM_EPIPOLAR_SLICES:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            float fSliderVal;\n            pSlider->GetValue(fSliderVal);\n            m_PPAttribs.m_uiNumEpipolarSlices = 1 << (int)fSliderVal;\n            std::wstringstream NumSlicesSS;\n            NumSlicesSS << \"Epipolar slices: \" << m_PPAttribs.m_uiNumEpipolarSlices;\n            pSlider->SetText( NumSlicesSS.str().c_str() );\n            break;\n        }\n    \n    case ID_NUM_INTEGRATION_STEPS:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            float fSliderVal;\n            pSlider->GetValue(fSliderVal);\n            m_PPAttribs.m_uiInstrIntegralSteps = (int)fSliderVal;\n            std::wstringstream NumStepsSS;\n            NumStepsSS << \"Num integration steps: \" << m_PPAttribs.m_uiInstrIntegralSteps;\n            pSlider->SetText( NumStepsSS.str().c_str() );\n            break;\n        }\n\n    case ID_NUM_SAMPLES_IN_EPIPOLAR_SLICE:\n        {\n            CPUTSlider* pNumSamplesSlider = static_cast<CPUTSlider*>(pControl);\n            float fSliderVal;\n            pNumSamplesSlider->GetValue(fSliderVal);\n            m_PPAttribs.m_uiMaxSamplesInSlice = 1 << (int)fSliderVal;\n            std::wstringstream NumSamplesSS;\n            NumSamplesSS << \"Total samples in slice: \" << m_PPAttribs.m_uiMaxSamplesInSlice;\n            pNumSamplesSlider->SetText( NumSamplesSS.str().c_str() );\n\n            {\n                CPUTSlider* pInitialSamplesSlider = static_cast<CPUTSlider*>(pGUI->GetControl(ID_INITIAL_SAMPLE_STEP_IN_EPIPOLAR_SLICE));\n                unsigned long ulStartVal=0, ulEndVal, ulCurrVal;\n                BitScanForward(&ulEndVal, m_PPAttribs.m_uiMaxSamplesInSlice / m_iMinInitialSamplesInEpipolarSlice);\n                pInitialSamplesSlider->SetScale( (float)ulStartVal, (float)ulEndVal, ulEndVal-ulStartVal+1 );\n                if( m_PPAttribs.m_uiInitialSampleStepInSlice > (1u<<ulEndVal) )\n                {\n                    m_PPAttribs.m_uiInitialSampleStepInSlice = 1 << ulEndVal;\n                    std::wstringstream InitialSamplesStepSS;\n                    InitialSamplesStepSS << \"Initial sample step: \" << m_PPAttribs.m_uiInitialSampleStepInSlice;\n                    pInitialSamplesSlider->SetText( InitialSamplesStepSS.str().c_str() );\n                }\n                BitScanForward(&ulCurrVal, m_PPAttribs.m_uiInitialSampleStepInSlice);\n                pInitialSamplesSlider->SetValue( (float)ulCurrVal );\n            }\n            break;\n        }\n\n    case ID_INITIAL_SAMPLE_STEP_IN_EPIPOLAR_SLICE:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            float fSliderVal;\n            pSlider->GetValue(fSliderVal);\n            m_PPAttribs.m_uiInitialSampleStepInSlice = 1 << (int)fSliderVal;\n            std::wstringstream InitialSamplesStepSS;\n            InitialSamplesStepSS << \"Initial sample step: \" << m_PPAttribs.m_uiInitialSampleStepInSlice;\n            pSlider->SetText( InitialSamplesStepSS.str().c_str() );\n\n            break;\n        }\n\n    case ID_EPIPOLE_SAMPLING_DENSITY_FACTOR:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            float fSliderVal;\n            pSlider->GetValue(fSliderVal);\n            m_PPAttribs.m_uiEpipoleSamplingDensityFactor = 1 << (int)fSliderVal;\n            std::wstringstream EpipoleSamplingDensitySS;\n            EpipoleSamplingDensitySS << \"Epipole sampling density: \" << m_PPAttribs.m_uiEpipoleSamplingDensityFactor;\n            pSlider->SetText( EpipoleSamplingDensitySS.str().c_str() );\n\n            break;\n        }\n\n    case ID_REFINEMENT_THRESHOLD:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            pSlider->GetValue(m_PPAttribs.m_fRefinementThreshold);\n            break;\n        }\n\n    case ID_SHOW_SAMPLING:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bShowSampling = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_MIN_MAX_SHADOW_MAP_OPTIMIZATION:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bUse1DMinMaxTree = pCheckBox->GetCheckboxState()== CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_CORRECT_SCATTERING_AT_DEPTH_BREAKS:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bCorrectScatteringAtDepthBreaks = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_SCATTERING_SCALE:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            pSlider->GetValue(m_fScatteringScale);\n            break;\n        }\n\n    case ID_MIDDLE_GRAY:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            pSlider->GetValue(m_PPAttribs.m_fMiddleGray);\n            break;\n        }\n\n    case ID_WHITE_POINT:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            pSlider->GetValue(m_PPAttribs.m_fWhitePoint);\n            break;\n        }\n\n    case ID_LUM_SATURATION:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            pSlider->GetValue(m_PPAttribs.m_fLuminanceSaturation);\n            break;\n        }\n\n    case ID_AUTO_EXPOSURE:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bAutoExposure = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            pGUI->GetControl(ID_LIGHT_ADAPTATION)->SetEnable(m_PPAttribs.m_bAutoExposure ? true : false);\n            break;\n        }\n    \n    case ID_TONE_MAPPING_MODE:\n        {\n            CPUTDropdown *pDropDown = static_cast<CPUTDropdown*>(pControl);\n            pDropDown->GetSelectedItem(m_PPAttribs.m_uiToneMappingMode);\n            pGUI->GetControl(ID_LUM_SATURATION)->SetEnable( \n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_EXP ||\n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_REINHARD ||\n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_REINHARD_MOD ||\n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_LOGARITHMIC ||\n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_ADAPTIVE_LOG );\n            pGUI->GetControl(ID_WHITE_POINT)->SetEnable(  \n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_REINHARD_MOD ||\n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_UNCHARTED2 ||\n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_LOGARITHMIC ||\n                                m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_ADAPTIVE_LOG );\n            break;\n        }\n\n    case ID_LIGHT_ADAPTATION:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bLightAdaptation = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_OPTIMIZE_SAMPLE_LOCATIONS:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bOptimizeSampleLocations = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_SHOW_DEPTH_BREAKS:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bShowDepthBreaks = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_SHOW_LIGHTING_ONLY_CHECK:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bShowLightingOnly = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            break;\n        }\n\n    case ID_USE_CUSTOM_SCTR_COEFFS_CHECK:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_PPAttribs.m_bUseCustomSctrCoeffs = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n            pGUI->GetControl(ID_RLGH_COLOR_BTN)->SetEnable(!CPUTGetFullscreenState() && m_PPAttribs.m_bUseCustomSctrCoeffs);\n            pGUI->GetControl(ID_MIE_COLOR_BTN)->SetEnable(!CPUTGetFullscreenState() && m_PPAttribs.m_bUseCustomSctrCoeffs);\n            break;\n        }\n\n    case ID_RLGH_COLOR_BTN:\n        {\n            const float fRlghColorScale = 5e-5f;\n            D3DXVECTOR4 f4RlghColor = m_PPAttribs.m_f4CustomRlghBeta / fRlghColorScale;\n            if( SelectColor(f4RlghColor ) )\n            {\n                m_PPAttribs.m_f4CustomRlghBeta = f4RlghColor * fRlghColorScale;\n            }\n            break;\n        }\n\n    case ID_MIE_COLOR_BTN:\n        {\n            const float fMieColorScale = 5e-5f;\n            D3DXVECTOR4 f4MieColor = m_PPAttribs.m_f4CustomMieBeta / fMieColorScale;\n            if( SelectColor(f4MieColor ) )\n            {\n                m_PPAttribs.m_f4CustomMieBeta = f4MieColor * fMieColorScale;\n            }\n            break;\n        }\n\n    case ID_AEROSOL_DENSITY_SCALE_SLIDER:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            pSlider->GetValue(m_PPAttribs.m_fAerosolDensityScale);\n            break;\n        }\n\n    case ID_AEROSOL_ABSORBTION_SCALE_SLIDER:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            pSlider->GetValue(m_PPAttribs.m_fAerosolAbsorbtionScale);\n            break;\n        }\n\n    case ID_SINGLE_SCTR_MODE_DROPDOWN:\n        {\n            CPUTDropdown *pDropDown = static_cast<CPUTDropdown*>(pControl);\n            pDropDown->GetSelectedItem(m_PPAttribs.m_uiSingleScatteringMode);\n            pGUI->GetControl(ID_NUM_INTEGRATION_STEPS)->SetEnable(!m_PPAttribs.m_bEnableLightShafts && m_PPAttribs.m_uiSingleScatteringMode == SINGLE_SCTR_MODE_INTEGRATION);\n            break;\n        }\n\n    case ID_MULTIPLE_SCTR_MODE_DROPDOWN:\n        {\n            CPUTDropdown *pDropDown = static_cast<CPUTDropdown*>(pControl);\n            pDropDown->GetSelectedItem(m_PPAttribs.m_uiMultipleScatteringMode);\n            break;\n        }\n\n    case ID_NUM_CASCADES_DROPDOWN:\n        {\n            CPUTDropdown *pDropDown = static_cast<CPUTDropdown*>(pControl);\n            UINT uiSelectedItem;\n            pDropDown->GetSelectedItem(uiSelectedItem);\n            m_TerrainRenderParams.m_iNumShadowCascades = uiSelectedItem+1;\n            CreateShadowMap(mpD3dDevice);\n            m_EarthHemisphere.UpdateParams(m_TerrainRenderParams);\n            break;\n        }\n\n    case ID_SMOOTH_SHADOWS_CHECK:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_TerrainRenderParams.m_bSmoothShadows = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED ? TRUE : FALSE;\n            m_EarthHemisphere.UpdateParams(m_TerrainRenderParams);\n            break;\n        }\n\n    case ID_BEST_CASCADE_SEARCH_CHECK:\n        {\n            CPUTCheckbox *pCheckBox = static_cast<CPUTCheckbox*>(pControl);\n            m_TerrainRenderParams.m_bBestCascadeSearch = pCheckBox->GetCheckboxState() == CPUT_CHECKBOX_CHECKED ? TRUE : FALSE;\n            m_EarthHemisphere.UpdateParams(m_TerrainRenderParams);\n            break;\n        }\n\n    case ID_CASCADE_PARTITIONING_SLIDER:\n        {\n            CPUTSlider* pSlider = static_cast<CPUTSlider*>(pControl);\n            pSlider->GetValue(m_fCascadePartitioningFactor);\n            std::wstringstream SS;\n            SS << \"Partitioning Factor: \" << m_fCascadePartitioningFactor;\n            pSlider->SetText( SS.str().c_str() );\n            break;\n        }\n\n    case ID_CASCADE_PROCESSING_MODE_DROPDOWN:\n        {\n            CPUTDropdown *pDropDown = static_cast<CPUTDropdown*>(pControl);\n            pDropDown->GetSelectedItem(m_PPAttribs.m_uiCascadeProcessingMode);\n            break;\n        }\n\n    case ID_EXTINCTION_EVAL_MODE_DROPDOWN:\n        {\n            CPUTDropdown *pDropDown = static_cast<CPUTDropdown*>(pControl);\n            pDropDown->GetSelectedItem(m_PPAttribs.m_uiExtinctionEvalMode);\n            break;\n        }\n\n    case ID_MIN_MAX_MIP_FORMAT_DROPDOWN:\n        {\n            CPUTDropdown *pDropDown = static_cast<CPUTDropdown*>(pControl);\n            UINT uiSelectedItem;\n            pDropDown->GetSelectedItem(uiSelectedItem);\n            m_PPAttribs.m_bIs32BitMinMaxMipMap = (uiSelectedItem == 1);\n            break;\n        }\n\n\n    case ID_REFINEMENT_CRITERION_DROPDOWN:\n        {\n            CPUTDropdown *pDropDown = static_cast<CPUTDropdown*>(pControl);\n            pDropDown->GetSelectedItem(m_PPAttribs.m_uiRefinementCriterion);\n            break;\n        }\n\n    default:\n        break;\n    }\n}\n\n// Handle resize events\n//-----------------------------------------------------------------------------\nvoid COutdoorLightScatteringSample::ResizeWindow(UINT width, UINT height)\n{\n    if( width == 0 || height == 0 )\n        return;\n    m_uiBackBufferWidth = width;\n    m_uiBackBufferHeight = height;\n    // Before we can resize the swap chain, we must release any references to it.\n    // We could have a \"AssetLibrary::ReleaseSwapChainResources(), or similar.  But,\n    // Generic \"release all\" works, is simpler to implement/maintain, and is not performance critical.\n    //pAssetLibrary->ReleaseTexturesAndBuffers();\n\n    CPUT_DX11::ResizeWindow( width, height );\n\n    // Resize any application-specific render targets here\n    if( mpCamera ) \n    {\n        mpCamera->SetAspectRatio(((float)width)/((float)height));\n        mpCamera->Update();\n    }\n\n    m_pLightSctrPP->OnResizedSwapChain(mpD3dDevice, width, height );\n    m_pOffscreenRenderTarget->RecreateRenderTarget(width, height);\n    m_pOffscreenDepth->RecreateRenderTarget(width, height);\n}\n\n\nvoid COutdoorLightScatteringSample::ReleaseTmpBackBuffAndDepthBuff()\n{\n    SAFE_DELETE(m_pOffscreenRenderTarget);\n    SAFE_DELETE(m_pOffscreenDepth);\n}\n\nHRESULT COutdoorLightScatteringSample::CreateTmpBackBuffAndDepthBuff(ID3D11Device* pd3dDevice)\n{\n    ReleaseTmpBackBuffAndDepthBuff();\n\n    DXGI_SWAP_CHAIN_DESC SwapChainDesc;\n    mpSwapChain->GetDesc(&SwapChainDesc);\n        \n    SAFE_DELETE(m_pOffscreenRenderTarget);\n    m_pOffscreenRenderTarget = new CPUTRenderTargetColor();\n    m_pOffscreenRenderTarget->CreateRenderTarget( \n        cString( _L(\"OffscreenRenderTarget\") ),\n        SwapChainDesc.BufferDesc.Width,                                 //UINT Width\n        SwapChainDesc.BufferDesc.Height,                                //UINT Height\n        // It is essential to use floating point format for back buffer\n        // to avoid banding artifacts at low light conditions\n        DXGI_FORMAT_R11G11B10_FLOAT);\n\n    SAFE_DELETE(m_pOffscreenDepth);\n    m_pOffscreenDepth = new CPUTRenderTargetDepth();\n    m_pOffscreenDepth->CreateRenderTarget( \n        cString( _L(\"OffscreenDepthBuffer\") ),\n        SwapChainDesc.BufferDesc.Width,                                 //UINT Width\n        SwapChainDesc.BufferDesc.Height,                                //UINT Height\n        DXGI_FORMAT_D32_FLOAT ); \n\n\n    return D3D_OK;\n}\n\nvoid COutdoorLightScatteringSample::ReleaseShadowMap()\n{\n    // Check for the existance of a shadow map buffer and if it exists, destroy it and set its pointer to NULL\n\n    // Release the light space depth shader resource and depth stencil views\n    m_pShadowMapDSVs.clear();\n    m_pShadowMapSRV.Release();\n}\n\n\nHRESULT COutdoorLightScatteringSample::CreateShadowMap(ID3D11Device* pd3dDevice)\n{\n    HRESULT hr;\n\n    ReleaseShadowMap();\n\n    static const bool bIs32BitShadowMap = true;\n\t//ShadowMap\n\tD3D11_TEXTURE2D_DESC ShadowMapDesc =\n\t{\n        m_uiShadowMapResolution,\n        m_uiShadowMapResolution,\n\t\t1,\n\t\tm_TerrainRenderParams.m_iNumShadowCascades,\n\t\tbIs32BitShadowMap ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_R16_TYPELESS,\n        {1,0},\n\t\tD3D11_USAGE_DEFAULT,\n\t\tD3D11_BIND_SHADER_RESOURCE|D3D11_BIND_DEPTH_STENCIL,\n\t\t0,\n\t\t0\n\t};\n\n\tCComPtr<ID3D11Texture2D> ptex2DShadowMap;\n\tV_RETURN(pd3dDevice->CreateTexture2D(&ShadowMapDesc, NULL, &ptex2DShadowMap));\n\n\tD3D11_SHADER_RESOURCE_VIEW_DESC ShadowMapSRVDesc;\n    ZeroMemory( &ShadowMapSRVDesc, sizeof(ShadowMapSRVDesc) );\n    ShadowMapSRVDesc.Format = bIs32BitShadowMap ? DXGI_FORMAT_R32_FLOAT : DXGI_FORMAT_R16_UNORM;\n    ShadowMapSRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;\n\tShadowMapSRVDesc.Texture2DArray.MostDetailedMip = 0;\n\tShadowMapSRVDesc.Texture2DArray.MipLevels = 1;\n    ShadowMapSRVDesc.Texture2DArray.FirstArraySlice = 0;\n    ShadowMapSRVDesc.Texture2DArray.ArraySize = ShadowMapDesc.ArraySize;\n\n    V_RETURN(pd3dDevice->CreateShaderResourceView(ptex2DShadowMap, &ShadowMapSRVDesc, &m_pShadowMapSRV));\n\n    D3D11_DEPTH_STENCIL_VIEW_DESC ShadowMapDSVDesc;\n    ZeroMemory( &ShadowMapDSVDesc, sizeof(ShadowMapDSVDesc) );\n    ShadowMapDSVDesc.Format = bIs32BitShadowMap ? DXGI_FORMAT_D32_FLOAT : DXGI_FORMAT_D16_UNORM;\n    ShadowMapDSVDesc.Flags = 0;\n    ShadowMapDSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;\n    ShadowMapDSVDesc.Texture2DArray.MipSlice = 0;\n    ShadowMapDSVDesc.Texture2DArray.ArraySize = 1;\n    m_pShadowMapDSVs.resize(ShadowMapDesc.ArraySize);\n    for(UINT iArrSlice=0; iArrSlice < ShadowMapDesc.ArraySize; iArrSlice++)\n    {\n        ShadowMapDSVDesc.Texture2DArray.FirstArraySlice = iArrSlice;\n        V_RETURN(pd3dDevice->CreateDepthStencilView(ptex2DShadowMap, &ShadowMapDSVDesc, &m_pShadowMapDSVs[iArrSlice]));\n    }\n\n    return D3D_OK;\n}\n\nfloat COutdoorLightScatteringSample::GetSceneExtent()\n{\n    return 10000;\n}\n\n// Handle OnCreation events\n//-----------------------------------------------------------------------------\nvoid COutdoorLightScatteringSample::Create()\n{    \n    CPUTAssetLibrary*       pAssetLibrary   = CPUTAssetLibrary::GetAssetLibrary();\n    CPUTGuiControllerDX11*  pGUI            = CPUTGetGuiController();\n\n    pGUI->DrawFPS(true);\n\n    HRESULT hr;\n\tLPCWSTR ConfigPath = L\"Default_Config.txt\";\n    if( FAILED(ParseConfigurationFile( ConfigPath )) )\n    {\n        LOG_ERROR(_T(\"Failed to load config file %s\"), ConfigPath );\n        return;\n    }\n\n    /*\n    * Initialize GUI\n    */\n\n    static_assert( _countof(m_pSelectPanelDropDowns) == _countof(CONTROL_PANEL_IDS), \"Incorrect size of m_pSelectPanelDropDowns\" );\n    for(int iPanel=0; iPanel < _countof(CONTROL_PANEL_IDS); ++iPanel)\n    {\n        pGUI->CreateDropdown( L\"Controls: basic\", ID_SELECT_PANEL_COMBO, CONTROL_PANEL_IDS[iPanel], &m_pSelectPanelDropDowns[iPanel]);\n        m_pSelectPanelDropDowns[iPanel]->AddSelectionItem( L\"Controls: additional\" );\n        m_pSelectPanelDropDowns[iPanel]->AddSelectionItem( L\"Controls: tone mapping\" );\n        // SelectedItem is 1-based\n        m_pSelectPanelDropDowns[iPanel]->SetSelectedItem(m_uiSelectedPanelInd+1);\n    }\n\n\n    CPUTButton* pButton = NULL;\n    pGUI->CreateButton(_L(\"Fullscreen\"), ID_FULLSCREEN_BUTTON, ID_MAIN_PANEL, &pButton);\n    \n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"VSync\", ID_ENABLE_VSYNC, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( mSyncInterval ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Enable light scattering\", ID_ENABLE_LIGHT_SCATTERING, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_bEnableLightScattering ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Enable light shafts\", ID_ENABLE_LIGHT_SHAFTS, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bEnableLightShafts ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTDropdown* pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Epipolar sampling\", ID_LIGHT_SCTR_TECHNIQUE, ID_MAIN_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Brute force ray marching\" );\n        // SelectedItem is 1-based\n        pDropDown->SetSelectedItem(m_PPAttribs.m_uiLightSctrTechnique+1);\n    }\n\n    {\n        CPUTDropdown* pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Shadow Map res: 512x512\", ID_SHADOW_MAP_RESOLUTION, ID_MAIN_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Shadow Map res: 1024x1024\" );\n        pDropDown->AddSelectionItem( L\"Shadow Map res: 2048x2048\" );\n        pDropDown->AddSelectionItem( L\"Shadow Map res: 4096x4096\" );\n        unsigned long ulCurrVal;\n        BitScanForward(&ulCurrVal, m_uiShadowMapResolution);\n        // SelectedItem is 1-based\n        pDropDown->SetSelectedItem(ulCurrVal-9 + 1);\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        std::wstringstream NumStepsSS;\n        NumStepsSS << \"Num integration steps: \" << m_PPAttribs.m_uiInstrIntegralSteps;\n        pGUI->CreateSlider( NumStepsSS.str().c_str(), ID_NUM_INTEGRATION_STEPS, ID_MAIN_PANEL, &pSlider);\n        pSlider->SetEnable(!m_PPAttribs.m_bEnableLightShafts && m_PPAttribs.m_uiSingleScatteringMode == SINGLE_SCTR_MODE_INTEGRATION);\n\n        unsigned long ulStartVal, ulEndVal;\n        BitScanForward(&ulStartVal, m_iMinEpipolarSlices);\n        BitScanForward(&ulEndVal, m_iMaxEpipolarSlices);\n        pSlider->SetScale( 5, 100, 20 );\n        pSlider->SetValue( (float)m_PPAttribs.m_uiInstrIntegralSteps );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        std::wstringstream NumSlicesSS;\n        NumSlicesSS << \"Epipolar slices: \" << m_PPAttribs.m_uiNumEpipolarSlices;\n        pGUI->CreateSlider( NumSlicesSS.str().c_str(), ID_NUM_EPIPOLAR_SLICES, ID_MAIN_PANEL, &pSlider);\n\n        unsigned long ulStartVal, ulEndVal, ulCurrVal;\n        BitScanForward(&ulStartVal, m_iMinEpipolarSlices);\n        BitScanForward(&ulEndVal, m_iMaxEpipolarSlices);\n        pSlider->SetScale( (float)ulStartVal, (float)ulEndVal, ulEndVal-ulStartVal+1 );\n\n        BitScanForward(&ulCurrVal, m_PPAttribs.m_uiNumEpipolarSlices);\n        pSlider->SetValue( (float)ulCurrVal );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        std::wstringstream NumSamplesSS;\n        NumSamplesSS << \"Total samples in slice: \" << m_PPAttribs.m_uiMaxSamplesInSlice;\n        pGUI->CreateSlider( NumSamplesSS.str().c_str(), ID_NUM_SAMPLES_IN_EPIPOLAR_SLICE, ID_MAIN_PANEL, &pSlider);\n\n        unsigned long ulStartVal, ulEndVal, ulCurrVal;\n        BitScanForward(&ulStartVal, m_iMinSamplesInEpipolarSlice);\n        BitScanForward(&ulEndVal, m_iMaxSamplesInEpipolarSlice);\n        pSlider->SetScale( (float)ulStartVal, (float)ulEndVal, ulEndVal-ulStartVal+1 );\n\n        BitScanForward(&ulCurrVal, m_PPAttribs.m_uiMaxSamplesInSlice);\n        pSlider->SetValue( (float)ulCurrVal );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        std::wstringstream InitialSamplesStepSS;\n        InitialSamplesStepSS << \"Initial sample step: \" << m_PPAttribs.m_uiInitialSampleStepInSlice;\n        pGUI->CreateSlider( InitialSamplesStepSS.str().c_str(), ID_INITIAL_SAMPLE_STEP_IN_EPIPOLAR_SLICE, ID_MAIN_PANEL, &pSlider);\n\n        unsigned long ulStartVal=0, ulEndVal, ulCurrVal;\n        BitScanForward(&ulEndVal, m_PPAttribs.m_uiMaxSamplesInSlice / m_iMinInitialSamplesInEpipolarSlice);\n        pSlider->SetScale( (float)ulStartVal, (float)ulEndVal, ulEndVal-ulStartVal+1 );\n\n        BitScanForward(&ulCurrVal, m_PPAttribs.m_uiInitialSampleStepInSlice);\n        pSlider->SetValue( (float)ulCurrVal );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        std::wstringstream EpipoleSamplingDensitySS;\n        EpipoleSamplingDensitySS << \"Epipole sampling density: \" << m_PPAttribs.m_uiEpipoleSamplingDensityFactor;\n        pGUI->CreateSlider( EpipoleSamplingDensitySS.str().c_str(), ID_EPIPOLE_SAMPLING_DENSITY_FACTOR, ID_MAIN_PANEL, &pSlider);\n\n        unsigned long ulStartVal=0, ulEndVal, ulCurrVal;\n        BitScanForward(&ulEndVal, m_iMaxEpipoleSamplingDensityFactor);\n        pSlider->SetScale( (float)ulStartVal, (float)ulEndVal, ulEndVal-ulStartVal+1 );\n\n        BitScanForward(&ulCurrVal, m_PPAttribs.m_uiEpipoleSamplingDensityFactor);\n        pSlider->SetValue( (float)ulCurrVal );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        pGUI->CreateSlider( L\"Refinement threshold\", ID_REFINEMENT_THRESHOLD, ID_MAIN_PANEL, &pSlider);\n        pSlider->SetScale( 0.001f, 0.5f, 100 );\n        pSlider->SetValue( m_PPAttribs.m_fRefinementThreshold );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        pGUI->CreateSlider( L\"Scattering Scale\", ID_SCATTERING_SCALE, ID_MAIN_PANEL, &pSlider);\n        pSlider->SetScale( 0.1f, 2.f, 50 );\n        pSlider->SetValue( m_fScatteringScale );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Show sampling\", ID_SHOW_SAMPLING, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bShowSampling ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"1D Min/Max optimization\", ID_MIN_MAX_SHADOW_MAP_OPTIMIZATION, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bUse1DMinMaxTree ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Optimize sample locations\", ID_OPTIMIZE_SAMPLE_LOCATIONS, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bOptimizeSampleLocations ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Correction at depth breaks\", ID_CORRECT_SCATTERING_AT_DEPTH_BREAKS, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bCorrectScatteringAtDepthBreaks ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Show depth breaks\", ID_SHOW_DEPTH_BREAKS, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bShowDepthBreaks ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Lighting only\", ID_SHOW_LIGHTING_ONLY_CHECK, ID_MAIN_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bShowLightingOnly ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Sngl sctr: none\", ID_SINGLE_SCTR_MODE_DROPDOWN, ID_ADDITIONAL_ATTRIBS_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Sngl sctr: integration\" );\n        pDropDown->AddSelectionItem( L\"Sngl sctr: LUT\" );\n        pDropDown->SetSelectedItem( m_PPAttribs.m_uiSingleScatteringMode+1 );\n    }\n    \n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Mult sctr: none\", ID_MULTIPLE_SCTR_MODE_DROPDOWN, ID_ADDITIONAL_ATTRIBS_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Mult sctr: unoccluded\" );\n        pDropDown->AddSelectionItem( L\"Mult sctr: occluded\" );\n        pDropDown->SetSelectedItem( m_PPAttribs.m_uiMultipleScatteringMode+1 );\n    }\n    \n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Num Cascades: 1\", ID_NUM_CASCADES_DROPDOWN, ID_ADDITIONAL_ATTRIBS_PANEL, &pDropDown);\n        for(int i=2; i <= MAX_CASCADES; ++i)\n        {\n            WCHAR Text[32];\n            _stprintf_s(Text, _countof(Text), L\"Num Cascades: %d\", i);\n            pDropDown->AddSelectionItem( Text );\n        }\n        pDropDown->SetSelectedItem( m_TerrainRenderParams.m_iNumShadowCascades );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Show cascades\", ID_SHOW_CASCADES_CHECK, ID_ADDITIONAL_ATTRIBS_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Smooth shadows\", ID_SMOOTH_SHADOWS_CHECK, ID_ADDITIONAL_ATTRIBS_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_TerrainRenderParams.m_bSmoothShadows ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Best cascade search\", ID_BEST_CASCADE_SEARCH_CHECK, ID_ADDITIONAL_ATTRIBS_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_TerrainRenderParams.m_bBestCascadeSearch ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTSlider *pSlider = NULL;\n        std::wstringstream SS;\n        SS << \"Partitioning Factor: \" << m_fCascadePartitioningFactor;\n        pGUI->CreateSlider( SS.str().c_str(), ID_CASCADE_PARTITIONING_SLIDER, ID_ADDITIONAL_ATTRIBS_PANEL, &pSlider);\n        pSlider->SetScale( 0.0f, 1.f, 101 );\n        pSlider->SetValue( m_fCascadePartitioningFactor );\n    }\n\n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Cascades processing: single pass\", ID_CASCADE_PROCESSING_MODE_DROPDOWN, ID_ADDITIONAL_ATTRIBS_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Cascades processing: multi pass\" );\n        pDropDown->AddSelectionItem( L\"Cascades processing: multi pass inst\" );\n        pDropDown->SetSelectedItem( m_PPAttribs.m_uiCascadeProcessingMode+1 );\n    }\n\n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"First cascade to ray march: 0\", ID_FIRST_CASCADE_TO_RAY_MARCH_DROPDOWN, ID_ADDITIONAL_ATTRIBS_PANEL, &pDropDown);\n        for(int i=1; i<MAX_CASCADES; ++i)\n        {\n            WCHAR Text[32];\n            _stprintf_s(Text, _countof(Text), L\"First cascade to ray march: %d\", i);\n            pDropDown->AddSelectionItem( Text );\n        }\n        pDropDown->SetSelectedItem( m_PPAttribs.m_iFirstCascade+1 );\n    }\n\n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Extinction eval mode: per pixel\", ID_EXTINCTION_EVAL_MODE_DROPDOWN, ID_ADDITIONAL_ATTRIBS_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Extinction eval mode: Epipolar\" );\n        pDropDown->SetSelectedItem( m_PPAttribs.m_uiExtinctionEvalMode+1 );\n    }\n\n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Refinement criterion: depth\", ID_REFINEMENT_CRITERION_DROPDOWN, ID_ADDITIONAL_ATTRIBS_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Refinement criterion: inscattering\" );\n        pDropDown->SetSelectedItem( m_PPAttribs.m_uiRefinementCriterion+1 );\n    }\n\n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Min/max format: 16u\", ID_MIN_MAX_MIP_FORMAT_DROPDOWN, ID_ADDITIONAL_ATTRIBS_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Min/max format: 32f\" );\n        pDropDown->SetSelectedItem( m_PPAttribs.m_bIs32BitMinMaxMipMap ? 2 : 1 );\n    }\n    \n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Use custom sctr coeffs\", ID_USE_CUSTOM_SCTR_COEFFS_CHECK, ID_ADDITIONAL_ATTRIBS_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bUseCustomSctrCoeffs ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTButton *pBtn = NULL;\n        pGUI->CreateButton( L\"Set Rayleigh color\", ID_RLGH_COLOR_BTN, ID_ADDITIONAL_ATTRIBS_PANEL, &pBtn);\n        pBtn->SetEnable(!CPUTGetFullscreenState() && m_PPAttribs.m_bUseCustomSctrCoeffs);\n    }\n\n    {\n        CPUTButton *pBtn = NULL;\n        pGUI->CreateButton( L\"Set Mie color\", ID_MIE_COLOR_BTN, ID_ADDITIONAL_ATTRIBS_PANEL, &pBtn);\n        pBtn->SetEnable(!CPUTGetFullscreenState() && m_PPAttribs.m_bUseCustomSctrCoeffs);\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        pGUI->CreateSlider( L\"Aerosol density\", ID_AEROSOL_DENSITY_SCALE_SLIDER, ID_ADDITIONAL_ATTRIBS_PANEL, &pSlider);\n        pSlider->SetScale( 0.1f, 5.f, 50 );\n        pSlider->SetValue( m_PPAttribs.m_fAerosolDensityScale );\n\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        pGUI->CreateSlider( L\"Aerosol absorbtion\", ID_AEROSOL_ABSORBTION_SCALE_SLIDER, ID_ADDITIONAL_ATTRIBS_PANEL, &pSlider);\n        pSlider->SetScale( 0.0f, 5.f, 50 );\n        pSlider->SetValue( m_PPAttribs.m_fAerosolAbsorbtionScale );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Animate sun\", ID_ANIMATE_SUN, ID_ADDITIONAL_ATTRIBS_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_bAnimateSun ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        pGUI->CreateSlider( L\"Middle gray (Key)\", ID_MIDDLE_GRAY, ID_TONE_MAPPING_ATTRIBS_PANEL, &pSlider);\n        pSlider->SetScale( 0.01f, 1.f, 50 );\n        pSlider->SetValue( m_PPAttribs.m_fMiddleGray );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        pGUI->CreateSlider( L\"White point\", ID_WHITE_POINT, ID_TONE_MAPPING_ATTRIBS_PANEL, &pSlider);\n        pSlider->SetScale( 0.01f, 10.f, 50 );\n        pSlider->SetValue( m_PPAttribs.m_fWhitePoint );\n        pSlider->SetEnable( m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_REINHARD_MOD ||\n                            m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_UNCHARTED2 ||\n                            m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_LOGARITHMIC ||\n                            m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_ADAPTIVE_LOG );\n    }\n\n    {\n        CPUTSlider* pSlider = NULL;\n        pGUI->CreateSlider( L\"Luminance saturation\", ID_LUM_SATURATION, ID_TONE_MAPPING_ATTRIBS_PANEL, &pSlider);\n        pSlider->SetScale( 0.01f, 2.f, 50 );\n        pSlider->SetValue( m_PPAttribs.m_fLuminanceSaturation );\n        pSlider->SetEnable( m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_EXP ||\n                            m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_REINHARD ||\n                            m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_MODE_REINHARD_MOD ||\n                            m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_LOGARITHMIC ||\n                            m_PPAttribs.m_uiToneMappingMode == TONE_MAPPING_ADAPTIVE_LOG );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Auto exposure\", ID_AUTO_EXPOSURE, ID_TONE_MAPPING_ATTRIBS_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bAutoExposure ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n    }\n\n    {\n        CPUTDropdown *pDropDown = NULL;\n        pGUI->CreateDropdown( L\"Tone mapping: exp\", ID_TONE_MAPPING_MODE, ID_TONE_MAPPING_ATTRIBS_PANEL, &pDropDown);\n        pDropDown->AddSelectionItem( L\"Tone mapping: Reinhard\" );\n        pDropDown->AddSelectionItem( L\"Tone mapping: Reinhard Mod\" );\n        pDropDown->AddSelectionItem( L\"Tone mapping: Uncharted 2\" );\n        pDropDown->AddSelectionItem( L\"Tone mapping: Filmic ALU\" );\n        pDropDown->AddSelectionItem( L\"Tone mapping: Logarithmic\" );\n        pDropDown->AddSelectionItem( L\"Tone mapping: Adaptive log\" );\n        pDropDown->SetSelectedItem( m_PPAttribs.m_uiToneMappingMode + 1 );\n    }\n\n    {\n        CPUTCheckbox *pCheckBox = NULL;\n        pGUI->CreateCheckbox( L\"Light adaptation\", ID_LIGHT_ADAPTATION, ID_TONE_MAPPING_ATTRIBS_PANEL, &pCheckBox);\n        pCheckBox->SetCheckboxState( m_PPAttribs.m_bLightAdaptation ? CPUT_CHECKBOX_CHECKED : CPUT_CHECKBOX_UNCHECKED );\n        pCheckBox->SetEnable(m_PPAttribs.m_bAutoExposure ? true : false );\n    }\n\n    pGUI->CreateText( _L(\"F1 for Help\"), ID_IGNORE_CONTROL_ID, ID_HELP_TEXT_PANEL);\n    pGUI->CreateText( _L(\"[Escape] to quit application\"), ID_IGNORE_CONTROL_ID, ID_HELP_TEXT_PANEL);\n    pGUI->CreateText( _L(\"A,S,D,F - move camera position\"), ID_IGNORE_CONTROL_ID, ID_HELP_TEXT_PANEL);\n    pGUI->CreateText( _L(\"Q - camera position down\"), ID_IGNORE_CONTROL_ID, ID_HELP_TEXT_PANEL);\n    pGUI->CreateText( _L(\"E - camera position up\"), ID_IGNORE_CONTROL_ID, ID_HELP_TEXT_PANEL);\n    pGUI->CreateText( _L(\"[Shift] - accelerate camera movement\"), ID_IGNORE_CONTROL_ID, ID_HELP_TEXT_PANEL);\n    pGUI->CreateText( _L(\"mouse + left click - camera look rotation\"), ID_IGNORE_CONTROL_ID, ID_HELP_TEXT_PANEL);\n    pGUI->CreateText( _L(\"mouse + right click - light rotation\"), ID_IGNORE_CONTROL_ID, ID_HELP_TEXT_PANEL);\n\n    //\n    // Make the main panel active\n    //\n    pGUI->SetActivePanel(CONTROL_PANEL_IDS[m_uiSelectedPanelInd]);\n\n    CreateTmpBackBuffAndDepthBuff(mpD3dDevice);\n\n    // Create shadow map before other assets!!!\n    HRESULT hResult = CreateShadowMap(mpD3dDevice);\n    if( FAILED( hResult ) )\n        return;\n\n    pAssetLibrary->SetMediaDirectoryName(  _L(\"Media\\\\\"));\n\n    // Add our programatic (and global) material parameters\n    CPUTMaterial::mGlobalProperties.AddValue( _L(\"cbPerFrameValues\"), _L(\"$cbPerFrameValues\") );\n    CPUTMaterial::mGlobalProperties.AddValue( _L(\"cbPerModelValues\"), _L(\"#cbPerModelValues\") );\n\n    int width, height;\n    CPUTOSServices::GetOSServices()->GetClientDimensions(&width, &height);\n\n    CPUTRenderStateBlockDX11 *pBlock = new CPUTRenderStateBlockDX11();\n    CPUTRenderStateDX11 *pStates = pBlock->GetState();\n\n    // Override default sampler desc for our default shadowing sampler\n    pStates->SamplerDesc[1].Filter         = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;\n    pStates->SamplerDesc[1].AddressU       = D3D11_TEXTURE_ADDRESS_BORDER;\n    pStates->SamplerDesc[1].AddressV       = D3D11_TEXTURE_ADDRESS_BORDER;\n    pStates->SamplerDesc[1].ComparisonFunc = D3D11_COMPARISON_GREATER;\n    pBlock->CreateNativeResources();\n    CPUTAssetLibrary::GetAssetLibrary()->AddRenderStateBlock( _L(\"$DefaultRenderStates\"), pBlock );\n    \n    pBlock->Release(); // We're done with it.  The library owns it now.\n\n    // Initialize\n    mpCamera = new CPUTCamera();\n    CPUTAssetLibraryDX11::GetAssetLibrary()->AddCamera( _L(\"Outdoor light scattering sample camera\"), mpCamera );\n\n    // Set the projection matrix for all of the cameras to match our window.\n    mpCamera->SetAspectRatio(((float)width)/((float)height));\n \n    mpCamera->SetFov( XMConvertToRadians(45.0f) );\n    mpCamera->SetFarPlaneDistance(1e+7);\n    mpCamera->SetNearPlaneDistance(50.0f);\n    float4x4 InitialWorldMatrix\n    (\n\t\t -0.88250709f,  0.00000000f,  0.47029909f, 0.0000000f,\n\t\t -0.10293237f,  0.97575504f, -0.19315059f, 0.0000000f,\n\t\t -0.45889670f, -0.21886577f, -0.86111075f, 0.0000000f, \n\t\t          0.f,   8023.6152f,          0.f, 1.0000000f \n    );\n\n    mpCamera->SetParentMatrix(InitialWorldMatrix);\n    mpCamera->Update();\n\n    mpCameraController = new CPUTCameraControllerFPS();\n    mpCameraController->SetCamera(mpCamera);\n    mpCameraController->SetLookSpeed(0.004f);\n    mpCameraController->SetMoveSpeed(200.0f);\n\n    // \n    // Create camera\n    // \n\n    m_pDirectionalLightCamera = new CParallelLightCamera();\n    \n    m_pDirLightOrienationCamera = new CParallelLightCamera();\n    float4x4 LightOrientationWorld\n    (\n        -0.92137718f, -0.36748588f,  -0.12656364f, 0.0000000f,\n\t\t-0.37707147f,  0.92411846f,  0.061823435f, 0.0000000f,\n\t\t0.094240554f,  0.10468624f,  -0.99003011f, 0.0000000f,\n\t\t         0.f,          0.f,           0.f, 1.0000000f\n    );\n\n    m_pDirLightOrienationCamera->SetParentMatrix( LightOrientationWorld );\n    m_pDirLightOrienationCamera->Update();\n    \n    m_pLightController = new CPUTCameraControllerArcBall();\n    m_pLightController->SetCamera( m_pDirLightOrienationCamera );\n    m_pLightController->SetLookSpeed(0.002f);\n\n    // Call ResizeWindow() because it creates some resources that our blur material needs (e.g., the back buffer)\n    ResizeWindow(width, height);\n\n    \n\n    /*\n    * Create DX resources\n    */ \n\n    // Initialize the post process object to the device and context\n    hResult = m_pLightSctrPP->OnCreateDevice(mpD3dDevice, mpContext);\n    if( FAILED( hResult ) )\n        return;\n\n\n    // Create data source\n    try\n    {\n\t\tm_pElevDataSource.reset( new CElevationDataSource(m_strRawDEMDataFile.c_str()) );\n        m_pElevDataSource->SetOffsets(m_TerrainRenderParams.m_iColOffset, m_TerrainRenderParams.m_iRowOffset);\n        m_fMinElevation = m_pElevDataSource->GetGlobalMinElevation() * m_TerrainRenderParams.m_TerrainAttribs.m_fElevationScale;\n        m_fMaxElevation = m_pElevDataSource->GetGlobalMaxElevation() * m_TerrainRenderParams.m_TerrainAttribs.m_fElevationScale;\n    }\n    catch(const std::exception &)\n    {\n        LOG_ERROR(_T(\"Failed to create elevation data source\"));\n        return;\n    }\n\n\n\tLPCTSTR strTileTexPaths[CEarthHemsiphere::NUM_TILE_TEXTURES], strNormalMapPaths[CEarthHemsiphere::NUM_TILE_TEXTURES];\n\tfor(int iTile=0; iTile < _countof(strTileTexPaths); ++iTile )\n    {\n\t\tstrTileTexPaths[iTile] = m_strTileTexPaths[iTile].c_str();\n        strNormalMapPaths[iTile] = m_strNormalMapTexPaths[iTile].c_str();\n    }\n    \n    V( m_EarthHemisphere.OnD3D11CreateDevice(m_pElevDataSource.get(), m_TerrainRenderParams, mpD3dDevice, mpContext, m_strRawDEMDataFile.c_str(), m_strMtrlMaskFile.c_str(), strTileTexPaths, strNormalMapPaths ) );\n\n\n    D3D11_BUFFER_DESC CBDesc = \n    {\n        sizeof(SLightAttribs),\n        D3D11_USAGE_DYNAMIC,\n        D3D11_BIND_CONSTANT_BUFFER,\n        D3D11_CPU_ACCESS_WRITE, //UINT CPUAccessFlags\n        0, //UINT MiscFlags;\n        0, //UINT StructureByteStride;\n    };\n    V( mpD3dDevice->CreateBuffer( &CBDesc, NULL, &m_pcbLightAttribs) );\n}\n\n\nvoid GetRaySphereIntersection(D3DXVECTOR3 f3RayOrigin,\n                              const D3DXVECTOR3 &f3RayDirection,\n                              const D3DXVECTOR3 &f3SphereCenter,\n                              float fSphereRadius,\n                              D3DXVECTOR2 &f2Intersections)\n{\n    // http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection\n    f3RayOrigin -= f3SphereCenter;\n    float A = D3DXVec3Dot(&f3RayDirection, &f3RayDirection);\n    float B = 2 * D3DXVec3Dot(&f3RayOrigin, &f3RayDirection);\n    float C = D3DXVec3Dot(&f3RayOrigin, &f3RayOrigin) - fSphereRadius*fSphereRadius;\n    float D = B*B - 4*A*C;\n    // If discriminant is negative, there are no real roots hence the ray misses the\n    // sphere\n    if( D<0 )\n    {\n        f2Intersections = D3DXVECTOR2(-1,-1);\n    }\n    else\n    {\n        D = sqrt(D);\n        f2Intersections = D3DXVECTOR2(-B - D, -B + D) / (2*A); // A must be positive here!!\n    }\n}\n\nextern float3 gLightDir;\nvoid COutdoorLightScatteringSample::RenderShadowMap(ID3D11DeviceContext *pContext,\n                                             SLightAttribs &LightAttribs)\n{\n    //CPUTRenderParametersDX drawParams(pContext);\n    SShadowMapAttribs& ShadowMapAttribs = LightAttribs.ShadowAttribs;\n\n    //CPUTCamera *pLastCamera = mpCamera;\n    D3DXVECTOR3 v3DirOnLight = (D3DXVECTOR3&)LightAttribs.f4DirOnLight;\n    D3DXVECTOR3 v3LightDirection = -v3DirOnLight;\n\n    gLightDir.x = v3LightDirection.x;\n    gLightDir.y = v3LightDirection.y;\n    gLightDir.z = v3LightDirection.z;\n\n    // Declare working vectors\n    D3DXVECTOR3 vLightSpaceX, vLightSpaceY, vLightSpaceZ;\n\n    // Compute an inverse vector for the direction on the sun\n    vLightSpaceZ = v3LightDirection;\n    // And a vector for X light space\n    vLightSpaceX = D3DXVECTOR3( 1.0f, 0.0, 0.0 );\n    // Compute the cross products\n    D3DXVec3Cross(&vLightSpaceY, &vLightSpaceX, &vLightSpaceZ);\n    D3DXVec3Cross(&vLightSpaceX, &vLightSpaceZ, &vLightSpaceY);\n    // And then normalize them\n    D3DXVec3Normalize( &vLightSpaceX, &vLightSpaceX );\n    D3DXVec3Normalize( &vLightSpaceY, &vLightSpaceY );\n    D3DXVec3Normalize( &vLightSpaceZ, &vLightSpaceZ );\n\n    // Declare a world to light space transformation matrix\n    // Initialize to an identity matrix\n    D3DXMATRIX WorldToLightViewSpaceMatr;\n    D3DXMatrixIdentity( &WorldToLightViewSpaceMatr );\n    // Adjust elements to the light space\n    WorldToLightViewSpaceMatr._11 = vLightSpaceX.x;\n    WorldToLightViewSpaceMatr._21 = vLightSpaceX.y;\n    WorldToLightViewSpaceMatr._31 = vLightSpaceX.z;\n\n    WorldToLightViewSpaceMatr._12 = vLightSpaceY.x;\n    WorldToLightViewSpaceMatr._22 = vLightSpaceY.y;\n    WorldToLightViewSpaceMatr._32 = vLightSpaceY.z;\n\n    WorldToLightViewSpaceMatr._13 = vLightSpaceZ.x;\n    WorldToLightViewSpaceMatr._23 = vLightSpaceZ.y;\n    WorldToLightViewSpaceMatr._33 = vLightSpaceZ.z;\n\n    D3DXMatrixTranspose(&ShadowMapAttribs.mWorldToLightViewT, &WorldToLightViewSpaceMatr);\n\n    D3DXVECTOR3 f3CameraPosInLightSpace;\n    D3DXVec3TransformCoord(&f3CameraPosInLightSpace, &m_CameraPos, &WorldToLightViewSpaceMatr);\n\n    D3DXMATRIX mProj = (D3DXMATRIX &)*mpCamera->GetProjectionMatrix();\n    float fMainCamNearPlane = -mProj._43 / mProj._33;\n    float fMainCamFarPlane = mProj._33 / (mProj._33-1) * fMainCamNearPlane;\n    //fMainCamNearPlane = min(fMainCamNearPlane, 2e+5f);\n\n    for(int i=0; i < MAX_CASCADES; ++i)\n        ShadowMapAttribs.fCascadeCamSpaceZEnd[i] = +FLT_MAX;\n\n    CComPtr<ID3D11RenderTargetView> pOrigRTV;\n    CComPtr<ID3D11DepthStencilView> pOrigDSV;\n    D3D11_VIEWPORT OrigViewport;\n    pContext->OMGetRenderTargets(1, &pOrigRTV, &pOrigDSV);\n    UINT uiNumVP = 1;\n    pContext->RSGetViewports(&uiNumVP, &OrigViewport);\n\n    // Render cascades\n    for(int iCascade = 0; iCascade < m_TerrainRenderParams.m_iNumShadowCascades; ++iCascade)\n    {\n        auto &CurrCascade = ShadowMapAttribs.Cascades[iCascade];\n        D3DXMATRIX CascadeFrustumProjMatrix;\n        float &fCascadeNearZ = ShadowMapAttribs.fCascadeCamSpaceZEnd[iCascade];\n        float fCascadeFarZ = (iCascade == 0) ? fMainCamFarPlane : ShadowMapAttribs.fCascadeCamSpaceZEnd[iCascade-1];\n        fCascadeNearZ = fMainCamNearPlane;\n\n        if (iCascade < m_TerrainRenderParams.m_iNumShadowCascades-1) \n        {\n            float ratio = fMainCamNearPlane / fMainCamFarPlane;\n            float power = (float)(iCascade+1) / (float)m_TerrainRenderParams.m_iNumShadowCascades;\n            float logZ = fMainCamFarPlane * pow(ratio, power);\n        \n            float range = fMainCamNearPlane - fMainCamFarPlane;\n            float uniformZ = fMainCamFarPlane + range * power;\n\n            fCascadeNearZ = m_fCascadePartitioningFactor * (logZ - uniformZ) + uniformZ;\n        }\n        float fMaxLightShaftsDist = 3e+5f;\n        CurrCascade.f4StartEndZ.x = (iCascade == m_PPAttribs.m_iFirstCascade) ? 0 : min(fCascadeFarZ, fMaxLightShaftsDist);\n        CurrCascade.f4StartEndZ.y = min(fCascadeNearZ, fMaxLightShaftsDist);\n        CascadeFrustumProjMatrix = mProj;\n        CascadeFrustumProjMatrix._33 = fCascadeFarZ / (fCascadeFarZ - fCascadeNearZ);\n        CascadeFrustumProjMatrix._43 = -fCascadeNearZ * CascadeFrustumProjMatrix._33;\n\n        D3DXMATRIX CascadeFrustumViewProjMatr = m_CameraViewMatrix * CascadeFrustumProjMatrix;\n        D3DXMATRIX CascadeFrustumProjSpaceToWorldSpace;\n        D3DXMatrixInverse(&CascadeFrustumProjSpaceToWorldSpace, nullptr, &CascadeFrustumViewProjMatr);\n        D3DXMATRIX CascadeFrustumProjSpaceToLightSpace = CascadeFrustumProjSpaceToWorldSpace * WorldToLightViewSpaceMatr;\n\n        // Set reference minimums and maximums for each coordinate\n        D3DXVECTOR3 f3MinXYZ(f3CameraPosInLightSpace), f3MaxXYZ(f3CameraPosInLightSpace);\n        \n        // First cascade used for ray marching must contain camera within it\n        if( iCascade != m_PPAttribs.m_iFirstCascade )\n        {\n            f3MinXYZ = D3DXVECTOR3(+FLT_MAX, +FLT_MAX, +FLT_MAX);\n            f3MaxXYZ = D3DXVECTOR3(-FLT_MAX, -FLT_MAX, -FLT_MAX);\n        }\n\n        for(int iClipPlaneCorner=0; iClipPlaneCorner < 8; ++iClipPlaneCorner)\n        {\n            D3DXVECTOR3 f3PlaneCornerProjSpace( (iClipPlaneCorner & 0x01) ? +1.f : - 1.f, \n                                                (iClipPlaneCorner & 0x02) ? +1.f : - 1.f,\n                                                // Since we use complimentary depth buffering, \n                                                // far plane has depth 0\n                                                (iClipPlaneCorner & 0x04) ? 1.f : 0.f);\n            D3DXVECTOR3 f3PlaneCornerLightSpace;\n            D3DXVec3TransformCoord(&f3PlaneCornerLightSpace, &f3PlaneCornerProjSpace, &CascadeFrustumProjSpaceToLightSpace);\n            D3DXVec3Minimize(&f3MinXYZ, &f3MinXYZ, &f3PlaneCornerLightSpace);\n            D3DXVec3Maximize(&f3MaxXYZ, &f3MaxXYZ, &f3PlaneCornerLightSpace);\n        }\n\n        // It is necessary to ensure that shadow-casting patches, which are not visible \n        // in the frustum, are still rendered into the shadow map\n        f3MinXYZ.z -= SAirScatteringAttribs().fEarthRadius * sqrt(2.f);\n        \n        // Align cascade extent to the closest power of two\n        float fShadowMapDim = (float)m_uiShadowMapResolution;\n        float fCascadeXExt = (f3MaxXYZ.x - f3MinXYZ.x) * (1 + 1.f/fShadowMapDim);\n        float fCascadeYExt = (f3MaxXYZ.y - f3MinXYZ.y) * (1 + 1.f/fShadowMapDim);\n        const float fExtStep = 2.f;\n        fCascadeXExt = pow( fExtStep, ceil( log(fCascadeXExt)/log(fExtStep) ) );\n        fCascadeYExt = pow( fExtStep, ceil( log(fCascadeYExt)/log(fExtStep) ) );\n        // Align cascade center with the shadow map texels to alleviate temporal aliasing\n        float fCascadeXCenter = (f3MaxXYZ.x + f3MinXYZ.x)/2.f;\n        float fCascadeYCenter = (f3MaxXYZ.y + f3MinXYZ.y)/2.f;\n        float fTexelXSize = fCascadeXExt / fShadowMapDim;\n        float fTexelYSize = fCascadeXExt / fShadowMapDim;\n        fCascadeXCenter = floor(fCascadeXCenter/fTexelXSize) * fTexelXSize;\n        fCascadeYCenter = floor(fCascadeYCenter/fTexelYSize) * fTexelYSize;\n        // Compute new cascade min/max xy coords\n        f3MaxXYZ.x = fCascadeXCenter + fCascadeXExt/2.f;\n        f3MinXYZ.x = fCascadeXCenter - fCascadeXExt/2.f;\n        f3MaxXYZ.y = fCascadeYCenter + fCascadeYExt/2.f;\n        f3MinXYZ.y = fCascadeYCenter - fCascadeYExt/2.f;\n\n        CurrCascade.f4LightSpaceScale.x =  2.f / (f3MaxXYZ.x - f3MinXYZ.x);\n        CurrCascade.f4LightSpaceScale.y =  2.f / (f3MaxXYZ.y - f3MinXYZ.y);\n        CurrCascade.f4LightSpaceScale.z = -1.f / (f3MaxXYZ.z - f3MinXYZ.z);\n        // Apply bias to shift the extent to [-1,1]x[-1,1]x[1,0]\n        CurrCascade.f4LightSpaceScaledBias.x = -f3MinXYZ.x * CurrCascade.f4LightSpaceScale.x - 1.f;\n        CurrCascade.f4LightSpaceScaledBias.y = -f3MinXYZ.y * CurrCascade.f4LightSpaceScale.y - 1.f;\n        CurrCascade.f4LightSpaceScaledBias.z = -f3MaxXYZ.z * CurrCascade.f4LightSpaceScale.z + 0.f;\n        D3DXMATRIX ScaleMatrix;\n        D3DXMatrixScaling(&ScaleMatrix, CurrCascade.f4LightSpaceScale.x, CurrCascade.f4LightSpaceScale.y, CurrCascade.f4LightSpaceScale.z);\n        D3DXMATRIX ScaledBiasMatrix;\n        D3DXMatrixTranslation(&ScaledBiasMatrix, CurrCascade.f4LightSpaceScaledBias.x, CurrCascade.f4LightSpaceScaledBias.y, CurrCascade.f4LightSpaceScaledBias.z);\n\n        // Note: bias is applied after scaling!\n        D3DXMATRIX CascadeProjMatr = ScaleMatrix * ScaledBiasMatrix;\n        //D3DXMatrixOrthoOffCenterLH( &m_LightOrthoMatrix, MinX, MaxX, MinY, MaxY, MaxZ, MinZ);\n\n        // Adjust the world to light space transformation matrix\n        D3DXMATRIX WorldToLightProjSpaceMatr = WorldToLightViewSpaceMatr * CascadeProjMatr;\n        D3DXMATRIX ProjToUVScale, ProjToUVBias;\n        D3DXMatrixScaling( &ProjToUVScale, 0.5f, -0.5f, 1.f);\n        D3DXMatrixTranslation( &ProjToUVBias, 0.5f, 0.5f, 0.f);\n        D3DXMATRIX WorldToShadowMapUVDepthMatr = WorldToLightProjSpaceMatr * ProjToUVScale * ProjToUVBias;\n        D3DXMatrixTranspose( &ShadowMapAttribs.mWorldToShadowMapUVDepthT[iCascade], &WorldToShadowMapUVDepthMatr );\n\n        D3D11_VIEWPORT NewViewPort;\n        NewViewPort.TopLeftX = 0;\n        NewViewPort.TopLeftY = 0;\n        NewViewPort.Width  = static_cast<float>( m_uiShadowMapResolution );\n        NewViewPort.Height = static_cast<float>( m_uiShadowMapResolution );\n        NewViewPort.MinDepth = 0;\n        NewViewPort.MaxDepth = 1;\n        // Set the viewport\n        pContext->RSSetViewports(1, &NewViewPort);\n        pContext->OMSetRenderTargets(0, nullptr, m_pShadowMapDSVs[iCascade]);\n        pContext->ClearDepthStencilView(m_pShadowMapDSVs[iCascade], D3D11_CLEAR_DEPTH, 0.f, 0);\n\n        // Render terrain to shadow map\n        m_EarthHemisphere.Render(mpContext, m_CameraPos, WorldToLightProjSpaceMatr, nullptr, nullptr, nullptr, nullptr, nullptr, true);\n\n    }\n\n    pContext->OMSetRenderTargets(1, &pOrigRTV.p, pOrigDSV);\n    pContext->RSSetViewports(1, &OrigViewport);\n}\n\nvoid ComputeApproximateNearFarPlaneDist(const D3DXVECTOR3 &CameraPos,\n                                        const D3DXMATRIX &ViewMatr,\n                                        const D3DXMATRIX &ProjMatr, \n                                        const D3DXVECTOR3 &EarthCenter,\n                                        float fEarthRadius,\n                                        float fMinRadius,\n                                        float fMaxRadius,\n                                        float &fNearPlaneZ,\n                                        float &fFarPlaneZ)\n{\n    D3DXMATRIX ViewProjMatr = ViewMatr * ProjMatr;\n    D3DXMATRIX ViewProjInv;\n    D3DXMatrixInverse(&ViewProjInv, nullptr, &ViewProjMatr);\n    \n    // Compute maximum view distance for the current camera altitude\n    D3DXVECTOR3 f3CameraGlobalPos = CameraPos - EarthCenter;\n    float fCameraElevationSqr = D3DXVec3Dot(&f3CameraGlobalPos, &f3CameraGlobalPos);\n    float fMaxViewDistance = (float)(sqrt( (double)fCameraElevationSqr - (double)fEarthRadius*fEarthRadius ) + \n                                     sqrt( (double)fMaxRadius*fMaxRadius - (double)fEarthRadius*fEarthRadius ));\n    float fCameraElev = sqrt(fCameraElevationSqr);\n\n    fNearPlaneZ = 50.f;\n    if( fCameraElev > fMaxRadius )\n    {\n        // Adjust near clipping plane\n        fNearPlaneZ = (fCameraElev - fMaxRadius) / sqrt( 1 + 1.f/(ProjMatr._11*ProjMatr._11) + 1.f/(ProjMatr._22*ProjMatr._22) );\n    }\n\n    fNearPlaneZ = max(fNearPlaneZ, 50);\n    fFarPlaneZ = 1000;\n    \n    const int iNumTestDirections = 5;\n    for(int i=0; i<iNumTestDirections; ++i)\n        for(int j=0; j<iNumTestDirections; ++j)\n        {\n            D3DXVECTOR3 PosPS, PosWS, DirFromCamera;\n            PosPS.x = (float)i / (float)(iNumTestDirections-1) * 2.f - 1.f;\n            PosPS.y = (float)j / (float)(iNumTestDirections-1) * 2.f - 1.f;\n            PosPS.z = 0; // Far plane is at 0 in complimentary depth buffer\n            D3DXVec3TransformCoord(&PosWS, &PosPS, &ViewProjInv);\n\n            DirFromCamera = PosWS - CameraPos;\n            D3DXVec3Normalize(&DirFromCamera, &DirFromCamera);\n\n            D3DXVECTOR2 IsecsWithBottomBoundSphere;\n            GetRaySphereIntersection(CameraPos, DirFromCamera, EarthCenter, fMinRadius, IsecsWithBottomBoundSphere);\n\n            float fNearIsecWithBottomSphere = IsecsWithBottomBoundSphere.x > 0 ? IsecsWithBottomBoundSphere.x : IsecsWithBottomBoundSphere.y;\n            if( fNearIsecWithBottomSphere > 0 )\n            {\n                // The ray hits the Earth. Use hit point to compute camera space Z\n                D3DXVECTOR3 HitPointWS = CameraPos + DirFromCamera*fNearIsecWithBottomSphere;\n                D3DXVECTOR3 HitPointCamSpace;\n                D3DXVec3TransformCoord(&HitPointCamSpace, &HitPointWS, &ViewMatr);\n                fFarPlaneZ = max(fFarPlaneZ, HitPointCamSpace.z);\n            }\n            else\n            {\n                // The ray misses the Earth. In that case the whole earth could be seen\n                fFarPlaneZ = fMaxViewDistance;\n            }\n        }\n}\n\n//-----------------------------------------------------------------------------\nvoid COutdoorLightScatteringSample::Update(double deltaSeconds)\n{\n    if( m_bAnimateSun )\n    {\n        auto &LightOrientationMatrix = *m_pDirLightOrienationCamera->GetParentMatrix();\n        float3 RotationAxis( 0.5f, 0.3f, 0.0f );\n        float3 LightDir = m_pDirLightOrienationCamera->GetLook() * -1;\n        float fRotationScaler = ( LightDir.y > +0.2f ) ? 50.f : 1.f;\n        float4x4 RotationMatrix = float4x4RotationAxis(RotationAxis, 0.02f * (float)deltaSeconds * fRotationScaler);\n        LightOrientationMatrix = LightOrientationMatrix * RotationMatrix;\n        m_pDirLightOrienationCamera->SetParentMatrix(LightOrientationMatrix);\n    }\n\n    if( mpCameraController )\n    {\n        float fSpeedScale = max( (m_CameraPos.y-5000)/20, 200.f );\n        mpCameraController->SetMoveSpeed(fSpeedScale);\n\n        mpCameraController->Update( static_cast<float>(deltaSeconds) );\n    }\n\n    mpCamera->GetPosition(&m_CameraPos.x, &m_CameraPos.y, &m_CameraPos.z);\n\n    float fTerrainHeightUnderCamera = \n        m_pElevDataSource->GetInterpolatedHeight(m_CameraPos.x/m_TerrainRenderParams.m_TerrainAttribs.m_fElevationSamplingInterval, \n                                                 m_CameraPos.z/m_TerrainRenderParams.m_TerrainAttribs.m_fElevationSamplingInterval)\n        * m_TerrainRenderParams.m_TerrainAttribs.m_fElevationScale;\n    fTerrainHeightUnderCamera += 100.f;\n    float fXZMoveRadius = 512 * m_TerrainRenderParams.m_TerrainAttribs.m_fElevationSamplingInterval;\n    bool bUpdateCamPos = false;\n    float fDistFromCenter = sqrt(m_CameraPos.x*m_CameraPos.x + m_CameraPos.z*m_CameraPos.z);\n    if( fDistFromCenter > fXZMoveRadius )\n    {\n        m_CameraPos.x *= fXZMoveRadius/fDistFromCenter;\n        m_CameraPos.z *= fXZMoveRadius/fDistFromCenter;\n        bUpdateCamPos = true;\n    }\n    if( m_CameraPos.y < fTerrainHeightUnderCamera )\n    {\n        m_CameraPos.y = fTerrainHeightUnderCamera; \n        bUpdateCamPos = true;\n    }\n    float fMaxCameraAltitude = SAirScatteringAttribs().fAtmTopHeight * 10;\n    if( m_CameraPos.y > fMaxCameraAltitude )\n    {\n        m_CameraPos.y = fMaxCameraAltitude;\n        bUpdateCamPos = true;\n    }\n    if( bUpdateCamPos )\n    {\n        mpCamera->SetPosition(m_CameraPos.x, m_CameraPos.y, m_CameraPos.z);\n        mpCamera->Update();\n    }\n    \n    m_CameraViewMatrix = (D3DXMATRIX&)*mpCamera->GetViewMatrix();\n    D3DXMATRIX mProj = (D3DXMATRIX &)*mpCamera->GetProjectionMatrix();\n    float fEarthRadius = SAirScatteringAttribs().fEarthRadius;\n    D3DXVECTOR3 EarthCenter(0, -fEarthRadius, 0);\n    float fNearPlaneZ, fFarPlaneZ;\n    ComputeApproximateNearFarPlaneDist(m_CameraPos,\n                                       m_CameraViewMatrix,\n                                       mProj,\n                                       EarthCenter,\n                                       fEarthRadius,\n                                       fEarthRadius + m_fMinElevation,\n                                       fEarthRadius + m_fMaxElevation,\n                                       fNearPlaneZ,\n                                       fFarPlaneZ);\n    fNearPlaneZ = max(fNearPlaneZ, 50);\n    fFarPlaneZ  = max(fFarPlaneZ, fNearPlaneZ+100);\n    fFarPlaneZ  = max(fFarPlaneZ, 1000);\n    \n    mpCamera->SetNearPlaneDistance( fNearPlaneZ );\n    mpCamera->SetFarPlaneDistance( fFarPlaneZ );\n    mpCamera->Update();\n}\n\nstatic D3DXVECTOR2 ProjToUV(const D3DXVECTOR2& f2ProjSpaceXY)\n{\n    return D3DXVECTOR2(0.5f + 0.5f*f2ProjSpaceXY.x, 0.5f - 0.5f*f2ProjSpaceXY.y);\n}\n\n// DirectX 11 render callback\n//-----------------------------------------------------------------------------\nvoid COutdoorLightScatteringSample::Render(double deltaSeconds)\n{\n    const float srgbClearColor[] = { 0.0993f, 0.0993f, 0.0993f, 1.0f }; //sRGB - red,green,blue,alpha pow(0.350, 2.2)\n    const float  rgbClearColor[] = {  0.350f,  0.350f,  0.350f, 1.0f }; //RGB - red,green,blue,alpha\n\n    // Clear back buffer\n    const float clearColor[] = { 0.0993f, 0.0993f, 0.0993f, 1.0f };\n    mpContext->ClearRenderTargetView( mpBackBufferRTV,  clearColor );\n    mpContext->ClearDepthStencilView( mpDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 0.0f, 0);\n\n    CPUTRenderParametersDX drawParams(mpContext);\n\n    D3DXMATRIX mProj = (D3DXMATRIX &)*mpCamera->GetProjectionMatrix();\n    D3DXMATRIX mView = m_CameraViewMatrix;//(D3DXMATRIX &)*mpCamera->GetViewMatrix();\n    D3DXMATRIX mViewProj = mView * mProj;\n\n    // Get the camera position\n    D3DXMATRIX CameraWorld;\n    D3DXMatrixInverse(&CameraWorld, NULL, &mView);\n    D3DXVECTOR3 CameraPos = *(D3DXVECTOR3*)&CameraWorld._41;\n\n    D3DXVECTOR3 v3LightDir = -(D3DXVECTOR3&)m_pDirLightOrienationCamera->GetLook();\n    D3DXVECTOR3 v3DirOnLight = -v3LightDir;\n\n    SLightAttribs LightAttribs;\n    LightAttribs.f4DirOnLight = D3DXVECTOR4( v3DirOnLight.x, v3DirOnLight.y, v3DirOnLight.z, 0 );\n\n    D3DXVECTOR4 f4ExtraterrestrialSunColor = D3DXVECTOR4(10,10,10,10);\n    LightAttribs.f4ExtraterrestrialSunColor = f4ExtraterrestrialSunColor*m_fScatteringScale;\n    mLightColor = (float3&)f4ExtraterrestrialSunColor;\n\n    CPUTGuiControllerDX11* pGUI = CPUTGetGuiController();\n    UINT uiSelectedItem;\n    ((CPUTDropdown*)pGUI->GetControl(ID_FIRST_CASCADE_TO_RAY_MARCH_DROPDOWN))->GetSelectedItem(uiSelectedItem);\n    m_PPAttribs.m_iFirstCascade = min((int)uiSelectedItem, m_TerrainRenderParams.m_iNumShadowCascades - 1);\n    m_PPAttribs.m_fFirstCascade = (float)m_PPAttribs.m_iFirstCascade;\n\n\tRenderShadowMap(mpContext, LightAttribs);\n    \n    LightAttribs.ShadowAttribs.bVisualizeCascades = ((CPUTCheckbox*)pGUI->GetControl(ID_SHOW_CASCADES_CHECK))->GetCheckboxState() == CPUT_CHECKBOX_CHECKED;\n\n    // Calculate location of the sun on the screen\n    D3DXVECTOR4 &f4LightPosPS = LightAttribs.f4LightScreenPos;\n    D3DXVec4Transform(&f4LightPosPS, &LightAttribs.f4DirOnLight, &mViewProj);\n\n    f4LightPosPS.x /= f4LightPosPS.w;\n    f4LightPosPS.y /= f4LightPosPS.w;\n    f4LightPosPS.z /= f4LightPosPS.w;\n    float fDistToLightOnScreen = D3DXVec2Length( (D3DXVECTOR2*)&f4LightPosPS );\n    float fMaxDist = 100;\n    if( fDistToLightOnScreen > fMaxDist )\n        (D3DXVECTOR2&)f4LightPosPS *= fMaxDist/fDistToLightOnScreen;\n\n    // Note that in fact the outermost visible screen pixels do not lie exactly on the boundary (+1 or -1), but are biased by\n    // 0.5 screen pixel size inwards. Using these adjusted boundaries improves precision and results in\n    // smaller number of pixels which require inscattering correction\n    LightAttribs.bIsLightOnScreen = abs(f4LightPosPS.x) <= 1.f - 1.f/(float)m_uiBackBufferWidth && \n                                    abs(f4LightPosPS.y) <= 1.f - 1.f/(float)m_uiBackBufferHeight;\n\n    UpdateConstantBuffer(mpContext, m_pcbLightAttribs, &LightAttribs, sizeof(LightAttribs));\n\n    if( m_bEnableLightScattering )\n    {\n        float pClearColor[4] = {0,0,0,0};\n        m_pOffscreenRenderTarget->SetRenderTarget( drawParams, m_pOffscreenDepth, 0, pClearColor, true, 0.f );\n    }\n    else\n    {\n        mpContext->ClearRenderTargetView( mpBackBufferRTV, srgbClearColor );\n        mpContext->ClearDepthStencilView(mpDepthStencilView, D3D11_CLEAR_DEPTH, 0.0f, 0);   \n    }\n\n    \n    // Render terrain\n    ID3D11Buffer *pcMediaScatteringParams = m_pLightSctrPP->GetMediaAttribsCB();\n    ID3D11ShaderResourceView *pPrecomputedNetDensitySRV = m_pLightSctrPP->GetPrecomputedNetDensitySRV();\n    ID3D11ShaderResourceView *pAmbientSkyLightSRV = m_pLightSctrPP->GetAmbientSkyLightSRV(mpD3dDevice, mpContext);\n    m_EarthHemisphere.Render( mpContext, m_CameraPos, mViewProj, m_pcbLightAttribs, pcMediaScatteringParams, m_pShadowMapSRV, pPrecomputedNetDensitySRV, pAmbientSkyLightSRV, false);\n\n    if( m_bEnableLightScattering )\n    {\n        D3DXMATRIX mViewProjInverseMatr;\n        D3DXMatrixInverse(&mViewProjInverseMatr, NULL, &mViewProj);\n\n        SFrameAttribs FrameAttribs;\n\n        FrameAttribs.pd3dDevice = mpD3dDevice;\n        FrameAttribs.pd3dDeviceContext = mpContext;\n        FrameAttribs.dElapsedTime = deltaSeconds;\n        FrameAttribs.pLightAttribs = &LightAttribs;\n\n        m_PPAttribs.m_iNumCascades = m_TerrainRenderParams.m_iNumShadowCascades;\n        m_PPAttribs.m_fNumCascades = (float)m_TerrainRenderParams.m_iNumShadowCascades;\n\n        CPUTGuiControllerDX11* pGUI = CPUTGetGuiController(); \n        CPUTSlider* pSlider = static_cast<CPUTSlider*>(pGUI->GetControl(ID_REFINEMENT_THRESHOLD));\n        pSlider->GetValue(m_PPAttribs.m_fRefinementThreshold);\n\n        FrameAttribs.CameraAttribs.f4CameraPos = D3DXVECTOR4(CameraPos.x, CameraPos.y, CameraPos.z, 0);            ///< Camera world position\n        FrameAttribs.CameraAttribs.fNearPlaneZ = mpCamera->GetNearPlaneDistance();\n        FrameAttribs.CameraAttribs.fFarPlaneZ  = mpCamera->GetFarPlaneDistance() * 0.999999f;\n        D3DXMatrixTranspose( &FrameAttribs.CameraAttribs.mViewT, &mView);\n        D3DXMatrixTranspose( &FrameAttribs.CameraAttribs.mProjT, &mProj);\n        D3DXMatrixTranspose( &FrameAttribs.CameraAttribs.mViewProjInvT, &mViewProjInverseMatr);\n\n        FrameAttribs.pcbLightAttribs = m_pcbLightAttribs;\n\n        m_PPAttribs.m_fMaxShadowMapStep = static_cast<float>(m_uiShadowMapResolution / 4);\n\n        m_PPAttribs.m_f2ShadowMapTexelSize = D3DXVECTOR2( 1.f / static_cast<float>(m_uiShadowMapResolution), 1.f / static_cast<float>(m_uiShadowMapResolution) );\n        m_PPAttribs.m_uiShadowMapResolution = m_uiShadowMapResolution;\n        // During the ray marching, on each step we move by the texel size in either horz \n        // or vert direction. So resolution of min/max mipmap should be the same as the \n        // resolution of the original shadow map\n        m_PPAttribs.m_uiMinMaxShadowMapResolution = m_uiShadowMapResolution;\n\n        FrameAttribs.ptex2DSrcColorBufferSRV = m_pOffscreenRenderTarget->GetColorResourceView();\n        FrameAttribs.ptex2DSrcColorBufferRTV = m_pOffscreenRenderTarget->GetActiveRenderTargetView();\n        FrameAttribs.ptex2DSrcDepthBufferSRV = m_pOffscreenDepth->GetDepthResourceView();\n        FrameAttribs.ptex2DSrcDepthBufferDSV = m_pOffscreenDepth->GetActiveDepthStencilView();\n        FrameAttribs.ptex2DShadowMapSRV      = m_pShadowMapSRV;\n        FrameAttribs.pDstRTV                 = mpBackBufferRTV;\n\n        // Then perform the post processing, swapping the inverseworld view  projection matrix axes.\n        m_pLightSctrPP->PerformPostProcessing(FrameAttribs, m_PPAttribs);\n\n        m_pOffscreenRenderTarget->RestoreRenderTarget(drawParams);\n    }\n\n    // Draw GUI\n    //\n    if( m_iGUIMode )\n        CPUTDrawGUI();\n}\n\n// Handle the shutdown event - clean up everything you created\n//-----------------------------------------------------------------------------\nvoid COutdoorLightScatteringSample::Shutdown()\n{\n    CPUT_DX11::Shutdown();\n}\n\n\n// Entrypoint for your sample\n//-----------------------------------------------------------------------------\nint WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )\n{\n    UNREFERENCED_PARAMETER(hInstance);\n    UNREFERENCED_PARAMETER(hPrevInstance);\n    UNREFERENCED_PARAMETER(lpCmdLine);\n    UNREFERENCED_PARAMETER(nCmdShow);\n\n    // tell VS to report leaks at any exit of the program\n    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );\n\n    CPUTResult result=CPUT_SUCCESS;\n    int returnCode=0;\n\n    // create an instance of my sample\n    COutdoorLightScatteringSample* sample = new COutdoorLightScatteringSample(); \n\n\n    // Initialize the system and give it the base CPUT resource directory (location of GUI images/etc)\n    sample->CPUTInitialize(_L(\"CPUT//resources//\"));\n\n    // window parameters\n    CPUTWindowCreationParams params;\n    params.startFullscreen  = false;\n    params.windowPositionX = 64;\n    params.windowPositionY = 64;\n\n    // device parameters\n    params.deviceParams.refreshRate         = 60;\n    params.deviceParams.swapChainBufferCount= 1;\n    params.deviceParams.swapChainFormat     = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;\n    params.deviceParams.swapChainUsage      = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT;\n\n    // parse out the parameter settings\n    cString AssetFilename_NotUsed;\n    cString CommandLine(lpCmdLine);\n    sample->CPUTParseCommandLine(CommandLine, &params, &AssetFilename_NotUsed);       \n\n    // create the window and device context\n    result = sample->CPUTCreateWindowAndContext(_L(\"Outdoor Light Scattering Sample\"), params);\n    ASSERT( CPUTSUCCESS(result), _L(\"CPUT Error creating window and context.\") );\n\n    // start the main message loop\n    returnCode = sample->CPUTMessageLoop();\n\n\tsample->DeviceShutdown();\n\n    // cleanup resources\n    delete sample; \n\n    // exit\n    return returnCode;\n}\n"
  },
  {
    "path": "OutdoorLightScattering.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#pragma once\n\n#include <d3dx9math.h>\n\n#include \"Structures.fxh\"\n// Temporary:\n#undef float2\n#undef float3\n#undef float4\n\n#include <stdio.h>\n\n#include \"CPUT_DX11.h\"\n#include \"CPUTMaterial.h\"\n\n#include <D3D11.h> // for D3D11_BUFFER_DESC\n#include <xnamath.h> // for XMFLOAT\n\n#include <time.h> // for srand(time)\n\n#include \"EarthHemisphere.h\"\n#include \"ElevationDataSource.h\"\n\nstruct FrameConstantBuffer\n{\n    XMFLOAT4 Eye;\n    XMFLOAT4 LookAt;\n    XMFLOAT4 Up;\n    XMFLOAT4 LightDirection;  \n\n\tXMMATRIX  worldMatrix;\n    XMMATRIX  viewMatrix;\t\n\tXMMATRIX  projectionMatrix;\n};\n\nstatic const CPUTControlID ID_MAIN_PANEL = 10;\nstatic const CPUTControlID ID_ADDITIONAL_ATTRIBS_PANEL = 20;\nstatic const CPUTControlID ID_TONE_MAPPING_ATTRIBS_PANEL = 30;\nstatic const CPUTControlID ID_HELP_TEXT_PANEL = 40;\nstatic const CPUTControlID ID_IGNORE_CONTROL_ID = -1;\nstatic const CPUTControlID CONTROL_PANEL_IDS[] = {ID_MAIN_PANEL, ID_ADDITIONAL_ATTRIBS_PANEL, ID_TONE_MAPPING_ATTRIBS_PANEL};\n\nenum CONTROL_IDS\n{\n    ID_SELECT_PANEL_COMBO = 100,\n    ID_FULLSCREEN_BUTTON,\n    ID_ENABLE_VSYNC,\n    ID_ENABLE_LIGHT_SCATTERING,\n    ID_ENABLE_LIGHT_SHAFTS,\n    ID_ANIMATE_SUN,\n    ID_LIGHT_SCTR_TECHNIQUE,\n    ID_NUM_INTEGRATION_STEPS,\n    ID_NUM_EPIPOLAR_SLICES,\n    ID_NUM_SAMPLES_IN_EPIPOLAR_SLICE,\n    ID_INITIAL_SAMPLE_STEP_IN_EPIPOLAR_SLICE,\n    ID_EPIPOLE_SAMPLING_DENSITY_FACTOR,\n    ID_REFINEMENT_THRESHOLD,\n    ID_SHOW_SAMPLING,\n    ID_MIN_MAX_SHADOW_MAP_OPTIMIZATION,\n    ID_OPTIMIZE_SAMPLE_LOCATIONS,\n    ID_CORRECT_SCATTERING_AT_DEPTH_BREAKS,\n    ID_SCATTERING_SCALE,\n    ID_MIDDLE_GRAY,\n    ID_WHITE_POINT,\n    ID_LUM_SATURATION,\n    ID_AUTO_EXPOSURE,\n    ID_TONE_MAPPING_MODE,\n    ID_LIGHT_ADAPTATION,\n    ID_SHOW_DEPTH_BREAKS,   \n    ID_SHOW_LIGHTING_ONLY_CHECK,\n    ID_SHADOW_MAP_RESOLUTION,\n    ID_USE_CUSTOM_SCTR_COEFFS_CHECK,\n    ID_RLGH_COLOR_BTN,\n    ID_MIE_COLOR_BTN,\n    ID_SINGLE_SCTR_MODE_DROPDOWN,\n    ID_MULTIPLE_SCTR_MODE_DROPDOWN,\n    ID_NUM_CASCADES_DROPDOWN,\n    ID_SHOW_CASCADES_CHECK,\n    ID_SMOOTH_SHADOWS_CHECK,\n    ID_BEST_CASCADE_SEARCH_CHECK,\n    ID_CASCADE_PARTITIONING_SLIDER,\n    ID_CASCADE_PROCESSING_MODE_DROPDOWN,\n    ID_FIRST_CASCADE_TO_RAY_MARCH_DROPDOWN,\n    ID_REFINEMENT_CRITERION_DROPDOWN,\n    ID_EXTINCTION_EVAL_MODE_DROPDOWN,\n    ID_MIN_MAX_MIP_FORMAT_DROPDOWN,\n    ID_AEROSOL_DENSITY_SCALE_SLIDER,\n    ID_AEROSOL_ABSORBTION_SCALE_SLIDER,\n    ID_TEXTLINES = 1000\n};\n\n\n\n// DirectX 11 Sample\n//-----------------------------------------------------------------------------\nclass COutdoorLightScatteringSample:public CPUT_DX11\n{\npublic:\n    COutdoorLightScatteringSample();\n    virtual ~COutdoorLightScatteringSample();\n\n    // Event handling\n    virtual CPUTEventHandledCode HandleKeyboardEvent(CPUTKey key);\n    virtual CPUTEventHandledCode HandleMouseEvent(int x, int y, int wheel, CPUTMouseState state);\n    virtual void                 HandleCallbackEvent( CPUTEventID Event, CPUTControlID ControlID, CPUTControl* pControl );\n\n    // 'callback' handlers for rendering events.  Derived from CPUT_DX11\n    virtual void Create();\n    virtual void Render(double deltaSeconds);\n    virtual void Update(double deltaSeconds);\n    virtual void ResizeWindow(UINT width, UINT height);\n    \n    void Shutdown();\n\n    HRESULT ParseConfigurationFile( LPCWSTR ConfigFilePath );\n\nprivate:\n\n    HRESULT CreateShadowMap(ID3D11Device* pd3dDevice);\n    void ReleaseShadowMap();\n\n    HRESULT CreateTmpBackBuffAndDepthBuff(ID3D11Device* pd3dDevice);\n    void ReleaseTmpBackBuffAndDepthBuff();\n    \n    void RenderShadowMap(ID3D11DeviceContext *pContext, \n                         SLightAttribs &LightAttribs);\n\n    void Destroy();\n\n    float GetSceneExtent();\n\n    class CLightSctrPostProcess *m_pLightSctrPP;\n\n    UINT m_uiShadowMapResolution;\n    float m_fCascadePartitioningFactor;\n    bool m_bEnableLightScattering;\n    bool m_bAnimateSun;\n\n    static const int m_iMinEpipolarSlices = 32;\n    static const int m_iMaxEpipolarSlices = 2048;\n    static const int m_iMinSamplesInEpipolarSlice = 32;\n    static const int m_iMaxSamplesInEpipolarSlice = 2048;\n    static const int m_iMaxEpipoleSamplingDensityFactor = 32;\n    static const int m_iMinInitialSamplesInEpipolarSlice = 8;\n    SPostProcessingAttribs m_PPAttribs;\n    float m_fScatteringScale;\n\n    std::vector< CComPtr<ID3D11DepthStencilView> > m_pShadowMapDSVs;\n    CComPtr<ID3D11ShaderResourceView> m_pShadowMapSRV; \n\n    CPUTRenderTargetColor*  m_pOffscreenRenderTarget;\n    CPUTRenderTargetDepth*  m_pOffscreenDepth;\n\n    CPUTCamera*           m_pDirectionalLightCamera;\n    CPUTCamera*           m_pDirLightOrienationCamera;\n    CPUTCameraController* mpCameraController;\n    CPUTCameraController* m_pLightController;\n\n    CPUTTimerWin          m_Timer;\n    float                 m_fElapsedTime;\n\n    D3DXVECTOR4 m_f4LightColor;\n    \n    int m_iGUIMode;\n    \n    SRenderingParams m_TerrainRenderParams;\n\tstd::wstring m_strRawDEMDataFile;\n\tstd::wstring m_strMtrlMaskFile;\n    std::wstring m_strTileTexPaths[CEarthHemsiphere::NUM_TILE_TEXTURES];\n    std::wstring m_strNormalMapTexPaths[CEarthHemsiphere::NUM_TILE_TEXTURES];\n\n\tstd::auto_ptr<CElevationDataSource> m_pElevDataSource;\n\n    CEarthHemsiphere m_EarthHemisphere;\n\n    D3DXMATRIX  m_CameraViewMatrix;\n\tD3DXVECTOR3 m_CameraPos;\n\n    CComPtr<ID3D11Buffer> m_pcbLightAttribs;\n    UINT m_uiBackBufferWidth, m_uiBackBufferHeight;\n\n    CPUTDropdown* m_pSelectPanelDropDowns[3];\n    UINT m_uiSelectedPanelInd;\n\n    float m_fMinElevation, m_fMaxElevation;\nprivate:\n    COutdoorLightScatteringSample(const COutdoorLightScatteringSample&);\n    const COutdoorLightScatteringSample& operator = (const COutdoorLightScatteringSample&);\n};\n"
  },
  {
    "path": "OutdoorLightScattering_2010.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 11.00\n# Visual Studio 2010\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"OutdoorLightScatteringSample_2010\", \"OutdoorLightScattering_2010.vcxproj\", \"{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD} = {8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"CPUT-DX11\", \"CPUT\\CPUT-DX11.vcxproj\", \"{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Win32 = Debug|Win32\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|Win32 = Release|Win32\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}.Debug|x64.Build.0 = Debug|x64\n\t\t{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}.Release|Win32.Build.0 = Release|Win32\n\t\t{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}.Release|x64.ActiveCfg = Release|x64\n\t\t{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}.Release|x64.Build.0 = Release|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|x64.Build.0 = Debug|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|Win32.Build.0 = Release|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|x64.ActiveCfg = Release|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "OutdoorLightScattering_2010.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Profile|Win32\">\n      <Configuration>Profile</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Profile|x64\">\n      <Configuration>Profile</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"RenderTechnique.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Use</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"LightSctrPostProcess.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Use</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"OutdoorLightScattering.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Use</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\ConfigFile.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Use</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\EarthHemisphere.cpp\" />\n    <ClCompile Include=\"Terrain\\ElevationDataSource.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">Use</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Use</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\stdafx.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Create</PrecompiledHeader>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"RenderTechnique.h\" />\n    <ClInclude Include=\"LightSctrPostProcess.h\" />\n    <ClInclude Include=\"OutdoorLightScattering.h\" />\n    <ClInclude Include=\"ShaderMacroHelper.h\" />\n    <ClInclude Include=\"Terrain\\DynamicQuadTreeNode.h\" />\n    <ClInclude Include=\"Terrain\\EarthHemisphere.h\" />\n    <ClInclude Include=\"Terrain\\ElevationDataSource.h\" />\n    <ClInclude Include=\"Terrain\\Errors.h\" />\n    <ClInclude Include=\"Terrain\\HierarchyArray.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"fx\\Common.fxh\" />\n    <CustomBuild Include=\"fx\\LightScattering.fx\">\n      <FileType>Document</FileType>\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">fxc /I ..\\Core\\effects /T fx_5_0 %(FullPath) /Fc $(IntDir)fx_asm\\%(Filename).asm</Command>\n      <Outputs Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(IntDir)fx_asm\\%(Filename).asm;%(Outputs)</Outputs>\n    </CustomBuild>\n    <CustomBuild Include=\"fx\\RefineSampleLocations.fx\">\n      <FileType>Document</FileType>\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">fxc /I ..\\Core\\effects /T fx_5_0 %(FullPath) /Fc $(IntDir)fx_asm\\%(Filename).asm</Command>\n      <Outputs Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(IntDir)fx_asm\\%(Filename).asm;%(Outputs)</Outputs>\n    </CustomBuild>\n    <CustomBuild Include=\"fx\\Terrain.fx\">\n      <FileType>Document</FileType>\n      <Command Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">fxc /I ..\\Core\\effects /T fx_5_0 %(FullPath) /Fc $(IntDir)fx_asm\\%(Filename).asm</Command>\n      <Outputs Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">$(IntDir)fx_asm\\%(Filename).asm;%(Outputs)</Outputs>\n    </CustomBuild>\n    <None Include=\"fx\\Structures.fxh\" />\n    <None Include=\"fx\\TerrainStructs.fxh\" />\n    <None Include=\"OutdoorLightScattering.ico\" />\n    <None Include=\"small.ico\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"OutdoorLightScattering_2010.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"CPUT\\CPUT-DX11.vcxproj\">\n      <Project>{8b2ddedc-a574-4b24-aec5-03949b5f57bd}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{168ECB7C-9ECB-42FE-809E-28A0B3428F5F}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>SampleStartDX</RootNamespace>\n    <ProjectName>OutdoorLightScatteringSample</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>.\\;.\\Terrain;.\\fx;$(DXSDK_DIR)Include;$(IncludePath);CPUT\\CPUT;..\\Effects11\\Inc;..\\Effects11</IncludePath>\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x86</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <ExecutablePath>$(DXSDK_DIR)Utilities\\bin\\x86;$(ExecutablePath)</ExecutablePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <IncludePath>.\\;.\\Terrain;.\\fx;$(DXSDK_DIR)Include;$(IncludePath);CPUT\\CPUT;..\\Effects11\\Inc;..\\Effects11</IncludePath>\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x64;</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <ExecutablePath>$(DXSDK_DIR)Utilities\\bin\\x64;$(ExecutablePath)</ExecutablePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>.\\;.\\Terrain;.\\fx;$(DXSDK_DIR)Include;$(IncludePath);CPUT\\CPUT;..\\Effects11\\Inc;..\\Effects11</IncludePath>\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x86</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <ExecutablePath>$(DXSDK_DIR)Utilities\\bin\\x86;$(ExecutablePath)</ExecutablePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>.\\;.\\Terrain;.\\fx;$(DXSDK_DIR)Include;$(IncludePath);CPUT\\CPUT;$(GPA_INCLUDE_DIR);..\\Effects11\\Inc;..\\Effects11;..\\Effects11\\Inc</IncludePath>\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x86;$(GPA_LIBRARY_DIR)\\x86</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <ExecutablePath>$(DXSDK_DIR)Utilities\\bin\\x86;$(ExecutablePath)</ExecutablePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>.\\;.\\Terrain;.\\fx;$(DXSDK_DIR)Include;$(IncludePath);CPUT\\CPUT;..\\Effects11\\Inc;..\\Effects11</IncludePath>\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x64;</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <ExecutablePath>$(DXSDK_DIR)Utilities\\bin\\x64;$(ExecutablePath)</ExecutablePath>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <IncludePath>.\\;.\\Terrain;.\\fx;$(DXSDK_DIR)Include;$(IncludePath);CPUT\\CPUT;$(GPA_INCLUDE_DIR);..\\Effects11\\Inc;..\\Effects11;..\\Effects11\\Inc</IncludePath>\n    <LibraryPath>$(LibraryPath);$(DXSDK_DIR)Lib\\x64;$(GPA_LIBRARY_DIR)\\x64</LibraryPath>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <ExecutablePath>$(DXSDK_DIR)Utilities\\bin\\x64;$(ExecutablePath)</ExecutablePath>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>d3d11.lib;d3dx11.lib;d3dcompiler.lib;d3dx11d.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>d3d11.lib;d3dcompiler.lib;d3dx11d.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>d3d11.lib;d3dx11.lib;d3dcompiler.lib;d3dx11.lib;d3dx9.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <GenerateMapFile>false</GenerateMapFile>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;CPUT_GPA_INSTRUMENTATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>d3d11.lib;d3dx11.lib;d3dcompiler.lib;d3dx11.lib;d3dx9.lib;dxerr.lib;dxguid.lib;d3d9.lib;gpasdk_s.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <AdditionalLibraryDirectories>\n      </AdditionalLibraryDirectories>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>d3d11.lib;d3dx11.lib;d3dcompiler.lib;d3dx11.lib;d3dx9.lib;dxerr.lib;dxguid.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Profile|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;CPUT_GPA_INSTRUMENTATION;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>d3d11.lib;d3dx11.lib;d3dcompiler.lib;d3dx11.lib;d3dx9.lib;dxerr.lib;dxguid.lib;d3d9.lib;gpasdk_s.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <AdditionalLibraryDirectories>\n      </AdditionalLibraryDirectories>\n    </Link>\n  </ItemDefinitionGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "OutdoorLightScattering_2010.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n    <Filter Include=\"Sample Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Shaders\">\n      <UniqueIdentifier>{c95fe20e-27c4-40a1-8a03-55ccad7902ba}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Sample Files\\Terrain\">\n      <UniqueIdentifier>{95d79d31-6ee9-4479-9563-d42d7b270e31}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Sample Files\\Terrain\\fx\">\n      <UniqueIdentifier>{02e11d75-b0cc-4ec1-b99a-daa6c657d6c7}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Sample Files\\Terrain\\Source\">\n      <UniqueIdentifier>{b001a578-6ac0-43ae-962b-0403aea00dc5}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Sample Files\\Terrain\\Include\">\n      <UniqueIdentifier>{60d679d6-0738-4634-a1b4-4072d0924537}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"OutdoorLightScattering.cpp\">\n      <Filter>Sample Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"LightSctrPostProcess.cpp\">\n      <Filter>Sample Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"RenderTechnique.cpp\">\n      <Filter>Sample Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\stdafx.cpp\">\n      <Filter>Sample Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\ConfigFile.cpp\">\n      <Filter>Sample Files\\Terrain\\Source</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\ElevationDataSource.cpp\">\n      <Filter>Sample Files\\Terrain\\Source</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\EarthHemisphere.cpp\">\n      <Filter>Sample Files\\Terrain\\Source</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"OutdoorLightScattering.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"LightSctrPostProcess.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"RenderTechnique.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"ShaderMacroHelper.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\ElevationDataSource.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\Errors.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\EarthHemisphere.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\HierarchyArray.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\DynamicQuadTreeNode.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"small.ico\">\n      <Filter>Resource Files</Filter>\n    </None>\n    <None Include=\"OutdoorLightScattering.ico\">\n      <Filter>Resource Files</Filter>\n    </None>\n    <None Include=\"fx\\TerrainStructs.fxh\">\n      <Filter>Sample Files\\Terrain\\fx</Filter>\n    </None>\n    <None Include=\"fx\\Structures.fxh\">\n      <Filter>Shaders</Filter>\n    </None>\n    <None Include=\"fx\\Common.fxh\">\n      <Filter>Shaders</Filter>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"OutdoorLightScattering_2010.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <CustomBuild Include=\"fx\\LightScattering.fx\">\n      <Filter>Shaders</Filter>\n    </CustomBuild>\n    <CustomBuild Include=\"fx\\Terrain.fx\">\n      <Filter>Sample Files\\Terrain\\fx</Filter>\n    </CustomBuild>\n    <CustomBuild Include=\"fx\\RefineSampleLocations.fx\">\n      <Filter>Shaders</Filter>\n    </CustomBuild>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "OutdoorLightScattering_2012.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"OutdoorLightScattering_2012\", \"OutdoorLightScattering_2012.vcxproj\", \"{08459B5C-581A-4041-AD84-32490B6D0CEB}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"CPUT-DX11\", \"CPUT\\CPUT-DX11_2012.vcxproj\", \"{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Win32 = Debug|Win32\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|Win32 = Release|Win32\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{08459B5C-581A-4041-AD84-32490B6D0CEB}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{08459B5C-581A-4041-AD84-32490B6D0CEB}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{08459B5C-581A-4041-AD84-32490B6D0CEB}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{08459B5C-581A-4041-AD84-32490B6D0CEB}.Debug|x64.Build.0 = Debug|x64\n\t\t{08459B5C-581A-4041-AD84-32490B6D0CEB}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{08459B5C-581A-4041-AD84-32490B6D0CEB}.Release|Win32.Build.0 = Release|Win32\n\t\t{08459B5C-581A-4041-AD84-32490B6D0CEB}.Release|x64.ActiveCfg = Release|x64\n\t\t{08459B5C-581A-4041-AD84-32490B6D0CEB}.Release|x64.Build.0 = Release|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|Win32.ActiveCfg = Debug|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|Win32.Build.0 = Debug|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Debug|x64.Build.0 = Debug|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|Win32.ActiveCfg = Release|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|Win32.Build.0 = Release|Win32\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|x64.ActiveCfg = Release|x64\n\t\t{8B2DDEDC-A574-4B24-AEC5-03949B5F57BD}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "OutdoorLightScattering_2012.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{08459B5C-581A-4041-AD84-32490B6D0CEB}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>LightScattering_2012</RootNamespace>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v110</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v110</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v110</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v110</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <IncludePath>.\\;.\\fx;.\\Terrain;$(VCInstallDir)include;$(VCInstallDir)atlmfc\\include;$(WindowsSDK_IncludePath);$(DXSDK_DIR)Include;CPUT\\CPUT;..\\Effects11\\Inc;..\\Effects11</IncludePath>\n    <LibraryPath>$(DXSDK_DIR)Lib\\x86;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\\lib;$(WindowsSDK_LibraryPath_x86);</LibraryPath>\n    <TargetName>$(ProjectName)_D32</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <IncludePath>.\\;.\\fx;.\\Terrain;$(VCInstallDir)include;$(VCInstallDir)atlmfc\\include;$(WindowsSDK_IncludePath);$(DXSDK_DIR)Include;CPUT\\CPUT;..\\Effects11\\Inc;..\\Effects11</IncludePath>\n    <LibraryPath>$(DXSDK_DIR)Lib\\x64;$(VCInstallDir)lib\\amd64;$(VCInstallDir)atlmfc\\lib\\amd64;$(WindowsSDK_LibraryPath_x64);</LibraryPath>\n    <TargetName>$(ProjectName)_D64</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <IncludePath>.\\;.\\fx;.\\Terrain;$(VCInstallDir)include;$(VCInstallDir)atlmfc\\include;$(WindowsSDK_IncludePath);$(DXSDK_DIR)Include;CPUT\\CPUT;..\\Effects11\\Inc;..\\Effects11</IncludePath>\n    <LibraryPath>$(DXSDK_DIR)Lib\\x86;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\\lib;$(WindowsSDK_LibraryPath_x86);</LibraryPath>\n    <TargetName>$(ProjectName)_R32</TargetName>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <OutDir>$(SolutionDir)bin\\$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>bin\\$(Configuration)\\$(Platform)\\</IntDir>\n    <IncludePath>.\\;.\\fx;.\\Terrain;$(VCInstallDir)include;$(VCInstallDir)atlmfc\\include;$(WindowsSDK_IncludePath);$(DXSDK_DIR)Include;CPUT\\CPUT;..\\Effects11\\Inc;..\\Effects11</IncludePath>\n    <LibraryPath>$(DXSDK_DIR)Lib\\x64;$(VCInstallDir)lib\\amd64;$(VCInstallDir)atlmfc\\lib\\amd64;$(WindowsSDK_LibraryPath_x64);</LibraryPath>\n    <TargetName>$(ProjectName)_R64</TargetName>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>d3d11.lib;d3dx11.lib;d3dcompiler.lib;d3dx11d.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <AdditionalDependencies>d3d11.lib;d3dcompiler.lib;d3dx11d.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>d3d11.lib;d3dx11.lib;d3dcompiler.lib;d3dx11.lib;d3dx9.lib;dxerr.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>\n      </PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <AdditionalDependencies>d3d11.lib;d3dx11.lib;d3dcompiler.lib;d3dx11.lib;d3dx9.lib;dxerr.lib;dxguid.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <Image Include=\"OutdoorLightScattering.ico\" />\n    <Image Include=\"small.ico\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"fx\\LightScattering.fx\">\n      <FileType>Document</FileType>\n    </None>\n    <None Include=\"fx\\RefineSampleLocations.fx\">\n      <FileType>Document</FileType>\n    </None>\n    <None Include=\"fx\\Terrain.fx\">\n      <FileType>Document</FileType>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"fx\\Common.fxh\" />\n    <None Include=\"fx\\Structures.fxh\" />\n    <None Include=\"fx\\TerrainStructs.fxh\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"LightSctrPostProcess.h\" />\n    <ClInclude Include=\"OutdoorLightScattering.h\" />\n    <ClInclude Include=\"RenderTechnique.h\" />\n    <ClInclude Include=\"resource.h\" />\n    <ClInclude Include=\"ShaderMacroHelper.h\" />\n    <ClInclude Include=\"stdafx.h\" />\n    <ClInclude Include=\"Terrain\\DynamicQuadTreeNode.h\" />\n    <ClInclude Include=\"Terrain\\EarthHemisphere.h\" />\n    <ClInclude Include=\"Terrain\\ElevationDataSource.h\" />\n    <ClInclude Include=\"Terrain\\Errors.h\" />\n    <ClInclude Include=\"Terrain\\HierarchyArray.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"LightSctrPostProcess.cpp\" />\n    <ClCompile Include=\"OutdoorLightScattering.cpp\" />\n    <ClCompile Include=\"RenderTechnique.cpp\" />\n    <ClCompile Include=\"Terrain\\ConfigFile.cpp\" />\n    <ClCompile Include=\"Terrain\\EarthHemisphere.cpp\" />\n    <ClCompile Include=\"Terrain\\ElevationDataSource.cpp\" />\n    <ClCompile Include=\"Terrain\\stdafx.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Create</PrecompiledHeader>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"OutdoorLightScattering_2010.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"CPUT\\CPUT-DX11_2012.vcxproj\">\n      <Project>{8b2ddedc-a574-4b24-aec5-03949b5f57bd}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "OutdoorLightScattering_2012.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n    <Filter Include=\"Sample Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Sample Files\\Terrain\">\n      <UniqueIdentifier>{a449af6a-af21-4134-9018-aa784f199ca8}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Sample Files\\Terrain\\fx\">\n      <UniqueIdentifier>{cfd4dd41-e415-4640-87b2-5ff0e71f2c7a}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Sample Files\\Terrain\\Include\">\n      <UniqueIdentifier>{1071fe35-d241-48f9-80e9-f8cc34bcd67b}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Sample Files\\Terrain\\Source\">\n      <UniqueIdentifier>{abc3e307-fb25-4ab4-92d9-a6dcfcfe1ef1}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Sample Files\\Shaders\">\n      <UniqueIdentifier>{b182bc3b-b482-46c0-a1a9-797bd32b980c}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <Image Include=\"small.ico\">\n      <Filter>Resource Files</Filter>\n    </Image>\n    <Image Include=\"OutdoorLightScattering.ico\">\n      <Filter>Resource Files</Filter>\n    </Image>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"fx\\TerrainStructs.fxh\">\n      <Filter>Sample Files\\Terrain\\fx</Filter>\n    </None>\n    <None Include=\"fx\\Common.fxh\">\n      <Filter>Sample Files\\Shaders</Filter>\n    </None>\n    <None Include=\"fx\\Structures.fxh\">\n      <Filter>Sample Files\\Shaders</Filter>\n    </None>\n    <None Include=\"fx\\LightScattering.fx\">\n      <Filter>Sample Files\\Shaders</Filter>\n    </None>\n    <None Include=\"fx\\RefineSampleLocations.fx\">\n      <Filter>Sample Files\\Shaders</Filter>\n    </None>\n    <None Include=\"fx\\Terrain.fx\">\n      <Filter>Sample Files\\Terrain\\fx</Filter>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"Terrain\\DynamicQuadTreeNode.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\EarthHemisphere.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\ElevationDataSource.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\Errors.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Terrain\\HierarchyArray.h\">\n      <Filter>Sample Files\\Terrain\\Include</Filter>\n    </ClInclude>\n    <ClInclude Include=\"LightSctrPostProcess.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"OutdoorLightScattering.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"RenderTechnique.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"resource.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"ShaderMacroHelper.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"stdafx.h\">\n      <Filter>Sample Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"Terrain\\ConfigFile.cpp\">\n      <Filter>Sample Files\\Terrain\\Source</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\EarthHemisphere.cpp\">\n      <Filter>Sample Files\\Terrain\\Source</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\ElevationDataSource.cpp\">\n      <Filter>Sample Files\\Terrain\\Source</Filter>\n    </ClCompile>\n    <ClCompile Include=\"Terrain\\stdafx.cpp\">\n      <Filter>Sample Files\\Terrain\\Source</Filter>\n    </ClCompile>\n    <ClCompile Include=\"LightSctrPostProcess.cpp\">\n      <Filter>Sample Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"OutdoorLightScattering.cpp\">\n      <Filter>Sample Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"RenderTechnique.cpp\">\n      <Filter>Sample Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"OutdoorLightScattering_2010.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "RenderTechnique.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"stdafx.h\"\n\n#include \"RenderTechnique.h\"\n#include <D3DX11.h>\n#include <D3Dcompiler.h>\n#include <fstream>\n\nCRenderTechnique::CRenderTechnique(void)\n{\n}\n\n\nCRenderTechnique::~CRenderTechnique(void)\n{\n}\n\nvoid CRenderTechnique::Release()\n{\n    m_pVS.Release();\n    m_pGS.Release();\n    m_pPS.Release();\n    m_pCS.Release();\n    m_pRS.Release();\n    m_pDS.Release();\n    m_pBS.Release();\n\tm_pVSByteCode.Release();\n    m_pContext.Release();\n    m_pDevice.Release();\n}\n\nstatic\nHRESULT CompileShaderFromFile(LPCTSTR strFilePath, \n                              LPCSTR strFunctionName,\n                              const D3D_SHADER_MACRO* pDefines, \n                              LPCSTR profile, \n                              ID3DBlob **ppBlobOut)\n{\n    DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;\n#if defined( DEBUG ) || defined( _DEBUG )\n    // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders.\n    // Setting this flag improves the shader debugging experience, but still allows \n    // the shaders to be optimized and to run exactly the way they will run in \n    // the release configuration of this program.\n    dwShaderFlags |= D3D10_SHADER_DEBUG;\n#else\n    // Warning: do not use this flag as it causes shader compiler to fail the compilation and \n    // report strange errors:\n    // dwShaderFlags |= D3D10_SHADER_OPTIMIZATION_LEVEL3;\n#endif\n\tHRESULT hr;\n\tdo\n\t{\n\t\tCComPtr<ID3DBlob> errors;\n        hr = D3DX11CompileFromFile(strFilePath, pDefines, NULL, strFunctionName, profile, dwShaderFlags, 0, NULL, ppBlobOut, &errors, NULL);\n\t\tif( errors )\n\t\t{\n\t\t\tOutputDebugStringA((char*) errors->GetBufferPointer());\n\t\t\tif( FAILED(hr) && \n\t\t\t\tIDRETRY != MessageBoxA(NULL, (char*) errors->GetBufferPointer(), \"FX Error\", MB_ICONERROR|MB_ABORTRETRYIGNORE) )\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} while( FAILED(hr) );\n\treturn hr;\n}\n\nHRESULT CRenderTechnique::CreateVertexShaderFromFile(LPCTSTR strFilePath, \n                                                      LPSTR strFunctionName,\n                                                      const D3D_SHADER_MACRO* pDefines)\n{\n\tHRESULT hr;\n    m_pVSByteCode.Release();\n    hr = CompileShaderFromFile( strFilePath, strFunctionName, pDefines, \"vs_5_0\", &m_pVSByteCode );\n    if(FAILED(hr))return hr;\n\n    m_pVS.Release();\n    if( m_pDevice )\n        hr = m_pDevice->CreateVertexShader( m_pVSByteCode->GetBufferPointer(), m_pVSByteCode->GetBufferSize(), NULL, &m_pVS );\n    else\n        return E_FAIL;\n\n    return hr;\n}\n\nHRESULT CRenderTechnique::CreateGeometryShaderFromFile(LPCTSTR strFilePath, \n                                                        LPSTR strFunctionName,\n                                                        const D3D_SHADER_MACRO* pDefines)\n{\n    CComPtr<ID3DBlob> pShaderByteCode;\n\n    HRESULT hr;\n    hr = CompileShaderFromFile( strFilePath, strFunctionName, pDefines, \"gs_5_0\", &pShaderByteCode );\n    if(FAILED(hr))return hr;\n\n    m_pGS.Release();\n    if( m_pDevice )\n        hr = m_pDevice->CreateGeometryShader( pShaderByteCode->GetBufferPointer(), pShaderByteCode->GetBufferSize(), NULL, &m_pGS );\n    else\n        return E_FAIL;\n\n    return hr;\n}\n\nHRESULT CRenderTechnique::CreatePixelShaderFromFile(LPCTSTR strFilePath, \n                                                     LPSTR strFunctionName,\n                                                     const D3D_SHADER_MACRO* pDefines)\n{\n    CComPtr<ID3DBlob> pShaderByteCode;\n\n    HRESULT hr;\n    hr = CompileShaderFromFile( strFilePath, strFunctionName, pDefines, \"ps_5_0\", &pShaderByteCode );\n    if(FAILED(hr))return hr;\n\n    m_pPS.Release();\n    if( m_pDevice )\n        hr = m_pDevice->CreatePixelShader( pShaderByteCode->GetBufferPointer(), pShaderByteCode->GetBufferSize(), NULL, &m_pPS );\n    else\n        return E_FAIL;\n\n    return hr;\n}\n\nHRESULT CRenderTechnique::CreateComputeShaderFromFile(LPCTSTR strFilePath, \n                                                       LPSTR strFunctionName,\n                                                       const D3D_SHADER_MACRO* pDefines)\n{\n    CComPtr<ID3DBlob> pShaderByteCode;\n\n    HRESULT hr;\n    hr = CompileShaderFromFile( strFilePath, strFunctionName, pDefines, \"cs_5_0\", &pShaderByteCode );\n    if(FAILED(hr))return hr;\n\n    m_pCS.Release();\n    if( m_pDevice )\n        hr = m_pDevice->CreateComputeShader( pShaderByteCode->GetBufferPointer(), pShaderByteCode->GetBufferSize(), NULL, &m_pCS );\n    else\n        return E_FAIL;\n\n    return hr;\n}\n\nHRESULT CRenderTechnique::CreateVGPShadersFromFile(LPCTSTR strFilePath, \n                                                    LPSTR strVSFunctionName, \n                                                    LPSTR strGSFunctionName, \n                                                    LPSTR strPSFunctionName, \n                                                    const D3D_SHADER_MACRO* pDefines)\n{\n    HRESULT hr = S_OK;\n    if( strVSFunctionName )\n    {\n        hr = CreateVertexShaderFromFile(strFilePath, strVSFunctionName, pDefines);\n        if( FAILED(hr) )return hr;\n    }\n\n    if( strPSFunctionName )\n    {\n        hr = CreatePixelShaderFromFile(strFilePath, strPSFunctionName, pDefines);\n        if( FAILED(hr) )return hr;\n    }\n\n    if( strGSFunctionName )\n    {\n        hr = CreateGeometryShaderFromFile(strFilePath, strGSFunctionName, pDefines);\n        if( FAILED(hr) )return hr;\n    }\n\n    return hr;\n}\n\nvoid CRenderTechnique::Apply()\n{\n    m_pContext->HSSetShader(NULL, NULL, 0);\n    m_pContext->DSSetShader(NULL, NULL, 0);\n    m_pContext->VSSetShader(m_pVS, NULL, 0);\n    m_pContext->GSSetShader(m_pGS, NULL, 0);\n    m_pContext->PSSetShader(m_pPS, NULL, 0);\n    m_pContext->CSSetShader(m_pCS, NULL, 0);\n    m_pContext->RSSetState(m_pRS);\n    m_pContext->OMSetDepthStencilState(m_pDS, m_uiSampleRef);  \n    float fBlendFactor[] = {0, 0, 0, 0};\n    m_pContext->OMSetBlendState(m_pBS, fBlendFactor, 0xFFFFFFFF);\n}\n\nHRESULT CRenderTechnique::CreateDefaultBlendState()\n{\n    HRESULT hr;\n    D3D11_BLEND_DESC DefaultBlendStateDesc;\n    ZeroMemory(&DefaultBlendStateDesc, sizeof(DefaultBlendStateDesc));\n    DefaultBlendStateDesc.IndependentBlendEnable = FALSE;\n    for(int i=0; i< _countof(DefaultBlendStateDesc.RenderTarget); i++)\n        DefaultBlendStateDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;\n    V( m_pDevice->CreateBlendState( &DefaultBlendStateDesc, &m_pBS) );\n    \n    return hr;\n}\n\nHRESULT CRenderTechnique::CreateDefaultDepthState(BOOL bEnableDepth, \n                                                  D3D11_DEPTH_WRITE_MASK WriteMask)\n{\n    HRESULT hr;\n    \n    D3D11_DEPTH_STENCIL_DESC DSDesc;\n    ZeroMemory(&DSDesc, sizeof(DSDesc));\n    DSDesc.DepthEnable = bEnableDepth;\n    DSDesc.DepthWriteMask = WriteMask;\n    DSDesc.DepthFunc = D3D11_COMPARISON_GREATER;\n    CComPtr<ID3D11DepthStencilState> pDisableDepthTestDS;\n    V( m_pDevice->CreateDepthStencilState(  &DSDesc, &m_pDS) );\n\n    return hr;\n}\n\nHRESULT CRenderTechnique::CreateDefaultRasterizerState(D3D11_FILL_MODE FillMode,\n                                                       D3D11_CULL_MODE CullMode,\n                                                       BOOL bIsFrontCCW)\n{\n    HRESULT hr;\n\n    D3D11_RASTERIZER_DESC RSDesc;\n    ZeroMemory(&RSDesc, sizeof(RSDesc));\n    RSDesc.FillMode = FillMode;\n    RSDesc.CullMode = CullMode;\n    RSDesc.FrontCounterClockwise = bIsFrontCCW;\n    CComPtr<ID3D11RasterizerState> pRSSolidFillNoCull;\n    V( m_pDevice->CreateRasterizerState( &RSDesc, &m_pRS) );\n\n    return hr;\n}\n\nHRESULT CRenderTechnique::CreateSampler(ID3D11SamplerState **ppSamplerState,\n                                        D3D11_FILTER Filter, \n                                        D3D11_TEXTURE_ADDRESS_MODE AddressMode)\n{\n    \n    D3D11_SAMPLER_DESC SamDesc = \n    {\n        Filter,\n        AddressMode,\n        AddressMode,\n        AddressMode,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_NEVER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    \n    HRESULT hr = m_pDevice->CreateSamplerState(&SamDesc, ppSamplerState);\n    return hr;\n}\n"
  },
  {
    "path": "RenderTechnique.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#pragma once\n\n#include <D3D11.h>\n#include <atlcomcli.h>\n\nclass CRenderTechnique\n{\npublic:\n    CRenderTechnique(void);\n    ~CRenderTechnique(void);\n\n    void Release();\n    void SetDeviceAndContext(ID3D11Device *pDevice, ID3D11DeviceContext *pCtx){m_pDevice = pDevice; m_pContext = pCtx;}\n    void Apply();\n\n    ID3D11VertexShader      * GetVS(){return m_pVS;}\n    ID3D11GeometryShader    * GetGS(){return m_pGS;}\n    ID3D11PixelShader       * GetPS(){return m_pPS;}\n    ID3D11ComputeShader     * GetCS(){return m_pCS;}\n    ID3D11RasterizerState   * GetRS(){return m_pRS;}\n    ID3D11DepthStencilState * GetDS(){return m_pDS;}\n    ID3D11BlendState        * GetBS(){return m_pBS;}\n\tID3DBlob\t\t\t\t* GetVSByteCode(){return m_pVSByteCode;}\n\n    void SetVS(ID3D11VertexShader      *pVS ){m_pVS = pVS;}\n    void SetGS(ID3D11GeometryShader    *pGS ){m_pGS = pGS;}\n    void SetPS(ID3D11PixelShader       *pPS ){m_pPS = pPS;}\n    void SetCS(ID3D11ComputeShader     *pCS ){m_pCS = pCS;}\n    void SetRS(ID3D11RasterizerState   *pRS ){m_pRS = pRS;}\n    void SetDS(ID3D11DepthStencilState *pDS, UINT uiSampleRef = 0 ){m_pDS = pDS; m_uiSampleRef = uiSampleRef;}\n    void SetBS(ID3D11BlendState        *pBS ){m_pBS = pBS;}\n\n    HRESULT CreateVertexShaderFromFile   (LPCTSTR strFilePath, LPSTR strFunctionName, const D3D_SHADER_MACRO* pDefines);\n    HRESULT CreateGeometryShaderFromFile (LPCTSTR strFilePath, LPSTR strFunctionName, const D3D_SHADER_MACRO* pDefines);\n    HRESULT CreatePixelShaderFromFile    (LPCTSTR strFilePath, LPSTR strFunctionName, const D3D_SHADER_MACRO* pDefines);\n    HRESULT CreateComputeShaderFromFile  (LPCTSTR strFilePath, LPSTR strFunctionName, const D3D_SHADER_MACRO* pDefines);\n    \n    HRESULT CreateVGPShadersFromFile     (LPCTSTR strFilePath, LPSTR strVSFunctionName, LPSTR strGSFunctionName, LPSTR strPSFunctionName, const D3D_SHADER_MACRO* pDefines);\n\n    bool IsValid(){ return m_pDevice && m_pContext && (m_pPS || m_pCS);}\n\n    HRESULT CreateDefaultBlendState();\n    HRESULT CreateDefaultDepthState(BOOL bEnableDepth = TRUE, D3D11_DEPTH_WRITE_MASK WriteMask = D3D11_DEPTH_WRITE_MASK_ALL);\n    HRESULT CreateDefaultRasterizerState(D3D11_FILL_MODE FillMode = D3D11_FILL_SOLID,\n                                         D3D11_CULL_MODE CullMode = D3D11_CULL_BACK,\n                                         BOOL bIsFrontCCW = FALSE);\n\n    HRESULT CreateSampler(ID3D11SamplerState **ppSamplerState,\n                          D3D11_FILTER Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR,\n                          D3D11_TEXTURE_ADDRESS_MODE AddressMode = D3D11_TEXTURE_ADDRESS_CLAMP);\n\nprivate:\n    CComPtr<ID3D11Device> m_pDevice;\n    CComPtr<ID3D11DeviceContext> m_pContext;\n    CComPtr<ID3D11VertexShader> m_pVS;\n    CComPtr<ID3D11GeometryShader> m_pGS;\n    CComPtr<ID3D11PixelShader> m_pPS;\n    CComPtr<ID3D11ComputeShader> m_pCS;\n    CComPtr<ID3D11RasterizerState> m_pRS;\n    CComPtr<ID3D11DepthStencilState> m_pDS;\n    CComPtr<ID3D11BlendState> m_pBS;\n    UINT m_uiSampleRef;\n\tCComPtr<ID3DBlob> m_pVSByteCode;\n};\n"
  },
  {
    "path": "ShaderMacroHelper.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include <set>\n#include <vector>\n#include <sstream>\n\nclass CD3DShaderMacroHelper\n{\npublic:\n    CD3DShaderMacroHelper() : m_bIsFinalized(false) {}\n\n    template<typename DefintionType>\n\tvoid AddShaderMacro( LPCSTR Name, DefintionType Definition )\n\t{\n        assert( !m_bIsFinalized );\n\t\tstd::ostringstream ss;\n\t\tss << Definition;\n\t\tAddShaderMacro<LPCSTR>( Name, ss.str().c_str() );\n\t}\n\n\ttemplate<>\n\tvoid AddShaderMacro( LPCSTR Name, LPCSTR Definition )\n\t{\n        assert( !m_bIsFinalized );\n\t\tD3D_SHADER_MACRO NewMacro = \n\t\t{\n\t\t\tName,\n\t\t\tm_DefinitionsPull.insert(Definition).first->c_str()\n\t\t};\n\t\tm_Macroes.push_back(NewMacro);\n\t}\n\n\ttemplate<>\n\tvoid AddShaderMacro( LPCSTR Name, bool Definition )\n\t{\n        assert( !m_bIsFinalized );\n\t\tAddShaderMacro( Name, Definition ? \"1\" : \"0\");\n\t}\n\t\n    void Finalize()\n\t{\n\t\tD3D_SHADER_MACRO LastMacro = {NULL, NULL};\n\t\tm_Macroes.push_back(LastMacro);\n        m_bIsFinalized = true;\n\t}\n\n\toperator const D3D_SHADER_MACRO* ()\n\t{\n        assert( !m_Macroes.size() || m_bIsFinalized );\n        if( m_Macroes.size() && !m_bIsFinalized )\n            Finalize();\n        return m_Macroes.size() ? &m_Macroes[0] : NULL;\n\t}\n    \nprivate:\n\n\tstd::vector< D3D_SHADER_MACRO > m_Macroes;\n\tstd::set< std::string > m_DefinitionsPull;\n    bool m_bIsFinalized;\n};\n"
  },
  {
    "path": "Terrain/ConfigFile.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"stdafx.h\"\n#include \"OutdoorLightScattering.h\"\n\n// Parses the string as bool value\nHRESULT ParseParameterBool( LPWSTR Value, bool &BoolValue )\n{\n    if( wcscmp(L\"true\", Value) == 0 )\n        BoolValue = true;\n    else if( wcscmp(L\"false\", Value) == 0 )\n        BoolValue = false;\n    else\n    {\n        CHECK_HR_RET( E_FAIL, L\"\\\"%s\\\" is not correct boolean value. Only \\\"true\\\" and \\\"false\\\" are allowed\", Value);\n    }\n    return S_OK;\n}\n\n// Parses the string as float value\nfloat ParseParameterFloat( LPWSTR Value )\n{\n    float FloatVal;\n    _stscanf_s( Value, L\"%f\", &FloatVal );\n    return FloatVal;\n}\n\n// Parses the string as int value\nint ParseParameterInt( LPWSTR Value )\n{\n    int IntVal;\n    _stscanf_s( Value, L\"%d\", &IntVal);\n    return IntVal;\n}\n\n// Parses the string as string value\nvoid ParseParameterString( std::wstring &StringValue, FILE *pFile )\n{\n\tStringValue.clear();\n    // Read space\n    fgetc(pFile);\n\twhile( !feof(pFile) )\n\t{\n\t\tWCHAR CurrSymb = fgetc(pFile);\n\t\tif( CurrSymb != L'\\n' && CurrSymb != 65535 )\n\t\t\tStringValue += CurrSymb;\n\t\telse\n\t\t\tbreak;\n\t}\n}\n\nvoid ParseParameterString( LPWSTR StringValue, int MaxLen, FILE *pFile )\n{\n    // Read space\n    fgetc(pFile);\n    fgetws(StringValue, MaxLen, pFile);\n    size_t len = wcslen(StringValue);\n    // Remove \\n from the end of the line \n    if( StringValue[len-1] == L'\\n' ) \n        StringValue[len-1] = L'\\0';\n}\n\n// Parses the configuration file\nHRESULT COutdoorLightScatteringSample :: ParseConfigurationFile( LPCWSTR ConfigFilePath )\n{\n\tm_strRawDEMDataFile.clear();\n\tm_strMtrlMaskFile.clear();\n\n    FILE *pConfigFile = NULL;\n    if( _tfopen_s( &pConfigFile, ConfigFilePath, _T(\"r\") ) != 0 )\n    {\n        CHECK_HR_RET(E_FAIL, L\"Failed to open the configuration file (%s)\", ConfigFilePath);\n    }\n    \n    while( !feof(pConfigFile) )\n    {\n        TCHAR Parameter[128];\n        TCHAR EqualSign[128];\n\n        _ftscanf_s( pConfigFile, _T(\"%s\"), Parameter, _countof(Parameter));\n        _ftscanf_s( pConfigFile, _T(\"%s\"), EqualSign, _countof(EqualSign));\n        if( wcscmp(EqualSign, L\"=\") != 0 )\n        {\n            LOG_ERROR( L\"Equal sign (=) is missing for parameter \\\"%s\\\"\", Parameter);\n            goto ERROR_EXIT;\n        }\n\n        if( wcscmp(L\"RawDEMDataFile\", Parameter) == 0 )\n        {\n            ParseParameterString(m_strRawDEMDataFile, pConfigFile);\n        }\n\t\telse if( wcscmp(L\"MaterialMaskFile\", Parameter) == 0 )\n        {\n            ParseParameterString(m_strMtrlMaskFile, pConfigFile);\n        }\n        else if( wcsncmp(L\"TileTexture\", Parameter, _tcslen(L\"TileTexture\")) == 0 )\n        {\n            int iTileNum = _tstoi(Parameter + _tcslen(L\"TileTexture\") );\n\t\t\tif( iTileNum >= 0 && iTileNum < CEarthHemsiphere::NUM_TILE_TEXTURES )\n            {\n                ParseParameterString(m_strTileTexPaths[iTileNum], pConfigFile);  \n            }\n        }\n        else if( wcsncmp(L\"TileNormalMap\", Parameter, _tcslen(L\"TileNormalMap\")) == 0 )\n        {\n            int iTileNum = _tstoi(Parameter + _tcslen(L\"TileNormalMap\") );\n\t\t\tif( iTileNum >= 0 && iTileNum < CEarthHemsiphere::NUM_TILE_TEXTURES )\n            {\n                ParseParameterString(m_strNormalMapTexPaths[iTileNum], pConfigFile);  \n            }\n        }\n        else if( wcscmp(L\"TexturingMode\", Parameter) == 0 )\n        {\n            TCHAR Value[128];\n            ParseParameterString(Value, _countof(Value), pConfigFile);\n            if( wcscmp(L\"HeightBased\", Value) == 0 )\n                m_TerrainRenderParams.m_TexturingMode = SRenderingParams::TM_HEIGHT_BASED;\n            else if( wcscmp(L\"MaterialMask\", Value) == 0 )\n                m_TerrainRenderParams.m_TexturingMode = SRenderingParams::TM_MATERIAL_MASK;\n            else if( wcscmp(L\"MaterialMaskNM\", Value) == 0 )\n                m_TerrainRenderParams.m_TexturingMode = SRenderingParams::TM_MATERIAL_MASK_NM;\n            else \n                LOG_ERROR( L\"Unknown texturing mode (%s)\\n\"\n                           L\"Only the following modes are recognized:\\n\"\n                           L\"HeightBased\\n\", Value);\n        }\n        else\n        {\n            TCHAR Value[128];\n            _ftscanf_s( pConfigFile, _T(\"%s\"), Value, _countof(Value));\n\n            // Parameters\n            if( wcscmp(L\"ElevationSamplingInterval\", Parameter) == 0 )\n            {\n                m_TerrainRenderParams.m_TerrainAttribs.m_fElevationSamplingInterval = ParseParameterFloat( Value );\n            }\n            else if(wcsncmp(L\"TilingScale\", Parameter, _tcslen(L\"TilingScale\")) == 0 )\n            {\n                int iTileNum = _tstoi(Parameter + _tcslen(L\"TilingScale\") );\n                if( iTileNum == 0 )\n                {\n                    m_TerrainRenderParams.m_TerrainAttribs.m_fBaseMtrlTilingScale = ParseParameterFloat( Value );\n                }\n\t\t\t    else if( iTileNum >= 1 && iTileNum < CEarthHemsiphere::NUM_TILE_TEXTURES )\n                {\n                    ((float*)&m_TerrainRenderParams.m_TerrainAttribs.m_f4TilingScale)[iTileNum-1] = ParseParameterFloat( Value );\n                }\n            }\n            else if( wcscmp(L\"RingDimension\", Parameter) == 0 )\n            {\n                m_TerrainRenderParams.m_iRingDimension = ParseParameterInt( Value );\n            }\n            else if( wcscmp(L\"NumRings\", Parameter) == 0 )\n            {\n                m_TerrainRenderParams.m_iNumRings = ParseParameterInt( Value );\n            }\n            else if( wcscmp(L\"ColOffset\", Parameter) == 0 )\n            {\n                m_TerrainRenderParams.m_iColOffset = ParseParameterInt( Value );\n            } \n            else if( wcscmp(L\"RowOffset\", Parameter) == 0 )\n            {\n                m_TerrainRenderParams.m_iRowOffset = ParseParameterInt( Value );\n            } \n            else if( wcscmp(L\"AnimateSun\", Parameter) == 0 )\n            {\n                ParseParameterBool( Value, m_bAnimateSun );\n            } \n        }\n    }\n\n    fclose(pConfigFile);\n\n    return S_OK;\n\nERROR_EXIT:\n\n    fclose(pConfigFile);\n\n    return E_FAIL;\n}\n"
  },
  {
    "path": "Terrain/DynamicQuadTreeNode.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#pragma once\n\n#include <memory>\n\n// Structure describing quad tree node location\nstruct SQuadTreeNodeLocation\n{\n    // Position in a tree\n\tint horzOrder;\n\tint vertOrder;\n\tint level;\n\n\tSQuadTreeNodeLocation(int h, int v, int l)\n\t\t: horzOrder(h)\n\t\t, vertOrder(v)\n\t\t, level(l)\n\t{\n\t\tassert(h < (1 << l));\n\t\tassert(v < (1 << l));\n\t}\n\tSQuadTreeNodeLocation()\n\t\t: horzOrder(0)\n\t\t, vertOrder(0)\n\t\t, level(0)\n\t{}\n\n    // Gets location of a child\n\tinline friend SQuadTreeNodeLocation GetChildLocation(const SQuadTreeNodeLocation &parent,\n\t\tunsigned int siblingOrder)\n\t{\n\t\treturn SQuadTreeNodeLocation(parent.horzOrder * 2 + (siblingOrder&1),\n\t\t\tparent.vertOrder * 2 + (siblingOrder>>1),\n\t\t\tparent.level + 1);\n\t}\n\n    // Gets location of a parent\n\tinline friend SQuadTreeNodeLocation GetParentLocation(const SQuadTreeNodeLocation &node)\n\t{\n\t\tassert(node.level > 0);\n\t\treturn SQuadTreeNodeLocation(node.horzOrder / 2, node.vertOrder / 2, node.level - 1);\n\t}\n};\n\n// Base class for iterators traversing the quad tree\nclass HierarchyIteratorBase\n{\npublic:\n\toperator const SQuadTreeNodeLocation& () const { return m_current; }\n\tint Level() const { return m_current.level; }\n\tint Horz()  const { return m_current.horzOrder; }\n\tint Vert()  const { return m_current.vertOrder; }\nprotected:\n\tSQuadTreeNodeLocation m_current;\n\tint m_currentLevelSize;\n};\n\n// Iterator for recursively traversing the quad tree starting from the root up to the specified level\nclass HierarchyIterator : public HierarchyIteratorBase\n{\npublic:\n\tHierarchyIterator(int nLevels)\n\t\t: m_nLevels(nLevels)\n\t{\n\t\tm_currentLevelSize = 1;\n\t}\n\tbool IsValid() const { return m_current.level < m_nLevels; }\n\tvoid Next()\n\t{\n\t\tif( ++m_current.horzOrder == m_currentLevelSize )\n\t\t{\n\t\t\tm_current.horzOrder = 0;\n\t\t\tif( ++m_current.vertOrder == m_currentLevelSize )\n\t\t\t{\n\t\t\t\tm_current.vertOrder = 0;\n\t\t\t\tm_currentLevelSize = 1 << ++m_current.level;\n\t\t\t}\n\t\t}\n\t}\n\nprivate:\n\tint m_nLevels;\n};\n\n// Iterator for recursively traversing the quad tree starting from the specified level up to the root\nclass HierarchyReverseIterator : public HierarchyIteratorBase\n{\npublic:\n\tHierarchyReverseIterator(int nLevels)\n\t{\n\t\tm_current.level = nLevels - 1;\n\t\tm_currentLevelSize = 1 << m_current.level;\n\t}\n\tbool IsValid() const { return m_current.level >= 0; }\n\tvoid Next()\n\t{\n\t\tif( ++m_current.horzOrder == m_currentLevelSize )\n\t\t{\n\t\t\tm_current.horzOrder = 0;\n\t\t\tif( ++m_current.vertOrder == m_currentLevelSize )\n\t\t\t{\n\t\t\t\tm_current.vertOrder = 0;\n\t\t\t\tm_currentLevelSize = 1 << --m_current.level;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Template class for the node of a dynamic quad tree\ntemplate<typename NodeDataType>\nclass CDynamicQuadTreeNode\n{\npublic:\n    CDynamicQuadTreeNode() : \n        m_pAncestor(NULL)\n    {\n    }\n\n    NodeDataType &GetData(){return m_Data;}\n    const NodeDataType &GetData()const{return m_Data;}\n\n    CDynamicQuadTreeNode *GetAncestor() const        { return m_pAncestor; }\n    void GetDescendants(const CDynamicQuadTreeNode* &LBDescendant,\n                        const CDynamicQuadTreeNode* &RBDescendant,\n                        const CDynamicQuadTreeNode* &LTDescendant,\n                        const CDynamicQuadTreeNode* &RTDescendant) const\n    {\n        LBDescendant = m_pLBDescendant.get();\n        RBDescendant = m_pRBDescendant.get();\n        LTDescendant = m_pLTDescendant.get();\n        RTDescendant = m_pRTDescendant.get();\n    }\n\n    void GetDescendants(CDynamicQuadTreeNode* &LBDescendant,\n                        CDynamicQuadTreeNode* &RBDescendant,\n                        CDynamicQuadTreeNode* &LTDescendant,\n                        CDynamicQuadTreeNode* &RTDescendant)\n    {\n        LBDescendant = m_pLBDescendant.get();\n        RBDescendant = m_pRBDescendant.get();\n        LTDescendant = m_pLTDescendant.get();\n        RTDescendant = m_pRTDescendant.get();\n    }\n\n    typedef std::auto_ptr<CDynamicQuadTreeNode<NodeDataType> > AutoPtrType;\n    // Attahes specified descendants to the tree\n    void CreateDescendants(AutoPtrType pLBDescendant,\n                           AutoPtrType pRBDescendant,\n                           AutoPtrType pLTDescendant,\n                           AutoPtrType pRTDescendant);\n    // Creates descendants UNATTACHED to the tree\n    void CreateFloatingDescendants(AutoPtrType &pLBDescendant,\n                                   AutoPtrType &pRBDescendant,\n                                   AutoPtrType &pLTDescendant,\n                                   AutoPtrType &pRTDescendant);\n    // Destroys ALL descendants for the node\n    void DestroyDescendants();\n\n\tconst SQuadTreeNodeLocation& GetPos() const { return m_pos; }\n\n\tvoid SetPos(const SQuadTreeNodeLocation& pos){ m_pos = pos; }\n\nprivate:\n    CDynamicQuadTreeNode(CDynamicQuadTreeNode *pAncestor, int iSiblingOrder) : \n        m_pAncestor(pAncestor),\n        m_pos(GetChildLocation(pAncestor->m_pos, iSiblingOrder))\n    {\n    }\n\n    NodeDataType m_Data;\n\n    std::auto_ptr< CDynamicQuadTreeNode > m_pLBDescendant;\n    std::auto_ptr< CDynamicQuadTreeNode > m_pRBDescendant;\n    std::auto_ptr< CDynamicQuadTreeNode > m_pLTDescendant;\n    std::auto_ptr< CDynamicQuadTreeNode > m_pRTDescendant;\n    CDynamicQuadTreeNode *m_pAncestor;\n\n    SQuadTreeNodeLocation m_pos;\n};\n\ntemplate<typename NodeDataType>\nvoid CDynamicQuadTreeNode<NodeDataType>::CreateFloatingDescendants(AutoPtrType &pLBDescendant,\n                                                                   AutoPtrType &pRBDescendant,\n                                                                   AutoPtrType &pLTDescendant,\n                                                                   AutoPtrType &pRTDescendant)\n{\n    pLBDescendant.reset(new CDynamicQuadTreeNode<NodeDataType>(this, 0));\n    pRBDescendant.reset(new CDynamicQuadTreeNode<NodeDataType>(this, 1));\n    pLTDescendant.reset(new CDynamicQuadTreeNode<NodeDataType>(this, 2));\n    pRTDescendant.reset(new CDynamicQuadTreeNode<NodeDataType>(this, 3));\n}\n\ntemplate<typename NodeDataType>\nvoid CDynamicQuadTreeNode<NodeDataType>::CreateDescendants(AutoPtrType pLBDescendant,\n                                                           AutoPtrType pRBDescendant,\n                                                           AutoPtrType pLTDescendant,\n                                                           AutoPtrType pRTDescendant)\n{\n    assert( !m_pLBDescendant.get() );\n    assert( !m_pRBDescendant.get() );\n    assert( !m_pLTDescendant.get() );\n    assert( !m_pRTDescendant.get() );\n\n    m_pLBDescendant = pLBDescendant;\n    m_pRBDescendant = pRBDescendant;\n    m_pLTDescendant = pLTDescendant;\n    m_pRTDescendant = pRTDescendant;\n}\n\ntemplate<typename NodeDataType>\nvoid CDynamicQuadTreeNode<NodeDataType>::DestroyDescendants()\n{\n    if( m_pLBDescendant.get() )m_pLBDescendant->DestroyDescendants();\n    if( m_pRBDescendant.get() )m_pRBDescendant->DestroyDescendants();\n    if( m_pLTDescendant.get() )m_pLTDescendant->DestroyDescendants();\n    if( m_pRTDescendant.get() )m_pRTDescendant->DestroyDescendants();\n    \n    m_pLBDescendant.reset();\n    m_pRBDescendant.reset();\n    m_pLTDescendant.reset();\n    m_pRTDescendant.reset();\n}\n"
  },
  {
    "path": "Terrain/EarthHemisphere.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n#include \"stdafx.h\"\n#include \"EarthHemisphere.h\"\n#include \"Structures.fxh\"\n#include \"ElevationDataSource.h\"\n#include \"ShaderMacroHelper.h\"\n\nvoid ExtractViewFrustumPlanesFromMatrix(const D3DXMATRIX &Matrix, SViewFrustum &ViewFrustum)\n{\n    // For more details, see Gribb G., Hartmann K., \"Fast Extraction of Viewing Frustum Planes from the \n    // World-View-Projection Matrix\" (the paper is available at \n    // http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf)\n\n\t// Left clipping plane \n    ViewFrustum.LeftPlane.Normal.x = Matrix._14 + Matrix._11; \n\tViewFrustum.LeftPlane.Normal.y = Matrix._24 + Matrix._21; \n\tViewFrustum.LeftPlane.Normal.z = Matrix._34 + Matrix._31; \n\tViewFrustum.LeftPlane.Distance = Matrix._44 + Matrix._41;\n\n\t// Right clipping plane \n\tViewFrustum.RightPlane.Normal.x = Matrix._14 - Matrix._11; \n\tViewFrustum.RightPlane.Normal.y = Matrix._24 - Matrix._21; \n\tViewFrustum.RightPlane.Normal.z = Matrix._34 - Matrix._31; \n\tViewFrustum.RightPlane.Distance = Matrix._44 - Matrix._41;\n\n\t// Top clipping plane \n\tViewFrustum.TopPlane.Normal.x = Matrix._14 - Matrix._12; \n\tViewFrustum.TopPlane.Normal.y = Matrix._24 - Matrix._22; \n\tViewFrustum.TopPlane.Normal.z = Matrix._34 - Matrix._32; \n\tViewFrustum.TopPlane.Distance = Matrix._44 - Matrix._42;\n\n\t// Bottom clipping plane \n\tViewFrustum.BottomPlane.Normal.x = Matrix._14 + Matrix._12; \n\tViewFrustum.BottomPlane.Normal.y = Matrix._24 + Matrix._22; \n\tViewFrustum.BottomPlane.Normal.z = Matrix._34 + Matrix._32; \n\tViewFrustum.BottomPlane.Distance = Matrix._44 + Matrix._42;\n\n\t// Near clipping plane \n\tViewFrustum.NearPlane.Normal.x = Matrix._13; \n\tViewFrustum.NearPlane.Normal.y = Matrix._23; \n\tViewFrustum.NearPlane.Normal.z = Matrix._33; \n\tViewFrustum.NearPlane.Distance = Matrix._43;\n\n\t// Far clipping plane \n\tViewFrustum.FarPlane.Normal.x = Matrix._14 - Matrix._13; \n\tViewFrustum.FarPlane.Normal.y = Matrix._24 - Matrix._23; \n\tViewFrustum.FarPlane.Normal.z = Matrix._34 - Matrix._33; \n\tViewFrustum.FarPlane.Distance = Matrix._44 - Matrix._43; \n}\n\nbool IsBoxVisible(const SViewFrustum &ViewFrustum, const SBoundingBox &Box)\n{\n    SPlane3D *pPlanes = (SPlane3D *)&ViewFrustum;\n    // If bounding box is \"behind\" some plane, then it is invisible\n    // Otherwise it is treated as visible\n    for(int iViewFrustumPlane = 0; iViewFrustumPlane < 6; iViewFrustumPlane++)\n    {\n        SPlane3D *pCurrPlane = pPlanes + iViewFrustumPlane;\n        D3DXVECTOR3 *pCurrNormal = &pCurrPlane->Normal;\n        D3DXVECTOR3 MaxPoint;\n        \n        MaxPoint.x = (pCurrNormal->x > 0) ? Box.fMaxX : Box.fMinX;\n        MaxPoint.y = (pCurrNormal->y > 0) ? Box.fMaxY : Box.fMinY;\n        MaxPoint.z = (pCurrNormal->z > 0) ? Box.fMaxZ : Box.fMinZ;\n        \n        float DMax = D3DXVec3Dot( &MaxPoint, pCurrNormal ) + pCurrPlane->Distance;\n\n        if( DMax < 0 )\n            return false;\n    }\n\n    return true;\n}\n\nstruct SHemisphereVertex\n{\n    D3DXVECTOR3 f3WorldPos;\n    D3DXVECTOR2 f2MaskUV0;\n    SHemisphereVertex() : f3WorldPos(0,0,0), f2MaskUV0(0,0){}\n};\n\nenum QUAD_TRIANGULATION_TYPE\n{\n    QUAD_TRIANG_TYPE_UNDEFINED = 0,\n\n    // 01      11\n    //  *------*\n    //  |   .' |\n    //  | .'   |\n    //  * -----*\n    // 00      10\n    QUAD_TRIANG_TYPE_00_TO_11,\n\n    // 01      11\n    //  *------*\n    //  | '.   |\n    //  |   '. |\n    //  * -----*\n    // 00      10\n    QUAD_TRIANG_TYPE_01_TO_10\n};\n\ntemplate<typename IndexType, class CIndexGenerator>\nclass CTriStrip\n{\npublic:\n    CTriStrip(std::vector<IndexType> &Indices, CIndexGenerator IndexGenerator):\n        m_Indices(Indices),\n        m_IndexGenerator(IndexGenerator),\n        m_QuadTriangType(QUAD_TRIANG_TYPE_UNDEFINED)\n    {\n    }\n    \n    void AddStrip(int iBaseIndex,\n                  int iStartCol,\n                  int iStartRow,\n                  int iNumCols,\n                  int iNumRows,\n                  QUAD_TRIANGULATION_TYPE QuadTriangType)\n    {\n        assert( QuadTriangType == QUAD_TRIANG_TYPE_00_TO_11 || QuadTriangType == QUAD_TRIANG_TYPE_01_TO_10 );\n        int iFirstVertex = iBaseIndex + m_IndexGenerator(iStartCol, iStartRow + (QuadTriangType==QUAD_TRIANG_TYPE_00_TO_11 ? 1:0));\n        if(m_QuadTriangType != QUAD_TRIANG_TYPE_UNDEFINED)\n        {\n            // To move from one strip to another, we have to generate two degenerate triangles\n            // by duplicating the last vertex in previous strip and the first vertex in new strip\n            m_Indices.push_back( m_Indices.back() );\n            m_Indices.push_back( iFirstVertex );\n        }\n\n        if(m_QuadTriangType != QUAD_TRIANG_TYPE_UNDEFINED && m_QuadTriangType != QuadTriangType || \n           m_QuadTriangType == QUAD_TRIANG_TYPE_UNDEFINED && QuadTriangType == QUAD_TRIANG_TYPE_01_TO_10)\n        {\n            // If triangulation orientation changes, or if start strip orientation is 01 to 10, \n            // we also have to add one additional vertex to preserve winding order\n            m_Indices.push_back( iFirstVertex );\n        }\n        m_QuadTriangType = QuadTriangType;\n\n        for(int iRow = 0; iRow < iNumRows-1; ++iRow)\n        {\n            for(int iCol = 0; iCol < iNumCols; ++iCol)\n            {\n                int iV00 = iBaseIndex + m_IndexGenerator(iStartCol+iCol, iStartRow+iRow);\n                int iV01 = iBaseIndex + m_IndexGenerator(iStartCol+iCol, iStartRow+iRow+1);\n                if( m_QuadTriangType == QUAD_TRIANG_TYPE_01_TO_10 )\n                {\n                    if( iCol == 0 && iRow == 0)\n                        assert(iFirstVertex == iV00);\n                    // 01      11\n                    //  *------*\n                    //  | '.   |\n                    //  |   '. |\n                    //  * -----*\n                    // 00      10\n                    m_Indices.push_back(iV00);\n                    m_Indices.push_back(iV01);\n                }\n                else if( m_QuadTriangType == QUAD_TRIANG_TYPE_00_TO_11 )\n                {\n                    if( iCol == 0 && iRow == 0)\n                        assert(iFirstVertex == iV01);\n                    // 01      11\n                    //  *------*\n                    //  |   .' |\n                    //  | .'   |\n                    //  * -----*\n                    // 00      10\n                    m_Indices.push_back(iV01);\n                    m_Indices.push_back(iV00);\n                }\n                else\n                {\n                    assert(false);\n                }\n            }\n        \n            if(iRow < iNumRows-2)\n            {\n                m_Indices.push_back( m_Indices.back() );\n                m_Indices.push_back( iBaseIndex + m_IndexGenerator(iStartCol, iStartRow+iRow+1 + (QuadTriangType==QUAD_TRIANG_TYPE_00_TO_11 ? 1:0)) );\n            }\n        }\n    }\n\nprivate:\n    QUAD_TRIANGULATION_TYPE m_QuadTriangType;\n    std::vector<IndexType> &m_Indices;\n    CIndexGenerator m_IndexGenerator;\n};\n\nclass CStdIndexGenerator\n{\npublic:\n    CStdIndexGenerator(int iPitch):m_iPitch(iPitch){}\n    UINT operator ()(int iCol, int iRow){return iCol + iRow*m_iPitch;}\n\nprivate:\n    int m_iPitch;\n};\n\ntypedef CTriStrip<UINT,  CStdIndexGenerator> StdTriStrip32;\n\nvoid ComputeVertexHeight(SHemisphereVertex &Vertex, \n                         class CElevationDataSource *pDataSource,\n                         float fSamplingStep,\n                         float fSampleScale)\n{\n    D3DXVECTOR3 &f3PosWS = Vertex.f3WorldPos;\n\n    float fCol = f3PosWS.x / fSamplingStep;\n    float fRow = f3PosWS.z / fSamplingStep;\n    float fDispl = pDataSource->GetInterpolatedHeight(fCol, fRow);\n    int iColOffset, iRowOffset;\n    pDataSource->GetOffsets(iColOffset, iRowOffset);\n    Vertex.f2MaskUV0.x = (fCol + (float)iColOffset + 0.5f)/(float)pDataSource->GetNumCols();\n    Vertex.f2MaskUV0.y = (fRow + (float)iRowOffset + 0.5f)/(float)pDataSource->GetNumRows();\n    \n    D3DXVECTOR3 f3SphereNormal;\n    D3DXVec3Normalize(&f3SphereNormal, &f3PosWS);\n    f3PosWS += f3SphereNormal * fDispl * fSampleScale;\n}\n\nclass CRingMeshBuilder\n{\npublic:\n    CRingMeshBuilder(ID3D11Device *pDevice,\n                     const std::vector<SHemisphereVertex> &VB,\n                     int iGridDimenion,\n                     std::vector<SRingSectorMesh> &RingMeshes) : m_pDevice(pDevice), m_VB(VB), m_iGridDimenion(iGridDimenion), m_RingMeshes(RingMeshes){}\n\n    void CreateMesh(int iBaseIndex, \n                    int iStartCol, \n                    int iStartRow, \n                    int iNumCols, \n                    int iNumRows, \n                    enum QUAD_TRIANGULATION_TYPE QuadTriangType)\n    {\n        m_RingMeshes.push_back( SRingSectorMesh() );\n        auto& CurrMesh = m_RingMeshes.back();\n\n        std::vector<UINT> IB;\n        StdTriStrip32 TriStrip( IB, CStdIndexGenerator(m_iGridDimenion) );\n        TriStrip.AddStrip(iBaseIndex, iStartCol, iStartRow, iNumCols, iNumRows, QuadTriangType);\n\n        CurrMesh.uiNumIndices = (UINT)IB.size();\n\n        // Prepare buffer description\n        D3D11_BUFFER_DESC IndexBufferDesc=\n        {\n            (UINT)(IB.size() * sizeof(IB[0])),\n            D3D11_USAGE_IMMUTABLE,\n            D3D11_BIND_INDEX_BUFFER,\n            0, //UINT CPUAccessFlags\n            0, //UINT MiscFlags;\n            0, //UINT StructureByteStride;\n        };\n        D3D11_SUBRESOURCE_DATA IBInitData = {&IB[0], 0, 0};\n        // Create the buffer\n        HRESULT hr;\n        V( m_pDevice->CreateBuffer( &IndexBufferDesc, &IBInitData, &CurrMesh.pIndBuff) );\n\n        // Compute bounding box\n        auto &BB = CurrMesh.BoundBox;\n        BB.fMaxX =BB.fMaxY = BB.fMaxZ = -FLT_MAX;\n        BB.fMinX =BB.fMinY = BB.fMinZ = +FLT_MAX;\n        for(auto Ind = IB.begin(); Ind != IB.end(); ++Ind)\n        {\n            const auto &CurrVert = m_VB[*Ind].f3WorldPos;\n            BB.fMinX = min(BB.fMinX, CurrVert.x);\n            BB.fMinY = min(BB.fMinY, CurrVert.y);\n            BB.fMinZ = min(BB.fMinZ, CurrVert.z);\n\n            BB.fMaxX = max(BB.fMaxX, CurrVert.x);\n            BB.fMaxY = max(BB.fMaxY, CurrVert.y);\n            BB.fMaxZ = max(BB.fMaxZ, CurrVert.z);\n        }\n    }\n\nprivate:\n    CComPtr<ID3D11Device> m_pDevice;\n    std::vector<SRingSectorMesh> &m_RingMeshes;\n    const std::vector<SHemisphereVertex> &m_VB;\n    const int m_iGridDimenion;\n};\n\nvoid GenerateSphereGeometry(ID3D11Device *pDevice,\n                            const float fEarthRadius,\n                            int iGridDimension, \n                            const int iNumRings,\n                            class CElevationDataSource *pDataSource,\n                            float fSamplingStep,\n                            float fSampleScale,\n                            std::vector<SHemisphereVertex> &VB,\n                            std::vector<UINT> &StitchIB,\n                            std::vector<SRingSectorMesh> &SphereMeshes)\n{\n    if( (iGridDimension - 1) % 4 != 0 )\n    {\n        assert(false);\n        iGridDimension = SRenderingParams().m_iRingDimension;\n    }\n    const int iGridMidst = (iGridDimension-1)/2;\n    const int iGridQuart = (iGridDimension-1)/4;\n\n    const int iLargestGridScale = iGridDimension << (iNumRings-1);\n    \n    CRingMeshBuilder RingMeshBuilder(pDevice, VB, iGridDimension, SphereMeshes);\n\n    int iStartRing = 0;\n    VB.reserve( (iNumRings-iStartRing) * iGridDimension * iGridDimension );\n    for(int iRing = iStartRing; iRing < iNumRings; ++iRing)\n    {\n        int iCurrGridStart = (int)VB.size();\n        VB.resize(VB.size() + iGridDimension * iGridDimension);\n        float fGridScale = 1.f / (float)(1<<(iNumRings-1 - iRing));\n        // Fill vertex buffer\n        for(int iRow = 0; iRow < iGridDimension; ++iRow)\n            for(int iCol = 0; iCol < iGridDimension; ++iCol)\n            {\n                auto &CurrVert = VB[iCurrGridStart + iCol + iRow*iGridDimension];\n                auto &f3Pos = CurrVert.f3WorldPos;\n                f3Pos.x = static_cast<float>(iCol) / static_cast<float>(iGridDimension-1);\n                f3Pos.z = static_cast<float>(iRow) / static_cast<float>(iGridDimension-1);\n                f3Pos.x = f3Pos.x*2 - 1;\n                f3Pos.z = f3Pos.z*2 - 1;\n                f3Pos.y = 0;\n                float fDirectionScale = 1;\n                if( f3Pos.x != 0 || f3Pos.z != 0 )\n                {\n                    float fDX = abs(f3Pos.x);\n                    float fDZ = abs(f3Pos.z);\n                    float fMaxD = max(fDX, fDZ);\n                    float fMinD = min(fDX, fDZ);\n                    float fTan = fMinD/fMaxD;\n                    fDirectionScale = 1 / sqrt(1 + fTan*fTan);\n                }\n            \n                f3Pos.x *= fDirectionScale*fGridScale;\n                f3Pos.z *= fDirectionScale*fGridScale;\n                f3Pos.y = sqrt( max(0, 1 - (f3Pos.x*f3Pos.x + f3Pos.z*f3Pos.z)) );\n\n                f3Pos.x *= fEarthRadius;\n                f3Pos.z *= fEarthRadius;\n                f3Pos.y *= fEarthRadius;\n\n                ComputeVertexHeight(CurrVert, pDataSource, fSamplingStep, fSampleScale);\n                f3Pos.y -= fEarthRadius;\n            }\n\n        // Align vertices on the outer boundary\n        if( iRing < iNumRings-1 )\n        {\n            for(int i=1; i < iGridDimension-1; i+=2)\n            {\n                // Top & bottom boundaries\n                for(int iRow=0; iRow < iGridDimension; iRow += iGridDimension-1)\n                {\n                    const auto &V0 = VB[iCurrGridStart + i - 1 + iRow*iGridDimension].f3WorldPos;\n                          auto &V1 = VB[iCurrGridStart + i + 0 + iRow*iGridDimension].f3WorldPos;\n                    const auto &V2 = VB[iCurrGridStart + i + 1 + iRow*iGridDimension].f3WorldPos;\n                    V1 = (V0+V2)/2.f;\n                }\n\n                // Left & right boundaries\n                for(int iCol=0; iCol < iGridDimension; iCol += iGridDimension-1)\n                {\n                    const auto &V0 = VB[iCurrGridStart + iCol + (i - 1)*iGridDimension].f3WorldPos;\n                          auto &V1 = VB[iCurrGridStart + iCol + (i + 0)*iGridDimension].f3WorldPos;\n                    const auto &V2 = VB[iCurrGridStart + iCol + (i + 1)*iGridDimension].f3WorldPos;\n                    V1 = (V0+V2)/2.f;\n                }\n            }\n\n\n            // Add triangles stitching this ring with the next one\n            int iNextGridStart = (int)VB.size();\n            assert( iNextGridStart == iCurrGridStart + iGridDimension*iGridDimension);\n\n            // Bottom boundary\n            for(int iCol=0; iCol < iGridDimension-1; iCol += 2)\n            {\n                StitchIB.push_back(iNextGridStart + (iGridQuart + iCol/2) + iGridQuart * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iCol+1) + 0 * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iCol+0) + 0 * iGridDimension); \n\n                StitchIB.push_back(iNextGridStart + (iGridQuart + iCol/2) + iGridQuart * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iCol+2) + 0 * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iCol+1) + 0 * iGridDimension); \n\n                StitchIB.push_back(iNextGridStart + (iGridQuart + iCol/2)   + iGridQuart * iGridDimension); \n                StitchIB.push_back(iNextGridStart + (iGridQuart + iCol/2+1) + iGridQuart * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iCol+2) + 0 * iGridDimension); \n            }\n\n            // Top boundary\n            for(int iCol=0; iCol < iGridDimension-1; iCol += 2)\n            {\n                StitchIB.push_back(iCurrGridStart + (iCol+0) + (iGridDimension-1) * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iCol+1) + (iGridDimension-1) * iGridDimension); \n                StitchIB.push_back(iNextGridStart + (iGridQuart + iCol/2) + iGridQuart* 3 * iGridDimension); \n\n                StitchIB.push_back(iCurrGridStart + (iCol+1) + (iGridDimension-1) * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iCol+2) + (iGridDimension-1) * iGridDimension); \n                StitchIB.push_back(iNextGridStart + (iGridQuart + iCol/2) + iGridQuart* 3 * iGridDimension); \n\n                StitchIB.push_back(iCurrGridStart + (iCol+2) + (iGridDimension-1) * iGridDimension); \n                StitchIB.push_back(iNextGridStart + (iGridQuart + iCol/2 + 1) + iGridQuart* 3 * iGridDimension); \n                StitchIB.push_back(iNextGridStart + (iGridQuart + iCol/2)     + iGridQuart* 3 * iGridDimension); \n            }\n\n            // Left boundary\n            for(int iRow=0; iRow < iGridDimension-1; iRow += 2)\n            {\n                StitchIB.push_back(iNextGridStart + iGridQuart + (iGridQuart+ iRow/2) * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + 0 + (iRow+0) * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + 0 + (iRow+1) * iGridDimension); \n\n                StitchIB.push_back(iNextGridStart + iGridQuart + (iGridQuart+ iRow/2) * iGridDimension);  \n                StitchIB.push_back(iCurrGridStart + 0 + (iRow+1) * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + 0 + (iRow+2) * iGridDimension); \n\n                StitchIB.push_back(iNextGridStart + iGridQuart + (iGridQuart + iRow/2 + 1) * iGridDimension); \n                StitchIB.push_back(iNextGridStart + iGridQuart + (iGridQuart + iRow/2)     * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + 0 + (iRow+2) * iGridDimension); \n            }\n\n            // Right boundary\n            for(int iRow=0; iRow < iGridDimension-1; iRow += 2)\n            {\n                StitchIB.push_back(iCurrGridStart + (iGridDimension-1) + (iRow+1) * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iGridDimension-1) + (iRow+0) * iGridDimension); \n                StitchIB.push_back(iNextGridStart + iGridQuart*3 + (iGridQuart+ iRow/2) * iGridDimension); \n\n                StitchIB.push_back(iCurrGridStart + (iGridDimension-1) + (iRow+2) * iGridDimension); \n                StitchIB.push_back(iCurrGridStart + (iGridDimension-1) + (iRow+1) * iGridDimension); \n                StitchIB.push_back(iNextGridStart + iGridQuart*3 + (iGridQuart+ iRow/2) * iGridDimension); \n\n                StitchIB.push_back(iCurrGridStart + (iGridDimension-1) + (iRow+2) * iGridDimension); \n                StitchIB.push_back(iNextGridStart + iGridQuart*3 + (iGridQuart+ iRow/2)     * iGridDimension); \n                StitchIB.push_back(iNextGridStart + iGridQuart*3 + (iGridQuart+ iRow/2 + 1) * iGridDimension); \n            }\n        }\n\n\n        // Generate indices for the current ring\n        if( iRing == 0 )\n        {\n            RingMeshBuilder.CreateMesh( iCurrGridStart, 0,                   0, iGridMidst+1, iGridMidst+1, QUAD_TRIANG_TYPE_00_TO_11);\n            RingMeshBuilder.CreateMesh( iCurrGridStart, iGridMidst,          0, iGridMidst+1, iGridMidst+1, QUAD_TRIANG_TYPE_01_TO_10);\n            RingMeshBuilder.CreateMesh( iCurrGridStart, 0,          iGridMidst, iGridMidst+1, iGridMidst+1, QUAD_TRIANG_TYPE_01_TO_10);\n            RingMeshBuilder.CreateMesh( iCurrGridStart, iGridMidst, iGridMidst, iGridMidst+1, iGridMidst+1, QUAD_TRIANG_TYPE_00_TO_11);\n        }\n        else\n        {\n            RingMeshBuilder.CreateMesh( iCurrGridStart,            0,            0,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_00_TO_11);\n            RingMeshBuilder.CreateMesh( iCurrGridStart,   iGridQuart,            0,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_00_TO_11);\n\n            RingMeshBuilder.CreateMesh( iCurrGridStart,   iGridMidst,            0,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_01_TO_10);\n            RingMeshBuilder.CreateMesh( iCurrGridStart, iGridQuart*3,            0,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_01_TO_10);\n                                        \n            RingMeshBuilder.CreateMesh( iCurrGridStart,            0,   iGridQuart,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_00_TO_11);\n            RingMeshBuilder.CreateMesh( iCurrGridStart,            0,   iGridMidst,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_01_TO_10);\n                                        \n            RingMeshBuilder.CreateMesh( iCurrGridStart, iGridQuart*3,   iGridQuart,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_01_TO_10);\n            RingMeshBuilder.CreateMesh( iCurrGridStart, iGridQuart*3,   iGridMidst,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_00_TO_11);\n\n            RingMeshBuilder.CreateMesh( iCurrGridStart,            0, iGridQuart*3,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_01_TO_10);\n            RingMeshBuilder.CreateMesh( iCurrGridStart,   iGridQuart, iGridQuart*3,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_01_TO_10);\n\n            RingMeshBuilder.CreateMesh( iCurrGridStart,   iGridMidst, iGridQuart*3,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_00_TO_11);\n            RingMeshBuilder.CreateMesh( iCurrGridStart, iGridQuart*3, iGridQuart*3,   iGridQuart+1, iGridQuart+1, QUAD_TRIANG_TYPE_00_TO_11);\n        }\n    }\n    \n    // We do not need per-vertex normals as we use normal map to shade terrain\n    // Sphere tangent vertex are computed in the shader\n#if 0\n    // Compute normals\n    const D3DXVECTOR3 *pV0 = nullptr;\n    const D3DXVECTOR3 *pV1 = &VB[ IB[0] ].f3WorldPos;\n    const D3DXVECTOR3 *pV2 = &VB[ IB[1] ].f3WorldPos;\n    float fSign = +1;\n    for(UINT Ind=2; Ind < m_uiIndicesInIndBuff; ++Ind)\n    {\n        fSign = -fSign;\n        pV0 = pV1;\n        pV1 = pV2;\n        pV2 =  &VB[ IB[Ind] ].f3WorldPos;\n        D3DXVECTOR3 Rib0 = *pV0 - *pV1;\n        D3DXVECTOR3 Rib1 = *pV1 - *pV2;\n        D3DXVECTOR3 TriN;\n        D3DXVec3Cross(&TriN, &Rib0, &Rib1);\n        float fLength = D3DXVec3Length(&TriN);\n        if( fLength > 0.1 )\n        {\n            TriN /= fLength*fSign;\n            for(int i=-2; i <= 0; ++i)\n                VB[ IB[Ind+i] ].f3Normal += TriN;\n        }\n    }\n    for(auto VBIt=VB.begin(); VBIt != VB.end(); ++VBIt)\n    {\n        float fLength = D3DXVec3Length(&VBIt->f3Normal);\n        if( fLength > 1 )\n            VBIt->f3Normal /= fLength;\n    }\n\n    // Adjust normals on boundaries\n    for(int iRing = iStartRing; iRing < iNumRings-1; ++iRing)\n    {\n        int iCurrGridStart = (iRing-iStartRing) * iGridDimension*iGridDimension;\n        int iNextGridStart = (iRing-iStartRing+1) * iGridDimension*iGridDimension;\n        for(int i=0; i < iGridDimension; i+=2)\n        {\n            for(int Bnd=0; Bnd < 2; ++Bnd)\n            {\n                const int CurrGridOffsets[] = {0, iGridDimension-1};\n                const int NextGridPffsets[] = {iGridQuart, iGridQuart*3};\n                // Left and right boundaries\n                {\n                    auto &CurrGridN = VB[iCurrGridStart + CurrGridOffsets[Bnd] + i*iGridDimension].f3Normal;\n                    auto &NextGridN = VB[iNextGridStart + NextGridPffsets[Bnd] + (iGridQuart+i/2)*iGridDimension].f3Normal;\n                    auto NewN = CurrGridN + NextGridN;\n                    D3DXVec3Normalize(&NewN, &NewN);\n                    CurrGridN = NextGridN = NewN;\n                    if( i > 1 )\n                    {\n                        auto &PrevCurrGridN = VB[iCurrGridStart + CurrGridOffsets[Bnd] + (i-2)*iGridDimension].f3Normal;\n                        auto MiddleN = PrevCurrGridN + NewN;\n                        D3DXVec3Normalize( &VB[iCurrGridStart + CurrGridOffsets[Bnd] + (i-1)*iGridDimension].f3Normal, &MiddleN);\n                    }\n                }\n\n                // Bottom and top boundaries\n                {\n                    auto &CurrGridN = VB[iCurrGridStart +                i + CurrGridOffsets[Bnd]*iGridDimension].f3Normal;\n                    auto &NextGridN = VB[iNextGridStart + (iGridQuart+i/2) + NextGridPffsets[Bnd]*iGridDimension].f3Normal;\n                    auto NewN = CurrGridN + NextGridN;\n                    D3DXVec3Normalize(&NewN, &NewN);\n                    CurrGridN = NextGridN = NewN;\n                    if( i > 1 )\n                    {\n                        auto &PrevCurrGridN = VB[iCurrGridStart + (i-2) + CurrGridOffsets[Bnd]*iGridDimension].f3Normal;\n                        auto MiddleN = PrevCurrGridN + NewN;\n                        D3DXVec3Normalize( &VB[iCurrGridStart + (i-1) + CurrGridOffsets[Bnd]*iGridDimension].f3Normal, &MiddleN);\n                    }\n                }\n            }\n        }\n    }\n#endif\n}\n\nHRESULT CEarthHemsiphere::CreateRenderStates(ID3D11Device* pd3dDevice)\n{\n    HRESULT hr;\n\n    // Create depth stencil state\n    D3D11_DEPTH_STENCIL_DESC DisableDepthTestDSDesc;\n    ZeroMemory(&DisableDepthTestDSDesc, sizeof(DisableDepthTestDSDesc));\n    DisableDepthTestDSDesc.DepthEnable = FALSE;\n    DisableDepthTestDSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;\n    V( pd3dDevice->CreateDepthStencilState(  &DisableDepthTestDSDesc, &m_pDisableDepthTestDS) );\n\n\tD3D11_DEPTH_STENCIL_DESC EnableDepthTestDSDesc;\n\tZeroMemory(&EnableDepthTestDSDesc, sizeof(EnableDepthTestDSDesc));\n\tEnableDepthTestDSDesc.DepthEnable = TRUE;\n\tEnableDepthTestDSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;\n\tEnableDepthTestDSDesc.DepthFunc = D3D11_COMPARISON_GREATER;\n    V( pd3dDevice->CreateDepthStencilState(  &EnableDepthTestDSDesc, &m_pEnableDepthTestDS) );\n\n    // Create default blend state\n    D3D11_BLEND_DESC DefaultBlendStateDesc;\n    ZeroMemory(&DefaultBlendStateDesc, sizeof(DefaultBlendStateDesc));\n    DefaultBlendStateDesc.IndependentBlendEnable = FALSE;\n    for(int i=0; i< _countof(DefaultBlendStateDesc.RenderTarget); i++)\n        DefaultBlendStateDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;\n    V( pd3dDevice->CreateBlendState( &DefaultBlendStateDesc, &m_pDefaultBS) );\n\n\n    // Create rasterizer state for solid fill mode\n    D3D11_RASTERIZER_DESC RSSolidFill = \n    {\n        D3D11_FILL_SOLID,\n        D3D11_CULL_BACK,\n        TRUE, //BOOL FrontCounterClockwise;\n        0,// INT DepthBias;\n        0,// FLOAT DepthBiasClamp;\n        0,// FLOAT SlopeScaledDepthBias;\n        TRUE,//BOOL DepthClipEnable;\n        FALSE,//BOOL ScissorEnable;\n        FALSE,//BOOL MultisampleEnable;\n        FALSE,//BOOL AntialiasedLineEnable;\n    };\n    hr = pd3dDevice->CreateRasterizerState( &RSSolidFill, &m_pRSSolidFill );\n\n    D3D11_RASTERIZER_DESC RSWireframeFill = RSSolidFill;\n    RSWireframeFill.FillMode = D3D11_FILL_WIREFRAME;\n    hr = pd3dDevice->CreateRasterizerState( &RSWireframeFill, &m_pRSWireframeFill );\n\n    D3D11_RASTERIZER_DESC SolidFillNoCullRSDesc;\n    ZeroMemory(&SolidFillNoCullRSDesc, sizeof(SolidFillNoCullRSDesc));\n    SolidFillNoCullRSDesc.FillMode = D3D11_FILL_SOLID;\n    SolidFillNoCullRSDesc.CullMode = D3D11_CULL_NONE;\n    V( pd3dDevice->CreateRasterizerState( &SolidFillNoCullRSDesc, &m_pRSSolidFillNoCull) );\n\n    D3D11_RASTERIZER_DESC ZOnlyPassRSDesc = RSSolidFill;\n    // Disable depth clipping\n    ZOnlyPassRSDesc.DepthClipEnable = FALSE;\n    // Do not use slope-scaled depth bias because this results in light leaking\n    // through terrain!\n    //ZOnlyPassRSDesc.DepthBias = -1;\n    //ZOnlyPassRSDesc.SlopeScaledDepthBias = -4;\n    //ZOnlyPassRSDesc.DepthBiasClamp = -1e-6;\n    ZOnlyPassRSDesc.FrontCounterClockwise = FALSE;\n    V( pd3dDevice->CreateRasterizerState( &ZOnlyPassRSDesc, &m_pRSZOnlyPass) );\n\n    D3D11_SAMPLER_DESC SamLinearMirrorDesc = \n    {\n        D3D11_FILTER_MIN_MAG_MIP_LINEAR,\n        D3D11_TEXTURE_ADDRESS_MIRROR,\n        D3D11_TEXTURE_ADDRESS_MIRROR,\n        D3D11_TEXTURE_ADDRESS_MIRROR,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_NEVER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    V( pd3dDevice->CreateSamplerState( &SamLinearMirrorDesc, &m_psamLinearMirror) );\n\n    D3D11_SAMPLER_DESC SamPointClamp = \n    {\n        D3D11_FILTER_MIN_MAG_MIP_POINT,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_NEVER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    V( pd3dDevice->CreateSamplerState( &SamPointClamp, &m_psamPointClamp) );\n    \n    D3D11_SAMPLER_DESC SamLinearClamp = \n    {\n        D3D11_FILTER_MIN_MAG_MIP_LINEAR,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_NEVER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    V( pd3dDevice->CreateSamplerState( &SamLinearClamp, &m_psamLinearClamp) );\n\n\n    D3D11_SAMPLER_DESC SamComparison = \n    {\n        D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        D3D11_TEXTURE_ADDRESS_CLAMP,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_GREATER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    V( pd3dDevice->CreateSamplerState( &SamComparison, &m_psamComaprison) );\n\n    D3D11_SAMPLER_DESC SamLinearWrapDesc = \n    {\n        D3D11_FILTER_MIN_MAG_MIP_LINEAR,\n        D3D11_TEXTURE_ADDRESS_WRAP,\n        D3D11_TEXTURE_ADDRESS_WRAP,\n        D3D11_TEXTURE_ADDRESS_WRAP,\n        0, //FLOAT MipLODBias;\n        0, //UINT MaxAnisotropy;\n        D3D11_COMPARISON_NEVER, // D3D11_COMPARISON_FUNC ComparisonFunc;\n        {0.f, 0.f, 0.f, 0.f}, //FLOAT BorderColor[ 4 ];\n        -FLT_MAX, //FLOAT MinLOD;\n        +FLT_MAX //FLOAT MaxLOD;\n    };\n    V( pd3dDevice->CreateSamplerState( &SamLinearWrapDesc, &m_psamLinearWrap) );\n    \n    return S_OK;\n}\n\nvoid CEarthHemsiphere::RenderNormalMap(ID3D11Device* pd3dDevice,\n                                       ID3D11DeviceContext* pd3dImmediateContext,\n                                       const UINT16 *pHeightMap,\n                                       size_t HeightMapPitch,\n                                       int iHeightMapDim)\n{\n    HRESULT hr;\n\n\tD3D11_TEXTURE2D_DESC HeightMapDesc =\n\t{\n        iHeightMapDim,\n        iHeightMapDim,\n\t\t1,\n\t\t1,\n        DXGI_FORMAT_R16_UNORM,\n        {1,0},\n\t\tD3D11_USAGE_IMMUTABLE,\n\t\tD3D11_BIND_SHADER_RESOURCE,\n\t\t0,\n\t\t0\n\t};\n    while( (iHeightMapDim >> HeightMapDesc.MipLevels) > 1 )\n        ++HeightMapDesc.MipLevels;\n    std::vector<UINT16> CoarseMipLevels;\n    CoarseMipLevels.resize( iHeightMapDim/2 * iHeightMapDim );\n\n    std::vector<D3D11_SUBRESOURCE_DATA> InitData(HeightMapDesc.MipLevels);\n    InitData[0].pSysMem = pHeightMap;\n    InitData[0].SysMemPitch = (UINT)HeightMapPitch*sizeof(pHeightMap[0]);\n    const UINT16 *pFinerMipLevel = pHeightMap;\n    UINT16 *pCurrMipLevel = &CoarseMipLevels[0];\n    size_t FinerMipPitch = HeightMapPitch;\n    size_t CurrMipPitch = iHeightMapDim/2;\n    for(UINT uiMipLevel = 1; uiMipLevel < HeightMapDesc.MipLevels; ++uiMipLevel)\n    {\n        auto MipWidth  = HeightMapDesc.Width >> uiMipLevel;\n        auto MipHeight = HeightMapDesc.Height >> uiMipLevel;\n        for(UINT uiRow=0; uiRow < MipHeight; ++uiRow)\n            for(UINT uiCol=0; uiCol < MipWidth; ++uiCol)\n            {\n                int iAverageHeight = 0;\n                for(int i=0; i<2; ++i)\n                    for(int j=0; j<2; ++j)\n                        iAverageHeight += pFinerMipLevel[ (uiCol*2+i) + (uiRow*2+j)*FinerMipPitch];\n                pCurrMipLevel[uiCol + uiRow*CurrMipPitch] = (UINT16)(iAverageHeight>>2);\n            }\n\n        InitData[uiMipLevel].pSysMem = pCurrMipLevel;\n        InitData[uiMipLevel].SysMemPitch = (UINT)CurrMipPitch*sizeof(*pCurrMipLevel);\n        pFinerMipLevel = pCurrMipLevel;\n        FinerMipPitch = CurrMipPitch;\n        pCurrMipLevel += MipHeight*CurrMipPitch;\n        CurrMipPitch = iHeightMapDim/2;\n    }\n\n    CComPtr<ID3D11Texture2D> ptex2DHeightMap;\n    pd3dDevice->CreateTexture2D(&HeightMapDesc, &InitData[0], &ptex2DHeightMap);\n    CComPtr<ID3D11ShaderResourceView> ptex2DHeightMapSRV;\n    pd3dDevice->CreateShaderResourceView(ptex2DHeightMap, nullptr, &ptex2DHeightMapSRV);\n\n    D3D11_TEXTURE2D_DESC NormalMapDesc = HeightMapDesc;\n    NormalMapDesc.Format = DXGI_FORMAT_R8G8_SNORM;\n    NormalMapDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;\n    NormalMapDesc.Usage = D3D11_USAGE_DEFAULT;\n    \n    CComPtr<ID3D11Texture2D> ptex2DNormalMap;\n    pd3dDevice->CreateTexture2D(&NormalMapDesc, &InitData[0], &ptex2DNormalMap);\n    pd3dDevice->CreateShaderResourceView(ptex2DNormalMap, nullptr, &m_ptex2DNormalMapSRV);\n\n    CComPtr<ID3D11RenderTargetView> pOrigRTV;\n    CComPtr<ID3D11DepthStencilView> pOrigDSV;\n    pd3dImmediateContext->OMGetRenderTargets( 1, &pOrigRTV, &pOrigDSV );\n\n    D3D11_VIEWPORT OrigViewPort;\n    UINT iNumOldViewports = 1;\n    pd3dImmediateContext->RSGetViewports(&iNumOldViewports, &OrigViewPort);\n\n    CRenderTechnique RenderNormalMapTech;\n    RenderNormalMapTech.SetDeviceAndContext(pd3dDevice, pd3dImmediateContext);\n\tV( RenderNormalMapTech.CreateVGPShadersFromFile( L\"fx\\\\Terrain.fx\", \"GenerateScreenSizeQuadVS\", NULL, \"GenerateNormalMapPS\", NULL ) );\n\tRenderNormalMapTech.SetDS( m_pDisableDepthTestDS );\n    RenderNormalMapTech.SetRS( m_pRSSolidFillNoCull );\n\tRenderNormalMapTech.SetBS( m_pDefaultBS );\n    \n    D3D11_VIEWPORT NewViewPort;\n    NewViewPort.TopLeftX = 0;\n    NewViewPort.TopLeftY = 0;\n    NewViewPort.MinDepth = 0;\n    NewViewPort.MaxDepth = 1;\n\n\n    D3D11_BUFFER_DESC CBDesc = \n    {\n        sizeof(SNMGenerationAttribs),\n        D3D11_USAGE_DYNAMIC,\n        D3D11_BIND_CONSTANT_BUFFER,\n        D3D11_CPU_ACCESS_WRITE, //UINT CPUAccessFlags\n        0, //UINT MiscFlags;\n        0, //UINT StructureByteStride;\n    };\n    CComPtr<ID3D11Buffer> pcbNMGenerationAttribs;\n    V( pd3dDevice->CreateBuffer( &CBDesc, NULL, &pcbNMGenerationAttribs) );\n\n    pd3dImmediateContext->PSSetConstantBuffers(0, 1, &pcbNMGenerationAttribs.p);\n\n    pd3dImmediateContext->PSSetShaderResources(0, 1, &ptex2DHeightMapSRV.p);\n    pd3dImmediateContext->PSSetSamplers(0, 1, &m_psamPointClamp.p);\n    for(UINT uiMipLevel = 0; uiMipLevel < NormalMapDesc.MipLevels; ++uiMipLevel)\n    {\n        D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;\n        RTVDesc.Format = NormalMapDesc.Format;\n        RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;\n        RTVDesc.Texture2D.MipSlice = uiMipLevel;\n        CComPtr<ID3D11RenderTargetView> ptex2DNormalMapRTV;\n        pd3dDevice->CreateRenderTargetView(ptex2DNormalMap, &RTVDesc, &ptex2DNormalMapRTV);\n\n        NewViewPort.Width  = (float)(NormalMapDesc.Width  >> uiMipLevel);\n        NewViewPort.Height = (float)(NormalMapDesc.Height >> uiMipLevel);\n        pd3dImmediateContext->RSSetViewports(1, &NewViewPort);  \n\n        pd3dImmediateContext->OMSetRenderTargets(1, &ptex2DNormalMapRTV.p, NULL);  \n\n        SNMGenerationAttribs NMGenerationAttribs;\n        NMGenerationAttribs.m_fElevationScale = m_Params.m_TerrainAttribs.m_fElevationScale;\n        NMGenerationAttribs.m_fSampleSpacingInterval = m_Params.m_TerrainAttribs.m_fElevationSamplingInterval;\n        NMGenerationAttribs.m_fMIPLevel = (float)uiMipLevel;\n        UpdateConstantBuffer(pd3dImmediateContext, pcbNMGenerationAttribs, &NMGenerationAttribs, sizeof(NMGenerationAttribs));\n\n        RenderNormalMapTech.Apply();\n\n        pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);\n        pd3dImmediateContext->Draw(4,0);\n    }\n\n    pd3dImmediateContext->RSSetViewports(iNumOldViewports, &OrigViewPort);\n    pd3dImmediateContext->OMSetRenderTargets( 1, &pOrigRTV.p, pOrigDSV );\n}\n\n\nHRESULT CEarthHemsiphere::OnD3D11CreateDevice( class CElevationDataSource *pDataSource,\n                                               const SRenderingParams &Params,\n                                               ID3D11Device* pd3dDevice,\n                                               ID3D11DeviceContext* pd3dImmediateContext,\n                                               LPCTSTR HeightMapPath,\n                                               LPCTSTR MaterialMaskPath,\n\t\t\t\t\t\t\t\t\t\t\t   LPCTSTR *TileTexturePath,\n                                               LPCTSTR *TileNormalMapPath)\n{\n    HRESULT hr;\n    m_Params = Params;\n\n    const UINT16 *pHeightMap;\n    size_t HeightMapPitch;\n    pDataSource->GetDataPtr(pHeightMap, HeightMapPitch);\n    int iHeightMapDim = pDataSource->GetNumCols();\n    assert(iHeightMapDim == pDataSource->GetNumRows() );\n\n    std::vector<SHemisphereVertex> VB;\n    std::vector<UINT> StitchIB;\n    GenerateSphereGeometry(pd3dDevice, SAirScatteringAttribs().fEarthRadius, m_Params.m_iRingDimension, m_Params.m_iNumRings, pDataSource, m_Params.m_TerrainAttribs.m_fElevationSamplingInterval, m_Params.m_TerrainAttribs.m_fElevationScale, VB, StitchIB, m_SphereMeshes);\n\n    D3D11_BUFFER_DESC VBDesc = \n    {\n        (UINT)(VB.size() * sizeof(VB[0])),\n        D3D11_USAGE_IMMUTABLE,\n        D3D11_BIND_VERTEX_BUFFER,\n        0, //UINT CPUAccessFlags\n        0, //UINT MiscFlags;\n        0, //UINT StructureByteStride;\n    };\n    D3D11_SUBRESOURCE_DATA VBInitData = {&VB[0], 0, 0};\n    hr = pd3dDevice->CreateBuffer(&VBDesc, &VBInitData , &m_pVertBuff);\n    CHECK_HR_RET(hr, _T(\"Failed to create the Earth heimsphere vertex buffer\") )\n\n\n    m_uiNumStitchIndices = (UINT)StitchIB.size();\n    D3D11_BUFFER_DESC StitchIndexBufferDesc=\n    {\n        (UINT)(m_uiNumStitchIndices * sizeof(StitchIB[0])),\n        D3D11_USAGE_IMMUTABLE,\n        D3D11_BIND_INDEX_BUFFER,\n        0, //UINT CPUAccessFlags\n        0, //UINT MiscFlags;\n        0, //UINT StructureByteStride;\n    };\n    D3D11_SUBRESOURCE_DATA IBInitData = {&StitchIB[0], 0, 0};\n    // Create the buffer\n    V( pd3dDevice->CreateBuffer( &StitchIndexBufferDesc, &IBInitData, &m_pStitchIndBuff) );\n\n    V( CreateRenderStates(pd3dDevice) );\n\n    m_RenderEarthHemisphereZOnlyTech.SetDeviceAndContext(pd3dDevice, pd3dImmediateContext);\n\tV( m_RenderEarthHemisphereZOnlyTech.CreateVGPShadersFromFile( L\"fx\\\\Terrain.fx\", \"HemisphereZOnlyVS\", NULL, NULL, NULL ) );\n\tm_RenderEarthHemisphereZOnlyTech.SetDS( m_pEnableDepthTestDS );\n\tm_RenderEarthHemisphereZOnlyTech.SetRS( m_pRSZOnlyPass );\n\tm_RenderEarthHemisphereZOnlyTech.SetBS( m_pDefaultBS );\n    \n    RenderNormalMap(pd3dDevice, pd3dImmediateContext, pHeightMap, HeightMapPitch, iHeightMapDim);\n\n    D3DX11CreateShaderResourceViewFromFile(pd3dDevice, MaterialMaskPath, nullptr, nullptr, &m_ptex2DMtrlMaskSRV, nullptr);\n\n    // Load tiles\n\tfor(int iTileTex = 0; iTileTex < (int)NUM_TILE_TEXTURES; iTileTex++)\n    {\n\t\tV( D3DX11CreateShaderResourceViewFromFile(pd3dDevice, TileTexturePath[iTileTex], NULL, NULL, &m_ptex2DTilesSRV[iTileTex], NULL) );\n\n        D3DX11_IMAGE_LOAD_INFO LoadInfo;\n        memset( &LoadInfo, 0, sizeof(LoadInfo));\n        D3DX11_IMAGE_INFO NMFileInfo;\n        D3DX11GetImageInfoFromFile(TileNormalMapPath[iTileTex],NULL,&NMFileInfo,NULL);\n        LoadInfo.Width = NMFileInfo.Width;\n        LoadInfo.Height = NMFileInfo.Height;\n        LoadInfo.Depth = NMFileInfo.Depth;\n        LoadInfo.MipLevels = (int)( log( (double)max(NMFileInfo.Width, NMFileInfo.Height)) / log(2.0) );\n        LoadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;\n        LoadInfo.Usage = D3D11_USAGE_IMMUTABLE;\n        LoadInfo.Format = DXGI_FORMAT_R8G8B8A8_UNORM;\n        LoadInfo.MipFilter = D3DX11_DEFAULT;\n        LoadInfo.Filter = D3DX11_DEFAULT;\n        V( D3DX11CreateShaderResourceViewFromFile(pd3dDevice, TileNormalMapPath[iTileTex], &LoadInfo, NULL, &m_ptex2DTilNormalMapsSRV[iTileTex], NULL) );\n\t}\n\n    D3D11_BUFFER_DESC CBDesc = \n    {\n        0,\n        D3D11_USAGE_DYNAMIC,\n        D3D11_BIND_CONSTANT_BUFFER,\n        D3D11_CPU_ACCESS_WRITE, //UINT CPUAccessFlags\n        0, //UINT MiscFlags;\n        0, //UINT StructureByteStride;\n    };\n\n    CBDesc.ByteWidth = sizeof(STerrainAttribs);\n    V( pd3dDevice->CreateBuffer( &CBDesc, NULL, &m_pcbTerrainAttribs) );\n\n    CBDesc.ByteWidth = sizeof(SCameraAttribs);\n    V( pd3dDevice->CreateBuffer( &CBDesc, NULL, &m_pcbCameraAttribs) );\n\n    return S_OK;\n}\n\nvoid CEarthHemsiphere::OnD3D11DestroyDevice()\n{\n    m_pStitchIndBuff.Release();\n    m_SphereMeshes.clear();\n    m_pVertBuff.Release();\n    m_pInputLayout.Release();\n    m_RenderEarthHemisphereTech.Release();\n    m_RenderEarthHemisphereZOnlyTech.Release();\n    m_psamPointClamp.Release();\n    m_psamLinearMirror.Release();\n    m_psamLinearWrap.Release();\n    m_psamLinearClamp.Release();\n    m_psamComaprison.Release();\n\tm_pEnableDepthTestDS.Release();\n    m_pDisableDepthTestDS.Release();\n\tm_pDefaultBS.Release();\n    m_pRSSolidFill.Release();\n    m_pRSSolidFillNoCull.Release();\n    m_pRSZOnlyPass.Release();\n    m_pRSWireframeFill.Release();\n    m_ptex2DNormalMapSRV.Release();\n\n    m_pcbTerrainAttribs.Release();\n    m_pcbCameraAttribs.Release();\n\n    for(int iTileTex = 0; iTileTex < NUM_TILE_TEXTURES; iTileTex++)\n    {\n        m_ptex2DTilesSRV[iTileTex].Release();\n        m_ptex2DTilNormalMapsSRV[iTileTex].Release();\n    }\n}\n\nvoid CEarthHemsiphere::Render(ID3D11DeviceContext* pd3dImmediateContext,\n                              const D3DXVECTOR3 &vCameraPosition, \n                              const D3DXMATRIX &CameraViewProjMatrix,\n                              ID3D11Buffer *pcbLightAttribs,\n                              ID3D11Buffer *pcMediaScatteringParams,\n                              ID3D11ShaderResourceView *pShadowMapSRV,\n                              ID3D11ShaderResourceView *pPrecomputedNetDensitySRV,\n                              ID3D11ShaderResourceView *pAmbientSkylightSRV,\n                              bool bZOnlyPass)\n{\n    if( GetAsyncKeyState(VK_F9) )\n    {\n        m_RenderEarthHemisphereTech.Release();\n    }\n\n    if( !m_RenderEarthHemisphereTech.IsValid() )\n    {\n        HRESULT hr;\n        CD3DShaderMacroHelper Macros;\n        Macros.AddShaderMacro(\"TEXTURING_MODE\", m_Params.m_TexturingMode);\n        Macros.AddShaderMacro(\"NUM_TILE_TEXTURES\", NUM_TILE_TEXTURES);\n        Macros.AddShaderMacro(\"NUM_SHADOW_CASCADES\", m_Params.m_iNumShadowCascades);\n        Macros.AddShaderMacro(\"BEST_CASCADE_SEARCH\", m_Params.m_bBestCascadeSearch ? true : false);\n        Macros.AddShaderMacro(\"SMOOTH_SHADOWS\", m_Params.m_bSmoothShadows ? true : false);\n\n        Macros.Finalize();\n        CComPtr<ID3D11Device> pDevice;\n        pd3dImmediateContext->GetDevice(&pDevice);\n        m_RenderEarthHemisphereTech.SetDeviceAndContext(pDevice, pd3dImmediateContext);\n\t    V( m_RenderEarthHemisphereTech.CreateVGPShadersFromFile( L\"fx\\\\Terrain.fx\", \"HemisphereVS\", NULL, \"HemispherePS\", Macros ) );\n\t    m_RenderEarthHemisphereTech.SetDS( m_pEnableDepthTestDS );\n\t    m_RenderEarthHemisphereTech.SetRS( m_pRSSolidFill );\n\t    m_RenderEarthHemisphereTech.SetBS( m_pDefaultBS );\n        if( !m_pInputLayout )\n        {\n\t        // Create vertex input layout for bounding box buffer\n            const D3D11_INPUT_ELEMENT_DESC layout[] =\n            {\n                { \"WORLD_POS\",  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0*4, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n                { \"MASK0_UV\",   0, DXGI_FORMAT_R32G32_FLOAT,    0, 3*4, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n            };\n\n\t        auto pVSByteCode = m_RenderEarthHemisphereTech.GetVSByteCode();\n            V( pDevice->CreateInputLayout( layout, ARRAYSIZE( layout ),\n                                           pVSByteCode->GetBufferPointer(),\n\t\t\t\t\t\t\t\t\t\t   pVSByteCode->GetBufferSize(),\n                                           &m_pInputLayout ) );\n        }\n    }\n\n    SViewFrustum ViewFrustum;\n    ExtractViewFrustumPlanesFromMatrix(CameraViewProjMatrix, ViewFrustum);\n\n    UpdateConstantBuffer(pd3dImmediateContext, m_pcbTerrainAttribs, &m_Params.m_TerrainAttribs, sizeof(m_Params.m_TerrainAttribs));\n\n    SCameraAttribs CameraAttribs;\n    D3DXMatrixTranspose(&CameraAttribs.WorldViewProjT, &CameraViewProjMatrix);\n    CameraAttribs.f4CameraPos = D3DXVECTOR4(vCameraPosition.x, vCameraPosition.y, vCameraPosition.z, 0);\n    UpdateConstantBuffer(pd3dImmediateContext, m_pcbCameraAttribs, &CameraAttribs, sizeof(CameraAttribs));\n\n    ID3D11Buffer *pCBs[] = \n    {\n        m_pcbTerrainAttribs,\n        m_pcbCameraAttribs,\n        pcbLightAttribs,\n        pcMediaScatteringParams\n    };\n    pd3dImmediateContext->VSSetConstantBuffers(0, _countof(pCBs), pCBs);\n    pd3dImmediateContext->PSSetConstantBuffers(0, _countof(pCBs), pCBs);\n\n    ID3D11ShaderResourceView *pSRVs[3 + 2*NUM_TILE_TEXTURES] = \n    {\n        m_ptex2DNormalMapSRV,\n        m_ptex2DMtrlMaskSRV,\n        pShadowMapSRV\n    };\n    for(int iTileTex = 0; iTileTex < NUM_TILE_TEXTURES; iTileTex++)\n    {\n        pSRVs[3+iTileTex] = m_ptex2DTilesSRV[iTileTex];\n        pSRVs[3+NUM_TILE_TEXTURES+iTileTex] = m_ptex2DTilNormalMapsSRV[iTileTex];\n    }\n    pd3dImmediateContext->PSSetShaderResources(1, _countof(pSRVs), pSRVs);\n    pSRVs[0] = pPrecomputedNetDensitySRV;\n    pSRVs[1] = pAmbientSkylightSRV;\n    pd3dImmediateContext->VSSetShaderResources(0, 2, pSRVs);\n\n    ID3D11SamplerState *pSamplers[] = {m_psamLinearMirror, m_psamLinearWrap, m_psamComaprison, m_psamLinearClamp};\n\tpd3dImmediateContext->VSSetSamplers(0, _countof(pSamplers), pSamplers);\n\tpd3dImmediateContext->PSSetSamplers(0, _countof(pSamplers), pSamplers);\n\n    UINT offset[1] = { 0 };\n    UINT stride[1] = { sizeof(SHemisphereVertex) };\n    ID3D11Buffer* const ppBuffers[1] = { m_pVertBuff };\n    pd3dImmediateContext->IASetVertexBuffers( 0, 1, ppBuffers, stride, offset );\n\n    pd3dImmediateContext->IASetInputLayout( m_pInputLayout );\n    pd3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );\n    \n    if( bZOnlyPass )\n        m_RenderEarthHemisphereZOnlyTech.Apply();\n    else\n        m_RenderEarthHemisphereTech.Apply();\n    \n    for(auto MeshIt = m_SphereMeshes.begin();  MeshIt != m_SphereMeshes.end(); ++MeshIt)\n    {\n        if(IsBoxVisible(ViewFrustum, MeshIt->BoundBox))\n        {\n            pd3dImmediateContext->IASetIndexBuffer( MeshIt->pIndBuff, DXGI_FORMAT_R32_UINT, 0);\n            pd3dImmediateContext->DrawIndexed(MeshIt->uiNumIndices, 0, 0);\n        }\n    }\n    \n    pd3dImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );\n    pd3dImmediateContext->IASetIndexBuffer( m_pStitchIndBuff, DXGI_FORMAT_R32_UINT, 0);\n    pd3dImmediateContext->DrawIndexed(m_uiNumStitchIndices, 0, 0);\n\n    UnbindPSResources(pd3dImmediateContext);\n}\n\nvoid CEarthHemsiphere::UpdateParams(const SRenderingParams &NewParams)\n{\n    if( m_Params.m_iNumShadowCascades    != NewParams.m_iNumShadowCascades    ||\n        m_Params.m_bBestCascadeSearch    != NewParams.m_bBestCascadeSearch    || \n        m_Params.m_bSmoothShadows        != NewParams.m_bSmoothShadows )\n    {\n        m_RenderEarthHemisphereTech.Release();\n    }\n\n    m_Params = NewParams;\n}\n"
  },
  {
    "path": "Terrain/EarthHemisphere.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#pragma once\n\n#include \"RenderTechnique.h\"\n#include \"TerrainStructs.fxh\"\n\nstruct SBoundingBox\n{\n    float fMinX, fMaxX, fMinY, fMaxY, fMinZ, fMaxZ;\n};\n\n// Structure describing a plane\nstruct SPlane3D\n{\n    D3DXVECTOR3 Normal;\n    float Distance;     //Distance from the coordinate system origin to the plane along normal direction\n};\n\n#pragma pack(1)\nstruct SViewFrustum\n{\n    SPlane3D LeftPlane, RightPlane, BottomPlane, TopPlane, NearPlane, FarPlane;\n};\n#pragma pack()\n\n// Extract view frustum planes from the world-view-projection matrix\nvoid ExtractViewFrustumPlanesFromMatrix(const D3DXMATRIX &Matrix, SViewFrustum &ViewFrustum);\n\n// Tests if bounding box is visible by the camera\nbool IsBoxVisible(const SViewFrustum &ViewFrustum, const SBoundingBox &Box);\n\n// Structure describing terrain rendering parameters\nstruct SRenderingParams\n{\n    STerrainAttribs m_TerrainAttribs;\n\n    enum TEXTURING_MODE\n    {\n        TM_HEIGHT_BASED = 0,\n\t\tTM_MATERIAL_MASK = 1,\n        TM_MATERIAL_MASK_NM = 2\n    };\n    \n    // Patch rendering params\n    TEXTURING_MODE m_TexturingMode;\n    int m_iRingDimension;\n    int m_iNumRings;\n\n    int m_iNumShadowCascades;\n    BOOL m_bBestCascadeSearch;\n    BOOL m_bSmoothShadows;\n    int m_iColOffset, m_iRowOffset;\n\n    SRenderingParams() : \n\t\tm_TexturingMode(TM_MATERIAL_MASK),\n        m_iRingDimension(65),\n        m_iNumRings(15),\n        m_iNumShadowCascades(4),\n        m_bBestCascadeSearch(TRUE),\n        m_bSmoothShadows(TRUE),\n        m_iColOffset(0), \n        m_iRowOffset(0)\n\t{}\n};\n\nstruct SRingSectorMesh\n{\n    CComPtr<ID3D11Buffer> pIndBuff;\n    UINT uiNumIndices;\n    SBoundingBox BoundBox;\n    SRingSectorMesh() : uiNumIndices(0){}\n};\n\n// This class renders the adaptive model using DX11 API\nclass CEarthHemsiphere\n{\npublic:\n    CEarthHemsiphere(void) : m_uiNumStitchIndices(0){}\n\n    // Renders the model\n\tvoid Render(ID3D11DeviceContext* pd3dImmediateContext,\n                const D3DXVECTOR3 &vCameraPosition, \n                const D3DXMATRIX &CameraViewProjMatrix,\n                ID3D11Buffer *pcbLightAttribs,\n                ID3D11Buffer *pcMediaScatteringParams,\n                ID3D11ShaderResourceView *pShadowMapSRV,\n                ID3D11ShaderResourceView *pPrecomputedNetDensitySRV,\n                ID3D11ShaderResourceView *pAmbientSkylightSRV,\n                bool bZOnlyPass);\n    \n    // Creates Direct3D11 device resources\n    HRESULT OnD3D11CreateDevice( class CElevationDataSource *pDataSource,\n                                 const SRenderingParams &Params,\n                                 ID3D11Device* pd3dDevice,\n                                 ID3D11DeviceContext* pd3dImmediateContext,\n                                 LPCTSTR HeightMapPath,\n                                 LPCTSTR MaterialMaskPath,\n\t\t\t\t\t\t\t\t LPCTSTR *TileTexturePath,\n                                 LPCTSTR *TileNormalMapPath );\n\n    // Releases Direct3D11 device resources\n    void OnD3D11DestroyDevice( );\n\n    enum {NUM_TILE_TEXTURES = 1 + 4};// One base material + 4 masked materials\n\n    void UpdateParams(const SRenderingParams &NewParams);\n\nprivate:\n    HRESULT CreateRenderStates(ID3D11Device* pd3dDevice);\n    void RenderNormalMap(ID3D11Device* pd3dDevice,\n                         ID3D11DeviceContext* pd3dImmediateContext,\n                         const UINT16 *pHeightMap,\n                         size_t HeightMapPitch,\n                         int iHeightMapDim);\n\n    SRenderingParams m_Params;\n\n    CRenderTechnique m_RenderEarthHemisphereTech;\n    CRenderTechnique m_RenderEarthHemisphereZOnlyTech;\n\n    CComPtr<ID3D11Buffer> m_pVertBuff;\n    CComPtr<ID3D11InputLayout> m_pInputLayout;\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DNormalMapSRV, m_ptex2DMtrlMaskSRV;\n\tCComPtr<ID3D11DepthStencilState> m_pEnableDepthTestDS;\n    CComPtr<ID3D11DepthStencilState> m_pDisableDepthTestDS;\n\tCComPtr<ID3D11BlendState> m_pDefaultBS;\n    CComPtr<ID3D11RasterizerState> m_pRSSolidFill, m_pRSSolidFillNoCull, m_pRSZOnlyPass, m_pRSWireframeFill;\n    CComPtr<ID3D11SamplerState> m_psamPointClamp, m_psamLinearMirror, m_psamLinearWrap, m_psamComaprison, m_psamLinearClamp;\n    CComPtr<ID3D11Buffer> m_pcbTerrainAttribs;\n    CComPtr<ID3D11Buffer> m_pcbCameraAttribs;\n\n\tCComPtr<ID3D11ShaderResourceView> m_ptex2DTilesSRV[NUM_TILE_TEXTURES];\n    CComPtr<ID3D11ShaderResourceView> m_ptex2DTilNormalMapsSRV[NUM_TILE_TEXTURES];\n\n    std::vector<SRingSectorMesh> m_SphereMeshes;\n    \n    CComPtr<ID3D11Buffer> m_pStitchIndBuff;\n    UINT m_uiNumStitchIndices;\n\nprivate:\n    CEarthHemsiphere(const CEarthHemsiphere&);\n    CEarthHemsiphere& operator = (const CEarthHemsiphere&);\n};\n"
  },
  {
    "path": "Terrain/ElevationDataSource.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"stdafx.h\"\n\n#include \"ElevationDataSource.h\"\n#include \"DynamicQuadTreeNode.h\"\n#include <exception>\n\n#include <wincodec.h>\n#include <wincodecsdk.h>\n#pragma comment(lib, \"WindowsCodecs.lib\")\n\n// Creates data source from the specified raw data file\nCElevationDataSource::CElevationDataSource(LPCTSTR strSrcDemFile) : \n    m_iPatchSize(128),\n    m_iNumLevels(0),\n    m_iColOffset(0), \n    m_iRowOffset(0)\n{\n    HRESULT hr;\n    V( CoInitialize(NULL) );\n\n    // Create components to read 16-bit png data\n    CComPtr<IWICImagingFactory> pFactory;\n    hr = pFactory.CoCreateInstance(CLSID_WICImagingFactory);\n    if( FAILED(hr) )\n        throw std::exception(\"Failed to create WICImagingFactory\");\n\n    CComPtr<IWICStream> pInputStream;\n    hr = pFactory->CreateStream(&pInputStream);\n    if( FAILED(hr) )\n        throw std::exception(\"Failed to create WICStream\");\n\n    hr = pInputStream->InitializeFromFilename(strSrcDemFile, GENERIC_READ);\n    if( FAILED(hr) )\n        throw std::exception(\"Failed to initialize WICStream from file\");\n\n    CComPtr<IWICBitmapDecoder> pDecoder;\n    hr = pFactory->CreateDecoderFromStream(\n                  pInputStream,\n                  0, // vendor\n                  WICDecodeMetadataCacheOnDemand,\n                  &pDecoder);\n    if( FAILED(hr) )\n        throw std::exception(\"Failed to Create decoder from stream\");\n\n    //GUID ContainerFormat;\n    //pDecoder->GetContainerFormat(&ContainerFormat);\n    //if( ContainerFormat == GUID_ContainerFormatPng )\n    //    printf(\"Container Format: PNG\\n\");\n    //else if( ContainerFormat == GUID_ContainerFormatTiff )\n    //    printf(\"Container Format: TIFF\\n\");\n\n    UINT frameCount = 0;\n    hr = pDecoder->GetFrameCount(&frameCount);\n    //printf(\"Frame count %d\\n\", frameCount);\n    assert( frameCount == 1 );\n\n    CComPtr<IWICBitmapFrameDecode> pTheFrame;\n    pDecoder->GetFrame(0, &pTheFrame);\n\n    UINT width = 0;\n    UINT height = 0;\n    pTheFrame->GetSize(&width, &height);\n\n    // Calculate minimal number of columns and rows\n    // in the form 2^n+1 that encompass the data\n    m_iNumCols = 1;\n    m_iNumRows = 1;\n    while( m_iNumCols+1 < width || m_iNumRows+1 < height)\n    {\n        m_iNumCols *= 2;\n        m_iNumRows *= 2;\n    }\n\n    m_iNumLevels = 1;\n    while( (m_iPatchSize << (m_iNumLevels-1)) < (int)m_iNumCols ||\n           (m_iPatchSize << (m_iNumLevels-1)) < (int)m_iNumRows )\n        m_iNumLevels++;\n\n    m_iNumCols++;\n    m_iNumRows++;\n\n    GUID pixelFormat = { 0 };\n    pTheFrame->GetPixelFormat(&pixelFormat);\n    if( pixelFormat != GUID_WICPixelFormat16bppGray )\n    {\n        assert(false);\n        throw std::exception(\"expected 16 bit format\");\n    }\n\n    // Load the data\n    m_TheHeightMap.resize( m_iNumCols * m_iNumRows );\n    WICRect SrcRect;\n    SrcRect.X = 0;\n    SrcRect.Y = 0;\n    SrcRect.Height = height;\n    SrcRect.Width = width;\n    pTheFrame->CopyPixels(\n      &SrcRect,\n      (UINT)m_iNumCols*2, //UINT stride\n      (UINT)m_TheHeightMap.size()*2, //UINT bufferSize\n      (BYTE*)&m_TheHeightMap[0]);\n\n    // Duplicate the last row and column\n    for(UINT iRow = 0; iRow < height; iRow++)\n        for(UINT iCol = width; iCol < m_iNumCols; iCol++)\n            m_TheHeightMap[iCol + iRow * m_iNumCols] = m_TheHeightMap[(width-1) + iRow * m_iNumCols];\n    for(UINT iCol = 0; iCol < m_iNumCols; iCol++)\n        for(UINT iRow = height; iRow < m_iNumRows; iRow++)\n            m_TheHeightMap[iCol + iRow * m_iNumCols] = m_TheHeightMap[iCol + (height-1) * m_iNumCols];\n\n    pTheFrame.Release();\n    pFactory.Release();\n    pDecoder.Release();\n    pInputStream.Release();\n\n    CoUninitialize();\n\n    m_MinMaxElevation.Resize(m_iNumLevels);\n    \n    // Calcualte min/max elevations\n    CalculateMinMaxElevations();\n}\n\nCElevationDataSource::~CElevationDataSource(void)\n{\n}\n\nUINT16 CElevationDataSource :: GetGlobalMinElevation()const\n{\n    return m_MinMaxElevation[SQuadTreeNodeLocation()].first;\n}\n\nUINT16 CElevationDataSource :: GetGlobalMaxElevation()const\n{\n    return m_MinMaxElevation[SQuadTreeNodeLocation()].second;\n}\n\nint MirrorCoord(int iCoord, int iDim)\n{\n    iCoord = abs(iCoord);\n    int iPeriod = iCoord / iDim;\n    iCoord = iCoord % iDim;\n    if( iPeriod & 0x01 )\n    {\n        iCoord = (iDim-1) - iCoord;\n    }\n    return iCoord;\n}\n\nfloat CElevationDataSource::GetInterpolatedHeight(float fCol, float fRow, int iStep)const\n{\n    float fCol0 = floor(fCol);\n    float fRow0 = floor(fRow);\n    int iCol0 = static_cast<int>(fCol0);\n    int iRow0 = static_cast<int>(fRow0);\n    iCol0 = (iCol0/iStep)*iStep;\n    iRow0 = (iRow0/iStep)*iStep;\n    float fHWeight = (fCol - (float)iCol0) / (float)iStep;\n    float fVWeight = (fRow - (float)iRow0) / (float)iStep;\n    iCol0 += m_iColOffset;\n    iRow0 += m_iRowOffset;\n    //if( iCol0 < 0 || iCol0 >= (int)m_iNumCols || iRow0 < 0 || iRow0 >= (int)m_iNumRows )\n    //    return -FLT_MAX;\n\n    int iCol1 = iCol0+iStep;//min(iCol0+iStep, (int)m_iNumCols-1);\n    int iRow1 = iRow0+iStep;//min(iRow0+iStep, (int)m_iNumRows-1);\n\n    iCol0 = MirrorCoord(iCol0, m_iNumCols);\n    iCol1 = MirrorCoord(iCol1, m_iNumCols);\n    iRow0 = MirrorCoord(iRow0, m_iNumRows);\n    iRow1 = MirrorCoord(iRow1, m_iNumRows);\n\n    UINT16 H00 = m_TheHeightMap[iCol0 + iRow0 * m_iNumCols];\n    UINT16 H10 = m_TheHeightMap[iCol1 + iRow0 * m_iNumCols];\n    UINT16 H01 = m_TheHeightMap[iCol0 + iRow1 * m_iNumCols];\n    UINT16 H11 = m_TheHeightMap[iCol1 + iRow1 * m_iNumCols];\n    float fInterpolatedHeight = (H00 * (1 - fHWeight) + H10 * fHWeight) * (1-fVWeight) + \n                                (H01 * (1 - fHWeight) + H11 * fHWeight) * fVWeight;\n    return fInterpolatedHeight;\n}\n\nD3DXVECTOR3 CElevationDataSource::ComputeSurfaceNormal(float fCol, float fRow,\n                                                       float fSampleSpacing,\n                                                       float fHeightScale, \n                                                       int iStep)const\n{\n    float Height1 = GetInterpolatedHeight(fCol + (float)iStep, fRow, iStep);\n    float Height2 = GetInterpolatedHeight(fCol - (float)iStep, fRow, iStep);\n    float Height3 = GetInterpolatedHeight(fCol, fRow + (float)iStep, iStep);\n    float Height4 = GetInterpolatedHeight(fCol, fRow - (float)iStep, iStep);\n       \n    D3DXVECTOR3 Grad;\n    Grad.x = Height2 - Height1;\n    Grad.y = Height4 - Height3;\n    Grad.z = (float)iStep * fSampleSpacing * 2.f;\n\n    Grad.x *= fHeightScale;\n    Grad.y *= fHeightScale;\n    D3DXVECTOR3 Normal;\n    D3DXVec3Normalize(&Normal, &Grad);\n\n    return Normal;\n}\n\nvoid CElevationDataSource::RecomputePatchMinMaxElevations(const SQuadTreeNodeLocation &pos)\n{\n\tif( pos.level == m_iNumLevels-1 )\n\t{\n\t\tstd::pair<UINT16, UINT16> &CurrPatchMinMaxElev = m_MinMaxElevation[SQuadTreeNodeLocation(pos.horzOrder, pos.vertOrder, pos.level)];\n        int iStartCol = pos.horzOrder*m_iPatchSize;\n        int iStartRow = pos.vertOrder*m_iPatchSize;\n        CurrPatchMinMaxElev.first = CurrPatchMinMaxElev.second = m_TheHeightMap[iStartCol + iStartRow*m_iNumCols];\n        for(int iRow = iStartRow; iRow <= iStartRow + m_iPatchSize; iRow++)\n            for(int iCol = iStartCol; iCol <= iStartCol + m_iPatchSize; iCol++)\n            {\n                UINT16 CurrElev = m_TheHeightMap[iCol + iRow*m_iNumCols];\n                CurrPatchMinMaxElev.first = min(CurrPatchMinMaxElev.first, CurrElev);\n                CurrPatchMinMaxElev.second = max(CurrPatchMinMaxElev.second, CurrElev);\n            }\n\t}\n\telse\n\t{\n        std::pair<UINT16, UINT16> &CurrPatchMinMaxElev = m_MinMaxElevation[pos];\n        std::pair<UINT16, UINT16> &LBChildMinMaxElev = m_MinMaxElevation[GetChildLocation(pos, 0)];\n        std::pair<UINT16, UINT16> &RBChildMinMaxElev = m_MinMaxElevation[GetChildLocation(pos, 1)];\n        std::pair<UINT16, UINT16> &LTChildMinMaxElev = m_MinMaxElevation[GetChildLocation(pos, 2)];\n        std::pair<UINT16, UINT16> &RTChildMinMaxElev = m_MinMaxElevation[GetChildLocation(pos, 3)];\n\n        CurrPatchMinMaxElev.first = min( LBChildMinMaxElev.first, RBChildMinMaxElev.first );\n        CurrPatchMinMaxElev.first = min( CurrPatchMinMaxElev.first, LTChildMinMaxElev.first );\n        CurrPatchMinMaxElev.first = min( CurrPatchMinMaxElev.first, RTChildMinMaxElev.first );\n\n        CurrPatchMinMaxElev.second = max( LBChildMinMaxElev.second, RBChildMinMaxElev.second);\n        CurrPatchMinMaxElev.second = max( CurrPatchMinMaxElev.second, LTChildMinMaxElev.second );\n        CurrPatchMinMaxElev.second = max( CurrPatchMinMaxElev.second, RTChildMinMaxElev.second );\n\t}\n}\n\n// Calculates min/max elevations for the hierarchy\nvoid CElevationDataSource :: CalculateMinMaxElevations()\n{\n    // Calculate min/max elevations starting from the finest level\n    for( HierarchyReverseIterator it(m_iNumLevels); it.IsValid(); it.Next() )\n    {\n\t\tRecomputePatchMinMaxElevations(it);\n    }\n}\n\nvoid CElevationDataSource::GetDataPtr(const UINT16* &pDataPtr, size_t &Pitch)\n{\n\tpDataPtr = &m_TheHeightMap[0];\n\tPitch = m_iNumCols;\n}\n"
  },
  {
    "path": "Terrain/ElevationDataSource.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#pragma once\n\n#include <vector>\n#include \"HierarchyArray.h\"\n#include \"DynamicQuadTreeNode.h\"\n\n// Class implementing elevation data source\nclass CElevationDataSource\n{\npublic:\n    // Creates data source from the specified raw data file\n    CElevationDataSource(LPCTSTR strSrcDemFile);\n    virtual ~CElevationDataSource(void);\n\n\tvoid GetDataPtr(const UINT16* &pDataPtr, size_t &Pitch);\n    \n    // Returns minimal height of the whole terrain\n    UINT16 GetGlobalMinElevation()const;\n\n    // Returns maximal height of the whole terrain\n    UINT16 GetGlobalMaxElevation()const;\n\n    void RecomputePatchMinMaxElevations(const SQuadTreeNodeLocation &pos);\n    \n    void SetOffsets(int iColOffset, int iRowOffset){m_iColOffset = iColOffset; m_iRowOffset = iRowOffset;}\n    void GetOffsets(int &iColOffset, int &iRowOffset)const{iColOffset = m_iColOffset; iRowOffset = m_iRowOffset;}\n\n    float GetInterpolatedHeight(float fCol, float fRow, int iStep = 1)const;\n    \n    D3DXVECTOR3 ComputeSurfaceNormal(float fCol, float fRow,\n                                     float fSampleSpacing,\n                                     float fHeightScale, \n                                     int iStep = 1)const;\n\n    unsigned int GetNumCols()const{return m_iNumCols;}\n    unsigned int GetNumRows()const{return m_iNumRows;}\nprivate:\n    CElevationDataSource();\n\n    // Calculates min/max elevations for all patches in the tree\n    void CalculateMinMaxElevations();\n    \n    // Hierarchy array storing minimal and maximal heights for quad tree nodes\n    HierarchyArray< std::pair<UINT16, UINT16> > m_MinMaxElevation;\n    \n    int m_iNumLevels;\n    int m_iPatchSize;\n    int m_iColOffset, m_iRowOffset;\n    \n    // The whole terrain height map\n    std::vector<UINT16> m_TheHeightMap;\n    unsigned int m_iNumCols, m_iNumRows;\n};\n"
  },
  {
    "path": "Terrain/Errors.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#pragma once\n\n\n#define LOG_ERROR(ErrorMsg, ...)\\\n{                                       \\\n    TCHAR FormattedErrorMsg[256];       \\\n    _stprintf_s(FormattedErrorMsg, sizeof(FormattedErrorMsg)/sizeof(FormattedErrorMsg[0]), ErrorMsg, __VA_ARGS__ ); \\\n    TCHAR FullErrorMsg[1024];           \\\n    _stprintf_s(FullErrorMsg, sizeof(FullErrorMsg)/sizeof(FullErrorMsg[0]), _T(\"The following error occured in the %s function() (%s, line %d):\\n%s\"), _T(__FUNCTION__), _T(__FILE__), __LINE__, FormattedErrorMsg); \\\n    MessageBox(NULL, FullErrorMsg, _T(\"Error\"), MB_ICONERROR|MB_OK ); \\\n}\n\n#define CHECK_HR(Result, ErrorMsg, ...)\\\n    if( FAILED(Result) )                \\\n        LOG_ERROR(ErrorMsg, __VA_ARGS__);\n\n#define CHECK_HR_RET(Result, ErrorMsg, ...)\\\n    if( FAILED(Result) )                    \\\n    {                                       \\\n        LOG_ERROR(ErrorMsg, __VA_ARGS__);   \\\n        return Result;                      \\\n    }\n"
  },
  {
    "path": "Terrain/HierarchyArray.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#pragma once\n\n#include <vector>\n#include \"DynamicQuadTreeNode.h\"\n\n// Template class implementing hierarchy array, which is a quad tree indexed by \n// quad tree node location\ntemplate <class T>\nclass HierarchyArray\n{\npublic:\n\tT& operator [] (const SQuadTreeNodeLocation &at)\n\t{\n\t\treturn m_data[at.level][at.horzOrder + (at.vertOrder << at.level)];\n\t}\n\tconst T& operator [] (const SQuadTreeNodeLocation &at) const\n\t{\n\t\treturn m_data[at.level][at.horzOrder + (at.vertOrder << at.level)];\n\t}\n\n\tvoid Resize(size_t numLevelsInHierarchy)\n\t{\n\t\tm_data.resize(numLevelsInHierarchy);\n\t\tif( numLevelsInHierarchy )\n\t\t{\n\t\t\tfor(size_t level = numLevelsInHierarchy; level--; )\n\t\t\t{\n\t\t\t\tsize_t numElementsInLevel = 1 << level;\n\t\t\t\tm_data[level].resize(numElementsInLevel*numElementsInLevel);\n\t\t\t}\n\t\t}\n\t}\n\n\tbool Empty() const\n\t{\n\t\treturn m_data.empty();\n\t}\n\nprivate:\n\tstd::vector<std::vector<T> > m_data;\n};\n\n\n// end of file\n"
  },
  {
    "path": "Terrain/stdafx.cpp",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"stdafx.h\"\n\n// end of file\n"
  },
  {
    "path": "fx/Common.fxh",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"Structures.fxh\"\n\n#define FLT_MAX 3.402823466e+38f\n\n#define RGB_TO_LUMINANCE float3(0.212671, 0.715160, 0.072169)\n\n// Using static definitions instead of constant buffer variables is \n// more efficient because the compiler is able to optimize the code \n// more aggressively\n\n#ifndef NUM_EPIPOLAR_SLICES\n#   define NUM_EPIPOLAR_SLICES 1024\n#endif\n\n#ifndef MAX_SAMPLES_IN_SLICE\n#   define MAX_SAMPLES_IN_SLICE 512\n#endif\n\n#ifndef SCREEN_RESLOUTION\n#   define SCREEN_RESLOUTION float2(1024,768)\n#endif\n\n#define MIN_MAX_DATA_FORMAT float2\n\n#ifndef CASCADE_PROCESSING_MODE\n#   define CASCADE_PROCESSING_MODE CASCADE_PROCESSING_MODE_SINGLE_PASS\n#endif\n\n#ifndef USE_COMBINED_MIN_MAX_TEXTURE\n#   define USE_COMBINED_MIN_MAX_TEXTURE 1\n#endif\n\n#ifndef EXTINCTION_EVAL_MODE\n#   define EXTINCTION_EVAL_MODE EXTINCTION_EVAL_MODE_EPIPOLAR\n#endif\n\n#ifndef AUTO_EXPOSURE\n#   define AUTO_EXPOSURE 1\n#endif\n\ncbuffer cbPostProcessingAttribs : register( b0 )\n{\n    SPostProcessingAttribs g_PPAttribs;\n};\n\ncbuffer cbParticipatingMediaScatteringParams : register( b1 )\n{\n    SAirScatteringAttribs g_MediaParams;\n}\n\n// Frame parameters\ncbuffer cbCameraAttribs : register( b2 )\n{\n    SCameraAttribs g_CameraAttribs;\n}\n\ncbuffer cbLightParams : register( b3 )\n{\n    SLightAttribs g_LightAttribs;\n}\n\ncbuffer cbMiscDynamicParams : register( b4 )\n{\n    SMiscDynamicParams g_MiscParams;\n}\n\nSamplerState samLinearClamp : register( s0 )\n{\n    Filter = MIN_MAG_MIP_LINEAR;\n    AddressU = Clamp;\n    AddressV = Clamp;\n};\n\nTexture2D<float>  g_tex2DDepthBuffer            : register( t0 );\nTexture2D<float>  g_tex2DCamSpaceZ              : register( t0 );\nTexture2D<float4> g_tex2DSliceEndPoints         : register( t4 );\nTexture2D<float2> g_tex2DCoordinates            : register( t1 );\nTexture2D<float>  g_tex2DEpipolarCamSpaceZ      : register( t2 );\nTexture2D<uint2>  g_tex2DInterpolationSource    : register( t6 );\nTexture2DArray<float> g_tex2DLightSpaceDepthMap : register( t3 );\nTexture2D<float4> g_tex2DSliceUVDirAndOrigin    : register( t6 );\nTexture2D<MIN_MAX_DATA_FORMAT> g_tex2DMinMaxLightSpaceDepth  : register( t4 );\nTexture2D<float3> g_tex2DInitialInsctrIrradiance: register( t5 );\nTexture2D<float4> g_tex2DColorBuffer            : register( t1 );\nTexture2D<float3> g_tex2DScatteredColor         : register( t3 );\nTexture2D<float2> g_tex2DOccludedNetDensityToAtmTop : register( t5 );\nTexture2D<float3> g_tex2DEpipolarExtinction     : register( t6 );\nTexture3D<float3> g_tex3DSingleSctrLUT          : register( t7 );\nTexture3D<float3> g_tex3DHighOrderSctrLUT       : register( t8 );\nTexture3D<float3> g_tex3DMultipleSctrLUT        : register( t9 );\nTexture2D<float3> g_tex2DSphereRandomSampling   : register( t1 );\nTexture3D<float3> g_tex3DPreviousSctrOrder      : register( t0 );\nTexture3D<float3> g_tex3DPointwiseSctrRadiance  : register( t0 );\nTexture2D<float>  g_tex2DAverageLuminance       : register( t10 );\nTexture2D<float>  g_tex2DLowResLuminance        : register( t0 );\n\n\nfloat3 ProjSpaceXYZToWorldSpace(in float3 f3PosPS)\n{\n    // We need to compute depth before applying view-proj inverse matrix\n    float fDepth = g_CameraAttribs.mProj[2][2] + g_CameraAttribs.mProj[3][2] / f3PosPS.z;\n    float4 ReconstructedPosWS = mul( float4(f3PosPS.xy,fDepth,1), g_CameraAttribs.mViewProjInv );\n    ReconstructedPosWS /= ReconstructedPosWS.w;\n    return ReconstructedPosWS.xyz;\n}\n\nvoid GetRaySphereIntersection(in float3 f3RayOrigin,\n                              in float3 f3RayDirection,\n                              in float3 f3SphereCenter,\n                              in float fSphereRadius,\n                              out float2 f2Intersections)\n{\n    // http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection\n    f3RayOrigin -= f3SphereCenter;\n    float A = dot(f3RayDirection, f3RayDirection);\n    float B = 2 * dot(f3RayOrigin, f3RayDirection);\n    float C = dot(f3RayOrigin,f3RayOrigin) - fSphereRadius*fSphereRadius;\n    float D = B*B - 4*A*C;\n    // If discriminant is negative, there are no real roots hence the ray misses the\n    // sphere\n    if( D<0 )\n    {\n        f2Intersections = -1;\n    }\n    else\n    {\n        D = sqrt(D);\n        f2Intersections = float2(-B - D, -B + D) / (2*A); // A must be positive here!!\n    }\n}\n\nvoid GetRaySphereIntersection2(in float3 f3RayOrigin,\n                               in float3 f3RayDirection,\n                               in float3 f3SphereCenter,\n                               in float2 f2SphereRadius,\n                               out float4 f4Intersections)\n{\n    // http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection\n    f3RayOrigin -= f3SphereCenter;\n    float A = dot(f3RayDirection, f3RayDirection);\n    float B = 2 * dot(f3RayOrigin, f3RayDirection);\n    float2 C = dot(f3RayOrigin,f3RayOrigin) - f2SphereRadius*f2SphereRadius;\n    float2 D = B*B - 4*A*C;\n    // If discriminant is negative, there are no real roots hence the ray misses the\n    // sphere\n    float2 f2RealRootMask = (D.xy >= 0);\n    D = sqrt( max(D,0) );\n    f4Intersections =   f2RealRootMask.xxyy * float4(-B - D.x, -B + D.x, -B - D.y, -B + D.y) / (2*A) + \n                      (1-f2RealRootMask.xxyy) * float4(-1,-1,-1,-1);\n}\n\nfloat GetAverageSceneLuminance()\n{\n#if AUTO_EXPOSURE\n    float fAveLogLum = g_tex2DAverageLuminance.Load( int3(0,0,0) );\n#else\n    float fAveLogLum =  0.1;\n#endif\n    fAveLogLum = max(0.05, fAveLogLum); // Average luminance is an approximation to the key of the scene\n    return fAveLogLum;\n}\n"
  },
  {
    "path": "fx/LightScattering.fx",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"Common.fxh\"\n\n#ifndef OPTIMIZE_SAMPLE_LOCATIONS\n#   define OPTIMIZE_SAMPLE_LOCATIONS 1\n#endif\n\n#ifndef CORRECT_INSCATTERING_AT_DEPTH_BREAKS\n#   define CORRECT_INSCATTERING_AT_DEPTH_BREAKS 0\n#endif\n\n//#define SHADOW_MAP_DEPTH_BIAS 1e-4\n\n#ifndef TRAPEZOIDAL_INTEGRATION\n#   define TRAPEZOIDAL_INTEGRATION 1\n#endif\n\n#ifndef EARTH_RADIUS\n#   define EARTH_RADIUS 6360000.f\n#endif\n\n#ifndef ATM_TOP_HEIGHT\n#   define ATM_TOP_HEIGHT 80000.f\n#endif\n\n#ifndef ATM_TOP_RADIUS\n#   define ATM_TOP_RADIUS (EARTH_RADIUS+ATM_TOP_HEIGHT)\n#endif\n\n#ifndef PARTICLE_SCALE_HEIGHT\n#   define PARTICLE_SCALE_HEIGHT float2(7994.f, 1200.f)\n#endif\n\n#ifndef ENABLE_LIGHT_SHAFTS\n#   define ENABLE_LIGHT_SHAFTS 1\n#endif\n\n#ifndef IS_32BIT_MIN_MAX_MAP\n#   define IS_32BIT_MIN_MAX_MAP 0\n#endif\n\n#ifndef SINGLE_SCATTERING_MODE\n#   define SINGLE_SCATTERING_MODE SINGLE_SCTR_MODE_LUT\n#endif\n\n#ifndef MULTIPLE_SCATTERING_MODE\n#   define MULTIPLE_SCATTERING_MODE MULTIPLE_SCTR_MODE_OCCLUDED\n#endif\n\n#ifndef PRECOMPUTED_SCTR_LUT_DIM\n#   define PRECOMPUTED_SCTR_LUT_DIM float4(32,128,32,16)\n#endif\n\n#ifndef NUM_RANDOM_SPHERE_SAMPLES\n#   define NUM_RANDOM_SPHERE_SAMPLES 128\n#endif\n\n#ifndef PERFORM_TONE_MAPPING\n#   define PERFORM_TONE_MAPPING 1\n#endif\n\n#ifndef LOW_RES_LUMINANCE_MIPS\n#   define LOW_RES_LUMINANCE_MIPS 7\n#endif\n\n#ifndef TONE_MAPPING_MODE\n#   define TONE_MAPPING_MODE TONE_MAPPING_MODE_REINHARD_MOD\n#endif\n\n#ifndef LIGHT_ADAPTATION\n#   define LIGHT_ADAPTATION 1\n#endif\n\n#define INVALID_EPIPOLAR_LINE float4(-1000,-1000, -100, -100)\n\n//--------------------------------------------------------------------------------------\n// Texture samplers\n//--------------------------------------------------------------------------------------\n\nSamplerState samLinearBorder0 : register( s1 )\n{\n    Filter = MIN_MAG_MIP_LINEAR;\n    AddressU = Border;\n    AddressV = Border;\n    BorderColor = float4(0.0, 0.0, 0.0, 0.0);\n};\n\nSamplerComparisonState samComparison : register( s2 )\n{\n    Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;\n    AddressU = Border;\n    AddressV = Border;\n    ComparisonFunc = GREATER;\n    BorderColor = float4(0.0, 0.0, 0.0, 0.0);\n};\n\nSamplerState samPointClamp : register( s3 );\n\n//--------------------------------------------------------------------------------------\n// Depth stencil states\n//--------------------------------------------------------------------------------------\n\n// Depth stencil state disabling depth test\nDepthStencilState DSS_NoDepthTest\n{\n    DepthEnable = false;\n    DepthWriteMask = ZERO;\n};\n\nDepthStencilState DSS_NoDepthTestIncrStencil\n{\n    DepthEnable = false;\n    DepthWriteMask = ZERO;\n    STENCILENABLE = true;\n    FRONTFACESTENCILFUNC = ALWAYS;\n    BACKFACESTENCILFUNC = ALWAYS;\n    FRONTFACESTENCILPASS = INCR;\n    BACKFACESTENCILPASS = INCR;\n};\n\nDepthStencilState DSS_NoDepth_StEqual_IncrStencil\n{\n    DepthEnable = false;\n    DepthWriteMask = ZERO;\n    STENCILENABLE = true;\n    FRONTFACESTENCILFUNC = EQUAL;\n    BACKFACESTENCILFUNC = EQUAL;\n    FRONTFACESTENCILPASS = INCR;\n    BACKFACESTENCILPASS = INCR;\n    FRONTFACESTENCILFAIL = KEEP;\n    BACKFACESTENCILFAIL = KEEP;\n};\n\nDepthStencilState DSS_NoDepth_StEqual_KeepStencil\n{\n    DepthEnable = false;\n    DepthWriteMask = ZERO;\n    STENCILENABLE = true;\n    FRONTFACESTENCILFUNC = EQUAL;\n    BACKFACESTENCILFUNC = EQUAL;\n    FRONTFACESTENCILPASS = KEEP;\n    BACKFACESTENCILPASS = KEEP;\n    FRONTFACESTENCILFAIL = KEEP;\n    BACKFACESTENCILFAIL = KEEP;\n};\n\n//--------------------------------------------------------------------------------------\n// Rasterizer states\n//--------------------------------------------------------------------------------------\n\n// Rasterizer state for solid fill mode with no culling\nRasterizerState RS_SolidFill_NoCull\n{\n    FILLMODE = Solid;\n    CullMode = NONE;\n};\n\n\n// Blend state disabling blending\nBlendState NoBlending\n{\n    BlendEnable[0] = FALSE;\n    BlendEnable[1] = FALSE;\n    BlendEnable[2] = FALSE;\n};\n\nfloat2 ProjToUV(in float2 f2ProjSpaceXY)\n{\n    return float2(0.5, 0.5) + float2(0.5, -0.5) * f2ProjSpaceXY;\n}\n\nfloat2 UVToProj(in float2 f2UV)\n{\n    return float2(-1.0, 1.0) + float2(2.0, -2.0) * f2UV;\n}\n\nfloat GetCamSpaceZ(in float2 ScreenSpaceUV)\n{\n    return g_tex2DCamSpaceZ.SampleLevel(samLinearClamp, ScreenSpaceUV, 0);\n}\n\n \nfloat3 Uncharted2Tonemap(float3 x)\n{\n    // http://www.gdcvault.com/play/1012459/Uncharted_2__HDR_Lighting\n    // http://filmicgames.com/archives/75 - the coefficients are from here\n    float A = 0.15; // Shoulder Strength\n    float B = 0.50; // Linear Strength\n    float C = 0.10; // Linear Angle\n    float D = 0.20; // Toe Strength\n    float E = 0.02; // Toe Numerator\n    float F = 0.30; // Toe Denominator\n    return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F; // E/F = Toe Angle\n}\n\nfloat3 ToneMap(in float3 f3Color)\n{\n    float fAveLogLum = GetAverageSceneLuminance();\n    \n    //const float middleGray = 1.03 - 2 / (2 + log10(fAveLogLum+1));\n    const float middleGray = g_PPAttribs.m_fMiddleGray;\n    // Compute scale factor such that average luminance maps to middle gray\n    float fLumScale = middleGray / fAveLogLum;\n    \n    f3Color = max(f3Color, 0);\n    float fInitialPixelLum = max(dot(RGB_TO_LUMINANCE, f3Color), 1e-10);\n    float fScaledPixelLum = fInitialPixelLum * fLumScale;\n    float3 f3ScaledColor = f3Color * fLumScale;\n\n    float whitePoint = g_PPAttribs.m_fWhitePoint;\n\n#if TONE_MAPPING_MODE == TONE_MAPPING_MODE_EXP\n    \n    float  fToneMappedLum = 1.0 - exp( -fScaledPixelLum );\n    return fToneMappedLum * pow(f3Color / fInitialPixelLum, g_PPAttribs.m_fLuminanceSaturation);\n\n#elif TONE_MAPPING_MODE == TONE_MAPPING_MODE_REINHARD || TONE_MAPPING_MODE == TONE_MAPPING_MODE_REINHARD_MOD\n\n    // http://www.cs.utah.edu/~reinhard/cdrom/tonemap.pdf\n    // http://imdoingitwrong.wordpress.com/2010/08/19/why-reinhard-desaturates-my-blacks-3/\n    // http://content.gpwiki.org/index.php/D3DBook:High-Dynamic_Range_Rendering\n\n    float  L_xy = fScaledPixelLum;\n#   if TONE_MAPPING_MODE == TONE_MAPPING_MODE_REINHARD\n        float  fToneMappedLum = L_xy / (1 + L_xy);\n#   else\n\t    float  fToneMappedLum = L_xy * (1 + L_xy / (whitePoint*whitePoint)) / (1 + L_xy);\n#   endif\n\treturn fToneMappedLum * pow(f3Color / fInitialPixelLum, g_PPAttribs.m_fLuminanceSaturation);\n\n#elif TONE_MAPPING_MODE == TONE_MAPPING_MODE_UNCHARTED2\n\n    // http://filmicgames.com/archives/75\n    float ExposureBias = 2.0f;\n    float3 curr = Uncharted2Tonemap(ExposureBias*f3ScaledColor);\n    float3 whiteScale = 1.0f/Uncharted2Tonemap(whitePoint);\n    return curr*whiteScale;\n\n#elif TONE_MAPPING_MODE == TONE_MAPPING_FILMIC_ALU\n\n    // http://www.gdcvault.com/play/1012459/Uncharted_2__HDR_Lighting\n    float3 f3ToneMappedColor = max(0, f3ScaledColor - 0.004f);\n    f3ToneMappedColor = (f3ToneMappedColor * (6.2f * f3ToneMappedColor + 0.5f)) / \n                        (f3ToneMappedColor * (6.2f * f3ToneMappedColor + 1.7f)+ 0.06f);\n    // result has 1/2.2 gamma baked in\n    return pow(f3ToneMappedColor, 2.2f);\n\n#elif TONE_MAPPING_MODE == TONE_MAPPING_LOGARITHMIC\n    \n    // http://www.mpi-inf.mpg.de/resources/tmo/logmap/logmap.pdf\n    float fToneMappedLum = log10(1 + fScaledPixelLum) / log10(1 + whitePoint);\n\treturn fToneMappedLum * pow(f3Color / fInitialPixelLum, g_PPAttribs.m_fLuminanceSaturation);\n\n#elif TONE_MAPPING_MODE == TONE_MAPPING_ADAPTIVE_LOG\n\n    // http://www.mpi-inf.mpg.de/resources/tmo/logmap/logmap.pdf\n    float Bias = 0.85;\n    float fToneMappedLum = \n        1 / log10(1 + whitePoint) *\n        log(1 + fScaledPixelLum) / log( 2 + 8 * pow( fScaledPixelLum / whitePoint, log(Bias) / log(0.5f)) );\n\treturn fToneMappedLum * pow(f3Color / fInitialPixelLum, g_PPAttribs.m_fLuminanceSaturation);\n\n#endif\n}\n\nfloat4 UpdateAverageLuminancePS() : SV_Target\n{\n#if LIGHT_ADAPTATION\n    const float fAdaptationRate = 1.f;\n    float fNewLuminanceWeight = 1 - exp( - fAdaptationRate * g_MiscParams.fElapsedTime );\n#else\n    float fNewLuminanceWeight = 1;\n#endif\n    return float4( exp( g_tex2DLowResLuminance.Load( int3(0,0,LOW_RES_LUMINANCE_MIPS-1) ) ), 0, 0, fNewLuminanceWeight );\n}\n\nfloat3 ProjSpaceXYToWorldSpace(in float2 f2PosPS)\n{\n    // We can sample camera space z texture using bilinear filtering\n    float fCamSpaceZ = g_tex2DCamSpaceZ.SampleLevel(samLinearClamp, ProjToUV(f2PosPS), 0);\n    return ProjSpaceXYZToWorldSpace(float3(f2PosPS, fCamSpaceZ));\n}\n\nfloat3 WorldSpaceToShadowMapUV(in float3 f3PosWS, in matrix mWorldToShadowMapUVDepth)\n{\n    float4 f4ShadowMapUVDepth = mul( float4(f3PosWS, 1), mWorldToShadowMapUVDepth );\n    // Shadow map projection matrix is orthographic, so we do not need to divide by w\n    //f4ShadowMapUVDepth.xyz /= f4ShadowMapUVDepth.w;\n    \n    // Applying depth bias results in light leaking through the opaque objects when looking directly\n    // at the light source\n    return f4ShadowMapUVDepth.xyz;\n}\n\nstruct SScreenSizeQuadVSOutput\n{\n    float4 m_f4Pos : SV_Position;\n    float2 m_f2PosPS : PosPS; // Position in projection space [-1,1]x[-1,1]\n    float m_fInstID : InstanceID;\n};\n\nSScreenSizeQuadVSOutput GenerateScreenSizeQuadVS(in uint VertexId : SV_VertexID,\n                                                 in uint InstID : SV_InstanceID)\n{\n    float4 MinMaxUV = float4(-1, -1, 1, 1);\n    \n    SScreenSizeQuadVSOutput Verts[4] = \n    {\n        {float4(MinMaxUV.xy, 1.0, 1.0), MinMaxUV.xy, InstID}, \n        {float4(MinMaxUV.xw, 1.0, 1.0), MinMaxUV.xw, InstID},\n        {float4(MinMaxUV.zy, 1.0, 1.0), MinMaxUV.zy, InstID},\n        {float4(MinMaxUV.zw, 1.0, 1.0), MinMaxUV.zw, InstID}\n    };\n\n    return Verts[VertexId];\n}\n\nfloat ReconstructCameraSpaceZPS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    float fDepth = g_tex2DDepthBuffer.Load( uint3(In.m_f4Pos.xy,0) );\n    float fCamSpaceZ = g_CameraAttribs.mProj[3][2]/(fDepth - g_CameraAttribs.mProj[2][2]);\n    return fCamSpaceZ;\n};\n\ntechnique11 ReconstructCameraSpaceZ\n{\n    pass\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, ReconstructCameraSpaceZPS() ) );\n    }\n}\n\nconst float4 GetOutermostScreenPixelCoords()\n{\n    // The outermost visible screen pixels centers do not lie exactly on the boundary (+1 or -1), but are biased by\n    // 0.5 screen pixel size inwards\n    //\n    //                                        2.0\n    //    |<---------------------------------------------------------------------->|\n    //\n    //       2.0/Res\n    //    |<--------->|\n    //    |     X     |      X     |     X     |    ...    |     X     |     X     |\n    //   -1     |                                                            |    +1\n    //          |                                                            |\n    //          |                                                            |\n    //      -1 + 1.0/Res                                                  +1 - 1.0/Res\n    //\n    // Using shader macro is much more efficient than using constant buffer variable\n    // because the compiler is able to optimize the code more aggressively\n    // return float4(-1,-1,1,1) + float4(1, 1, -1, -1)/g_PPAttribs.m_f2ScreenResolution.xyxy;\n    return float4(-1,-1,1,1) + float4(1, 1, -1, -1) / SCREEN_RESLOUTION.xyxy;\n}\n\n// When checking if a point is inside the screen, we must test against \n// the biased screen boundaries \nbool IsValidScreenLocation(in float2 f2XY)\n{\n    const float SAFETY_EPSILON = 0.2f;\n    return all( abs(f2XY) <= 1.f - (1.f - SAFETY_EPSILON) / SCREEN_RESLOUTION.xy );\n}\n\n// This function computes entry point of the epipolar line given its exit point\n//                  \n//    g_LightAttribs.f4LightScreenPos\n//       *\n//        \\\n//         \\  f2EntryPoint\n//        __\\/___\n//       |   \\   |\n//       |    \\  |\n//       |_____\\_|\n//           | |\n//           | f2ExitPoint\n//           |\n//        Exit boundary\nfloat2 GetEpipolarLineEntryPoint(float2 f2ExitPoint)\n{\n    float2 f2EntryPoint;\n\n    //if( IsValidScreenLocation(g_LightAttribs.f4LightScreenPos.xy) )\n    if( g_LightAttribs.bIsLightOnScreen )\n    {\n        // If light source is on the screen, its location is entry point for each epipolar line\n        f2EntryPoint = g_LightAttribs.f4LightScreenPos.xy;\n    }\n    else\n    {\n        // If light source is outside the screen, we need to compute intersection of the ray with\n        // the screen boundaries\n        \n        // Compute direction from the light source to the exit point\n        // Note that exit point must be located on shrinked screen boundary\n        float2 f2RayDir = f2ExitPoint.xy - g_LightAttribs.f4LightScreenPos.xy;\n        float fDistToExitBoundary = length(f2RayDir);\n        f2RayDir /= fDistToExitBoundary;\n        // Compute signed distances along the ray from the light position to all four boundaries\n        // The distances are computed as follows using vector instructions:\n        // float fDistToLeftBoundary   = abs(f2RayDir.x) > 1e-5 ? (-1 - g_LightAttribs.f4LightScreenPos.x) / f2RayDir.x : -FLT_MAX;\n        // float fDistToBottomBoundary = abs(f2RayDir.y) > 1e-5 ? (-1 - g_LightAttribs.f4LightScreenPos.y) / f2RayDir.y : -FLT_MAX;\n        // float fDistToRightBoundary  = abs(f2RayDir.x) > 1e-5 ? ( 1 - g_LightAttribs.f4LightScreenPos.x) / f2RayDir.x : -FLT_MAX;\n        // float fDistToTopBoundary    = abs(f2RayDir.y) > 1e-5 ? ( 1 - g_LightAttribs.f4LightScreenPos.y) / f2RayDir.y : -FLT_MAX;\n        \n        // Note that in fact the outermost visible screen pixels do not lie exactly on the boundary (+1 or -1), but are biased by\n        // 0.5 screen pixel size inwards. Using these adjusted boundaries improves precision and results in\n        // smaller number of pixels which require inscattering correction\n        float4 f4Boundaries = GetOutermostScreenPixelCoords();\n        bool4 b4IsCorrectIntersectionFlag = abs(f2RayDir.xyxy) > 1e-5;\n        float4 f4DistToBoundaries = (f4Boundaries - g_LightAttribs.f4LightScreenPos.xyxy) / (f2RayDir.xyxy + !b4IsCorrectIntersectionFlag);\n        // Addition of !b4IsCorrectIntersectionFlag is required to prevent divison by zero\n        // Note that such incorrect lanes will be masked out anyway\n\n        // We now need to find first intersection BEFORE the intersection with the exit boundary\n        // This means that we need to find maximum intersection distance which is less than fDistToBoundary\n        // We thus need to skip all boundaries, distance to which is greater than the distance to exit boundary\n        // Using -FLT_MAX as the distance to these boundaries will result in skipping them:\n        b4IsCorrectIntersectionFlag = b4IsCorrectIntersectionFlag && ( f4DistToBoundaries < (fDistToExitBoundary - 1e-4) );\n        f4DistToBoundaries = b4IsCorrectIntersectionFlag * f4DistToBoundaries + \n                            !b4IsCorrectIntersectionFlag * float4(-FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX);\n\n        float fFirstIntersecDist = 0;\n        fFirstIntersecDist = max(fFirstIntersecDist, f4DistToBoundaries.x);\n        fFirstIntersecDist = max(fFirstIntersecDist, f4DistToBoundaries.y);\n        fFirstIntersecDist = max(fFirstIntersecDist, f4DistToBoundaries.z);\n        fFirstIntersecDist = max(fFirstIntersecDist, f4DistToBoundaries.w);\n        \n        // The code above is equivalent to the following lines:\n        // fFirstIntersecDist = fDistToLeftBoundary   < fDistToBoundary-1e-4 ? max(fFirstIntersecDist, fDistToLeftBoundary)   : fFirstIntersecDist;\n        // fFirstIntersecDist = fDistToBottomBoundary < fDistToBoundary-1e-4 ? max(fFirstIntersecDist, fDistToBottomBoundary) : fFirstIntersecDist;\n        // fFirstIntersecDist = fDistToRightBoundary  < fDistToBoundary-1e-4 ? max(fFirstIntersecDist, fDistToRightBoundary)  : fFirstIntersecDist;\n        // fFirstIntersecDist = fDistToTopBoundary    < fDistToBoundary-1e-4 ? max(fFirstIntersecDist, fDistToTopBoundary)    : fFirstIntersecDist;\n\n        // Now we can compute entry point:\n        f2EntryPoint = g_LightAttribs.f4LightScreenPos.xy + f2RayDir * fFirstIntersecDist;\n\n        // For invalid rays, coordinates are outside [-1,1]x[-1,1] area\n        // and such rays will be discarded\n        //\n        //       g_LightAttribs.f4LightScreenPos\n        //             *\n        //              \\|\n        //               \\-f2EntryPoint\n        //               |\\\n        //               | \\  f2ExitPoint \n        //               |__\\/___\n        //               |       |\n        //               |       |\n        //               |_______|\n        //\n    }\n\n    return f2EntryPoint;\n}\n\nfloat4 GenerateSliceEndpointsPS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    float2 f2UV = ProjToUV(In.m_f2PosPS);\n\n    // Note that due to the rasterization rules, UV coordinates are biased by 0.5 texel size.\n    //\n    //      0.5     1.5     2.5     3.5\n    //   |   X   |   X   |   X   |   X   |     ....       \n    //   0       1       2       3       4   f2UV * TexDim\n    //   X - locations where rasterization happens\n    //\n    // We need to remove this offset. Also clamp to [0,1] to fix fp32 precision issues\n    float fEpipolarSlice = saturate(f2UV.x - 0.5f / (float)NUM_EPIPOLAR_SLICES);\n\n    // fEpipolarSlice now lies in the range [0, 1 - 1/NUM_EPIPOLAR_SLICES]\n    // 0 defines location in exacatly left top corner, 1 - 1/NUM_EPIPOLAR_SLICES defines\n    // position on the top boundary next to the top left corner\n    uint uiBoundary = clamp(floor( fEpipolarSlice * 4 ), 0, 3);\n    float fPosOnBoundary = frac( fEpipolarSlice * 4 );\n\n    bool4 b4BoundaryFlags = bool4( uiBoundary.xxxx == uint4(0,1,2,3) );\n\n    // Note that in fact the outermost visible screen pixels do not lie exactly on the boundary (+1 or -1), but are biased by\n    // 0.5 screen pixel size inwards. Using these adjusted boundaries improves precision and results in\n    // samller number of pixels which require inscattering correction\n    float4 f4OutermostScreenPixelCoords = GetOutermostScreenPixelCoords();// xyzw = (left, bottom, right, top)\n\n    // Check if there can definitely be no correct intersection with the boundary:\n    //  \n    //  Light.x <= LeftBnd    Light.y <= BottomBnd     Light.x >= RightBnd     Light.y >= TopBnd    \n    //                                                                                 *             \n    //          ____                 ____                    ____                   __/_             \n    //        .|    |               |    |                  |    |  .*             |    |            \n    //      .' |____|               |____|                  |____|.'               |____|            \n    //     *                           \\                                                               \n    //                                  *                                                  \n    //     Left Boundary       Bottom Boundary           Right Boundary          Top Boundary \n    //\n    bool4 b4IsInvalidBoundary = bool4( (g_LightAttribs.f4LightScreenPos.xyxy - f4OutermostScreenPixelCoords.xyzw) * float4(1,1,-1,-1) <= 0 );\n    if( dot(b4IsInvalidBoundary, b4BoundaryFlags) )\n        return INVALID_EPIPOLAR_LINE;\n    // Additinal check above is required to eliminate false epipolar lines which can appear is shown below.\n    // The reason is that we have to use some safety delta when performing check in IsValidScreenLocation() \n    // function. If we do not do this, we will miss valid entry points due to precision issues.\n    // As a result there could appear false entry points which fall into the safety region, but in fact lie\n    // outside the screen boundary:\n    //\n    //   LeftBnd-Delta LeftBnd           \n    //                      false epipolar line\n    //          |        |  /\n    //          |        | /          \n    //          |        |/         X - false entry point\n    //          |        *\n    //          |       /|\n    //          |------X-|-----------  BottomBnd\n    //          |     /  |\n    //          |    /   |\n    //          |___/____|___________ BottomBnd-Delta\n    //          \n    //          \n\n\n    //             <------\n    //   +1   0,1___________0.75\n    //          |     3     |\n    //        | |           | A\n    //        | |0         2| |\n    //        V |           | |\n    //   -1     |_____1_____|\n    //       0.25  ------>  0.5\n    //\n    //         -1          +1\n    //\n\n    //                                   Left             Bottom           Right              Top   \n    float4 f4BoundaryXPos = float4(               0, fPosOnBoundary,                1, 1-fPosOnBoundary);\n    float4 f4BoundaryYPos = float4( 1-fPosOnBoundary,              0,  fPosOnBoundary,                1);\n    // Select the right coordinates for the boundary\n    float2 f2ExitPointPosOnBnd = float2( dot(f4BoundaryXPos, b4BoundaryFlags), dot(f4BoundaryYPos, b4BoundaryFlags) );\n    float2 f2ExitPoint = lerp(f4OutermostScreenPixelCoords.xy, f4OutermostScreenPixelCoords.zw, f2ExitPointPosOnBnd);\n    // GetEpipolarLineEntryPoint() gets exit point on SHRINKED boundary\n    float2 f2EntryPoint = GetEpipolarLineEntryPoint(f2ExitPoint);\n    \n#if OPTIMIZE_SAMPLE_LOCATIONS\n    // If epipolar slice is not invisible, advance its exit point if necessary\n    if( IsValidScreenLocation(f2EntryPoint) )\n    {\n        // Compute length of the epipolar line in screen pixels:\n        float fEpipolarSliceScreenLen = length( (f2ExitPoint - f2EntryPoint) * SCREEN_RESLOUTION.xy / 2 );\n        // If epipolar line is too short, update epipolar line exit point to provide 1:1 texel to screen pixel correspondence:\n        f2ExitPoint = f2EntryPoint + (f2ExitPoint - f2EntryPoint) * max((float)MAX_SAMPLES_IN_SLICE / fEpipolarSliceScreenLen, 1);\n    }\n#endif\n\n    return float4(f2EntryPoint, f2ExitPoint);\n}\n\n\nvoid GenerateCoordinateTexturePS(SScreenSizeQuadVSOutput In, \n                                 out float2 f2XY : SV_Target0,\n                                 out float fCamSpaceZ : SV_Target1)\n\n{\n    float4 f4SliceEndPoints = g_tex2DSliceEndPoints.Load( int3(In.m_f4Pos.y,0,0) );\n    \n    // If slice entry point is outside [-1,1]x[-1,1] area, the slice is completely invisible\n    // and we can skip it from further processing.\n    // Note that slice exit point can lie outside the screen, if sample locations are optimized\n    if( !IsValidScreenLocation(f4SliceEndPoints.xy) )\n    {\n        // Discard invalid slices\n        // Such slices will not be marked in the stencil and as a result will always be skipped\n        discard;\n    }\n\n    float2 f2UV = ProjToUV(In.m_f2PosPS);\n\n    // Note that due to the rasterization rules, UV coordinates are biased by 0.5 texel size.\n    //\n    //      0.5     1.5     2.5     3.5\n    //   |   X   |   X   |   X   |   X   |     ....       \n    //   0       1       2       3       4   f2UV * f2TexDim\n    //   X - locations where rasterization happens\n    //\n    // We need remove this offset:\n    float fSamplePosOnEpipolarLine = f2UV.x - 0.5f / (float)MAX_SAMPLES_IN_SLICE;\n    // fSamplePosOnEpipolarLine is now in the range [0, 1 - 1/MAX_SAMPLES_IN_SLICE]\n    // We need to rescale it to be in [0, 1]\n    fSamplePosOnEpipolarLine *= (float)MAX_SAMPLES_IN_SLICE / ((float)MAX_SAMPLES_IN_SLICE-1.f);\n    fSamplePosOnEpipolarLine = saturate(fSamplePosOnEpipolarLine);\n\n    // Compute interpolated position between entry and exit points:\n    f2XY = lerp(f4SliceEndPoints.xy, f4SliceEndPoints.zw, fSamplePosOnEpipolarLine);\n    if( !IsValidScreenLocation(f2XY) )\n    {\n        // Discard pixels that fall behind the screen\n        // This can happen if slice exit point was optimized\n        discard;\n    }\n\n    // Compute camera space z for current location\n    fCamSpaceZ = GetCamSpaceZ( ProjToUV(f2XY) );\n};\n\n\ntechnique11 GenerateCoordinateTexture\n{\n    pass\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        // Increase stencil value for all valid rays\n        SetDepthStencilState( DSS_NoDepthTestIncrStencil, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, GenerateCoordinateTexturePS() ) );\n    }\n}\n\nstatic const float4 g_f4IncorrectSliceUVDirAndStart = float4(-10000, -10000, 0, 0);\nfloat4 RenderSliceUVDirInShadowMapTexturePS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    uint uiSliceInd = In.m_f4Pos.x;\n    // Load epipolar slice endpoints\n    float4 f4SliceEndpoints = g_tex2DSliceEndPoints.Load(  uint3(uiSliceInd,0,0) );\n    // All correct entry points are completely inside the [-1+1/W,1-1/W]x[-1+1/H,1-1/H] area\n    if( !IsValidScreenLocation(f4SliceEndpoints.xy) )\n        return g_f4IncorrectSliceUVDirAndStart;\n\n    uint uiCascadeInd = In.m_f4Pos.y;\n    matrix mWorldToShadowMapUVDepth = g_LightAttribs.ShadowAttribs.mWorldToShadowMapUVDepth[uiCascadeInd];\n\n    // Reconstruct slice exit point position in world space\n    float3 f3SliceExitWS = ProjSpaceXYZToWorldSpace( float3(f4SliceEndpoints.zw, g_LightAttribs.ShadowAttribs.Cascades[uiCascadeInd].f4StartEndZ.y) );\n    // Transform it to the shadow map UV\n    float2 f2SliceExitUV = WorldSpaceToShadowMapUV(f3SliceExitWS, mWorldToShadowMapUVDepth).xy;\n    \n    // Compute camera position in shadow map UV space\n    float2 f2SliceOriginUV = WorldSpaceToShadowMapUV(g_CameraAttribs.f4CameraPos.xyz, mWorldToShadowMapUVDepth).xy;\n\n    // Compute slice direction in shadow map UV space\n    float2 f2SliceDir = f2SliceExitUV - f2SliceOriginUV;\n    f2SliceDir /= max(abs(f2SliceDir.x), abs(f2SliceDir.y));\n    \n    float4 f4BoundaryMinMaxXYXY = float4(0,0,1,1) + float4(0.5, 0.5, -0.5, -0.5)*g_PPAttribs.m_f2ShadowMapTexelSize.xyxy;\n    if( any( (f2SliceOriginUV.xyxy - f4BoundaryMinMaxXYXY) * float4( 1, 1, -1, -1) < 0 ) )\n    {\n        // If slice origin in UV coordinates falls beyond [0,1]x[0,1] region, we have\n        // to continue the ray and intersect it with this rectangle\n        //                  \n        //    f2SliceOriginUV\n        //       *\n        //        \\\n        //         \\  New f2SliceOriginUV\n        //    1   __\\/___\n        //       |       |\n        //       |       |\n        //    0  |_______|\n        //       0       1\n        //           \n        \n        // First, compute signed distances from the slice origin to all four boundaries\n        bool4 b4IsValidIsecFlag = abs(f2SliceDir.xyxy) > 1e-6;\n        float4 f4DistToBoundaries = (f4BoundaryMinMaxXYXY - f2SliceOriginUV.xyxy) / (f2SliceDir.xyxy + !b4IsValidIsecFlag);\n\n        //We consider only intersections in the direction of the ray\n        b4IsValidIsecFlag = b4IsValidIsecFlag && (f4DistToBoundaries>0);\n        // Compute the second intersection coordinate\n        float4 f4IsecYXYX = f2SliceOriginUV.yxyx + f4DistToBoundaries * f2SliceDir.yxyx;\n        \n        // Select only these coordinates that fall onto the boundary\n        b4IsValidIsecFlag = b4IsValidIsecFlag && (f4IsecYXYX >= f4BoundaryMinMaxXYXY.yxyx) && (f4IsecYXYX <= f4BoundaryMinMaxXYXY.wzwz);\n        // Replace distances to all incorrect boundaries with the large value\n        f4DistToBoundaries = b4IsValidIsecFlag * f4DistToBoundaries + \n                            !b4IsValidIsecFlag * float4(+FLT_MAX, +FLT_MAX, +FLT_MAX, +FLT_MAX);\n        // Select the closest valid intersection\n        float2 f2MinDist = min(f4DistToBoundaries.xy, f4DistToBoundaries.zw);\n        float fMinDist = min(f2MinDist.x, f2MinDist.y);\n        \n        // Update origin\n        f2SliceOriginUV = f2SliceOriginUV + fMinDist * f2SliceDir;\n    }\n    \n    f2SliceDir *= g_PPAttribs.m_f2ShadowMapTexelSize;\n\n    return float4(f2SliceDir, f2SliceOriginUV);\n}\n\ntechnique11 RenderSliceUVDirInShadowMapTexture\n{\n    pass p0\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        // Only interpolation samples will not be discarded and increase the stencil value\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, RenderSliceUVDirInShadowMapTexturePS() ) );\n    }\n}\n\n// Note that min/max shadow map does not contain finest resolution level\n// The first level it contains corresponds to step == 2\nMIN_MAX_DATA_FORMAT InitializeMinMaxShadowMapPS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    uint uiSliceInd;\n    float fCascadeInd;\n#if USE_COMBINED_MIN_MAX_TEXTURE\n    fCascadeInd = floor(In.m_f4Pos.y / NUM_EPIPOLAR_SLICES);\n    uiSliceInd = In.m_f4Pos.y - fCascadeInd * NUM_EPIPOLAR_SLICES;\n    fCascadeInd += g_PPAttribs.m_fFirstCascade;\n#else\n    uiSliceInd = In.m_f4Pos.y;\n    fCascadeInd = g_MiscParams.fCascadeInd;\n#endif\n    // Load slice direction in shadow map\n    float4 f4SliceUVDirAndOrigin = g_tex2DSliceUVDirAndOrigin.Load( uint3(uiSliceInd, fCascadeInd, 0) );\n    // Calculate current sample position on the ray\n    float2 f2CurrUV = f4SliceUVDirAndOrigin.zw + f4SliceUVDirAndOrigin.xy * floor(In.m_f4Pos.x) * 2.f;\n    \n    float4 f4MinDepth = 1;\n    float4 f4MaxDepth = 0;\n    // Gather 8 depths which will be used for PCF filtering for this sample and its immediate neighbor \n    // along the epipolar slice\n    // Note that if the sample is located outside the shadow map, Gather() will return 0 as \n    // specified by the samLinearBorder0. As a result volumes outside the shadow map will always be lit\n    for( float i=0; i<=1; ++i )\n    {\n        float4 f4Depths = g_tex2DLightSpaceDepthMap.Gather(samLinearBorder0, float3(f2CurrUV + i * f4SliceUVDirAndOrigin.xy, fCascadeInd) );\n        f4MinDepth = min(f4MinDepth, f4Depths);\n        f4MaxDepth = max(f4MaxDepth, f4Depths);\n    }\n\n    f4MinDepth.xy = min(f4MinDepth.xy, f4MinDepth.zw);\n    f4MinDepth.x = min(f4MinDepth.x, f4MinDepth.y);\n\n    f4MaxDepth.xy = max(f4MaxDepth.xy, f4MaxDepth.zw);\n    f4MaxDepth.x = max(f4MaxDepth.x, f4MaxDepth.y);\n#if !IS_32BIT_MIN_MAX_MAP\n    const float R16_UNORM_PRECISION = 1.f / (float)(1<<16);\n    f4MinDepth.x = floor(f4MinDepth.x/R16_UNORM_PRECISION)*R16_UNORM_PRECISION;\n    f4MaxDepth.x =  ceil(f4MaxDepth.x/R16_UNORM_PRECISION)*R16_UNORM_PRECISION;\n#endif\n    return float2(f4MinDepth.x, f4MaxDepth.x);\n}\n\n// 1D min max mip map is arranged as follows:\n//\n//    g_MiscParams.ui4SrcDstMinMaxLevelOffset.x\n//     |\n//     |      g_MiscParams.ui4SrcDstMinMaxLevelOffset.z\n//     |_______|____ __\n//     |       |    |  |\n//     |       |    |  |\n//     |       |    |  |\n//     |       |    |  |\n//     |_______|____|__|\n//     |<----->|<-->|\n//         |     |\n//         |    uiMinMaxShadowMapResolution/\n//      uiMinMaxShadowMapResolution/2\n//                         \nMIN_MAX_DATA_FORMAT ComputeMinMaxShadowMapLevelPS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    uint2 uiDstSampleInd = uint2(In.m_f4Pos.xy);\n    uint2 uiSrcSample0Ind = uint2(g_MiscParams.ui4SrcDstMinMaxLevelOffset.x + (uiDstSampleInd.x - g_MiscParams.ui4SrcDstMinMaxLevelOffset.z)*2, uiDstSampleInd.y);\n    uint2 uiSrcSample1Ind = uiSrcSample0Ind + uint2(1,0);\n    MIN_MAX_DATA_FORMAT fnMinMaxDepth0 = g_tex2DMinMaxLightSpaceDepth.Load( uint3(uiSrcSample0Ind,0) );\n    MIN_MAX_DATA_FORMAT fnMinMaxDepth1 = g_tex2DMinMaxLightSpaceDepth.Load( uint3(uiSrcSample1Ind,0) );\n\n    float2 f2MinMaxDepth;\n    f2MinMaxDepth.x = min(fnMinMaxDepth0.x, fnMinMaxDepth1.x);\n    f2MinMaxDepth.y = max(fnMinMaxDepth0.y, fnMinMaxDepth1.y);\n    return f2MinMaxDepth;\n}\n\ntechnique11 BuildMinMaxMipMap\n{\n    pass PInitializeMinMaxShadowMap\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        // Only interpolation samples will not be discarded and increase the stencil value\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, InitializeMinMaxShadowMapPS() ) );\n    }\n\n    pass PComputeMinMaxShadowMapLevel\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        // Only interpolation samples will not be discarded and increase the stencil value\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, ComputeMinMaxShadowMapLevelPS() ) );\n    }\n}\n\n\nvoid MarkRayMarchingSamplesInStencilPS(SScreenSizeQuadVSOutput In)\n{\n    uint2 ui2InterpolationSources = g_tex2DInterpolationSource.Load( uint3(In.m_f4Pos.xy,0) );\n    // Ray marching samples are interpolated from themselves, so it is easy to detect them:\n    if( ui2InterpolationSources.x != ui2InterpolationSources.y )\n          discard;\n}\n\ntechnique11 MarkRayMarchingSamplesInStencil\n{\n    pass\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        // Only interpolation samples will not be discarded and increase the stencil value\n        SetDepthStencilState( DSS_NoDepth_StEqual_IncrStencil, 1 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, MarkRayMarchingSamplesInStencilPS() ) );\n    }\n}\n\nfloat3 InterpolateIrradiancePS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    uint uiSampleInd = In.m_f4Pos.x;\n    uint uiSliceInd = In.m_f4Pos.y;\n    // Get interpolation sources\n    uint2 ui2InterpolationSources = g_tex2DInterpolationSource.Load( uint3(uiSampleInd, uiSliceInd, 0) );\n    float fInterpolationPos = float(uiSampleInd - ui2InterpolationSources.x) / float( max(ui2InterpolationSources.y - ui2InterpolationSources.x,1) );\n\n    float3 f3SrcInsctr0 = g_tex2DInitialInsctrIrradiance.Load( uint3(ui2InterpolationSources.x, uiSliceInd, 0) );\n    float3 f3SrcInsctr1 = g_tex2DInitialInsctrIrradiance.Load( uint3(ui2InterpolationSources.y, uiSliceInd, 0));\n\n    // Ray marching samples are interpolated from themselves\n    return lerp(f3SrcInsctr0, f3SrcInsctr1, fInterpolationPos);\n}\n\ntechnique11 InterpolateIrradiance\n{\n    pass\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, InterpolateIrradiancePS() ) );\n    }\n}\n\nvoid UnwarpEpipolarInsctrImage( SScreenSizeQuadVSOutput In, \n                                in float fCamSpaceZ,\n                                out float3 f3Inscattering,\n                                out float3 f3Extinction )\n{\n    // Compute direction of the ray going from the light through the pixel\n    float2 f2RayDir = normalize( In.m_f2PosPS - g_LightAttribs.f4LightScreenPos.xy );\n\n    // Find, which boundary the ray intersects. For this, we will \n    // find which two of four half spaces the f2RayDir belongs to\n    // Each of four half spaces is produced by the line connecting one of four\n    // screen corners and the current pixel:\n    //    ________________        _______'________           ________________           \n    //   |'            . '|      |      '         |         |                |          \n    //   | '       . '    |      |     '          |      .  |                |          \n    //   |  '  . '        |      |    '           |        '|.        hs1    |          \n    //   |   *.           |      |   *     hs0    |         |  '*.           |          \n    //   |  '   ' .       |      |  '             |         |      ' .       |          \n    //   | '        ' .   |      | '              |         |          ' .   |          \n    //   |'____________ '_|      |'_______________|         | ____________ '_.          \n    //                           '                                             '\n    //                           ________________  .        '________________  \n    //                           |             . '|         |'               | \n    //                           |   hs2   . '    |         | '              | \n    //                           |     . '        |         |  '             | \n    //                           | . *            |         |   *            | \n    //                         . '                |         |    '           | \n    //                           |                |         | hs3 '          | \n    //                           |________________|         |______'_________| \n    //                                                              '\n    // The equations for the half spaces are the following:\n    //bool hs0 = (In.m_f2PosPS.x - (-1)) * f2RayDir.y < f2RayDir.x * (In.m_f2PosPS.y - (-1));\n    //bool hs1 = (In.m_f2PosPS.x -  (1)) * f2RayDir.y < f2RayDir.x * (In.m_f2PosPS.y - (-1));\n    //bool hs2 = (In.m_f2PosPS.x -  (1)) * f2RayDir.y < f2RayDir.x * (In.m_f2PosPS.y -  (1));\n    //bool hs3 = (In.m_f2PosPS.x - (-1)) * f2RayDir.y < f2RayDir.x * (In.m_f2PosPS.y -  (1));\n    // Note that in fact the outermost visible screen pixels do not lie exactly on the boundary (+1 or -1), but are biased by\n    // 0.5 screen pixel size inwards. Using these adjusted boundaries improves precision and results in\n    // smaller number of pixels which require inscattering correction\n    float4 f4Boundaries = GetOutermostScreenPixelCoords();//left, bottom, right, top\n    float4 f4HalfSpaceEquationTerms = (In.m_f2PosPS.xxyy - f4Boundaries.xzyw/*float4(-1,1,-1,1)*/) * f2RayDir.yyxx;\n    bool4 b4HalfSpaceFlags = f4HalfSpaceEquationTerms.xyyx < f4HalfSpaceEquationTerms.zzww;\n\n    // Now compute mask indicating which of four sectors the f2RayDir belongs to and consiquently\n    // which border the ray intersects:\n    //    ________________ \n    //   |'            . '|         0 : hs3 && !hs0\n    //   | '   3   . '    |         1 : hs0 && !hs1\n    //   |  '  . '        |         2 : hs1 && !hs2\n    //   |0  *.       2   |         3 : hs2 && !hs3\n    //   |  '   ' .       |\n    //   | '   1    ' .   |\n    //   |'____________ '_|\n    //\n    bool4 b4SectorFlags = b4HalfSpaceFlags.wxyz && !b4HalfSpaceFlags.xyzw;\n    // Note that b4SectorFlags now contains true (1) for the exit boundary and false (0) for 3 other\n\n    // Compute distances to boundaries according to following lines:\n    //float fDistToLeftBoundary   = abs(f2RayDir.x) > 1e-5 ? ( -1 - g_LightAttribs.f4LightScreenPos.x) / f2RayDir.x : -FLT_MAX;\n    //float fDistToBottomBoundary = abs(f2RayDir.y) > 1e-5 ? ( -1 - g_LightAttribs.f4LightScreenPos.y) / f2RayDir.y : -FLT_MAX;\n    //float fDistToRightBoundary  = abs(f2RayDir.x) > 1e-5 ? (  1 - g_LightAttribs.f4LightScreenPos.x) / f2RayDir.x : -FLT_MAX;\n    //float fDistToTopBoundary    = abs(f2RayDir.y) > 1e-5 ? (  1 - g_LightAttribs.f4LightScreenPos.y) / f2RayDir.y : -FLT_MAX;\n    float4 f4DistToBoundaries = ( f4Boundaries - g_LightAttribs.f4LightScreenPos.xyxy ) / (f2RayDir.xyxy + float4( abs(f2RayDir.xyxy)<1e-6 ) );\n    // Select distance to the exit boundary:\n    float fDistToExitBoundary = dot( b4SectorFlags, f4DistToBoundaries );\n    // Compute exit point on the boundary:\n    float2 f2ExitPoint = g_LightAttribs.f4LightScreenPos.xy + f2RayDir * fDistToExitBoundary;\n\n    // Compute epipolar slice for each boundary:\n    //if( LeftBoundary )\n    //    fEpipolarSlice = 0.0  - (LeftBoudaryIntersecPoint.y   -   1 )/2 /4;\n    //else if( BottomBoundary )\n    //    fEpipolarSlice = 0.25 + (BottomBoudaryIntersecPoint.x - (-1))/2 /4;\n    //else if( RightBoundary )\n    //    fEpipolarSlice = 0.5  + (RightBoudaryIntersecPoint.y  - (-1))/2 /4;\n    //else if( TopBoundary )\n    //    fEpipolarSlice = 0.75 - (TopBoudaryIntersecPoint.x      - 1 )/2 /4;\n    float4 f4EpipolarSlice = float4(0, 0.25, 0.5, 0.75) + \n        saturate( (f2ExitPoint.yxyx - f4Boundaries.wxyz)*float4(-1, +1, +1, -1) / (f4Boundaries.wzwz - f4Boundaries.yxyx) ) / 4.0;\n    // Select the right value:\n    float fEpipolarSlice = dot(b4SectorFlags, f4EpipolarSlice);\n\n    // Now find two closest epipolar slices, from which we will interpolate\n    // First, find index of the slice which precedes our slice\n    // Note that 0 <= fEpipolarSlice <= 1, and both 0 and 1 refer to the first slice\n    float fPrecedingSliceInd = min( floor(fEpipolarSlice*NUM_EPIPOLAR_SLICES), NUM_EPIPOLAR_SLICES-1 );\n\n    // Compute EXACT texture coordinates of preceding and succeeding slices and their weights\n    // Note that slice 0 is stored in the first texel which has exact texture coordinate 0.5/NUM_EPIPOLAR_SLICES\n    // (search for \"fEpipolarSlice = saturate(f2UV.x - 0.5f / (float)NUM_EPIPOLAR_SLICES)\"):\n    float fSrcSliceV[2];\n    // Compute V coordinate to refer exactly the center of the slice row\n    fSrcSliceV[0] = fPrecedingSliceInd/NUM_EPIPOLAR_SLICES + 0.5f/(float)NUM_EPIPOLAR_SLICES;\n    // Use frac() to wrap around to the first slice from the next-to-last slice:\n    fSrcSliceV[1] = frac( fSrcSliceV[0] + 1.f/(float)NUM_EPIPOLAR_SLICES );\n        \n    // Compute slice weights\n    float fSliceWeights[2];\n    fSliceWeights[1] = (fEpipolarSlice*NUM_EPIPOLAR_SLICES) - fPrecedingSliceInd;\n    fSliceWeights[0] = 1 - fSliceWeights[1];\n\n    f3Inscattering = 0;\n    f3Extinction = 0;\n    float fTotalWeight = 0;\n    [unroll]\n    for(int i=0; i<2; ++i)\n    {\n        // Load epipolar line endpoints\n        float4 f4SliceEndpoints = g_tex2DSliceEndPoints.SampleLevel( samLinearClamp, float2(fSrcSliceV[i], 0.5), 0 );\n\n        // Compute line direction on the screen\n        float2 f2SliceDir = f4SliceEndpoints.zw - f4SliceEndpoints.xy;\n        float fSliceLenSqr = dot(f2SliceDir, f2SliceDir);\n        \n        // Project current pixel onto the epipolar line\n        float fSamplePosOnLine = dot((In.m_f2PosPS - f4SliceEndpoints.xy), f2SliceDir) / max(fSliceLenSqr, 1e-8);\n        // Compute index of the slice on the line\n        // Note that the first sample on the line (fSamplePosOnLine==0) is exactly the Entry Point, while \n        // the last sample (fSamplePosOnLine==1) is exactly the Exit Point\n        // (search for \"fSamplePosOnEpipolarLine *= (float)MAX_SAMPLES_IN_SLICE / ((float)MAX_SAMPLES_IN_SLICE-1.f)\")\n        float fSampleInd = fSamplePosOnLine * (float)(MAX_SAMPLES_IN_SLICE-1);\n       \n        // We have to manually perform bilateral filtering of the scattered radiance texture to\n        // eliminate artifacts at depth discontinuities\n\n        float fPrecedingSampleInd = floor(fSampleInd);\n        // Get bilinear filtering weight\n        float fUWeight = fSampleInd - fPrecedingSampleInd;\n        // Get texture coordinate of the left source texel. Again, offset by 0.5 is essential\n        // to align with the texel center\n        float fPrecedingSampleU = (fPrecedingSampleInd + 0.5) / (float)(MAX_SAMPLES_IN_SLICE);\n    \n        float2 f2SctrColorUV = float2(fPrecedingSampleU, fSrcSliceV[i]);\n\n        // Gather 4 camera space z values\n        // Note that we need to bias f2SctrColorUV by 0.5 texel size to refer the location between all four texels and\n        // get the required values for sure\n        // The values in float4, which Gather() returns are arranged as follows:\n        //   _______ _______\n        //  |       |       |\n        //  |   x   |   y   |\n        //  |_______o_______|  o gather location\n        //  |       |       |\n        //  |   *w  |   z   |  * f2SctrColorUV\n        //  |_______|_______|\n        //  |<----->|\n        //     1/f2ScatteredColorTexDim.x\n        \n        // x == g_tex2DEpipolarCamSpaceZ.SampleLevel(samPointClamp, f2SctrColorUV, 0, int2(0,1))\n        // y == g_tex2DEpipolarCamSpaceZ.SampleLevel(samPointClamp, f2SctrColorUV, 0, int2(1,1))\n        // z == g_tex2DEpipolarCamSpaceZ.SampleLevel(samPointClamp, f2SctrColorUV, 0, int2(1,0))\n        // w == g_tex2DEpipolarCamSpaceZ.SampleLevel(samPointClamp, f2SctrColorUV, 0, int2(0,0))\n\n        const float2 f2ScatteredColorTexDim = float2(MAX_SAMPLES_IN_SLICE, NUM_EPIPOLAR_SLICES);\n        float2 f2SrcLocationsCamSpaceZ = g_tex2DEpipolarCamSpaceZ.Gather(samLinearClamp, f2SctrColorUV + float2(0.5, 0.5) / f2ScatteredColorTexDim.xy).wz;\n        \n        // Compute depth weights in a way that if the difference is less than the threshold, the weight is 1 and\n        // the weights fade out to 0 as the difference becomes larger than the threshold:\n        float2 f2MaxZ = max( f2SrcLocationsCamSpaceZ, max(fCamSpaceZ,1) );\n        float2 f2DepthWeights = saturate( g_PPAttribs.m_fRefinementThreshold / max( abs(fCamSpaceZ-f2SrcLocationsCamSpaceZ)/f2MaxZ, g_PPAttribs.m_fRefinementThreshold ) );\n        // Note that if the sample is located outside the [-1,1]x[-1,1] area, the sample is invalid and fCurrCamSpaceZ == fInvalidCoordinate\n        // Depth weight computed for such sample will be zero\n        f2DepthWeights = pow(f2DepthWeights, 4);\n\n        // Multiply bilinear weights with the depth weights:\n        float2 f2BilateralUWeights = float2(1-fUWeight, fUWeight) * f2DepthWeights * fSliceWeights[i];\n        // If the sample projection is behind [0,1], we have to discard this slice\n        // We however must take into account the fact that if at least one sample from the two \n        // bilinear sources is correct, the sample can still be properly computed\n        //        \n        //            -1       0       1                  N-2     N-1      N              Sample index\n        // |   X   |   X   |   X   |   X   |  ......   |   X   |   X   |   X   |   X   |\n        //         1-1/(N-1)   0    1/(N-1)                        1   1+1/(N-1)          fSamplePosOnLine   \n        //             |                                                   |\n        //             |<-------------------Clamp range------------------->|                   \n        //\n        f2BilateralUWeights *= (abs(fSamplePosOnLine - 0.5) < 0.5 + 1.f / (MAX_SAMPLES_IN_SLICE-1));\n        // We now need to compute the following weighted summ:\n        //f3FilteredSliceCol = \n        //    f2BilateralUWeights.x * g_tex2DScatteredColor.SampleLevel(samPoint, f2SctrColorUV, 0, int2(0,0)) +\n        //    f2BilateralUWeights.y * g_tex2DScatteredColor.SampleLevel(samPoint, f2SctrColorUV, 0, int2(1,0));\n\n        // We will use hardware to perform bilinear filtering and get this value using single bilinear fetch:\n\n        // Offset:                  (x=1,y=0)                (x=1,y=0)               (x=0,y=0)\n        float fSubpixelUOffset = f2BilateralUWeights.y / max(f2BilateralUWeights.x + f2BilateralUWeights.y, 0.001);\n        fSubpixelUOffset /= f2ScatteredColorTexDim.x;\n        \n        float3 f3FilteredSliceInsctr = \n            (f2BilateralUWeights.x + f2BilateralUWeights.y) * \n                g_tex2DScatteredColor.SampleLevel(samLinearClamp, f2SctrColorUV + float2(fSubpixelUOffset, 0), 0);\n        f3Inscattering += f3FilteredSliceInsctr;\n\n#if EXTINCTION_EVAL_MODE == EXTINCTION_EVAL_MODE_EPIPOLAR\n        float3 f3FilteredSliceExtinction = \n            (f2BilateralUWeights.x + f2BilateralUWeights.y) * \n                g_tex2DEpipolarExtinction.SampleLevel(samLinearClamp, f2SctrColorUV + float2(fSubpixelUOffset, 0), 0);\n        f3Extinction += f3FilteredSliceExtinction;\n#endif\n\n        // Update total weight\n        fTotalWeight += dot(f2BilateralUWeights, 1);\n    }\n\n#if CORRECT_INSCATTERING_AT_DEPTH_BREAKS\n    if( fTotalWeight < 1e-2 )\n    {\n        // Discarded pixels will keep 0 value in stencil and will be later\n        // processed to correct scattering\n        discard;\n    }\n#endif\n    \n    f3Inscattering /= fTotalWeight;\n    f3Extinction /= fTotalWeight;\n}\n\nfloat2 GetDensityIntegralAnalytic(float r, float mu, float d);\nfloat3 GetExtinction(in float3 f3StartPos, in float3 f3EndPos);\nfloat3 GetExtinctionUnverified(in float3 f3StartPos, in float3 f3EndPos, in float3 f3ViewDir, in float3 f3EarthCentre);\n\nfloat3 ApplyInscatteredRadiancePS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    float2 f2UV = ProjToUV(In.m_f2PosPS);\n    float fCamSpaceZ = GetCamSpaceZ( f2UV );\n    \n    float3 f3Inscttering, f3Extinction;\n    UnwarpEpipolarInsctrImage(In, fCamSpaceZ, f3Inscttering, f3Extinction);\n\n    float3 f3BackgroundColor = 0;\n    [branch]\n    if( !g_PPAttribs.m_bShowLightingOnly )\n    {\n        f3BackgroundColor = g_tex2DColorBuffer.SampleLevel( samPointClamp, f2UV, 0).rgb;\n        // fFarPlaneZ is pre-multiplied with 0.999999f\n        f3BackgroundColor *= (fCamSpaceZ > g_CameraAttribs.fFarPlaneZ) ? g_LightAttribs.f4ExtraterrestrialSunColor.rgb : 1;\n\n#if EXTINCTION_EVAL_MODE == EXTINCTION_EVAL_MODE_PER_PIXEL\n        float3 f3ReconstructedPosWS = ProjSpaceXYZToWorldSpace(float3(In.m_f2PosPS.xy, fCamSpaceZ));\n        f3Extinction = GetExtinction(g_CameraAttribs.f4CameraPos.xyz, f3ReconstructedPosWS);\n#endif\n        f3BackgroundColor *= f3Extinction;\n    }\n\n#if PERFORM_TONE_MAPPING\n    return ToneMap(f3BackgroundColor + f3Inscttering);\n#else\n    const float DELTA = 0.00001;\n    return log( max(DELTA, dot(f3BackgroundColor + f3Inscttering, RGB_TO_LUMINANCE)) );\n#endif\n}\n\ntechnique11 ApplyInscatteredRadiance\n{\n    pass PUnwarpInsctr\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepthTestIncrStencil, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, ApplyInscatteredRadiancePS() ) );\n    }\n}\n\n\nstruct PassThroughVS_Output\n{\n    uint uiVertexID : VERTEX_ID;\n};\n\nPassThroughVS_Output PassThroughVS(uint VertexID : SV_VertexID)\n{\n    PassThroughVS_Output Out = {VertexID};\n    return Out;\n}\n\n\n\nstruct SRenderSamplePositionsGS_Output\n{\n    float4 f4PosPS : SV_Position;\n    float3 f3Color : COLOR;\n    float2 f2PosXY : XY;\n    float4 f4QuadCenterAndSize : QUAD_CENTER_SIZE;\n};\n[maxvertexcount(4)]\nvoid RenderSamplePositionsGS(point PassThroughVS_Output In[1], \n                             inout TriangleStream<SRenderSamplePositionsGS_Output> triStream )\n{\n    uint2 CoordTexDim;\n    g_tex2DCoordinates.GetDimensions(CoordTexDim.x, CoordTexDim.y);\n    uint2 TexelIJ = uint2( In[0].uiVertexID%CoordTexDim.x, In[0].uiVertexID/CoordTexDim.x );\n    float2 f2QuadCenterPos = g_tex2DCoordinates.Load(int3(TexelIJ,0));\n\n    uint2 ui2InterpolationSources = g_tex2DInterpolationSource.Load( uint3(TexelIJ,0) );\n    bool bIsInterpolation = ui2InterpolationSources.x != ui2InterpolationSources.y;\n\n    float2 f2QuadSize = (bIsInterpolation ? 1.f : 4.f) / SCREEN_RESLOUTION.xy;\n    float4 MinMaxUV = float4(f2QuadCenterPos.x-f2QuadSize.x, f2QuadCenterPos.y - f2QuadSize.y, f2QuadCenterPos.x+f2QuadSize.x, f2QuadCenterPos.y + f2QuadSize.y);\n    \n    float3 f3Color = bIsInterpolation ? float3(0.5,0,0) : float3(1,0,0);\n    float4 Verts[4] = \n    {\n        float4(MinMaxUV.xy, 1.0, 1.0), \n        float4(MinMaxUV.xw, 1.0, 1.0),\n        float4(MinMaxUV.zy, 1.0, 1.0),\n        float4(MinMaxUV.zw, 1.0, 1.0)\n    };\n\n    for(int i=0; i<4; i++)\n    {\n        SRenderSamplePositionsGS_Output Out;\n        Out.f4PosPS = Verts[i];\n        Out.f2PosXY = Out.f4PosPS.xy;\n        Out.f3Color = f3Color;\n        Out.f4QuadCenterAndSize = float4(f2QuadCenterPos, f2QuadSize);\n        triStream.Append( Out );\n    }\n}\n\nfloat4 RenderSampleLocationsPS(SRenderSamplePositionsGS_Output In) : SV_Target\n{\n    return float4(In.f3Color, 1 - pow( length( (In.f2PosXY - In.f4QuadCenterAndSize.xy) / In.f4QuadCenterAndSize.zw),4) );\n}\n\nBlendState OverBS\n{\n    BlendEnable[0] = TRUE;\n    RenderTargetWriteMask[0] = 0x0F;\n    BlendOp = ADD;\n    SrcBlend = SRC_ALPHA;\n    DestBlend = INV_SRC_ALPHA;\n    SrcBlendAlpha = ZERO;\n    DestBlendAlpha = INV_SRC_ALPHA;\n};\n\ntechnique11 RenderSampleLocations\n{\n    pass\n    {\n        SetBlendState( OverBS, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, PassThroughVS() ) );\n        SetGeometryShader( CompileShader(gs_4_0, RenderSamplePositionsGS() ) );\n        SetPixelShader( CompileShader(ps_5_0, RenderSampleLocationsPS() ) );\n    }\n}\n\n\nfloat4 WorldParams2InsctrLUTCoords(float fHeight,\n                                   float fCosViewZenithAngle,\n                                   float fCosSunZenithAngle,\n                                   float fCosSunViewAngle,\n                                   in float4 f4PrevUVWQ = -1);\n\nfloat3 LookUpPrecomputedScattering(float3 f3StartPoint, \n                                   float3 f3ViewDir, \n                                   float3 f3EarthCentre,\n                                   float3 f3DirOnLight,\n                                   in Texture3D<float3> tex3DScatteringLUT,\n                                   inout float4 f4UVWQ)\n{\n    float3 f3EarthCentreToPointDir = f3StartPoint - f3EarthCentre;\n    float fDistToEarthCentre = length(f3EarthCentreToPointDir);\n    f3EarthCentreToPointDir /= fDistToEarthCentre;\n    float fHeightAboveSurface = fDistToEarthCentre - EARTH_RADIUS;\n    float fCosViewZenithAngle = dot( f3EarthCentreToPointDir, f3ViewDir    );\n    float fCosSunZenithAngle  = dot( f3EarthCentreToPointDir, f3DirOnLight );\n    float fCosSunViewAngle    = dot( f3ViewDir,               f3DirOnLight );\n\n    // Provide previous look-up coordinates\n    f4UVWQ = WorldParams2InsctrLUTCoords(fHeightAboveSurface, fCosViewZenithAngle,\n                                         fCosSunZenithAngle, fCosSunViewAngle, \n                                         f4UVWQ);\n\n    float3 f3UVW0; \n    f3UVW0.xy = f4UVWQ.xy;\n    float fQ0Slice = floor(f4UVWQ.w * PRECOMPUTED_SCTR_LUT_DIM.w - 0.5);\n    fQ0Slice = clamp(fQ0Slice, 0, PRECOMPUTED_SCTR_LUT_DIM.w-1);\n    float fQWeight = (f4UVWQ.w * PRECOMPUTED_SCTR_LUT_DIM.w - 0.5) - fQ0Slice;\n    fQWeight = max(fQWeight, 0);\n    float2 f2SliceMinMaxZ = float2(fQ0Slice, fQ0Slice+1)/PRECOMPUTED_SCTR_LUT_DIM.w + float2(0.5,-0.5) / (PRECOMPUTED_SCTR_LUT_DIM.z*PRECOMPUTED_SCTR_LUT_DIM.w);\n    f3UVW0.z =  (fQ0Slice + f4UVWQ.z) / PRECOMPUTED_SCTR_LUT_DIM.w;\n    f3UVW0.z = clamp(f3UVW0.z, f2SliceMinMaxZ.x, f2SliceMinMaxZ.y);\n    \n    float fQ1Slice = min(fQ0Slice+1, PRECOMPUTED_SCTR_LUT_DIM.w-1);\n    float fNextSliceOffset = (fQ1Slice - fQ0Slice) / PRECOMPUTED_SCTR_LUT_DIM.w;\n    float3 f3UVW1 = f3UVW0 + float3(0,0,fNextSliceOffset);\n    float3 f3Insctr0 = tex3DScatteringLUT.SampleLevel(samLinearClamp, f3UVW0, 0);\n    float3 f3Insctr1 = tex3DScatteringLUT.SampleLevel(samLinearClamp, f3UVW1, 0);\n    float3 f3Inscattering = lerp(f3Insctr0, f3Insctr1, fQWeight);\n\n    return f3Inscattering;\n}\n\nfloat2 GetNetParticleDensity(in float fHeightAboveSurface,\n                             in float fCosZenithAngle)\n{\n    float fRelativeHeightAboveSurface = fHeightAboveSurface / ATM_TOP_HEIGHT;\n    return g_tex2DOccludedNetDensityToAtmTop.SampleLevel(samLinearClamp, float2(fRelativeHeightAboveSurface, fCosZenithAngle*0.5+0.5), 0).xy;\n}\n\nfloat2 GetNetParticleDensity(in float3 f3Pos,\n                             in float3 f3EarthCentre,\n                             in float3 f3RayDir)\n{\n    float3 f3EarthCentreToPointDir = f3Pos - f3EarthCentre;\n    float fDistToEarthCentre = length(f3EarthCentreToPointDir);\n    f3EarthCentreToPointDir /= fDistToEarthCentre;\n    float fHeightAboveSurface = fDistToEarthCentre - EARTH_RADIUS;\n    float fCosZenithAngle = dot( f3EarthCentreToPointDir, f3RayDir );\n    return GetNetParticleDensity(fHeightAboveSurface, fCosZenithAngle);\n}\n\nvoid ApplyPhaseFunctions(inout float3 f3RayleighInscattering,\n                         inout float3 f3MieInscattering,\n                         in float cosTheta)\n{\n    f3RayleighInscattering *= g_MediaParams.f4AngularRayleighSctrCoeff.rgb * (1.0 + cosTheta*cosTheta);\n    \n    // Apply Cornette-Shanks phase function (see Nishita et al. 93):\n    // F(theta) = 1/(4*PI) * 3*(1-g^2) / (2*(2+g^2)) * (1+cos^2(theta)) / (1 + g^2 - 2g*cos(theta))^(3/2)\n    // f4CS_g = ( 3*(1-g^2) / (2*(2+g^2)), 1+g^2, -2g, 1 )\n    float fDenom = rsqrt( dot(g_MediaParams.f4CS_g.yz, float2(1.f, cosTheta)) ); // 1 / (1 + g^2 - 2g*cos(theta))^(1/2)\n    float fCornettePhaseFunc = g_MediaParams.f4CS_g.x * (fDenom*fDenom*fDenom) * (1 + cosTheta*cosTheta);\n    f3MieInscattering *= g_MediaParams.f4AngularMieSctrCoeff.rgb * fCornettePhaseFunc;\n}\n\n// This function computes atmospheric properties in the given point\nvoid GetAtmosphereProperties(in float3 f3Pos,\n                             in float3 f3EarthCentre,\n                             in float3 f3DirOnLight,\n                             out float2 f2ParticleDensity,\n                             out float2 f2NetParticleDensityToAtmTop)\n{\n    // Calculate the point height above the SPHERICAL Earth surface:\n    float3 f3EarthCentreToPointDir = f3Pos - f3EarthCentre;\n    float fDistToEarthCentre = length(f3EarthCentreToPointDir);\n    f3EarthCentreToPointDir /= fDistToEarthCentre;\n    float fHeightAboveSurface = fDistToEarthCentre - EARTH_RADIUS;\n\n    f2ParticleDensity = exp( -fHeightAboveSurface / PARTICLE_SCALE_HEIGHT );\n\n    // Get net particle density from the integration point to the top of the atmosphere:\n    float fCosSunZenithAngleForCurrPoint = dot( f3EarthCentreToPointDir, f3DirOnLight );\n    f2NetParticleDensityToAtmTop = GetNetParticleDensity(fHeightAboveSurface, fCosSunZenithAngleForCurrPoint);\n}\n\n// This function computes differential inscattering for the given particle densities \n// (without applying phase functions)\nvoid ComputePointDiffInsctr(in float2 f2ParticleDensityInCurrPoint,\n                            in float2 f2NetParticleDensityFromCam,\n                            in float2 f2NetParticleDensityToAtmTop,\n                            out float3 f3DRlghInsctr,\n                            out float3 f3DMieInsctr)\n{\n    // Compute total particle density from the top of the atmosphere through the integraion point to camera\n    float2 f2TotalParticleDensity = f2NetParticleDensityFromCam + f2NetParticleDensityToAtmTop;\n        \n    // Get optical depth\n    float3 f3TotalRlghOpticalDepth = g_MediaParams.f4RayleighExtinctionCoeff.rgb * f2TotalParticleDensity.x;\n    float3 f3TotalMieOpticalDepth  = g_MediaParams.f4MieExtinctionCoeff.rgb      * f2TotalParticleDensity.y;\n        \n    // And total extinction for the current integration point:\n    float3 f3TotalExtinction = exp( -(f3TotalRlghOpticalDepth + f3TotalMieOpticalDepth) );\n\n    f3DRlghInsctr = f2ParticleDensityInCurrPoint.x * f3TotalExtinction;\n    f3DMieInsctr  = f2ParticleDensityInCurrPoint.y * f3TotalExtinction; \n}\n\nvoid ComputeInsctrIntegral(in float3 f3RayStart,\n                           in float3 f3RayEnd,\n                           in float3 f3EarthCentre,\n                           in float3 f3DirOnLight,\n                           inout float2 f2NetParticleDensityFromCam,\n                           inout float3 f3RayleighInscattering,\n                           inout float3 f3MieInscattering,\n                           uniform const float fNumSteps)\n{\n    float3 f3Step = (f3RayEnd - f3RayStart) / fNumSteps;\n    float fStepLen = length(f3Step);\n\n#if TRAPEZOIDAL_INTEGRATION\n    // For trapezoidal integration we need to compute some variables for the starting point of the ray\n    float2 f2PrevParticleDensity = 0;\n    float2 f2NetParticleDensityToAtmTop = 0;\n    GetAtmosphereProperties(f3RayStart, f3EarthCentre, f3DirOnLight, f2PrevParticleDensity, f2NetParticleDensityToAtmTop);\n\n    float3 f3PrevDiffRInsctr = 0, f3PrevDiffMInsctr = 0;\n    ComputePointDiffInsctr(f2PrevParticleDensity, f2NetParticleDensityFromCam, f2NetParticleDensityToAtmTop, f3PrevDiffRInsctr, f3PrevDiffMInsctr);\n#endif\n\n\n#if TRAPEZOIDAL_INTEGRATION\n    // With trapezoidal integration, we will evaluate the function at the end of each section and \n    // compute area of a trapezoid\n    for(float fStepNum = 1.f; fStepNum <= fNumSteps; fStepNum += 1.f)\n#else\n    // With stair-step integration, we will evaluate the function at the middle of each section and \n    // compute area of a rectangle\n    for(float fStepNum = 0.5f; fStepNum < fNumSteps; fStepNum += 1.f)\n#endif\n    {\n        float3 f3CurrPos = f3RayStart + f3Step * fStepNum;\n        float2 f2ParticleDensity, f2NetParticleDensityToAtmTop;\n        GetAtmosphereProperties(f3CurrPos, f3EarthCentre, f3DirOnLight, f2ParticleDensity, f2NetParticleDensityToAtmTop);\n\n        // Accumulate net particle density from the camera to the integration point:\n#if TRAPEZOIDAL_INTEGRATION\n        f2NetParticleDensityFromCam += (f2PrevParticleDensity + f2ParticleDensity) * (fStepLen / 2.f);\n        f2PrevParticleDensity = f2ParticleDensity;\n#else\n        f2NetParticleDensityFromCam += f2ParticleDensity * fStepLen;\n#endif\n\n        float3 f3DRlghInsctr, f3DMieInsctr;\n        ComputePointDiffInsctr(f2ParticleDensity, f2NetParticleDensityFromCam, f2NetParticleDensityToAtmTop, f3DRlghInsctr, f3DMieInsctr);\n\n#if TRAPEZOIDAL_INTEGRATION\n        f3RayleighInscattering += (f3DRlghInsctr + f3PrevDiffRInsctr) * (fStepLen / 2.f);\n        f3MieInscattering      += (f3DMieInsctr  + f3PrevDiffMInsctr) * (fStepLen / 2.f);\n\n        f3PrevDiffRInsctr = f3DRlghInsctr;\n        f3PrevDiffMInsctr = f3DMieInsctr;\n#else\n        f3RayleighInscattering += f3DRlghInsctr * fStepLen;\n        f3MieInscattering      += f3DMieInsctr * fStepLen;\n#endif\n    }\n}\n\nvoid IntegrateUnshadowedInscattering(in float3 f3RayStart, \n                                     in float3 f3RayEnd,\n                                     in float3 f3ViewDir,\n                                     in float3 f3EarthCentre,\n                                     in float3 f3DirOnLight,\n                                     uniform const float fNumSteps,\n                                     out float3 f3Inscattering,\n                                     out float3 f3Extinction)\n{\n    float2 f2NetParticleDensityFromCam = 0;\n    float3 f3RayleighInscattering = 0;\n    float3 f3MieInscattering = 0;\n    ComputeInsctrIntegral( f3RayStart,\n                           f3RayEnd,\n                           f3EarthCentre,\n                           f3DirOnLight,\n                           f2NetParticleDensityFromCam,\n                           f3RayleighInscattering,\n                           f3MieInscattering,\n                           fNumSteps);\n\n    float3 f3TotalRlghOpticalDepth = g_MediaParams.f4RayleighExtinctionCoeff.rgb * f2NetParticleDensityFromCam.x;\n    float3 f3TotalMieOpticalDepth  = g_MediaParams.f4MieExtinctionCoeff.rgb      * f2NetParticleDensityFromCam.y;\n    f3Extinction = exp( -(f3TotalRlghOpticalDepth + f3TotalMieOpticalDepth) );\n\n    // Apply phase function\n    // Note that cosTheta = dot(DirOnCamera, LightDir) = dot(ViewDir, DirOnLight) because\n    // DirOnCamera = -ViewDir and LightDir = -DirOnLight\n    float cosTheta = dot(f3ViewDir, f3DirOnLight);\n    ApplyPhaseFunctions(f3RayleighInscattering, f3MieInscattering, cosTheta);\n\n    f3Inscattering = f3RayleighInscattering + f3MieInscattering;\n}\n\nvoid ComputeUnshadowedInscattering(float2 f2SampleLocation, \n                                   float fCamSpaceZ,\n                                   uniform const float fNumSteps,\n                                   out float3 f3Inscattering,\n                                   out float3 f3Extinction)\n{\n    f3Inscattering = 0;\n    f3Extinction = 1;\n    float3 f3RayTermination = ProjSpaceXYZToWorldSpace( float3(f2SampleLocation, fCamSpaceZ) );\n    float3 f3CameraPos = g_CameraAttribs.f4CameraPos.xyz;\n    float3 f3ViewDir = f3RayTermination - f3CameraPos;\n    float fRayLength = length(f3ViewDir);\n    f3ViewDir /= fRayLength;\n\n    float3 f3EarthCentre =  - float3(0,1,0) * EARTH_RADIUS;\n    float2 f2RayAtmTopIsecs;\n    GetRaySphereIntersection( f3CameraPos, f3ViewDir, f3EarthCentre, \n                              ATM_TOP_RADIUS, \n                              f2RayAtmTopIsecs);\n    if( f2RayAtmTopIsecs.y <= 0 )\n        return;\n\n    float3 f3RayStart = f3CameraPos + f3ViewDir * max(0, f2RayAtmTopIsecs.x);\n    if( fCamSpaceZ > g_CameraAttribs.fFarPlaneZ ) // fFarPlaneZ is pre-multiplied with 0.999999f\n        fRayLength = +FLT_MAX;\n    float3 f3RayEnd = f3CameraPos + f3ViewDir * min(fRayLength, f2RayAtmTopIsecs.y);\n            \n#if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_INTEGRATION\n    IntegrateUnshadowedInscattering(f3RayStart, \n                                    f3RayEnd,\n                                    f3ViewDir,\n                                    f3EarthCentre,\n                                    g_LightAttribs.f4DirOnLight.xyz,\n                                    fNumSteps,\n                                    f3Inscattering,\n                                    f3Extinction);\n#endif\n\n#if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_LUT || MULTIPLE_SCATTERING_MODE > MULTIPLE_SCTR_MODE_NONE\n\n#if MULTIPLE_SCATTERING_MODE > MULTIPLE_SCTR_MODE_NONE\n    #if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_LUT\n        Texture3D<float3> tex3DSctrLUT = g_tex3DMultipleSctrLUT;\n    #elif SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_NONE || SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_INTEGRATION\n        Texture3D<float3> tex3DSctrLUT = g_tex3DHighOrderSctrLUT;\n    #endif\n#else\n    Texture3D<float3> tex3DSctrLUT = g_tex3DSingleSctrLUT;\n#endif\n\n    f3Extinction = GetExtinctionUnverified(f3RayStart, f3RayEnd, f3ViewDir, f3EarthCentre);\n\n    // To avoid artifacts, we must be consistent when performing look-ups into the scattering texture, i.e.\n    // we must assure that if the first look-up is above (below) horizon, then the second look-up\n    // is also above (below) horizon. \n    float4 f4UVWQ = -1;\n    f3Inscattering +=                LookUpPrecomputedScattering(f3RayStart, f3ViewDir, f3EarthCentre, g_LightAttribs.f4DirOnLight.xyz, tex3DSctrLUT, f4UVWQ); \n    // Provide previous look-up coordinates to the function to assure that look-ups are consistent\n    f3Inscattering -= f3Extinction * LookUpPrecomputedScattering(f3RayEnd,   f3ViewDir, f3EarthCentre, g_LightAttribs.f4DirOnLight.xyz, tex3DSctrLUT, f4UVWQ);\n\n#endif\n\n\n}\n\n// This function calculates inscattered light integral over the ray from the camera to \n// the specified world space position using ray marching\nfloat3 ComputeShadowedInscattering( in float2 f2RayMarchingSampleLocation,\n                                    in float fRayEndCamSpaceZ,\n                                    in float fCascadeInd,\n                                    in uniform const bool bUse1DMinMaxMipMap = false,\n                                    uint uiEpipolarSliceInd = 0 )\n{   \n    float3 f3CameraPos = g_CameraAttribs.f4CameraPos.xyz;\n    uint uiCascadeInd = fCascadeInd;\n    \n    // Compute the ray termination point, full ray length and view direction\n    float3 f3RayTermination = ProjSpaceXYZToWorldSpace( float3(f2RayMarchingSampleLocation, fRayEndCamSpaceZ) );\n    float3 f3FullRay = f3RayTermination - f3CameraPos;\n    float fFullRayLength = length(f3FullRay);\n    float3 f3ViewDir = f3FullRay / fFullRayLength;\n\n    const float3 f3EarthCentre = float3(0, -EARTH_RADIUS, 0);\n\n    // Intersect the ray with the top of the atmosphere and the Earth:\n    float4 f4Isecs;\n    GetRaySphereIntersection2(f3CameraPos, f3ViewDir, f3EarthCentre, \n                              float2(ATM_TOP_RADIUS, EARTH_RADIUS), f4Isecs);\n    float2 f2RayAtmTopIsecs = f4Isecs.xy; \n    float2 f2RayEarthIsecs  = f4Isecs.zw;\n    \n    if( f2RayAtmTopIsecs.y <= 0 )\n    {\n        //                                                          view dir\n        //                                                        /\n        //             d<0                                       /\n        //               *--------->                            *\n        //            .      .                             .   /  . \n        //  .  '                    '  .         .  '         /\\         '  .\n        //                                                   /  f2rayatmtopisecs.y < 0\n        //\n        // the camera is outside the atmosphere and the ray either does not intersect the\n        // top of it or the intersection point is behind the camera. In either\n        // case there is no inscattering\n        return 0;\n    }\n\n    // Restrict the camera position to the top of the atmosphere\n    float fDistToAtmosphere = max(f2RayAtmTopIsecs.x, 0);\n    float3 f3RestrainedCameraPos = f3CameraPos + fDistToAtmosphere * f3ViewDir;\n\n    // Limit the ray length by the distance to the top of the atmosphere if the ray does not hit terrain\n    float fOrigRayLength = fFullRayLength;\n    if( fRayEndCamSpaceZ > g_CameraAttribs.fFarPlaneZ ) // fFarPlaneZ is pre-multiplied with 0.999999f\n        fFullRayLength = +FLT_MAX;\n    // Limit the ray length by the distance to the point where the ray exits the atmosphere\n    fFullRayLength = min(fFullRayLength, f2RayAtmTopIsecs.y);\n\n    // If there is an intersection with the Earth surface, limit the tracing distance to the intersection\n    if( f2RayEarthIsecs.x > 0 )\n    {\n        fFullRayLength = min(fFullRayLength, f2RayEarthIsecs.x);\n    }\n\n    fRayEndCamSpaceZ *= fFullRayLength / fOrigRayLength; \n    \n    float3 f3RayleighInscattering = 0;\n    float3 f3MieInscattering = 0;\n    float2 f2ParticleNetDensityFromCam = 0;\n    float3 f3RayEnd = 0, f3RayStart = 0;\n    \n    // Note that cosTheta = dot(DirOnCamera, LightDir) = dot(ViewDir, DirOnLight) because\n    // DirOnCamera = -ViewDir and LightDir = -DirOnLight\n    float cosTheta = dot(f3ViewDir, g_LightAttribs.f4DirOnLight.xyz);\n    \n    float fCascadeEndCamSpaceZ = 0;\n    float fTotalLitLength = 0, fTotalMarchedLength = 0; // Required for multiple scattering\n    float fDistToFirstLitSection = -1; // Used only in when SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_LUT\n\n#if CASCADE_PROCESSING_MODE == CASCADE_PROCESSING_MODE_SINGLE_PASS\n    for(; uiCascadeInd < (uint)g_PPAttribs.m_iNumCascades; ++uiCascadeInd, ++fCascadeInd)\n#else\n    for(int i=0; i<1; ++i)\n#endif\n    {\n        float2 f2CascadeStartEndCamSpaceZ = g_LightAttribs.ShadowAttribs.Cascades[uiCascadeInd].f4StartEndZ.xy;\n        float fCascadeStartCamSpaceZ = f2CascadeStartEndCamSpaceZ.x;//(uiCascadeInd > (uint)g_PPAttribs.m_iFirstCascade) ? f2CascadeStartEndCamSpaceZ.x : 0;\n        fCascadeEndCamSpaceZ = f2CascadeStartEndCamSpaceZ.y;\n        \n        // Check if the ray terminates before it enters current cascade \n        if( fRayEndCamSpaceZ < fCascadeStartCamSpaceZ )\n        {\n#if CASCADE_PROCESSING_MODE == CASCADE_PROCESSING_MODE_SINGLE_PASS\n            break;\n#else\n            return 0;\n#endif\n        }\n\n        // Truncate the ray against the far and near planes of the current cascade:\n        float fRayEndRatio = min( fRayEndCamSpaceZ, fCascadeEndCamSpaceZ ) / fRayEndCamSpaceZ;\n        float fRayStartRatio = fCascadeStartCamSpaceZ / fRayEndCamSpaceZ;\n        float fDistToRayStart = fFullRayLength * fRayStartRatio;\n        float fDistToRayEnd   = fFullRayLength * fRayEndRatio;\n\n        // If the camera is outside the atmosphere and the ray intersects the top of it,\n        // we must start integration from the first intersection point.\n        // If the camera is in the atmosphere, first intersection point is always behind the camera \n        // and thus is negative\n        //                               \n        //                      \n        //                     \n        //                   *                                              /\n        //              .   /  .                                       .   /  . \n        //    .  '         /\\         '  .                   .  '         /\\         '  .\n        //                /  f2RayAtmTopIsecs.x > 0                      /  f2RayAtmTopIsecs.y > 0\n        //                                                              *\n        //                 f2RayAtmTopIsecs.y > 0                         f2RayAtmTopIsecs.x < 0\n        //                /                                              /\n        //\n        fDistToRayStart = max(fDistToRayStart, f2RayAtmTopIsecs.x);\n        fDistToRayEnd   = max(fDistToRayEnd,   f2RayAtmTopIsecs.x);\n        \n        // To properly compute scattering from the space, we must \n        // set up ray end position before extiting the loop\n        f3RayEnd   = f3CameraPos + f3ViewDir * fDistToRayEnd;\n        f3RayStart = f3CameraPos + f3ViewDir * fDistToRayStart;\n\n#if CASCADE_PROCESSING_MODE != CASCADE_PROCESSING_MODE_SINGLE_PASS\n        float r = length(f3RestrainedCameraPos - f3EarthCentre);\n        float fCosZenithAngle = dot(f3RestrainedCameraPos-f3EarthCentre, f3ViewDir) / r;\n        float fDist = max(fDistToRayStart - fDistToAtmosphere, 0);\n        f2ParticleNetDensityFromCam = GetDensityIntegralAnalytic(r, fCosZenithAngle, fDist);\n#endif\n\n        float fRayLength = fDistToRayEnd - fDistToRayStart;\n        if( fRayLength <= 10 )\n        {\n#if CASCADE_PROCESSING_MODE == CASCADE_PROCESSING_MODE_SINGLE_PASS\n            continue;\n#else\n            if( (int)uiCascadeInd == g_PPAttribs.m_iNumCascades-1 )\n                // We need to process remaining part of the ray\n                break;\n            else\n                return 0;\n#endif\n        }\n\n        // We trace the ray in the light projection space, not in the world space\n        // Compute shadow map UV coordinates of the ray end point and its depth in the light space\n        matrix mWorldToShadowMapUVDepth = g_LightAttribs.ShadowAttribs.mWorldToShadowMapUVDepth[uiCascadeInd];\n        float3 f3StartUVAndDepthInLightSpace = WorldSpaceToShadowMapUV(f3RayStart, mWorldToShadowMapUVDepth);\n        //f3StartUVAndDepthInLightSpace.z -= SHADOW_MAP_DEPTH_BIAS;\n        float3 f3EndUVAndDepthInLightSpace = WorldSpaceToShadowMapUV(f3RayEnd, mWorldToShadowMapUVDepth);\n        //f3EndUVAndDepthInLightSpace.z -= SHADOW_MAP_DEPTH_BIAS;\n\n        // Calculate normalized trace direction in the light projection space and its length\n        float3 f3ShadowMapTraceDir = f3EndUVAndDepthInLightSpace.xyz - f3StartUVAndDepthInLightSpace.xyz;\n        // If the ray is directed exactly at the light source, trace length will be zero\n        // Clamp to a very small positive value to avoid division by zero\n        float fTraceLenInShadowMapUVSpace = max( length( f3ShadowMapTraceDir.xy ), 1e-7 );\n        // Note that f3ShadowMapTraceDir.xy can be exactly zero\n        f3ShadowMapTraceDir /= fTraceLenInShadowMapUVSpace;\n    \n        float fShadowMapUVStepLen = 0;\n        float2 f2SliceOriginUV = 0;\n        float2 f2SliceDirUV = 0;\n        uint uiMinMaxTexYInd = 0;\n        if( bUse1DMinMaxMipMap )\n        {\n            // Get UV direction for this slice\n            float4 f4SliceUVDirAndOrigin = g_tex2DSliceUVDirAndOrigin.Load( uint3(uiEpipolarSliceInd,uiCascadeInd,0) );\n            f2SliceDirUV = f4SliceUVDirAndOrigin.xy;\n            //if( all(f4SliceUVDirAndOrigin == g_f4IncorrectSliceUVDirAndStart) )\n            //{\n            //    return float3(0,0,0);\n            //}\n            //return float3(f4SliceUVDirAndOrigin.xy,0);\n            // Scale with the shadow map texel size\n            fShadowMapUVStepLen = length(f2SliceDirUV);\n            f2SliceOriginUV = f4SliceUVDirAndOrigin.zw;\n         \n#if USE_COMBINED_MIN_MAX_TEXTURE\n            uiMinMaxTexYInd = uiEpipolarSliceInd + (uiCascadeInd - g_PPAttribs.m_iFirstCascade) * g_PPAttribs.m_uiNumEpipolarSlices;\n#else\n            uiMinMaxTexYInd = uiEpipolarSliceInd;\n#endif\n\n        }\n        else\n        {\n            //Calculate length of the trace step in light projection space\n            float fMaxTraceDirDim = max( abs(f3ShadowMapTraceDir.x), abs(f3ShadowMapTraceDir.y) );\n            fShadowMapUVStepLen = (fMaxTraceDirDim > 0) ? (g_PPAttribs.m_f2ShadowMapTexelSize.x / fMaxTraceDirDim) : 0;\n            // Take into account maximum number of steps specified by the g_MiscParams.fMaxStepsAlongRay\n            fShadowMapUVStepLen = max(fTraceLenInShadowMapUVSpace/g_MiscParams.fMaxStepsAlongRay, fShadowMapUVStepLen);\n        }\n    \n        // Calcualte ray step length in world space\n        float fRayStepLengthWS = fRayLength * (fShadowMapUVStepLen / fTraceLenInShadowMapUVSpace);\n        // Note that fTraceLenInShadowMapUVSpace can be very small when looking directly at sun\n        // Since fShadowMapUVStepLen is at least one shadow map texel in size, \n        // fShadowMapUVStepLen / fTraceLenInShadowMapUVSpace >> 1 in this case and as a result\n        // fRayStepLengthWS >> fRayLength\n\n        // March the ray\n        float fDistanceMarchedInCascade = 0;\n        float3 f3CurrShadowMapUVAndDepthInLightSpace = f3StartUVAndDepthInLightSpace.xyz;\n\n        // The following variables are used only if 1D min map optimization is enabled\n        uint uiMinLevel = 0;\n        // It is essential to round initial sample pos to the closest integer\n        uint uiCurrSamplePos = length(f3StartUVAndDepthInLightSpace.xy - f2SliceOriginUV.xy)/fShadowMapUVStepLen + 0.5;\n        uint uiCurrTreeLevel = 0;\n        // Note that min/max shadow map does not contain finest resolution level\n        // The first level it contains corresponds to step == 2\n        int iLevelDataOffset = -int(g_PPAttribs.m_uiMinMaxShadowMapResolution);\n        float fStepScale = 1.f;\n        float fMaxStepScale = g_PPAttribs.m_fMaxShadowMapStep;\n#if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_INTEGRATION\n        // In order for the numerical integration to be accurate enough, it is necessary to make \n        // at least 10 steps along the ray. To assure this, limit the maximum world step by \n        // 1/10 of the ray length.\n        // To avoid aliasing artifacts due to unstable sampling along the view ray, do this for\n        // each cascade separately\n        float fMaxAllowedWorldStepLen = fRayLength/10;\n        fMaxStepScale = min(fMaxStepScale, fMaxAllowedWorldStepLen/fRayStepLengthWS);\n        \n        // Make sure that the world step length is not greater than the maximum allowable length\n        if( fRayStepLengthWS > fMaxAllowedWorldStepLen )\n        {\n            fRayStepLengthWS = fMaxAllowedWorldStepLen;\n            // Recalculate shadow map UV step len\n            fShadowMapUVStepLen = fTraceLenInShadowMapUVSpace * fRayStepLengthWS / fRayLength;\n            // Disable 1D min/max optimization. Note that fMaxStepScale < 1 anyway since \n            // fRayStepLengthWS > fMaxAllowedWorldStepLen. Thus there is no real need to\n            // make the max shadow map step negative. We do this just for clarity\n            fMaxStepScale = -1;\n        }\n#endif\n\n        // Scale trace direction in light projection space to calculate the step in shadow map\n        float3 f3ShadowMapUVAndDepthStep = f3ShadowMapTraceDir * fShadowMapUVStepLen;\n        \n        [loop]\n        while( fDistanceMarchedInCascade < fRayLength )\n        {\n            // Clamp depth to a very small positive value to avoid z-fighting at camera location\n            float fCurrDepthInLightSpace = max(f3CurrShadowMapUVAndDepthInLightSpace.z, 1e-7);\n            float IsInLight = 0;\n\n            if( bUse1DMinMaxMipMap )\n            {\n                // If the step scale can be doubled without exceeding the maximum allowed scale and \n                // the sample is located at the appropriate position, advance to the next coarser level\n                if( 2*fStepScale < fMaxStepScale && ((uiCurrSamplePos & ((2<<uiCurrTreeLevel)-1)) == 0) )\n                {\n                    iLevelDataOffset += g_PPAttribs.m_uiMinMaxShadowMapResolution >> uiCurrTreeLevel;\n                    uiCurrTreeLevel++;\n                    fStepScale *= 2.f;\n                }\n\n                while(uiCurrTreeLevel > uiMinLevel)\n                {\n                    // Compute light space depths at the ends of the current ray section\n\n                    // What we need here is actually depth which is divided by the camera view space z\n                    // Thus depth can be correctly interpolated in screen space:\n                    // http://www.comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf\n                    // A subtle moment here is that we need to be sure that we can skip fStepScale samples \n                    // starting from 0 up to fStepScale-1. We do not need to do any checks against the sample fStepScale away:\n                    //\n                    //     --------------->\n                    //\n                    //          *\n                    //               *         *\n                    //     *              *     \n                    //     0    1    2    3\n                    //\n                    //     |------------------>|\n                    //        fStepScale = 4\n                    float fNextLightSpaceDepth = f3CurrShadowMapUVAndDepthInLightSpace.z + f3ShadowMapUVAndDepthStep.z * (fStepScale-1);\n                    float2 f2StartEndDepthOnRaySection = float2(f3CurrShadowMapUVAndDepthInLightSpace.z, fNextLightSpaceDepth);\n                    f2StartEndDepthOnRaySection = f2StartEndDepthOnRaySection;//max(f2StartEndDepthOnRaySection, 1e-7);\n\n                    // Load 1D min/max depths\n                    float2 f2CurrMinMaxDepth = g_tex2DMinMaxLightSpaceDepth.Load( uint3( (uiCurrSamplePos>>uiCurrTreeLevel) + iLevelDataOffset, uiMinMaxTexYInd, 0) );\n                \n                    // Since we use complimentary depth buffer, the relations are reversed\n                    IsInLight = all( f2StartEndDepthOnRaySection >= f2CurrMinMaxDepth.yy );\n                    bool bIsInShadow = all( f2StartEndDepthOnRaySection < f2CurrMinMaxDepth.xx );\n\n                    if( IsInLight || bIsInShadow )\n                        // If the ray section is fully lit or shadowed, we can break the loop\n                        break;\n                    // If the ray section is neither fully lit, nor shadowed, we have to go to the finer level\n                    uiCurrTreeLevel--;\n                    iLevelDataOffset -= (int)(g_PPAttribs.m_uiMinMaxShadowMapResolution >> uiCurrTreeLevel);\n                    fStepScale /= 2.f;\n                };\n\n                // If we are at the finest level, sample the shadow map with PCF\n                [branch]\n                if( uiCurrTreeLevel <= uiMinLevel )\n                {\n                    IsInLight = g_tex2DLightSpaceDepthMap.SampleCmpLevelZero( samComparison, float3(f3CurrShadowMapUVAndDepthInLightSpace.xy,fCascadeInd), fCurrDepthInLightSpace  ).x;\n                }\n            }\n            else\n            {\n                IsInLight = g_tex2DLightSpaceDepthMap.SampleCmpLevelZero( samComparison, float3(f3CurrShadowMapUVAndDepthInLightSpace.xy,fCascadeInd), fCurrDepthInLightSpace ).x;\n            }\n\n            float fRemainingDist = max(fRayLength - fDistanceMarchedInCascade, 0);\n            float fIntegrationStep = min(fRayStepLengthWS * fStepScale, fRemainingDist);\n            float fIntegrationDist = fDistanceMarchedInCascade + fIntegrationStep/2;\n\n#if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_INTEGRATION\n            float3 f3CurrPos = f3RayStart + f3ViewDir * fIntegrationDist;\n\n            // Calculate integration point height above the SPHERICAL Earth surface:\n            float3 f3EarthCentreToPointDir = f3CurrPos - f3EarthCentre;\n            float fDistToEarthCentre = length(f3EarthCentreToPointDir);\n            f3EarthCentreToPointDir /= fDistToEarthCentre;\n            float fHeightAboveSurface = fDistToEarthCentre - EARTH_RADIUS;\n\n            float2 f2ParticleDensity = exp( -fHeightAboveSurface / PARTICLE_SCALE_HEIGHT );\n\n            // Do not use this branch as it only degrades performance\n            //if( IsInLight == 0)\n            //    continue;\n\n            // Get net particle density from the integration point to the top of the atmosphere:\n            float fCosSunZenithAngle = dot( f3EarthCentreToPointDir, g_LightAttribs.f4DirOnLight.xyz );\n            float2 f2NetParticleDensityToAtmTop = GetNetParticleDensity(fHeightAboveSurface, fCosSunZenithAngle);\n        \n            // Compute total particle density from the top of the atmosphere through the integraion point to camera\n            float2 f2TotalParticleDensity = f2ParticleNetDensityFromCam + f2NetParticleDensityToAtmTop;\n        \n            // Update net particle density from the camera to the integration point:\n            f2ParticleNetDensityFromCam += f2ParticleDensity * fIntegrationStep;\n\n            // Get optical depth\n            float3 f3TotalRlghOpticalDepth = g_MediaParams.f4RayleighExtinctionCoeff.rgb * f2TotalParticleDensity.x;\n            float3 f3TotalMieOpticalDepth  = g_MediaParams.f4MieExtinctionCoeff.rgb      * f2TotalParticleDensity.y;\n        \n            // And total extinction for the current integration point:\n            float3 f3TotalExtinction = exp( -(f3TotalRlghOpticalDepth + f3TotalMieOpticalDepth) );\n\n            f2ParticleDensity *= fIntegrationStep * IsInLight;\n            f3RayleighInscattering += f2ParticleDensity.x * f3TotalExtinction;\n            f3MieInscattering      += f2ParticleDensity.y * f3TotalExtinction;\n#endif\n\n#if MULTIPLE_SCATTERING_MODE == MULTIPLE_SCTR_MODE_OCCLUDED || SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_LUT\n            // Store the distance where the ray first enters the light\n            fDistToFirstLitSection = (fDistToFirstLitSection < 0 && IsInLight > 0) ? fTotalMarchedLength : fDistToFirstLitSection;\n#endif\n            f3CurrShadowMapUVAndDepthInLightSpace += f3ShadowMapUVAndDepthStep * fStepScale;\n            uiCurrSamplePos += 1 << uiCurrTreeLevel; // int -> float conversions are slow\n            fDistanceMarchedInCascade += fRayStepLengthWS * fStepScale;\n\n#if MULTIPLE_SCATTERING_MODE == MULTIPLE_SCTR_MODE_OCCLUDED || SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_LUT\n            fTotalLitLength += fIntegrationStep * IsInLight;\n            fTotalMarchedLength += fIntegrationStep;\n#endif\n        }\n    }\n\n#if MULTIPLE_SCATTERING_MODE == MULTIPLE_SCTR_MODE_OCCLUDED || SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_LUT\n    // If the whole ray is in shadow, set the distance to the first lit section to the\n    // total marched distance\n    if( fDistToFirstLitSection < 0 )\n        fDistToFirstLitSection = fTotalMarchedLength;\n#endif\n\n    float3 f3RemainingRayStart = 0;\n    float fRemainingLength = 0;\n    if( \n#if CASCADE_PROCESSING_MODE != CASCADE_PROCESSING_MODE_SINGLE_PASS\n        (int)uiCascadeInd == g_PPAttribs.m_iNumCascades-1 && \n#endif\n        fRayEndCamSpaceZ > fCascadeEndCamSpaceZ \n       )\n    {\n        f3RemainingRayStart = f3RayEnd;\n        f3RayEnd = f3CameraPos + fFullRayLength * f3ViewDir;\n        fRemainingLength = length(f3RayEnd - f3RemainingRayStart);\n#if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_INTEGRATION\n        // Do not allow integration step to become less than 50 km\n        // Maximum possible view ray length is 2023 km (from the top of the\n        // atmosphere touching the Earth and then again to the top of the \n        // atmosphere).\n        // For such ray, 41 integration step will be performed\n        // Also assure that at least 20 steps are always performed\n        float fMinStep = 50000.f;\n        float fMumSteps = max(20, ceil(fRemainingLength/fMinStep) );\n        ComputeInsctrIntegral(f3RemainingRayStart,\n                              f3RayEnd,\n                              f3EarthCentre,\n                              g_LightAttribs.f4DirOnLight.xyz,\n                              f2ParticleNetDensityFromCam,\n                              f3RayleighInscattering,\n                              f3MieInscattering,\n                              fMumSteps);\n#endif\n    }\n\n    float3 f3InsctrIntegral = 0;\n\n#if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_INTEGRATION\n    // Apply phase functions\n    // Note that cosTheta = dot(DirOnCamera, LightDir) = dot(ViewDir, DirOnLight) because\n    // DirOnCamera = -ViewDir and LightDir = -DirOnLight\n    ApplyPhaseFunctions(f3RayleighInscattering, f3MieInscattering, cosTheta);\n\n    f3InsctrIntegral = f3RayleighInscattering + f3MieInscattering;\n#endif\n\n#if CASCADE_PROCESSING_MODE == CASCADE_PROCESSING_MODE_SINGLE_PASS\n    // Note that the first cascade used for ray marching must contain camera within it\n    // otherwise this expression might fail\n    f3RayStart = f3RestrainedCameraPos;\n#endif\n\n#if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_LUT || MULTIPLE_SCATTERING_MODE == MULTIPLE_SCTR_MODE_OCCLUDED\n\n#if MULTIPLE_SCATTERING_MODE == MULTIPLE_SCTR_MODE_OCCLUDED\n    #if SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_LUT\n        Texture3D<float3> tex3DSctrLUT = g_tex3DMultipleSctrLUT;\n    #elif SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_NONE || SINGLE_SCATTERING_MODE == SINGLE_SCTR_MODE_INTEGRATION\n        Texture3D<float3> tex3DSctrLUT = g_tex3DHighOrderSctrLUT;\n    #endif\n#else\n    Texture3D<float3> tex3DSctrLUT = g_tex3DSingleSctrLUT;\n#endif\n\n    float3 f3MultipleScattering = 0;\n    if( fTotalLitLength > 0 )\n    {    \n        float3 f3LitSectionStart = f3RayStart + fDistToFirstLitSection * f3ViewDir;\n        float3 f3LitSectionEnd = f3LitSectionStart + fTotalLitLength * f3ViewDir;\n\n        float3 f3ExtinctionToStart = GetExtinctionUnverified(f3RestrainedCameraPos, f3LitSectionStart, f3ViewDir, f3EarthCentre);\n        float4 f4UVWQ = -1;\n        f3MultipleScattering = f3ExtinctionToStart * LookUpPrecomputedScattering(f3LitSectionStart, f3ViewDir, f3EarthCentre, g_LightAttribs.f4DirOnLight.xyz, tex3DSctrLUT, f4UVWQ); \n        \n        float3 f3ExtinctionToEnd = GetExtinctionUnverified(f3RestrainedCameraPos, f3LitSectionEnd, f3ViewDir,  f3EarthCentre);\n        // To avoid artifacts, we must be consistent when performing look-ups into the scattering texture, i.e.\n        // we must assure that if the first look-up is above (below) horizon, then the second look-up\n        // is also above (below) horizon.\n        // We provide previous look-up coordinates to the function so that it is able to figure out where the first look-up\n        // was performed\n        f3MultipleScattering -= f3ExtinctionToEnd * LookUpPrecomputedScattering(f3LitSectionEnd, f3ViewDir, f3EarthCentre, g_LightAttribs.f4DirOnLight.xyz, tex3DSctrLUT, f4UVWQ);\n        \n        f3InsctrIntegral += max(f3MultipleScattering, 0);\n    }\n\n    // Add contribution from the reminder of the ray behind the largest cascade\n    if( fRemainingLength > 0 )\n    {\n        float3 f3Extinction = GetExtinctionUnverified(f3RestrainedCameraPos, f3RemainingRayStart, f3ViewDir, f3EarthCentre);\n        float4 f4UVWQ = -1;\n        float3 f3RemainingInsctr = \n            f3Extinction * LookUpPrecomputedScattering(f3RemainingRayStart, f3ViewDir, f3EarthCentre, g_LightAttribs.f4DirOnLight.xyz, tex3DSctrLUT, f4UVWQ);\n        \n        f3Extinction = GetExtinctionUnverified(f3RestrainedCameraPos, f3RayEnd, f3ViewDir, f3EarthCentre);\n        f3RemainingInsctr -= \n            f3Extinction * LookUpPrecomputedScattering(f3RayEnd, f3ViewDir, f3EarthCentre, g_LightAttribs.f4DirOnLight.xyz, tex3DSctrLUT, f4UVWQ);\n\n        f3InsctrIntegral += max(f3RemainingInsctr, 0);\n    }\n#endif\n\n#if MULTIPLE_SCATTERING_MODE == MULTIPLE_SCTR_MODE_UNOCCLUDED\n    {\n        float3 f3HighOrderScattering = 0, f3Extinction = 0;\n        \n        float4 f4UVWQ = -1;\n        f3Extinction = GetExtinctionUnverified(f3RestrainedCameraPos, f3RayStart, f3ViewDir, f3EarthCentre);\n        f3HighOrderScattering += f3Extinction * LookUpPrecomputedScattering(f3RayStart, f3ViewDir, f3EarthCentre, g_LightAttribs.f4DirOnLight.xyz, g_tex3DHighOrderSctrLUT, f4UVWQ); \n        \n        f3Extinction = GetExtinctionUnverified(f3RestrainedCameraPos, f3RayEnd, f3ViewDir, f3EarthCentre);\n        // We provide previous look-up coordinates to the function so that it is able to figure out where the first look-up\n        // was performed\n        f3HighOrderScattering -= f3Extinction * LookUpPrecomputedScattering(f3RayEnd, f3ViewDir, f3EarthCentre, g_LightAttribs.f4DirOnLight.xyz, g_tex3DHighOrderSctrLUT, f4UVWQ); \n\n        f3InsctrIntegral += f3HighOrderScattering;\n    }\n#endif\n\n    return f3InsctrIntegral * g_LightAttribs.f4ExtraterrestrialSunColor.rgb;\n}\n\nfloat3 RayMarchMinMaxOptPS(SScreenSizeQuadVSOutput In) : SV_TARGET\n{\n    uint2 ui2SamplePosSliceInd = uint2(In.m_f4Pos.xy);\n    float2 f2SampleLocation = g_tex2DCoordinates.Load( uint3(ui2SamplePosSliceInd, 0) );\n    float fRayEndCamSpaceZ = g_tex2DEpipolarCamSpaceZ.Load( uint3(ui2SamplePosSliceInd, 0) );\n\n    [branch]\n    if( any(abs(f2SampleLocation) > 1+1e-3) )\n        return 0;\n\n    float fCascade = g_MiscParams.fCascadeInd + In.m_fInstID;\n\n#if ENABLE_LIGHT_SHAFTS\n    return ComputeShadowedInscattering(f2SampleLocation, \n                                 fRayEndCamSpaceZ,\n                                 fCascade,\n                                 true,  // Use min/max optimization\n                                 ui2SamplePosSliceInd.y);\n#else\n    float3 f3Inscattering, f3Extinction;\n    ComputeUnshadowedInscattering(f2SampleLocation, fRayEndCamSpaceZ, g_PPAttribs.m_uiInstrIntegralSteps, f3Inscattering, f3Extinction);\n    f3Inscattering *= g_LightAttribs.f4ExtraterrestrialSunColor.rgb;\n    return f3Inscattering;\n#endif\n}\n\nfloat3 RayMarchPS(SScreenSizeQuadVSOutput In) : SV_TARGET\n{\n    float2 f2SampleLocation = g_tex2DCoordinates.Load( uint3(In.m_f4Pos.xy, 0) );\n    float fRayEndCamSpaceZ = g_tex2DEpipolarCamSpaceZ.Load( uint3(In.m_f4Pos.xy, 0) );\n\n    [branch]\n    if( any(abs(f2SampleLocation) > 1+1e-3) )\n        return 0;\n\n#if ENABLE_LIGHT_SHAFTS\n    float fCascade = g_MiscParams.fCascadeInd + In.m_fInstID;\n    return ComputeShadowedInscattering(f2SampleLocation, \n                                 fRayEndCamSpaceZ,\n                                 fCascade,\n                                 false, // Do not use min/max optimization\n                                 0 // Ignored\n                                 );\n#else\n    float3 f3Inscattering, f3Extinction;\n    ComputeUnshadowedInscattering(f2SampleLocation, fRayEndCamSpaceZ, g_PPAttribs.m_uiInstrIntegralSteps, f3Inscattering, f3Extinction);\n    f3Inscattering *= g_LightAttribs.f4ExtraterrestrialSunColor.rgb;\n    return f3Inscattering;\n#endif\n}\n\ntechnique10 DoRayMarch\n{\n    pass P0\n    {\n        // Skip all samples which are not marked in the stencil as ray marching\n        SetDepthStencilState( DSS_NoDepth_StEqual_IncrStencil, 2 );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n\n        SetVertexShader( CompileShader( vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader(NULL);\n        SetPixelShader( CompileShader( ps_5_0, RayMarchPS() ) );\n    }\n\n    pass P1\n    {\n        // Skip all samples which are not marked in the stencil as ray marching\n        SetDepthStencilState( DSS_NoDepth_StEqual_IncrStencil, 2 );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n\n        SetVertexShader( CompileShader( vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader(NULL);\n        SetPixelShader( CompileShader( ps_5_0, RayMarchMinMaxOptPS() ) );\n    }\n}\n\nfloat3 FixInscatteredRadiancePS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    if( g_PPAttribs.m_bShowDepthBreaks )\n        return float3(0,1,0);\n\n    float fCascade = g_MiscParams.fCascadeInd + In.m_fInstID;\n    float fRayEndCamSpaceZ = g_tex2DCamSpaceZ.SampleLevel( samLinearClamp, ProjToUV(In.m_f2PosPS.xy), 0 );\n\n#if ENABLE_LIGHT_SHAFTS\n    return ComputeShadowedInscattering(In.m_f2PosPS.xy, \n                              fRayEndCamSpaceZ,\n                              fCascade,\n                              false, // We cannot use min/max optimization at depth breaks\n                              0 // Ignored\n                              );\n#else\n    float3 f3Inscattering, f3Extinction;\n    ComputeUnshadowedInscattering(In.m_f2PosPS.xy, fRayEndCamSpaceZ, g_PPAttribs.m_uiInstrIntegralSteps, f3Inscattering, f3Extinction);\n    f3Inscattering *= g_LightAttribs.f4ExtraterrestrialSunColor.rgb;\n    return f3Inscattering;\n#endif\n\n}\n\nfloat3 FixAndApplyInscatteredRadiancePS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    if( g_PPAttribs.m_bShowDepthBreaks )\n        return float3(0,1,0);\n\n    float fCamSpaceZ = GetCamSpaceZ( ProjToUV(In.m_f2PosPS) );\n    float3 f3BackgroundColor = 0;\n    [branch]\n    if( !g_PPAttribs.m_bShowLightingOnly )\n    {\n        f3BackgroundColor = g_tex2DColorBuffer.Load(int3(In.m_f4Pos.xy,0)).rgb;\n        f3BackgroundColor *= (fCamSpaceZ > g_CameraAttribs.fFarPlaneZ) ? g_LightAttribs.f4ExtraterrestrialSunColor.rgb : 1;\n        float3 f3ReconstructedPosWS = ProjSpaceXYZToWorldSpace(float3(In.m_f2PosPS.xy, fCamSpaceZ));\n        float3 f3Extinction = GetExtinction(g_CameraAttribs.f4CameraPos.xyz, f3ReconstructedPosWS);\n        f3BackgroundColor *= f3Extinction.rgb;\n    }\n    \n    float fCascade = g_MiscParams.fCascadeInd + In.m_fInstID;\n\n#if ENABLE_LIGHT_SHAFTS\n    float3 f3InsctrColor = \n        ComputeShadowedInscattering(In.m_f2PosPS.xy, \n                              fCamSpaceZ,\n                              fCascade,\n                              false, // We cannot use min/max optimization at depth breaks\n                              0 // Ignored\n                              );\n#else\n    float3 f3InsctrColor, f3Extinction;\n    ComputeUnshadowedInscattering(In.m_f2PosPS.xy, fCamSpaceZ, g_PPAttribs.m_uiInstrIntegralSteps, f3InsctrColor, f3Extinction);\n    f3InsctrColor *= g_LightAttribs.f4ExtraterrestrialSunColor.rgb;\n#endif\n\n#if PERFORM_TONE_MAPPING\n    return ToneMap(f3BackgroundColor + f3InsctrColor);\n#else\n    const float DELTA = 0.00001;\n    return log( max(DELTA, dot(f3BackgroundColor + f3InsctrColor, RGB_TO_LUMINANCE)) );\n#endif\n}\n\ntechnique11 FixInscatteredRadiance\n{\n    pass PRenderScatteringOnly\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepth_StEqual_IncrStencil, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, FixAndApplyInscatteredRadiancePS() ) );\n    }\n}\n\nvoid RenderCoarseUnshadowedInsctrPS(SScreenSizeQuadVSOutput In,\n                                    out float3 f3Inscattering : SV_Target0\n#if EXTINCTION_EVAL_MODE == EXTINCTION_EVAL_MODE_EPIPOLAR\n                                  , out float3 f3Extinction   : SV_Target1\n#endif\n                                  ) \n{\n    // Compute unshadowed inscattering from the camera to the ray end point using few steps\n    float fCamSpaceZ =  g_tex2DEpipolarCamSpaceZ.Load( uint3(In.m_f4Pos.xy, 0) );\n    float2 f2SampleLocation = g_tex2DCoordinates.Load( uint3(In.m_f4Pos.xy, 0) );\n#if EXTINCTION_EVAL_MODE != EXTINCTION_EVAL_MODE_EPIPOLAR\n    float3 f3Extinction = 1;\n#endif\n\n    ComputeUnshadowedInscattering(f2SampleLocation, fCamSpaceZ, \n                                  7, // Use hard-coded constant here so that compiler can optimize the code\n                                     // more efficiently\n                                  f3Inscattering, f3Extinction);\n    f3Inscattering *= g_LightAttribs.f4ExtraterrestrialSunColor.rgb;\n}\n\ntechnique11 RenderCoarseUnshadowedInsctr\n{\n    pass PRenderScatteringOnly\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepth_StEqual_KeepStencil, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, RenderCoarseUnshadowedInsctrPS() ) );\n    }\n}\n\nfloat2 IntegrateParticleDensity(in float3 f3Start, \n                                in float3 f3End,\n                                in float3 f3EarthCentre,\n                                float fNumSteps )\n{\n    float3 f3Step = (f3End - f3Start) / fNumSteps;\n    float fStepLen = length(f3Step);\n        \n    float fStartHeightAboveSurface = abs( length(f3Start - f3EarthCentre) - g_MediaParams.fEarthRadius );\n    float2 f2PrevParticleDensity = exp( -fStartHeightAboveSurface / g_MediaParams.f2ParticleScaleHeight );\n\n    float2 f2ParticleNetDensity = 0;\n    for(float fStepNum = 1; fStepNum <= fNumSteps; fStepNum += 1.f)\n    {\n        float3 f3CurrPos = f3Start + f3Step * fStepNum;\n        float fHeightAboveSurface = abs( length(f3CurrPos - f3EarthCentre) - g_MediaParams.fEarthRadius );\n        float2 f2ParticleDensity = exp( -fHeightAboveSurface / g_MediaParams.f2ParticleScaleHeight );\n        f2ParticleNetDensity += (f2ParticleDensity + f2PrevParticleDensity) * fStepLen / 2.f;\n        f2PrevParticleDensity = f2ParticleDensity;\n    }\n    return f2ParticleNetDensity;\n}\n\n\nfloat2 IntegrateParticleDensityAlongRay(in float3 f3Pos, \n                                        in float3 f3RayDir,\n                                        float3 f3EarthCentre, \n                                        uniform const float fNumSteps,\n                                        uniform const bool bOccludeByEarth)\n{\n    if( bOccludeByEarth )\n    {\n        // If the ray intersects the Earth, return huge optical depth\n        float2 f2RayEarthIsecs; \n        GetRaySphereIntersection(f3Pos, f3RayDir, f3EarthCentre, g_MediaParams.fEarthRadius, f2RayEarthIsecs);\n        if( f2RayEarthIsecs.x > 0 )\n            return 1e+20;\n    }\n\n    // Get intersection with the top of the atmosphere (the start point must always be under the top of it)\n    //      \n    //                     /\n    //                .   /  . \n    //      .  '         /\\         '  .\n    //                  /  f2RayAtmTopIsecs.y > 0\n    //                 *\n    //                   f2RayAtmTopIsecs.x < 0\n    //                  /\n    //      \n    float2 f2RayAtmTopIsecs;\n    GetRaySphereIntersection(f3Pos, f3RayDir, f3EarthCentre, g_MediaParams.fAtmTopRadius, f2RayAtmTopIsecs);\n    float fIntegrationDist = f2RayAtmTopIsecs.y;\n\n    float3 f3RayEnd = f3Pos + f3RayDir * fIntegrationDist;\n\n    return IntegrateParticleDensity(f3Pos, f3RayEnd, f3EarthCentre, fNumSteps);\n}\n\nfloat2 PrecomputeNetDensityToAtmTopPS( SScreenSizeQuadVSOutput In ) : SV_Target0\n{\n    float2 f2UV = ProjToUV(In.m_f2PosPS);\n    // Do not allow start point be at the Earth surface and on the top of the atmosphere\n    float fStartHeight = clamp( lerp(0, g_MediaParams.fAtmTopHeight, f2UV.x), 10, g_MediaParams.fAtmTopHeight-10 );\n\n    float fCosTheta = -In.m_f2PosPS.y;\n    float fSinTheta = sqrt( saturate(1 - fCosTheta*fCosTheta) );\n    float3 f3RayStart = float3(0, 0, fStartHeight);\n    float3 f3RayDir = float3(fSinTheta, 0, fCosTheta);\n    \n    float3 f3EarthCentre = float3(0,0,-g_MediaParams.fEarthRadius);\n\n    const float fNumSteps = 200;\n    return IntegrateParticleDensityAlongRay(f3RayStart, f3RayDir, f3EarthCentre, fNumSteps, true);\n}\n\n\ntechnique11 PrecomputeNetDensityToAtmTopTech\n{\n    pass P0\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, PrecomputeNetDensityToAtmTopPS() ) );\n    }\n}\n\n// This function for analytical evaluation of particle density integral is \n// provided by Eric Bruneton\n// http://www-evasion.inrialpes.fr/Membres/Eric.Bruneton/\n//\n// optical depth for ray (r,mu) of length d, using analytic formula\n// (mu=cos(view zenith angle)), intersections with ground ignored\nfloat2 GetDensityIntegralAnalytic(float r, float mu, float d) \n{\n    float2 f2A = sqrt( (0.5/PARTICLE_SCALE_HEIGHT.xy) * r );\n    float4 f4A01 = f2A.xxyy * float2(mu, mu + d / r).xyxy;\n    float4 f4A01s = sign(f4A01);\n    float4 f4A01sq = f4A01*f4A01;\n    \n    float2 f2X;\n    f2X.x = f4A01s.y > f4A01s.x ? exp(f4A01sq.x) : 0.0;\n    f2X.y = f4A01s.w > f4A01s.z ? exp(f4A01sq.z) : 0.0;\n    \n    float4 f4Y = f4A01s / (2.3193*abs(f4A01) + sqrt(1.52*f4A01sq + 4.0)) * float3(1.0, exp(-d/PARTICLE_SCALE_HEIGHT.xy*(d/(2.0*r)+mu))).xyxz;\n\n    return sqrt((6.2831*PARTICLE_SCALE_HEIGHT)*r) * exp((EARTH_RADIUS-r)/PARTICLE_SCALE_HEIGHT.xy) * (f2X + float2( dot(f4Y.xy, float2(1.0, -1.0)), dot(f4Y.zw, float2(1.0, -1.0)) ));\n}\n\nfloat3 GetExtinctionUnverified(in float3 f3StartPos, in float3 f3EndPos, float3 f3EyeDir, float3 f3EarthCentre)\n{\n#if 0\n    float2 f2ParticleDensity = IntegrateParticleDensity(f3StartPos, f3EndPos, f3EarthCentre, 20);\n#else\n    float r = length(f3StartPos-f3EarthCentre);\n    float fCosZenithAngle = dot(f3StartPos-f3EarthCentre, f3EyeDir) / r;\n    float2 f2ParticleDensity = GetDensityIntegralAnalytic(r, fCosZenithAngle, length(f3StartPos - f3EndPos));\n#endif\n\n    // Get optical depth\n    float3 f3TotalRlghOpticalDepth = g_MediaParams.f4RayleighExtinctionCoeff.rgb * f2ParticleDensity.x;\n    float3 f3TotalMieOpticalDepth  = g_MediaParams.f4MieExtinctionCoeff.rgb * f2ParticleDensity.y;\n        \n    // Compute extinction\n    float3 f3Extinction = exp( -(f3TotalRlghOpticalDepth + f3TotalMieOpticalDepth) );\n    return f3Extinction;\n}\n\nfloat3 GetExtinction(in float3 f3StartPos, in float3 f3EndPos)\n{\n    float3 f3EyeDir = f3EndPos - f3StartPos;\n    float fRayLength = length(f3EyeDir);\n    f3EyeDir /= fRayLength;\n\n    float3 f3EarthCentre = /*g_CameraAttribs.f4CameraPos.xyz*float3(1,0,1)*/ - float3(0,1,0) * EARTH_RADIUS;\n\n    float2 f2RayAtmTopIsecs; \n    // Compute intersections of the view ray with the atmosphere\n    GetRaySphereIntersection(f3StartPos, f3EyeDir, f3EarthCentre, ATM_TOP_RADIUS, f2RayAtmTopIsecs);\n    // If the ray misses the atmosphere, there is no extinction\n    if( f2RayAtmTopIsecs.y < 0 )return 1;\n\n    // Do not let the start and end point be outside the atmosphere\n    f3EndPos = f3StartPos + f3EyeDir * min(f2RayAtmTopIsecs.y, fRayLength);\n    f3StartPos += f3EyeDir * max(f2RayAtmTopIsecs.x, 0);\n\n    return GetExtinctionUnverified(f3StartPos, f3EndPos, f3EyeDir, f3EarthCentre);\n}\n\nfloat GetCosHorizonAnlge(float fHeight)\n{\n    // Due to numeric precision issues, fHeight might sometimes be slightly negative\n    fHeight = max(fHeight, 0);\n    return -sqrt(fHeight * (2*EARTH_RADIUS + fHeight) ) / (EARTH_RADIUS + fHeight);\n}\n\nfloat ZenithAngle2TexCoord(float fCosZenithAngle, float fHeight, in float fTexDim, float power, float fPrevTexCoord)\n{\n    fCosZenithAngle = fCosZenithAngle;\n    float fTexCoord;\n    float fCosHorzAngle = GetCosHorizonAnlge(fHeight);\n    // When performing look-ups into the scattering texture, it is very important that all the look-ups are consistent\n    // wrt to the horizon. This means that if the first look-up is above (below) horizon, then the second look-up\n    // should also be above (below) horizon. \n    // We use previous texture coordinate, if it is provided, to find out if previous look-up was above or below\n    // horizon. If texture coordinate is negative, then this is the first look-up\n    bool bIsAboveHorizon = fPrevTexCoord >= 0.5;\n    bool bIsBelowHorizon = 0 <= fPrevTexCoord && fPrevTexCoord < 0.5;\n    if(  bIsAboveHorizon || \n        !bIsBelowHorizon && (fCosZenithAngle > fCosHorzAngle) )\n    {\n        // Scale to [0,1]\n        fTexCoord = saturate( (fCosZenithAngle - fCosHorzAngle) / (1 - fCosHorzAngle) );\n        fTexCoord = pow(fTexCoord, power);\n        // Now remap texture coordinate to the upper half of the texture.\n        // To avoid filtering across discontinuity at 0.5, we must map\n        // the texture coordinate to [0.5 + 0.5/fTexDim, 1 - 0.5/fTexDim]\n        //\n        //      0.5   1.5               D/2+0.5        D-0.5  texture coordinate x dimension\n        //       |     |                   |            |\n        //    |  X  |  X  | .... |  X  ||  X  | .... |  X  |  \n        //       0     1          D/2-1   D/2          D-1    texel index\n        //\n        fTexCoord = 0.5f + 0.5f / fTexDim + fTexCoord * (fTexDim/2 - 1) / fTexDim;\n    }\n    else\n    {\n        fTexCoord = saturate( (fCosHorzAngle - fCosZenithAngle) / (fCosHorzAngle - (-1)) );\n        fTexCoord = pow(fTexCoord, power);\n        // Now remap texture coordinate to the lower half of the texture.\n        // To avoid filtering across discontinuity at 0.5, we must map\n        // the texture coordinate to [0.5, 0.5 - 0.5/fTexDim]\n        //\n        //      0.5   1.5        D/2-0.5             texture coordinate x dimension\n        //       |     |            |       \n        //    |  X  |  X  | .... |  X  ||  X  | .... \n        //       0     1          D/2-1   D/2        texel index\n        //\n        fTexCoord = 0.5f / fTexDim + fTexCoord * (fTexDim/2 - 1) / fTexDim;\n    }    \n\n    return fTexCoord;\n}\n\nfloat TexCoord2ZenithAngle(float fTexCoord, float fHeight, in float fTexDim, float power)\n{\n    float fCosZenithAngle;\n\n    float fCosHorzAngle = GetCosHorizonAnlge(fHeight);\n    if( fTexCoord > 0.5 )\n    {\n        // Remap to [0,1] from the upper half of the texture [0.5 + 0.5/fTexDim, 1 - 0.5/fTexDim]\n        fTexCoord = saturate( (fTexCoord - (0.5f + 0.5f / fTexDim)) * fTexDim / (fTexDim/2 - 1) );\n        fTexCoord = pow(fTexCoord, 1/power);\n        // Assure that the ray does NOT hit Earth\n        fCosZenithAngle = max( (fCosHorzAngle + fTexCoord * (1 - fCosHorzAngle)), fCosHorzAngle + 1e-4);\n    }\n    else\n    {\n        // Remap to [0,1] from the lower half of the texture [0.5, 0.5 - 0.5/fTexDim]\n        fTexCoord = saturate((fTexCoord - 0.5f / fTexDim) * fTexDim / (fTexDim/2 - 1));\n        fTexCoord = pow(fTexCoord, 1/power);\n        // Assure that the ray DOES hit Earth\n        fCosZenithAngle = min( (fCosHorzAngle - fTexCoord * (fCosHorzAngle - (-1))), fCosHorzAngle - 1e-4);\n    }\n    return fCosZenithAngle;\n}\n\nstatic const float SafetyHeightMargin = 16.f;\n#define NON_LINEAR_PARAMETERIZATION 1\nstatic const float HeightPower = 0.5f;\nstatic const float ViewZenithPower = 0.2;\nstatic const float SunViewPower = 1.5f;\n\nvoid InsctrLUTCoords2WorldParams(in float4 f4UVWQ,\n                                 out float fHeight,\n                                 out float fCosViewZenithAngle,\n                                 out float fCosSunZenithAngle,\n                                 out float fCosSunViewAngle)\n{\n#if NON_LINEAR_PARAMETERIZATION\n    // Rescale to exactly 0,1 range\n    f4UVWQ.xzw = saturate((f4UVWQ* PRECOMPUTED_SCTR_LUT_DIM - 0.5) / (PRECOMPUTED_SCTR_LUT_DIM-1)).xzw;\n\n    f4UVWQ.x = pow( f4UVWQ.x, 1/HeightPower );\n    // Allowable height range is limited to [SafetyHeightMargin, AtmTopHeight - SafetyHeightMargin] to\n    // avoid numeric issues at the Earth surface and the top of the atmosphere\n    fHeight = f4UVWQ.x * (g_MediaParams.fAtmTopHeight - 2*SafetyHeightMargin) + SafetyHeightMargin;\n\n    fCosViewZenithAngle = TexCoord2ZenithAngle(f4UVWQ.y, fHeight, PRECOMPUTED_SCTR_LUT_DIM.y, ViewZenithPower);\n    \n    // Use Eric Bruneton's formula for cosine of the sun-zenith angle\n    fCosSunZenithAngle = tan((2.0 * f4UVWQ.z - 1.0 + 0.26) * 1.1) / tan(1.26 * 1.1);\n\n    f4UVWQ.w = sign(f4UVWQ.w - 0.5) * pow( abs((f4UVWQ.w - 0.5)*2), 1/SunViewPower)/2 + 0.5;\n    fCosSunViewAngle = cos(f4UVWQ.w*PI);\n#else\n    // Rescale to exactly 0,1 range\n    f4UVWQ = (f4UVWQ * PRECOMPUTED_SCTR_LUT_DIM - 0.5) / (PRECOMPUTED_SCTR_LUT_DIM-1);\n\n    // Allowable height range is limited to [SafetyHeightMargin, AtmTopHeight - SafetyHeightMargin] to\n    // avoid numeric issues at the Earth surface and the top of the atmosphere\n    fHeight = f4UVWQ.x * (g_MediaParams.fAtmTopHeight - 2*SafetyHeightMargin) + SafetyHeightMargin;\n\n    fCosViewZenithAngle = f4UVWQ.y * 2 - 1;\n    fCosSunZenithAngle  = f4UVWQ.z * 2 - 1;\n    fCosSunViewAngle    = f4UVWQ.w * 2 - 1;\n#endif\n\n    fCosViewZenithAngle = clamp(fCosViewZenithAngle, -1, +1);\n    fCosSunZenithAngle  = clamp(fCosSunZenithAngle,  -1, +1);\n    // Compute allowable range for the cosine of the sun view angle for the given\n    // view zenith and sun zenith angles\n    float D = (1.0 - fCosViewZenithAngle * fCosViewZenithAngle) * (1.0 - fCosSunZenithAngle  * fCosSunZenithAngle);\n    \n    // !!!!  IMPORTANT NOTE regarding NVIDIA hardware !!!!\n\n    // There is a very weird issue on NVIDIA hardware with clamp(), saturate() and min()/max() \n    // functions. No matter what function is used, fCosViewZenithAngle and fCosSunZenithAngle\n    // can slightly fall outside [-1,+1] range causing D to be negative\n    // Using saturate(D), max(D, 0) and even D>0?D:0 does not work!\n    // The only way to avoid taking the square root of negative value and obtaining NaN is \n    // to use max() with small positive value:\n    D = sqrt( max(D, 1e-20) );\n    \n    // The issue was reproduceable on NV GTX 680, driver version 9.18.13.2723 (9/12/2013).\n    // The problem does not arise on Intel hardware\n\n    float2 f2MinMaxCosSunViewAngle = fCosViewZenithAngle*fCosSunZenithAngle + float2(-D, +D);\n    // Clamp to allowable range\n    fCosSunViewAngle    = clamp(fCosSunViewAngle, f2MinMaxCosSunViewAngle.x, f2MinMaxCosSunViewAngle.y);\n}\n\nfloat4 WorldParams2InsctrLUTCoords(float fHeight,\n                                   float fCosViewZenithAngle,\n                                   float fCosSunZenithAngle,\n                                   float fCosSunViewAngle,\n                                   in float4 f4RefUVWQ)\n{\n    float4 f4UVWQ;\n\n    // Limit allowable height range to [SafetyHeightMargin, AtmTopHeight - SafetyHeightMargin] to\n    // avoid numeric issues at the Earth surface and the top of the atmosphere\n    // (ray/Earth and ray/top of the atmosphere intersection tests are unstable when fHeight == 0 and\n    // fHeight == AtmTopHeight respectively)\n    fHeight = clamp(fHeight, SafetyHeightMargin, g_MediaParams.fAtmTopHeight - SafetyHeightMargin);\n    f4UVWQ.x = saturate( (fHeight - SafetyHeightMargin) / (g_MediaParams.fAtmTopHeight - 2*SafetyHeightMargin) );\n\n#if NON_LINEAR_PARAMETERIZATION\n    f4UVWQ.x = pow(f4UVWQ.x, HeightPower);\n\n    f4UVWQ.y = ZenithAngle2TexCoord(fCosViewZenithAngle, fHeight, PRECOMPUTED_SCTR_LUT_DIM.y, ViewZenithPower, f4RefUVWQ.y);\n    \n    // Use Eric Bruneton's formula for cosine of the sun-zenith angle\n    f4UVWQ.z = (atan(max(fCosSunZenithAngle, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5;\n\n    fCosSunViewAngle = clamp(fCosSunViewAngle, -1, +1);\n    f4UVWQ.w = acos(fCosSunViewAngle) / PI;\n    f4UVWQ.w = sign(f4UVWQ.w - 0.5) * pow( abs((f4UVWQ.w - 0.5)/0.5), SunViewPower)/2 + 0.5;\n    \n    f4UVWQ.xzw = ((f4UVWQ * (PRECOMPUTED_SCTR_LUT_DIM-1) + 0.5) / PRECOMPUTED_SCTR_LUT_DIM).xzw;\n#else\n    f4UVWQ.y = (fCosViewZenithAngle+1.f) / 2.f;\n    f4UVWQ.z = (fCosSunZenithAngle +1.f) / 2.f;\n    f4UVWQ.w = (fCosSunViewAngle   +1.f) / 2.f;\n\n    f4UVWQ = (f4UVWQ * (PRECOMPUTED_SCTR_LUT_DIM-1) + 0.5) / PRECOMPUTED_SCTR_LUT_DIM;\n#endif\n\n    return f4UVWQ;\n}\n\nfloat3 ComputeViewDir(in float fCosViewZenithAngle)\n{\n    return float3(sqrt(saturate(1 - fCosViewZenithAngle*fCosViewZenithAngle)), fCosViewZenithAngle, 0);\n}\n\nfloat3 ComputeLightDir(in float3 f3ViewDir, in float fCosSunZenithAngle, in float fCosSunViewAngle)\n{\n    float3 f3DirOnLight;\n    f3DirOnLight.x = (f3ViewDir.x > 0) ? (fCosSunViewAngle - fCosSunZenithAngle * f3ViewDir.y) / f3ViewDir.x : 0;\n    f3DirOnLight.y = fCosSunZenithAngle;\n    f3DirOnLight.z = sqrt( saturate(1 - dot(f3DirOnLight.xy, f3DirOnLight.xy)) );\n    // Do not normalize f3DirOnLight! Even if its length is not exactly 1 (which can \n    // happen because of fp precision issues), all the dot products will still be as \n    // specified, which is essentially important. If we normalize the vector, all the \n    // dot products will deviate, resulting in wrong pre-computation.\n    // Since fCosSunViewAngle is clamped to allowable range, f3DirOnLight should always\n    // be normalized. However, due to some issues on NVidia hardware sometimes\n    // it may not be as that (see IMPORTANT NOTE regarding NVIDIA hardware)\n    //f3DirOnLight = normalize(f3DirOnLight);\n    return f3DirOnLight;\n}\n\n// This shader pre-computes the radiance of single scattering at a given point in given\n// direction.\nfloat3 PrecomputeSingleScatteringPS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    // Get attributes for the current point\n    float2 f2UV = ProjToUV(In.m_f2PosPS);\n    float fHeight, fCosViewZenithAngle, fCosSunZenithAngle, fCosSunViewAngle;\n    InsctrLUTCoords2WorldParams(float4(f2UV, g_MiscParams.f2WQ), fHeight, fCosViewZenithAngle, fCosSunZenithAngle, fCosSunViewAngle );\n    float3 f3EarthCentre =  - float3(0,1,0) * EARTH_RADIUS;\n    float3 f3RayStart = float3(0, fHeight, 0);\n    float3 f3ViewDir = ComputeViewDir(fCosViewZenithAngle);\n    float3 f3DirOnLight = ComputeLightDir(f3ViewDir, fCosSunZenithAngle, fCosSunViewAngle);\n  \n    // Intersect view ray with the top of the atmosphere and the Earth\n    float4 f4Isecs;\n    GetRaySphereIntersection2( f3RayStart, f3ViewDir, f3EarthCentre, \n                               float2(EARTH_RADIUS, ATM_TOP_RADIUS), \n                               f4Isecs);\n    float2 f2RayEarthIsecs  = f4Isecs.xy;\n    float2 f2RayAtmTopIsecs = f4Isecs.zw;\n\n    if(f2RayAtmTopIsecs.y <= 0)\n        return 0; // This is just a sanity check and should never happen\n                  // as the start point is always under the top of the \n                  // atmosphere (look at InsctrLUTCoords2WorldParams())\n\n    // Set the ray length to the distance to the top of the atmosphere\n    float fRayLength = f2RayAtmTopIsecs.y;\n    // If ray hits Earth, limit the length by the distance to the surface\n    if(f2RayEarthIsecs.x > 0)\n        fRayLength = min(fRayLength, f2RayEarthIsecs.x);\n    \n    float3 f3RayEnd = f3RayStart + f3ViewDir * fRayLength;\n\n    // Integrate single-scattering\n    float3 f3Inscattering, f3Extinction;\n    IntegrateUnshadowedInscattering(f3RayStart, \n                                    f3RayEnd,\n                                    f3ViewDir,\n                                    f3EarthCentre,\n                                    f3DirOnLight.xyz,\n                                    100,\n                                    f3Inscattering,\n                                    f3Extinction);\n\n    return f3Inscattering;\n}\n\n// This shader pre-computes the radiance of light scattered at a given point in given\n// direction. It multiplies the previous order in-scattered light with the phase function \n// for each type of particles and integrates the result over the whole set of directions,\n// see eq. (7) in [Bruneton and Neyret 08].\nfloat3 ComputeSctrRadiancePS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    // Get attributes for the current point\n    float2 f2UV = ProjToUV(In.m_f2PosPS);\n    float fHeight, fCosViewZenithAngle, fCosSunZenithAngle, fCosSunViewAngle;\n    InsctrLUTCoords2WorldParams( float4(f2UV, g_MiscParams.f2WQ), fHeight, fCosViewZenithAngle, fCosSunZenithAngle, fCosSunViewAngle );\n    float3 f3EarthCentre =  - float3(0,1,0) * EARTH_RADIUS;\n    float3 f3RayStart = float3(0, fHeight, 0);\n    float3 f3ViewDir = ComputeViewDir(fCosViewZenithAngle);\n    float3 f3DirOnLight = ComputeLightDir(f3ViewDir, fCosSunZenithAngle, fCosSunViewAngle);\n    \n    // Compute particle density scale factor\n    float2 f2ParticleDensity = exp( -fHeight / PARTICLE_SCALE_HEIGHT );\n    \n    float3 f3SctrRadiance = 0;\n    // Go through a number of samples randomly distributed over the sphere\n    for(int iSample = 0; iSample < NUM_RANDOM_SPHERE_SAMPLES; ++iSample)\n    {\n        // Get random direction\n        float3 f3RandomDir = normalize( g_tex2DSphereRandomSampling.Load(int3(iSample,0,0)) );\n        // Get the previous order in-scattered light when looking in direction f3RandomDir (the light thus goes in direction -f3RandomDir)\n        float4 f4UVWQ = -1;\n        float3 f3PrevOrderSctr = LookUpPrecomputedScattering(f3RayStart, f3RandomDir, f3EarthCentre, f3DirOnLight.xyz, g_tex3DPreviousSctrOrder, f4UVWQ); \n        \n        // Apply phase functions for each type of particles\n        // Note that total scattering coefficients are baked into the angular scattering coeffs\n        float3 f3DRlghInsctr = f2ParticleDensity.x * f3PrevOrderSctr;\n        float3 f3DMieInsctr  = f2ParticleDensity.y * f3PrevOrderSctr;\n        float fCosTheta = dot(f3ViewDir, f3RandomDir);\n        ApplyPhaseFunctions(f3DRlghInsctr, f3DMieInsctr, fCosTheta);\n\n        f3SctrRadiance += f3DRlghInsctr + f3DMieInsctr;\n    }\n    // Since we tested N random samples, each sample covered 4*Pi / N solid angle\n    // Note that our phase function is normalized to 1 over the sphere. For instance,\n    // uniform phase function would be p(theta) = 1 / (4*Pi).\n    // Notice that for uniform intensity I if we get N samples, we must obtain exactly I after\n    // numeric integration\n    return f3SctrRadiance * 4*PI / NUM_RANDOM_SPHERE_SAMPLES;\n}\n\n// This shader computes in-scattering order for a given point and direction. It performs integration of the \n// light scattered at particular point along the ray, see eq. (11) in [Bruneton and Neyret 08].\nfloat3 ComputeScatteringOrderPS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    // Get attributes for the current point\n    float2 f2UV = ProjToUV(In.m_f2PosPS);\n    float fHeight, fCosViewZenithAngle, fCosSunZenithAngle, fCosSunViewAngle;\n    InsctrLUTCoords2WorldParams(float4(f2UV, g_MiscParams.f2WQ), fHeight, fCosViewZenithAngle, fCosSunZenithAngle, fCosSunViewAngle );\n    float3 f3EarthCentre =  - float3(0,1,0) * EARTH_RADIUS;\n    float3 f3RayStart = float3(0, fHeight, 0);\n    float3 f3ViewDir = ComputeViewDir(fCosViewZenithAngle);\n    float3 f3DirOnLight = ComputeLightDir(f3ViewDir, fCosSunZenithAngle, fCosSunViewAngle);\n    \n    // Intersect the ray with the atmosphere and Earth\n    float4 f4Isecs;\n    GetRaySphereIntersection2( f3RayStart, f3ViewDir, f3EarthCentre, \n                               float2(EARTH_RADIUS, ATM_TOP_RADIUS), \n                               f4Isecs);\n    float2 f2RayEarthIsecs  = f4Isecs.xy;\n    float2 f2RayAtmTopIsecs = f4Isecs.zw;\n\n    if(f2RayAtmTopIsecs.y <= 0)\n        return 0; // This is just a sanity check and should never happen\n                  // as the start point is always under the top of the \n                  // atmosphere (look at InsctrLUTCoords2WorldParams())\n\n    float fRayLength = f2RayAtmTopIsecs.y;\n    if(f2RayEarthIsecs.x > 0)\n        fRayLength = min(fRayLength, f2RayEarthIsecs.x);\n    \n    float3 f3RayEnd = f3RayStart + f3ViewDir * fRayLength;\n\n    const float fNumSamples = 64;\n    float fStepLen = fRayLength / fNumSamples;\n\n    float4 f4UVWQ = -1;\n    float3 f3PrevSctrRadiance = LookUpPrecomputedScattering(f3RayStart, f3ViewDir, f3EarthCentre, f3DirOnLight.xyz, g_tex3DPointwiseSctrRadiance, f4UVWQ); \n    float2 f2PrevParticleDensity = exp( -fHeight / PARTICLE_SCALE_HEIGHT );\n\n    float2 f2NetParticleDensityFromCam = 0;\n    float3 f3Inscattering = 0;\n\n    for(float fSample=1; fSample <= fNumSamples; ++fSample)\n    {\n        float3 f3Pos = lerp(f3RayStart, f3RayEnd, fSample/fNumSamples);\n\n        float fCurrHeight = length(f3Pos - f3EarthCentre) - EARTH_RADIUS;\n        float2 f2ParticleDensity = exp( -fCurrHeight / PARTICLE_SCALE_HEIGHT );\n\n        f2NetParticleDensityFromCam += (f2PrevParticleDensity + f2ParticleDensity) * (fStepLen / 2.f);\n        f2PrevParticleDensity = f2ParticleDensity;\n        \n        // Get optical depth\n        float3 f3RlghOpticalDepth = g_MediaParams.f4RayleighExtinctionCoeff.rgb * f2NetParticleDensityFromCam.x;\n        float3 f3MieOpticalDepth  = g_MediaParams.f4MieExtinctionCoeff.rgb      * f2NetParticleDensityFromCam.y;\n        \n        // Compute extinction from the camera for the current integration point:\n        float3 f3ExtinctionFromCam = exp( -(f3RlghOpticalDepth + f3MieOpticalDepth) );\n\n        // Get attenuated scattered light radiance in the current point\n        float4 f4UVWQ = -1;\n        float3 f3SctrRadiance = f3ExtinctionFromCam * LookUpPrecomputedScattering(f3Pos, f3ViewDir, f3EarthCentre, f3DirOnLight.xyz, g_tex3DPointwiseSctrRadiance, f4UVWQ); \n        // Update in-scattering integral\n        f3Inscattering += (f3SctrRadiance +  f3PrevSctrRadiance) * (fStepLen/2.f);\n        f3PrevSctrRadiance = f3SctrRadiance;\n    }\n\n    return f3Inscattering;\n}\n\nfloat3 AddScatteringOrderPS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    // Accumulate in-scattering using alpha-blending\n    return g_tex3DPreviousSctrOrder.Load( uint4(In.m_f4Pos.xy, g_MiscParams.uiDepthSlice, 0) );\n}\n\ntechnique11 PrecomputeScatteringTech\n{\n    pass P0\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, PrecomputeSingleScatteringPS() ) );\n    }\n\n    pass P1\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, ComputeSctrRadiancePS() ) );\n    }\n\n    pass P2\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetDepthStencilState( DSS_NoDepthTest, 0 );\n\n        SetVertexShader( CompileShader(vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, ComputeScatteringOrderPS() ) );\n    }\n}\n\nfloat3 PrecomputeAmbientSkyLightPS(SScreenSizeQuadVSOutput In) : SV_Target\n{\n    float fU = ProjToUV(In.m_f2PosPS).x;\n    float3 f3RayStart = float3(0,20,0);\n    float3 f3EarthCentre =  -float3(0,1,0) * EARTH_RADIUS;\n    float fCosZenithAngle = clamp(fU * 2 - 1, -1, +1);\n    float3 f3DirOnLight = float3(sqrt(saturate(1 - fCosZenithAngle*fCosZenithAngle)), fCosZenithAngle, 0);\n    float3 f3SkyLight = 0;\n    // Go through a number of random directions on the sphere\n    for(int iSample = 0; iSample < NUM_RANDOM_SPHERE_SAMPLES; ++iSample)\n    {\n        // Get random direction\n        float3 f3RandomDir = normalize( g_tex2DSphereRandomSampling.Load(int3(iSample,0,0)) );\n        // Reflect directions from the lower hemisphere\n        f3RandomDir.y = abs(f3RandomDir.y);\n        // Get multiple scattered light radiance when looking in direction f3RandomDir (the light thus goes in direction -f3RandomDir)\n        float4 f4UVWQ = -1;\n        float3 f3Sctr = LookUpPrecomputedScattering(f3RayStart, f3RandomDir, f3EarthCentre, f3DirOnLight.xyz, g_tex3DPreviousSctrOrder, f4UVWQ); \n        // Accumulate ambient irradiance through the horizontal plane\n        f3SkyLight += f3Sctr * dot(f3RandomDir, float3(0,1,0));\n    }\n    // Each sample covers 2 * PI / NUM_RANDOM_SPHERE_SAMPLES solid angle (integration is performed over\n    // upper hemisphere)\n    return f3SkyLight * 2 * PI / NUM_RANDOM_SPHERE_SAMPLES;\n}\n\nstruct SSunVSOutput\n{\n    float4 m_f4Pos : SV_Position;\n    float2 m_f2PosPS : PosPS; // Position in projection space [-1,1]x[-1,1]\n};\n\nstatic const float fSunAngularRadius =  32.f/2.f / 60.f * ((2.f * PI)/180); // Sun angular DIAMETER is 32 arc minutes\nstatic const float fTanSunAngularRadius = tan(fSunAngularRadius);\n\nSSunVSOutput SunVS(in uint VertexId : SV_VertexID)\n{\n    float2 fCotanHalfFOV = float2( g_CameraAttribs.mProj[0][0], g_CameraAttribs.mProj[1][1] );\n    float2 f2SunScreenPos = g_LightAttribs.f4LightScreenPos.xy;\n    float2 f2SunScreenSize = fTanSunAngularRadius * fCotanHalfFOV;\n    float4 MinMaxUV = f2SunScreenPos.xyxy + float4(-1,-1,1,1) * f2SunScreenSize.xyxy;\n \n    SSunVSOutput Verts[4] = \n    {\n        {float4(MinMaxUV.xy, 0.0, 1.0), MinMaxUV.xy}, \n        {float4(MinMaxUV.xw, 0.0, 1.0), MinMaxUV.xw},\n        {float4(MinMaxUV.zy, 0.0, 1.0), MinMaxUV.zy},\n        {float4(MinMaxUV.zw, 0.0, 1.0), MinMaxUV.zw}\n    };\n\n    return Verts[VertexId];\n}\n\nfloat3 SunPS(SSunVSOutput In) : SV_Target\n{\n    float2 fCotanHalfFOV = float2( g_CameraAttribs.mProj[0][0], g_CameraAttribs.mProj[1][1] );\n    float2 f2SunScreenSize = fTanSunAngularRadius * fCotanHalfFOV;\n    float2 f2dXY = (In.m_f2PosPS - g_LightAttribs.f4LightScreenPos.xy) / f2SunScreenSize;\n    return sqrt(saturate(1 - dot(f2dXY, f2dXY)));\n}\n\ntechnique11 RenderSunTech\n{\n    pass P0\n    {\n        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n        SetRasterizerState( RS_SolidFill_NoCull );\n\n        SetVertexShader( CompileShader(vs_5_0, SunVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader(ps_5_0, SunPS() ) );\n    }\n}\n"
  },
  {
    "path": "fx/RefineSampleLocations.fx",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"Common.fxh\"\n\nRWTexture2D<uint2> g_rwtex2DInterpolationSource : register( u0 );\n\n#ifndef INITIAL_SAMPLE_STEP\n#   define INITIAL_SAMPLE_STEP 128\n#endif\n\n#ifndef THREAD_GROUP_SIZE\n#   define THREAD_GROUP_SIZE max(INITIAL_SAMPLE_STEP, 32)\n#endif\n\n#ifndef REFINEMENT_CRITERION\n#   define REFINEMENT_CRITERION REFINEMENT_CRITERION_INSCTR_DIFF\n#endif\n\n// In my first implementation I used group shared memory to store camera space z\n// values. This was a very low-performing method\n// After that I tried using arrays of bool flags instead, but this did not help very much\n// since memory bandwidth was almost the same (on GPU each bool consumes 4 bytes)\n// Finally, I came up with packing 32 flags into single uint value.\n// This not only enables using 32x times less memory, but also enables very efficient\n// test if depth break is present in the section\nstatic const uint g_uiNumPackedFlags = THREAD_GROUP_SIZE/32;\ngroupshared uint g_uiPackedCamSpaceDiffFlags[ g_uiNumPackedFlags ];\n#if REFINEMENT_CRITERION == REFINEMENT_CRITERION_INSCTR_DIFF\ngroupshared float3 g_f3Inscattering[THREAD_GROUP_SIZE+1];\n#endif\n\n[numthreads(THREAD_GROUP_SIZE, 1, 1)]\nvoid RefineSampleLocationsCS(uint3 Gid  : SV_GroupID, \n                             uint3 GTid : SV_GroupThreadID)\n{\n    // Each thread group processes one slice\n    uint uiSliceInd = Gid.y;\n    // Compute global index of the first sample in the thread group\n    // Each group processes THREAD_GROUP_SIZE samples in the slice\n    uint uiGroupStartGlobalInd = Gid.x * THREAD_GROUP_SIZE;\n    uint uiSampleInd = GTid.x; // Sample index in the group\n    // Compute global index of this sample which is required to fetch the sample's coordinates\n    uint uiGlobalSampleInd = uiGroupStartGlobalInd + uiSampleInd;\n    // Load location of the current sample using global sample index\n    float2 f2SampleLocationPS = g_tex2DCoordinates.Load( uint3(uiGlobalSampleInd, uiSliceInd, 0) );\n    \n    bool bIsValidThread = all( abs(f2SampleLocationPS) < 1+1e-4 );\n\n    // Initialize flags with zeroes\n    if( GTid.x < g_uiNumPackedFlags )\n        g_uiPackedCamSpaceDiffFlags[GTid.x] = 0;\n    \n    GroupMemoryBarrierWithGroupSync();\n\n    // Let each thread in the group compute its own flag\n    // Note that if the sample is located behind the screen, its flag will be set to zero\n    // Besides, since g_tex2DEpipolarCamSpaceZ is cleared with invalid coordinates, the difference\n    // flag between valid and invalid locations will also be zero. Thus the sample next to invalid will always\n    // be marked as ray marching sample\n    [branch]\n    if( bIsValidThread )\n    {\n#if REFINEMENT_CRITERION == REFINEMENT_CRITERION_DEPTH_DIFF\n        // Load camera space Z for this sample and for its right neighbour (remeber to use global sample index)\n        float fCamSpaceZ =            g_tex2DEpipolarCamSpaceZ.Load( uint3(uiGlobalSampleInd,   uiSliceInd, 0) );\n        float fRightNeighbCamSpaceZ = g_tex2DEpipolarCamSpaceZ.Load( uint3(uiGlobalSampleInd+1, uiSliceInd, 0) );\n        float fMaxZ = max(fCamSpaceZ, fRightNeighbCamSpaceZ);\n        fMaxZ = max(fMaxZ, 1);\n        // Compare the difference with the threshold\n        bool bFlag = abs(fCamSpaceZ - fRightNeighbCamSpaceZ)/fMaxZ < 0.2*g_PPAttribs.m_fRefinementThreshold;\n#elif REFINEMENT_CRITERION == REFINEMENT_CRITERION_INSCTR_DIFF\n        // Load inscattering for this sample and for its right neighbour\n        float3 f3Insctr0 = g_tex2DScatteredColor.Load( uint3(uiGlobalSampleInd,   uiSliceInd, 0) );\n        float3 f3Insctr1 = g_tex2DScatteredColor.Load( uint3(uiGlobalSampleInd+1, uiSliceInd, 0) );\n        float3 f3MaxInsctr = max(f3Insctr0, f3Insctr1);\n        \n        // Compute minimum inscattering threshold based on the average scene luminance\n        float fAverageLum = GetAverageSceneLuminance();\n        // Inscattering threshold should be proportional to the average scene luminance and\n        // inversely proportional to the middle gray level (the higher middle gray, the briter the scene,\n        // thus the less the theshold)\n        // It should also account for the fact that rgb channels contribute differently\n        // to the percieved brightness. For r channel the threshold should be smallest, \n        // for b channel - the largest\n        float3 f3MinInsctrThreshold = (0.02f * fAverageLum.xxx / RGB_TO_LUMINANCE.xyz) / g_PPAttribs.m_fMiddleGray;\n\n        f3MaxInsctr = max(f3MaxInsctr, f3MinInsctrThreshold);\n        // Compare the difference with the threshold. If the neighbour sample is invalid, its inscattering\n        // is large negative value and the difference is guaranteed to be larger than the threshold\n        bool bFlag = all( (abs(f3Insctr0 - f3Insctr1)/f3MaxInsctr) < g_PPAttribs.m_fRefinementThreshold );\n#endif\n        // Set appropriate flag using INTERLOCKED Or:\n        InterlockedOr( g_uiPackedCamSpaceDiffFlags[uiSampleInd/32], bFlag << (uiSampleInd%32) );\n    }\n\n    // Synchronize threads in the group\n    GroupMemoryBarrierWithGroupSync();\n    \n    // Skip invalid threads. This can be done only after the synchronization\n    if( !bIsValidThread )\n        return;\n\n    //                                 uiInitialSampleStep\n    //       uiSampleInd             |<--------->|\n    //          |                    |           |\n    //       X  *  *  *  X  *  *  *  X  *  *  *  X           X - locations of initial samples\n    //       |           |\n    //       |           uiInitialSample1Ind\n    //      uiInitialSample0Ind\n    //\n    // Find two closest initial ray marching samples\n    uint uiInitialSampleStep = INITIAL_SAMPLE_STEP;\n    uint uiInitialSample0Ind = (uiSampleInd / uiInitialSampleStep) * uiInitialSampleStep;\n    // Use denser sampling near the epipole to account for high variation\n    // Note that sampling near the epipole is very cheap since only a few steps\n    // are required to perform ray marching\n    uint uiInitialSample0GlobalInd = uiInitialSample0Ind + uiGroupStartGlobalInd;\n    float2 f2InitialSample0Coords = g_tex2DCoordinates.Load( uint3(uiInitialSample0GlobalInd, uiSliceInd, 0) );\n    if( uiInitialSample0GlobalInd/(float)MAX_SAMPLES_IN_SLICE < 0.05 && \n        length(f2InitialSample0Coords - g_LightAttribs.f4LightScreenPos.xy) < 0.1 )\n    {\n        uiInitialSampleStep = max( INITIAL_SAMPLE_STEP / g_PPAttribs.m_uiEpipoleSamplingDensityFactor, 1 );\n        uiInitialSample0Ind = (uiSampleInd / uiInitialSampleStep) * uiInitialSampleStep;\n    }\n    uint uiInitialSample1Ind = uiInitialSample0Ind + uiInitialSampleStep;\n\n    // Remeber that the last sample in each epipolar slice must be ray marching one\n    uint uiInterpolationTexWidth, uiInterpolationTexHeight;\n    g_rwtex2DInterpolationSource.GetDimensions(uiInterpolationTexWidth, uiInterpolationTexHeight);\n    if( Gid.x == uiInterpolationTexWidth/THREAD_GROUP_SIZE - 1 )\n        uiInitialSample1Ind = min(uiInitialSample1Ind, THREAD_GROUP_SIZE-1);\n\n    uint uiLeftSrcSampleInd  = uiSampleInd;\n    uint uiRightSrcSampleInd = uiSampleInd;\n\n    // Do nothing if sample is one of initial samples. In this case the sample will be \n    // interpolated from itself\n    if( uiSampleInd > uiInitialSample0Ind && uiSampleInd < uiInitialSample1Ind )\n    {\n        // Load group shared memory to the thread local memory\n        uint uiPackedCamSpaceDiffFlags[ g_uiNumPackedFlags ];\n        for(uint i=0; i < g_uiNumPackedFlags; ++i)\n            uiPackedCamSpaceDiffFlags[i] = g_uiPackedCamSpaceDiffFlags[i];\n    \n        // Check if there are no depth breaks in the whole section\n        // In such case all the flags are set\n        bool bNoDepthBreaks = true;\n#if INITIAL_SAMPLE_STEP < 32\n        {\n            // Check if all uiInitialSampleStep flags starting from\n            // position uiInitialSample0Ind are set:\n            int iFlagPackOrder = uiInitialSample0Ind / 32;\n            int iFlagOrderInPack = uiInitialSample0Ind % 32;\n            uint uiFlagPack = uiPackedCamSpaceDiffFlags[iFlagPackOrder];\n            uint uiAllFlagsMask = ((1<<uiInitialSampleStep) - 1);\n            if( ((uiFlagPack >> iFlagOrderInPack) & uiAllFlagsMask) != uiAllFlagsMask )\n                bNoDepthBreaks = false;\n        }\n#else\n        {\n            for(uint i=0; i < g_uiNumPackedFlags; ++i)\n                if( uiPackedCamSpaceDiffFlags[i] != 0xFFFFFFFFU )\n                    // If at least one flag is not set, there is a depth break on this section\n                    bNoDepthBreaks = false;\n        }\n#endif\n\n        if( bNoDepthBreaks )\n        {\n            // If there are no depth breaks, we can skip all calculations\n            // and use initial sample locations as interpolation sources:\n            uiLeftSrcSampleInd = uiInitialSample0Ind;\n            uiRightSrcSampleInd = uiInitialSample1Ind;\n        }\n        else\n        {\n            // Find left interpolation source\n            {\n                // Note that i-th flag reflects the difference between i-th and (i+1)-th samples:\n                // Flag[i] = abs(fCamSpaceZ[i] - fCamSpaceZ[i+1]) < g_PPAttribs.m_fRefinementThreshold;\n                // We need to find first depth break starting from iFirstDepthBreakToTheLeftInd sample\n                // and going to the left up to uiInitialSample0Ind\n                int iFirstDepthBreakToTheLeftInd = uiSampleInd-1;\n                //                                                              iFirstDepthBreakToTheLeftInd\n                //                                                                     |\n                //                                                                     V\n                //      0  1  2  3                       30 31   32 33     ....   i-1  i  i+1 ....  63   64\n                //   |                                         |                           1  1  1  1  |\n                //          uiPackedCamSpaceDiffFlags[0]             uiPackedCamSpaceDiffFlags[1]\n                //\n                //   iFlagOrderInPack == i % 32\n\n                int iFlagPackOrder = uint(iFirstDepthBreakToTheLeftInd) / 32;\n                int iFlagOrderInPack = uint(iFirstDepthBreakToTheLeftInd) % 32;\n                uint uiFlagPack = uiPackedCamSpaceDiffFlags[iFlagPackOrder];\n                // To test if there is a depth break in the current flag pack,\n                // we must check all flags starting from the iFlagOrderInPack\n                // downward to 0 position. We must skip all flags from iFlagOrderInPack+1 to 31\n                if( iFlagOrderInPack < 31 )\n                {\n                    // Set all higher flags to 1, so that they will be skipped\n                    // Note that if iFlagOrderInPack == 31, there are no flags to skip\n                    // Note also that (U << 32) != 0 as it can be expected. (U << 32) == U instead\n                    uiFlagPack |= ( uint(0x0FFFFFFFFU) << uint(iFlagOrderInPack+1) );\n                }\n                // Find first zero flag starting from iFlagOrderInPack position. Since all\n                // higher bits are set, they will be effectivelly skipped\n                int iFirstUnsetFlagPos = firstbithigh( uint(~uiFlagPack) );\n                // firstbithigh(0) == +INT_MAX\n                if( !(0 <= iFirstUnsetFlagPos && iFirstUnsetFlagPos < 32) )\n                    // There are no set flags => proceed to the next uint flag pack\n                    iFirstUnsetFlagPos = -1;\n                iFirstDepthBreakToTheLeftInd -= iFlagOrderInPack - iFirstUnsetFlagPos;\n\n#if INITIAL_SAMPLE_STEP > 32\n                // Check the remaining full flag packs\n                iFlagPackOrder--;\n                while( iFlagPackOrder >= 0 && iFirstUnsetFlagPos == -1 )\n                {\n                    uiFlagPack = uiPackedCamSpaceDiffFlags[iFlagPackOrder];\n                    iFirstUnsetFlagPos = firstbithigh( uint(~uiFlagPack) );\n                    if( !(0 <= iFirstUnsetFlagPos && iFirstUnsetFlagPos < 32) )\n                        iFirstUnsetFlagPos = -1;\n                    iFirstDepthBreakToTheLeftInd -= 31 - iFirstUnsetFlagPos;\n                    iFlagPackOrder--;\n                }\n#endif\n                // Ray marching sample is located next to the identified depth break:\n                uiLeftSrcSampleInd = max( uint(iFirstDepthBreakToTheLeftInd + 1), uiInitialSample0Ind );\n            }\n\n            // Find right interpolation source using symmetric method\n            {\n                // We need to find first depth break starting from iRightSrcSampleInd and\n                // going to the right up to the uiInitialSample1Ind\n                uiRightSrcSampleInd = uiSampleInd;\n                int iFlagPackOrder = uiRightSrcSampleInd / 32;\n                uint iFlagOrderInPack = uiRightSrcSampleInd % 32;\n                uint uiFlagPack = uiPackedCamSpaceDiffFlags[iFlagPackOrder];\n                // We need to find first unset flag in the current flag pack\n                // starting from iFlagOrderInPack position and up to the 31st bit\n                // Set all lower order bits to 1 so that they are skipped during\n                // the test:\n                if( iFlagOrderInPack > 0 )\n                    uiFlagPack |= ( (1 << uint(iFlagOrderInPack))-1 );\n                // Find first zero flag:\n                int iFirstUnsetFlagPos = firstbitlow( uint(~uiFlagPack) );\n                if( !(0 <= iFirstUnsetFlagPos && iFirstUnsetFlagPos < 32) )\n                    iFirstUnsetFlagPos = 32;\n                uiRightSrcSampleInd += iFirstUnsetFlagPos - iFlagOrderInPack;\n\n#if INITIAL_SAMPLE_STEP > 32\n                // Check the remaining full flag packs\n                iFlagPackOrder++;\n                while( iFlagPackOrder < int(g_uiNumPackedFlags) && iFirstUnsetFlagPos == 32 )\n                {\n                    uiFlagPack = uiPackedCamSpaceDiffFlags[iFlagPackOrder];\n                    iFirstUnsetFlagPos = firstbitlow( uint(~uiFlagPack) );\n                    if( !(0 <= iFirstUnsetFlagPos && iFirstUnsetFlagPos < 32) )\n                        iFirstUnsetFlagPos = 32;\n                    uiRightSrcSampleInd += iFirstUnsetFlagPos;\n                    iFlagPackOrder++;\n                }\n#endif\n                uiRightSrcSampleInd = min(uiRightSrcSampleInd, uiInitialSample1Ind);\n            }\n        }\n\n        // If at least one interpolation source is the same as the sample itself, the\n        // sample is ray marching sample and is interpolated from itself:\n        if(uiLeftSrcSampleInd == uiSampleInd || uiRightSrcSampleInd == uiSampleInd )\n            uiLeftSrcSampleInd = uiRightSrcSampleInd = uiSampleInd;\n    }\n\n    g_rwtex2DInterpolationSource[ uint2(uiGlobalSampleInd, uiSliceInd) ] = uint2(uiGroupStartGlobalInd + uiLeftSrcSampleInd, uiGroupStartGlobalInd + uiRightSrcSampleInd);\n}\n\ntechnique11 RefineSampleLocations\n{\n    pass\n    {\n        SetVertexShader( NULL );\n        SetGeometryShader( NULL );\n        SetPixelShader( NULL );\n        SetComputeShader( CompileShader(cs_5_0, RefineSampleLocationsCS() ) );\n    }\n}\n"
  },
  {
    "path": "fx/Structures.fxh",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#ifndef _STRCUTURES_FXH_\n#define _STRCUTURES_FXH_\n\n#define PI 3.1415928f\n\n#ifdef __cplusplus\n\n#   define float2 D3DXVECTOR2\n#   define float3 D3DXVECTOR3\n#   define float4 D3DXVECTOR4\n#   define uint UINT\n\n#else\n\n#   define BOOL bool // Do not use bool, because sizeof(bool)==1 !\n\n#endif\n\n#ifdef __cplusplus\n#   define CHECK_STRUCT_ALIGNMENT(s) static_assert( sizeof(s) % 16 == 0, \"sizeof(\"#s\") is not multiple of 16\" );\n#else\n#   define CHECK_STRUCT_ALIGNMENT(s)\n#endif\n\n\n\n#define MAX_CASCADES 8\nstruct SCascadeAttribs\n{\n\tfloat4 f4LightSpaceScale;\n\tfloat4 f4LightSpaceScaledBias;\n    float4 f4StartEndZ;\n};\n#ifdef __cplusplus\nstatic_assert( (sizeof(SCascadeAttribs) % 16) == 0, \"sizeof(SCascadeAttribs) is not multiple of 16\" );\n#endif\n\nstruct SShadowMapAttribs\n{\n    // 0\n#ifdef __cplusplus\n    D3DXMATRIX mWorldToLightViewT; // Matrices in HLSL are COLUMN-major while D3DXMATRIX is ROW major\n#else\n    matrix mWorldToLightView;  // Transform from view space to light projection space\n#endif\n    // 16\n    SCascadeAttribs Cascades[MAX_CASCADES];\n\n#ifdef __cplusplus\n    float fCascadeCamSpaceZEnd[MAX_CASCADES];\n    D3DXMATRIX mWorldToShadowMapUVDepthT[MAX_CASCADES];\n#else\n\tfloat4 f4CascadeCamSpaceZEnd[MAX_CASCADES/4];\n    matrix mWorldToShadowMapUVDepth[MAX_CASCADES];\n#endif\n\n    // Do not use bool, because sizeof(bool)==1 !\n\tBOOL bVisualizeCascades;\n\n    float3 f3Padding;\n};\n#ifdef __cplusplus\nstatic_assert( (sizeof(SShadowMapAttribs) % 16) == 0, \"sizeof(SShadowMapAttribs) is not multiple of 16\" );\n#endif\n\n\nstruct SLightAttribs\n{\n    float4 f4DirOnLight;\n    float4 f4AmbientLight;\n    float4 f4LightScreenPos;\n    float4 f4ExtraterrestrialSunColor;\n\n    BOOL bIsLightOnScreen;\n    float3 f3Dummy;\n\n    SShadowMapAttribs ShadowAttribs;\n};\nCHECK_STRUCT_ALIGNMENT(SLightAttribs);\n\nstruct SCameraAttribs\n{\n    float4 f4CameraPos;            ///< Camera world position\n    float fNearPlaneZ; \n    float fFarPlaneZ; // fNearPlaneZ < fFarPlaneZ\n    float2 f2Dummy;\n\n#ifdef __cplusplus\n    D3DXMATRIX WorldViewProjT;\n    D3DXMATRIX mViewT;\n    D3DXMATRIX mProjT;\n    D3DXMATRIX mViewProjInvT;\n#else\n    matrix WorldViewProj;\n    matrix mView;\n    matrix mProj;\n    matrix mViewProjInv;\n#endif\n};\nCHECK_STRUCT_ALIGNMENT(SCameraAttribs);\n\n#define LIGHT_SCTR_TECHNIQUE_EPIPOLAR_SAMPLING 0\n#define LIGHT_SCTR_TECHNIQUE_BRUTE_FORCE 1\n\n#define CASCADE_PROCESSING_MODE_SINGLE_PASS 0\n#define CASCADE_PROCESSING_MODE_MULTI_PASS 1\n#define CASCADE_PROCESSING_MODE_MULTI_PASS_INST 2\n\n#define REFINEMENT_CRITERION_DEPTH_DIFF 0\n#define REFINEMENT_CRITERION_INSCTR_DIFF 1\n\n// Extinction evaluation mode used when attenuating background\n#define EXTINCTION_EVAL_MODE_PER_PIXEL 0// Evaluate extinction for each pixel using analytic formula \n                                        // by Eric Bruneton\n#define EXTINCTION_EVAL_MODE_EPIPOLAR 1 // Render extinction in epipolar space and perform\n                                        // bilateral filtering in the same manner as for\n                                        // inscattering\n\n#define SINGLE_SCTR_MODE_NONE 0\n#define SINGLE_SCTR_MODE_INTEGRATION 1\n#define SINGLE_SCTR_MODE_LUT 2\n\n#define MULTIPLE_SCTR_MODE_NONE 0\n#define MULTIPLE_SCTR_MODE_UNOCCLUDED 1\n#define MULTIPLE_SCTR_MODE_OCCLUDED 2\n\n#define TONE_MAPPING_MODE_EXP 0\n#define TONE_MAPPING_MODE_REINHARD 1\n#define TONE_MAPPING_MODE_REINHARD_MOD 2\n#define TONE_MAPPING_MODE_UNCHARTED2 3\n#define TONE_MAPPING_FILMIC_ALU 4\n#define TONE_MAPPING_LOGARITHMIC 5\n#define TONE_MAPPING_ADAPTIVE_LOG 6\n\n\nstruct SPostProcessingAttribs\n{\n    uint m_uiNumEpipolarSlices;\n    uint m_uiMaxSamplesInSlice;\n    uint m_uiInitialSampleStepInSlice;\n    uint m_uiEpipoleSamplingDensityFactor;\n\n    float m_fRefinementThreshold;\n    // do not use bool, because sizeof(bool)==1 and as a result bool variables\n    // will be incorrectly mapped on GPU constant buffer\n    BOOL m_bShowSampling; \n    BOOL m_bCorrectScatteringAtDepthBreaks; \n    BOOL m_bShowDepthBreaks; \n\n    BOOL m_bShowLightingOnly;\n    BOOL m_bOptimizeSampleLocations;\n    BOOL m_bEnableLightShafts;\n    uint m_uiInstrIntegralSteps;\n    \n    float2 m_f2ShadowMapTexelSize;\n    uint m_uiShadowMapResolution;\n    uint m_uiMinMaxShadowMapResolution;\n\n    BOOL m_bUse1DMinMaxTree;\n    float m_fMaxShadowMapStep;\n    float m_fMiddleGray;\n    uint m_uiLightSctrTechnique;\n\n    int m_iNumCascades;\n    int m_iFirstCascade;\n    float m_fNumCascades;\n    float m_fFirstCascade;\n\n    uint m_uiCascadeProcessingMode;\n    uint m_uiRefinementCriterion;\n    BOOL m_bIs32BitMinMaxMipMap;\n    uint m_uiMultipleScatteringMode;\n\n    uint m_uiSingleScatteringMode;\n    BOOL m_bAutoExposure;\n    uint m_uiToneMappingMode;\n    BOOL m_bLightAdaptation;\n    \n    float m_fWhitePoint;\n    float m_fLuminanceSaturation;\n    float2 f2Dummy;\n    \n    uint m_uiExtinctionEvalMode;\n    BOOL m_bUseCustomSctrCoeffs;\n    float m_fAerosolDensityScale;\n    float m_fAerosolAbsorbtionScale;\n\n    float4 m_f4CustomRlghBeta;\n    float4 m_f4CustomMieBeta;\n\n#ifdef __cplusplus\n    SPostProcessingAttribs() : \n        m_uiNumEpipolarSlices(512),\n        m_uiMaxSamplesInSlice(256),\n        m_uiInitialSampleStepInSlice(16),\n        // Note that sampling near the epipole is very cheap since only a few steps\n        // required to perform ray marching\n        m_uiEpipoleSamplingDensityFactor(2),\n        m_fRefinementThreshold(0.03f),\n        m_bShowSampling(FALSE),\n        m_bCorrectScatteringAtDepthBreaks(FALSE),\n        m_bShowDepthBreaks(FALSE),\n        m_bShowLightingOnly(FALSE),\n        m_bOptimizeSampleLocations(TRUE),\n        m_bEnableLightShafts(TRUE),\n        m_uiInstrIntegralSteps(30),\n        m_bUse1DMinMaxTree(TRUE),\n        m_fMaxShadowMapStep(16.f),\n        m_f2ShadowMapTexelSize(0,0),\n        m_uiMinMaxShadowMapResolution(0),\n        m_fMiddleGray(0.18f),\n        m_uiLightSctrTechnique(LIGHT_SCTR_TECHNIQUE_EPIPOLAR_SAMPLING),\n        m_iNumCascades(0),\n        m_iFirstCascade(1),\n        m_fNumCascades(0),\n        m_fFirstCascade(1),\n        m_uiCascadeProcessingMode(CASCADE_PROCESSING_MODE_SINGLE_PASS),\n        m_uiRefinementCriterion(REFINEMENT_CRITERION_INSCTR_DIFF),\n        m_bIs32BitMinMaxMipMap(FALSE),\n        m_uiMultipleScatteringMode(MULTIPLE_SCTR_MODE_UNOCCLUDED),\n        m_uiSingleScatteringMode(SINGLE_SCTR_MODE_LUT),\n        m_bAutoExposure(TRUE),\n        m_uiToneMappingMode(TONE_MAPPING_MODE_UNCHARTED2),\n        m_bLightAdaptation(TRUE),\n        m_fWhitePoint(3.f),\n        m_fLuminanceSaturation(1.f),\n        m_uiExtinctionEvalMode(EXTINCTION_EVAL_MODE_EPIPOLAR),\n        m_bUseCustomSctrCoeffs(FALSE),\n        m_fAerosolDensityScale(1.f),\n        m_fAerosolAbsorbtionScale(0.1f),\n        m_f4CustomRlghBeta( 5.8e-6f, 13.5e-6f, 33.1e-6f, 0.f ),\n        m_f4CustomMieBeta(2.0e-5f, 2.0e-5f, 2.0e-5f, 0.f)\n        {}\n#endif\n};\nCHECK_STRUCT_ALIGNMENT(SPostProcessingAttribs);\n\nstruct SAirScatteringAttribs\n{\n    // Angular Rayleigh scattering coefficient contains all the terms exepting 1 + cos^2(Theta):\n    // Pi^2 * (n^2-1)^2 / (2*N) * (6+3*Pn)/(6-7*Pn)\n    float4 f4AngularRayleighSctrCoeff;\n    // Total Rayleigh scattering coefficient is the integral of angular scattering coefficient in all directions\n    // and is the following:\n    // 8 * Pi^3 * (n^2-1)^2 / (3*N) * (6+3*Pn)/(6-7*Pn)\n    float4 f4TotalRayleighSctrCoeff;\n    float4 f4RayleighExtinctionCoeff;\n\n    // Note that angular scattering coefficient is essentially a phase function multiplied by the\n    // total scattering coefficient\n    float4 f4AngularMieSctrCoeff;\n    float4 f4TotalMieSctrCoeff;\n    float4 f4MieExtinctionCoeff;\n\n    float4 f4TotalExtinctionCoeff;\n    // Cornette-Shanks phase function (see Nishita et al. 93) normalized to unity has the following form:\n    // F(theta) = 1/(4*PI) * 3*(1-g^2) / (2*(2+g^2)) * (1+cos^2(theta)) / (1 + g^2 - 2g*cos(theta))^(3/2)\n    float4 f4CS_g; // x == 3*(1-g^2) / (2*(2+g^2))\n                   // y == 1 + g^2\n                   // z == -2*g\n\n    float fEarthRadius;\n    float fAtmTopHeight;\n    float2 f2ParticleScaleHeight;\n    \n    float fTurbidity;\n    float fAtmTopRadius;\n    float m_fAerosolPhaseFuncG;\n    float m_fDummy;\n\n\n#ifdef __cplusplus\n    SAirScatteringAttribs():        \n        f2ParticleScaleHeight(7994.f, 1200.f),\n        // Air molecules and aerosols are assumed to be distributed\n        // between 6360 km and 6420 km\n        fEarthRadius(6360000.f),\n        fAtmTopHeight(80000.f),\n        fTurbidity(1.02f),\n        m_fAerosolPhaseFuncG(0.76f)\n    {\n        fAtmTopRadius = fEarthRadius + fAtmTopHeight;\n    }\n#endif\n};\n\nCHECK_STRUCT_ALIGNMENT(SAirScatteringAttribs);\n\nstruct SMiscDynamicParams\n{\n    float fMaxStepsAlongRay;   // Maximum number of steps during ray tracing\n    float fCascadeInd;\n    float2 f2WQ; // Used when pre-computing inscattering look-up table\n\n    uint uiDepthSlice;\n    float fElapsedTime;\n    float2 f2Dummy;\n\n#ifdef __cplusplus\n    uint ui4SrcMinMaxLevelXOffset;\n    uint ui4SrcMinMaxLevelYOffset;\n    uint ui4DstMinMaxLevelXOffset;\n    uint ui4DstMinMaxLevelYOffset;\n#else\n    uint4 ui4SrcDstMinMaxLevelOffset;\n#endif\n};\nCHECK_STRUCT_ALIGNMENT(SMiscDynamicParams);\n\n#endif //_STRCUTURES_FXH_"
  },
  {
    "path": "fx/Terrain.fx",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#include \"TerrainStructs.fxh\"\n#include \"..\\fx\\Structures.fxh\"\n\n// Texturing modes\n#define TM_HEIGHT_BASED 0             // Simple height-based texturing mode using 1D look-up table\n#define TM_MATERIAL_MASK 1\n#define TM_MATERIAL_MASK_NM 2\n\n#ifndef TEXTURING_MODE\n#   define TEXTURING_MODE TM_MATERIAL_MASK_NM\n#endif\n\n#ifndef NUM_TILE_TEXTURES\n#\tdefine NUM_TILE_TEXTURES 5\n#endif\n\n#ifndef NUM_SHADOW_CASCADES\n#   define NUM_SHADOW_CASCADES 4\n#endif\n\nstatic const float g_fEarthReflectance = 0.4f;\n\ncbuffer cbTerrainAttribs : register( b0 )\n{\n    STerrainAttribs g_TerrainAttribs;\n}\n\ncbuffer cbCameraAttribs : register( b1 )\n{\n    SCameraAttribs g_CameraAttribs;\n};\n\ncbuffer cbLightAttribs : register( b2 )\n{\n    SLightAttribs g_LightAttribs;\n}\n\ncbuffer cbParticipatingMediaScatteringParams : register( b3 )\n{\n    SAirScatteringAttribs g_MediaParams;\n}\n\n\ncbuffer cbNMGenerationAttribs : register( b0 )\n{\n    SNMGenerationAttribs g_NMGenerationAttribs;\n}\n\nSamplerState samPointClamp : register( s0 )\n{\n    Filter = MIN_MAG_MIP_LINEAR;\n    AddressU = Clamp;\n    AddressV = Clamp;\n};\n\nSamplerState samLinearMirror : register( s0 )\n{\n    Filter = MIN_MAG_MIP_LINEAR;\n    AddressU = Mirror;\n    AddressV = Mirror;\n};\n\nSamplerState samLinearWrap : register( s1 )\n{\n    Filter = MIN_MAG_MIP_LINEAR;\n    AddressU = Wrap;\n    AddressV = Wrap;\n};\n\nSamplerComparisonState samComparison : register (s2)\n{\n    Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;\n    AddressU = Clamp;\n    AddressV = Clamp;\n};\n\nSamplerState samLinearClamp : register( s3 )\n{\n    Filter = MIN_MAG_MIP_LINEAR;\n    AddressU = Clamp;\n    AddressV = Clamp;\n};\n\n\nTexture2D<float> g_tex2DElevationMap  : register( t0 );\n// Normal map stores only x,y components. z component is calculated as sqrt(1 - x^2 - y^2)\nTexture2D g_tex2DNormalMap            : register( t1 );\nTexture2D<float4> g_tex2DMtrlMap      : register( t2 );\nTexture2DArray<float>  g_tex2DShadowMap : register (t3);\nTexture2D<float4> g_tex2DTileTextures[NUM_TILE_TEXTURES]   : register( t4 );   // Material texture\nTexture2D<float3> g_tex2DTileNormalMaps[NUM_TILE_TEXTURES] : register( t9 );   // Material texture\n//Texture2D<float3> g_tex2DElevationColor: register( t4 );\nTexture2D<float2> g_tex2DOccludedNetDensityToAtmTop : register( t0 ); // Used in VS\nTexture2D<float3> g_tex2DAmbientSkylight            : register( t1 ); // Used in VS\n\n#ifndef BEST_CASCADE_SEARCH\n#   define BEST_CASCADE_SEARCH 1\n#endif\n\n#ifndef SMOOTH_SHADOWS\n#   define SMOOTH_SHADOWS 1\n#endif\n\nvoid FindCascade(float3 f3PosInLightViewSpace,\n                 float fCameraViewSpaceZ,\n                 out float3 f3PosInCascadeProjSpace,\n                 out float3 f3CascadeLightSpaceScale,\n                 out float Cascade)\n{\n    Cascade = 0;\n#if BEST_CASCADE_SEARCH\n    while(Cascade < NUM_SHADOW_CASCADES)\n    {\n        // Find the smallest cascade which covers current point\n        SCascadeAttribs CascadeAttribs = g_LightAttribs.ShadowAttribs.Cascades[Cascade];\n        f3CascadeLightSpaceScale = CascadeAttribs.f4LightSpaceScale.xyz;\n        f3PosInCascadeProjSpace = f3PosInLightViewSpace * f3CascadeLightSpaceScale + g_LightAttribs.ShadowAttribs.Cascades[Cascade].f4LightSpaceScaledBias.xyz;\n        \n        // In order to perform PCF filtering without getting out of the cascade shadow map,\n        // we need to be far enough from its boundaries.\n        if( //Cascade == (NUM_SHADOW_CASCADES - 1) || \n            all( abs(f3PosInCascadeProjSpace.xy) < 1/*- CascadeAttribs.f4LightProjSpaceFilterRadius.xy*/ ) &&\n            // It is necessary to check f3PosInCascadeProjSpace.z as well since it could be behind\n            // the far clipping plane of the current cascade\n            // Besides, if VSM or EVSM filtering is performed, there is also z boundary\n            0 /*+ CascadeAttribs.f4LightProjSpaceFilterRadius.z*/ < f3PosInCascadeProjSpace.z && f3PosInCascadeProjSpace.z < 1  /*- CascadeAttribs.f4LightProjSpaceFilterRadius.w*/ )\n            break;\n        else\n            Cascade++;\n    }\n#else\n    [unroll]for(int i=0; i<(NUM_SHADOW_CASCADES+3)/4; ++i)\n    {\n\t    float4 v = float4(g_LightAttribs.ShadowAttribs.f4CascadeCamSpaceZEnd[i] < fCameraViewSpaceZ);\n\t    Cascade += dot(float4(1,1,1,1), v);\n    }\n    if( Cascade < NUM_SHADOW_CASCADES )\n    {\n    //Cascade = min(Cascade, NUM_SHADOW_CASCADES - 1);\n        f3CascadeLightSpaceScale = g_LightAttribs.ShadowAttribs.Cascades[Cascade].f4LightSpaceScale.xyz;\n        f3PosInCascadeProjSpace = f3PosInLightViewSpace * f3CascadeLightSpaceScale + g_LightAttribs.ShadowAttribs.Cascades[Cascade].f4LightSpaceScaledBias.xyz;\n    }\n#endif\n}\n\nfloat2 ComputeReceiverPlaneDepthBias(float3 ShadowUVDepthDX, float3 ShadowUVDepthDY)\n{    \n    // Compute (dDepth/dU, dDepth/dV):\n    //  \n    //  | dDepth/dU |    | dX/dU    dX/dV |T  | dDepth/dX |     | dU/dX    dU/dY |-1T | dDepth/dX |\n    //                 =                                     =                                      =\n    //  | dDepth/dV |    | dY/dU    dY/dV |   | dDepth/dY |     | dV/dX    dV/dY |    | dDepth/dY |\n    //\n    //  | A B |-1   | D  -B |                      | A B |-1T   | D  -C |                                   \n    //            =           / det                           =           / det                    \n    //  | C D |     |-C   A |                      | C D |      |-B   A |\n    //\n    //  | dDepth/dU |           | dV/dY   -dV/dX |  | dDepth/dX |\n    //                 = 1/det                                       \n    //  | dDepth/dV |           |-dU/dY    dU/dX |  | dDepth/dY |\n\n    float2 biasUV;\n    //               dV/dY       V      dDepth/dX    D       dV/dX       V     dDepth/dY     D\n    biasUV.x =   ShadowUVDepthDY.y * ShadowUVDepthDX.z - ShadowUVDepthDX.y * ShadowUVDepthDY.z;\n    //               dU/dY       U      dDepth/dX    D       dU/dX       U     dDepth/dY     D\n    biasUV.y = - ShadowUVDepthDY.x * ShadowUVDepthDX.z + ShadowUVDepthDX.x * ShadowUVDepthDY.z;\n\n    float Det = (ShadowUVDepthDX.x * ShadowUVDepthDY.y) - (ShadowUVDepthDX.y * ShadowUVDepthDY.x);\n\tbiasUV /= sign(Det) * max( abs(Det), 1e-20 );\n    //biasUV = abs(Det) > 1e-7 ? biasUV / abs(Det) : 0;// sign(Det) * max( abs(Det), 1e-10 );\n    return biasUV;\n}\n\nfloat ComputeShadowAmount(in float3 f3PosInLightViewSpace, in float fCameraSpaceZ, out float Cascade)\n{\n    float3 f3PosInCascadeProjSpace = 0, f3CascadeLightSpaceScale = 0;\n    FindCascade( f3PosInLightViewSpace.xyz, fCameraSpaceZ, f3PosInCascadeProjSpace, f3CascadeLightSpaceScale, Cascade);\n    if( Cascade == NUM_SHADOW_CASCADES )\n        return 1;\n\n    float3 f3ShadowMapUVDepth;\n    f3ShadowMapUVDepth.xy = float2(0.5, 0.5) + float2(0.5, -0.5) * f3PosInCascadeProjSpace.xy;\n    f3ShadowMapUVDepth.z = f3PosInCascadeProjSpace.z;\n        \n    float3 f3ddXShadowMapUVDepth = ddx(f3PosInLightViewSpace) * f3CascadeLightSpaceScale * float3(0.5,-0.5,1);\n    float3 f3ddYShadowMapUVDepth = ddy(f3PosInLightViewSpace) * f3CascadeLightSpaceScale * float3(0.5,-0.5,1);\n\n    float2 f2DepthSlopeScaledBias = ComputeReceiverPlaneDepthBias(f3ddXShadowMapUVDepth, f3ddYShadowMapUVDepth);\n    float2 ShadowMapDim; float Elems;\n    g_tex2DShadowMap.GetDimensions(ShadowMapDim.x, ShadowMapDim.y, Elems);\n    f2DepthSlopeScaledBias /= ShadowMapDim.xy;\n\n    float fractionalSamplingError = dot( float2(1.f, 1.f), abs(f2DepthSlopeScaledBias.xy) );\n    f3ShadowMapUVDepth.z += fractionalSamplingError;\n    \n    float fLightAmount = g_tex2DShadowMap.SampleCmp(samComparison, float3(f3ShadowMapUVDepth.xy, Cascade), float(f3ShadowMapUVDepth.z)).x;\n\n#if SMOOTH_SHADOWS\n        int2 Offsets[] = \n        {\n            int2(-1,-1),\n            int2(+1,-1),\n            int2(-1,+1),\n            int2(+1,+1),\n        };\n        [unroll]\n        for(int i=0; i<4; ++i)\n        {\n            float fDepthBias = dot(Offsets[i].xy, f2DepthSlopeScaledBias.xy);\n            fLightAmount += g_tex2DShadowMap.SampleCmp(samComparison, float3(f3ShadowMapUVDepth.xy, Cascade), f3ShadowMapUVDepth.z + fDepthBias, Offsets[i]).x;\n        }\n        fLightAmount /= 5;\n#endif\n    return fLightAmount;\n}\n\nvoid CombineMaterials(in float4 MtrlWeights,\n                      in float2 f2TileUV,\n                      out float3 SurfaceColor,\n                      out float3 SurfaceNormalTS)\n{\n    SurfaceNormalTS = 0;\n    // Normalize weights and compute base material weight\n    MtrlWeights /= max( dot(MtrlWeights, float4(1,1,1,1)) , 1 );\n    float BaseMaterialWeight = saturate(1 - dot(MtrlWeights, float4(1,1,1,1)));\n    \n    // The mask is already sharp\n\n    ////Sharpen the mask\n    //float2 TmpMin2 = min(MtrlWeights.rg, MtrlWeights.ba);\n    //float Min = min(TmpMin2.r, TmpMin2.g);\n    //Min = min(Min, BaseMaterialWeight);\n    //float p = 4;\n    //BaseMaterialWeight = pow(BaseMaterialWeight-Min, p);\n    //MtrlWeights = pow(MtrlWeights-Min, p);\n    //float NormalizationFactor = dot(MtrlWeights, float4(1,1,1,1)) + BaseMaterialWeight;\n    //MtrlWeights /= NormalizationFactor;\n    //BaseMaterialWeight /= NormalizationFactor;\n\n\t// Get diffuse color of the base material\n    float4 BaseMaterialDiffuse = g_tex2DTileTextures[0].Sample(samLinearWrap, f2TileUV.xy / g_TerrainAttribs.m_fBaseMtrlTilingScale);\n    float4x4 MaterialColors = (float4x4)0;\n\n    // Get tangent space normal of the base material\n#if TEXTURING_MODE == TM_MATERIAL_MASK_NM\n    float3 BaseMaterialNormal = g_tex2DTileNormalMaps[0].Sample(samLinearWrap, f2TileUV.xy / g_TerrainAttribs.m_fBaseMtrlTilingScale);\n    float4x3 MaterialNormals = (float4x3)0;\n#endif\n\n    float4 f4TilingScale = g_TerrainAttribs.m_f4TilingScale;\n    float fTilingScale[5] = {0, f4TilingScale.x, f4TilingScale.y, f4TilingScale.z, f4TilingScale.w};\n    // Load material colors and normals\n    [unroll]for(int iTileTex = 1; iTileTex < NUM_TILE_TEXTURES; iTileTex++)\n\t{\n        const float fThresholdWeight = 3.f/256.f;\n        MaterialColors[iTileTex-1] = \n\t\t\tMtrlWeights[iTileTex-1] > fThresholdWeight ? \n\t\t\t\tg_tex2DTileTextures[iTileTex].Sample(samLinearWrap, f2TileUV.xy  / fTilingScale[iTileTex]) : 0.f;\n#if TEXTURING_MODE == TM_MATERIAL_MASK_NM\n        MaterialNormals[iTileTex-1] = \n\t\t\tMtrlWeights[iTileTex-1] > fThresholdWeight ? \n\t\t\t\tg_tex2DTileNormalMaps[iTileTex].Sample(samLinearWrap, f2TileUV.xy / fTilingScale[iTileTex]) : 0.f;\n#endif\n\t}\n    // Blend materials and normals using the weights\n    SurfaceColor = BaseMaterialDiffuse.rgb * BaseMaterialWeight + mul(MtrlWeights, MaterialColors).rgb;\n\n#if TEXTURING_MODE == TM_MATERIAL_MASK_NM\n    SurfaceNormalTS = BaseMaterialNormal * BaseMaterialWeight + mul(MtrlWeights, MaterialNormals);\n    SurfaceNormalTS = normalize(SurfaceNormalTS*2-1);\n#endif\n}\n\nRasterizerState RS_SolidFill;//Set by the app; can be biased or not\n//{\n//    FILLMODE = Solid;\n//    CullMode = Back;\n//    FrontCounterClockwise = true;\n//};\n\nRasterizerState RS_SolidFill_NoCull\n{\n    FILLMODE = Solid;\n    CullMode = None;\n};\n\nRasterizerState RS_Wireframe_NoCull\n{\n    FILLMODE = Wireframe;\n    CullMode = None;\n};\n\nBlendState BS_DisableBlending\n{\n    BlendEnable[0] = FALSE;\n    BlendEnable[1] = FALSE;\n    BlendEnable[2] = FALSE;\n};\n\nDepthStencilState DSS_EnableDepthTest\n{\n    DepthEnable = TRUE;\n    DepthWriteMask = ALL;\n    DEPTHFUNC = GREATER;\n};\n\nDepthStencilState DSS_DisableDepthTest\n{\n    DepthEnable = FALSE;\n    DepthWriteMask = ZERO;\n};\n\nstruct SHemisphereVSOutput\n{\n    float4 f4PosPS : SV_Position;\n    float2 TileTexUV  : TileTextureUV;\n    float3 f3Normal : Normal;\n    float3 f3PosInLightViewSpace : POS_IN_LIGHT_VIEW_SPACE;\n    float fCameraSpaceZ : CAMERA_SPACE_Z;\n    float2 f2MaskUV0 : MASK_UV0;\n    float3 f3Tangent : TANGENT;\n    float3 f3Bitangent : BITANGENT;\n    float3 f3SunLightExtinction : EXTINCTION;\n    float3 f3AmbientSkyLight : AMBIENT_SKY_LIGHT;\n};\n\nvoid GetSunLightExtinctionAndSkyLight(in float3 f3PosWS,\n                                      out float3 f3Extinction,\n                                      out float3 f3AmbientSkyLight)\n{\n    float3 f3EarthCentre = float3(0, -g_MediaParams.fEarthRadius, 0);\n    float3 f3DirFromEarthCentre = f3PosWS - f3EarthCentre;\n    float fDistToCentre = length(f3DirFromEarthCentre);\n    f3DirFromEarthCentre /= fDistToCentre;\n    float fHeightAboveSurface = fDistToCentre - g_MediaParams.fEarthRadius;\n    float fCosZenithAngle = dot(f3DirFromEarthCentre, g_LightAttribs.f4DirOnLight.xyz);\n\n    float fRelativeHeightAboveSurface = fHeightAboveSurface / g_MediaParams.fAtmTopHeight;\n    float2 f2ParticleDensityToAtmTop = g_tex2DOccludedNetDensityToAtmTop.SampleLevel(samLinearClamp, float2(fRelativeHeightAboveSurface, fCosZenithAngle*0.5+0.5), 0).xy;\n    \n    float3 f3RlghOpticalDepth = g_MediaParams.f4RayleighExtinctionCoeff.rgb * f2ParticleDensityToAtmTop.x;\n    float3 f3MieOpticalDepth  = g_MediaParams.f4MieExtinctionCoeff.rgb      * f2ParticleDensityToAtmTop.y;\n        \n    // And total extinction for the current integration point:\n    f3Extinction = exp( -(f3RlghOpticalDepth + f3MieOpticalDepth) );\n    \n    f3AmbientSkyLight = g_tex2DAmbientSkylight.SampleLevel(samLinearClamp, float2(fCosZenithAngle*0.5+0.5, 0.5), 0);\n}\n\n\nSHemisphereVSOutput HemisphereVS(in float3 f3PosWS : WORLD_POS,\n                                 in float2 f2MaskUV0 : MASK0_UV)\n{\n    SHemisphereVSOutput Out;\n    Out.TileTexUV = f3PosWS.xz;\n\n    Out.f4PosPS = mul( float4(f3PosWS,1), g_CameraAttribs.WorldViewProj);\n    \n    float4 ShadowMapSpacePos = mul( float4(f3PosWS,1), g_LightAttribs.ShadowAttribs.mWorldToLightView);\n    Out.f3PosInLightViewSpace = ShadowMapSpacePos.xyz / ShadowMapSpacePos.w;\n    Out.fCameraSpaceZ = Out.f4PosPS.w;\n    Out.f2MaskUV0 = f2MaskUV0;\n    float3 f3Normal = normalize(f3PosWS - float3(0, -g_TerrainAttribs.m_fEarthRadius, 0));\n    Out.f3Normal = f3Normal;\n    Out.f3Tangent = normalize( cross(f3Normal, float3(0,0,1)) );\n    Out.f3Bitangent = normalize( cross(Out.f3Tangent, f3Normal) );\n\n    GetSunLightExtinctionAndSkyLight(f3PosWS, Out.f3SunLightExtinction, Out.f3AmbientSkyLight);\n\n    return Out;\n}\n\nfloat4 HemisphereZOnlyVS(in float3 f3PosWS : WORLD_POS) : SV_Position\n{\n    float4 f4PosPS = mul( float4(f3PosWS,1), g_CameraAttribs.WorldViewProj);\n    return f4PosPS;\n}\n\nfloat3 HemispherePS(SHemisphereVSOutput In) : SV_Target\n{\n    float3 EarthNormal = normalize(In.f3Normal);\n    float3 EarthTangent = normalize(In.f3Tangent);\n    float3 EarthBitangent = normalize(In.f3Bitangent);\n    float3 f3TerrainNormal;\n    f3TerrainNormal.xz = g_tex2DNormalMap.Sample(samLinearMirror, In.f2MaskUV0.xy).xy;\n    // Since UVs are mirrored, we have to adjust normal coords accordingly:\n    float2 f2XZSign = sign( 0.5 - frac(In.f2MaskUV0.xy/2) );\n    f3TerrainNormal.xz *= f2XZSign;\n\n    f3TerrainNormal.y = sqrt( saturate(1 - dot(f3TerrainNormal.xz,f3TerrainNormal.xz)) );\n    //float3 Tangent   = normalize(float3(1,0,In.HeightMapGradients.x));\n    //float3 Bitangent = normalize(float3(0,1,In.HeightMapGradients.y));\n    f3TerrainNormal = normalize( mul(f3TerrainNormal, float3x3(EarthTangent, EarthNormal, EarthBitangent)) );\n    \n    float4 MtrlWeights = g_tex2DMtrlMap.Sample(samLinearMirror, In.f2MaskUV0.xy);\n    float3 SurfaceColor, SurfaceNormalTS;\n    CombineMaterials(MtrlWeights, In.TileTexUV, SurfaceColor.xyz, SurfaceNormalTS);\n    \n    float3 f3TerrainTangent = normalize( cross(f3TerrainNormal, float3(0,0,1)) );\n    float3 f3TerrainBitangent = normalize( cross(f3TerrainTangent, f3TerrainNormal) );\n    float3 f3Normal = normalize( mul(SurfaceNormalTS.xzy, float3x3(f3TerrainTangent, f3TerrainNormal, f3TerrainBitangent)) );\n\n    // Attenuate extraterrestrial sun color with the extinction factor\n    float3 f3SunLight = g_LightAttribs.f4ExtraterrestrialSunColor.rgb * In.f3SunLightExtinction;\n    // Ambient sky light is not pre-multiplied with the sun intensity\n    float3 f3AmbientSkyLight = g_LightAttribs.f4ExtraterrestrialSunColor.rgb * In.f3AmbientSkyLight;\n    // Account for occlusion by the ground plane\n    f3AmbientSkyLight *= saturate((1 + dot(EarthNormal, f3Normal))/2.f);\n\n    // We need to divide diffuse color by PI to get the reflectance value\n    float3 SurfaceReflectance = SurfaceColor * g_fEarthReflectance / PI;\n\n    float Cascade;\n    float fLightAmount = ComputeShadowAmount(In.f3PosInLightViewSpace.xyz, In.fCameraSpaceZ, Cascade);\n    float DiffuseIllumination = max(0, dot(f3Normal, g_LightAttribs.f4DirOnLight.xyz));\n    \n    float3 f3CascadeColor = 0;\n    if( g_LightAttribs.ShadowAttribs.bVisualizeCascades )\n    {\n        f3CascadeColor = (Cascade < NUM_SHADOW_CASCADES ? g_TerrainAttribs.f4CascadeColors[Cascade].rgb : float3(1,1,1)) / 8 ;\n    }\n    \n    float3 f3FinalColor = f3CascadeColor +  SurfaceReflectance * (fLightAmount*DiffuseIllumination*f3SunLight + f3AmbientSkyLight);\n\n    return f3FinalColor;\n}\n\ntechnique11 RenderHemisphereTech\n{\n    pass P0\n    {\n        SetVertexShader( CompileShader( vs_5_0, HemisphereVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader( ps_5_0, HemispherePS() ) );\n    }\n}\n\n\nstruct SScreenSizeQuadVSOutput\n{\n    float4 m_f4Pos : SV_Position;\n    float2 m_f2PosPS : PosPS; // Position in projection space [-1,1]x[-1,1]\n};\n\nSScreenSizeQuadVSOutput GenerateScreenSizeQuadVS(in uint VertexId : SV_VertexID)\n{\n    float4 MinMaxUV = float4(-1, -1, 1, 1);\n    \n    SScreenSizeQuadVSOutput Verts[4] = \n    {\n        {float4(MinMaxUV.xy, 1.0, 1.0), MinMaxUV.xy}, \n        {float4(MinMaxUV.xw, 1.0, 1.0), MinMaxUV.xw},\n        {float4(MinMaxUV.zy, 1.0, 1.0), MinMaxUV.zy},\n        {float4(MinMaxUV.zw, 1.0, 1.0), MinMaxUV.zw}\n    };\n\n    return Verts[VertexId];\n}\n\nfloat3 ComputeNormal(float2 f2ElevMapUV,\n                     float fSampleSpacingInterval,\n                     float fMIPLevel)\n{\n#   define GET_ELEV(Offset) g_tex2DElevationMap.SampleLevel( samPointClamp, f2ElevMapUV, fMIPLevel, Offset)\n\n#if 1\n    float Height00 = GET_ELEV( int2( -1, -1) );\n    float Height10 = GET_ELEV( int2(  0, -1) );\n    float Height20 = GET_ELEV( int2( +1, -1) );\n\n    float Height01 = GET_ELEV( int2( -1, 0) );\n    //float Height11 = GET_ELEV( int2(  0, 0) );\n    float Height21 = GET_ELEV( int2( +1, 0) );\n\n    float Height02 = GET_ELEV( int2( -1, +1) );\n    float Height12 = GET_ELEV( int2(  0, +1) );\n    float Height22 = GET_ELEV( int2( +1, +1) );\n\n    float3 Grad;\n    Grad.x = (Height00+Height01+Height02) - (Height20+Height21+Height22);\n    Grad.y = (Height00+Height10+Height20) - (Height02+Height12+Height22);\n    Grad.z = fSampleSpacingInterval * 6.f;\n    //Grad.x = (3*Height00+10*Height01+3*Height02) - (3*Height20+10*Height21+3*Height22);\n    //Grad.y = (3*Height00+10*Height10+3*Height20) - (3*Height02+10*Height12+3*Height22);\n    //Grad.z = fSampleSpacingInterval * 32.f;\n#else\n    float Height1 = GET_ELEV( int2( 1, 0) );\n    float Height2 = GET_ELEV( int2(-1, 0) );\n    float Height3 = GET_ELEV( int2( 0, 1) );\n    float Height4 = GET_ELEV( int2( 0,-1) );\n       \n    float3 Grad;\n    Grad.x = Height2 - Height1;\n    Grad.y = Height4 - Height3;\n    Grad.z = fSampleSpacingInterval * 2.f;\n#endif\n    Grad.xy *= HEIGHT_MAP_SCALE*g_NMGenerationAttribs.m_fElevationScale;\n    float3 Normal = normalize( Grad );\n\n    return Normal;\n}\n\nfloat2 GenerateNormalMapPS(SScreenSizeQuadVSOutput In) : SV_TARGET\n{\n\tfloat2 f2UV = float2(0.5,0.5) + float2(0.5,-0.5) * In.m_f2PosPS.xy;\n    float3 Normal = ComputeNormal( f2UV, g_NMGenerationAttribs.m_fSampleSpacingInterval*exp2(g_NMGenerationAttribs.m_fMIPLevel), g_NMGenerationAttribs.m_fMIPLevel );\n    // Only xy components are stored. z component is calculated in the shader\n    return Normal.xy;\n}\n\ntechnique11 RenderNormalMapTech\n{\n    pass\n    {\n        SetDepthStencilState( DSS_DisableDepthTest, 0 );\n        SetRasterizerState( RS_SolidFill_NoCull );\n        SetBlendState( BS_DisableBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );\n\n        SetVertexShader( CompileShader( vs_5_0, GenerateScreenSizeQuadVS() ) );\n        SetGeometryShader( NULL );\n        SetPixelShader( CompileShader( ps_5_0, GenerateNormalMapPS() ) );\n    }\n}\n"
  },
  {
    "path": "fx/TerrainStructs.fxh",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#ifndef _TERRAIN_STRCUTS_FXH_\n#define _TERRAIN_STRCUTS_FXH_\n\n#include \"Structures.fxh\"\n\n#define PI 3.1415928f\n#define HEIGHT_MAP_SCALE 65535.f\n\n#ifndef __cplusplus\n\n#   define D3DXVECTOR2 float2\n#   define D3DXVECTOR3 float3\n#   define D3DXVECTOR4 float4\n\n#endif\n\n#ifdef __cplusplus\n#   define CHECK_STRUCT_ALIGNMENT(s) static_assert( sizeof(s) % 16 == 0, \"sizeof(\"#s\") is not multiple of 16\" );\n#else\n#   define CHECK_STRUCT_ALIGNMENT(s)\n#endif\n\nstruct STerrainAttribs\n{\n    float m_fElevationScale;\n    float m_fElevationSamplingInterval;\n    float m_fEarthRadius;\n    float m_fBaseMtrlTilingScale;\n    float4 m_f4TilingScale;\n\n\tfloat4 f4CascadeColors[MAX_CASCADES];\n\n#ifdef __cplusplus\n    STerrainAttribs() : \n        m_fElevationScale(0.1f),\n\t\tm_fElevationSamplingInterval(1.f),\n        m_fEarthRadius( SAirScatteringAttribs().fEarthRadius ),\n        m_fBaseMtrlTilingScale(100.f),\n        m_f4TilingScale(100.f, 100.f, 100.f, 100.f)\n    {\n        f4CascadeColors[0] = float4(0,1,0,1);\n\t\tf4CascadeColors[1] = float4(0,0,1,1);\n\t\tf4CascadeColors[2] = float4(1,1,0,1);\n\t\tf4CascadeColors[3] = float4(0,1,1,1);\n\t\tf4CascadeColors[4] = float4(1,0,1,1);\n\t\tf4CascadeColors[5] = float4(0.3f, 1, 0.7f,1);\n\t\tf4CascadeColors[6] = float4(0.7f, 0.3f,1,1);\n\t\tf4CascadeColors[7] = float4(1, 0.7f, 0.3f, 1);\n    }\n#endif\n};\nCHECK_STRUCT_ALIGNMENT(STerrainAttribs);\n\nstruct SNMGenerationAttribs\n{\n    float m_fSampleSpacingInterval;\n    float m_fMIPLevel;\n    float m_fElevationScale;\n    float m_fDummy;\n};\nCHECK_STRUCT_ALIGNMENT(SNMGenerationAttribs);\n\n\n#endif //_TERRAIN_STRCUTS_FXH_\n"
  },
  {
    "path": "license.txt",
    "content": "\nApache License\n Version 2.0, January 2004\n\n http://www.apache.org/licenses/ \n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION \n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and \ndistribution as defined by Sections 1 through 9 of this document. \n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright \nowner that is granting the License. \n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities \nthat control, are controlled by, or are under common control with that entity. \nFor the purposes of this definition, \"control\" means (i) the power, direct or \nindirect, to cause the direction or management of such entity, whether by \ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the \noutstanding shares, or (iii) beneficial ownership of such entity. \n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising \npermissions granted by this License. \n\n\"Source\" form shall mean the preferred form for making modifications, including \nbut not limited to software source code, documentation source, and configuration \nfiles. \n\n\"Object\" form shall mean any form resulting from mechanical transformation or \ntranslation of a Source form, including but not limited to compiled object code, \ngenerated documentation, and conversions to other media types. \n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made \navailable under the License, as indicated by a copyright notice that is included \nin or attached to the work (an example is provided in the Appendix below). \n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that \nis based on (or derived from) the Work and for which the editorial revisions, \nannotations, elaborations, or other modifications represent, as a whole, an \noriginal work of authorship. For the purposes of this License, Derivative Works \nshall not include works that remain separable from, or merely link (or bind by \nname) to the interfaces of, the Work and Derivative Works thereof. \n\n\"Contribution\" shall mean any work of authorship, including the original version \nof the Work and any modifications or additions to that Work or Derivative Works \nthereof, that is intentionally submitted to Licensor for inclusion in the Work \nby the copyright owner or by an individual or Legal Entity authorized to submit \non behalf of the copyright owner. For the purposes of this definition, \n\"submitted\" means any form of electronic, verbal, or written communication sent \nto the Licensor or its representatives, including but not limited to \ncommunication on electronic mailing lists, source code control systems, and \nissue tracking systems that are managed by, or on behalf of, the Licensor for \nthe purpose of discussing and improving the Work, but excluding communication \nthat is conspicuously marked or otherwise designated in writing by the copyright \nowner as \"Not a Contribution.\" \n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf \nof whom a Contribution has been received by Licensor and subsequently \nincorporated within the Work. \n\n2. Grant of Copyright License. Subject to the terms and conditions of this \nLicense, each Contributor hereby grants to You a perpetual, worldwide, \nnon-exclusive, no-charge, royalty-free, irrevocable copyright license to \nreproduce, prepare Derivative Works of, publicly display, publicly perform, \nsublicense, and distribute the Work and such Derivative Works in Source or \nObject form. \n\n3. Grant of Patent License. Subject to the terms and conditions of this License, \neach Contributor hereby grants to You a perpetual, worldwide, non-exclusive, \nno-charge, royalty-free, irrevocable (except as stated in this section) patent \nlicense to make, have made, use, offer to sell, sell, import, and otherwise \ntransfer the Work, where such license applies only to those patent claims \nlicensable by such Contributor that are necessarily infringed by their \nContribution(s) alone or by combination of their Contribution(s) with the Work \nto which such Contribution(s) was submitted. If You institute patent litigation \nagainst any entity (including a cross-claim or counterclaim in a lawsuit) \nalleging that the Work or a Contribution incorporated within the Work \nconstitutes direct or contributory patent infringement, then any patent licenses \ngranted to You under this License for that Work shall terminate as of the date \nsuch litigation is filed. \n\n4. Redistribution. You may reproduce and distribute copies of the Work or \nDerivative Works thereof in any medium, with or without modifications, and in \nSource or Object form, provided that You meet the following conditions: \n  You must give any other recipients of the Work or Derivative Works a copy of \n  this License; and \n\n\n  You must cause any modified files to carry prominent notices stating that You \n  changed the files; and \n\n\n  You must retain, in the Source form of any Derivative Works that You \n  distribute, all copyright, patent, trademark, and attribution notices from the \n  Source form of the Work, excluding those notices that do not pertain to any \n  part of the Derivative Works; and \n\n\n  If the Work includes a \"NOTICE\" text file as part of its distribution, then \n  any Derivative Works that You distribute must include a readable copy of the \n  attribution notices contained within such NOTICE file, excluding those notices \n  that do not pertain to any part of the Derivative Works, in at least one of \n  the following places: within a NOTICE text file distributed as part of the \n  Derivative Works; within the Source form or documentation, if provided along \n  with the Derivative Works; or, within a display generated by the Derivative \n  Works, if and wherever such third-party notices normally appear. The contents \n  of the NOTICE file are for informational purposes only and do not modify the \n  License. You may add Your own attribution notices within Derivative Works that \n  You distribute, alongside or as an addendum to the NOTICE text from the Work, \n  provided that such additional attribution notices cannot be construed as \n  modifying the License.\nYou may add Your own copyright statement to Your modifications and may provide \nadditional or different license terms and conditions for use, reproduction, or \ndistribution of Your modifications, or for any such Derivative Works as a whole, \nprovided Your use, reproduction, and distribution of the Work otherwise complies \nwith the conditions stated in this License. \n\n5. Submission of Contributions. Unless You explicitly state otherwise, any \nContribution intentionally submitted for inclusion in the Work by You to the \nLicensor shall be under the terms and conditions of this License, without any \nadditional terms or conditions. Notwithstanding the above, nothing herein shall \nsupersede or modify the terms of any separate license agreement you may have \nexecuted with Licensor regarding such Contributions. \n\n6. Trademarks. This License does not grant permission to use the trade names, \ntrademarks, service marks, or product names of the Licensor, except as required \nfor reasonable and customary use in describing the origin of the Work and \nreproducing the content of the NOTICE file. \n\n7. Disclaimer of Warranty. Unless required by applicable law or agreed to in \nwriting, Licensor provides the Work (and each Contributor provides its \nContributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY \nKIND, either express or implied, including, without limitation, any warranties \nor conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A \nPARTICULAR PURPOSE. You are solely responsible for determining the \nappropriateness of using or redistributing the Work and assume any risks \nassociated with Your exercise of permissions under this License. \n\n8. Limitation of Liability. In no event and under no legal theory, whether in \ntort (including negligence), contract, or otherwise, unless required by \napplicable law (such as deliberate and grossly negligent acts) or agreed to in \nwriting, shall any Contributor be liable to You for damages, including any \ndirect, indirect, special, incidental, or consequential damages of any character \narising as a result of this License or out of the use or inability to use the \nWork (including but not limited to damages for loss of goodwill, work stoppage, \ncomputer failure or malfunction, or any and all other commercial damages or \nlosses), even if such Contributor has been advised of the possibility of such \ndamages. \n\n9. Accepting Warranty or Additional Liability. While redistributing the Work or \nDerivative Works thereof, You may choose to offer, and charge a fee for, \nacceptance of support, warranty, indemnity, or other liability obligations \nand/or rights consistent with this License. However, in accepting such \nobligations, You may act only on Your own behalf and on Your sole \nresponsibility, not on behalf of any other Contributor, and only if You agree to \nindemnify, defend, and hold each Contributor harmless for any liability incurred \nby, or claims asserted against, such Contributor by reason of your accepting any \nsuch warranty or additional liability. \n\nEND OF TERMS AND CONDITIONS \n\nAPPENDIX: How to apply the Apache License to your work \n\nTo apply the Apache License to your work, attach the following boilerplate \nnotice, with the fields enclosed by brackets \"[]\" replaced with your own \nidentifying information. (Don't include the brackets!) The text should be \nenclosed in the appropriate comment syntax for the file format. We also \nrecommend that a file or class name and description of purpose be included on \nthe same \"printed page\" as the copyright notice for easier identification within \nthird-party archives. \n\nCopyright [yyyy] [name of copyright owner] Licensed under the Apache License, \nVersion 2.0 (the \"License\"); you may not use this file except in compliance with \nthe License. You may obtain a copy of the License at \nhttp://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or \nagreed to in writing, software distributed under the License is distributed on \nan \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express \nor implied. See the License for the specific language governing permissions and \nlimitations under the License.\n"
  },
  {
    "path": "readme.txt",
    "content": "Intel Corporation - Outdoor Light Scattering Sample\n\nThis sample shows how high-quality light scattering effects in large outdoor environments can be rendered on Intel HD graphics in real time. The technique extends the approach shown in the previously published sample and exploits the same main ideas. Epipolar sampling helps minimize the number of samples for which expensive ray marching algorithm is executed while 1D min/max binary trees are used to accelerate computations.\n\nIn this sample, a more complex physical model is exploited to simulate light propagation in the atmosphere. It assumes that the planet is spherical and that the particle density decreases exponentially with the altitude computed with respect to the planet surface. To facilitate shadows in large outdoor environments, cascaded shadow maps are used. Scattering contribution from each cascade is computed and accumulated to obtain the final result.\n\nNote: Media Elements are the images, clip art, animations, sounds, music, shapes, video clips, 2D Images, 2D and 3D Meshs and mesh data, animation and animation data, and Textures included in the software. This license does not grant you any rights in the Media Elements and you may not reproduce, prepare derivative works, distribute, publicly display, or publicly perform the Media Elements.\n\nNote: The source code sample is provided under the BSD license.  See the license folder within the sample source directory for additional details."
  },
  {
    "path": "stdafx.h",
    "content": "/////////////////////////////////////////////////////////////////////////////////////////////\n// Copyright 2017 Intel Corporation\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/////////////////////////////////////////////////////////////////////////////////////////////\n\n#define WIN32_LEAN_AND_MEAN\n\n#pragma warning (disable: 4100 4127) // warning C4100:  unreferenced formal parameter;  warning C4127:  conditional expression is constant\n\n#pragma warning (push)\n#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union\n\n//\n// windows headers\n//\n#include <sdkddkver.h>\n#include <Windows.h>\n#include <tchar.h>\n#include <atlcomcli.h> // for CComPtr support\n\n//\n// C++ headers\n//\n\n#include <cassert>\n#include <stdexcept>\n#include <algorithm>\n#include <sstream>\n#include <fstream>\n#include <map>\n#include <set>\n#include <vector>\n#include <list>\n#include <ctime>\n\n//\n// DirectX headers\n//\n#include <D3D11.h>\n#include <D3DX11.h>\n#include <D3DX10math.h>\n#include <xnamath.h>\n\n#pragma warning (pop)\n\n#include \"Errors.h\"\n\n#include \"CPUT.h\"\n\n#if defined(DEBUG) || defined(_DEBUG)\n#ifndef V\n#define V(x)           { hr = (x); assert(SUCCEEDED(hr)); }\n#endif\n#ifndef V_RETURN\n#define V_RETURN(x)    { hr = (x); assert(SUCCEEDED(hr)); if( FAILED(hr) ) { return hr; } }\n#endif\n#else\n#ifndef V\n#define V(x)           { hr = (x); }\n#endif\n#ifndef V_RETURN\n#define V_RETURN(x)    { hr = (x); if( FAILED(hr) ) { return hr; } }\n#endif\n#endif\n\n//#define assert(x) if(!(x)) _CrtDbgBreak(); else {}\n\ninline void UnbindPSResources(ID3D11DeviceContext *pCtx)\n{\n\tID3D11ShaderResourceView *pSRVs[20] = {NULL};\n\tpCtx->PSSetShaderResources(0, _countof(pSRVs), pSRVs);\n}\n\ninline void UnbindVSResources(ID3D11DeviceContext *pCtx)\n{\n\tID3D11ShaderResourceView *pSRVs[8] = {NULL};\n\tpCtx->VSSetShaderResources(0, _countof(pSRVs), pSRVs);\n}\n\ninline void UpdateConstantBuffer(ID3D11DeviceContext *pDeviceCtx, ID3D11Buffer *pCB, const void *pData, size_t DataSize)\n{\n    D3D11_MAPPED_SUBRESOURCE MappedData;\n    pDeviceCtx->Map(pCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedData);\n    memcpy(MappedData.pData, pData, DataSize);\n    pDeviceCtx->Unmap(pCB, 0);\n}\n\n// end of file\n"
  }
]