OpenGL OpenTK-与Assimp不一致的模型加载

问题描述

我正在尝试使用Assimp将多个网格模型(sponza)导入到我的OpenGL渲染器中。 尽管我有场景的obj文件,但该文件似乎无法正确加载。为简单起见,即使UV仍然加载,我也忽略了所有纹理,只是将颜色设置为蓝色。

This is what I end up with

像斯坦福巨龙这样的单网格高多边形计数对象可以很好地加载。

这就是我加载对象的方式

if (Path.ToLower().EndsWith(".x"))        
{
                _scene = _context.ImportFile(Path,PostProcessSteps.LimitBoneWeights
                    | PostProcessSteps.Triangulate
                    | PostProcessSteps.ValidateDataStructure
                    | PostProcessSteps.FlipWindingOrder
                    | PostProcessSteps.FixInFacingNormals
                );
}
        

else
{
        _scene = _context.ImportFile(Path,PostProcessSteps.LimitBoneWeights
            | PostProcessSteps.Triangulate
            | PostProcessSteps.ValidateDataStructure
        );
}

for (int i = 0; i < _scene.MeshCount; i++)
{
    for (int j = 0; j < _scene.Meshes[i].Vertices.Count; j++)
    {
        _verts.Add(_scene.Meshes[i].Vertices[j].X);
        _verts.Add(_scene.Meshes[i].Vertices[j].Y);
        _verts.Add(_scene.Meshes[i].Vertices[j].Z);


        _verts.Add(_scene.Meshes[i].HasTextureCoords(0) ? _scene.Meshes[i].TextureCoordinateChannels[0][j].X : 0f);
        _verts.Add(_scene.Meshes[i].HasTextureCoords(0) ? _scene.Meshes[i].TextureCoordinateChannels[0][j].Y : 0f);


        _verts.Add(_scene.Meshes[i].Normals[j].X * InvertNormal.X);
        _verts.Add(_scene.Meshes[i].Normals[j].Y * InvertNormal.Y);
        _verts.Add(_scene.Meshes[i].Normals[j].Z * InvertNormal.Z);

    }
}
float[] _data = _verts.ToArray();
GL.NamedBufferData(VBO,_verts.Count * sizeof(float),_data,BufferUsageHint.StaticDraw);

// Indecis
List<uint> _indecisList = new List<uint>();
for (int i = 0; i < _debugMeshes; i++)
{
    uint[] _tempArr = _scene.Meshes[i].GetUnsignedIndices();
    for (int j = 0; j < _tempArr.Length; j++)
    {
        _indecisList.Add(_tempArr[j]);
    }
}
uint[] _indecis = _indecisList.ToArray();
GL.NamedBufferData(IBO,_indecis.Length * sizeof(uint),_indecis,BufferUsageHint.StaticDraw);
GL.BindVertexArray(Renderer.Forward.OBJ4.VAO);        
{       
    _modelViewMatrix = Matrix4.CreateScale(0.01f) * Matrix4.CreateTranslation(30,10);
    GL.UniformMatrix4(21,false,ref _modelViewMatrix);

    ColorMode(1);
    GL.BindBuffer(BufferTarget.ElementArrayBuffer,Renderer.Forward.OBJ4.IBO);
    GL.DrawElements(PrimitiveType.Triangles,786801,DrawElementsType.UnsignedInt,0); _drawCalls++;
    ColorMode(0);
}

解决方法

您的代码只是将所有网格合并为一个顶点数组+元素数组。但是,每个网格的元素数据是该特定网格中顶点数据的从0开始的索引。因此,第一个网格之后的所有内容都将使用引用错误顶点的元素数据。

如果要解决此问题,必须将元素索引数据偏移在当前网格之前添加到顶点数组中的网格的所有顶点的总和。

但是,您的方法似乎令人怀疑。通常,由于某种原因,例如不同的纹理和材质属性,对象会被分成不同的网格。无论如何(至少不是天真的),您不能在单个绘制调用中绘制它们。 GL确实提供了glDrawElementsBaseVertex之类的功能,用于您要从一个组合的顶点数组绘制不同的子网格,并在内部为您进行上述偏移的情况。

还请注意,通过按您的方式组合网格,您还将忽略场景层次结构中的转换。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...