顶点位置未正确导入/在 OpenGL 中正确绘制 [关闭]

问题描述 投票:0回答:1

我最近尝试在我的 OpenGL 应用程序中导入网格时遇到问题。网格导入成功,但是在渲染时它看起来完全毁容了。在我看来,网格的顶点位置没有正确加载。下面是问题的图像。 注意: 此处导入的 .obj 是 Blender 的默认猴子网格。可以看出,网格的大体轮廓被保留了下来,但是,它完全偏离了目标。

我不能在这里问最好的问题,因为我似乎无法确定代码在哪一点失败。没有构建或运行时错误。然而,我最好的猜测是代码在加载网格时失败了。下面的代码是加载器函数。

bool Loader::LoadObject(
    std::string objectFP,
    std::vector<glm::vec3>& VBD,
    std::vector<glm::vec2>& UVBD,
    std::vector<glm::vec3>& NBD,
    std::vector<unsigned int>& IBD
)
{
    Helpers::Log(LOG, "Loading object (" + objectFP + ")...");

    std::vector<glm::vec3> VertexData;
    std::vector<glm::vec2> UVData;
    std::vector<glm::vec3> NormalData;

    FILE* file = fopen(objectFP.c_str(), "r");

    if (file == 0)
    {
        Helpers::Error(ERR, L"Failed to load object.");
        
        return false;
    }
    else
    {
        while (true)
        {
            char lineHeader[128] = { 0 };

            int res = fscanf(file, "%s", lineHeader);

            /* RUN CHECKS */

                            // End of File (EOF)
            if (res == EOF)
            {
                break;
            }
            else
            {
                if (res <= 0)
                {
                    Helpers::Error(ERR, L"(RES) Failed to load object.");
                    break;
                }
                else
                {
                    if (strcmp(lineHeader, "v") == 0)
                    {
                        glm::vec3 vertex = glm::vec3(0.0f, 0.0f, 0.0f);
                        // Return value is not needed here, just to get rid of the warning
                        int out = fscanf(file, "%f %f %f\n", &vertex.x, &vertex.y, &vertex.z);
                        VertexData.push_back(vertex);
                    }
                    else if (strcmp(lineHeader, "vt") == 0)
                    {
                        glm::vec2 uv = glm::vec2(0.0f, 0.0f);
                        int out = fscanf(file, "%f %f\n", &uv.x, &uv.y);
                        UVData.push_back(uv);
                    }
                    else if (strcmp(lineHeader, "vn") == 0)
                    {
                        glm::vec3 normal = glm::vec3(0.0f, 0.0f, 0.0f);
                        int out = fscanf(file, "%f %f %f\n", &normal.x, &normal.y, &normal.z);
                        NormalData.push_back(normal);
                    }
                    else
                    {
                        char fillBuffer[1000];
                        fgets(fillBuffer, 100, file);
                    }

                    VBD.reserve(VertexData.size());
                    UVBD.reserve(UVData.size());
                    NBD.reserve(NormalData.size());

                    for (unsigned int i = 0; i < VertexData.size(); i++)
                    {
                        VBD.push_back(VertexData[i]);
                    }
                    for (unsigned int i = 0; i < UVData.size(); i++)
                    {
                        UVBD.push_back(UVData[i]);
                    }
                    for (unsigned int i = 0; i < NormalData.size(); i++)
                    {
                        NBD.push_back(NormalData[i]);
                    }
                }
            }
        }

        ComputeIndexBuffer(VBD, IBD);

        fclose(file);
        return true;
    }
}

如果这不是问题。源代码是公开的here.

着色器也可能有问题。

c++ opengl mesh glm-math wavefront
1个回答
0
投票
我从你的回购中检查了你的

monkey.obj

,正如我所怀疑的那样,你的网格没有被三角化。从搅拌机导出时。选中如下所示的
Triangulated Mesh
框,将网格从多边形转换为三角形,因为您在导入器中将面解释为三角形。

在你的

ComputeIndexBuffer()

函数中:

void Loader::ComputeIndexBuffer(std::vector<glm::vec3> VBD, std::vector<unsigned int>& IBD) { for (unsigned int i = 0; i < VBD.size() / 3; i++) { unsigned int i1 = i * 3; unsigned int i2 = i * 3 + 1; unsigned int i3 = i * 3 + 2; IBD.push_back(i1); IBD.push_back(i2); IBD.push_back(i3); } }
您假设面是三角形,而 

monkey.obj

 文件主要包含四边形,因此渲染不正确。为了处理多边形,你要么必须改进你的进口商,要么求助于使用专门的进口商,比如
assimp

编辑:为了进一步澄清,我将显示您的“monkey.obj”中的线条和三角线:

在下面的行中:

f 505/553/499 323/353/499 321/349/499 391/427/499
这是

monkey.obj

的最后一行,定义了一个面(
f
在行的开头),有4个顶点(即四边形),每个顶点包含关于位置/uv坐标/法线的信息;而三角剖分的人的所有面孔都是这样定义的:

f 505/553/942 323/353/942 321/349/942
 如您所见,共有三个 

/

 组,因此有三个顶点,因此有一个 
triangle
.

© www.soinside.com 2019 - 2024. All rights reserved.