Jump to content
  • Advertisement

Archived

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

random

Fast and dirty opacity algorithm (check it out :)

This topic is 6452 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

Hey all, Been working on alpha/opacity rendering on 2d surfaces. I read a bunch of articles by different people on how to do it and then decided "to hell with it, lemme try this." It''s not exactly an accurate opacity generator, but it''s darned close. Light areas tend to get lighter and any black (0x000000) areas totally disappear. Anyways, give me your opinions and if you see any optimiziations I''d be more than interested in it. I should mention that the algorithm also covers sizing, thus there''s a few "extra" variables in it. I''m not overly concerned about the sizing part of it right now, that part has been only minimally optimized.
srcDD.lPitch >>= 2;
destDD.lPitch >>= 2;
destRaw += destDD.lPitch * p.y + p.x;
srcRaw = (DWORD*)srcDD.lpSurface;

for (indexYd = 0, indexYs = 0; indexYd < bHeight; indexYd++, indexYs += advGfxY)
{
  for (indexXs = 0; indexXs < bWidth; indexXs += advGfxX)
  {
    srcVal = srcRaw[(int)indexXs];
    *destRaw |= (lookup[(BYTE)(srcVal    )]    ) |
                (lookup[(BYTE)(srcVal>>=8)]<<8 ) |
                (lookup[(BYTE)(srcVal>> 8)]<<16);
    destRaw++;
  }
  destRaw += dpitch;
  tempY = (int)indexYs;
  if (tempY)
  {
    srcRaw += spitch * tempY;
    indexYs -= tempY;
  }
}
 
An explanation... most of you won''t need this, but here it is anyways. Resets the pitch to the size of a DWORD instead of unsigned char.
srcDD.lPitch >>= 2;
destDD.lPitch >>= 2;
 
Set start points for each graphic.
destRaw += destDD.lPitch * p.y + p.x;
srcRaw = (DWORD*)srcDD.lpSurface;
 
Loop through the height of the graphic (bHeight). (int)indexYd is a destination pixel counter whereas (float) indexYs is the source index counter. advGfxY is a float which specifies how far ahead each iteration should move in the y direction.
for (indexYd = 0, indexYs = 0; indexYd < bHeight; indexYd++, indexYs += advGfxY)
{
 
Basically, this is a standard pixel copy. The difference is, since we''re doing opacity, we''ll OR the original with a lookup value of the source. The lookup value is a 256 byte array and is set beforehand (when they set the opacity of a sprite) with the calculation: lookup[index] = (BYTE)(opacity * index); opacity is a value ranging from 0.0f to 0.99f. Opacities outside of this range are handled a touch differently (opacity is ignored )
  for (indexXs = 0; indexXs < bWidth; indexXs += advGfxX)
  {
    srcVal = srcRaw[(int)indexXs];
    *destRaw |= (lookup[(BYTE)(srcVal    )]    ) |
                (lookup[(BYTE)(srcVal>>=8)]<<8 ) |
                (lookup[(BYTE)(srcVal>> 8)]<<16);
    destRaw++;
  }
 
Here, we advance the destination raw by dpitch, which is simply (destDD.lPitch - graphic width). Then, we check to see if we need to advance the source Y. The only case in which we shouldn''t advance is if the graphic is being stretched on the Y axis. I haven''t put a whole lot of thought into this part of it yet. It works though.
  destRaw += dpitch;
  tempY = (int)indexYs;
  if (tempY)
  {
    srcRaw += spitch * tempY;
    indexYs -= tempY;
  }
}
 
Anyways, if you guys could give me your opinions, I''d greatly appreciate it. Any optimizations are welcome (even assembly, muhaha!) I''ve got a feeling that some background colors combined with some foreground colors will produce "interesting" results, but I haven''t had time to test this all out yet. Thanks! --- Wait, you mean I have to actually... THINK?!

Share this post


Link to post
Share on other sites
Advertisement

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!