dirty rectangles

I'm trying to implement dirty rectangles in a game I'm making in directx. For those who don't know, this means that when the background is drawn, not all of it is drawn every time, when a player/bullet/whatever moves, it marks the area that it used to occupy as a dirty rectangle, ie an area which needs to be redrawn. This saves a few fps because the background is the largest texture in the game and drawing it every single game loop is wasteful.

So, when an entity moves, it marks the area as dirty like so:

1
2
WORLD.Dirty(m_pos, VIS.getFrameWidth(m_gfxID), m_scale);
m_pos += m_direction;


the dirty function is shown below

1
2
3
4
5
6
7
8
void CWorld::Dirty(D3DXVECTOR2 pos, int width, float scale)
{
	D3DXVECTOR2 minimum(pos.x - width/2*scale, pos.y - width/2*scale);
	D3DXVECTOR2 maximum(pos.x + width/2*scale, pos.y + width/2*scale);

	CRectangle* rect = new CRectangle(minimum, maximum);
	m_dirtyRectangles.push_back(rect);
}


m_dirtyRectangles is an std::vector storing pointers to CRectangles.

After drawing all entities, the world class deletes all dirty rectangles and then more are made in the next update loop.

1
2
3
4
5
6
7
for (unsigned int i=0; i<m_entityVector.size(); i++)
	{
		if (m_entityVector[i]->IsActive())
				m_entityVector[i]->Draw();
	}

m_dirtyRectangles.erase(m_dirtyRectangles.begin(), m_dirtyRectangles.end());


Here is the CBackground::Draw function, which calls CVisualisation::DrawBackground() which calls CSprite::DrawBackground.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void CBackground::Draw()
{
	std::vector<CRectangle*> *rects = WORLD.getDirtyRectangles();
	std::vector<CRectangle*>::iterator iter;

	for (iter = rects->begin(); iter < rects->end(); iter++)
	{
		CRectangle * rect = *iter;
		VIS.DrawBackground(m_gfxID, rect);
	}
}

void CVisualisation::DrawBackground(int id, CRectangle* rect)
{
	assert ( id < (int)m_spriteVector.size() );

	m_spriteVector[id]->DrawBackground(m_sprite, rect);
}

void CSprite::DrawBackground(LPD3DXSPRITE spritePtr, CRectangle* rect)
{
	RECT rct;

	rct.left = rect->m_min.x;
	rct.right = rect->m_max.x;
	rct.top = rect->m_min.y;
	rct.bottom = rect->m_max.y;

	spritePtr->Begin(D3DXSPRITE_ALPHABLEND);
	spritePtr->Draw(m_texture,&rct,NULL,NULL,0xFFFFFFFF);
	spritePtr->End();
}


When entities are rotated the dirty rectangles don't work properly, the wrong part of the background texture is drawn over the entity's old location. Testing it with an entity moving directily downwards with a rotation value of 0.0f it works as it should. The rectangle class has been tested and works fine so that is not the cause of the problem. Other than that, I am confused!

Sorry that was so long. Danke =)
Are you drawing in hardware or in software? It doesn't really make sense to do this if it's the GPU who does the drawing. Drawing 2D surfaces only involves a few polygons, which is extremely fast. It's easier to redraw the scene every frame.
Yeah the GPU does the drawing I just wanted to do this because I've never tried it before, this whole project is just for fun really I'm killing time until I start university again.
Topic archived. No new replies allowed.