|
最近在看红龙书的雪球粒子样例,实现方式是建立一个2048的顶点缓存,每个片断可容纳512个粒子。我看它直接创建了6000个雪球粒子,然后逐个片断填充到顶点缓存里。- Particle* v = 0;
- _vb->Lock(
- _vbOffset * sizeof( Particle ),
- _vbBatchSize * sizeof( Particle ),
- (void**)&v,
- _vbOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);
- DWORD numParticlesInBatch = 0;
- std::list<Attribute>::iterator i;
- for(i = _particles.begin(); i != _particles.end(); i++)
- {
- if( i->_isAlive )
- {
- // 更新例子坐标和颜色
- v->_position = i->_position;
- v->_color = (D3DCOLOR)i->_color;
- v++;
- numParticlesInBatch++; //增加片断计数
- // 当一个批次渲染完成时
- if(numParticlesInBatch == _vbBatchSize)
- {
- _vb->Unlock();
- _device->DrawPrimitive(
- D3DPT_POINTLIST,
- _vbOffset,
- _vbBatchSize);
- // 增加偏移,使其指向下一个片断
- _vbOffset += _vbBatchSize;
- if(_vbOffset >= _vbSize)
- _vbOffset = 0;
- _vb->Lock(
- _vbOffset * sizeof( Particle ),
- _vbBatchSize * sizeof( Particle ),
- (void**)&v,
- _vbOffset ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD);
- numParticlesInBatch = 0; // 重新对新的片断进行计数
- }
- }
- }
- _vb->Unlock();
复制代码
然后我的问题就来了,顶点缓存不是只能容纳2048个粒子吗,难道不是只会在一屏里显示2048个粒子,6000个粒子是怎么做到的?
当我假设只能容纳2048个粒子时,如果先渲染前2048个粒子,当我渲染下一组2048时,由于跟前面2048个粒子位置或者颜色之类的参数不一样,应该会出现画面一闪一闪才对。所以推翻了自己的假设。又陷入另一个问题,难道是因为渲染速度太快,所以残留在我们视野里,所以看起来很多?如果不是,那怎么解释即能同时存在6000个粒子,还能改他们位置和颜色状态的。
还有另一个问题是,为什么_vbOffset为0时使用D3DLOCK_DISCARD,而不为0用D3DLOCK_NOOVERWRITE。难道是因为用了D3DLOCK_DISCARD时,它跟Lock方法的第一个参数和第二个参数无关,不是替换的其中一段大小为_vbBatchSize * sizeof( Particle )的内存,而是整段顶点缓存的内存都返回一个新的,然后才让我能够用D3DLOCK_NOOVERWRITE继续追加到下一个片断?假如它返回的是一整段新的顶点缓存,那当我Unlock是不是会造成我只填充了顶点缓存的前一部分,后面的还没填充?
因为我是刚接触DX相关的,所以有些东西理解的不是很明白,希望各位能指点指点,先谢谢各位了
|
|