Archived

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

Hanzo

CTileSet::PutTile modified to color tile?

Recommended Posts

I'm working with the CTileSet() class that Ernest created for the Isometric book. A lot of the tiles I am using are very simple (like, 2 colors!)...but the functionality I need is the ability to color these tiles dymamically. It would be nice to be able to modify PutTile() so that it could take a color, and alternately Blt() the tile to the surface in its new color. I thought this would be as simple as adding ddbltfx with a dwFillColor property to the Blt(), with the flag DDBLT_COLORFILL. Sadly, when I use this, I get nothing drawn to the screen. I have tried all combinations of DDBLT_COLORFILL, DDBLT_WAIT and DDBLT_KEYSRC, to no avail. Any tips would be appreciated. - Hanzo Edited by - Hanzo on October 20, 2001 7:07:45 PM

Share this post


Link to post
Share on other sites
One idea, although admittedly low level, would be to lock the surface you are drawing to, retrieve a pointer to it, and then color the pixels in it, one at a time. You have to run through two nested loops. One (the outer loop) would move vertically down the tile and the other would make horizontal sweeps across the tile, coloring in its pixels. This horizontal loop would not have a fixed number of iterations. Instead it would start with like 2, then have 4, then 6, until you reach the maximum width of the tile, and then it starts to decrease by 2 again.

If you have a limited number of colors, how about just making an array of different colored tiles?

Share this post


Link to post
Share on other sites
Using an array of differently color tiles would probably be the easiest solution to this problem. However, there is a lot of tile reuse that simply could benefit by being re-colored before the blt.

I think perhaps I need to be looking at an earlier call, LPDDS_LoadFromFile(), which is another function in Ernest''s class that creates an offscreen surface. I believe the surface must be ColorFilled before the bitmap is blitted to it, initially.

His function reads:

LPDIRECTDRAWSURFACE7 LPDDS_LoadFromFile(LPDIRECTDRAW7 lpdd,LPCTSTR lpszFileName)
{
//load the bitmap
CGDICanvas gdic;
gdic.Load(NULL,lpszFileName);

//create offscreen surface with same width and height
LPDIRECTDRAWSURFACE7 lpdds=LPDDS_CreateOffscreen(lpdd,gdic.GetWidth(),gdic.GetHeight());

//retrieve hdc for surface
HDC hdcSurf;
lpdds->GetDC(&hdcSurf);

//blit image onto surface
BitBlt(hdcSurf,0,0,gdic.GetWidth(),gdic.GetHeight(),gdic,0,0,SRCCOPY);

//release dc
lpdds->ReleaseDC(hdcSurf);

//return surface
return(lpdds);
}

My initial hunch is that you would set up a DDBLTFX structure, set the dwFillColor to your needed bitmap color, and perform a Blt with DDBLT_COLORFILL *prior* to the GDI BitBlt. My assumption is that you now have a surface filled with the color of the bitmap, so as you perform the BitBlt of the actual bitmap to the surface, the non key colors of the bitmap take on the color of the surface. However, I wouldn''t know if I''m right and executing the code improperly, or if I''m flat out wrong in theory, here.

- Hanzo

Share this post


Link to post
Share on other sites
Ok. Problem solved. Actually, it ended up being a lot more that just a fillcolor on the bitblit. Here's the process I ended up taking.

First, the tiles are loaded, a new surface is created, and they are bitblitted to the surface. The keycolor is then set...but not the color for the image's background. Instead, a new key color is used, a solid gray that is the color of all the sprites (gray on black). So in essense, the sprite itself has been made transparent, and its background is what becomes visible.

Next, a new surface is created to match the bitmap's dimensions. a DDBLTFX is created, and has it's dwFillColor set to the needed final color (let's say green). The new surface gets the colorfill blt. Then, that surface's keycolor is set to the original background transparency color (the black outline).

Finally, the original bitmap (transparent sprite with visible black background) is blittled to the new, fillcolored surface. In the process, the black outline paints over the colored surface and is removed as a keycolor, while the transparent sprite itself fills out the remaining shape of the lower colored surface. It basically carves itself out of the colored surface.

Voila. Repainted tiles.

- Hanzo

Edited by - Hanzo on October 24, 2001 2:01:38 AM

Share this post


Link to post
Share on other sites