Advertisement

Transparent sprite image can't be used in DirectDraw?

Started by December 20, 2020 05:25 AM
6 comments, last by eu5 3 years, 10 months ago

Hi. I got sprite images. these images are transparent like next image. but some people say DirectDraw does not support alpha blending. It means I can't use transparent sprite image?

Hi,

How will you render the sprites on the screen? Is there code for it that does not work, or is the question more general. Like, is it possible at all do have transparency in sprites?

To the general question:

Yes, you can have transparent backgrounds in sprites. This is how *all 2D games work. No 2D game would be possible without this feature (or at least look good), and as you can easily google, there are plenty 2d games out there. I made a nr of them myself, with sprites and transparent backgrounds as a given feature.

For the DirectDraw part of the question, I do not know the state of DirectDraw nowadays, I haven't been using it forever, but I use libraries that use it, and they are perfectly able to do 2d sprites with transparent backgrounds, so yes it is possible.

When googling a bit more, you find, there are certain issues with transparency and 2d sprite drawing. There seem to be ways that it works and ways that it does not work. But here we go into details, and you would need to share some code snippet or so, to explain what does not work.

ps. Some of the googling lead me to this thread: https://www.gamedev.net/forums/topic/256775-directdraw-transparency/​​ , maybe it is helpful to read.

Good luck

/C

Chao55 / Retro Games, Programming, AI, Space and Robots

Currently working on HyperPyxel paint program - http://www.hyperpyxel.com​​ and an asteroids clone under my "Game1" javascript game "engine".

Advertisement

@chao51 Thank you! my rendering way has next a few step.

  1. Read a bitmap file. (I used a image that has a magenta for color key)
  2. Get pixel data(RGBA) from the bitmap except a magenta pixel and store in my buffer.
    (Actually pixel's type is like 0x00BBGGRR. alpha is fixed for ZERO. so I thought a transparent sprite can't be used)
  3. write pixels in backbuffer from the buffer.

Hi,

I am not sure I am helping, I am just being social, and trying to ask questions so you find the answer yourself. I am sure someone else on the board is more qualified to talk about DirectX then me, I used it 15 years ago, and found it to tedious, and went instead for a library called SDL. I am sure you can create great things with DirectX itself, and if you are being a professional I am sure it's worth learning the bits and the bytes of it, but to me Microsoft moved to much each time I got a hold on things. When they went from DirectX 7 to 8, I threw in the towel, and went for a wrapper library instead, so I could focus on the game instead of the quirks of direct draw. But that is probably just me.

Anyway, to make sure I get your question right, which version of DirectX are you using? And are you trying to use DirectDraw or DirectX? There seem to be significant difference in the aproach.

At the same time, maybe it is also good to double check that you image is saved in a format that can hold alpha information. For example PNG holds alpha information, but BMP and GIF does not.

Anyway, some background info, that maybe helps.

An alpha channel, is transparency information that usually comes from when you load a picture, it can be 0% or 100% or in between. It's nice for explosions and particle/light effects.

Transparent. A pixel of a certain colour can be transparent, just like you do. In the old days it was called colour key. You usually had an image of 8 bits (256 colors), and these colours were not defined per pixel, but seperatly in a palette. With the colour key, you could say which colour in the palette you want to treat as transparent.

What I am doing in my JavaScript engine (sorry, not coding c++ now), is similar to what you do, but a bit different.

I load the image, put it into the canvas (==buffer), and then I set the alpha channel byte in the bitmap for each pixel to either fully or not at all transparent (in the same image). Then I use normal drawimage functions on the mage, where I manually introduces an alpha channel. Why do I do like this? It is easier to work in a paint program with visible colours then invisible colours (at least to me it is).

Cheers
/C

Chao55 / Retro Games, Programming, AI, Space and Robots

Currently working on HyperPyxel paint program - http://www.hyperpyxel.com​​ and an asteroids clone under my "Game1" javascript game "engine".

You can not use transparency direct from the source image (the alpha channel), but using color key. This mean you need to select one color (RGB value) which will be “left out” when rendering the sprite. Usually this color was magenta (RGB(255, 0, 255), but you can use whatever color you want.

image with magenta as transparent region

Use can modify you sprite in any image editor to do this, or you can load the RGBA version and using this A channel info to change RGB pixels to this transparent value.

After you loaded the image and created the IDirectDrawSurface7 object, the DDSetColorKey does this:

(sorry for the quality of this code, i wrote it 16 years ago :) )

DWORD DDColorMatch(IDirectDrawSurface7* lpdds, COLORREF rgb)
{
	COLORREF		rgbT;
	HDC				hdc;
	DWORD			dw = CLR_INVALID;
	DDSURFACEDESC2	ddsd;
	HRESULT			hRes;

	if(rgb != CLR_INVALID && lpdds->GetDC(&hdc)== DD_OK)
	{
		rgbT = GetPixel(hdc,0,0);
		SetPixel(hdc,0,0,rgb);
		lpdds->ReleaseDC(hdc);
	}
	
	ddsd.dwSize = sizeof(ddsd);
	while((hRes = lpdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
;
	
	if(hRes == DD_OK)
	{
		dw= *(DWORD*)ddsd.lpSurface;
		if(ddsd.ddpfPixelFormat.dwRGBBitCount<32)
			dw &= (1<<ddsd.ddpfPixelFormat.dwRGBBitCount)-1;
		lpdds->Unlock(NULL);
	}

	if(rgb != CLR_INVALID && lpdds->GetDC(&hdc) == DD_OK)
	{
		SetPixel(hdc,0,0,rgbT);
		lpdds->ReleaseDC(hdc);
	}

	return dw;
}

void DDSetColorKey(IDirectDrawSurface7* lpdds, COLORREF rgb)
{
	DDCOLORKEY	ddck;

	ddck.dwColorSpaceLowValue = DDColorMatch(lpdds, rgb);
	ddck.dwColorSpaceHighValue= ddck.dwColorSpaceLowValue;
	lpdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
}

Drawing this image with color key:

lpBuffer->BltFast(tscreenx, tscreeny , lpTile[0], &tr, DDBLTFAST_SRCCOLORKEY);

@JariRG I'm late. Thank you!

Advertisement

@chao51 No. your first answer already helped me a lot. and second one too. I just wrote my rendering way. thank you!

This topic is closed to new replies.

Advertisement