#### Archived

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

# Optimizing Fire Effect

This topic is 6604 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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).]

##### Share on other sites
It's written in TC 3.0/BC 5.0 and uses asm.

##### Share on other sites

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).]

##### Share on other sites
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?

##### Share on other sites
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

##### Share on other sites
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.

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

##### Share on other sites

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

##### Share on other sites
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

##### Share on other sites
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.

##### Share on other sites
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.

##### Share on other sites
When I say C++ is hard to optimize, I don't mean from a progammers perspective, I mean from the compilers perspective.

As a programmer, you know a lot about the code you write (for example the possible domain of variables, certain special cases that never occur etc.), because of all the sh*t you can do in C++ (e.g. pointer arithmetics) the compiler can't make ANY assumptions as to what the programmer inteded with a piece of code, but have to go by the book - producing code with a large, frequently unnecesarry, overhead.

In most cases this is completely irrelevant, but for tight loops where each statement is executed millions of times each frame, every cycle counts.

Java beeing a much more strict language is a lot easier to auto-optimize.

/Niels

##### Share on other sites
Hi all !!

I am currently developing my own 3DEngine and I use procedural textures. One of these textures uses that simple fire-effect. I think all of you know that. The texture is 8Bit (so Palettized). My question is:

How can optimize the routine below ??? It's more a less a Blur-Filter. Is it worth to do it in assembler or can you think of other optimisations ??

code:
void C8BitTexture::Fire(int blurval){	long x,y;	int color = 0;	for (y=1;y		for (x=1;x			color = 0;			color += (int)GetByte((y*width)+x);			color += (int)GetByte(((y-1)*width)+x);			color += (int)GetByte((y*width)+x+1);			color += (int)GetByte(((y+1)*width)+x);			color += (int)GetByte((y*width)+x-1);			//If we divide by 5 and do not set color to 0 it gives a very 			//interesting effect			color = color / blurval;						if (color > palette.numColors) color = palette.numColors;						SetPixel(x,y-1,color);		}	}}

Phillip

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

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

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

• ### Forum Statistics

• Total Topics
628686
• Total Posts
2984234

• 14
• 13
• 13
• 10
• 10