Val
08-22-2006, 09:13 PM
Hello,
I am using the following C++ function to generate a region from a Direct3D9 surface with transparent areas. The only problem is that when I am looping through pixels, I am not getting the right ones. I can't for the life of me figure out how to "stay within a rectangle" when looping through DWORDS where pixels are stored.
BOOL CThunderRgn::GenerateFromSurface(LPDIRECT3DSURFACE9 pSurf, const LPRECT prcTexCoords)
{
if(!pSurf || !prcTexCoords) return FALSE;
if(!Release()) return FALSE;
D3DSURFACE_DESC desc;
if(FAILED(pSurf->GetDesc(&desc))) return FALSE;
// Surface format must be A8R8G8B8 or X8R8G8B8
if(desc.Format != D3DFMT_A8R8G8B8 &&
desc.Format != D3DFMT_X8R8G8B8)
return FALSE;
// Get surface bits
D3DLOCKED_RECT lock;
HRESULT hr = pSurf->LockRect(&lock, prcTexCoords, D3DLOCK_READONLY);
if(FAILED(hr)) return FALSE;
// Create subregions for each scanline, excluding transparent pixels
// Based on the VB6 example by Elad Rosenheim
HRGN hRgnLine = NULL;
BOOL bInFirstRegion = TRUE;
BOOL bInLineRegion = FALSE;
int nStartLineX = 0;
int nRectWidth = prcTexCoords->right - prcTexCoords->left;
int nExtra = int(lock.Pitch) - nRectWidth;
DWORD* pdwCurPixel = (DWORD*)lock.pBits;
for(int y = prcTexCoords->top; y < prcTexCoords->bottom; y++, pdwCurPixel += nExtra)
{
for(int x = prcTexCoords->left; x < prcTexCoords->right; x++, pdwCurPixel++)
{
if(*pdwCurPixel >> 24)
{
// Opaque pixels
if(!bInLineRegion)
{
bInLineRegion = TRUE;
nStartLineX = x;
}
}
else
{
// Transparent pixels
if(bInLineRegion)
{
bInLineRegion = FALSE;
hRgnLine = CreateRectRgn(nStartLineX, y, x, y + 1);
if(bInFirstRegion)
{
hRgn = hRgnLine;
bInFirstRegion = FALSE;
}
else
{
CombineRgn(hRgn, hRgn, hRgnLine, RGN_OR);
DeleteObject(hRgnLine);
hRgnLine = NULL;
}
}
}
}
}
pSurf->UnlockRect();
return TRUE;
}
I am using the following C++ function to generate a region from a Direct3D9 surface with transparent areas. The only problem is that when I am looping through pixels, I am not getting the right ones. I can't for the life of me figure out how to "stay within a rectangle" when looping through DWORDS where pixels are stored.
BOOL CThunderRgn::GenerateFromSurface(LPDIRECT3DSURFACE9 pSurf, const LPRECT prcTexCoords)
{
if(!pSurf || !prcTexCoords) return FALSE;
if(!Release()) return FALSE;
D3DSURFACE_DESC desc;
if(FAILED(pSurf->GetDesc(&desc))) return FALSE;
// Surface format must be A8R8G8B8 or X8R8G8B8
if(desc.Format != D3DFMT_A8R8G8B8 &&
desc.Format != D3DFMT_X8R8G8B8)
return FALSE;
// Get surface bits
D3DLOCKED_RECT lock;
HRESULT hr = pSurf->LockRect(&lock, prcTexCoords, D3DLOCK_READONLY);
if(FAILED(hr)) return FALSE;
// Create subregions for each scanline, excluding transparent pixels
// Based on the VB6 example by Elad Rosenheim
HRGN hRgnLine = NULL;
BOOL bInFirstRegion = TRUE;
BOOL bInLineRegion = FALSE;
int nStartLineX = 0;
int nRectWidth = prcTexCoords->right - prcTexCoords->left;
int nExtra = int(lock.Pitch) - nRectWidth;
DWORD* pdwCurPixel = (DWORD*)lock.pBits;
for(int y = prcTexCoords->top; y < prcTexCoords->bottom; y++, pdwCurPixel += nExtra)
{
for(int x = prcTexCoords->left; x < prcTexCoords->right; x++, pdwCurPixel++)
{
if(*pdwCurPixel >> 24)
{
// Opaque pixels
if(!bInLineRegion)
{
bInLineRegion = TRUE;
nStartLineX = x;
}
}
else
{
// Transparent pixels
if(bInLineRegion)
{
bInLineRegion = FALSE;
hRgnLine = CreateRectRgn(nStartLineX, y, x, y + 1);
if(bInFirstRegion)
{
hRgn = hRgnLine;
bInFirstRegion = FALSE;
}
else
{
CombineRgn(hRgn, hRgn, hRgnLine, RGN_OR);
DeleteObject(hRgnLine);
hRgnLine = NULL;
}
}
}
}
}
pSurf->UnlockRect();
return TRUE;
}