Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sprite/polygon engine

0 views
Skip to first unread message

William Rubens

unread,
May 20, 1999, 3:00:00 AM5/20/99
to
Hello,

I'm currently developing a sprite/polygon engine for Directx. Nothing fancy
and it's all in 2D. I'm getting tired of 3D games so I'm going back to 2D.
Anyway, I'm a relative new-commer to the scene. I have two questions that I
would love some help on:

(1) At the start of every frame the sprites and triangles need to be erased.
Is it better for me to have a big surface, the size of the back buffer and
just blt from there on to the primary where sprites should be erased. Or,
should each sprite and triangle have its own smaller surface. The data for
erasing the sprite is stored there before it is drawn and blt to the
backsurface when it should be erased.

I realise that in terms of memory if there are a small number of sprites it
would be better to opt for each sprite has its own surface, and vice-versa.
But I would like to know if Directx prefers any method, and more importantly
would there be any speed differences.

(2) When the game runs in full screen, should I bother interacting with the
windows message subsytem. The DX samples do. The problem seems to be that
when I call any kind of message function (eg PeekMessage()) it seems to
erase the back buffer and the screen starts to flicker. I cannot find the
cause of the problem despite the fact that the sample seem to interact
perfectly with the subsytem in full screen mode.


Thanking you in advance,

William Rubens

Michael K

unread,
May 21, 1999, 3:00:00 AM5/21/99
to
If you don't regularly collect your messages from Windows, it assumes that
your program has stopped functioning and when/if the user hits Ctrl-Alt-Del
it will show up with that nasty (not responding) beside its name. Anyway, in
a released game you will want to talk to Windows. It tells you all sorts of
stuff that your game will need to know, like if the user has changed the
desktop bitdepth or moved your window or tried to change your game to
fullscreen/windowed.

Michael K

Frank Schoondermark

unread,
May 21, 1999, 3:00:00 AM5/21/99
to
>(1) At the start of every frame the sprites and triangles need to be
erased.
>Is it better for me to have a big surface, the size of the back buffer and
>just blt from there on to the primary where sprites should be erased. Or,
>should each sprite and triangle have its own smaller surface. The data for
>erasing the sprite is stored there before it is drawn and blt to the
>backsurface when it should be erased.
>
>I realise that in terms of memory if there are a small number of sprites it
>would be better to opt for each sprite has its own surface, and vice-versa.
>But I would like to know if Directx prefers any method, and more
importantly
>would there be any speed differences.


If you have a parallel scrolling game, say with two layers scrolling at
different speeds, there is no need to keep a copy of the background since it
will always change.

If you have a game with a single (scrolling) background you have to take in
account the number of sprites you use. If it are a few it's better to keep a
copy of the background occupied by the sprite. If there are many you can
best keep a copy of the whole background.

I can't give any estimations for the number of sprites. It's best to just
try both methods and test which seems to give the best performance.

>(2) When the game runs in full screen, should I bother interacting with the
>windows message subsytem. The DX samples do. The problem seems to be that
>when I call any kind of message function (eg PeekMessage()) it seems to
>erase the back buffer and the screen starts to flicker. I cannot find the
>cause of the problem despite the fact that the sample seem to interact
>perfectly with the subsytem in full screen mode.


You should interact with the windows message subsystem. It tells you when a
user switches to another application. In that case you have to pause your
game. And when the window gets closed (WM_CLOSE)you have to send a post quit
message (PostQuitMessage(0)) or the application won't stop.

I use two threads in my DirectDraw applications: one thread which contains
the window and processes the neccesary messages. the other is running the
main program. This way I'm not bothered by the windows messaging thingy and
it's just like plain old DOS. ;-)

Frank Schoondermark

nekhbet

unread,
May 22, 1999, 3:00:00 AM5/22/99
to
On Thu, 20 May 1999 12:14:10 +0100, "William Rubens" <Rub...@btinternet.com> wrote:

>Hello,
>
>I'm currently developing a sprite/polygon engine for Directx. Nothing fancy
>and it's all in 2D. I'm getting tired of 3D games so I'm going back to 2D.
>Anyway, I'm a relative new-commer to the scene. I have two questions that I
>would love some help on:
>

>(1) At the start of every frame the sprites and triangles need to be erased.
>Is it better for me to have a big surface, the size of the back buffer and
>just blt from there on to the primary where sprites should be erased. Or,
>should each sprite and triangle have its own smaller surface. The data for
>erasing the sprite is stored there before it is drawn and blt to the
>backsurface when it should be erased.
>
>I realise that in terms of memory if there are a small number of sprites it
>would be better to opt for each sprite has its own surface, and vice-versa.
>But I would like to know if Directx prefers any method, and more importantly
>would there be any speed differences.
>

