在混合器

时间:2016-11-17 07:43:05

标签: c++ opengl blender

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

当我加载本教程中提供的模型时,一切都很好,但是当我创建我的简单幼崽模型时,我遇到映射问题。在搅拌机中,这个模型看起来像这样:

normal mapping in blender

model in my program

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

  • 写法线
  • Trangulate Faces
  • 包含UVs

任何人都可以解释我的模型有什么问题吗?

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

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);
}

0 个答案:

没有答案