add ddsurf=>pixbuf conversion

This commit is contained in:
cxgeorge 2001-02-24 03:43:02 +00:00
parent 79e66527ed
commit 32052691ad

View File

@ -21,7 +21,8 @@
//#define FORCE_16bpp_1555
typedef enum {None,Conv32to32,Conv32to32_NoAlpha,Conv32to24,Conv32to16_0555,
typedef enum {
None,Conv32to32,Conv32to32_NoAlpha,Conv32to24,Conv32to16_0555,
Conv32to16_1555,Conv32to16_0565,Conv32to16_4444,Conv24to32,Conv24to24,
Conv24to16_0555,Conv24to16_0565,ConvLum16to16_1555,ConvLum16to16_4444,
ConvLum16to32,ConvLum16to16,ConvLum8to8,ConvLum8to24,ConvLum8to32,ConvLum8to16_0555,ConvLum8to16_0565
@ -127,6 +128,7 @@ enum Format {
// Note: PixelBuffer's format indicates REQUESTED final format,
// not the stored format, which is indicated by pixelbuffer type
////////////////////////////////////////////////////////////////////
unsigned int DXTextureContext::
get_bits_per_pixel(PixelBuffer::Format format, int *alphbits) {
*alphbits = 0; // assume no alpha bits
@ -188,8 +190,6 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
DWORD lPitch = ddsd.lPitch;
BYTE* pDDSurfBytes = (BYTE*)ddsd.lpSurface;
BYTE r,g,b,a;
DWORD x,y,dwPixel;
DWORD dwOrigWidth=ddsd.dwWidth,dwOrigHeight=ddsd.dwHeight;
switch(ConvNeeded) {
@ -200,15 +200,16 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
DWORD *pDstWord;
DWORD dwAlphaMaskOff = (ConvNeeded==Conv32to32_NoAlpha) ? 0x00FFFFFF : 0xFFFFFFFF;
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
pDstWord = (DWORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
dwPixel = *pSrcWord;
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
DWORD dwPixel = *pSrcWord;
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order to ARGB
#if 0
BYTE r,g,b,a;
a = (BYTE)((dwPixel>>24)); // unsigned >>, no need to &
b = (BYTE)((dwPixel>>16)&0x000000ff);
g = (BYTE)((dwPixel>> 8)&0x000000ff);
@ -216,6 +217,7 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
*pDstWord = (a << 24) | (r << 16)| (g << 8) | b;
#else
BYTE r,b;
// simpler: just swap r & b
b = (BYTE)((dwPixel>>16)&0x000000ff);
r = (BYTE)((dwPixel )&0x000000ff);
@ -228,7 +230,7 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
case Conv32to16_1555:
case Conv32to16_0555: {
DWORD abit,*pSrcWord = (DWORD *) pbuf;
DWORD *pSrcWord = (DWORD *) pbuf;
WORD *pDstWord;
DWORD dwAlphaMaskOff = (ConvNeeded==Conv32to16_0555) ? 0x7FFF : 0xFFFF;
@ -236,11 +238,12 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
// for some reason, bits are 'in-order' when converting to 16bit
// just handle 1/15 alpha/rgb
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
pDstWord = (WORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
dwPixel = *pSrcWord;
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
BYTE r,g,b;
DWORD abit,dwPixel = *pSrcWord;
// pixel buffer is in ABGR format (orig fmt designed for big-endian RGBA)
// need to change byte order to ARGB
@ -270,11 +273,12 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
// for some reason, bits are 'in-order' when converting to 16bit
// just handle 1/15 alpha/rgb
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
pDstWord = (WORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
dwPixel = *pSrcWord;
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
BYTE r,g,b;
DWORD dwPixel = *pSrcWord;
// pixel buffer is in ABGR format (orig fmt designed for big-endian RGBA)
// need to change byte order to ARGB
@ -300,13 +304,14 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
DWORD *pSrcWord = (DWORD *) pbuf;
BYTE *pDstWord;
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
pDstWord = (BYTE*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord+=3) {
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord+=3) {
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order to ARGB
dwPixel = *pSrcWord;
BYTE r,g,b;
DWORD dwPixel = *pSrcWord;
b = (BYTE)((dwPixel>>16) & 0x000000ff);
g = (BYTE)((dwPixel>> 8) & 0x000000ff);
@ -328,11 +333,12 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
assert(ddsd.ddpfPixelFormat.dwRGBAlphaBitMask==0xf000); // assumes ARGB
assert(ddsd.ddpfPixelFormat.dwRBitMask==0x0f00); // assumes ARGB
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
pDstWord = (WORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
dwPixel = *pSrcWord;
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
BYTE r,g,b,a;
DWORD dwPixel = *pSrcWord;
// pixel buffer is in ABGR format (orig fmt designed for big-endian RGBA)
// need to change byte order to ARGB
@ -354,10 +360,11 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
BYTE *pSrcWord = (BYTE *) pbuf;
BYTE *pDstWord;
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
pDstWord = (BYTE*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord+=3) {
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord+=3) {
BYTE r,g,b;
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order to ARGB
@ -380,10 +387,11 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
assert(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00);
// for some reason, bits are 'in-order' when converting to 16bit
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
pDstWord = (WORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
BYTE r,g,b;
// pixel buffer is in ABGR format (orig fmt designed for big-endian RGBA)
// need to change byte order to ARGB
@ -406,10 +414,11 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
assert(ddsd.ddpfPixelFormat.dwRBitMask==0xF800);
// for some reason, bits are 'in-order' when converting to 16bit
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
pDstWord = (WORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
BYTE r,g,b;
// pixel buffer is in ABGR format (orig fmt designed for big-endian RGBA)
// need to change byte order to ARGB
@ -430,10 +439,11 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
BYTE *pSrcWord = (BYTE *) pbuf;
DWORD *pDstWord;
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
pDstWord = (DWORD *)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord+=3,pDstWord++) {
BYTE r,g,b;
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order to ARGB
@ -456,13 +466,14 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
WORD *pSrcWord = (WORD *) pbuf;
DWORD *pDstWord;
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
pDstWord = (DWORD *)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order to ARGB
dwPixel=*pSrcWord;
DWORD dwPixel=*pSrcWord;
BYTE r,a;
a = dwPixel >> 8;
r = dwPixel & 0xFF;
@ -479,10 +490,12 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
assert(ddsd.ddpfPixelFormat.dwRGBAlphaBitMask==0xf000); // assumes ARGB
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
pDstWord = (WORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
DWORD dwPixel=*pSrcWord;
BYTE r,a;
dwPixel = *pSrcWord;
a = (BYTE)(dwPixel>>8) >> 4;
@ -500,11 +513,12 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
assert(ddsd.ddpfPixelFormat.dwRGBAlphaBitMask==0x8000); // assumes ARGB
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
pDstWord = (WORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
dwPixel = *pSrcWord;
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
DWORD dwPixel=*pSrcWord;
BYTE r;
r = (BYTE)(dwPixel & 0x000000ff) >> 3;
@ -524,7 +538,7 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
case ConvLum8to16_0555: {
BYTE *pSrcWord = (BYTE *) pbuf;
WORD *pDstWord;
DWORD FarShift,OrVal,MiddleRoundShift,GrnVal;
DWORD FarShift,OrVal,MiddleRoundShift;
if(ConvNeeded==ConvLum8to16_0555) {
FarShift=10; OrVal=0x8000; // turn on alpha bit, just in case
@ -536,11 +550,12 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
assert(ddsd.ddpfPixelFormat.dwRBitMask==0xF800);
}
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes+=ddsd.lPitch) {
pDstWord = (WORD*)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
dwPixel = *pSrcWord;
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
DWORD dwPixel=*pSrcWord,GrnVal;
BYTE r;
r = (BYTE) dwPixel >> 3;
GrnVal = (BYTE) dwPixel >> MiddleRoundShift;
@ -564,11 +579,11 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
BYTE *pSrcWord = (BYTE *) pbuf;
DWORD *pDstWord;
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
pDstWord = (DWORD *)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
dwPixel=*pSrcWord;
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
DWORD dwPixel=*pSrcWord;
*pDstWord = 0xFF000000 | (dwPixel<<16) | (dwPixel<<8) | dwPixel;
}
@ -582,11 +597,11 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
BYTE *pSrcWord = (BYTE *) pbuf;
BYTE *pDstWord;
for( y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
for(DWORD y=0; y<dwOrigHeight; y++,pDDSurfBytes += ddsd.lPitch) {
pDstWord = (BYTE *)pDDSurfBytes;
for( x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
dwPixel=*pSrcWord;
for(DWORD x=0; x<dwOrigWidth; x++,pSrcWord++,pDstWord++) {
DWORD dwPixel=*pSrcWord;
*pDstWord++ = dwPixel;
*pDstWord++ = dwPixel;
@ -607,7 +622,295 @@ HRESULT ConvertPixBuftoDDSurf(ConversionType ConvNeeded,BYTE *pbuf,LPDIRECTDRAWS
return S_OK;
}
HRESULT ConvertDDSurftoPixBuf(PixelBuffer *pixbuf,LPDIRECTDRAWSURFACE7 pDDSurf) {
HRESULT hr;
DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd);
DWORD dwNumComponents=pixbuf->get_num_components();
assert(pixbuf->get_component_width()==sizeof(BYTE)); // cant handle anything else now
assert(pixbuf->get_image_type()==PixelBuffer::T_unsigned_byte); // cant handle anything else now
assert((dwNumComponents==3) || (dwNumComponents==4)); // cant handle anything else now
BYTE *pbuf=pixbuf->_image.p();
if(FAILED( hr = pDDSurf->Lock( NULL, &ddsd, DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL ))) {
dxgsg_cat.error() << "ConvertDDSurftoPixBuf Lock() failed! hr = " << ConvD3DErrorToString(hr) << "\n";
return hr;
}
DWORD dwXWindowOffset=0,dwYWindowOffset=0;
DWORD dwCopyWidth=ddsd.dwWidth,dwCopyHeight=ddsd.dwHeight;
// get window offset so we know where to start grabbing pixels
LPDIRECTDRAWCLIPPER pDDClipper;
hr = pDDSurf->GetClipper(&pDDClipper);
#ifdef _DEBUG
if(FAILED(hr) && !((hr == DDERR_NOCLIPPERATTACHED) && dx_full_screen)) {
dxgsg_cat.error() << "ConvertDDSurftoPixBuf GetClipper failed! hr = " << ConvD3DErrorToString(hr) << "\n";
return hr;
}
#endif
if(hr==S_OK) {
HWND hWin;
if(FAILED(hr = pDDClipper->GetHWnd(&hWin))) {
dxgsg_cat.error() << "ConvertDDSurftoPixBuf GetHwnd failed! hr = " << ConvD3DErrorToString(hr) << "\n";
return hr;
}
RECT view_rect;
GetClientRect( hWin, &view_rect );
ClientToScreen( hWin, (POINT*)&view_rect.left );
ClientToScreen( hWin, (POINT*)&view_rect.right );
dwXWindowOffset=view_rect.left;
dwYWindowOffset=view_rect.top;
dwCopyWidth=view_rect.right-view_rect.left;
dwCopyHeight=view_rect.bottom-view_rect.top;
pDDClipper->Release(); // dec ref cnt
}
//make sure there's enough space in the pixbuf, its size must match (especially xsize)
// or scanlines will be too long
if(!((dwCopyWidth==pixbuf->get_xsize()) && (dwCopyHeight<=pixbuf->get_ysize()))) {
pDDSurf->Unlock(NULL);
assert(0);
dxgsg_cat.error() << "ConvertDDSurftoPixBuf, PixBuf incorrect size to hold display surface!\n";
return E_FAIL;
}
// others not handled yet
assert((ddsd.ddpfPixelFormat.dwRGBBitCount==32)||(ddsd.ddpfPixelFormat.dwRGBBitCount==16)||(ddsd.ddpfPixelFormat.dwRGBBitCount==24));
//pbuf contains raw ARGB in PixelBuffer byteorder
DWORD lPitch = ddsd.lPitch;
BYTE* pDDSurfBytes = (BYTE*)ddsd.lpSurface;
if(dwNumComponents==4) {
DWORD *pDstWord = (DWORD *) pbuf;
switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
case 32: {
DWORD *pSrcWord;
pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
pSrcWord = ((DWORD*)pDDSurfBytes)+dwXWindowOffset;
for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++,pDstWord++) {
BYTE r,g,b;
DWORD dwPixel = *pSrcWord;
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order from ARGB
// simpler: just swap r & b
r = (BYTE)((dwPixel>>16)&0x000000ff);
g = (BYTE)((dwPixel>> 8)&0x000000ff);
b = (BYTE)((dwPixel )&0x000000ff);
*pDstWord = (dwPixel & 0xff00ff00) | (r<<16) | b;
}
}
break;
}
case 24: {
BYTE *pSrcByte;
pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
pSrcByte = pDDSurfBytes+dwXWindowOffset*3*sizeof(BYTE);
for(DWORD x=0; x<dwCopyWidth; x++,pDstWord++) {
DWORD r,g,b;
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order from ARGB
b = *pSrcByte++;
g = *pSrcByte++;
r = *pSrcByte++;
*pDstWord = 0xFF000000 | (r << 16) | (g << 8) | b;
}
}
break;
}
case 16: {
assert((ddsd.ddpfPixelFormat.dwRBitMask==0xF800) || // 565
(ddsd.ddpfPixelFormat.dwRBitMask==0x0F00) || // 4444
(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00)); // 555 or 1555
WORD *pSrcWord;
// handle 0555,1555,0565 in same loop
BYTE redshift,greenshift,blueshift;
DWORD redmask,greenmask,bluemask;
if(ddsd.ddpfPixelFormat.dwRBitMask==0xF800) {
redshift=(11-3);
redmask=0xF800;
greenmask=0x07E0;
greenshift=(5-2);
bluemask=0x001F;
blueshift=3;
} else if(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00) {
redmask=0x7C00;
redshift=(10-3);
greenmask=0x03E0;
greenshift=(5-3);
bluemask=0x001F;
blueshift=3;
} else {
assert(ddsd.ddpfPixelFormat.dwRBitMask==0x0F00);
redmask=0x0F00;
redshift=4;
greenmask=0x00F0;
greenshift=0;
bluemask=0x000F;
blueshift=4;
}
pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
pSrcWord = ((WORD*)pDDSurfBytes)+dwXWindowOffset;
for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++,pDstWord++) {
WORD dwPixel = *pSrcWord;
BYTE r,g,b;
b = (dwPixel & bluemask) << blueshift;
g = (dwPixel & greenmask) >> greenshift;
r = (dwPixel & redmask) >> redshift;
*pDstWord = 0xFF000000 | (b << 16) | (g << 8) | r;
}
}
}
break;
}
} else { // convert to 24bpp pixbuf
BYTE *pDstWord = (BYTE *) pbuf;
switch(ddsd.ddpfPixelFormat.dwRGBBitCount) {
case 32: {
DWORD *pSrcWord;
pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
pSrcWord = ((DWORD*)pDDSurfBytes)+dwXWindowOffset;
for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++) {
BYTE r,g,b;
DWORD dwPixel = *pSrcWord;
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order to ARGB
// simpler: just swap r & b
r = (BYTE)((dwPixel>>16)&0x000000ff);
g = (BYTE)((dwPixel>> 8)&0x000000ff);
b = (BYTE)((dwPixel )&0x000000ff);
*pDstWord++ = r;
*pDstWord++ = g;
*pDstWord++ = b;
}
}
break;
}
case 24: {
BYTE *pSrcByte,*pDstByte;
pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
pSrcByte = pDDSurfBytes+dwXWindowOffset*3*sizeof(BYTE);
for(DWORD x=0; x<dwCopyWidth; x++) {
BYTE r,g,b;
// pixel buffer is in ABGR format(it stores big-endian RGBA)
// need to change byte order from ARGB
b = *pSrcByte++;
g = *pSrcByte++;
r = *pSrcByte++;
*pDstByte++ = r;
*pDstByte++ = g;
*pDstByte++ = b;
}
}
break;
}
case 16: { // handle 555,1555,565,4444 cases (not 8-8 yet)
assert((ddsd.ddpfPixelFormat.dwRBitMask==0xF800) || // 565
(ddsd.ddpfPixelFormat.dwRBitMask==0x0F00) || // 4444
(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00)); // 555 or 1555
WORD *pSrcWord;
// handle 0555,1555,0565 in same loop
BYTE redshift,greenshift,blueshift;
DWORD redmask,greenmask,bluemask;
if(ddsd.ddpfPixelFormat.dwRBitMask==0xF800) {
redshift=(11-3);
redmask=0xF800;
greenmask=0x07E0;
greenshift=(5-2);
bluemask=0x001F;
blueshift=3;
} else if(ddsd.ddpfPixelFormat.dwRBitMask==0x7C00) {
redmask=0x7C00;
redshift=(10-3);
greenmask=0x03E0;
greenshift=(5-3);
bluemask=0x001F;
blueshift=3;
} else {
assert(ddsd.ddpfPixelFormat.dwRBitMask==0x0F00);
redmask=0x0F00;
redshift=4;
greenmask=0x00F0;
greenshift=0;
bluemask=0x000F;
blueshift=4;
}
pDDSurfBytes+=ddsd.lPitch*(dwYWindowOffset+dwCopyHeight-1);
for(DWORD y=0; y<dwCopyHeight; y++,pDDSurfBytes-=ddsd.lPitch) {
pSrcWord = ((WORD*)pDDSurfBytes)+dwXWindowOffset;
for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++) {
WORD dwPixel = *pSrcWord;
BYTE r,g,b;
b = (dwPixel & bluemask) << blueshift;
g = (dwPixel & greenmask) >> greenshift;
r = (dwPixel & redmask) >> redshift;
*pDstWord++ = r;
*pDstWord++ = g;
*pDstWord++ = b;
}
}
}
break;
}
}
pDDSurf->Unlock(NULL);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CreateTextureFromBitmap()
@ -680,15 +983,13 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
ddsd.ddpfPixelFormat.dwRGBBitCount = bpp;
if(cNumAlphaBits) {
if (bpp == 8 && cNumAlphaBits == 8) // handle special case: Alpha only buffer
{
if(bpp == 8 && cNumAlphaBits == 8) { // handle special case: Alpha only buffer
ddsd.dwFlags |= DDPF_ALPHA;
ddsd.dwAlphaBitDepth = 8;
ddsd.ddpfPixelFormat.dwAlphaBitDepth = 8;
ddsd.ddpfPixelFormat.dwFlags = DDPF_ALPHA;
ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff;
}
else {
} else {
ddsd.ddpfPixelFormat.dwFlags |= DDPF_ALPHAPIXELS;
if(cNumAlphaBits == 8)
ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000;
@ -766,7 +1067,9 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
{ static BOOL bPrinted=FALSE;
if(!bPrinted) {
dxgsg_cat.debug() << "Gfx card supported TexFmts:\n";
for(i=0;i<cNumTexPixFmts;i++) { DebugPrintPixFmt(&pTexPixFmts[i]); }
for(i=0;i<cNumTexPixFmts;i++) {
DebugPrintPixFmt(&pTexPixFmts[i]);
}
bPrinted=TRUE;
}
}
@ -885,6 +1188,7 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
#ifdef _DEBUG
if(!dx_force_16bpptextures)
#endif
// no 24-bit fmt. look for 32 bit fmt (note: this is memory-hogging choice
// instead I could look for memory-conserving 16-bit fmt).
// check mask to ensure ARGB, not RGBA (which I am not handling here)
@ -1199,8 +1503,7 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
PRINTVIDMEM(pDD,&ddsd.ddsCaps,"texture surf (includes AGP mem)");
// Create a new surface for the texture
if( FAILED( hr = pDD->CreateSurface( &ddsd, &_surface, NULL ) ) )
{
if(FAILED( hr = pDD->CreateSurface( &ddsd, &_surface, NULL ) )) {
dxgsg_cat.error() << "CreateTexture failed: pDD->CreateSurface() failed! hr = " << ConvD3DErrorToString(hr) << "\n";
goto error_exit;
}
@ -1360,6 +1663,7 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
// loader inverts y, so use StretchBlt to re-invert it
// res = StretchBlt(PrimaryDC,0,ddsd_cur.dwHeight+cury,ddsd_cur.dwWidth,-ddsd_cur.dwHeight, TexDC,0,0,ddsd_cur.dwWidth,ddsd_cur.dwHeight,SRCCOPY);
#if 0
// dxgsg_cat.error() << "WINVER = " << (void*)WINVER << "\n";
if(cNumAlphaBits>0) {
BLENDFUNCTION bf;
@ -1458,8 +1762,7 @@ CreateTexture( HDC PrimaryDC, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts,
// Desc: Release the surface used to store the texture
//-----------------------------------------------------------------------------
void DXTextureContext::
DeleteTexture( )
{
DeleteTexture( ) {
if(_surface) _surface->Release();
_surface = NULL;
}
@ -1472,8 +1775,7 @@ DeleteTexture( )
////////////////////////////////////////////////////////////////////
DXTextureContext::
DXTextureContext(Texture *tex) :
TextureContext(tex)
{
TextureContext(tex) {
#ifdef _DEBUG
dxgsg_cat.spam() << "Making DX texture for " << tex->get_name() << "\n";
#endif
@ -1482,8 +1784,7 @@ DXTextureContext(Texture *tex) :
}
DXTextureContext::
~DXTextureContext()
{
~DXTextureContext() {
#ifdef _DEBUG
dxgsg_cat.spam() << "Deleting DX texture for " << _tex->get_name() << "\n";
#endif