Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 使用顶点缓冲区绘制大量相同的模型?_Performance_Xna_Vertex Buffer - Fatal编程技术网

Performance 使用顶点缓冲区绘制大量相同的模型?

Performance 使用顶点缓冲区绘制大量相同的模型?,performance,xna,vertex-buffer,Performance,Xna,Vertex Buffer,我面临着一个问题,许多开发人员可能已经找到了解决方案。 我有一个小项目,地板用小立方体(100X100)设计。 如果我超过了这个限制,我的游戏将遭受严重的减速和延迟 下面是我如何画地板的: //Function to draw my ground ( 100 X 100 X 1) public void DrawGround(GameTime gameTime) { // Copy any parent transforms. Matrix[] t

我面临着一个问题,许多开发人员可能已经找到了解决方案。 我有一个小项目,地板用小立方体(100X100)设计。 如果我超过了这个限制,我的游戏将遭受严重的减速和延迟

下面是我如何画地板的:

//Function to draw my ground ( 100 X 100 X 1)
    public void DrawGround(GameTime gameTime)
    {
        // Copy any parent transforms.
        Matrix[] transforms = new Matrix[this.model.Bones.Count];
        this.model.CopyAbsoluteBoneTransformsTo(transforms);

        //loop 1 cube high
        for (int a = 0; a < 1; a++)
        {
            //loop 100 along cube
            for (int b = 0; b < 100; b++)
            {
                //loop 100 cubic wide
                for (int c = 0; c < 100; c++)
                {
                    // Draw the model. A model can have multiple meshes, so loop.
                    foreach (ModelMesh mesh in this.model.Meshes)
                    {
                        // This is where the mesh orientation is set, as well 
                        // as our camera and projection.
                        foreach (BasicEffect effect in mesh.Effects)
                        {
                            effect.EnableDefaultLighting();
                            effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(this.position);
                            effect.View = this.view;
                            effect.Projection = this.projection;


                        }

                        // Draw the mesh, using the effects set above.
                        mesh.Draw();
                    }
                }
            }
        }
    }
//绘制我的背景的函数(100 X 100 X 1)
公共空地(游戏时间游戏时间)
{
//复制任何父变换。
矩阵[]变换=新矩阵[this.model.Bones.Count];
this.model.copyAbsoluteBonetTransformsTo(转换);
//环路1立方高
对于(int a=0;a<1;a++)
{
//沿着立方体绕100圈
对于(int b=0;b<100;b++)
{
//100立方宽的环路
对于(int c=0;c<100;c++)
{
//绘制模型。一个模型可以有多个网格,所以循环。
foreach(此.model.mesh中的ModelMesh网格)
{
//这也是设置网格方向的地方
//作为我们的相机和投影。
foreach(网格中的基本效果。效果)
{
effect.EnableDefaultLighting();
effect.World=transforms[mesh.ParentBone.Index]*Matrix.CreateTranslation(this.position);
effect.View=this.View;
effect.Projection=this.Projection;
}
//使用上面设置的效果绘制网格。
mesh.Draw();
}
}
}
}
}
我认为最好使用[VertexBuffer]“图形卡内存”,但我还没有找到一个我想做的教程

你能给我举个例子在我的函数“DrawGround”中使用[VertexBuffer]吗? 多谢各位

tl;博士

用于绘制立方体。(可选)使用以避免绘制不可见实例。通过读取开始顶点和索引缓冲区


实例 其思想是,顶点和索引缓冲区绑定到设备一次,然后在单个绘制调用中绘制多次。实例是一小包数据,只包含模型实例的唯一信息。该实例数据将写入额外的vertexbuffer,并与包含实际顶点和索引的缓冲区一起绑定到设备

你怎么能利用它呢? 在您的情况下,您将具有以下设置:

  • 包含立方体网格索引的IndexBuffer
  • 包含立方体网格顶点的VertexBuffer
  • 第二个VertexBuffer,包含要绘制的所有立方体的变换
  • 考虑实例数据的特殊输入布局
由于立方体的位置不同,您甚至不必向着色器发送完整的变换矩阵。只需发送实例位置并将其添加到顶点位置。您还可以发送其他数据,如每个实例的颜色

你如何实现它? 快速的谷歌搜索给了我大量xna实例的搜索结果,所以这应该可以让你开始了。这里有两个看似有希望的随机结果:


破片拣选 在任何时候,场景中只有一小部分网格实际可见。一个物体可能被另一个物体遮挡,或者完全位于玩家的视野之外。在绘制这些不可见网格之前删除这些网格的过程称为剔除。视图截锥剔除处理第二种情况:

所有与摄影机体积不相交的体积都不可见

相机的音量是多少?正交投影具有长方体形式的边界体积。通过透视投影,这个盒子是锥形的,一个金字塔,由近平面和远平面裁剪而成;因此,视锥

你怎么能利用它呢? 使用平截头体标识当前帧中不可见的实例。仅绘制与相机视锥体相交的立方体。当玩家仰望天空时,渲染负载最多可减少100%。-)

您可以将其与空间层次(或)相结合,以减少长方体截锥体交点计算量

你如何实现它? Xna提供了一个和一个。你所要做的就是使用它们


小小的缺点 结合使用视锥剔除和硬件实例可能会很棘手。剔除实例意味着您还必须将它们从实例缓冲区=>中删除,这意味着重新创建整个过程。可能考虑计算立方体可见性和仅在每隔几帧或当相机快速移动时更新实例缓冲区。最终实现这些技术的方式和范围取决于您自己,并取决于您的需求


我刚意识到您想知道顶点缓冲区是如何工作的:

顶点缓冲区 在屏幕上绘制三角形之前,必须准备好图形设备。这包括绑定着色器、采样器、纹理,当然还有绑定几何体数据。生成渲染后,图形设备将运行着色器并将输出写入渲染目标

目前,您正在使用XNA的内置抽象,它简化了流程(并从您那里获得了所有控制权)。绑定着色器、常量、输入布局等当前都隐藏在Effect类中,而Mesh类负责处理几何体方面的事情

“mesh.Draw()”是做什么的? 创建网格时,将创建两个缓冲区:a和a。创建这个缓冲区是非常昂贵的,所以最好只做一次。调用draw方法时,缓冲区绑定到t
// Instantiate the VertexBuffer
var vertexBuffer = new VertexBuffer(
    device, 
    VertexPositionColorNormal.VertexDeclaration, 
    vertices.Length, 
    BufferUsage.WriteOnly
);

// Write data to the buffer
vertexBuffer.SetData(vertices);

// Instantiate the IndexBuffer
var indexBuffer = new IndexBuffer(
    device, 
    typeof(int), 
    indices.Length,      
    BufferUsage.WriteOnly
);

// Write data to the buffer
indexBuffer.SetData(indices);
device.Indices = myIndexBuffer;
device.SetVertexBuffer(myVertexBuffer);