render order

Started by
11 comments, last by lodoss118 17 years, 11 months ago
hi don't have enough programming experiuence with sorting and searching algorithms but i got something like this for my rendering method renderChars() { char[0] = renderKen(); char[1] = renderRyu(); etc } i am trying to make a scrolling beat em up, i know the last element gets drawn first, so how do i sort according to the y value of the main char or enemies i.e the main char could be ken so if ryu->y is less than ken->y, draw ken first etc any examples would help thanks
Advertisement
What's wrong with:
renderChars(){   if(ken->y > ryu->y)   {      char[0] = renderKen();      char[1] = renderRyu();   }   else   {      char[1] = renderKen();      char[0] = renderRyu();   }}

?
hmm but say if i have loads of enemies aswell and want their order to be sorted

enemy[1]->y > enemy[6]->y etc?
Use the STL. It provides classes for tracking a bunch of objects (known as "container" classes - such as list, vector, queue, stack, etc), and provides a bunch of algorithms for things like sorting and searching.

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

is it possible to demonstrate to me a quick example of this i heard of the built in library for queues deqeues list etc but never used them?
OK, sure. We'll need to suppose some things about your game first though.

Let's suppose that what we're looking at is, instead of a character renderer or suchlike, just a generalised system for rendering sprites. That allows you to use it for characters, powerups, special effects... whatever you like.

The way it's going to work will be like this: Your renderer is going to have a list of the sprites that it needs to draw (that it keeps from frame to frame, because the set of sprites that you need to draw in one frame are usually the same set that you need to draw the next frame). Each of your enemies or characters or whatever-the-heck-you-likes that are graphically visible (i.e. aren't invisible objects like triggers or spawn points) will have a pointer to an entry in this list. If the object moves or changes state, it goes through the pointer and updates the relevant information about where its sprite should be and which frame of animation it should display.

When it comes to actually rendering all these objects, you've got every sprite in a nice list and you can use a predicated sort (a sort where you provide code that tells the sort algorithm how to compare two entries) to sort them however you like - by depth, by spritesheet, etc.

