C++ 混合器中的纹理贴图UV存在问题

C++ 混合器中的纹理贴图UV存在问题,c++,opengl,blender,C++,Opengl,Blender,我对纹理贴图有问题。我已经使用本教程创建了OBJ加载器:youtube.com/watch?v=YKFYtekgnP8&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP&index=10 当我加载本教程中提供的模型时,一切都很好,但是当我创建简单的cub模型时,我在映射方面遇到了问题。在blender中,此模型如下所示: 导出模型时,我使用的是选项: 写入法线 表情转换 包括紫外线 谁能解释一下我的模型有什么问题吗 在我的程序中看起来正常的模型: dropb

我对纹理贴图有问题。我已经使用本教程创建了OBJ加载器:youtube.com/watch?v=YKFYtekgnP8&list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP&index=10

当我加载本教程中提供的模型时,一切都很好,但是当我创建简单的cub模型时,我在映射方面遇到了问题。在blender中,此模型如下所示:

导出模型时,我使用的是选项:

  • 写入法线
  • 表情转换
  • 包括紫外线
谁能解释一下我的模型有什么问题吗

在我的程序中看起来正常的模型:

dropbox.com/sh/7l598pr7b4zx63j/AAB_PzQl3zU2WS5hhlKgMb1Wa?dl=0

OBJ加载器代码:

RawModel * OBJLoader::LoadObjModel(const std::string & fileName, Loader * loader)
{
    std::ifstream file("./resources/models/" + fileName);
    std::string   line;
    int count = 0;

    std::vector<std::string> currentLine;

    std::vector < glm::vec3 > vertices;
    std::vector < glm::vec2 > textures;
    std::vector < glm::vec3 > normals;
    std::vector < int >       indices;

    std::vector < float > verticesArray;
    std::vector < float > texturesArray;
    std::vector < float > normalsArray;

    if(file.is_open())
    {
        while(file.good())
        {
            getline(file, line);

            currentLine = SplitSpace(line);

            if(currentLine.size())
            {
                // Vertices
                if(currentLine[0] == "v")
                {
                    glm::vec3 vertex = glm::vec3(ParseToFloat(currentLine[1]), ParseToFloat(currentLine[2]), ParseToFloat(currentLine[3]));
                    vertices.push_back(vertex);
                }

                // Textures
                if(currentLine[0] == "vt")
                {
                    glm::vec2 texture = glm::vec2(ParseToFloat(currentLine[1]), ParseToFloat(currentLine[2]));
                    textures.push_back(texture);
                }

                // Normals
                if(currentLine[0] == "vn")
                {
                    glm::vec3 normal = glm::vec3(ParseToFloat(currentLine[1]), ParseToFloat(currentLine[2]), ParseToFloat(currentLine[3]));
                    normals.push_back(normal);
                }

                // Face
                if(currentLine[0] == "f")
                {
                    normalsArray.resize(vertices.size() * 3);
                    texturesArray.resize(vertices.size() * 2);

                    break;
                }
            }
        }

        while(file.good())
        {
            currentLine = SplitSpace(line);

            if(currentLine.size())
            {
                // Vertices
                if (currentLine[0] == "f")
                {
                    std::vector< std::string > vertex1 = Split(currentLine[1], '/');
                    std::vector< std::string > vertex2 = Split(currentLine[2], '/');
                    std::vector< std::string > vertex3 = Split(currentLine[3], '/');

                    ProcessVertex(vertex1, textures, normals, indices, texturesArray, normalsArray);
                    ProcessVertex(vertex2, textures, normals, indices, texturesArray, normalsArray);
                    ProcessVertex(vertex3, textures, normals, indices, texturesArray, normalsArray);
                }
            }

            getline(file, line);
        }
    }
    else
        std::cerr << "Unable to Load OBJ file: " << fileName << std::endl;

    file.close();

    verticesArray.resize(vertices.size() * 3);

    int vertexPoiner = 0;

    for(int i = 0; i < vertices.size(); i++)
    {
        verticesArray[vertexPoiner++] = vertices[i].x;
        verticesArray[vertexPoiner++] = vertices[i].y;
        verticesArray[vertexPoiner++] = vertices[i].z;
    }

    return loader->LoadToVAO(verticesArray, indices, texturesArray, normalsArray);
}

std::vector<std::string> OBJLoader::Split(const std::string& splitStr, const char & ch)
{
    std::string next;
    std::vector<std::string> result;

    for(std::string::const_iterator it = splitStr.begin(); it != splitStr.end(); it++) {
        if(*it == ch)
        {
            if(!next.empty())
            {
                result.push_back(next);
                next.clear();
            }
        }
        else
            next += *it;
    }

    if (!next.empty())
        result.push_back(next);

    return result;
}

