[PATCH] d3dx9: Implement point filtering in D3DXLoadSurfaceFromMemory
Tony Wasserka
tony.wasserka at freenet.de
Wed Jul 15 12:01:57 CDT 2009
---
dlls/d3dx9_36/surface.c | 89 ++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 85 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index b8530e9..cfee225 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -495,6 +495,80 @@ void filter_copy_simple_data(LPBYTE pSrc, UINT SrcPitch, POINT SrcSize, Stati
}
/************************************************************
+ * filter_point_simple_data
+ *
+ * Copies the source buffer to the destination buffer, performing
+ * any necessary format conversion. If the dimensions of the buffers
+ * don't match each other, the closest pixel is used.
+ * Works with ARGB and QWVU formats and mixtures of both.
+ *
+ */
+void filter_point_simple_data(LPBYTE pSrc, UINT SrcPitch, POINT SrcSize, StaticPixelFormatDesc SrcFormat,
+ LPBYTE pDest, UINT DestPitch, POINT DestSize, StaticPixelFormatDesc DestFormat,
+ DWORD dwFilter, DWORD dwColorKey)
+{
+ DWORD SrcShiftA, SrcShiftR, SrcShiftG, SrcShiftB;
+ DWORD DestShiftA, DestShiftR, DestShiftG, DestShiftB;
+ DWORD SrcSignMask, DestSignMask;
+ DWORD MaskA, MaskR, MaskG, MaskB;
+ BYTE *pSrcPtr, *pDestPtr, *pBufPtr;
+ DWORD CK_Mask;
+ UINT x, y;
+
+ get_shifts( SrcFormat, DestFormat, &SrcShiftA, &SrcShiftR, &SrcShiftG, &SrcShiftB);
+ get_shifts(DestFormat, SrcFormat, &DestShiftA, &DestShiftR, &DestShiftG, &DestShiftB);
+
+ get_masks(DestFormat, &MaskA, &MaskR, &MaskG, &MaskB);
+ if(dwColorKey) convert_a8r8g8b8_to_format(&dwColorKey, &CK_Mask, SrcFormat);
+
+ get_sign_mask( SrcFormat, &SrcSignMask);
+ get_sign_mask(DestFormat, &DestSignMask);
+
+
+ for(y = 0;y < DestSize.y;y++) {
+ pDestPtr = pDest + y * DestPitch;
+ pSrcPtr = pSrc + SrcPitch * (y * SrcSize.y / DestSize.y);
+ pBufPtr = pSrcPtr;
+
+ for(x = 0;x < DestSize.x;x++) {
+ DWORD Col = *(DWORD*)pSrcPtr;
+ DWORD *pPixel = (DWORD*)pDestPtr;
+
+ /* color keying */
+ if(dwColorKey)
+ if((Col & CK_Mask) == dwColorKey) {
+ *pPixel = 0;
+ pSrcPtr = pBufPtr + (x * SrcSize.x / DestSize.x) * SrcFormat.bpp;
+ pDestPtr += DestFormat.bpp;
+ continue;
+ }
+
+ /* convert to unsigned if necessary */
+ if(SrcSignMask) Col ^= SrcSignMask;
+
+ /* convert bits per channel */
+ if(SrcFormat.abits) *pPixel = ((Col >> SrcShiftA) << DestShiftA) & MaskA;
+ else *pPixel = MaskA;
+
+ if(SrcFormat.rbits) *pPixel += ((Col >> SrcShiftR) << DestShiftR) & MaskR;
+ else *pPixel |= MaskR;
+
+ if(SrcFormat.gbits) *pPixel += ((Col >> SrcShiftG) << DestShiftG) & MaskG;
+ else *pPixel |= MaskG;
+
+ if(SrcFormat.bbits) *pPixel += ((Col >> SrcShiftB) << DestShiftB) & MaskB;
+ else *pPixel |= MaskB;
+
+ /* convert to signed if necessary */
+ if(DestSignMask) *pPixel ^= DestSignMask;
+
+ pSrcPtr = pBufPtr + (x * SrcSize.x / DestSize.x) * SrcFormat.bpp;
+ pDestPtr += DestFormat.bpp;
+ }
+ }
+}
+
+/************************************************************
* D3DXLoadSurfaceFromMemory
*
* Loads data from a given memory chunk into a surface,
@@ -547,7 +621,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
if(SrcFormat == D3DFMT_UNKNOWN || pSrcRect->left >= pSrcRect->right || pSrcRect->top >= pSrcRect->bottom) return E_FAIL;
IDirect3DSurface9_GetDesc(pDestSurface, &SurfDesc);
- if(dwFilter != D3DX_FILTER_NONE) return E_NOTIMPL;
get_format_info(SrcFormat, &SrcFormatDesc);
get_format_info(SurfDesc.Format, &DestFormatDesc);
@@ -567,9 +640,17 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(LPDIRECT3DSURFACE9 pDestSurface,
hr = IDirect3DSurface9_LockRect(pDestSurface, &LockRect, pDestRect, 0);
if(FAILED(hr)) return D3DXERR_INVALIDDATA;
- filter_copy_simple_data((BYTE*)pSrcMemory, SrcPitch, SrcSize, SrcFormatDesc,
- LockRect.pBits, LockRect.Pitch, DestSize, DestFormatDesc,
- dwFilter, Colorkey);
+ if((dwFilter & 0xFFFF) == D3DX_FILTER_NONE) {
+ filter_copy_simple_data((BYTE*)pSrcMemory, SrcPitch, SrcSize, SrcFormatDesc,
+ LockRect.pBits, LockRect.Pitch, DestSize, DestFormatDesc,
+ dwFilter, Colorkey);
+ }
+ else /* if((dwFilter & 0xFFFF) == D3DX_FILTER_POINT) */ {
+ /* TODO: Implement other filters, always apply a point filter for now */
+ filter_point_simple_data((BYTE*)pSrcMemory, SrcPitch, SrcSize, SrcFormatDesc,
+ LockRect.pBits, LockRect.Pitch, DestSize, DestFormatDesc,
+ dwFilter, Colorkey);
+ }
IDirect3DSurface9_UnlockRect(pDestSurface);
return D3D_OK;
--
1.6.0.2
--------------060802090904070203030606--
More information about the wine-patches
mailing list