首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >绘制()20,32×32纹理或1次大纹理20,000倍

绘制()20,32×32纹理或1次大纹理20,000倍
EN

Stack Overflow用户
提问于 2010-12-28 01:50:21
回答 2查看 1.9K关注 0票数 6

我正在C#中使用.NET框架4编程,目的是用XNA制作一个基于瓷砖的游戏。我有一个大的纹理(256像素乘4096像素)。记住,这是一个基于瓷砖的游戏,所以这个纹理之所以如此巨大,只是因为它包含了许多块,每块都是32像素乘32像素。我想专家们肯定知道基于瓷砖的游戏是什么样子的。方向是正交的(就像棋盘),而不是等距的。

在Game.Draw()方法中,我有两个选择,其中一个将比另一个更高效。

选择/方法1:

半伪码:

代码语言:javascript
运行
复制
    public void Draw()
    {
        // map tiles are drawn left-to-right, top-to-bottom
        for (int x = 0; x < mapWidth; x++)
        {
            for (int y = 0; y < mapHeight; y++)
            {
                SpriteBatch.Draw(
                    MyLargeTexture, // One large 256 x 4096 texture
                    new Rectangle(x, y, 32, 32), // Destination rectangle - ignore this, its ok
                    new Rectangle(x, y, 32, 32), // Notice the source rectangle 'cuts out' 32 by 32 squares from the texture corresponding to the loop
                    Color.White); // No tint - ignore this, its ok
            }
        }
    }

描述:因此,有效地,第一种方法是多次引用一个大纹理,每次使用这个大纹理的一个小矩形来绘制合适的瓷砖图像。

选择/方法2

半伪码:

代码语言:javascript
运行
复制
    public void Draw()
    {
        // map tiles are drawn left-to-right, top-to-bottom
        for (int x = 0; x < mapWidth; x++)
        {
            for (int y = 0; y < mapHeight; y++)
            {
                Texture2D tileTexture = map.GetTileTexture(x, y); // Getting a small 32 by 32 texture (different each iteration of the loop)

                SpriteBatch.Draw(
                    tileTexture,
                    new Rectangle(x, y, 32, 32), // Destination rectangle - ignore this, its ok
                    new Rectangle(0, 0, tileTexture.Width, tileTexture.Height), // Notice the source rectangle uses the entire texture, because the entire texture IS 32 by 32
                    Color.White); // No tint - ignore this, its ok
            }
        }
    }

描述:因此,有效地,第二种方法是绘制许多小纹理多次。

的问题:哪种方法,为什么?本人,我认为使用第一种方法会非常有效。如果您考虑一下这对地图中的平铺数组意味着什么(比方说,考虑到2000到2000年瓷砖的大地图),每个tile对象只需要包含两个整数,对于源矩形的X和Y位置在一个大的纹理中--8个字节。然而,如果您使用方法2,则映射的平铺数组中的每个Tile对象都必须存储一个32x32纹理--一个图像--它必须为R像素分配内存32倍--那么每个瓷砖中的那个4096字节是吗?那么,哪种方法和为什么?第一要务是速度,然后是内存负荷,然后是效率或你专家认为的任何东西.

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-12-28 02:14:46

第一个方法是的速度要快得多!它与CPU端的数据结构也没有任何关系。在这两种情况下,您可能会减少到几个字节--所以这并不重要。

第一种方法之所以会更快,是因为GPU的工作方式。简单地说,您可以发送带有顶点/三角形列表的GPU绘制命令。这些顶点有各种数据(位置、颜色、纹理坐标等)。关键的是,它们不能指定纹理-绘制三角形的纹理必须在绘图设备上指定,然后再绘制整个三角形列表。

SpriteBatch所做的是自动将您的精灵批次到一起,在可以的地方,这样它就可以最小化纹理交换,从而绘制发送的命令。这就是为什么它有一个按纹理排序的选择。这也是为什么源-矩形参数的存在-允许使用雪碧片-这样就可以绘制更多的精灵,而不必改变纹理。

(事实上,您发送给GPU的绘图命令-即使您没有使用SpritBatch -被称为“批处理”。当你寄的太多时,你就变成了“批有限”。这是令人惊讶的是,很容易成为批限制-几百批是一个非常粗略的估计极限)。

票数 9
EN

Stack Overflow用户

发布于 2010-12-28 02:22:10

同意。你拉出的纹理越少,速度就越快,因为它最小化了GPU上的状态变化。

为了使它更快,请注意,您的大部分瓷砖不会在帧之间发生变化。因此,将它们全部绘制到一个屏幕大小的渲染目标一次,然后在随后的框架上,只需用一个绘图调用重新绘制单个纹理即可。添加改变顶部的瓷砖。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4543152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档