What you end up with is something like the following. (This is off the top of my head to convey an idea, it probably doesn't compile):

// The data we store for each sprite - just enough to render itstruct SpriteData{ int left, top, right, bottom; // position in worldspace - could do width/height instead of right/bottom if you prefer int zOrder; // draw order relative to other sprites - lower numbers are drawn last int animationID; // ID number of the animation this sprite is playing int animationFrame; // frame number within the animation};class SpriteRenderer{ private: // the list of sprites std::list<SpriteData*> sprites;  // a function used to compare two sprites, for sorting static bool CompareSprites(const SpriteData*& s1, const SpriteData*& s2) {  // push sprites with high zOrders to the beginning of the list so they are drawn first  return (s1.zOrder > s2.zOrder); } public: // create a new sprite entry in the list and return a pointer to the caller static SpriteData* CreateSprite() {  SpriteData* s = new SpriteData();  sprites.push_back(s);  return s; } // delete an entry from the list static void RemoveSprite(SpriteData* s) {  sprites.remove(s);  delete s; } // render all the sprites static void Render() {  // sort the sprite list, using our custom compare function  sprites.sort(CompareSprites);  // loop through all the sprites, first to last  for(std::list<SpriteData*>::iterator it = sprites.begin(); it != sprites.end(); ++it)  {   const SpriteData* thisSprite = (*it);   // .   // .   // .   // Do what you need to do to render the sprite given the info in thisSprite   // .   // .   // .  } }}// Elsewhere, in a game object somewhere - say a characterMyCharacter::MyCharacter(){ /* ... stuff ... */ m_Sprite = SpriteRenderer::CreateSprite();}void MyCharacter::Update(){ /* ... stuff ... */ if(userInput->PlayerIsPressingKey(KEY_JUMP)) {  m_Sprite->animationID = ANIMATION_JUMP;  m_Sprite->animationFrame = 0; } /* ... more stuff ... */ m_Sprite->left = m_Position.x - 32; m_Sprite->top = m_Position.y - 32; m_Sprite->right = m_Position.x + 32; m_Sprite->bottom = m_Position.y + 32; m_Sprite->animationFrame++;}

Richard "Superpig" Fine - saving pigs from untimely fates - Microsoft DirectX MVP 2006/2007/2008/2009
"Shaders are not meant to do everything. Of course you can try to use it for everything, but it's like playing football using cabbage." - MickeyMouse

i see what ur getting at , this what i did for my game (no cool sprite manager like above though) so u can see my shitty code :(

http://rapidshare.de/files/18391896/genesis_Engine.rar.html

that is my source i suppose if i did it like the above i would have to change the whole engine thingy, note i am using a directx wrapper to make my game.
hi i am trying to implement the above sprite list class but for the
sprites.sort(CompareSprites) how would that work or what should i put in it, i did this

void AnimatedSprite::Render(const SpriteData*& s1, const SpriteData*& s2)
{
sprites.sort(CompareSprites(s1, s2));
}

but i get an error?

how would i implement the DXUSPRITE using the above method?


struct SpriteData
{
int left, top, right, bottom; // position in worldspace - could do width/height instead of right/bottom if you prefer
int zOrder; // draw order relative to other sprites - lower numbers are drawn last
int animationID; // ID number of the animation this sprite is playing
int animationFrame; // frame number within the animation
DXUIMAGE image;
DXUSPRITE sprite;
};


SpriteData* AnimatedSprite::CreateSprite(TCHAR *path, int z, float posx, float posy, int r, int g, int b)
{
SpriteData* s = new SpriteData();
DXULoadImage(&s->image, path, DXURGB(r, g, b));
DXUSetSprite(&s->image, &s->sprite, posx, posy);
sprites.push_back(s);
return s;
}

void AnimatedSprite::RemoveSprite(SpriteData *s)
{
DXUReleaseImage(&s->image);
DXUReleaseSprite(&s->sprite);
sprites.remove(s);
delete s;
}

void AnimatedSprite::Render(/*const SpriteData*& s1, const SpriteData*& s2*/)
{
//sprites.sort(CompareSprites(s1, s2));

// loop through all the sprites, first to last
for(std::list<SpriteData*>::iterator it = sprites.begin(); it != sprites.end(); ++it)
{

SpriteData* thisSprite = (*it);

DXUMoveSprite(&thisSprite->sprite, thisSprite->sprite.x, thisSprite->sprite.y);
DXUDrawSprite(&thisSprite->sprite);

}
}
Quote:Original post by superpig
OK, sure. We'll need to suppose some things about your game first though.

Let's suppose that what we're looking at is, instead of a character renderer or suchlike, just a generalised system for rendering sprites. That allows you to use it for characters, powerups, special effects... whatever you like.

The way it's going to work will be like this: Your renderer is going to have a list of the sprites that it needs to draw (that it keeps from frame to frame, because the set of sprites that you need to draw in one frame are usually the same set that you need to draw the next frame). Each of your enemies or characters or whatever-the-heck-you-likes that are graphically visible (i.e. aren't invisible objects like triggers or spawn points) will have a pointer to an entry in this list. If the object moves or changes state, it goes through the pointer and updates the relevant information about where its sprite should be and which frame of animation it should display.

When it comes to actually rendering all these objects, you've got every sprite in a nice list and you can use a predicated sort (a sort where you provide code that tells the sort algorithm how to compare two entries) to sort them however you like - by depth, by spritesheet, etc.

What you end up with is something like the following. (This is off the top of my head to convey an idea, it probably doesn't compile):

*** Source Snippet Removed ***



oooh thank you, i was wondering exactly how to go about doing this; i was basically doing what you were except i didn't have a list object, instead i had a vector

although, won't sorting every cpu cycle be really intensive?


anyway thanks ill have to check it out more later ^^

This topic is closed to new replies.

Advertisement