std::vector<std::string> OBJLoader::SplitSpace(const std::string &splitStr)
{
    std::string buf;
    std::stringstream ss(splitStr); // Insert the string into a stream

    std::vector<std::string> tokens; // Create vector to hold our words

    while (ss >> buf)
        tokens.push_back(buf);

    return tokens;
}

void OBJLoader::ProcessVertex(std::vector<std::string> & vertexData,
                              std::vector<glm::vec2> & textures,
                              std::vector<glm::vec3> & normals,

                              std::vector<int>   & indices,
                              std::vector<float> & texturesArray,
                              std::vector<float> & normalsArray)
{
    // Vertices
    int currentVertexPointer = ParseToInt(vertexData[0]) - 1;
    indices.push_back(currentVertexPointer);

    // Texture
    glm::vec2 currentTexture = textures[ParseToInt(vertexData[1]) - 1];

    texturesArray[currentVertexPointer * 2]     = currentTexture.x;
    texturesArray[currentVertexPointer * 2 + 1] = 1 - currentTexture.y;

    // Normals
    glm::vec3 currentNorm = normals[ParseToInt(vertexData[2]) - 1];

    normalsArray[currentVertexPointer * 3]     = currentNorm.x;
    normalsArray[currentVertexPointer * 3 + 1] = currentNorm.y;
    normalsArray[currentVertexPointer * 3 + 2] = currentNorm.z;
}

float OBJLoader::ParseToFloat(std::string str)
{
    return std::stof(str);
}
RawModel*OBJLoader::LoadObjModel(const std::string&fileName,Loader*Loader)
{
std::ifstream文件(“./resources/models/”+文件名);
std::字符串行;
整数计数=0;
矢量电流线;
std::vector顶点;
std::vector纹理;
std::vector法线;
标准:向量指数;
std::vectorverticesArray;
标准::矢量纹理阵列;
std::vectornormalsArray;
if(file.is_open())
{
while(file.good())
{
getline(文件,行);
currentLine=拆分空间(行);
if(currentLine.size())
{
//顶点
如果(当前线路[0]=“v”)
{
glm::vec3顶点=glm::vec3(ParseToFloat(currentLine[1])、ParseToFloat(currentLine[2])、ParseToFloat(currentLine[3]);
顶点。向后推(顶点);
}
//质地
如果(当前线路[0]=“vt”)
{
glm::vec2纹理=glm::vec2(ParseToFloat(currentLine[1]),ParseToFloat(currentLine[2]);
纹理。推回(纹理);
}
//常态
如果(当前线路[0]=“vn”)
{
glm::vec3 normal=glm::vec3(ParseToFloat(currentLine[1])、ParseToFloat(currentLine[2])、ParseToFloat(currentLine[3]);
法线。推回(法线);
}
//脸
如果(当前线路[0]=“f”)
{
normalsArray.resize(顶点.size()*3);
TextureArray.resize(顶点.size()*2);
打破
}
}
}
while(file.good())
{
currentLine=拆分空间(行);
if(currentLine.size())
{
//顶点
如果(当前线路[0]=“f”)
{
std::vectorvertex1=Split(currentLine[1],“/”);
std::vectorvertex2=Split(currentLine[2],“/”);
std::vectorvertex3=Split(currentLine[3],“/”);
ProcessVertex(顶点1、纹理、法线、索引、纹理阵列、法线阵列);
ProcessVertex(顶点2、纹理、法线、索引、纹理阵列、法线阵列);
ProcessVertex(顶点3、纹理、法线、索引、纹理阵列、法线阵列);
}
}
getline(文件,行);
}
}
其他的
标准:cerr buf)
代币。推回(buf);
归还代币;
}
void OBJLoader::ProcessVertex(标准::向量和顶点数据,
标准::矢量和纹理,
标准::向量和法线,
标准::向量和索引,
标准::矢量和纹理阵列,
标准::向量和法线(Sarray)
{
//顶点
int currentVertexPoint=ParseToInt(顶点数据[0])-1;
指数。推回(当前顶点指数);
//质地
glm::vec2 currentTexture=纹理[ParseToInt(vertexData[1])-1];
纹理阵列[CurrentVertexInter*2]=currentTexture.x;
TextureArray[CurrentVertexInter*2+1]=1-currentTexture.y;
//常态
glm::vec3 currentNorm=法线[ParseToInt(vertexData[2])-1];
normalsArray[currentVertexInter*3]=currentNorm.x;
normalsArray[currentVertexInter*3+1]=currentNorm.y;
normalsArray[currentVertexInter*3+2]=currentNorm.z;
}
浮点对象加载程序::ParseToFloat(标准::字符串str)
{
返回std::stof(str);
}