sprite render is very slow

Started by
18 comments, last by Brain 8 years, 7 months ago

I use ID3DXSprite interface to make this game. At first I put all properties into one class which is not a good style. Then I try to use component - contain many pointers to different components in entity class. But problems come. The rendering becomes awful! when runing at 60 fps, you can see the jump between frames... I upload the code. if someone have spare time please give it a look. I've changed the code many times but this problem remains.

the code is not so complex. class scene create entities and update them. ticktimer is a timer class. gamestart, gamerun and gameend is called at proper place. that's all.

the file I upload is more smooth because I raise the framerate to 120fps. but when use 60fps, it will be horrible.. you can change it in main.cpp - it is in messageloop.

er..and any improve to this code is welcome..but be sure to send me a copysmile.png

Advertisement
I'm sorry, but you're going to have to provide more than a compressed archive of code if you want to get help. Post the sprite rendering code here in code tags. I'm not going to download a compressed archive and dig through multiple files to try and figure out where the error is and I doubt many people would either.

Also, it sounds like you want someone to download your code base, fix it and then send it back to you. Not going to happen. We'll comment on the code you post openly on the forum, but you'll need to be the one to make the changes.

Without looking at the code i can give one piece of advice.

You should be thinking of migrating away from D3DX functions as they have been obsolete for many years.

If you are using anything newer than directx 9 (which most people are by now) there are many better replacements. In fact, on windows 10, D3DX won't work at all unless you install it as a seperate DLL/dependency with your game. Time is ticking and leaving you behind! :)


..I raise the framerate to 120fps. but when use 60fps, it will be horrible..

If you're doing frame limiting could you post that section of code?

It can produce stuttering if you limit fps to 60 (in my engine it did), maybe using something like 62 fps will help?

Have you tried using vsync?

.:vinterberg:.

I've looked at it.

It's not sprite rendering slow. It's your simulation not depending on actual time.

You're waiting when time for rendering will come, then perform one fixed size step.

But that won't work on low fps, because actual time step and your desired 4ms step will differ drastically.

Just compare 1sec/60frames ~=16ms. You're doing 4 times less steps than you expect. Sure it will move slower.

Instead you should check exact amount of ms passed, and perform simulation based on that info.

@MarkS I'm sorry but I have no intention that someone else should fix the code for me. I just don't know which part is wrong, so I have to upload the whole project...I think I will choose some part for now. thanks for your advice;

@vstrakh thanks for your time! I've always had a question about the timer. and I have found an article discussing this topic. Maybe I am going to fix that!

as for using directx..,I have to say that I bought many books and they are all about dx9, so naturally I chose it

If you have problems with your applications being slow, you should consider learning about/looking into profilers.

They can help show you which sections of your code is running slowly. Even if you don't know a solution to the slow part yourself, you can at least narrow it down and be able to post a lot more specific questions, which is likely to give you better replies and solutions.

Hello to all my stalkers.

@vinterberg this is messageloop. tmr.tickprecise(4)will return true every 250ms(I've tested it in a separate project). but I only got 120fps.

	while (message.message != WM_QUIT)
	{
		if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&message);
			DispatchMessage(&message);
		}
		if (tmr.timeprecise(4))
		{
			UpdateDXGame();
		}
	}
and this is the entity class

class entity
{
public:
	entity();
	~entity();

	void make_transform(lpvector2 origin, float rotation);
	void make_movement(lpvector2 velocity, float angularvelocity);
	void make_graphics(lpvector2 topleft, RECT* SourceRect);
	void make_input(int iflag);
	void make_collision(vector2* vertice, int vercount);
	void make_fire();

	void messagepump(lptexture texture, entity** miss, int* iterator);

	transform* _transform;
	movement* _movement;
	graphics* _graphics;
	input* _input;
	collision* _collision;
	fire* _fire;
};

this is the funciton to be called every frame. implecolli calculate collisions and it works quite good.