As far as I can tell, DDraw wouldn't particularly have a preference. If you're using page flipping,
then you need to either re-create the backbuffer every frame, or else keep track of where each
sprite was two frames back--because that's the buffer that'll be your backbuffer now. (I hope that
made sense....) for example:

frame 1: sprite is at (10, 10)
frame 2: sprite moves to (15, 15)
frame 3: as you compose frame 3, you're working with the buffer that was displayed in frame 1, so
you need to erase the sprite from (10, 10) before drawing it at (20, 20).

If you have a lot of sprites, then you'll probably be best off just having a background surface,
blitting that to the backbuffer each frame, then blitting the sprites on top of it. You might be
able to speed this up by keeping track of "dirty rectangles", and only blitting those, but I think
that the hardware blit would be fast enough that just doing the whole (visible) scene would be
easiest.

>(2) When the game runs in full screen, should I bother interacting with the
>windows message subsytem. The DX samples do. The problem seems to be that
>when I call any kind of message function (eg PeekMessage()) it seems to
>erase the back buffer and the screen starts to flicker. I cannot find the
>cause of the problem despite the fact that the sample seem to interact
>perfectly with the subsytem in full screen mode.
>

You definately want to retreive those messages. Even if you're not using them yourself, passing
them on to DefWindowProc is important--for example, that's how ESC-TAB minimizes your program. And
using the windows messaging system to pass yourself messages can be a lot cleaner than other
methods--PostQuitMessage() being a good example of an easy way of doing things. I'm not sure what
might be causing the backbuffer erases or screen flicker, though..... Are you using any GDI
functions? Are you reacquiring lost surfaces? Remember, if a lost surface is restored, you still
have to regenerate its contents.

>Thanking you in advance,
>
Hope it helps...

--------------
Jeff S.

DarkOpz

unread,
Jun 2, 1999, 3:00:00 AM6/2/99
to
//////////////////////////////////////////////
Redrawing question
//////////////////////////////////////////////

ok im doing the same thing your doing kinda.. i use DD flip and just erase
my back buffer every frame.. I still get 60 fps doing this. I made a demo of
a character like in Final Fantasy III that walks around in a town. If you
would like I can send you the .exe for it. It's 999k because of the
character's sprite sheat is in 32-bit color. your card needs to be able to
support 1024x768x32 , if it doesnt tell me and i will re-compile it.

//////////////////////////////////////////////
Windows Messages
//////////////////////////////////////////////

Oh i would suggest playing nice with windows or it might not play nice
back... it's not a big deal.

while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{

// Game code here.. or whatever.

}

}

//////////////////////////////////////////////
Sprite Question
//////////////////////////////////////////////

I suggest making a new surface for every sprite sheat.. That way you can use
the blt functions and if hardware blitting is available it will take full
advantage of it.


Contact me at Devi...@mindspring.com if you want that demo. It has bugs
like Tile collision but hey it looks cool.

DarkOpz

p.s. sorry if all the text comes out wierd my proggy was being a pain for
some reason

Rubens <Rub...@btinternet.com> wrote in message
news:7i0qsh$m0m$1...@plutonium.btinternet.com...


>Hello,
>
>I'm currently developing a sprite/polygon engine for Directx. Nothing fancy
>and it's all in 2D. I'm getting tired of 3D games so I'm going back to 2D.
>Anyway, I'm a relative new-commer to the scene. I have two questions that I
>would love some help on:
>
>(1) At the start of every frame the sprites and triangles need to be
erased.
>Is it better for me to have a big surface, the size of the back buffer and
>just blt from there on to the primary where sprites should be erased. Or,
>should each sprite and triangle have its own smaller surface. The data for
>erasing the sprite is stored there before it is drawn and blt to the
>backsurface when it should be erased.
>
>I realise that in terms of memory if there are a small number of sprites it
>would be better to opt for each sprite has its own surface, and vice-versa.
>But I would like to know if Directx prefers any method, and more
importantly
>would there be any speed differences.
>

>(2) When the game runs in full screen, should I bother interacting with the
>windows message subsytem. The DX samples do. The problem seems to be that
>when I call any kind of message function (eg PeekMessage()) it seems to
>erase the back buffer and the screen starts to flicker. I cannot find the
>cause of the problem despite the fact that the sample seem to interact
>perfectly with the subsytem in full screen mode.
>
>

iare...@my-deja.com

unread,
Jun 7, 1999, 3:00:00 AM6/7/99
to

> I use two threads in my DirectDraw applications: one thread which
contains
> the window and processes the neccesary messages. the other is running
the
> main program. This way I'm not bothered by the windows messaging
thingy and
> it's just like plain old DOS. ;-)
> Frank Schoondermark

