Merge pull request #3053 from malortie/fix-simpledirectx11-sample

Fixed SimpleTexturedDirectX11 sample.
pull/3056/head
Kim Kulling 2020-03-07 17:59:24 +01:00 committed by GitHub
commit 1e2c3c9c01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 456 additions and 213 deletions

View File

@ -594,6 +594,8 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
ENDIF ()
IF ( ASSIMP_BUILD_SAMPLES)
SET( SAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/samples )
SET( SAMPLES_SHARED_CODE_DIR ${SAMPLES_DIR}/SharedCode )
IF ( WIN32 )
ADD_SUBDIRECTORY( samples/SimpleTexturedOpenGL/ )
ADD_SUBDIRECTORY( samples/SimpleTexturedDirectx11 )

View File

@ -0,0 +1,52 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UTFConverter.h"
namespace AssimpSamples {
namespace SharedCode {
typename UTFConverter::UTFConverterImpl UTFConverter::impl_;
}
}

View File

@ -0,0 +1,92 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
#define ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H
#include <string>
#include <locale>
#include <codecvt>
namespace AssimpSamples {
namespace SharedCode {
// Used to convert between multibyte and unicode strings.
class UTFConverter {
using UTFConverterImpl = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
public:
UTFConverter(const char* s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const wchar_t* s) :
s_(impl_.to_bytes(s)),
ws_(s) {
}
UTFConverter(const std::string& s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const std::wstring& s) :
s_(impl_.to_bytes(s)),
ws_(s) {
}
inline const char* c_str() const {
return s_.c_str();
}
inline const std::string& str() const {
return s_;
}
inline const wchar_t* c_wstr() const {
return ws_.c_str();
}
private:
static UTFConverterImpl impl_;
std::string s_;
std::wstring ws_;
};
}
}
#endif // ASSIMP_SAMPLES_SHARED_CODE_UTFCONVERTER_H

View File

