游戏开发论坛

 找回密码
 立即注册
搜索
查看: 11743|回复: 37

D3DXSPRITE多次begin-end对效率是不是影响很大?

[复制链接]

6

主题

20

帖子

24

积分

注册会员

Rank: 2

积分
24
发表于 2007-1-5 21:29:00 | 显示全部楼层 |阅读模式
有多个要渲染的对象,在渲染时每个对象都分别用begin-end对来操作,
效率和一次渲染只用一个begin-end是不是相差很远??
例如,我有一个房子,一个人物,一片草地要渲染

d3dxsprite::begin(...);
//画草地...
//画房子...
//画人物...
d3dxsprite::end();



d3dxsprite::begin(...);
//画草地...
d3dxsprite::end();

d3dxsprite::begin(...);
//画房子...
d3dxsprite::end();

d3dxsprite::begin(...);
//画人物...
d3dxsprite::end();

要效率上是不是差很远呢(更多对象时如何...)?

17

主题

258

帖子

264

积分

中级会员

Rank: 3Rank: 3

积分
264
发表于 2007-1-6 16:14:00 | 显示全部楼层

Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

最好是能自己先排序,然后只用一次begin end,似乎会好一点.

140

主题

1228

帖子

1233

积分

金牌会员

Rank: 6Rank: 6

积分
1233
QQ
发表于 2007-1-6 18:00:00 | 显示全部楼层

Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

他内部一次end就会draw一次。不end的话,他会尽可能把可以连接的顶点连起来绘制。

一般为了自己重新实现这一过程。

35

主题

1735

帖子

1739

积分

金牌会员

Rank: 6Rank: 6

积分
1739
QQ
发表于 2007-1-6 21:20:00 | 显示全部楼层

Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

曾经测试过,的确如此.

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2007-1-6 23:40:00 | 显示全部楼层

Re: Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

lights: Re3DXSPRITE多次begin-end对效率是不是影响很大?

他内部一次end就会draw一次。不end的话,他会尽可能把可以连接的顶点连起来绘制。

一般为了自己重新实现这一过程。

所以 D3D SDK 建议尽可能只使用一个 sprite。

8

主题

310

帖子

311

积分

中级会员

Rank: 3Rank: 3

积分
311
QQ
发表于 2007-1-7 10:51:00 | 显示全部楼层

Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

要是静态的就好了

20

主题

465

帖子

472

积分

中级会员

Rank: 3Rank: 3

积分
472
QQ
发表于 2007-1-7 11:32:00 | 显示全部楼层

Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

没有这回事。我曾经做过测试,虽然对速度还是有影响,但是那只是在大量的情况下才会出现。500-1000次(在一帧之内调用)以内的调用根本不影响速度。只有上到5000-10000次的时候,才会看得出来。
我之所以做这样的测试,是因为我要做一个控件的类,这个类是自己绘制自己的。我使用的Sprite也是只有一个全局实例,但是我要调用许多的Begin-End,就是因为不同的控件所要绘制的方法不同,就比如说图片控件,就有透明和不透明(Alpha混合)之分,这在Begin的时候就要设置不同的环境。诸如此类,所以要实现在同一个Begin-End循环中绘制是不可能的。

lights说的:“他内部一次end就会draw一次。不end的话,他会尽可能把可以连接的顶点连起来绘制。”这句话不完全正确。

Begin是用来设置绘制环境的,而End则是把Draw所绘制的图片提交到驱动,让其绘制。虽然是End一次就提交一次,但是主要影响性能的是你到底绘制了多少图片,而不是提交了多少次。至于后半句话,我简直不明白是什么意思!什么叫“把可以连接顶点连起来绘制”?

简单点来说,在Begin和End这两个方法里面,最占CPU的是Begin方法,因为它要改动一系列的参数,设置驱动为不同的绘制环境。但是不管怎样,他们所占的处理器时间比起Draw来说要差得远了。如果每帧只有100次左右的Begin-End循环,可以放心大胆的用。而且,有的时候你还必须使用多个Begin-End循环,因为画不同东西时,需要不同的环境。

