Archived

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

Fading

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''ve tried to make a fading in 32-bit color with help from ironblayde''s tutorial, but I can''t make it right, could someone please help me?
  
void Fade(DDSURFACEDESC ddsd, float pct)
{
	USHORT* temp = (USHORT*) ddsd.lpSurface;
	int jump = ddsd.lPitch - resolution_x;
	UCHAR r,g,b;
	USHORT color;

	for(int y = 0; y < resolution_y; y++)
	{
		for(int x = 0; x < resolution_x; x++)
		{
			color = *temp;

			r = (color & 0xF800) >> 16;
			g = (color & 0x0730) >> 8;
			b = (color & 0x001F);

			r = (UCHAR) ((float) r * pct);
			g = (UCHAR) ((float) g * pct);
			b = (UCHAR) ((float) b * pct);

			*temp= RGB_32BIT(r,g,b);
		}

		temp+= jump;
	}
}
  

Share this post


Link to post
Share on other sites
So what is it doing wrong?

I may be wrong, but I was rather under the impression that the correct way to seperate the RGB values is:
  
r = (color & 0xFF000) >> 16;
g = (color & 0x00FF0) >> 8;
b = (color & 0x000FF);


Signatures? We don''t need no steenking signatures!

Share this post


Link to post
Share on other sites
what sort of unsigned short are you using?
unsigned short is usually 16bit unless you specify it to be 32. Try using unsigned long (unsigned int is usually 32 bit as well).

Share this post


Link to post
Share on other sites
I''ve tried to use unsigned long, but I get the same problem.

I''m locking the back surface, then i''m calling that function and then unlocking the back surface. I don''t know what I''m doing wrong, could someone show me a example code on how to use fading? please?

Share this post


Link to post
Share on other sites
Well other than needing it to be 32 bit ULONG, look at your hex values, and also I believe your jump is incorrect. If resolution_x is just the width of the screen (or where you want to start at) then you need to shift the lPitch by two (I think you need to do this anyway). At present your jump is probably negative, this should fix that.

Also, your not updating where temp points to during the second loop. So your only updating the same pixel over and over again.

Share this post


Link to post
Share on other sites
Thanks alot for all your help. I've changed my code, but It still doesn't write over the whole area. I don't understand the last note you did TheFez. I get the latest pixel by color = *temp; And changing temp to the next line by jump =(ddsd.lPitch>>2) - resolution_x; Is there something else I should do?

Edited by - delbogun on October 31, 2001 3:45:31 AM

Share this post


Link to post
Share on other sites
try this: just worked it out in my head, might not be "exactly" correct but it's on the way.

One of the reasons why yours was not working ont he whole screen is because you have to do temp++ at the end of every for(x) and you only move temp at the end of every for(y). So the amount of pixels faded is your resolution_y on each scanline and not the whole screen.

The code is below...

    

// fading effect


void Fade(DDSURFACEDESC &ddsd, float pct)
{

USHORT *buffer;

long jump_x;

UCHAR r,g,b;

USHORT color;


buffer = (USHORT *)ddsd.lpSurface;

jump_x = ddsd.lPitch - resolution_x;

for (int y=0; y<resolution_y; y++)
{

for (int x=0; x<resolution_x; x++)
{

// value color from buffer


color = *buffer;

// extract each component from the color


r = (color & 0xF800) >> 11;
g = (color & 0x07E0) >> 5;
b = (color & 0x001F);

// apply the fading effect


r = (UCHAR) ((float) r * pct);
g = (UCHAR) ((float) g * pct);
b = (UCHAR) ((float) b * pct);

// store it back


*buffer = ((USHORT)r<<11)|(g<<5)|b;

buffer++;

} // end for x


buffer += jump_x;

} // end for y


} // end Fade




Hope this helps!

Edited by - Gladiator on October 31, 2001 3:59:22 AM

Share this post