Does this work? I've wondered about this in the past, but I've always
done my game loops with one-shot multimedia timers... Going as a thread
would kick ass! You're loop could just be a normal while loop... Wow..
Ok, so DOES THIS WORK? Is it fast enought? :)

Tony


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

Hakon Steinø

unread,
Jun 8, 1999, 3:00:00 AM6/8/99
to

iare...@my-deja.com wrote:
>
> > I use two threads in my DirectDraw applications: one thread which
> contains
> > the window and processes the neccesary messages. the other is running
> the
> > main program. This way I'm not bothered by the windows messaging
> thingy and
> > it's just like plain old DOS. ;-)
> > Frank Schoondermark
>
> Does this work? I've wondered about this in the past, but I've always
> done my game loops with one-shot multimedia timers... Going as a thread
> would kick ass! You're loop could just be a normal while loop... Wow..
> Ok, so DOES THIS WORK? Is it fast enought? :)
>
> Tony
>

Works fine for me. I haven't tested the speed yet, but the message
thread will be waiting most of the time (in most environments), so there
is very little overhead coming from context switching. So yes, it is
fast enough (not tested though!).

Just make sure you design your program in such a way that you won't have
to do any mutexes between the two threads.

- Hakon

SVR

unread,
Jun 8, 1999, 3:00:00 AM6/8/99
to
>Does this work? I've wondered about this in the past, but I've always
>done my game loops with one-shot multimedia timers... Going as a thread
>would kick ass! You're loop could just be a normal while loop... Wow..
>Ok, so DOES THIS WORK? Is it fast enought? :)
>
> Tony


I once converted the MS Fog demo to have a separate thread running the
render loop. The FPS dropped from 24 to 12. Using threads can make an app
more responsive by allowing input to process without waiting for other stuff
to finish but it can kill speed. The processor has to execute twice as many
instructions each render loop. You might say 'No it wont!' because it has to
do them 'inline' with one thread anyway. But it only has one 'loop'.
for example ...

proc Single
DoMsg
DoRender
Loop Single

proc Thread1
proc Thread2
DoMsg
DoRender
Loop Thread1
Loop Thread2

You can see the increase right away. Also the msg loop will most likely
execute a LOT more times during the render loop causing rendering to suffer
(not to mention the task switching overhead). Someone might think using
signaling will help but what's the point of making a loop sleep till the
other is done ? Might as well do it inline and save the cycles wasted on
task switching.

Besides, who needs the nightmare when Msg X changes Value Y and Renderer Z
explodes ;-)

Have Fun :)

Sloan


Hakon Steinø

unread,
Jun 9, 1999, 3:00:00 AM6/9/99
to

As i said... the msg loop is (supposed to be) sleeping most of the time.
Or do you have messages pumping through your msg loop at a rate higher
than your frame rate? I know i don't.

But.. as i said.. i haven't tested the speed yet. You might be right.

And - just for the record: it is not twice the amount of instructions.
It is only a matter of the overhead produced by context switching.

- Hakon

PS. I will probably go back to one thread some time in the future. The
dual-threaded version is just so much easier to debug, i think.

SVR

unread,
Jun 9, 1999, 3:00:00 AM6/9/99
to

>
>As i said... the msg loop is (supposed to be) sleeping most of the time.
>Or do you have messages pumping through your msg loop at a rate higher
>than your frame rate? I know i don't.


Yeah, if you call the 'blocking version' of your input function (GetMessage,
etc.) but what does that really do ? It sets there and loops (just like a
msg loop does with PeekMessage). People like to believe Windows is a
hardware driven pre-emptive OS but it isn't. Try making no Get/PeekMessage
calls in your msg loop and everything stops working.

Win98 is supposed to multitask better (than 95 did) but is still very bad.
It doesn't matter how many messages you get, a thread waiting on messages is
stealing CPU cycles from your render loop.

I haven't even mentioned cache thrash yet :)

I know what you mean about having to deal with the message loop though. It
was a lot easier when I was doing DOS coding. (Even when I had to write
handlers myself ;-) I try to get that same feel by wrapping up the msg
handling by itself and have it call my 'Main Loop' :)

Have fun ;-)
Sloan

Hakon Steinø

unread,
Jun 10, 1999, 3:00:00 AM6/10/99
to

SVR wrote:
>
> >
> >As i said... the msg loop is (supposed to be) sleeping most of the time.
> >Or do you have messages pumping through your msg loop at a rate higher
> >than your frame rate? I know i don't.
>
> Yeah, if you call the 'blocking version' of your input function (GetMessage,
> etc.) but what does that really do ? It sets there and loops (just like a
> msg loop does with PeekMessage). People like to believe Windows is a
> hardware driven pre-emptive OS but it isn't. Try making no Get/PeekMessage
> calls in your msg loop and everything stops working.
>

