2017-05-23 1 views
0

私のDirectXアプリケーションにメッシュを読み込もうとしています。私は正常に任意のメッシュを読み込むことができますが、テクスチャ座標はメッシュの側面に間違っています。 (側面のみ、他のテクスチャは正しくマップされています) ScreenShotDirectX Assimpの間違ったテクスチャ座標

ここに私のコードです。

Model.h

#ifndef MODEL_H 
#define MODEL_H 

#include <vector> 
#include <d3d11_1.h> 
#include <DirectXMath.h> 
#include <D3DX10.h> 

#include <Importer.hpp> 
#include <scene.h> 
#include <postprocess.h> 

#include "Mesh.h" 

using namespace DirectX; 

class CModel 
{ 
public: 
CModel(); 
~CModel(); 

bool Load(HWND hwnd, ID3D11Device* dev, ID3D11DeviceContext* devcon, std::string filename); 
void Draw(ID3D11DeviceContext* devcon); 

void Close(); 
private: 
ID3D11Device *dev; 
ID3D11DeviceContext *devcon; 
std::vector<Mesh> meshes; 
string directory; 
vector<Texture> textures_loaded; 
HWND hwnd; 

void processNode(aiNode* node, const aiScene* scene); 
Mesh processMesh(aiMesh* mesh, const aiScene* scene); 
vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName, const aiScene* scene); 
string determineTextureType(const aiScene* scene, aiMaterial* mat); 
int getTextureIndex(aiString* str); 
ID3D11ShaderResourceView* getTextureFromModel(const aiScene* scene, int textureindex); 
}; 
#endif 

Model.cpp

#include "Model.h" 



CModel::CModel() 
{ 
} 


CModel::~CModel() 
{ 
} 

bool CModel::Load(HWND hwnd, ID3D11Device* dev, ID3D11DeviceContext* devcon, 
std::string filename) 
{ 
Assimp::Importer importer; 

const aiScene* pScene = importer.ReadFile(filename, 
    aiProcess_Triangulate | 
    aiProcess_ConvertToLeftHanded | 
    aiProcess_FlipUVs); 

if (pScene == NULL) 
    return false; 

this->directory = filename.substr(0, filename.find_last_of('/')); 

this->dev = dev; 
this->hwnd = hwnd; 

processNode(pScene->mRootNode, pScene); 

return true; 
} 

void CModel::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++) 
{ 
    this->processNode(node->mChildren[i], scene); 
} 

} 

string textype; 

Mesh CModel::processMesh(aiMesh* mesh, const aiScene* scene) 
{ 
// Data to fill 
vector<VERTEX> vertices; 
vector<DWORD> indices; 
vector<Texture> textures; 

if (mesh->mMaterialIndex >= 0) 
{ 
    aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex]; 

    if(textype.empty()) textype = determineTextureType(scene, mat); 
} 

// Walk through each of the mesh's vertices 
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]) 
    { 
     vertex.TEXX = mesh->mTextureCoords[0][i].x; 
     vertex.TEXY = mesh->mTextureCoords[0][i].y; 
    } 
    else 
    { 
     vertex.TEXX = 0.0f; 
     vertex.TEXY = 0.0f; 
    } 

    vertices.push_back(vertex); 
} 

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) 
{ 
    aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; 

    vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse", scene); 
    textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end()); 

    //vector<Texture> specularMaps = this->loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular"); 
    //textures.insert(textures.end(), specularMaps.begin(), specularMaps.end()); 
} 

return Mesh(dev, vertices, indices, textures); 
} 

vector<Texture> CModel::loadMaterialTextures(aiMaterial* mat, aiTextureType 
type, string typeName, const aiScene* scene) 
{ 
vector<Texture> textures; 
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) 
     { 
      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 
     HRESULT hr; 
     Texture texture; 
     if (textype == "embedded compressed texture") 
     { 
      int textureindex = getTextureIndex(&str); 
      texture.texture = getTextureFromModel(scene, textureindex); 
     } 
     else 
     { 
      string filename = string(str.C_Str()); 
      filename = directory + '/' + filename; 
      hr = D3DX11CreateShaderResourceViewFromFile(dev, filename.c_str(), nullptr, nullptr, &texture.texture, nullptr); 
      if (FAILED(hr)) 
       MessageBox(hwnd, "Texture couldn't be loaded", "Error!", MB_ICONERROR | MB_OK); 
     } 
     texture.type = typeName; 
     texture.path = str; 
     textures.push_back(texture); 
     this->textures_loaded.push_back(texture); // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures. 
    } 
} 
return textures; 
} 


