--- /dev/null
+#ifndef MESH_H\r
+#define MESH_H\r
+\r
+#include <string>\r
+#include <fstream>\r
+#include <sstream>\r
+#include <iostream>\r
+#include <vector>\r
+using namespace std;\r
+\r
+#include <vector>\r
+#include <d3d11_1.h>\r
+#include <DirectXMath.h>\r
+using namespace DirectX;\r
+\r
+struct VERTEX {\r
+ FLOAT X, Y, Z;\r
+ XMFLOAT2 texcoord;\r
+};\r
+\r
+struct Texture {\r
+ string type;\r
+ aiString path;\r
+ ID3D11ShaderResourceView *texture;\r
+};\r
+\r
+class Mesh {\r
+public:\r
+ vector<VERTEX> vertices;\r
+ vector<UINT> indices;\r
+ vector<Texture> textures;\r
+ ID3D11Device *dev;\r
+\r
+ Mesh(ID3D11Device *dev, vector<VERTEX> vertices, vector<UINT> indices, vector<Texture> textures)\r
+ {\r
+ this->vertices = vertices;\r
+ this->indices = indices;\r
+ this->textures = textures;\r
+\r
+ this->dev = dev;\r
+\r
+ this->setupMesh(dev);\r
+ }\r
+\r
+ void Draw(ID3D11DeviceContext *devcon)\r
+ {\r
+ UINT stride = sizeof(VERTEX);\r
+ UINT offset = 0;\r
+\r
+ devcon->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);\r
+ devcon->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);\r
+\r
+ devcon->PSSetShaderResources(0, 1, &textures[0].texture);\r
+\r
+ devcon->DrawIndexed(indices.size(), 0, 0);\r
+ }\r
+\r
+ void Close()\r
+ {\r
+ VertexBuffer->Release();\r
+ IndexBuffer->Release();\r
+ }\r
+private:\r
+ /* Render data */\r
+ ID3D11Buffer *VertexBuffer, *IndexBuffer;\r
+\r
+ /* Functions */\r
+ // Initializes all the buffer objects/arrays\r
+ bool setupMesh(ID3D11Device *dev)\r
+ {\r
+ HRESULT hr;\r
+\r
+ D3D11_BUFFER_DESC vbd;\r
+ vbd.Usage = D3D11_USAGE_IMMUTABLE;\r
+ vbd.ByteWidth = sizeof(VERTEX) * vertices.size();\r
+ vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;\r
+ vbd.CPUAccessFlags = 0;\r
+ vbd.MiscFlags = 0;\r
+\r
+ D3D11_SUBRESOURCE_DATA initData;\r
+ initData.pSysMem = &vertices[0];\r
+\r
+ hr = dev->CreateBuffer(&vbd, &initData, &VertexBuffer);\r
+ if (FAILED(hr))\r
+ return false;\r
+\r
+ D3D11_BUFFER_DESC ibd;\r
+ ibd.Usage = D3D11_USAGE_IMMUTABLE;\r
+ ibd.ByteWidth = sizeof(UINT) * indices.size();\r
+ ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;\r
+ ibd.CPUAccessFlags = 0;\r
+ ibd.MiscFlags = 0;\r
+\r
+ initData.pSysMem = &indices[0];\r
+\r
+ hr = dev->CreateBuffer(&ibd, &initData, &IndexBuffer);\r
+ if (FAILED(hr))\r
+ return false;\r
+ }\r
+};\r
+\r
+#endif\r
--- /dev/null
+#include "ModelLoader.h"\r
+\r
+ModelLoader::ModelLoader()\r
+{\r
+}\r
+\r
+\r
+ModelLoader::~ModelLoader()\r
+{\r
+}\r
+\r
+bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devcon, std::string filename)\r
+{\r
+ Assimp::Importer importer;\r
+\r
+ const aiScene* pScene = importer.ReadFile(filename,\r
+ aiProcess_Triangulate |\r
+ aiProcess_ConvertToLeftHanded);\r
+\r
+ if (pScene == NULL)\r
+ return false;\r
+\r
+ this->directory = filename.substr(0, filename.find_last_of('/'));\r
+\r
+ this->dev = dev;\r
+ this->hwnd = hwnd;\r
+\r
+ processNode(pScene->mRootNode, pScene);\r
+\r
+ return true;\r
+}\r
+\r
+void ModelLoader::Draw(ID3D11DeviceContext * devcon)\r
+{\r
+ for (int i = 0; i < meshes.size(); i++)\r
+ {\r
+ meshes[i].Draw(devcon);\r
+ }\r
+}\r
+\r
+string textype;\r
+\r
+Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene)\r
+{\r
+ // Data to fill\r
+ vector<VERTEX> vertices;\r
+ vector<UINT> indices;\r
+ vector<Texture> textures;\r
+\r
+ if (mesh->mMaterialIndex >= 0)\r
+ {\r
+ aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];\r
+\r
+ if (textype.empty()) textype = determineTextureType(scene, mat);\r
+ }\r
+\r
+ // Walk through each of the mesh's vertices\r
+ for (UINT i = 0; i < mesh->mNumVertices; i++)\r
+ {\r
+ VERTEX vertex;\r
+\r
+ vertex.X = mesh->mVertices[i].x;\r
+ vertex.Y = mesh->mVertices[i].y;\r
+ vertex.Z = mesh->mVertices[i].z;\r
+\r
+ if (mesh->mTextureCoords[0])\r
+ {\r
+ vertex.texcoord.x = (float)mesh->mTextureCoords[0][i].x;\r
+ vertex.texcoord.y = (float)mesh->mTextureCoords[0][i].y;\r
+ }\r
+\r
+ vertices.push_back(vertex);\r
+ }\r
+\r
+ for (UINT i = 0; i < mesh->mNumFaces; i++)\r
+ {\r
+ aiFace face = mesh->mFaces[i];\r
+\r
+ for (UINT j = 0; j < face.mNumIndices; j++)\r
+ indices.push_back(face.mIndices[j]);\r
+ }\r
+\r
+ if (mesh->mMaterialIndex >= 0)\r
+ {\r
+ aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];\r
+\r
+ vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse", scene);\r
+ textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());\r
+ }\r
+\r
+ return Mesh(dev, vertices, indices, textures);\r
+}\r
+\r
+vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureType type, string typeName, const aiScene * scene)\r
+{\r
+ vector<Texture> textures;\r
+ for (UINT i = 0; i < mat->GetTextureCount(type); i++)\r
+ {\r
+ aiString str;\r
+ mat->GetTexture(type, i, &str);\r
+ // Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture\r
+ bool skip = false;\r
+ for (UINT j = 0; j < textures_loaded.size(); j++)\r
+ {\r
+ if (std::strcmp(textures_loaded[j].path.C_Str(), str.C_Str()) == 0)\r
+ {\r
+ textures.push_back(textures_loaded[j]);\r
+ skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization)\r
+ break;\r
+ }\r
+ }\r
+ if (!skip)\r
+ { // If texture hasn't been loaded already, load it\r
+ HRESULT hr;\r
+ Texture texture;\r
+ if (textype == "embedded compressed texture")\r
+ {\r
+ int textureindex = getTextureIndex(&str);\r
+ texture.texture = getTextureFromModel(scene, textureindex);\r
+ }\r
+ else\r
+ {\r
+ string filename = string(str.C_Str());\r
+ filename = directory + '/' + filename;\r
+ wstring filenamews = wstring(filename.begin(), filename.end());\r
+ hr = CreateWICTextureFromFile(dev, devcon, filenamews.c_str(), nullptr, &texture.texture);\r
+ if (FAILED(hr))\r
+ MessageBox(hwnd, "Texture couldn't be loaded", "Error!", MB_ICONERROR | MB_OK);\r
+ }\r
+ texture.type = typeName;\r
+ texture.path = str;\r
+ textures.push_back(texture);\r
+ this->textures_loaded.push_back(texture); // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.\r
+ }\r
+ }\r
+ return textures;\r
+}\r
+\r
+void ModelLoader::Close()\r
+{\r
+ for (int i = 0; i < meshes.size(); i++)\r
+ {\r
+ meshes[i].Close();\r
+ }\r
+\r
+ dev->Release();\r
+}\r
+\r
+void ModelLoader::processNode(aiNode * node, const aiScene * scene)\r
+{\r
+ for (UINT i = 0; i < node->mNumMeshes; i++)\r
+ {\r
+ aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];\r
+ meshes.push_back(this->processMesh(mesh, scene));\r
+ }\r
+\r
+ for (UINT i = 0; i < node->mNumChildren; i++)\r
+ {\r
+ this->processNode(node->mChildren[i], scene);\r
+ }\r
+}\r
+\r
+string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat)\r
+{\r
+ aiString textypeStr;\r
+ mat->GetTexture(aiTextureType_DIFFUSE, 0, &textypeStr);\r
+ string textypeteststr = textypeStr.C_Str();\r
+ if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5")\r
+ {\r
+ if (scene->mTextures[0]->mHeight == 0)\r
+ {\r
+ return "embedded compressed texture";\r
+ }\r
+ else\r
+ {\r
+ return "embedded non-compressed texture";\r
+ }\r
+ }\r
+ if (textypeteststr.find('.') != string::npos)\r
+ {\r
+ return "textures are on disk";\r
+ }\r
+}\r
+\r
+int ModelLoader::getTextureIndex(aiString * str)\r
+{\r
+ string tistr;\r
+ tistr = str->C_Str();\r
+ tistr = tistr.substr(1);\r
+ return stoi(tistr);\r
+}\r
+\r
+ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex)\r
+{\r
+ HRESULT hr;\r
+ ID3D11ShaderResourceView *texture;\r
+\r
+ int* size = reinterpret_cast<int*>(&scene->mTextures[textureindex]->mWidth);\r
+\r
+ hr = CreateWICTextureFromMemory(dev, devcon, reinterpret_cast<unsigned char*>(scene->mTextures[textureindex]->pcData), *size, nullptr, &texture);\r
+ if (FAILED(hr))\r
+ MessageBox(hwnd, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK);\r
+\r
+ return texture;\r
+}\r
--- /dev/null
+#ifndef MODEL_LOADER_H\r
+#define MODEL_LOADER_H\r
+\r
+#include <vector>\r
+#include <d3d11_1.h>\r
+#include <DirectXMath.h>\r
+\r
+#include <assimp\Importer.hpp>\r
+#include <assimp\scene.h>\r
+#include <assimp\postprocess.h>\r
+\r
+#include "Mesh.h"\r
+#include "TextureLoader.h"\r
+\r
+using namespace DirectX;\r
+\r
+class ModelLoader\r
+{\r
+public:\r
+ ModelLoader();\r
+ ~ModelLoader();\r
+\r
+ bool Load(HWND hwnd, ID3D11Device* dev, ID3D11DeviceContext* devcon, std::string filename);\r
+ void Draw(ID3D11DeviceContext* devcon);\r
+\r
+ void Close();\r
+private:\r
+ ID3D11Device *dev;\r
+ ID3D11DeviceContext *devcon;\r
+ std::vector<Mesh> meshes;\r
+ string directory;\r
+ vector<Texture> textures_loaded;\r
+ HWND hwnd;\r
+\r
+ void processNode(aiNode* node, const aiScene* scene);\r
+ Mesh processMesh(aiMesh* mesh, const aiScene* scene);\r
+ vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName, const aiScene* scene);\r
+ string determineTextureType(const aiScene* scene, aiMaterial* mat);\r
+ int getTextureIndex(aiString* str);\r
+ ID3D11ShaderResourceView* getTextureFromModel(const aiScene* scene, int textureindex);\r
+};\r
+\r
+#endif // !MODEL_LOADER_H\r
+\r
--- /dev/null
+Texture2D diffTexture;\r
+SamplerState SampleType;\r
+\r
+float4 main(float4 pos : SV_POSITION, float2 texcoord : TEXCOORD) : SV_TARGET\r
+{\r
+ float4 textureColor = diffTexture.Sample(SampleType, texcoord);\r
+\r
+ return textureColor;\r
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup Label="ProjectConfigurations">\r
+ <ProjectConfiguration Include="Debug|Win32">\r
+ <Configuration>Debug</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Release|Win32">\r
+ <Configuration>Release</Configuration>\r
+ <Platform>Win32</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Debug|x64">\r
+ <Configuration>Debug</Configuration>\r
+ <Platform>x64</Platform>\r
+ </ProjectConfiguration>\r
+ <ProjectConfiguration Include="Release|x64">\r
+ <Configuration>Release</Configuration>\r
+ <Platform>x64</Platform>\r
+ </ProjectConfiguration>\r
+ </ItemGroup>\r
+ <PropertyGroup Label="Globals">\r
+ <VCProjectVersion>15.0</VCProjectVersion>\r
+ <ProjectGuid>{E3B160B5-E71F-4F3F-9310-B8F156F736D8}</ProjectGuid>\r
+ <RootNamespace>SimpleTexturedDirectx11</RootNamespace>\r
+ <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <PlatformToolset>v141</PlatformToolset>\r
+ <CharacterSet>MultiByte</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>false</UseDebugLibraries>\r
+ <PlatformToolset>v141</PlatformToolset>\r
+ <WholeProgramOptimization>true</WholeProgramOptimization>\r
+ <CharacterSet>MultiByte</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <PlatformToolset>v141</PlatformToolset>\r
+ <CharacterSet>MultiByte</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>false</UseDebugLibraries>\r
+ <PlatformToolset>v141</PlatformToolset>\r
+ <WholeProgramOptimization>true</WholeProgramOptimization>\r
+ <CharacterSet>MultiByte</CharacterSet>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+ <ImportGroup Label="ExtensionSettings">\r
+ </ImportGroup>\r
+ <ImportGroup Label="Shared">\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <PropertyGroup Label="UserMacros" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <IncludePath>$(IncludePath);E:\OpenGL VS Files\include</IncludePath>\r
+ <LibraryPath>$(LibraryPath);E:\OpenGL VS Files\lib</LibraryPath>\r
+ </PropertyGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <ClCompile>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>Disabled</Optimization>\r
+ <SDLCheck>true</SDLCheck>\r
+ </ClCompile>\r
+ <Link>\r
+ <AdditionalDependencies>assimp-vc140-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+ <ClCompile>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>Disabled</Optimization>\r
+ <SDLCheck>true</SDLCheck>\r
+ </ClCompile>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <ClCompile>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>MaxSpeed</Optimization>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <IntrinsicFunctions>true</IntrinsicFunctions>\r
+ <SDLCheck>true</SDLCheck>\r
+ </ClCompile>\r
+ <Link>\r
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+ <OptimizeReferences>true</OptimizeReferences>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+ <ClCompile>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>MaxSpeed</Optimization>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <IntrinsicFunctions>true</IntrinsicFunctions>\r
+ <SDLCheck>true</SDLCheck>\r
+ </ClCompile>\r
+ <Link>\r
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+ <OptimizeReferences>true</OptimizeReferences>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="main.cpp" />\r
+ <ClCompile Include="ModelLoader.cpp" />\r
+ <ClCompile Include="TextureLoader.cpp" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <FxCompile Include="PixelShader.hlsl">\r
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType>\r
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType>\r
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>\r
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType>\r
+ </FxCompile>\r
+ <FxCompile Include="VertexShader.hlsl">\r
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Vertex</ShaderType>\r
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Vertex</ShaderType>\r
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Vertex</ShaderType>\r
+ <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Vertex</ShaderType>\r
+ </FxCompile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="Mesh.h" />\r
+ <ClInclude Include="ModelLoader.h" />\r
+ <ClInclude Include="TextureLoader.h" />\r
+ </ItemGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+ <ImportGroup Label="ExtensionTargets">\r
+ </ImportGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup>\r
+ <Filter Include="Source Files">\r
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+ </Filter>\r
+ <Filter Include="Header Files">\r
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
+ </Filter>\r
+ <Filter Include="Resource Files">\r
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+ </Filter>\r
+ <Filter Include="Shaders">\r
+ <UniqueIdentifier>{b6a86d3e-70a5-4d1e-ba05-c20902300206}</UniqueIdentifier>\r
+ </Filter>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="main.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="ModelLoader.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="TextureLoader.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <FxCompile Include="VertexShader.hlsl">\r
+ <Filter>Shaders</Filter>\r
+ </FxCompile>\r
+ <FxCompile Include="PixelShader.hlsl">\r
+ <Filter>Shaders</Filter>\r
+ </FxCompile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="ModelLoader.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="Mesh.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="TextureLoader.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ </ItemGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+//--------------------------------------------------------------------------------------\r
+// File: WICTextureLoader.cpp\r
+//\r
+// Function for loading a WIC image and creating a Direct3D 11 runtime texture for it\r
+// (auto-generating mipmaps if possible)\r
+//\r
+// Note: Assumes application has already called CoInitializeEx\r
+//\r
+// Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for\r
+// auto-gen mipmap support.\r
+//\r
+// Note these functions are useful for images created as simple 2D textures. For\r
+// more complex resources, DDSTextureLoader is an excellent light-weight runtime loader.\r
+// For a full-featured DDS file reader, writer, and texture processing pipeline see\r
+// the 'Texconv' sample and the 'DirectXTex' library.\r
+//\r
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF\r
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO\r
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A\r
+// PARTICULAR PURPOSE.\r
+//\r
+// Copyright (c) Microsoft Corporation. All rights reserved.\r
+//\r
+// http://go.microsoft.com/fwlink/?LinkId=248926\r
+// http://go.microsoft.com/fwlink/?LinkId=248929\r
+//--------------------------------------------------------------------------------------\r
+\r
+// We could load multi-frame images (TIFF/GIF) into a texture array.\r
+// For now, we just load the first frame (note: DirectXTex supports multi-frame images)\r
+\r
+#include <dxgiformat.h>\r
+#include <assert.h>\r
+\r
+#pragma warning(push)\r
+#pragma warning(disable : 4005)\r
+#include <wincodec.h>\r
+#pragma warning(pop)\r
+\r
+#include <memory>\r
+\r
+#include "TextureLoader.h"\r
+\r
+#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) && !defined(DXGI_1_2_FORMATS)\r
+#define DXGI_1_2_FORMATS\r
+#endif\r
+\r
+//---------------------------------------------------------------------------------\r
+template<class T> class ScopedObject\r
+{\r
+public:\r
+ explicit ScopedObject(T *p = 0) : _pointer(p) {}\r
+ ~ScopedObject()\r
+ {\r
+ if (_pointer)\r
+ {\r
+ _pointer->Release();\r
+ _pointer = nullptr;\r
+ }\r
+ }\r
+\r
+ bool IsNull() const { return (!_pointer); }\r
+\r
+ T& operator*() { return *_pointer; }\r
+ T* operator->() { return _pointer; }\r
+ T** operator&() { return &_pointer; }\r
+\r
+ void Reset(T *p = 0) { if (_pointer) { _pointer->Release(); } _pointer = p; }\r
+\r
+ T* Get() const { return _pointer; }\r
+\r
+private:\r
+ ScopedObject(const ScopedObject&);\r
+ ScopedObject& operator=(const ScopedObject&);\r
+\r
+ T* _pointer;\r
+};\r
+\r
+//-------------------------------------------------------------------------------------\r
+// WIC Pixel Format Translation Data\r
+//-------------------------------------------------------------------------------------\r
+struct WICTranslate\r
+{\r
+ GUID wic;\r
+ DXGI_FORMAT format;\r
+};\r
+\r
+static WICTranslate g_WICFormats[] =\r
+{\r
+ { GUID_WICPixelFormat128bppRGBAFloat, DXGI_FORMAT_R32G32B32A32_FLOAT },\r
+\r
+ { GUID_WICPixelFormat64bppRGBAHalf, DXGI_FORMAT_R16G16B16A16_FLOAT },\r
+ { GUID_WICPixelFormat64bppRGBA, DXGI_FORMAT_R16G16B16A16_UNORM },\r
+\r
+ { GUID_WICPixelFormat32bppRGBA, DXGI_FORMAT_R8G8B8A8_UNORM },\r
+ { GUID_WICPixelFormat32bppBGRA, DXGI_FORMAT_B8G8R8A8_UNORM }, // DXGI 1.1\r
+ { GUID_WICPixelFormat32bppBGR, DXGI_FORMAT_B8G8R8X8_UNORM }, // DXGI 1.1\r
+\r
+ { GUID_WICPixelFormat32bppRGBA1010102XR, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, // DXGI 1.1\r
+ { GUID_WICPixelFormat32bppRGBA1010102, DXGI_FORMAT_R10G10B10A2_UNORM },\r
+ { GUID_WICPixelFormat32bppRGBE, DXGI_FORMAT_R9G9B9E5_SHAREDEXP },\r
+\r
+#ifdef DXGI_1_2_FORMATS\r
+\r
+ { GUID_WICPixelFormat16bppBGRA5551, DXGI_FORMAT_B5G5R5A1_UNORM },\r
+ { GUID_WICPixelFormat16bppBGR565, DXGI_FORMAT_B5G6R5_UNORM },\r
+\r
+#endif // DXGI_1_2_FORMATS\r
+\r
+ { GUID_WICPixelFormat32bppGrayFloat, DXGI_FORMAT_R32_FLOAT },\r
+ { GUID_WICPixelFormat16bppGrayHalf, DXGI_FORMAT_R16_FLOAT },\r
+ { GUID_WICPixelFormat16bppGray, DXGI_FORMAT_R16_UNORM },\r
+ { GUID_WICPixelFormat8bppGray, DXGI_FORMAT_R8_UNORM },\r
+\r
+ { GUID_WICPixelFormat8bppAlpha, DXGI_FORMAT_A8_UNORM },\r
+\r
+#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)\r
+ { GUID_WICPixelFormat96bppRGBFloat, DXGI_FORMAT_R32G32B32_FLOAT },\r
+#endif\r
+};\r
+\r
+//-------------------------------------------------------------------------------------\r
+// WIC Pixel Format nearest conversion table\r
+//-------------------------------------------------------------------------------------\r
+\r
+struct WICConvert\r
+{\r
+ GUID source;\r
+ GUID target;\r
+};\r
+\r
+static WICConvert g_WICConvert[] =\r
+{\r
+ // Note target GUID in this conversion table must be one of those directly supported formats (above).\r
+\r
+ { GUID_WICPixelFormatBlackWhite, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM\r
+\r
+ { GUID_WICPixelFormat1bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+ { GUID_WICPixelFormat2bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+ { GUID_WICPixelFormat4bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+ { GUID_WICPixelFormat8bppIndexed, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+\r
+ { GUID_WICPixelFormat2bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM \r
+ { GUID_WICPixelFormat4bppGray, GUID_WICPixelFormat8bppGray }, // DXGI_FORMAT_R8_UNORM \r
+\r
+ { GUID_WICPixelFormat16bppGrayFixedPoint, GUID_WICPixelFormat16bppGrayHalf }, // DXGI_FORMAT_R16_FLOAT \r
+ { GUID_WICPixelFormat32bppGrayFixedPoint, GUID_WICPixelFormat32bppGrayFloat }, // DXGI_FORMAT_R32_FLOAT \r
+\r
+#ifdef DXGI_1_2_FORMATS\r
+\r
+ { GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat16bppBGRA5551 }, // DXGI_FORMAT_B5G5R5A1_UNORM\r
+\r
+#else\r
+\r
+ { GUID_WICPixelFormat16bppBGR555, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM\r
+ { GUID_WICPixelFormat16bppBGRA5551, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM\r
+ { GUID_WICPixelFormat16bppBGR565, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM\r
+\r
+#endif // DXGI_1_2_FORMATS\r
+\r
+ { GUID_WICPixelFormat32bppBGR101010, GUID_WICPixelFormat32bppRGBA1010102 }, // DXGI_FORMAT_R10G10B10A2_UNORM\r
+\r
+ { GUID_WICPixelFormat24bppBGR, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+ { GUID_WICPixelFormat24bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+ { GUID_WICPixelFormat32bppPBGRA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+ { GUID_WICPixelFormat32bppPRGBA, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+\r
+ { GUID_WICPixelFormat48bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+ { GUID_WICPixelFormat48bppBGR, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+ { GUID_WICPixelFormat64bppBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+ { GUID_WICPixelFormat64bppPRGBA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+ { GUID_WICPixelFormat64bppPBGRA, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+\r
+ { GUID_WICPixelFormat48bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT \r
+ { GUID_WICPixelFormat48bppBGRFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT \r
+ { GUID_WICPixelFormat64bppRGBAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT \r
+ { GUID_WICPixelFormat64bppBGRAFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT \r
+ { GUID_WICPixelFormat64bppRGBFixedPoint, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT \r
+ { GUID_WICPixelFormat64bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT \r
+ { GUID_WICPixelFormat48bppRGBHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT \r
+\r
+ { GUID_WICPixelFormat96bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT \r
+ { GUID_WICPixelFormat128bppPRGBAFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT \r
+ { GUID_WICPixelFormat128bppRGBFloat, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT \r
+ { GUID_WICPixelFormat128bppRGBAFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT \r
+ { GUID_WICPixelFormat128bppRGBFixedPoint, GUID_WICPixelFormat128bppRGBAFloat }, // DXGI_FORMAT_R32G32B32A32_FLOAT \r
+\r
+ { GUID_WICPixelFormat32bppCMYK, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM \r
+ { GUID_WICPixelFormat64bppCMYK, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+ { GUID_WICPixelFormat40bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+ { GUID_WICPixelFormat80bppCMYKAlpha, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+\r
+#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)\r
+ { GUID_WICPixelFormat32bppRGB, GUID_WICPixelFormat32bppRGBA }, // DXGI_FORMAT_R8G8B8A8_UNORM\r
+ { GUID_WICPixelFormat64bppRGB, GUID_WICPixelFormat64bppRGBA }, // DXGI_FORMAT_R16G16B16A16_UNORM\r
+ { GUID_WICPixelFormat64bppPRGBAHalf, GUID_WICPixelFormat64bppRGBAHalf }, // DXGI_FORMAT_R16G16B16A16_FLOAT \r
+#endif\r
+\r
+ // We don't support n-channel formats\r
+};\r
+\r
+//--------------------------------------------------------------------------------------\r
+static IWICImagingFactory* _GetWIC()\r
+{\r
+ static IWICImagingFactory* s_Factory = nullptr;\r
+\r
+ if (s_Factory)\r
+ return s_Factory;\r
+\r
+ HRESULT hr = CoCreateInstance(\r
+ CLSID_WICImagingFactory,\r
+ nullptr,\r
+ CLSCTX_INPROC_SERVER,\r
+ __uuidof(IWICImagingFactory),\r
+ (LPVOID*)&s_Factory\r
+ );\r
+\r
+ if (FAILED(hr))\r
+ {\r
+ s_Factory = nullptr;\r
+ return nullptr;\r
+ }\r
+\r
+ return s_Factory;\r
+}\r
+\r
+//---------------------------------------------------------------------------------\r
+static DXGI_FORMAT _WICToDXGI(const GUID& guid)\r
+{\r
+ for (size_t i = 0; i < _countof(g_WICFormats); ++i)\r
+ {\r
+ if (memcmp(&g_WICFormats[i].wic, &guid, sizeof(GUID)) == 0)\r
+ return g_WICFormats[i].format;\r
+ }\r
+\r
+ return DXGI_FORMAT_UNKNOWN;\r
+}\r
+\r
+//---------------------------------------------------------------------------------\r
+static size_t _WICBitsPerPixel(REFGUID targetGuid)\r
+{\r
+ IWICImagingFactory* pWIC = _GetWIC();\r
+ if (!pWIC)\r
+ return 0;\r
+\r
+ ScopedObject<IWICComponentInfo> cinfo;\r
+ if (FAILED(pWIC->CreateComponentInfo(targetGuid, &cinfo)))\r
+ return 0;\r
+\r
+ WICComponentType type;\r
+ if (FAILED(cinfo->GetComponentType(&type)))\r
+ return 0;\r
+\r
+ if (type != WICPixelFormat)\r
+ return 0;\r
+\r
+ ScopedObject<IWICPixelFormatInfo> pfinfo;\r
+ if (FAILED(cinfo->QueryInterface(__uuidof(IWICPixelFormatInfo), reinterpret_cast<void**>(&pfinfo))))\r
+ return 0;\r
+\r
+ UINT bpp;\r
+ if (FAILED(pfinfo->GetBitsPerPixel(&bpp)))\r
+ return 0;\r
+\r
+ return bpp;\r
+}\r
+\r
+//---------------------------------------------------------------------------------\r
+static HRESULT CreateTextureFromWIC(_In_ ID3D11Device* d3dDevice,\r
+ _In_opt_ ID3D11DeviceContext* d3dContext,\r
+ _In_ IWICBitmapFrameDecode *frame,\r
+ _Out_opt_ ID3D11Resource** texture,\r
+ _Out_opt_ ID3D11ShaderResourceView** textureView,\r
+ _In_ size_t maxsize)\r
+{\r
+ UINT width, height;\r
+ HRESULT hr = frame->GetSize(&width, &height);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ assert(width > 0 && height > 0);\r
+\r
+ if (!maxsize)\r
+ {\r
+ // This is a bit conservative because the hardware could support larger textures than\r
+ // the Feature Level defined minimums, but doing it this way is much easier and more\r
+ // performant for WIC than the 'fail and retry' model used by DDSTextureLoader\r
+\r
+ switch (d3dDevice->GetFeatureLevel())\r
+ {\r
+ case D3D_FEATURE_LEVEL_9_1:\r
+ case D3D_FEATURE_LEVEL_9_2:\r
+ maxsize = 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;\r
+ break;\r
+\r
+ case D3D_FEATURE_LEVEL_9_3:\r
+ maxsize = 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;\r
+ break;\r
+\r
+ case D3D_FEATURE_LEVEL_10_0:\r
+ case D3D_FEATURE_LEVEL_10_1:\r
+ maxsize = 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;\r
+ break;\r
+\r
+ default:\r
+ maxsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;\r
+ break;\r
+ }\r
+ }\r
+\r
+ assert(maxsize > 0);\r
+\r
+ UINT twidth, theight;\r
+ if (width > maxsize || height > maxsize)\r
+ {\r
+ float ar = static_cast<float>(height) / static_cast<float>(width);\r
+ if (width > height)\r
+ {\r
+ twidth = static_cast<UINT>(maxsize);\r
+ theight = static_cast<UINT>(static_cast<float>(maxsize) * ar);\r
+ }\r
+ else\r
+ {\r
+ theight = static_cast<UINT>(maxsize);\r
+ twidth = static_cast<UINT>(static_cast<float>(maxsize) / ar);\r
+ }\r
+ assert(twidth <= maxsize && theight <= maxsize);\r
+ }\r
+ else\r
+ {\r
+ twidth = width;\r
+ theight = height;\r
+ }\r
+\r
+ // Determine format\r
+ WICPixelFormatGUID pixelFormat;\r
+ hr = frame->GetPixelFormat(&pixelFormat);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ WICPixelFormatGUID convertGUID;\r
+ memcpy(&convertGUID, &pixelFormat, sizeof(WICPixelFormatGUID));\r
+\r
+ size_t bpp = 0;\r
+\r
+ DXGI_FORMAT format = _WICToDXGI(pixelFormat);\r
+ if (format == DXGI_FORMAT_UNKNOWN)\r
+ {\r
+ for (size_t i = 0; i < _countof(g_WICConvert); ++i)\r
+ {\r
+ if (memcmp(&g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID)) == 0)\r
+ {\r
+ memcpy(&convertGUID, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID));\r
+\r
+ format = _WICToDXGI(g_WICConvert[i].target);\r
+ assert(format != DXGI_FORMAT_UNKNOWN);\r
+ bpp = _WICBitsPerPixel(convertGUID);\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (format == DXGI_FORMAT_UNKNOWN)\r
+ return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);\r
+ }\r
+ else\r
+ {\r
+ bpp = _WICBitsPerPixel(pixelFormat);\r
+ }\r
+\r
+ if (!bpp)\r
+ return E_FAIL;\r
+\r
+ // Verify our target format is supported by the current device\r
+ // (handles WDDM 1.0 or WDDM 1.1 device driver cases as well as DirectX 11.0 Runtime without 16bpp format support)\r
+ UINT support = 0;\r
+ hr = d3dDevice->CheckFormatSupport(format, &support);\r
+ if (FAILED(hr) || !(support & D3D11_FORMAT_SUPPORT_TEXTURE2D))\r
+ {\r
+ // Fallback to RGBA 32-bit format which is supported by all devices\r
+ memcpy(&convertGUID, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID));\r
+ format = DXGI_FORMAT_R8G8B8A8_UNORM;\r
+ bpp = 32;\r
+ }\r
+\r
+ // Allocate temporary memory for image\r
+ size_t rowPitch = (twidth * bpp + 7) / 8;\r
+ size_t imageSize = rowPitch * theight;\r
+\r
+ std::unique_ptr<uint8_t[]> temp(new uint8_t[imageSize]);\r
+\r
+ // Load image data\r
+ if (memcmp(&convertGUID, &pixelFormat, sizeof(GUID)) == 0\r
+ && twidth == width\r
+ && theight == height)\r
+ {\r
+ // No format conversion or resize needed\r
+ hr = frame->CopyPixels(0, static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize), temp.get());\r
+ if (FAILED(hr))\r
+ return hr;\r
+ }\r
+ else if (twidth != width || theight != height)\r
+ {\r
+ // Resize\r
+ IWICImagingFactory* pWIC = _GetWIC();\r
+ if (!pWIC)\r
+ return E_NOINTERFACE;\r
+\r
+ ScopedObject<IWICBitmapScaler> scaler;\r
+ hr = pWIC->CreateBitmapScaler(&scaler);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = scaler->Initialize(frame, twidth, theight, WICBitmapInterpolationModeFant);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ WICPixelFormatGUID pfScaler;\r
+ hr = scaler->GetPixelFormat(&pfScaler);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ if (memcmp(&convertGUID, &pfScaler, sizeof(GUID)) == 0)\r
+ {\r
+ // No format conversion needed\r
+ hr = scaler->CopyPixels(0, static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize), temp.get());\r
+ if (FAILED(hr))\r
+ return hr;\r
+ }\r
+ else\r
+ {\r
+ ScopedObject<IWICFormatConverter> FC;\r
+ hr = pWIC->CreateFormatConverter(&FC);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = FC->Initialize(scaler.Get(), convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = FC->CopyPixels(0, static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize), temp.get());\r
+ if (FAILED(hr))\r
+ return hr;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // Format conversion but no resize\r
+ IWICImagingFactory* pWIC = _GetWIC();\r
+ if (!pWIC)\r
+ return E_NOINTERFACE;\r
+\r
+ ScopedObject<IWICFormatConverter> FC;\r
+ hr = pWIC->CreateFormatConverter(&FC);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = FC->Initialize(frame, convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = FC->CopyPixels(0, static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize), temp.get());\r
+ if (FAILED(hr))\r
+ return hr;\r
+ }\r
+\r
+ // See if format is supported for auto-gen mipmaps (varies by feature level)\r
+ bool autogen = false;\r
+ if (d3dContext != 0 && textureView != 0) // Must have context and shader-view to auto generate mipmaps\r
+ {\r
+ UINT fmtSupport = 0;\r
+ hr = d3dDevice->CheckFormatSupport(format, &fmtSupport);\r
+ if (SUCCEEDED(hr) && (fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN))\r
+ {\r
+ autogen = true;\r
+ }\r
+ }\r
+\r
+ // Create texture\r
+ D3D11_TEXTURE2D_DESC desc;\r
+ desc.Width = twidth;\r
+ desc.Height = theight;\r
+ desc.MipLevels = (autogen) ? 0 : 1;\r
+ desc.ArraySize = 1;\r
+ desc.Format = format;\r
+ desc.SampleDesc.Count = 1;\r
+ desc.SampleDesc.Quality = 0;\r
+ desc.Usage = D3D11_USAGE_DEFAULT;\r
+ desc.BindFlags = (autogen) ? (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET) : (D3D11_BIND_SHADER_RESOURCE);\r
+ desc.CPUAccessFlags = 0;\r
+ desc.MiscFlags = (autogen) ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0;\r
+\r
+ D3D11_SUBRESOURCE_DATA initData;\r
+ initData.pSysMem = temp.get();\r
+ initData.SysMemPitch = static_cast<UINT>(rowPitch);\r
+ initData.SysMemSlicePitch = static_cast<UINT>(imageSize);\r
+\r
+ ID3D11Texture2D* tex = nullptr;\r
+ hr = d3dDevice->CreateTexture2D(&desc, (autogen) ? nullptr : &initData, &tex);\r
+ if (SUCCEEDED(hr) && tex != 0)\r
+ {\r
+ if (textureView != 0)\r
+ {\r
+ D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;\r
+ memset(&SRVDesc, 0, sizeof(SRVDesc));\r
+ SRVDesc.Format = format;\r
+ SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;\r
+ SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1;\r
+\r
+ hr = d3dDevice->CreateShaderResourceView(tex, &SRVDesc, textureView);\r
+ if (FAILED(hr))\r
+ {\r
+ tex->Release();\r
+ return hr;\r
+ }\r
+\r
+ if (autogen)\r
+ {\r
+ assert(d3dContext != 0);\r
+ d3dContext->UpdateSubresource(tex, 0, nullptr, temp.get(), static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize));\r
+ d3dContext->GenerateMips(*textureView);\r
+ }\r
+ }\r
+\r
+ if (texture != 0)\r
+ {\r
+ *texture = tex;\r
+ }\r
+ else\r
+ {\r
+#if defined(_DEBUG) || defined(PROFILE)\r
+ tex->SetPrivateData(WKPDID_D3DDebugObjectName,\r
+ sizeof("WICTextureLoader") - 1,\r
+ "WICTextureLoader"\r
+ );\r
+#endif\r
+ tex->Release();\r
+ }\r
+ }\r
+\r
+ return hr;\r
+}\r
+\r
+//--------------------------------------------------------------------------------------\r
+HRESULT CreateWICTextureFromMemory(_In_ ID3D11Device* d3dDevice,\r
+ _In_opt_ ID3D11DeviceContext* d3dContext,\r
+ _In_bytecount_(wicDataSize) const uint8_t* wicData,\r
+ _In_ size_t wicDataSize,\r
+ _Out_opt_ ID3D11Resource** texture,\r
+ _Out_opt_ ID3D11ShaderResourceView** textureView,\r
+ _In_ size_t maxsize\r
+)\r
+{\r
+ if (!d3dDevice || !wicData || (!texture && !textureView))\r
+ {\r
+ return E_INVALIDARG;\r
+ }\r
+\r
+ if (!wicDataSize)\r
+ {\r
+ return E_FAIL;\r
+ }\r
+\r
+#ifdef _M_AMD64\r
+ if (wicDataSize > 0xFFFFFFFF)\r
+ return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);\r
+#endif\r
+\r
+ IWICImagingFactory* pWIC = _GetWIC();\r
+ if (!pWIC)\r
+ return E_NOINTERFACE;\r
+\r
+ // Create input stream for memory\r
+ ScopedObject<IWICStream> stream;\r
+ HRESULT hr = pWIC->CreateStream(&stream);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = stream->InitializeFromMemory(const_cast<uint8_t*>(wicData), static_cast<DWORD>(wicDataSize));\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ // Initialize WIC\r
+ ScopedObject<IWICBitmapDecoder> decoder;\r
+ hr = pWIC->CreateDecoderFromStream(stream.Get(), 0, WICDecodeMetadataCacheOnDemand, &decoder);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ ScopedObject<IWICBitmapFrameDecode> frame;\r
+ hr = decoder->GetFrame(0, &frame);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = CreateTextureFromWIC(d3dDevice, d3dContext, frame.Get(), texture, textureView, maxsize);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+#if defined(_DEBUG) || defined(PROFILE)\r
+ if (texture != 0 && *texture != 0)\r
+ {\r
+ (*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,\r
+ sizeof("WICTextureLoader") - 1,\r
+ "WICTextureLoader"\r
+ );\r
+ }\r
+\r
+ if (textureView != 0 && *textureView != 0)\r
+ {\r
+ (*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,\r
+ sizeof("WICTextureLoader") - 1,\r
+ "WICTextureLoader"\r
+ );\r
+ }\r
+#endif\r
+\r
+ return hr;\r
+}\r
+\r
+//--------------------------------------------------------------------------------------\r
+HRESULT CreateWICTextureFromFile(_In_ ID3D11Device* d3dDevice,\r
+ _In_opt_ ID3D11DeviceContext* d3dContext,\r
+ _In_z_ const wchar_t* fileName,\r
+ _Out_opt_ ID3D11Resource** texture,\r
+ _Out_opt_ ID3D11ShaderResourceView** textureView,\r
+ _In_ size_t maxsize)\r
+{\r
+ if (!d3dDevice || !fileName || (!texture && !textureView))\r
+ {\r
+ return E_INVALIDARG;\r
+ }\r
+\r
+ IWICImagingFactory* pWIC = _GetWIC();\r
+ if (!pWIC)\r
+ return E_NOINTERFACE;\r
+\r
+ // Initialize WIC\r
+ ScopedObject<IWICBitmapDecoder> decoder;\r
+ HRESULT hr = pWIC->CreateDecoderFromFilename(fileName, 0, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &decoder);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ ScopedObject<IWICBitmapFrameDecode> frame;\r
+ hr = decoder->GetFrame(0, &frame);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+ hr = CreateTextureFromWIC(d3dDevice, d3dContext, frame.Get(), texture, textureView, maxsize);\r
+ if (FAILED(hr))\r
+ return hr;\r
+\r
+#if defined(_DEBUG) || defined(PROFILE)\r
+ if (texture != 0 || textureView != 0)\r
+ {\r
+ CHAR strFileA[MAX_PATH];\r
+ WideCharToMultiByte(CP_ACP,\r
+ WC_NO_BEST_FIT_CHARS,\r
+ fileName,\r
+ -1,\r
+ strFileA,\r
+ MAX_PATH,\r
+ nullptr,\r
+ FALSE\r
+ );\r
+ const CHAR* pstrName = strrchr(strFileA, '\\');\r
+ if (!pstrName)\r
+ {\r
+ pstrName = strFileA;\r
+ }\r
+ else\r
+ {\r
+ pstrName++;\r
+ }\r
+\r
+ if (texture != 0 && *texture != 0)\r
+ {\r
+ (*texture)->SetPrivateData(WKPDID_D3DDebugObjectName,\r
+ static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),\r
+ pstrName\r
+ );\r
+ }\r
+\r
+ if (textureView != 0 && *textureView != 0)\r
+ {\r
+ (*textureView)->SetPrivateData(WKPDID_D3DDebugObjectName,\r
+ static_cast<UINT>(strnlen_s(pstrName, MAX_PATH)),\r
+ pstrName\r
+ );\r
+ }\r
+ }\r
+#endif\r
+\r
+ return hr;\r
+}\r
--- /dev/null
+//--------------------------------------------------------------------------------------\r
+// File: WICTextureLoader.h\r
+//\r
+// Function for loading a WIC image and creating a Direct3D 11 runtime texture for it\r
+// (auto-generating mipmaps if possible)\r
+//\r
+// Note: Assumes application has already called CoInitializeEx\r
+//\r
+// Warning: CreateWICTexture* functions are not thread-safe if given a d3dContext instance for\r
+// auto-gen mipmap support.\r
+//\r
+// Note these functions are useful for images created as simple 2D textures. For\r
+// more complex resources, DDSTextureLoader is an excellent light-weight runtime loader.\r
+// For a full-featured DDS file reader, writer, and texture processing pipeline see\r
+// the 'Texconv' sample and the 'DirectXTex' library.\r
+//\r
+// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF\r
+// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO\r
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A\r
+// PARTICULAR PURPOSE.\r
+//\r
+// Copyright (c) Microsoft Corporation. All rights reserved.\r
+//\r
+// http://go.microsoft.com/fwlink/?LinkId=248926\r
+// http://go.microsoft.com/fwlink/?LinkId=248929\r
+//--------------------------------------------------------------------------------------\r
+\r
+#ifdef _MSC_VER\r
+#pragma once\r
+#endif\r
+\r
+#include <d3d11.h>\r
+\r
+#pragma warning(push)\r
+#pragma warning(disable : 4005)\r
+#include <stdint.h>\r
+#pragma warning(pop)\r
+\r
+HRESULT CreateWICTextureFromMemory(_In_ ID3D11Device* d3dDevice,\r
+ _In_opt_ ID3D11DeviceContext* d3dContext,\r
+ _In_bytecount_(wicDataSize) const uint8_t* wicData,\r
+ _In_ size_t wicDataSize,\r
+ _Out_opt_ ID3D11Resource** texture,\r
+ _Out_opt_ ID3D11ShaderResourceView** textureView,\r
+ _In_ size_t maxsize = 0\r
+);\r
+\r
+HRESULT CreateWICTextureFromFile(_In_ ID3D11Device* d3dDevice,\r
+ _In_opt_ ID3D11DeviceContext* d3dContext,\r
+ _In_z_ const wchar_t* szFileName,\r
+ _Out_opt_ ID3D11Resource** texture,\r
+ _Out_opt_ ID3D11ShaderResourceView** textureView,\r
+ _In_ size_t maxsize = 0\r
+);\r
+\r
--- /dev/null
+cbuffer ConstantBuffer : register(b0)\r
+{\r
+ matrix World;\r
+ matrix View;\r
+ matrix Projection;\r
+}\r
+\r
+struct VOut {\r
+ float4 pos : SV_POSITION;\r
+ float2 texcoord : TEXCOORD;\r
+};\r
+\r
+VOut main(float4 pos : POSITION, float2 texcoord : TEXCOORD)\r
+{\r
+ VOut output;\r
+\r
+ output.pos = mul(pos, World);\r
+ output.pos = mul(output.pos, View);\r
+ output.pos = mul(output.pos, Projection);\r
+ output.texcoord = texcoord;\r
+\r
+ return output;\r
+}
\ No newline at end of file
-
+// ---------------------------------------------------------------------------\r
+// Simple Assimp Directx11 Sample\r
+// This is a very basic sample and only reads diffuse texture\r
+// but this can load both embedded textures in fbx and non-embedded textures\r
+//\r
+//\r
+// Replace ourModel->Load(hwnd, dev, devcon, "Models/myModel.fbx") this with your\r
+// model name (line 480)\r
+// If your model isn't a fbx with embedded textures make sure your model's\r
+// textures are in same directory as your model\r
+//\r
+//\r
+// Written by IAS. :)\r
+// ---------------------------------------------------------------------------\r
+\r
+#include <Windows.h>\r
+#include <windowsx.h>\r
+#include <d3d11_1.h>\r
+#include <dxgi1_2.h>\r
+#include <DirectXMath.h>\r
+#include <d3dcompiler.h>\r
+#include "ModelLoader.h"\r
+\r
+#pragma comment (lib, "d3d11.lib")\r
+#pragma comment (lib, "Dxgi.lib")\r
+#pragma comment(lib,"d3dcompiler.lib")\r
+#pragma comment (lib, "dxguid.lib")\r
+\r
+using namespace DirectX;\r
+\r
+// ------------------------------------------------------------\r
+// Structs\r
+// ------------------------------------------------------------\r
+struct ConstantBuffer {\r
+ XMMATRIX mWorld;\r
+ XMMATRIX mView;\r
+ XMMATRIX mProjection;\r
+};\r
+\r
+// ------------------------------------------------------------\r
+// Window Variables\r
+// ------------------------------------------------------------\r
+#define SCREEN_WIDTH 800\r
+#define SCREEN_HEIGHT 600\r
+\r
+const char g_szClassName[] = "directxWindowClass";\r
+\r
+\r
+UINT width, height;\r
+HWND hwnd;\r
+\r
+// ------------------------------------------------------------\r
+// DirectX Variables\r
+// ------------------------------------------------------------\r
+D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;\r
+D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;\r
+ID3D11Device *dev;\r
+ID3D11Device1 *dev1;\r
+ID3D11DeviceContext *devcon;\r
+ID3D11DeviceContext1 *devcon1;\r
+IDXGISwapChain *swapchain;\r
+IDXGISwapChain1 *swapchain1;\r
+ID3D11RenderTargetView *backbuffer;\r
+ID3D11VertexShader *pVS;\r
+ID3D11PixelShader *pPS;\r
+ID3D11InputLayout *pLayout;\r
+ID3D11Buffer *pConstantBuffer;\r
+ID3D11Texture2D *g_pDepthStencil;\r
+ID3D11DepthStencilView *g_pDepthStencilView;\r
+ID3D11SamplerState *TexSamplerState;\r
+\r
+XMMATRIX m_World;\r
+XMMATRIX m_View;\r
+XMMATRIX m_Projection;\r
+\r
+// ------------------------------------------------------------\r
+// Function identifiers\r
+// ------------------------------------------------------------\r
+\r
+void InitD3D(HINSTANCE hinstance, HWND hWnd);\r
+void CleanD3D(void);\r
+void RenderFrame(void);\r
+\r
+void InitPipeline();\r
+void InitGraphics();\r
+\r
+HRESULT CompileShaderFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefines, LPCSTR pEntryPoint, LPCSTR pShaderModel, ID3DBlob** ppBytecodeBlob);\r
+void Throwanerror(LPCSTR errormessage);\r
+\r
+// ------------------------------------------------------------\r
+// Our Model\r
+// ------------------------------------------------------------\r
+\r
+ModelLoader *ourModel;\r
+\r
+LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)\r
+{\r
+ switch (msg)\r
+ {\r
+ case WM_CLOSE:\r
+ DestroyWindow(hwnd);\r
+ break;\r
+ case WM_DESTROY:\r
+ PostQuitMessage(0);\r
+ break;\r
+ default:\r
+ return DefWindowProc(hwnd, msg, wParam, lParam);\r
+ }\r
+ return 0;\r
+}\r
+\r
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,\r
+ LPSTR lpCmdLine, int nCmdShow)\r
+{\r
+ WNDCLASSEX wc;\r
+ MSG msg;\r
+\r
+ wc.cbSize = sizeof(WNDCLASSEX);\r
+ wc.style = 0;\r
+ wc.lpfnWndProc = WndProc;\r
+ wc.cbClsExtra = 0;\r
+ wc.cbWndExtra = 0;\r
+ wc.hInstance = hInstance;\r
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);\r
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);\r
+ wc.hbrBackground = NULL;\r
+ wc.lpszMenuName = NULL;\r
+ wc.lpszClassName = g_szClassName;\r
+ wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);\r
+\r
+ if (!RegisterClassEx(&wc))\r
+ {\r
+ MessageBox(NULL, "Window Registration Failed!", "Error!",\r
+ MB_ICONEXCLAMATION | MB_OK);\r
+ return 0;\r
+ }\r
+\r
+ RECT wr = { 0,0, SCREEN_WIDTH, SCREEN_HEIGHT };\r
+ AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);\r
+\r
+ hwnd = CreateWindowEx(\r
+ WS_EX_CLIENTEDGE,\r
+ g_szClassName,\r
+ " Simple Textured Directx11 Sample ",\r
+ WS_OVERLAPPEDWINDOW,\r
+ CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top,\r
+ NULL, NULL, hInstance, NULL\r
+ );\r
+\r
+ if (hwnd == NULL)\r
+ {\r
+ MessageBox(NULL, "Window Creation Failed!", "Error!",\r
+ MB_ICONEXCLAMATION | MB_OK);\r
+ return 0;\r
+ }\r
+\r
+ ShowWindow(hwnd, nCmdShow);\r
+ UpdateWindow(hwnd);\r
+\r
+ width = wr.right - wr.left;\r
+ height = wr.bottom - wr.top;\r
+\r
+ InitD3D(hInstance, hwnd);\r
+\r
+ while (true)\r
+ {\r
+\r
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))\r
+ {\r
+ TranslateMessage(&msg);\r
+ DispatchMessage(&msg);\r
+\r
+ if (msg.message == WM_QUIT)\r
+ break;\r
+ }\r
+\r
+ RenderFrame();\r
+ }\r
+\r
+ CleanD3D();\r
+\r
+ return msg.wParam;\r
+}\r
+\r
+void InitD3D(HINSTANCE hinstance, HWND hWnd)\r
+{\r
+ HRESULT hr;\r
+\r
+ UINT createDeviceFlags = 0;\r
+#ifdef _DEBUG\r
+ createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;\r
+#endif\r
+\r
+ D3D_DRIVER_TYPE driverTypes[] =\r
+ {\r
+ D3D_DRIVER_TYPE_HARDWARE,\r
+ D3D_DRIVER_TYPE_WARP,\r
+ D3D_DRIVER_TYPE_REFERENCE,\r
+ };\r
+ UINT numDriverTypes = ARRAYSIZE(driverTypes);\r
+\r
+ D3D_FEATURE_LEVEL featureLevels[] =\r
+ {\r
+ D3D_FEATURE_LEVEL_11_1,\r
+ D3D_FEATURE_LEVEL_11_0,\r
+ D3D_FEATURE_LEVEL_10_1,\r
+ D3D_FEATURE_LEVEL_10_0,\r
+ };\r
+ UINT numFeatureLevels = ARRAYSIZE(featureLevels);\r
+\r
+ for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)\r
+ {\r
+ g_driverType = driverTypes[driverTypeIndex];\r
+ hr = D3D11CreateDevice(nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,\r
+ D3D11_SDK_VERSION, &dev, &g_featureLevel, &devcon);\r
+\r
+ if (hr == E_INVALIDARG)\r
+ {\r
+ // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it\r
+ hr = D3D11CreateDevice(nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1,\r
+ D3D11_SDK_VERSION, &dev, &g_featureLevel, &devcon);\r
+ }\r
+\r
+ if (SUCCEEDED(hr))\r
+ break;\r
+ }\r
+ if (FAILED(hr))\r
+ Throwanerror("Directx Device Creation Failed!");\r
+\r
+ UINT m4xMsaaQuality;\r
+ dev->CheckMultisampleQualityLevels(\r
+ DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);\r
+\r
+\r
+ // Obtain DXGI factory from device (since we used nullptr for pAdapter above)\r
+ IDXGIFactory1* dxgiFactory = nullptr;\r
+ {\r
+ IDXGIDevice* dxgiDevice = nullptr;\r
+ hr = dev->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice));\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ IDXGIAdapter* adapter = nullptr;\r
+ hr = dxgiDevice->GetAdapter(&adapter);\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory));\r
+ adapter->Release();\r
+ }\r
+ dxgiDevice->Release();\r
+ }\r
+ }\r
+ if (FAILED(hr))\r
+ Throwanerror("DXGI Factory couldn't be obtained!");\r
+\r
+ // Create swap chain\r
+ IDXGIFactory2* dxgiFactory2 = nullptr;\r
+ hr = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2));\r
+ if (dxgiFactory2)\r
+ {\r
+ // DirectX 11.1 or later\r
+ hr = dev->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&dev1));\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ (void)devcon->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&devcon1));\r
+ }\r
+\r
+ DXGI_SWAP_CHAIN_DESC1 sd;\r
+ ZeroMemory(&sd, sizeof(sd));\r
+ sd.Width = SCREEN_WIDTH;\r
+ sd.Height = SCREEN_HEIGHT;\r
+ sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;\r
+ sd.SampleDesc.Count = 4;\r
+ sd.SampleDesc.Quality = m4xMsaaQuality - 1;\r
+ sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;\r
+ sd.BufferCount = 1;\r
+\r
+ hr = dxgiFactory2->CreateSwapChainForHwnd(dev, hWnd, &sd, nullptr, nullptr, &swapchain1);\r
+ if (SUCCEEDED(hr))\r
+ {\r
+ hr = swapchain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&swapchain));\r
+ }\r
+\r
+ dxgiFactory2->Release();\r
+ }\r
+ else\r
+ {\r
+ // DirectX 11.0 systems\r
+ DXGI_SWAP_CHAIN_DESC sd;\r
+ ZeroMemory(&sd, sizeof(sd));\r
+ sd.BufferCount = 1;\r
+ sd.BufferDesc.Width = SCREEN_WIDTH;\r
+ sd.BufferDesc.Height = SCREEN_HEIGHT;\r
+ sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;\r
+ sd.BufferDesc.RefreshRate.Numerator = 60;\r
+ sd.BufferDesc.RefreshRate.Denominator = 1;\r
+ sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;\r
+ sd.OutputWindow = hWnd;\r
+ sd.SampleDesc.Count = 1;\r
+ sd.SampleDesc.Quality = m4xMsaaQuality - 1;\r
+ sd.Windowed = TRUE;\r
+\r
+ hr = dxgiFactory->CreateSwapChain(dev, &sd, &swapchain);\r
+ }\r
+\r
+ // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut\r
+ dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);\r
+\r
+ dxgiFactory->Release();\r
+\r
+ if (FAILED(hr))\r
+ Throwanerror("Swapchain Creation Failed!");\r
+\r
+ ID3D11Texture2D *pBackBuffer;\r
+ swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);\r
+\r
+ dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);\r
+ pBackBuffer->Release();\r
+\r
+ D3D11_TEXTURE2D_DESC descDepth;\r
+ ZeroMemory(&descDepth, sizeof(descDepth));\r
+ descDepth.Width = SCREEN_WIDTH;\r
+ descDepth.Height = SCREEN_HEIGHT;\r
+ descDepth.MipLevels = 1;\r
+ descDepth.ArraySize = 1;\r
+ descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;\r
+ descDepth.SampleDesc.Count = 4;\r
+ descDepth.SampleDesc.Quality = m4xMsaaQuality - 1;\r
+ descDepth.Usage = D3D11_USAGE_DEFAULT;\r
+ descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;\r
+ descDepth.CPUAccessFlags = 0;\r
+ descDepth.MiscFlags = 0;\r
+ hr = dev->CreateTexture2D(&descDepth, nullptr, &g_pDepthStencil);\r
+ if (FAILED(hr))\r
+ Throwanerror("Depth Stencil Texture couldn't be created!");\r
+\r
+ // Create the depth stencil view\r
+ D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;\r
+ ZeroMemory(&descDSV, sizeof(descDSV));\r
+ descDSV.Format = descDepth.Format;\r
+ descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;\r
+ descDSV.Texture2D.MipSlice = 0;\r
+ hr = dev->CreateDepthStencilView(g_pDepthStencil, 0, &g_pDepthStencilView);\r
+ if (FAILED(hr))\r
+ {\r
+ Throwanerror("Depth Stencil View couldn't be created!");\r
+ }\r
+\r
+ devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView);\r
+\r
+ D3D11_RASTERIZER_DESC rasterDesc;\r
+ ID3D11RasterizerState *rasterState;\r
+ rasterDesc.AntialiasedLineEnable = false;\r
+ rasterDesc.CullMode = D3D11_CULL_BACK;\r
+ rasterDesc.DepthBias = 0;\r
+ rasterDesc.DepthBiasClamp = 0.0f;\r
+ rasterDesc.DepthClipEnable = true;\r
+ rasterDesc.FillMode = D3D11_FILL_SOLID;\r
+ rasterDesc.FrontCounterClockwise = false;\r
+ rasterDesc.MultisampleEnable = false;\r
+ rasterDesc.ScissorEnable = false;\r
+ rasterDesc.SlopeScaledDepthBias = 0.0f;\r
+\r
+ dev->CreateRasterizerState(&rasterDesc, &rasterState);\r
+ devcon->RSSetState(rasterState);\r
+\r
+ D3D11_VIEWPORT viewport;\r
+ ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));\r
+\r
+ viewport.TopLeftX = 0;\r
+ viewport.TopLeftY = 0;\r
+ viewport.MinDepth = 0.0f;\r
+ viewport.MaxDepth = 1.0f;\r
+ viewport.Width = SCREEN_WIDTH;\r
+ viewport.Height = SCREEN_HEIGHT;\r
+\r
+ devcon->RSSetViewports(1, &viewport);\r
+\r
+ InitPipeline();\r
+ InitGraphics();\r
+}\r
+\r
+void CleanD3D(void)\r
+{\r
+ swapchain->SetFullscreenState(FALSE, NULL);\r
+\r
+ ourModel->Close();\r
+ g_pDepthStencil->Release();\r
+ g_pDepthStencilView->Release();\r
+ pLayout->Release();\r
+ pVS->Release();\r
+ pPS->Release();\r
+ pConstantBuffer->Release();\r
+ swapchain->Release();\r
+ backbuffer->Release();\r
+ dev->Release();\r
+ devcon->Release();\r
+}\r
+\r
+void RenderFrame(void)\r
+{\r
+ static float t = 0.0f;\r
+ static ULONGLONG timeStart = 0;\r
+ ULONGLONG timeCur = GetTickCount64();\r
+ if (timeStart == 0)\r
+ timeStart = timeCur;\r
+ t = (timeCur - timeStart) / 1000.0f;\r
+\r
+ float clearColor[4] = { 0.0f, 0.2f, 0.4f, 1.0f };\r
+ devcon->ClearRenderTargetView(backbuffer, clearColor);\r
+ devcon->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);\r
+\r
+ devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);\r
+\r
+ m_World = XMMatrixRotationY(-t);\r
+\r
+ ConstantBuffer cb;\r
+ cb.mWorld = XMMatrixTranspose(m_World);\r
+ cb.mView = XMMatrixTranspose(m_View);\r
+ cb.mProjection = XMMatrixTranspose(m_Projection);\r
+ devcon->UpdateSubresource(pConstantBuffer, 0, nullptr, &cb, 0, 0);\r
+\r
+ devcon->VSSetShader(pVS, 0, 0);\r
+ devcon->VSSetConstantBuffers(0, 1, &pConstantBuffer);\r
+ devcon->PSSetShader(pPS, 0, 0);\r
+ devcon->PSSetSamplers(0, 1, &TexSamplerState);\r
+ ourModel->Draw(devcon);\r
+\r
+ swapchain->Present(0, 0);\r
+}\r
+\r
+void InitPipeline()\r
+{\r
+ ID3DBlob *VS, *PS;\r
+ CompileShaderFromFile(L"VertexShader.hlsl", 0, "main", "vs_4_0", &VS);\r
+ CompileShaderFromFile(L"PixelShader.hlsl", 0, "main", "ps_4_0", &PS);\r
+\r
+ dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);\r
+ dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);\r
+\r
+ D3D11_INPUT_ELEMENT_DESC ied[] =\r
+ {\r
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },\r
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }\r
+ };\r
+\r
+ dev->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &pLayout);\r
+ devcon->IASetInputLayout(pLayout);\r
+}\r
+\r
+void InitGraphics()\r
+{\r
+ HRESULT hr;\r
+\r
+ m_Projection = XMMatrixPerspectiveFovLH(XM_PIDIV4, SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.01f, 1000.0f);\r
+\r
+ D3D11_BUFFER_DESC bd;\r
+ ZeroMemory(&bd, sizeof(bd));\r
+\r
+ bd.Usage = D3D11_USAGE_DEFAULT;\r
+ bd.ByteWidth = sizeof(ConstantBuffer);\r
+ bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;\r
+ bd.CPUAccessFlags = 0;\r
+\r
+ hr = dev->CreateBuffer(&bd, nullptr, &pConstantBuffer);\r
+ if (FAILED(hr))\r
+ Throwanerror("Constant buffer couldn't be created");\r
+\r
+ D3D11_SAMPLER_DESC sampDesc;\r
+ ZeroMemory(&sampDesc, sizeof(sampDesc));\r
+ sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;\r
+ sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;\r
+ sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;\r
+ sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;\r
+ sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;\r
+ sampDesc.MinLOD = 0;\r
+ sampDesc.MaxLOD = D3D11_FLOAT32_MAX;\r
+\r
+ hr = dev->CreateSamplerState(&sampDesc, &TexSamplerState);\r
+ if (FAILED(hr))\r
+ Throwanerror("Texture sampler state couldn't be created");\r
+\r
+ XMVECTOR Eye = XMVectorSet(0.0f, 5.0f, -300.0f, 0.0f);\r
+ XMVECTOR At = XMVectorSet(0.0f, 100.0f, 0.0f, 0.0f);\r
+ XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);\r
+ m_View = XMMatrixLookAtLH(Eye, At, Up);\r
+\r
+ ourModel = new ModelLoader;\r
+ if (!ourModel->Load(hwnd, dev, devcon, "Models/myModel.fbx"))\r
+ Throwanerror("Model couldn't be loaded");\r
+}\r
+\r
+HRESULT CompileShaderFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefines, LPCSTR pEntryPoint, LPCSTR pShaderModel, ID3DBlob** ppBytecodeBlob)\r
+{\r
+ UINT compileFlags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR;\r
+ \r
+#ifdef _DEBUG\r
+ compileFlags |= D3DCOMPILE_DEBUG;\r
+#endif\r
+\r
+ ID3DBlob* pErrorBlob = NULL;\r
+\r
+ HRESULT result = D3DCompileFromFile(pFileName, pDefines, D3D_COMPILE_STANDARD_FILE_INCLUDE, pEntryPoint, pShaderModel, compileFlags, 0, ppBytecodeBlob, &pErrorBlob);\r
+ if (FAILED(result))\r
+ {\r
+ if (pErrorBlob != NULL)\r
+ OutputDebugStringA((LPCSTR)pErrorBlob->GetBufferPointer());\r
+ }\r
+\r
+ if (pErrorBlob != NULL)\r
+ pErrorBlob->Release();\r
+\r
+ return result;\r
+}\r
+\r
+void Throwanerror(LPCSTR errormessage)\r
+{\r
+ MessageBox(hwnd, errormessage, "Error!", MB_ICONERROR | MB_OK);\r
+}
\ No newline at end of file