Archived

This topic is now archived and is closed to further replies.

glassJAw

Problems with scrolling in 2d Game (D3D 8)

Recommended Posts

Ok here''s the problem The engine works fine, and scrolls around fine and crap... buuuut, whenever I scroll, the framerate gets cut in half. It''s an RTS game so scrolling works by moving hte mouse to the side of the screen, like Starcraft or Command & Conquer. So anyways, I thought it might be the timing code, but it doesnt seem too bad (I posted it below). I ran it through the MSVC 6 profiler and came up with something weird (I spent the whole time in the game scrolling, so the framerate was quite low -- 46 compared to ~100 normally - so I could get an idea of what was causing the slowdown):
        Func          Func+Child           Hit
        Time   %         Time      %      Count  Function
---------------------------------------------------------
    5907.681  34.6     5907.681  34.6     1039 CDirect3D::Flip(void) (game.obj)
    2736.334  16.0     2736.334  16.0   710552 CDirect3D::BlitCustom(struct TLVERTEX *) (gamemap.obj)
 
CDirect3D is my Direct3D wrapper class. Flip() just calls Present(). BlitCustom is what I use to call DrawPrimitive for every tile on the map. It takes up about as much time as I expected it to. But the Flip() function takes up more! I know that Present() has to wait for the device to become free or whatever, but this seems pretty ridiculous. Now I don''t do dirty rectangle updating or anything; the map is redrawn every frame, so I have no idea why it slows down so much when I''m scrolling. Someone suggested it might have something to do with the hardware. I''m using a GeForce2 MX PCI (shut up). Here''s the main game loop code:
  
	//Calculate time delta

	QueryPerformanceCounter (&liCurrentTime);
	liTimeDelta.QuadPart = liCurrentTime.QuadPart - liLastTime.QuadPart;
	fTimeDelta = (double)liTimeDelta.QuadPart / (double)liFrequency.QuadPart * 1000;
	
	//Set last time and add built-up time to execution buffer

	liLastTime = liCurrentTime;
	if (fTimeDelta < 0) fTimeDelta = 0;		//Timer overflow check

	fExecutionTime += fTimeDelta;

	//Update mouse position

	POINT cursorPosition;
	GetCursorPos (&cursorPosition);
	iMouseX = cursorPosition.x;
	iMouseY = cursorPosition.y;

	//Run through logic loop

	while (fExecutionTime > UPDATE_TIME)
	{
		//Get input

		directInput.ReadKeyboard ((CDirectInput::CInputHandler *) &gameInput);

                //Update units and stuff here


		//Handle timing

		fExecutionTime -= UPDATE_TIME;
		iCurrentFrame++;
	}

	//Handle scrolling

	if (iMouseX > direct3D.screenWidth - 10)
		gameMap.iTopLeftX += fTimeDelta * SCROLL_SPEED;
	if (gameMap.iTopLeftX > gameMap.iMapWidth * 32 - direct3D.screenWidth)
		gameMap.iTopLeftX = gameMap.iMapWidth * 32 - direct3D.screenWidth;
	if (iMouseX < 10)
		gameMap.iTopLeftX -= fTimeDelta * SCROLL_SPEED;
	if (gameMap.iTopLeftX < 0)
		gameMap.iTopLeftX = 0;
	if (iMouseY > direct3D.screenHeight - 10)
		gameMap.iTopLeftY += fTimeDelta * SCROLL_SPEED;
	if (gameMap.iTopLeftY > gameMap.iMapHeight * 32 - direct3D.screenHeight)
		gameMap.iTopLeftY = gameMap.iMapHeight * 32 - direct3D.screenHeight;
	if (iMouseY < 10)
		gameMap.iTopLeftY -= fTimeDelta * SCROLL_SPEED;
	if (gameMap.iTopLeftY < 0)
		gameMap.iTopLeftY = 0;

	//Render frame

	RenderFrame ();
  
liCurrentTime, liLastTime, and liTimeDelta are all LARGE_INTEGERS iCurrentFrame is an unsigned int fExecutionTime and fTimeDelta are both doubles. Any help is greatly appreciated.

Share this post


Link to post
Share on other sites
Here''s the profiler output when I don''t scroll:

Func Func+Child Hit
Time % Time % Count Function
---------------------------------------------------------
2617.455 19.8 2617.455 19.8 589304 CDirect3D::BlitCustom(struct TLVERTEX *) (gamemap.obj)
2251.122 17.0 2251.122 17.0 70 CLogFile::operator<<(char *) (logfile.obj)
1976.691 14.9 1976.691 14.9 829 CDirect3D::Flip(void) (game.obj)


And here''s the RenderFrame() function:

  
//Make sure display device is working

if (direct3D.CheckDevice ())
{
//Start drawing

direct3D.ClearBuffer ();
direct3D.BeginDrawing ();

//Draw the map and minimap

gameMap.DrawMap ();
gameMap.DrawMinimap ();

//Draw menu if it is open

if (bMenuOpen)
{
//Draw the menu

DrawInGameMenu ();
}

//Draw FPS

char sFPS [50];
sprintf (sFPS, "%i", iFPS);
direct3D.BlitTextFast (sFPS, TEXT_VERYSMALL, 0, 0);

//Draw cursor

direct3D.DrawCursor (iMouseX, iMouseY, iMouseState);

//Finish Drawing

direct3D.EndDrawing ();
direct3D.Flip ();
}

Share this post


Link to post
Share on other sites
Ok.. weird stuff.

I commented the ClearBuffer() in RenderFrame() because I don''t need it (in fact I thought I had commented it out earlier, DrawMap() draws over everything on screen) and the whole scrolling slowdown business stopped.

Any ideas as to what happened?

Share this post


Link to post
Share on other sites