需要在 XNA 4.0 中使用实例的帮助

2023-12-01

我来询问有关 XNA 实例化的问题

我是一名初级 XNA 开发人员,最近才从 2D 游戏转向 3D 游戏。
我正在尝试绘制大量仅由代码中的顶点组成的立方体。正如人们可能怀疑的那样,绘制大量这些立方体会给我的计算机带来相当大的压力。
当我寻找一种提高性能的方法时,我遇到了“实例化”一词。
由于不知道实例化在 XNA 4.0 中的工作原理,我四处寻找适合我水平的教程。
但是,我遇到的唯一教程(http://blogs.msdn.com/b/shawnhar/archive/2010/06/17/drawinstancedprimitives-in-xna-game-studio-4-0.aspx)是对我来说有点太先进了。我认为他使用的是模型、网格和诸如此类的东西而不是顶点,所以我无法弄清楚哪段代码实际上与我所追求的内容相关。

这就是我来找你的原因。如果有人能给我一个简单的(如果可能的话)教程或代码片段,解释如何使用 XNA 4.0 中用顶点绘制的立方体(或任何图形)进行实例化,我将非常感激。


这是我能想到的最简单的代码片段。它是我几个月前编写的代码的改编版,用于显示一些立方体,就像您需要的那样,没有模型,也没有什么花哨的东西。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace HardwareInstancing
{
    public class Instancing
    {
        Texture2D texture;
        Effect effect;

        VertexDeclaration instanceVertexDeclaration;

        VertexBuffer instanceBuffer;
        VertexBuffer geometryBuffer;
        IndexBuffer  indexBuffer;

        VertexBufferBinding[] bindings;
        InstanceInfo[] instances;

        struct InstanceInfo
        {
            public Vector4 World;
            public Vector2 AtlasCoordinate;
        };

        Int32 instanceCount = 10000;

        public void Initialize(GraphicsDevice device)
        {
            GenerateInstanceVertexDeclaration();
            GenerateGeometry(device);
            GenerateInstanceInformation(device, instanceCount);

            bindings = new VertexBufferBinding[2];
            bindings[0] = new VertexBufferBinding(geometryBuffer);
            bindings[1] = new VertexBufferBinding(instanceBuffer, 0, 1);
        }

        public void Load(ContentManager Content)
        {
            effect = Content.Load<Effect>("InstancingShader");
            texture = Content.Load<Texture2D>("default_256");
        }

        private void GenerateInstanceVertexDeclaration()
        {
            VertexElement[] instanceStreamElements = new VertexElement[2];

            instanceStreamElements[0] = 
                    new VertexElement(0, VertexElementFormat.Vector4, 
                        VertexElementUsage.Position, 1);

            instanceStreamElements[1] = 
                new VertexElement(sizeof(float) * 4, VertexElementFormat.Vector2,
                    VertexElementUsage.TextureCoordinate, 1);

            instanceVertexDeclaration = new VertexDeclaration(instanceStreamElements);
        }

        //This creates a cube!
        public void GenerateGeometry(GraphicsDevice device)
        {
            VertexPositionTexture[] vertices = new VertexPositionTexture[24];

            #region filling vertices
            vertices[0].Position = new Vector3(-1, 1, -1);
            vertices[0].TextureCoordinate = new Vector2(0, 0);
            vertices[1].Position = new Vector3(1, 1, -1);
            vertices[1].TextureCoordinate = new Vector2(1, 0);
            vertices[2].Position = new Vector3(-1, 1, 1);
            vertices[2].TextureCoordinate = new Vector2(0, 1);
            vertices[3].Position = new Vector3(1, 1, 1);
            vertices[3].TextureCoordinate = new Vector2(1, 1);

            vertices[4].Position = new Vector3(-1, -1, 1);
            vertices[4].TextureCoordinate = new Vector2(0, 0);
            vertices[5].Position = new Vector3(1, -1, 1);
            vertices[5].TextureCoordinate = new Vector2(1, 0);
            vertices[6].Position = new Vector3(-1, -1, -1);
            vertices[6].TextureCoordinate = new Vector2(0, 1);
            vertices[7].Position = new Vector3(1, -1, -1);
            vertices[7].TextureCoordinate = new Vector2(1, 1);

            vertices[8].Position = new Vector3(-1, 1, -1);
            vertices[8].TextureCoordinate = new Vector2(0, 0);
            vertices[9].Position = new Vector3(-1, 1, 1);
            vertices[9].TextureCoordinate = new Vector2(1, 0);
            vertices[10].Position = new Vector3(-1, -1, -1);
            vertices[10].TextureCoordinate = new Vector2(0, 1);
            vertices[11].Position = new Vector3(-1, -1, 1);
            vertices[11].TextureCoordinate = new Vector2(1, 1);

            vertices[12].Position = new Vector3(-1, 1, 1);
            vertices[12].TextureCoordinate = new Vector2(0, 0);
            vertices[13].Position = new Vector3(1, 1, 1);
            vertices[13].TextureCoordinate = new Vector2(1, 0);
            vertices[14].Position = new Vector3(-1, -1, 1);
            vertices[14].TextureCoordinate = new Vector2(0, 1);
            vertices[15].Position = new Vector3(1, -1, 1);
            vertices[15].TextureCoordinate = new Vector2(1, 1);

            vertices[16].Position = new Vector3(1, 1, 1);
            vertices[16].TextureCoordinate = new Vector2(0, 0);
            vertices[17].Position = new Vector3(1, 1, -1);
            vertices[17].TextureCoordinate = new Vector2(1, 0);
            vertices[18].Position = new Vector3(1, -1, 1);
            vertices[18].TextureCoordinate = new Vector2(0, 1);
            vertices[19].Position = new Vector3(1, -1, -1);
            vertices[19].TextureCoordinate = new Vector2(1, 1);

            vertices[20].Position = new Vector3(1, 1, -1);
            vertices[20].TextureCoordinate = new Vector2(0, 0);
            vertices[21].Position = new Vector3(-1, 1, -1);
            vertices[21].TextureCoordinate = new Vector2(1, 0);
            vertices[22].Position = new Vector3(1, -1, -1);
            vertices[22].TextureCoordinate = new Vector2(0, 1);
            vertices[23].Position = new Vector3(-1, -1, -1);
            vertices[23].TextureCoordinate = new Vector2(1, 1);
            #endregion

            geometryBuffer = new VertexBuffer(device, VertexPositionTexture.VertexDeclaration,
                                              24, BufferUsage.WriteOnly);
            geometryBuffer.SetData(vertices);

            #region filling indices

            int[] indices = new int [36];
            indices[0] = 0; indices[1] = 1; indices[2] = 2;
            indices[3] = 1; indices[4] = 3; indices[5] = 2;

            indices[6] = 4; indices[7] = 5; indices[8] = 6;
            indices[9] = 5; indices[10] = 7; indices[11] = 6;

            indices[12] = 8; indices[13] = 9; indices[14] = 10;
            indices[15] = 9; indices[16] = 11; indices[17] = 10;

            indices[18] = 12; indices[19] = 13; indices[20] = 14;
            indices[21] = 13; indices[22] = 15; indices[23] = 14;

            indices[24] = 16; indices[25] = 17; indices[26] = 18;
            indices[27] = 17; indices[28] = 19; indices[29] = 18;

            indices[30] = 20; indices[31] = 21; indices[32] = 22;
            indices[33] = 21; indices[34] = 23; indices[35] = 22;

            #endregion

            indexBuffer = new IndexBuffer(device, typeof(int), 36, BufferUsage.WriteOnly);
            indexBuffer.SetData(indices);
        }

        private void GenerateInstanceInformation(GraphicsDevice device, Int32 count)
        {
            instances = new InstanceInfo[count]; 
            Random rnd = new Random();

            for (int i = 0; i < count; i++)
            {
                //random position example
                instances[i].World = new Vector4(-rnd.Next(400), 
                                                 -rnd.Next(400), 
                                                 -rnd.Next(400), 1);

                instances[i].AtlasCoordinate = new Vector2(rnd.Next(0, 2), rnd.Next(0, 2));
            }

            instanceBuffer = new VertexBuffer(device, instanceVertexDeclaration, 
                                              count, BufferUsage.WriteOnly);
            instanceBuffer.SetData(instances);
        }

        //view and projection should come from your camera
        public void Draw(ref Matrix view, ref Matrix projection, GraphicsDevice device)
        {
            device.Clear(Color.CornflowerBlue);

            effect.CurrentTechnique = effect.Techniques["Instancing"];
            effect.Parameters["WVP"].SetValue(view * projection);
            effect.Parameters["cubeTexture"].SetValue(texture);

            device.Indices = indexBuffer;

            effect.CurrentTechnique.Passes[0].Apply();

            device.SetVertexBuffers(bindings);
            device.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, 24, 0, 12, instanceCount);
        }
    }
}

