C++: Direct pixel access - please help to find mistake

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;
}

Val
08-23-2006, 01:52 PM
Issue resolved.

Line: "int nExtra = int(lock.Pitch) - nRectWidth;"

Should be: "int nExtra = lock.Pitch / 4 - nRectWidth;"

Because Pitch for the surface is given in bytes instead of pixels.

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum