C++ Directx Assimp错误的纹理坐标

C++ Directx Assimp错误的纹理坐标,c++,directx,textures,assimp,C++,Directx,Textures,Assimp,我正在尝试将网格加载到我的directx应用程序中。我可以成功加载任何网格,但网格一侧的纹理坐标错误。(仅一侧。另一侧的纹理已正确映射) 这是我的密码 模型h #ifndef MODEL_H #define MODEL_H #include <vector> #include <d3d11_1.h> #include <DirectXMath.h> #include <D3DX10.h> #include <Importer.hpp&g

我正在尝试将网格加载到我的directx应用程序中。我可以成功加载任何网格,但网格一侧的纹理坐标错误。(仅一侧。另一侧的纹理已正确映射)

这是我的密码

模型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
#ifndef模型
#定义模型
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“Mesh.h”
使用名称空间DirectX;
类CModel
{
公众:
CModel();
~CModel();
bool Load(HWND-HWND,ID3D11Device*dev,ID3D11DeviceContext*devcon,std::string文件名);
无效绘图(ID3D11DeviceContext*devcon);
无效关闭();
私人:
ID3D11设备*dev;
ID3D11DeviceContext*devcon;
矢量网格;
字符串目录;
矢量纹理加载;
HWND-HWND;
void processNode(aiNode*节点,const aiScene*场景);
网格处理网格(aiMesh*网格,const aiScene*场景);
矢量加载材质纹理(aiMaterial*mat、aiTextureType、string typeName、const aiScene*场景);
字符串determinateTextureType(const aiScene*场景,aiMaterial*mat);
int getTextureIndex(aiString*str);
ID3D11ShaderResourceView*getTextureFromModel(const-aiScene*场景,int-textureindex);
};
#恩迪夫
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;
}
#包括“Model.h”
CModel::CModel()
{
}
CModel::~CModel()
{
}
boolcmodel::Load(HWND-HWND,ID3D11Device*dev,ID3D11DeviceContext*devcon,
std::字符串(文件名)
{
助理:进口商;
const aiScene*pScene=importer.ReadFile(文件名,
AIU三角化|
AIU转炉炼钢工艺|
AIU流程(翻转UV);
if(pScene==NULL)
返回false;
this->directory=filename.substr(0,filename.find_last_of('/');
这->dev=dev;
此->hwnd=hwnd;
进程节点(pScene->mRootNode,pScene);
返回true;
}
void CModel::processNode(aiNode*节点,const aiScene*场景)
{
对于(UINT i=0;imNumMeshes;i++)
{
aiMesh*mesh=scene->mmesh[node->mmesh[i]];
网格。向后推(此->处理网格(网格,场景));
}
对于(UINT i=0;imNumChildren;i++)
{
此->处理节点(节点->mChildren[i],场景);
}
}
字符串文本类型;
网格CModel::processMesh(aiMesh*网格,const aiScene*场景)
{
//要填充的数据
向量顶点;
向量指数;
矢量纹理;
如果(网格->材质索引>=0)
{
AimMaterial*mat=场景->材质[网格->材质索引];
如果(textype.empty())textype=determinateTextureType(场景,mat);
}
//遍历网格的每个顶点
对于(UINT i=0;imNumVertices;i++)
{
顶点;
顶点.X=网格->多顶点[i].X;
顶点.Y=网格->多顶点[i].Y;
顶点.Z=网格->多顶点[i].Z;
如果(网格->mTextureCoords[0])
{
vertex.TEXX=mesh->mTextureCoords[0][i].x;
vertex.TEXY=mesh->mTextureCoords[0][i].y;
}
其他的
{
vertex.TEXX=0.0f;
vertex.TEXY=0.0f;
}
顶点。向后推(顶点);
}
对于(UINT i=0;imNumFaces;i++)
{
aiFace=mesh->mFaces[i];
对于(UINT j=0;j材质索引>=0)
{
AimMaterial*材质=场景->材质[网格->材质索引];
矢量漫射贴图=此->加载材质纹理(材质,aiTextureType\u漫反射,“纹理\u漫反射”,场景);
插入(textures.end(),diffuseMaps.begin(),diffuseMaps.end());
//vector specularMaps=this->loadMaterialTextures(材质,AitTextureType_镜面反射,“纹理_镜面反射”);
//插入(textures.end(),specularMaps.begin(),specularMaps.end());
}
返回网格(开发、顶点、索引、纹理);
}
向量CModel::loadMaterialTextures(AimMaterial*mat,AitTextureType
类型、字符串类型名称、常量(场景)
{
矢量纹理;
对于(UINT i=0;iGetTextureCount(type);i++)
{
艾斯特林街;
mat->GetTexture(类型、i和str);
//检查之前是否加载了纹理,如果是,请继续下一次迭代:跳过加载新纹理
bool skip=false;
对于(UINT j=0;j纹理加载。推回(纹理);//将其存储为整个模型加载的纹理,以确保我们不会不必要地加载重复纹理。
}
}
返回纹理;
}
void CModel::Draw(ID3D11DeviceContext*devcon)
{
对于(int i=0;iRelease();
}
字符串CModel::DeterminateTextureType(常量为场景,目标为材质*mat)
{
aiString textypeStr;
mat->GetTexture(aiTextureType_DIFFUSE、0和textypeStr);
字符串textypeteststr=textypeStr.C_Str();
如果(textypeteststr==“*0”| textypeteststr==”*1”| textypeteststr==“*2”| textypeteststr==”*3”| textypeteststr==“*4”| textypeteststr==“*5”)
{
如果(场景->mTextures[0]->mHweight==0)
{
返回“嵌入压缩纹理”;
}
其他的
{
return“嵌入式非压缩文本”
#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