Merge branch 'master' into raise-cmake-minimum-version-to-3.0

pull/3033/head
Kim Kulling 2020-03-08 09:06:09 +01:00 committed by GitHub
commit a3ff03f193
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 () ENDIF ()
IF ( ASSIMP_BUILD_SAMPLES) IF ( ASSIMP_BUILD_SAMPLES)
SET( SAMPLES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/samples )
SET( SAMPLES_SHARED_CODE_DIR ${SAMPLES_DIR}/SharedCode )
IF ( WIN32 ) IF ( WIN32 )
ADD_SUBDIRECTORY( samples/SimpleTexturedOpenGL/ ) ADD_SUBDIRECTORY( samples/SimpleTexturedOpenGL/ )
ADD_SUBDIRECTORY( samples/SimpleTexturedDirectx11 ) 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 ) REMOVE_DEFINITIONS( -DUNICODE -D_UNICODE )
endif () endif ()
ADD_COMPILE_DEFINITIONS(SHADER_PATH="${CMAKE_CURRENT_SOURCE_DIR}/SimpleTexturedDirectx11/")
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
${Assimp_SOURCE_DIR}/include ${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code ${Assimp_SOURCE_DIR}/code
${OPENGL_INCLUDE_DIR} ${SAMPLES_SHARED_CODE_DIR}
${GLUT_INCLUDE_DIR}
${Assimp_SOURCE_DIR}/samples/freeglut/include
) )
LINK_DIRECTORIES( LINK_DIRECTORIES(
@ -32,6 +32,9 @@ ADD_EXECUTABLE( assimp_simpletextureddirectx11 WIN32
SimpleTexturedDirectx11/TextureLoader.h SimpleTexturedDirectx11/TextureLoader.h
#SimpleTexturedDirectx11/VertexShader.hlsl #SimpleTexturedDirectx11/VertexShader.hlsl
SimpleTexturedDirectx11/main.cpp 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}) SET_PROPERTY(TARGET assimp_simpletextureddirectx11 PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})

View File

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

View File