我用过THIS纹理与此着色器一起:

float4x4 WVP;
texture cubeTexture;

sampler TextureSampler = sampler_state
{
    texture = <cubeTexture>;
    mipfilter = LINEAR;
    minfilter = LINEAR;
    magfilter = LINEAR;
};

struct InstancingVSinput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
};

struct InstancingVSoutput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
};

InstancingVSoutput InstancingVS(InstancingVSinput input, float4 instanceTransform : POSITION1, 
                                float2 atlasCoord : TEXCOORD1)
{
    InstancingVSoutput output;

    float4 pos = input.Position + instanceTransform;
    pos = mul(pos, WVP);

    output.Position = pos;
    output.TexCoord = float2((input.TexCoord.x / 2.0f) + (1.0f / 2.0f * atlasCoord.x),
                             (input.TexCoord.y / 2.0f) + (1.0f / 2.0f * atlasCoord.y));
    return output;
}

float4 InstancingPS(InstancingVSoutput input) : COLOR0
{
    return tex2D(TextureSampler, input.TexCoord);
}

technique Instancing
{
    pass Pass0
    {
        VertexShader = compile vs_3_0 InstancingVS();
        PixelShader = compile ps_3_0 InstancingPS();
    }
}

它应该命名为 InstancingShader.fx 并放置在您的 Content 文件夹中。