Link to post
Share on other sites
This should work better for you. You need to have a 32bit source surface and a 32bit primary surface to use this code!

  
void Fade(DDSURFACEDESC ddsd, float pct)
{
//can use int or unsigned int same thing

int *temp = (int*) ddsd.lpSurface;
//resolution_x are pixels

//ddsd.lPitch is bytes

//each pixel is 4 bytes in 32bit mode

int jump = ddsd.lPitch - (resolution_x*sizeof(int));

for(int y = 0; y < resolution_y; y++)
{
for(int x = 0; x < resolution_x; x++)
{
int color = *temp;
//this is for 32bit color not 16bit

//8bit shifts or 0 - 255

char r = (color & 0x00ff0000) >> 16;
char g = (color & 0x0000ff00) >> 8;
char b = (color & 0x000000ff);
//can use char or unsigned char same thing

r = (char) ((float) r * pct);
g = (char) ((float) g * pct);
b = (char) ((float) b * pct);
*temp = (r << 16) | (g << 8) | (g << 0)
//don''t forget to move to the the next pixel

temp++;
}
temp += jump;
}
}

Share this post


Link to post
Share on other sites
delbogun, what I meant was that your not moving the temp pointer to the next pixel:

color = *temp;
r = (color & 0xF800) >> 16;
g = (color & 0x0730) >> 8;
b = (color & 0x001F);
r = (UCHAR) ((float) r * pct);
g = (UCHAR) ((float) g * pct);
b = (UCHAR) ((float) b * pct);
*temp= RGB_32BIT(r,g,b);

This is what you had as your code in the for(int x...) loop. I noticed that you do not change the location of temp. So while it is in that loop, your not updating the position (so it stays the same until you leave that loop).

Share this post


Link to post
Share on other sites
Thanks for the help, I really appreciate it.
Ok, I understand now fez. That's logical.
I've tried your version burp, but I get one little problem on it. The colors is wrong. It's suppose to get darker, but all I get is some strange random colors. I have a 32bit surface and are using 32bit images. I suppose you meant to put (b << 0) and not g in the buffer. If I put pct to 1, I should get the original colors, but I don't. The green colors becomes orange..


Edited by - delbogun on October 31, 2001 10:45:20 AM

Share this post


Link to post
Share on other sites
Just a question, doesn''t that sort of thing require the surface to be locked, for a measurably long time?

I don''t use DirectDraw much anymore (I''ve gone to OpenGL) but I thought you shouldn''t lock surfaces for any long amount of time...

Share this post


Link to post
Share on other sites
Yes, I believe that code would be incredibly slow, but I don''t think locking a surface for a long time would do any harm.

As for the colors getting messed up, maybe you should use ULONGs for the r, g and b values. They might be getting shifted 8 and 16 digits, and since they''re 8-bit values, they''re getting shifted all to zeroes.

try this, it should be a lot faster (and hopefully work right):
  
void Fade(DDSURFACEDESC ddsd, float pct)
{
DWORD *buf = (DWORD*)ddsd.lpSurface;
DWORD jump = (ddsd.lPitch - ddsd.dwWidth) >> 2; //you''re moving 4 bytes at a time, so divide by 4

DWORD color, percent = (DWORD)(256.0f * pct); //it''s much faster to use fixed point since you''re converting to/from float 3 times per pixel


for(int y = 0; y < ddsd.dwHeight; y++)
{
for(int x = 0; x < ddsd.dwWidth; x++)
{
color = *buf;
*buf++ = (((color >> 16 & 0xff) * percent >> 8) << 16)|
(((color >> 8 & 0xff) * percent >> 8) << 8) |
((color & 0xff) * percent >> 8);
}
buf += jump;
}
}


Sorry if it''s not too clear what it''s doing, but if you do all the color calculations in one statement, you don''t have to declare the extra variables for r, g and b.
If you want, you can change it to do the colors like (color & 0x00ff0000 >> 16) like everyone else did instead of shift first and then AND with 0xff on every color, but I think it looks better that way cause it doesn''t take as much room^_^

Also, if you''ve never used fixed point math, try using a calculator to multiply 256 by some number between 0 and 1 (which would be pct in the program), then multiplying that by any number you want (this will be the color value), and dividing by 256. You should get the same result as if you multiplied the color value by pct directly. In computers, it''s faster to do a shift than a float/int conversion, so that gives it a big speed boost.

Hope this helps^^



-Deku-chan

DK Art (my site, which has little programming-related stuff on it, but you should go anyway^_^)

Share this post


Link to post
Share on other sites
YES!!! It WORKS!! Many Thanks!!
DekuTree64, your code seems to be fastest, but this line: "(ddsd.lPitch - ddsd.dwWidth) >> 2" makes my computer hang up for a strange reason... but if i''m using "ddsd.lPitch - (resolution_x*sizeof(int))" like burp wrote, it works :D

Share this post


Link to post
Share on other sites