@ -10,12 +10,12 @@ if ( MSVC )
REMOVE_DEFINITIONS( -DUNICODE -D_UNICODE )
endif ()
ADD_COMPILE_DEFINITIONS(SHADER_PATH="${CMAKE_CURRENT_SOURCE_DIR}/SimpleTexturedDirectx11/")
INCLUDE_DIRECTORIES(
${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code
${OPENGL_INCLUDE_DIR}
${GLUT_INCLUDE_DIR}
${Assimp_SOURCE_DIR}/samples/freeglut/include
${SAMPLES_SHARED_CODE_DIR}
)
LINK_DIRECTORIES(
@ -32,6 +32,9 @@ ADD_EXECUTABLE( assimp_simpletextureddirectx11 WIN32
SimpleTexturedDirectx11/TextureLoader.h
#SimpleTexturedDirectx11/VertexShader.hlsl
SimpleTexturedDirectx11/main.cpp
SimpleTexturedDirectx11/SafeRelease.hpp
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.cpp
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.h
)
SET_PROPERTY(TARGET assimp_simpletextureddirectx11 PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})

View File

@ -6,13 +6,14 @@
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;
#include <vector>
#include <stdexcept>
#include <d3d11_1.h>
#include <DirectXMath.h>
using namespace DirectX;
#include "SafeRelease.hpp"
struct VERTEX {
FLOAT X, Y, Z;
XMFLOAT2 texcoord;
@ -22,81 +23,85 @@ struct Texture {
string type;
string path;
ID3D11ShaderResourceView *texture;
void Release() {
SafeRelease(texture);
}
};
class Mesh {
public:
vector<VERTEX> vertices;
vector<UINT> indices;
vector<Texture> textures;
ID3D11Device *dev;
std::vector<VERTEX> vertices;
std::vector<UINT> indices;
std::vector<Texture> textures;
ID3D11Device *dev;
Mesh(ID3D11Device *dev, vector<VERTEX> vertices, vector<UINT> indices, vector<Texture> textures)
{
this->vertices = vertices;
this->indices = indices;
this->textures = textures;
Mesh(ID3D11Device *dev, const vector<VERTEX>& vertices, const vector<UINT>& indices, const vector<Texture>& textures) :
vertices(vertices),
indices(indices),
textures(textures),
dev(dev),
VertexBuffer(nullptr),
IndexBuffer(nullptr) {
this->setupMesh(this->dev);
}
this->dev = dev;
void Draw(ID3D11DeviceContext *devcon) {
UINT stride = sizeof(VERTEX);
UINT offset = 0;
this->setupMesh(dev);
}
devcon->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
devcon->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
void Draw(ID3D11DeviceContext *devcon)
{
UINT stride = sizeof(VERTEX);
UINT offset = 0;
devcon->PSSetShaderResources(0, 1, &textures[0].texture);
devcon->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
devcon->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->DrawIndexed(static_cast<UINT>(indices.size()), 0, 0);
}
devcon->PSSetShaderResources(0, 1, &textures[0].texture);
devcon->DrawIndexed(indices.size(), 0, 0);
}
void Close()
{
VertexBuffer->Release();
IndexBuffer->Release();
}
void Close() {
SafeRelease(VertexBuffer);
SafeRelease(IndexBuffer);
}
private:
/* Render data */
ID3D11Buffer *VertexBuffer, *IndexBuffer;
// Render data
ID3D11Buffer *VertexBuffer, *IndexBuffer;
/* Functions */
// Initializes all the buffer objects/arrays
bool setupMesh(ID3D11Device *dev)
{
HRESULT hr;
// Functions
// Initializes all the buffer objects/arrays
void setupMesh(ID3D11Device *dev) {
HRESULT hr;
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(VERTEX) * vertices.size();
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = static_cast<UINT>(sizeof(VERTEX) * vertices.size());
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = &vertices[0];
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = &vertices[0];
hr = dev->CreateBuffer(&vbd, &initData, &VertexBuffer);
if (FAILED(hr))
return false;
hr = dev->CreateBuffer(&vbd, &initData, &VertexBuffer);
if (FAILED(hr)) {
Close();
throw std::runtime_error("Failed to create vertex buffer.");
}
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * indices.size();
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = static_cast<UINT>(sizeof(UINT) * indices.size());
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
initData.pSysMem = &indices[0];
initData.pSysMem = &indices[0];
hr = dev->CreateBuffer(&ibd, &initData, &IndexBuffer);
if (FAILED(hr))
return false;
}
hr = dev->CreateBuffer(&ibd, &initData, &IndexBuffer);
if (FAILED(hr)) {
Close();
throw std::runtime_error("Failed to create index buffer.");
}
}
};
#endif

View File

@ -1,16 +1,21 @@
#include "ModelLoader.h"
ModelLoader::ModelLoader()
{
ModelLoader::ModelLoader() :
dev(nullptr),
devcon(nullptr),
meshes(),
directory(),
textures_loaded(),
hwnd(nullptr) {
// empty
}
ModelLoader::~ModelLoader()
{
ModelLoader::~ModelLoader() {
// empty
}
bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devcon, std::string filename)
{
bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devcon, std::string filename) {
Assimp::Importer importer;
const aiScene* pScene = importer.ReadFile(filename,
@ -20,9 +25,10 @@ bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devc
if (pScene == NULL)
return false;
this->directory = filename.substr(0, filename.find_last_of('/'));
this->directory = filename.substr(0, filename.find_last_of("/\\"));
this->dev = dev;
this->devcon = devcon;
this->hwnd = hwnd;
processNode(pScene->mRootNode, pScene);
@ -30,41 +36,37 @@ bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devc
return true;
}
void ModelLoader::Draw(ID3D11DeviceContext * devcon)
{
for (int i = 0; i < meshes.size(); i++)
{
void ModelLoader::Draw(ID3D11DeviceContext * devcon) {
for (int i = 0; i < meshes.size(); ++i ) {
meshes[i].Draw(devcon);
}
}
string textype;
Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene)
{
Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) {
// Data to fill
vector<VERTEX> vertices;
vector<UINT> indices;
vector<Texture> textures;
if (mesh->mMaterialIndex >= 0)
{
if (mesh->mMaterialIndex >= 0) {
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
if (textype.empty()) textype = determineTextureType(scene, mat);
if (textype.empty()) {
textype = determineTextureType(scene, mat);
}
}
// Walk through each of the mesh's vertices
for (UINT i = 0; i < mesh->mNumVertices; i++)
{
for (UINT i = 0; i < mesh->mNumVertices; i++) {
VERTEX vertex;
vertex.X = mesh->mVertices[i].x;
vertex.Y = mesh->mVertices[i].y;
vertex.Z = mesh->mVertices[i].z;
if (mesh->mTextureCoords[0])
{
if (mesh->mTextureCoords[0]) {
vertex.texcoord.x = (float)mesh->mTextureCoords[0][i].x;
vertex.texcoord.y = (float)mesh->mTextureCoords[0][i].y;
}
@ -72,16 +74,14 @@ Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene)
vertices.push_back(vertex);
}
for (UINT i = 0; i < mesh->mNumFaces; i++)
{
for (UINT i = 0; i < mesh->mNumFaces; i++) {
aiFace face = mesh->mFaces[i];
for (UINT j = 0; j < face.mNumIndices; j++)
indices.push_back(face.mIndices[j]);
}
if (mesh->mMaterialIndex >= 0)
{
if (mesh->mMaterialIndex >= 0) {
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse", scene);
@ -91,35 +91,27 @@ Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene)
return Mesh(dev, vertices, indices, textures);
}
vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureType type, string typeName, const aiScene * scene)
{
vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureType type, string typeName, const aiScene * scene) {
vector<Texture> textures;
for (UINT i = 0; i < mat->GetTextureCount(type); i++)
{
for (UINT i = 0; i < mat->GetTextureCount(type); i++) {
aiString str;
mat->GetTexture(type, i, &str);
// Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture
bool skip = false;
for (UINT j = 0; j < textures_loaded.size(); j++)
{
if (std::strcmp(textures_loaded[j].path.c_str(), str.C_Str()) == 0)
{
for (UINT j = 0; j < textures_loaded.size(); j++) {
if (std::strcmp(textures_loaded[j].path.c_str(), str.C_Str()) == 0) {
textures.push_back(textures_loaded[j]);
skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization)
break;
}
}
if (!skip)
{ // If texture hasn't been loaded already, load it
if (!skip) { // If texture hasn't been loaded already, load it
HRESULT hr;
Texture texture;
if (textype == "embedded compressed texture")
{
if (textype == "embedded compressed texture") {
int textureindex = getTextureIndex(&str);
texture.texture = getTextureFromModel(scene, textureindex);
}
else
{
} else {
string filename = string(str.C_Str());
filename = directory + '/' + filename;
wstring filenamews = wstring(filename.begin(), filename.end());
@ -136,64 +128,52 @@ vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureTyp
return textures;
}
void ModelLoader::Close()
{
for (int i = 0; i < meshes.size(); i++)
{
void ModelLoader::Close() {
for (auto& t : textures_loaded)
t.Release();
for (int i = 0; i < meshes.size(); i++) {
meshes[i].Close();
}
dev->Release();
}
void ModelLoader::processNode(aiNode * node, const aiScene * scene)
{
for (UINT i = 0; i < node->mNumMeshes; i++)
{
void ModelLoader::processNode(aiNode * node, const aiScene * scene) {
for (UINT i = 0; i < node->mNumMeshes; i++) {
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
meshes.push_back(this->processMesh(mesh, scene));
}
for (UINT i = 0; i < node->mNumChildren; i++)
{
for (UINT i = 0; i < node->mNumChildren; i++) {
this->processNode(node->mChildren[i], scene);
}
}
string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat)
{
string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat) {
aiString textypeStr;
mat->GetTexture(aiTextureType_DIFFUSE, 0, &textypeStr);
string textypeteststr = textypeStr.C_Str();
if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5")
{
if (scene->mTextures[0]->mHeight == 0)
{
if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5") {
if (scene->mTextures[0]->mHeight == 0) {
return "embedded compressed texture";
}
else
{
} else {
return "embedded non-compressed texture";
}
}
if (textypeteststr.find('.') != string::npos)
{
if (textypeteststr.find('.') != string::npos) {
return "textures are on disk";
}
return ".";
}
int ModelLoader::getTextureIndex(aiString * str)
{
int ModelLoader::getTextureIndex(aiString * str) {
string tistr;
tistr = str->C_Str();
tistr = tistr.substr(1);
return stoi(tistr);
}
ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex)
{
ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex) {
HRESULT hr;
ID3D11ShaderResourceView *texture;

View File

@ -0,0 +1,57 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifdef _MSC_VER
#pragma once
#endif
/* Used to reduce to reduce the number of lines when calling Release()
on a D3D interface. Implemented as a template instead of a 'SAFE_RELEASE'
MACRO to ease debugging. */
template<typename T>
inline void SafeRelease(T*& x) {
if (x) {
x->Release();
x = nullptr;
}
}

View File

@ -14,12 +14,16 @@
// ---------------------------------------------------------------------------
#include <Windows.h>
#include <shellapi.h>
#include <stdexcept>
#include <windowsx.h>
#include <d3d11_1.h>
#include <dxgi1_2.h>
#include <DirectXMath.h>
#include <d3dcompiler.h>
#include "ModelLoader.h"
#include "UTFConverter.h"
#include "SafeRelease.hpp"
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "Dxgi.lib")
@ -27,6 +31,10 @@
#pragma comment (lib, "dxguid.lib")
using namespace DirectX;
using namespace AssimpSamples::SharedCode;
#define VERTEX_SHADER_FILE L"VertexShader.hlsl"
#define PIXEL_SHADER_FILE L"PixelShader.hlsl"
// ------------------------------------------------------------
// Structs
@ -45,29 +53,32 @@ struct ConstantBuffer {
const char g_szClassName[] = "directxWindowClass";
static std::string g_ModelPath;
UINT width, height;
HWND hwnd;
HWND hwnd = nullptr;
// ------------------------------------------------------------
// DirectX Variables
// ------------------------------------------------------------
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device *dev;
ID3D11Device1 *dev1;
ID3D11DeviceContext *devcon;
ID3D11DeviceContext1 *devcon1;
IDXGISwapChain *swapchain;
IDXGISwapChain1 *swapchain1;
ID3D11RenderTargetView *backbuffer;
ID3D11VertexShader *pVS;
ID3D11PixelShader *pPS;
ID3D11InputLayout *pLayout;
ID3D11Buffer *pConstantBuffer;
ID3D11Texture2D *g_pDepthStencil;
ID3D11DepthStencilView *g_pDepthStencilView;
ID3D11SamplerState *TexSamplerState;
ID3D11Device *dev = nullptr;
ID3D11Device1 *dev1 = nullptr;
ID3D11DeviceContext *devcon = nullptr;
ID3D11DeviceContext1 *devcon1 = nullptr;
IDXGISwapChain *swapchain = nullptr;
IDXGISwapChain1 *swapchain1 = nullptr;
ID3D11RenderTargetView *backbuffer = nullptr;
ID3D11VertexShader *pVS = nullptr;
ID3D11PixelShader *pPS = nullptr;
ID3D11InputLayout *pLayout = nullptr;
ID3D11Buffer *pConstantBuffer = nullptr;
ID3D11Texture2D *g_pDepthStencil = nullptr;
ID3D11DepthStencilView *g_pDepthStencilView = nullptr;
ID3D11SamplerState *TexSamplerState = nullptr;
ID3D11RasterizerState *rasterstate = nullptr;
ID3D11Debug* d3d11debug = nullptr;
XMMATRIX m_World;
XMMATRIX m_View;
@ -91,7 +102,7 @@ void Throwanerror(LPCSTR errormessage);
// Our Model
// ------------------------------------------------------------
ModelLoader *ourModel;
ModelLoader *ourModel = nullptr;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
@ -109,9 +120,42 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPWSTR lpCmdLine, int nCmdShow)
{
int argc;
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if (!argv) {
MessageBox(NULL,
TEXT("An error occured while reading command line arguments."),
TEXT("Error!"),
MB_ICONERROR | MB_OK);
return EXIT_FAILURE;
}
// Free memory allocated from CommandLineToArgvW.
auto free_command_line_allocated_memory = [&argv]() {
if (argv) {
LocalFree(argv);
argv = nullptr;
}
};
// Ensure that a model file has been specified.
if (argc < 2) {
MessageBox(NULL,
TEXT("No model file specified. The program will now close."),
TEXT("Error!"),
MB_ICONERROR | MB_OK);
free_command_line_allocated_memory();
return EXIT_FAILURE;
}
// Retrieve the model file path.
g_ModelPath = UTFConverter(argv[1]).str();
free_command_line_allocated_memory();
WNDCLASSEX wc;
MSG msg;
@ -160,26 +204,35 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
width = wr.right - wr.left;
height = wr.bottom - wr.top;
InitD3D(hInstance, hwnd);
try {
InitD3D(hInstance, hwnd);
while (true)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
while (true)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT)
break;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT)
break;
}
RenderFrame();
}
RenderFrame();
CleanD3D();
return static_cast<int>(msg.wParam);
} catch (const std::exception& e) {
MessageBox(hwnd, e.what(), TEXT("Error!"), MB_ICONERROR | MB_OK);
CleanD3D();
return EXIT_FAILURE;
} catch (...) {
MessageBox(hwnd, TEXT("Caught an unknown exception."), TEXT("Error!"), MB_ICONERROR | MB_OK);
CleanD3D();
return EXIT_FAILURE;
}
CleanD3D();
return msg.wParam;
}
void InitD3D(HINSTANCE hinstance, HWND hWnd)
@ -227,6 +280,12 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
if (FAILED(hr))
Throwanerror("Directx Device Creation Failed!");
#if _DEBUG
hr = dev->QueryInterface(IID_PPV_ARGS(&d3d11debug));
if (FAILED(hr))
OutputDebugString(TEXT("Failed to retrieve DirectX 11 debug interface.\n"));
#endif
UINT m4xMsaaQuality;
dev->CheckMultisampleQualityLevels(
DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
@ -348,7 +407,6 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView);
D3D11_RASTERIZER_DESC rasterDesc;
ID3D11RasterizerState *rasterState;
rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_BACK;
rasterDesc.DepthBias = 0;
@ -360,8 +418,8 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;
dev->CreateRasterizerState(&rasterDesc, &rasterState);
devcon->RSSetState(rasterState);
dev->CreateRasterizerState(&rasterDesc, &rasterstate);
devcon->RSSetState(rasterstate);
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
@ -381,19 +439,38 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
void CleanD3D(void)
{
swapchain->SetFullscreenState(FALSE, NULL);
if (swapchain)
swapchain->SetFullscreenState(FALSE, NULL);
ourModel->Close();
g_pDepthStencil->Release();
g_pDepthStencilView->Release();
pLayout->Release();
pVS->Release();
pPS->Release();
pConstantBuffer->Release();
swapchain->Release();
backbuffer->Release();
dev->Release();
devcon->Release();
if (ourModel) {
ourModel->Close();
delete ourModel;
ourModel = nullptr;
}
SafeRelease(TexSamplerState);
SafeRelease(pConstantBuffer);
SafeRelease(pLayout);
SafeRelease(pVS);
SafeRelease(pPS);
SafeRelease(rasterstate);
SafeRelease(g_pDepthStencilView);
SafeRelease(g_pDepthStencil);
SafeRelease(backbuffer);
SafeRelease(swapchain);
SafeRelease(swapchain1);
SafeRelease(devcon1);
SafeRelease(dev1);
SafeRelease(devcon);
#if _DEBUG
if (d3d11debug) {
OutputDebugString(TEXT("Dumping DirectX 11 live objects.\n"));
d3d11debug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL);
SafeRelease(d3d11debug);
} else {
OutputDebugString(TEXT("Unable to dump live objects: no DirectX 11 debug interface available.\n"));
}
#endif
SafeRelease(dev);
}
void RenderFrame(void)
@ -431,8 +508,10 @@ void RenderFrame(void)
void InitPipeline()
{
ID3DBlob *VS, *PS;
CompileShaderFromFile(L"VertexShader.hlsl", 0, "main", "vs_4_0", &VS);
CompileShaderFromFile(L"PixelShader.hlsl", 0, "main", "ps_4_0", &PS);
if(FAILED(CompileShaderFromFile(SHADER_PATH VERTEX_SHADER_FILE, 0, "main", "vs_4_0", &VS)))
Throwanerror(UTFConverter(L"Failed to compile shader from file " VERTEX_SHADER_FILE).c_str());
if(FAILED(CompileShaderFromFile(SHADER_PATH PIXEL_SHADER_FILE, 0, "main", "ps_4_0", &PS)))
Throwanerror(UTFConverter(L"Failed to compile shader from file " PIXEL_SHADER_FILE).c_str());
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
@ -485,7 +564,7 @@ void InitGraphics()
m_View = XMMatrixLookAtLH(Eye, At, Up);
ourModel = new ModelLoader;
if (!ourModel->Load(hwnd, dev, devcon, "Models/myModel.fbx"))
if (!ourModel->Load(hwnd, dev, devcon, g_ModelPath))
Throwanerror("Model couldn't be loaded");
}
@ -514,5 +593,5 @@ HRESULT CompileShaderFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefine
void Throwanerror(LPCSTR errormessage)
{
MessageBox(hwnd, errormessage, "Error!", MB_ICONERROR | MB_OK);
throw std::runtime_error(errormessage);
}

View File

@ -21,6 +21,7 @@ INCLUDE_DIRECTORIES(
${Assimp_SOURCE_DIR}/code
${OPENGL_INCLUDE_DIR}
${GLUT_INCLUDE_DIR}
${SAMPLES_SHARED_CODE_DIR}
)
LINK_DIRECTORIES(
@ -31,6 +32,8 @@ LINK_DIRECTORIES(
ADD_EXECUTABLE( assimp_simpletexturedogl WIN32
SimpleTexturedOpenGL/include/boost_includes.h
SimpleTexturedOpenGL/src/model_loading.cpp
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.cpp
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.h
)
SET_PROPERTY(TARGET assimp_simpletexturedogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})

View File

@ -21,8 +21,6 @@
#define STB_IMAGE_IMPLEMENTATION
#include "contrib/stb_image/stb_image.h"
#include <locale>
#include <codecvt>
#include <fstream>
//to map image filenames to textureIds
@ -35,7 +33,7 @@
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/LogStream.hpp>
#include "UTFConverter.h"
// The default hard-coded path. Can be overridden by supplying a path through the command line.
static std::string modelpath = "../../test/models/OBJ/spider.obj";
@ -77,35 +75,7 @@ GLuint* textureIds; // pointer to texture Array
// Create an instance of the Importer class
Assimp::Importer importer;
// Used to convert between multibyte and unicode strings.
class UTFConverter {
using UTFConverterImpl = std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>;
public:
UTFConverter(const char* s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const std::string& s) :
s_(s),
ws_(impl_.from_bytes(s)) {
}
UTFConverter(const std::wstring& s) :
s_(impl_.to_bytes(s)),
ws_(s) {
}
inline const std::string& str() const {
return s_;
}
inline const wchar_t* c_wstr() const {
return ws_.c_str();
}
private:
static UTFConverterImpl impl_;
std::string s_;
std::wstring ws_;
};
typename UTFConverter::UTFConverterImpl UTFConverter::impl_;
using namespace AssimpSamples::SharedCode;
void createAILogger()
{