void scene::update()
{
	for (int i = 0; i < _iterator; i++)
	{
		_entities[i]->messagepump(texture, &_missilemanage[_iteratormiss], &_iteratormiss);

		if (_entities[i]->_collision->detector == true)
		{
			for (int j = 0; j < _iterator; j++)
			{
				if (j == i)
					continue;
				vector2 mtd;
				if (impleColli(_entities[i]->_collision->_vertrans, _entities[i]->_collision->_iterator,
					&_entities[i]->_movement->_velc, &_entities[i]->_transform->_ori,
					_entities[j]->_collision->_vertrans, _entities[j]->_collision->_iterator,
					&_entities[j]->_movement->_velc, &_entities[j]->_transform->_ori,
					&mtd))
				{
					if(mtd != NULL)
						_entities[i]->_transform->_ori += mtd;
				}
			}
		}
	}
	ostringstream os; string s;
	os << _iteratormiss; s = os.str();
	SetWindowText(GetActiveWindow(), s.c_str());
	for (int i = 0; i < _iteratormiss; i++)
	{
		_missilemanage[i]->messagepump(texture, &_missilemanage[_iteratormiss], &_iteratormiss);
	}
}

here is messagepump. it handles the communication between components

void entity::messagepump(lptexture texture, entity** miss, int* iterator)
{
	//movement
	if (_transform != NULL && _movement != NULL)
	{
		_transform->_ori += _movement->_velc;
		_transform->_rot += _movement->_angvelc;
	}
	//input
	if (_input != NULL && _movement != NULL && _transform != NULL)
	{
		int imove, irotate, addi;
		_input->update(&imove, &irotate, &addi);
		float tx = 0;
		float ty = 0;
		float rotR = 0;
		vector2 Vtrans = D3DXVECTOR2(0, 0);
		rotR = 3.14159265 * 2 * _transform->_rot / 360;
		tx = _movement->max_vel * sin(rotR);
		ty = -_movement->max_vel * cos(rotR);
		Vtrans = vector2(tx, ty);
		switch (imove)
		{
		case 1:
			_movement->_velc = Vtrans;
			break;

		case 2:
			_movement->_velc = -Vtrans;
			break;

		case 3:
			_movement->_velc = vector2(0, 0);
			break;
		}
		switch(irotate)
		{
		case 2:
			_movement->_angvelc = _movement->max_angv;
			break;

		case 1:
			_movement->_angvelc = -_movement->max_angv;
			break;

		case 3:
			_movement->_angvelc = 0;
			break;
		}
		if (addi == 1)
		{
			_fire->makefire(miss, &_collision->springarm, _transform->_rot);
			*iterator += 1;
		}
	}
	//graphics
	if (_graphics != NULL)
	{
		float rotR = 3.14159265f * 2.f / 360.f * _transform->_rot;
		D3DXMATRIX mat;
		D3DXMatrixTransformation2D(&mat, NULL, 0, NULL, &(_graphics->_topleft*-1), rotR, &_transform->_ori);
		spriteobj1->SetTransform(&mat);
		spriteobj1->Draw(texture, &_graphics->_srcrect, NULL, NULL, D3DCOLOR_XRGB(255, 255, 255));
	}
	//collision
	if (_collision != NULL)
	{
		_collision->update(&_transform->_rot, &_transform->_ori);
	}
}


tmr.tickprecise(4)

That line supposed to return true when 4 ms elapsed since previous update.

But your simulation updates is coupled with rendering. Means with VSync at 60fps you will get next check in 16ms.

After 16ms that check will again report true, since 16ms>=4ms, but only one fixed size step of simulation will be performed, while you need 4 steps to cover those 16ms.

&nbsp;

tmr.tickprecise(4)

That line supposed to return true when 4 ms elapsed since previous update.
But your simulation updates is coupled with rendering. Means with VSync at 60fps you will get next check in 16ms.
After 16ms that check will again report true, since 16ms&gt;=4ms, but only one fixed size step of simulation will be performed, while you need 4 steps to cover those 16ms.
&nbsp;

I see...but, how can I fix it? is there any articles about it?

This topic is closed to new replies.

Advertisement