我使用的是一个全局Sprite(一个全局类对象中的一个成员),SDK推荐使用一个Sprite的理由不是性能,而是为了避免错误。因为在一个驱动对象(Device)中,同时有效的环境只有一个。
看看下面的
sprite1->Begin() // 使用透明
sprite1->Draw() // 绘制一些东西
sprite2->Begin() // 不使用透明(在这里之后,sprite1中所设置的环境就无效化了!)
sprite1->Draw() // 绘制一些东西
sprite1->End() // 这里提交上去的东西,将都是不透明的!
sprite2->Draw() // 绘制一些东西
sprite2->End() // 在这里,提交的东西是透明的!!因为End会把Device的状态回滚到前一个!!

当然,你看到这样的代码,可以说:“我不会设计出这样的有问题的嵌套结构”,那好,既然是合法的结构,以下两种结构都不会出问题。
sprite1->Begin(Alpha);
sprite1->Draw();
sprite2->Begin(NoAlpha);
sprite2->Draw();
sprite2->End();
sprite1->End();
或是
sprite1->Begin(Alpha);
sprite1->Draw();
sprite1->End();
sprite2->Begin(NoAlpha);
sprite2->Draw();
sprite2->End();
那么,为什么有使用两个sprite的必要呢?只用一个sprite对象不就行了吗?说到底,Begin只是用来改变Device环境参数的,但是,Device的环境参数同时间只能存在一种,所以,根本没有使用多个sprite的必要。

6

主题

20

帖子

24

积分

注册会员

Rank: 2

积分
24
 楼主| 发表于 2007-1-7 11:43:00 | 显示全部楼层

Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

嗯,多谢楼上各位的回复,这点我明白了,现在又有一个问题,假如说我在渲染人物时,人物是由几个Texture给成的(身体,影子,魔法各一个texture),在渲染时,魔法这个texture的RenderState
与身体,影子的不同,但是一次begin-end对中设置的RenderState同一属性只有最后一次设置的有效,这样就好像非得把用两次beign-end对来渲染了,既然多次begin-end对比较影响效率,那有什么别的办法来实现而又不必把一个对象的渲染拆开来做?

g_pSprite->Begin( ...)
//g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
//影子
g_pSprite->Draw(...);
//身体
g_pSprite->Draw(...);
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,src);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,des);
//魔法
g_pSprite->Draw(...);
g_pSprite->End();       

上面的代码会把影子与身体部分的texture也使用AlphaBlend来画,只有下面这样结果才行:

g_pSprite->Begin( ...)
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
//影子
g_pSprite->Draw(...);
//身体
g_pSprite->Draw(...);
g_pSprite->End();       

g_pSprite->Begin( ...)
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,src);
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,des);
//魔法
g_pSprite->Draw(...);
g_pSprite->End();       

有其它的思路或方法来实现吗?请各位大哥帮忙指教!!!

6

主题

20

帖子

24

积分

注册会员

Rank: 2

积分
24
 楼主| 发表于 2007-1-7 11:44:00 | 显示全部楼层

Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

哈哈,我在请教第二个问题时,FlyMagic大哥又给我回复了,多谢!!!

20

主题

465

帖子

472

积分

中级会员

Rank: 3Rank: 3

积分
472
QQ
发表于 2007-1-7 11:52:00 | 显示全部楼层

Re:D3DXSPRITE多次begin-end对效率是不是影响很大?

人数不多的情况下,随便怎么用都无所谓,人数多的情况下,可以分成三次绘制,但是,这需要有一个人物的列表。伪代码如下
class character {
obj shadow;
obj body;
obj magic;
};

character * char_array; // 人物列表

sp->Begin(); // 设置身体环境
foreach (char_array) character->DrawShadow();
sp->End();

sp->Begin(); // 设置影子环境
foreach (char_array) character->DrawBody();
sp->End();

…… // 依次类推
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-26 06:56

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表