[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