I do call GetMessage and no, it doesn't loop like a PeekMessage loop.
Right now my system (WinNT) is running 151 threads. If they were all
looping.... This post would reach you around christmas. There IS such a
thing as a sleeping thread. It may not be hardware, but software can be
quite capable too :)

> Win98 is supposed to multitask better (than 95 did) but is still very bad.
> It doesn't matter how many messages you get, a thread waiting on messages is
> stealing CPU cycles from your render loop.
>
> I haven't even mentioned cache thrash yet :)

True, but it steals no more than the other 150 threads.

> I know what you mean about having to deal with the message loop though. It
> was a lot easier when I was doing DOS coding. (Even when I had to write
> handlers myself ;-) I try to get that same feel by wrapping up the msg
> handling by itself and have it call my 'Main Loop' :)
>
> Have fun ;-)
> Sloan


Anyway - this discussion is getting pointless (but i am too damn
stubborn to quit :) I will try to change to a single-threaded
implementation and compare the speed to the dual-threaded.

- Hakon

SVR

unread,
Jun 10, 1999, 3:00:00 AM6/10/99
to

>Anyway - this discussion is getting pointless (but i am too damn
>stubborn to quit :) I will try to change to a single-threaded
>implementation and compare the speed to the dual-threaded.
>
> - Hakon

Yeah, we did stray from the topo a bit :) Let me know how the test goes. I
don't have NT at home, It should be better than Win95/98.

Sloan

nekhbet

unread,
Jun 13, 1999, 3:00:00 AM6/13/99
to
On Wed, 9 Jun 1999 14:26:06 -0500, "SVR" <s...@intcomm.net> wrote:

>
>>
>>As i said... the msg loop is (supposed to be) sleeping most of the time.
>>Or do you have messages pumping through your msg loop at a rate higher
>>than your frame rate? I know i don't.
>
>
>Yeah, if you call the 'blocking version' of your input function (GetMessage,
>etc.) but what does that really do ? It sets there and loops (just like a
>msg loop does with PeekMessage). People like to believe Windows is a
>hardware driven pre-emptive OS but it isn't. Try making no Get/PeekMessage
>calls in your msg loop and everything stops working.
>

Unless I'm seriously mistaken, GetMessage() does *not* sit in an endless loop waiting for a
message--it sleeps. When it gets a message, the thread wakes up. This is the whole point of
cooperative multitasking. Having a second thread in your program that is waiting on GetMessage()
won't slow your program down any more than having a different program sitting idle in the
background.

That being said, there's probably not much time advantage to using two threads as opposed to
something like

PeekMessage()
if message
then process...
else
run next frame

The advantage of the multithreading is that you don't have to wait for the whole frame to finish
rendering before you process any messages, thus increasing your program's responsiveness. The
disadvantage is that you have to do all the synchronization mumbo-jumbo, and that's a whole 'nother
headache. :)

-------------------
Jeff S.


Jeff S.
--------------
The old religion redefined
for the facile, futile, totally blind...
--Sisters of Mercy
"Floorshow"


Richard Garand

unread,
Jul 7, 1999, 3:00:00 AM7/7/99
to
I'm not sure i understand this synchronization problem. On a single CPU
machine, one thread will be running at a time (it will switch between
threads a lot i think), so unless it takes more that one operation to change
something there should be no problem. Does anyne have an exmaple of how a
synchronization would work?

nekhbet

unread,
Jul 10, 1999, 3:00:00 AM7/10/99
to
On Wed, 7 Jul 1999 12:43:46 -0600, "Richard Garand" <krog...@hotmail.com> wrote:

>I'm not sure i understand this synchronization problem. On a single CPU
>machine, one thread will be running at a time (it will switch between
>threads a lot i think), so unless it takes more that one operation to change
>something there should be no problem. Does anyne have an exmaple of how a
>synchronization would work?

The problem is that with a time-slicing OS, you never know when your thread will get sliced out. As
a quick minor example--

buffer = GetSensorReading()
if (buffer < THRESHOLD) { ..... }

Now, the problem comes when your thread's timeslice ends in between the assignment and the
comparison. If another thread changes buffer, then your comparison is meaningless. This can result
in a wide range of problems, or might have no effect at all, depending on just what the other thread
happens to be doing. If, say, the second thread fills buffer with a reading from a different
sensor, you could end up with Chernobyl. :) The solution is to use some form of synchronization to
let other threads know that this thread is using buffer, and the other thread will need to wait
until this thread is done with it. There are several different methods of synchronizing (critical
sections, mutexes, semaphores, etc), each having their own advantages/disadvatages/specific
purposes.

-------------------
Jeff S.

0 new messages