XNA顶点缓冲区绘制得非常错误

XNA顶点缓冲区绘制得非常错误,xna,xna-4.0,Xna,Xna 4.0,我不熟悉在XNA中使用顶点缓冲区。在我的项目中,我使用大量顶点构建了一个。到目前为止,我一直在使用DrawUserIndexedPrimitions()绘制原语,但我已经从中成长出来,需要更高的效率,因此我正在尝试了解缓冲区的基本原理 我认为我已经成功地实现了一个缓冲区(并且对性能改进非常满意),除了所有的面看起来都是错误的。以下是在没有缓冲区的情况下原语的外观:(预期外观),以及在没有缓冲区的情况下原语的外观: 下面是我加载顶点缓冲区和索引缓冲区的代码: private void Refres

我不熟悉在XNA中使用顶点缓冲区。在我的项目中,我使用大量顶点构建了一个。到目前为止,我一直在使用DrawUserIndexedPrimitions()绘制原语,但我已经从中成长出来,需要更高的效率,因此我正在尝试了解缓冲区的基本原理

我认为我已经成功地实现了一个缓冲区(并且对性能改进非常满意),除了所有的面看起来都是错误的。以下是在没有缓冲区的情况下原语的外观:(预期外观),以及在没有缓冲区的情况下原语的外观:

下面是我加载顶点缓冲区和索引缓冲区的代码:

private void RefreshVertexBuffer()
    {
        List<VertexPositionNormalTexture> vertices = new List<VertexPositionNormalTexture>();
        List<int> indices = new List<int>();
        //rebuild the vertex list and index list
        foreach(var entry in blocks)
        {
            Block block = entry.Value;
            for (int q = 0; q < block.Quads.Count; q++)
            {
                vertices.AddRange(block.Quads[q].Corners);
                int offset = vertices.Count;
                foreach (Triangle tri in block.Quads[q].Triangles)
                {
                    indices.Add(tri.Indices[0] + offset);
                    indices.Add(tri.Indices[1] + offset);
                    indices.Add(tri.Indices[2] + offset);
                }
            }
        }

        vertexBuffer = new DynamicVertexBuffer(graphics, typeof(VertexPositionNormalTexture), vertices.Count, BufferUsage.None);
        indexBuffer = new DynamicIndexBuffer(graphics, IndexElementSize.ThirtyTwoBits, indices.Count, BufferUsage.None);
        vertexBuffer.SetData<VertexPositionNormalTexture>(vertices.ToArray(), 0, vertices.Count);
        indexBuffer.SetData<int>(indices.ToArray(), 0, indices.Count);

    }
我的指数可能会下降?或者这是由于图形设备如何使用缓冲区和用户索引的一些怪癖造成的

编辑:这也可能与我缝合三角形索引的方式有关。当我使用DrawUserIndexedPrimitives构建这个项目时,我遇到了一些类似的问题,即面向某个方向的三角形将绘制在错误的“边”(或者,错误的面将被剔除)。所以我提出了这个解决方案:

Triangle[] tris;
        if (faceDirection == ADJACENT_FACE_NAMES.BOTTOM | faceDirection == ADJACENT_FACE_NAMES.OUTER | faceDirection == ADJACENT_FACE_NAMES.LEFT)
        {
            //create the triangles for the quad
            tris = new Triangle[2]{
                new Triangle( //the bottom triangle
                    new int[3] {
                        0, //the bottom left corner
                        1, //the bottom right corner
                        2 //the top left corner
                    }),
                new Triangle( //the top triangle
                    new int[3] {
                        1, //the bottom right corner
                        3, //the top right corner
                        2 //the top left corner
                    })};
        }
        else
        {
            tris = new Triangle[2]{
                            new Triangle(
                                new int[3] {
                                    2, //the top left corner
                                    1, 
                                    0
                                }),
                                new Triangle(
                                    new int[3] {
                                        2,
                                        3,
                                        1
                                    })
                        };
        }

