优化你的手机游戏:使用脏矩形技术 |
| 作者:佚名 来源:本站整理 发布时间:2008-2-11 11:06:07 |
|
ool IsDirty( ) = 0;//是否有脏矩形 virtual bool GetBoundsRect(RECT*pRect) =0;//得到该物体的范围 virtual int GetDirtyRects ( RECT*pRectBuffer ) = 0;//该物体的脏矩形个数,填充到pRectBuffer里面,返回填充了多少个 ...其他函数 }; 我们还需要一个简单的能管理脏矩形和渲染物体的类 class CRenderObjectManager { pulibc: void RemoveRenderObject( CRenderObject*pObject );//删除一个渲染物体 void AddRenderObject( CRenderObject*pObject );//添加一个渲染物体 void Render( GraphicsDevice*pDevice );//渲染所有的物体 void Update( );//更新所有物体 .....其他函数 protected: std::list< CRenderObject* > m_RenderObjects; int m_nCurrentDirtyRectCount;//当前脏矩形数量 struct DirtyRect { RECT Range; //脏矩形范围 int AreaSize; //脏矩形大小,用来排序 }; BOOL m_bHoleDirty;//是否全部脏了 DirtyRect m_DirtyRects[128];//屏幕上最多的脏矩形数量,如果大于这个数量则认为屏幕所有范围都脏了 }; void CRenderObjectManager::Update() { m_bHoleDirty = false; m_nCurrentDirtyRectCount = 0; static RECT DirtyRectBuffer[128]; float TimeStamp = GetElapsedTime(); for(std::list< CRenderObject* >::iterator it = m_RenderObjects.begin(); it != m_RenderObjects.end(); it++) { CRenderObject*pObject = *it; pObject->OnUpdate( TimeStamp ); if(m_bHoleDirty == false && pObject->IsDirty() ) { int Count = pObject->GetDirtyRects(DirtyRectBuffer); for( i =0; i<Count;i++) { 对于该物体的每一个脏矩形DirtyRectBuffer[i] 如果DirtyRectBuffer[i] 没有在任何一个已有的脏矩形范围内 那么把这个脏矩形根据从大到小的顺序添加到脏矩形范围内,否则忽略这个脏矩形 如果脏矩形数量已经大于设定的最大脏矩形范围,设置所有所有屏幕都脏了的标志, } } } 如果屏幕所有都脏了,填充背景颜色 否则为每一个脏矩形填充背景颜色 } void CRenderObjectManager::Render( GraphicsDevice* pGraphics) { for(std::list< CRenderObject* >::iterator it = m_RenderObjects.begin(); it != m_RenderObjects.end(); it++) { CRenderObject*pObject = *it; if(如果屏幕都脏了的标志已经设定) { RECT rcBoundsRect = { 0, 0, 0, 0 }; if( pObject->GetBoundsRect( rcBoundsRect ) ) { //设置屏幕裁减区域 pGraphics->SetClipper( &rcBoundsRect ); } pObject->OnRender( pGraphics ); } else { RECT rcBoundsRect = { 0, 0, 0, 0 }; if( pObject->GetBoundsRect( rcBoundsRect ) ) { //如果该物体的范围与脏矩形缓冲区的任何一个脏矩形有交集的话 for( int i=0; i<m_nCurrentDirtyRectCount; i++ ) { RECT rcIntersect; if( ::IntersectRect( &rcIntersect, &m_DirtyRects[i].Range, &rcBoundsRect ) ) { //只画交集的部分 pGraphics-> SetClipper ( &m_DirtyRects[i].Range ); pObject->OnRender( pGraphics ); } } } } } } 好了,核心代码的伪代码就在这里,不知道大家看明白没有,当然我在这里上面实现的这种方法有一个缺陷,最坏情况下一个也许会导致重新画很多次,如图的情况:
|
| [] [返回上一页] [打 印] |
|
文章评论 |

