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

C# OpenGL OpenTK-与Assimp加载的模型不一致,c#,opengl,opentk,assimp,C#,Opengl,Opentk,Assimp,我正在尝试将带有Assimp的多网格模型(sponza)导入到我的OpenGL渲染器中。 虽然我有一个正在工作的场景obj文件,但该文件似乎无法正确加载。为了简单起见,我省略了所有的纹理,即使UV仍然被加载,而只是将颜色设置为蓝色。 单网格高多边形数对象(如Stanford Dragon)可以很好地加载 这就是我加载对象的方式 if (Path.ToLower().EndsWith(".x")) { _scene = _con

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

单网格高多边形数对象(如Stanford Dragon)可以很好地加载

这就是我加载对象的方式

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

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

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

然而,你的方法似乎是可疑的。通常,对象被分割成不同的网格是有原因的,比如不同的纹理和材质属性。无论如何,您不能在一次绘制调用中绘制这些内容(至少不能天真地绘制)。GL确实提供了一些功能,例如,您需要从一个组合顶点数组中绘制不同的子网格,并且在内部为您进行所述偏移


还请注意,通过以您的方式组合网格,您也忽略了场景层次结构中的变换。

好的,因此我现在可以使用
glDrawerElementsBaseVertex
。(谢谢!)在一个更严肃的项目中,这真的是这样做的吗?还是有其他更好的方法?您谈到将sceen拆分为不同的网格,这是否意味着我必须为每个网格创建一个VBO,或者甚至在每帧VBO中加载当前网格数据?嗯,这取决于具体情况。只要不必添加、删除或更改单个对象,就可以将所有网格放入同一VBO中。从简单开始,稍后再进行优化,当您清楚瓶颈所在时。
GL.BindVertexArray(Renderer.Forward.OBJ4.VAO);        
{       
    _modelViewMatrix = Matrix4.CreateScale(0.01f) * Matrix4.CreateTranslation(30, 0, 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);
}