在您的 Game1 中使用它就像调用以下命令一样简单:

instancing = new Instancing();
instancing.Initialize(this.GraphicsDevice);
instancing.Load(Content);

并在您的 Draw 方法中:

instancing.Draw(ref camera.View, ref camera.Projection, GraphicsDevice);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

需要在 XNA 4.0 中使用实例的帮助 的相关文章

  • “struct X typedef”与“typedef struct X”的含义是什么?

    我在现有代码库中有以下 工作 代码 在 C 和 C 之间共享的包含文件中使用 在 MSVC 2010 和 Windows DDK 上编译 struct X USHORT x typedef X PX And enum MY ENUM enu
  • 配置 Visual Studio 以使用更多内存

    我曾经读过一篇关于如何增加 Visual Studio 将使用的 RAM 量的博客文章 当我尝试在 Visual Studio 编辑器中复制一小行文本时 收到 没有足够的可用内存 错误消息 有谁知道我可以如何或在哪里配置它 这是符合您的描述
  • Silverlight xaml TextBlock.Text 与 CDATA 在运行时未显示?

    以下 xaml 会生成文本 激活左侧测试 在运行时和设计时可见 在 Vs2010 中
  • Visual Studio 2010 在程序结束后退出

    我正在通过编译 C 程序来尝试 Visual Studio 2010 在 DOS 命令窗口中显示解决方案后 该窗口立即关闭 在 Visual Studio 2008 中 用户会收到按任意键继续的消息 并按任意键关闭命令提示符窗口 我如何在
  • 实体框架左外连接和分组抛出:ORA-00907:缺少右括号

    我在基于实体框架的数据访问中使用实体框架来定位多个数据库 我们是一个使用 Entity Framework 已有 2 年的团队 生成的代码与 sql server 2008 完美配合 现在 我们在将数据库迁移到 Oracle 11 Expr
  • 为什么 Visual Studio 不移动发布中的某些文件?

    当我尝试发布项目时 Visual Studio 不会将某些文件移动到目标发布文件夹 目前我有这个问题 json文件 我正在使用 Visual Studio 2010 和 MVC4 是否有关于应发布哪些文件或 mime 类型并将其移动到目标文
  • 设置具有不同输入的测试方法

    我想在 C 中测试所有代码路径的以下方法 public int foo int x if x 1 return 1 if x 2 return 2 else return 0 我见过这个pex单元测试 http fernandomachad
  • UV 展开运行时优化

    我正在尝试在运行时创建 UV 我使用 BOX 类型 UV 类似于 3ds max 中的 BOX UVW 并基于面方向进行计算 我知道将其创建为运行时不是一个好的选择 但我别无选择 它是在计算后保存的 所以我做了一次 但我花了 40 秒处理
  • 在 Visual Studio 2010 中标准化行结尾

    我们有多个开发人员在开发一个应用程序 似乎每当一个特定的人在处理一个文件时 其他人在处理该文件时 他们都会得到 以下文件中的行结尾不一致 你想要 标准化行结尾 Visual Studio 中是否有一些选项可供开发人员更改 这样我们就不会一直
  • 如何重新包含排除的文件夹

    所以我只是无意中点击了我的项目的致命一击Exclude From Project代替Add在我的控制器文件夹中 当尝试添加名为 Controllers 的文件夹时 我收到错误 此文件夹存在 但是 如果我尝试单击该项目 gt Add Exis
  • vscode 窗口没有响应[重复]

    这个问题在这里已经有答案了 VS代码版本 1 77 0 操作系统版本 windows 11 22h2 这是我过去几天收到的问题 我使用了nodejs 并且没有安装任何Python或其他软件 我已经删除了所有扩展并删除了缓存 在此输入图像描述
  • 如何在构建后事件中获取版本号

    我想使用构建后事件自动创建 nuget 包 然后将其复制到我们网络上的共享文件夹 如下所示 版本号 1 0 0 0 在 MyLib nuspec 文件中指定 nuget exe pack SolutionDir MyLib nuspec x
  • 缩小 ASP.NET 生成的 Javascript 的最佳方法是什么?

    在 ASP NET 3 5 运行时缩小 ASP NET 生成的 Javascript 例如由 webresource axd 提供的 Javascript 的最佳方法是什么 我尝试使用Mb压缩 http mbcompression code
  • 多个 Visual Studio 项目抱怨临时文件丢失,因此无法打开。错误代码 &H80070003

    我在终端服务器上运行 Visual Studio 2010 并且已经运行了一段时间 问题相对较少 今天早上 我启动了我的电脑 在英国的长周末期间 似乎出现了以下问题 我有很多项目 但不是我的所有项目 也不是给定解决方案中的所有项目 抱怨无法
  • C++11 / VS2010:返回不可复制但可移动对象的容器

    考虑以下代码 include
  • C# 代码上的 ImageURL 不显示图像

    我在 aspx 页面上有图像
  • If 语句中 Bool 计算错误

    只是为了好奇 我的代码有这个问题 e被评估为false 我知道通过查看数据库中的数据会得到错误 但 if 语句并不关心这一点 并假设这是真的 并试图抛出异常 有什么想法吗 edit 没有 在第 16 行末尾 价值false是正确的 我已经检
  • 如何在 Visual Studio 2010 中处理 TODO 注释?

    我希望 Visual Studio 列出开头包含 TODO 的所有行 通常在注释符号之后 注释符号可能会根据文件类型而变化 这些行可以在解决方案中的任何文本文件中找到 无论是 C VB F T SQL ASPX XAML 或只是 TXT 在
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 在 EnvDTE 中调试时捕获 VS 局部变量

    是否可以使用 EnvDTE 进行 vsix Visual Studio 扩展来捕获本地和调试窗口使用的调试数据 或者可以通过其他方法吗 我想创建一个自定义的本地窗口 我们可以修改它以根据需要显示一些较重的内容 而无需为高级用户牺牲原始的本地