void CModel::Draw(ID3D11DeviceContext* devcon) 
{ 
for (int i = 0; i < meshes.size(); i++) 
{ 
    meshes[i].Draw(devcon); 
} 
} 

void CModel::Close() 
{ 
for (int i = 0; i < meshes.size(); i++) 
{ 
    meshes[i].Close(); 
} 

dev->Release(); 
} 

string CModel::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) 
    { 
     return "embedded compressed texture"; 
    } 
    else 
    { 
     return "embedded non-compressed texture"; 
    } 
} 
if (textypeteststr.find('.') != string::npos) 
{ 
    return "textures are on disk"; 
} 
} 

int CModel::getTextureIndex(aiString* str) 
{ 
string tistr; 
tistr = str->C_Str(); 
tistr = tistr.substr(1); 
return stoi(tistr); 
} 

ID3D11ShaderResourceView * CModel::getTextureFromModel(const aiScene * scene, int textureindex) 
{ 
HRESULT hr; 
ID3D11ShaderResourceView *texture; 

int* size = reinterpret_cast<int*>(&scene->mTextures[textureindex]->mWidth); 

hr = D3DX11CreateShaderResourceViewFromMemory(dev, reinterpret_cast<unsigned char*>(scene->mTextures[textureindex]->pcData), *size, nullptr, nullptr, &texture, nullptr); 
if (FAILED(hr)) 
    MessageBox(hwnd, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK); 

return texture; 
} 

Mesh.h

#ifndef MESH_H 
#define MESH_H 

#include <string> 
#include <fstream> 
#include <sstream> 
#include <iostream> 
#include <vector> 
using namespace std; 

#include <vector> 
#include <d3d11_1.h> 
#include <DirectXMath.h> 
#include <D3DX11.h> 
#include <D3DX10.h> 
using namespace DirectX; 

struct VERTEX { 
FLOAT X, Y, Z; 
D3DXCOLOR color; 
FLOAT TEXX, TEXY; 
}; 

struct Texture { 
string type; 
aiString path; 
ID3D11ShaderResourceView *texture; 
}; 

class Mesh { 
public: 
vector<VERTEX> vertices; 
vector<DWORD> indices; 
vector<Texture> textures; 
ID3D11Device *dev; 

Mesh(ID3D11Device *dev,vector<VERTEX> vertices, vector<DWORD> indices, vector<Texture> textures) 
{ 
    this->vertices = vertices; 
    this->indices = indices; 
    this->textures = textures; 

    this->dev = dev; 

    this->setupMesh(dev); 
} 

void Draw(ID3D11DeviceContext *devcon) 
{ 
    UINT stride = sizeof(VERTEX); 
    UINT offset = 0; 

    devcon->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset); 
    devcon->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0); 

    devcon->PSSetShaderResources(0, 1, &textures[0].texture); 

    devcon->DrawIndexed(indices.size(), 0, 0); 
} 

void Close() 
{ 
    VertexBuffer->Release(); 
    IndexBuffer->Release(); 
} 
private: 
/* Render data */ 
ID3D11Buffer *VertexBuffer, *IndexBuffer; 

/* Functions */ 
// Initializes all the buffer objects/arrays 
bool 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_SUBRESOURCE_DATA initData; 
    initData.pSysMem = &vertices[0]; 

    hr = dev->CreateBuffer(&vbd, &initData, &VertexBuffer); 
    if (FAILED(hr)) 
     return false; 

    D3D11_BUFFER_DESC ibd; 
    ibd.Usage = D3D11_USAGE_IMMUTABLE; 
    ibd.ByteWidth = sizeof(DWORD) * indices.size(); 
    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; 
    ibd.CPUAccessFlags = 0; 
    ibd.MiscFlags = 0; 

    initData.pSysMem = &indices[0]; 

    hr = dev->CreateBuffer(&ibd, &initData, &IndexBuffer); 
    if (FAILED(hr)) 
     return false; 
} 
}; 

#endif 

おかげで(これはヘッダのみのクラスです)。

+0

あなたはローダーコードがOKです。アプリケーションビューアでモデルを開いたことがありますか?テクスチャはどのように見えますか? – KimKulling

+0

はい私はそれを正しく示しています。いくつかのモデルもこのコードでは正しくレンダリングされますが、一部のモデルでは正しくありません(テクスチャマッピングの一部が正しくありません)。 – IAS0601

+0

インデックスが間違っている可能性がありますか?内部にノードがありますか?ここではエラーを見にくいです。私たちのgithubページで問題を生成することができます。 – KimKulling

答えて

0

私はそれを解決しました。この問題に直面している他の人がSamplerStateを設定していることを確認してください。

関連する問題