@ -1,16 +1,21 @@
#include "ModelLoader.h" #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; Assimp::Importer importer;
const aiScene* pScene = importer.ReadFile(filename, const aiScene* pScene = importer.ReadFile(filename,
@ -20,9 +25,10 @@ bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devc
if (pScene == NULL) if (pScene == NULL)
return false; return false;
this->directory = filename.substr(0, filename.find_last_of('/')); this->directory = filename.substr(0, filename.find_last_of("/\\"));
this->dev = dev; this->dev = dev;
this->devcon = devcon;
this->hwnd = hwnd; this->hwnd = hwnd;
processNode(pScene->mRootNode, pScene); processNode(pScene->mRootNode, pScene);
@ -30,41 +36,37 @@ bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devc
return true; return true;
} }
void ModelLoader::Draw(ID3D11DeviceContext * devcon) void ModelLoader::Draw(ID3D11DeviceContext * devcon) {
{ for (int i = 0; i < meshes.size(); ++i ) {
for (int i = 0; i < meshes.size(); i++)
{
meshes[i].Draw(devcon); meshes[i].Draw(devcon);
} }
} }
string textype; string textype;
Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) {
{
// Data to fill // Data to fill
vector<VERTEX> vertices; vector<VERTEX> vertices;
vector<UINT> indices; vector<UINT> indices;
vector<Texture> textures; vector<Texture> textures;
if (mesh->mMaterialIndex >= 0) if (mesh->mMaterialIndex >= 0) {
{
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex]; 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 // 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 vertex;
vertex.X = mesh->mVertices[i].x; vertex.X = mesh->mVertices[i].x;
vertex.Y = mesh->mVertices[i].y; vertex.Y = mesh->mVertices[i].y;
vertex.Z = mesh->mVertices[i].z; 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.x = (float)mesh->mTextureCoords[0][i].x;
vertex.texcoord.y = (float)mesh->mTextureCoords[0][i].y; 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); 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]; aiFace face = mesh->mFaces[i];
for (UINT j = 0; j < face.mNumIndices; j++) for (UINT j = 0; j < face.mNumIndices; j++)
indices.push_back(face.mIndices[j]); indices.push_back(face.mIndices[j]);
} }
if (mesh->mMaterialIndex >= 0) if (mesh->mMaterialIndex >= 0) {
{
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse", scene); 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); 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; vector<Texture> textures;
for (UINT i = 0; i < mat->GetTextureCount(type); i++) for (UINT i = 0; i < mat->GetTextureCount(type); i++) {
{
aiString str; aiString str;
mat->GetTexture(type, i, &str); mat->GetTexture(type, i, &str);
// Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture // Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture
bool skip = false; bool skip = false;
for (UINT j = 0; j < textures_loaded.size(); j++) for (UINT j = 0; j < textures_loaded.size(); j++) {
{ if (std::strcmp(textures_loaded[j].path.c_str(), str.C_Str()) == 0) {
if (std::strcmp(textures_loaded[j].path.c_str(), str.C_Str()) == 0)
{
textures.push_back(textures_loaded[j]); textures.push_back(textures_loaded[j]);
skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization) skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization)
break; break;
} }
} }
if (!skip) if (!skip) { // If texture hasn't been loaded already, load it
{ // If texture hasn't been loaded already, load it
HRESULT hr; HRESULT hr;
Texture texture; Texture texture;
if (textype == "embedded compressed texture") if (textype == "embedded compressed texture") {
{
int textureindex = getTextureIndex(&str); int textureindex = getTextureIndex(&str);
texture.texture = getTextureFromModel(scene, textureindex); texture.texture = getTextureFromModel(scene, textureindex);
} } else {
else
{
string filename = string(str.C_Str()); string filename = string(str.C_Str());
filename = directory + '/' + filename; filename = directory + '/' + filename;
wstring filenamews = wstring(filename.begin(), filename.end()); wstring filenamews = wstring(filename.begin(), filename.end());
@ -136,64 +128,52 @@ vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureTyp
return textures; return textures;
} }
void ModelLoader::Close() void ModelLoader::Close() {
{ for (auto& t : textures_loaded)
for (int i = 0; i < meshes.size(); i++) t.Release();
{
for (int i = 0; i < meshes.size(); i++) {
meshes[i].Close(); meshes[i].Close();
} }
dev->Release();
} }
void ModelLoader::processNode(aiNode * node, const aiScene * scene) void ModelLoader::processNode(aiNode * node, const aiScene * scene) {
{ for (UINT i = 0; i < node->mNumMeshes; i++) {
for (UINT i = 0; i < node->mNumMeshes; i++)
{
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
meshes.push_back(this->processMesh(mesh, scene)); 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); this->processNode(node->mChildren[i], scene);
} }
} }
string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat) string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat) {
{
aiString textypeStr; aiString textypeStr;
mat->GetTexture(aiTextureType_DIFFUSE, 0, &textypeStr); mat->GetTexture(aiTextureType_DIFFUSE, 0, &textypeStr);
string textypeteststr = textypeStr.C_Str(); string textypeteststr = textypeStr.C_Str();
if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5") if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5") {
{ if (scene->mTextures[0]->mHeight == 0) {
if (scene->mTextures[0]->mHeight == 0)
{
return "embedded compressed texture"; return "embedded compressed texture";
} } else {
else
{
return "embedded non-compressed texture"; return "embedded non-compressed texture";
} }
} }
if (textypeteststr.find('.') != string::npos) if (textypeteststr.find('.') != string::npos) {
{
return "textures are on disk"; return "textures are on disk";
} }
return "."; return ".";
} }
int ModelLoader::getTextureIndex(aiString * str) int ModelLoader::getTextureIndex(aiString * str) {
{
string tistr; string tistr;
tistr = str->C_Str(); tistr = str->C_Str();
tistr = tistr.substr(1); tistr = tistr.substr(1);
return stoi(tistr); return stoi(tistr);
} }
ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex) ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex) {
{
HRESULT hr; HRESULT hr;
ID3D11ShaderResourceView *texture; 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 <Windows.h>
#include <shellapi.h>
#include <stdexcept>
#include <windowsx.h> #include <windowsx.h>
#include <d3d11_1.h> #include <d3d11_1.h>
#include <dxgi1_2.h> #include <dxgi1_2.h>
#include <DirectXMath.h> #include <DirectXMath.h>
#include <d3dcompiler.h> #include <d3dcompiler.h>
#include "ModelLoader.h" #include "ModelLoader.h"
#include "UTFConverter.h"
#include "SafeRelease.hpp"
#pragma comment (lib, "d3d11.lib") #pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "Dxgi.lib") #pragma comment (lib, "Dxgi.lib")
@ -27,6 +31,10 @@
#pragma comment (lib, "dxguid.lib") #pragma comment (lib, "dxguid.lib")
using namespace DirectX; using namespace DirectX;
using namespace AssimpSamples::SharedCode;
#define VERTEX_SHADER_FILE L"VertexShader.hlsl"
#define PIXEL_SHADER_FILE L"PixelShader.hlsl"
// ------------------------------------------------------------ // ------------------------------------------------------------
// Structs // Structs
@ -45,29 +53,32 @@ struct ConstantBuffer {
const char g_szClassName[] = "directxWindowClass"; const char g_szClassName[] = "directxWindowClass";
static std::string g_ModelPath;
UINT width, height; UINT width, height;
HWND hwnd; HWND hwnd = nullptr;
// ------------------------------------------------------------ // ------------------------------------------------------------
// DirectX Variables // DirectX Variables
// ------------------------------------------------------------ // ------------------------------------------------------------
D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL; D3D_DRIVER_TYPE g_driverType = D3D_DRIVER_TYPE_NULL;
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
ID3D11Device *dev; ID3D11Device *dev = nullptr;
ID3D11Device1 *dev1; ID3D11Device1 *dev1 = nullptr;
ID3D11DeviceContext *devcon; ID3D11DeviceContext *devcon = nullptr;
ID3D11DeviceContext1 *devcon1; ID3D11DeviceContext1 *devcon1 = nullptr;
IDXGISwapChain *swapchain; IDXGISwapChain *swapchain = nullptr;
IDXGISwapChain1 *swapchain1; IDXGISwapChain1 *swapchain1 = nullptr;
ID3D11RenderTargetView *backbuffer; ID3D11RenderTargetView *backbuffer = nullptr;
ID3D11VertexShader *pVS; ID3D11VertexShader *pVS = nullptr;
ID3D11PixelShader *pPS; ID3D11PixelShader *pPS = nullptr;
ID3D11InputLayout *pLayout; ID3D11InputLayout *pLayout = nullptr;
ID3D11Buffer *pConstantBuffer; ID3D11Buffer *pConstantBuffer = nullptr;
ID3D11Texture2D *g_pDepthStencil; ID3D11Texture2D *g_pDepthStencil = nullptr;
ID3D11DepthStencilView *g_pDepthStencilView; ID3D11DepthStencilView *g_pDepthStencilView = nullptr;
ID3D11SamplerState *TexSamplerState; ID3D11SamplerState *TexSamplerState = nullptr;
ID3D11RasterizerState *rasterstate = nullptr;
ID3D11Debug* d3d11debug = nullptr;
XMMATRIX m_World; XMMATRIX m_World;
XMMATRIX m_View; XMMATRIX m_View;
@ -91,7 +102,7 @@ void Throwanerror(LPCSTR errormessage);
// Our Model // Our Model
// ------------------------------------------------------------ // ------------------------------------------------------------
ModelLoader *ourModel; ModelLoader *ourModel = nullptr;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 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; return 0;
} }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) 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; WNDCLASSEX wc;
MSG msg; MSG msg;
@ -160,6 +204,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
width = wr.right - wr.left; width = wr.right - wr.left;
height = wr.bottom - wr.top; height = wr.bottom - wr.top;
try {
InitD3D(hInstance, hwnd); InitD3D(hInstance, hwnd);
while (true) while (true)
@ -178,8 +223,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
} }
CleanD3D(); CleanD3D();
return static_cast<int>(msg.wParam);
return 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;
}
} }
void InitD3D(HINSTANCE hinstance, HWND hWnd) void InitD3D(HINSTANCE hinstance, HWND hWnd)
@ -227,6 +280,12 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
if (FAILED(hr)) if (FAILED(hr))
Throwanerror("Directx Device Creation Failed!"); 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; UINT m4xMsaaQuality;
dev->CheckMultisampleQualityLevels( dev->CheckMultisampleQualityLevels(
DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality); DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
@ -348,7 +407,6 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView); devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView);
D3D11_RASTERIZER_DESC rasterDesc; D3D11_RASTERIZER_DESC rasterDesc;
ID3D11RasterizerState *rasterState;
rasterDesc.AntialiasedLineEnable = false; rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.CullMode = D3D11_CULL_BACK;
rasterDesc.DepthBias = 0; rasterDesc.DepthBias = 0;
@ -360,8 +418,8 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
rasterDesc.ScissorEnable = false; rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f; rasterDesc.SlopeScaledDepthBias = 0.0f;
dev->CreateRasterizerState(&rasterDesc, &rasterState); dev->CreateRasterizerState(&rasterDesc, &rasterstate);
devcon->RSSetState(rasterState); devcon->RSSetState(rasterstate);
D3D11_VIEWPORT viewport; D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
@ -381,19 +439,38 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
void CleanD3D(void) void CleanD3D(void)
{ {
if (swapchain)
swapchain->SetFullscreenState(FALSE, NULL); swapchain->SetFullscreenState(FALSE, NULL);
if (ourModel) {
ourModel->Close(); ourModel->Close();
g_pDepthStencil->Release(); delete ourModel;
g_pDepthStencilView->Release(); ourModel = nullptr;
pLayout->Release(); }
pVS->Release(); SafeRelease(TexSamplerState);
pPS->Release(); SafeRelease(pConstantBuffer);
pConstantBuffer->Release(); SafeRelease(pLayout);
swapchain->Release(); SafeRelease(pVS);
backbuffer->Release(); SafeRelease(pPS);
dev->Release(); SafeRelease(rasterstate);
devcon->Release(); 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) void RenderFrame(void)
@ -431,8 +508,10 @@ void RenderFrame(void)
void InitPipeline() void InitPipeline()
{ {
ID3DBlob *VS, *PS; ID3DBlob *VS, *PS;
CompileShaderFromFile(L"VertexShader.hlsl", 0, "main", "vs_4_0", &VS); if(FAILED(CompileShaderFromFile(SHADER_PATH VERTEX_SHADER_FILE, 0, "main", "vs_4_0", &VS)))
CompileShaderFromFile(L"PixelShader.hlsl", 0, "main", "ps_4_0", &PS); 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->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS); dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
@ -485,7 +564,7 @@ void InitGraphics()
m_View = XMMatrixLookAtLH(Eye, At, Up); m_View = XMMatrixLookAtLH(Eye, At, Up);
ourModel = new ModelLoader; 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"); Throwanerror("Model couldn't be loaded");
} }
@ -514,5 +593,5 @@ HRESULT CompileShaderFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefine
void Throwanerror(LPCSTR errormessage) 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 ${Assimp_SOURCE_DIR}/code
${OPENGL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}
${GLUT_INCLUDE_DIR} ${GLUT_INCLUDE_DIR}
${SAMPLES_SHARED_CODE_DIR}
) )
LINK_DIRECTORIES( LINK_DIRECTORIES(
@ -31,6 +32,8 @@ LINK_DIRECTORIES(
ADD_EXECUTABLE( assimp_simpletexturedogl WIN32 ADD_EXECUTABLE( assimp_simpletexturedogl WIN32
SimpleTexturedOpenGL/include/boost_includes.h SimpleTexturedOpenGL/include/boost_includes.h
SimpleTexturedOpenGL/src/model_loading.cpp 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}) SET_PROPERTY(TARGET assimp_simpletexturedogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})

View File

@ -21,8 +21,6 @@
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "contrib/stb_image/stb_image.h" #include "contrib/stb_image/stb_image.h"
#include <locale>
#include <codecvt>
#include <fstream> #include <fstream>
//to map image filenames to textureIds //to map image filenames to textureIds
@ -35,7 +33,7 @@
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/LogStream.hpp> #include <assimp/LogStream.hpp>
#include "UTFConverter.h"
// The default hard-coded path. Can be overridden by supplying a path through the command line. // 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"; 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 // Create an instance of the Importer class
Assimp::Importer importer; Assimp::Importer importer;
// Used to convert between multibyte and unicode strings. using namespace AssimpSamples::SharedCode;
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_;
void createAILogger() void createAILogger()
{ {