随机推荐

  • 如何在同一个循环中同时循环所有 Firebase 子项?

    我在 firebase 中有三个节点 我想使用相同的循环来循环它们 我成功地能够使用以下代码循环遍历单个节点 cookie databaseRef child cookies observeSingleEvent of value with
  • 从 Java 到 PHP 重新创建 PDF 文件

    我有一个 Java 中的 WebService 使用 Apache Axis 它获取文档的 id 并调用 JasperReports 来创建 PDF 文件 之前在 java 应用程序中创建的报告 服务器端 以创建我正在使用的方法的报告 Ja
  • 使用 Javascript 删除从不同页面呈现的整个表格

    我有一张像这样的桌子 table class toc border 1 table 在许多页面中 所有这些页面都呈现在单个页面中 当我应用 Javascript 来删除加载时使用的内容时 仅删除一张表 其他表不会被删除 我正在尝试使用 Ja
  • Azure AD登录后如何重定向到特定页面?

    我正在将 Azure AD 登录集成到我的应用程序中 我想在成功登录天蓝色广告后重定向到特定操作 我的 Startup Auth cs 文件中有以下代码 但它没有重定向到redirecturi 任何人都可以建议我如何在成功登录后重定向到自定
  • Python Tkinter Treeview 添加图像作为列值

    我试图将图像添加到树视图上每一行的第一列 但无论我做什么 最终总是显示对象 pyimage1 的名称而不是实际图像 正如这张图片所示 我正在使用的代码是这样的 from tkinter import PhotoImage self img
  • 如何使用 jQuery 在 30 分钟内使 cookie 过期?

    如何让 Cookie 在 30 分钟内过期 我正在使用 jQuery cookie 我能够做这样的事情 cookie example foo expires 1 这是 1 天的时间 但是我们如何将到期时间设置为 30 分钟 30分钟是30
  • 在 SQL SERVER 2008 中从字符串转换日期和/或时间时转换失败

    我有以下 SQL UPDATE student queues SET Deleted 0 last accessed by raja last accessed on CONVERT VARCHAR 24 23 07 2014 09 37
  • 是否有 C# 中的 JSON Web Token (JWT) 示例?

    我觉得我在这里服用了疯狂的药 通常 对于任何给定的任务 网络上总会有一百万个库和示例 我正在尝试使用 JSON Web Tokens JWT 来实现 Google 服务帐户 的身份验证 如下所述here 但是 只有 PHP Python 和
  • 使用 C#/.NET 将图像上传到服务器并将文件名存储在数据库中

    我目前正在使用以下代码片段将数据插入数据库的表中 效果很好 但是 我想开始添加文件名数据 但不确定如何继续 我有以下内容 Create command comm new SqlCommand INSERT INTO Entries Titl
  • 基于主机的卡模拟,有什么指导吗?

    我是这个领域的新手 我有一个 Nexus S CyanogenMod11 Android Kitkat 4 4 2 我需要使用 HCE 基于主机的卡模拟 模式来模拟非接触式卡 为了实现这一目标 我需要遵循的步骤和技巧有什么指导吗 我需要对模
  • 如何从 hashCode 中获取字符串

    我正在开发一个项目 我得到了我的密码字段值hashCode出于安全目的 并将该 hashCode 存储在数据库中 现在我想从 hashCode 中恢复密码 我该怎么做 是否可以从 hashCode 中获取 String 值 如果不是 任何人
  • 为什么docker build后node_modules为空?

    为什么我的 docker 数据卷在主机系统上挂载为空 当 的时候docker compose up完成后我可以执行到 docker 容器并查看node modules目录中 我可以看到所有已成功安装的模块 但是当我检查我的node modu
  • 有没有办法在 ActionScript 中获取字形的实际边界框?

    我正在学习 ActionScript Flash 我喜欢玩弄文本 并且使用出色的 Java2D API 做了很多这样的事情 我想知道的一件事是 你到底在哪里画那个字形 TextField 类提供了方法getBounds and getCha
  • IE 中的 JQuery 复选框列表问题?保存为 on,on,on 的值应为 10,12,13 等

    我有一个使用 javascript 呈现的复选框列表
  • 开发和生产属性

    我有一个 GlassFish j2ee 应用程序 我在一个盒子上进行开发 生产是一个远程盒子 我有一个生成文件的函数 并且我需要根据我的开发盒或生产情况使文件的位置有所不同 有什么自动方法可以进行切换 这样我就不必根据部署位置来编辑源文件
  • 春季启动+休眠

    我的 Maven 依赖项出了什么问题 当我包含 JPA 时 我有例外列表 这是我的 Maven 依赖项
  • 如何将Hive连接到asp.net项目

    你好 我对 Hadoop 很陌生 我已将 Microsoft HDInsight 安装到本地系统 现在我想连接到 hive 和 HBase 但用于 HIVE 连接 我必须指定连接字符串 端口 用户名 密码 但我无法弄清楚如何获得这个值 我尝
  • Git:在提交/推送之前运行过滤器?

    有没有办法在提交之前通过过滤器运行更改的文件 我希望确保文件遵循项目的编码标准 我还想在提交 推送实际发生之前编译并运行一些测试 所以我知道存储库中的所有内容实际上都有效 预提交挂钩 继续阅读git钩子 Git 书籍有一个example例如
  • 将小计添加到 Pandas Groupby

    我正在寻找一种更干净的方法来将小计添加到 Pandas groupby 中 这是我的数据框 df pd DataFrame Category np random choice Group A Group B 50 Sub Category
  • 需要在 XNA 4.0 中使用实例的帮助

    我来询问有关 XNA 实例化的问题 我是一名初级 XNA 开发人员 最近才从 2D 游戏转向 3D 游戏 我正在尝试绘制大量仅由代码中的顶点组成的立方体 正如人们可能怀疑的那样 绘制大量这些立方体会给我的计算机带来相当大的压力 当我寻找一种