Optimizing Fire Effect

Started by
10 comments, last by Phillip Schuster 24 years, 5 months ago
I noticed a couple of things. First, this line:

color = color / blurval;

Is blurval between some known boudries? Are you always going to get one of the same, say, 100 values when you do the division on this line? If so, you could make an array of the possible answers to this division and store them in memory instead of doing the divide.

I tried looking at the for loop but it looks like some code was snipped out (there are more closing brackets at the bottom of your function than there are opens). So either something is missing, or i'm just *really* not awake yet enough to understand your for loop. If there is more code to it, there may be a way to "unroll" that second for() statement some and shave a few other instructions off. Anyway, hope this helps. --Nolan

[This message has been edited by nolan (edited November 08, 1999).]

Advertisement
I have an optimised fire demo available at: http://skyscraper.fortunecity.com/compiler/379/download/fire.zip
It's written in TC 3.0/BC 5.0 and uses asm.
A few comments about this...

I noticed you are using straight Windows API's to do this. I would consider looking into DirectX. If nothing else, do not use SetPixel. Create a memory DC and blt from it to your real one. This way you can use straight memory operations instead of calling SetPixel. That should help a bit.

I wrote a DirectX version of the fire simulation on the flipcode page at: http://www.flipcode.com/demomaking/issue05.shtml

One thing to notice about his filter is that it sums up the numbers of 8 pixels and does a shift right 3 to divide by 8. Accessing only 5 pixels and dividing by 5 is probably still quicker.

I implemented his source code, and decided to use inline assembly for the actual part that does the filter. I let the compiler compile the normal C++ code, then I looked at the disassembly. I was able to notice a lot of optimizations that could be made to that assembly. It kept putting the same values into one of the registers and things like that.

There are bigger issues though...
I would worry about using this effect, since it is framerate dependent. In other words, you can't calculate the time between frames and tween it somehow. Your fire can only move once per frame. In my example, I could get my fire moving at 75 fps in 320x240 (due to V-Sync), but when I went to 640x480, I can only get 42 fps. It took me quite a bit of work to get to 42 fps...

Good luck with whatever you're working on...it sounds fun!

------------------

-Kentamanos

[This message has been edited by Kentamanos (edited November 08, 1999).]

-Kentamanos
how would you go about making a collision detection thing with d3dim?

how would you go about testing collision detection ? i know the um is x is in x2 thing.. but umm how would you check for stuff like stairs? how do you check if you are at stairs and then go up the stairs? would you just do ifs to all objects? or is there better ways?

i doubt this is any help, but hell ill post the code to my dos 8-bit mode 13h fire effect for a demo i did (hmm why did i call it PLAZ?)

void Burn(unsigned long ulBufStart, unsigned long ulBufEnd)
{
unsigned int nC, nC2;

for (nC = ulBufStart; nC < ulBufEnd; nC+=2)
{
nC2 = (double_buffer[nC + 320] + double_buffer[nC + 639] + double_buffer[nC + 640] + double_buffer[nC + 641]) / 4;
if (nC2)
nC2--;
double_buffer[nC] = (unsigned char)nC2;

nC2 = (double_buffer[nC + 321] + double_buffer[nC + 640] + double_buffer[nC + 641] + double_buffer[nC + 642]) / 4;
if (nC2)
nC2--;
double_buffer[nC + 1] = (unsigned char)nC2;
}
}


well its not that optimized but i wanna post summit

Hi all !!

Ok, thanks for your help )
Perhaps I didn't write enough or I didn't give you enough source )
The function SetPixel is my own function of my class ByteMemory. This class allocates a number of bytes. So, SetPixel is not a call to GDI which is way too slow. SetPixel just copies the byte into the position of the bytememory. So, I don't think that SetPixel could be made faster.

I never learned assembler. Some people say it's useless today (with modern compilers) and if you can speed things up the little increase in speed is not worth the effort.

My procedural textures (Unreal uses the same technology for it's water fx and flames and so on) are quite fast now, but I don't think fast enough.

You can download a demo of my 3DEngine at www.voodoospotlight.com/devknowledge/downloads/demos/3dengineinstall.exe !! There you can see my procedural textures.

So, my question: Do you think is it worth to learn assembler and do that stuff in asm or isn't it worth the effort to learn assembler.

Phillip

Phillip Schuster

Just a little note to fix your code (if you want to go back and edit it):

Put spaces around your < and > operators, otherwise UBB will think
they are HTML tags and rip them out.

Reaver

I have a couple of suggestions:

1) Never make function calls in tight loops - If you need to re-use the code, use a macro (or possibly an in-line function). Functions have a rediculous overhead.

2) Whenever people tell you that optimizing C++ compilers produce better asm: Ignore them! C++ is VERY hard to optimize because of the extreme freedom built into the language. You don't have to be an ASM wiz to get a x2 speed increase from tight inner loops like the one you have - simply take the compiled (non optimized) code, disassemble it and remove the most obvious blunders.

/Niels

<b>/NJ</b>
You should definately learn asm.
You can optimise every PIECE of your code.

And when we will be set back and compilers doesn't work anymore (I know it never will ) we all have to use assembler again.

Yes - C++ can optimize as much as ASM but the way that C++ is similar to basic and the way you have to think harder about what youre doing in ASM makes you optimize in your head.

This topic is closed to new replies.

Advertisement