问题是三角形正在被剔除。因此,您有两个选项来解决此问题:

  • 您可以更改三角形索引的顺序

            foreach (Triangle tri in block.Quads[q].Triangles)
            {
                indices.Add(tri.Indices[1] + offset);
                indices.Add(tri.Indices[0] + offset);
                indices.Add(tri.Indices[2] + offset);
            }
    
  • 您可以更改光栅化状态

    默认光栅化器状态为光栅化器状态。请按顺时针方向

    可以将其逆时针更改为光栅化状态.cullstate

  • 编辑:

    这行有一个bug:

     graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, planet.Geometry.VertexBuffer.VertexCount, 0, planet.Geometry.IndexBuffer.IndexCount / 6)
    
    应该是:

     graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, planet.Geometry.VertexBuffer.VertexCount, 0, planet.Geometry.IndexBuffer.IndexCount / 3)
    

    问题是三角形正在被剔除。因此,您有两个选项来解决此问题:

  • 您可以更改三角形索引的顺序

            foreach (Triangle tri in block.Quads[q].Triangles)
            {
                indices.Add(tri.Indices[1] + offset);
                indices.Add(tri.Indices[0] + offset);
                indices.Add(tri.Indices[2] + offset);
            }
    
  • 您可以更改光栅化状态

    默认光栅化器状态为光栅化器状态。请按顺时针方向

    可以将其逆时针更改为光栅化状态.cullstate

  • 编辑:

    这行有一个bug:

     graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, planet.Geometry.VertexBuffer.VertexCount, 0, planet.Geometry.IndexBuffer.IndexCount / 6)
    
    应该是:

     graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, planet.Geometry.VertexBuffer.VertexCount, 0, planet.Geometry.IndexBuffer.IndexCount / 3)
    

    我已经在重新安排三角形索引顺序上胡闹了。以下是将光栅化状态切换为逆时针的结果:这让我感觉这不是一个适用于所有人脸的毛毯问题,而是其他一些问题正在进行中。。。当然,我希望我是错的,这只是一个简单的调整游戏如何吸引。编辑:如果我将“消隐模式”设置为“无”,行星将按其应有的方式向外绘制,但当然,如果不在内部进行消隐,则效率较低。这不是一个理想的解决方案,但它向我证明了几何体的构造至少是正确的。嗯,但现在我想起来了,我确实使用了DrawUserIndexedPrimitives的反复试验来获得这些索引的顺序。如果从缓冲区中绘制与手动绘制不同(或更聪明),我可能需要在之前的一些捏造上后退。只是在调整三角形的制作方式上乱搞。我这辈子都修不好。所有指向上(北极)、左(西)或内(朝向地核)的区块面都是反转的。我把它们挑了出来,尝试了各种排列方式,但当我突然改变它们时,其他的行为也很奇怪。。。这不像以前那么容易。无论我做了什么更改,它都会影响所有面的剔除,或者不会影响任何面。你能在绘制之前检查一下吗?GraphicsDevice.RasterizerState=RasterizerState.CullNone;我已经在重新安排三角形索引顺序上胡闹了。以下是将光栅化状态切换为逆时针的结果:这让我感觉这不是一个适用于所有人脸的毛毯问题,而是其他一些问题正在进行中。。。当然,我希望我是错的,这只是一个简单的调整游戏如何吸引。编辑:如果我将“消隐模式”设置为“无”,行星将按其应有的方式向外绘制,但当然,如果不在内部进行消隐,则效率较低。这不是一个理想的解决方案,但它向我证明了几何体的构造至少是正确的。嗯,但现在我想起来了,我确实使用了DrawUserIndexedPrimitives的反复试验来获得这些索引的顺序。如果从缓冲区中绘制与手动绘制不同(或更聪明),我可能需要在之前的一些捏造上后退。只是在调整三角形的制作方式上乱搞。我这辈子都修不好。所有指向上(北极)、左(西)或内(朝向地核)的区块面都是反转的。我把它们挑了出来,尝试了各种排列方式,但当我突然改变它们时,其他的行为也很奇怪。。。这不像以前那么容易。无论我做了什么更改,它都会影响所有面的剔除,或者不会影响任何面。你能在绘制之前检查一下吗?GraphicsDevice.RasterizerState=RasterizerState.CullNone;