D3DXLoadSurfaceFromSurface

Started by
29 comments, last by ms291052 20 years, 6 months ago
I am currently rewriting my slow old 2D engine to be a little more efficient. In the old version it copied a bitmap pixel by pixel to the desired surface frame by frame, which was, of course, extraordinarily slow. Now I copy it once, to a stored surface which I then D3DXLoadSurfaceFromSurface to the desired surface. The only problem with this is that with my old version if the current pixel (the one it''s about to copy) matched the ColorKey, it was never copied and with D3DXLoadSurfaceFromSurface it copies black instead, forcing a black rectangle around all my 2D bitmaps I''m trying to display. Is there a way, to simply make D3DXLoadSurfaceFromSurface not touch instead of setting all the ColorKey-colored pixels to black?
Advertisement
hmmm.. It appears as though D3DXLoadSurfaceFromSurface is doing its job after all. It''s setting the appropriate pixels to ARGB(0,0,0,0) but my program''s still rendering them and I''m not quite sure why...
You should set the alpha blending related renderstates for the transparency to work.
Use the search function, this has been discussed many, many times here...

-Nik

Niko Suni

g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);

I have ALPHABLENDENABLE as well as SRC and DEST BLENDs. Did I leave out any other important ones?
Those seem OK. What about texture stage states? In particular, alpha source state?

-Nik

EDIT:
Use D3DBLEND_INVSRCALPHA for dest factor, see if that has any effect (i doubt it).

[edited by - Nik02 on October 12, 2003 5:08:17 AM]

Niko Suni

g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );

EDIT:
D3DBLEND_INVSRCALPHA had no effect either

[edited by - ms291052 on October 12, 2003 5:19:00 AM]
Are you ABSOLUTELY sure that the texture really contains an alpha channel? Just ruling out the possibilities

-Nik

Niko Suni

The BMP doesn''t but the pixels do when they get to the surface... Assuming all unshown functions work (they do) here''s my code:
void CBitmap::DrawBitmap(DWORD* pDestData, int DestPitch, LPDIRECT3DSURFACE9 pDestSurface){	if(!RenderedOnce)	{		D3DLOCKED_RECT LockedRect;		pDestSurface->LockRect(&LockedRect, NULL, 0);		pDestSurface->UnlockRect();		pDestData = (DWORD*)LockedRect.pBits;		DestPitch = LockedRect.Pitch;		RenderedOnce = true;		LoadBitmapToSurface(strPathName, &pBitmapSurface, g_pd3dDevice);		D3DSURFACE_DESC d3dsd;		pBitmapSurface->GetDesc(&d3dsd);		width = d3dsd.Width;		height = d3dsd.Height;		HRESULT r = 0;		int OffsetX = 0, OffsetY = 0;		POINT BmpDestPoint = {0,0};		RECT BmpRect = {0,0,0,0};		OffsetX = rect.left;		OffsetY = rect.top;		SetRect(&BmpRect, OffsetX, OffsetY, rect.right, rect.bottom);		BmpDestPoint.x = x;		BmpDestPoint.y = y;		D3DLOCKED_RECT LockedBitmap;		r = pBitmapSurface->LockRect(&LockedBitmap, 0, D3DLOCK_READONLY);		if(FAILED(r))			return;		DWORD* pBMPData = (DWORD*)LockedBitmap.pBits;		LockedBitmap.Pitch /= 4;		DestPitch /= 4;		int BMPOffset = OffsetY * LockedBitmap.Pitch + OffsetX;		int DestOffset = y * DestPitch + x;		for(int cy = 0; cy < (rect.bottom - rect.top); cy++)		{			for(int cx = 0; cx < (rect.right - rect.left); cx++)			{				if(bTransparent)				{					if(pBMPData[BMPOffset] != ColorKey)						pDestData[DestOffset] = pBMPData[BMPOffset];					else						pBMPData[BMPOffset] = D3DCOLOR_ARGB(0, 255, 0, 255);				}				else				{					pDestData[DestOffset] = pBMPData[BMPOffset];				}				BMPOffset++;				DestOffset++;			}			DestOffset += DestPitch - (rect.right - rect.left);			BMPOffset += LockedBitmap.Pitch - (rect.right - rect.left);		}		pBitmapSurface->UnlockRect();		cout << "Copying..." << endl;	}	RECT rect3 = {x, y, x + width, y + height};	D3DXLoadSurfaceFromSurface(pDestSurface, NULL,&rect3,pBitmapSurface,NULL,NULL,D3DX_DEFAULT,D3DCOLOR_ARGB(0, 255, 0, 255));}

and the ColorKey is (255, 0, 255).
And for what it''s worth:
class CBitmap{public:char* strPathName;int x, y, height, width, xVel, yVel;BOOL bTransparent;BOOL RenderedOnce;BOOL draw;D3DCOLOR ColorKey;RECT rect;LPDIRECT3DSURFACE9 pBitmapSurface;CBitmap();~CBitmap();void DrawBitmap(DWORD* pDestData, int DestPitch, LPDIRECT3DSURFACE9);void Update();void GetBounds(RECT* prect);BOOL Intersects(CBitmap* cbmp);};
Can you spot a bug?

if(bTransparent){	if(pBMPData[BMPOffset] != ColorKey)		pDestData[DestOffset] = pBMPData[BMPOffset];	else						pBMPData[BMPOffset] = D3DCOLOR_ARGB(0, 255, 0, 255);	}				else				{		pDestData[DestOffset] = pBMPData[BMPOffset];}


-Nik

[edited by - Nik02 on October 12, 2003 5:40:51 AM]

Niko Suni

err...
test pixel against the color key... if it''s not the same, then copy it, otherwise set it to (0, 255, 0, 255)

unless I''m missing something, that code''s clean (although I''m known for missing the obvious)

This topic is closed to new replies.

Advertisement