00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "stdafx.h"
00023 #include <ddraw.h>
00024 #include <d3d.h>
00025 #include "DX7SubPic.h"
00026
00027
00028
00029
00030
00031 CDX7SubPic::CDX7SubPic(IDirect3DDevice7* pD3DDev, IDirectDrawSurface7* pSurface)
00032 : m_pSurface(pSurface)
00033 , m_pD3DDev(pD3DDev)
00034 {
00035 DDSURFACEDESC2 ddsd;
00036 INITDDSTRUCT(ddsd);
00037 if(SUCCEEDED(m_pSurface->GetSurfaceDesc(&ddsd)))
00038 {
00039 m_maxsize.SetSize(ddsd.dwWidth, ddsd.dwHeight);
00040 m_rcDirty.SetRect(0, 0, ddsd.dwWidth, ddsd.dwHeight);
00041 }
00042 }
00043
00044
00045
00046 STDMETHODIMP_(void*) CDX7SubPic::GetObject()
00047 {
00048 return (void*)(IDirectDrawSurface7*)m_pSurface;
00049 }
00050
00051 STDMETHODIMP CDX7SubPic::GetDesc(SubPicDesc& spd)
00052 {
00053 DDSURFACEDESC2 ddsd;
00054 INITDDSTRUCT(ddsd);
00055 if(FAILED(m_pSurface->GetSurfaceDesc(&ddsd)))
00056 return E_FAIL;
00057
00058 spd.type = 0;
00059 spd.w = m_size.cx;
00060 spd.h = m_size.cy;
00061 spd.bpp = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount;
00062 spd.pitch = ddsd.lPitch;
00063 spd.bits = ddsd.lpSurface;
00064 spd.vidrect = m_vidrect;
00065
00066 return S_OK;
00067 }
00068
00069 STDMETHODIMP CDX7SubPic::CopyTo(ISubPic* pSubPic)
00070 {
00071 HRESULT hr;
00072 if(FAILED(hr = __super::CopyTo(pSubPic)))
00073 return hr;
00074
00075 CPoint p = m_rcDirty.TopLeft();
00076 hr = m_pD3DDev->Load((IDirectDrawSurface7*)pSubPic->GetObject(), &p, (IDirectDrawSurface7*)GetObject(), m_rcDirty, 0);
00077
00078 return SUCCEEDED(hr) ? S_OK : E_FAIL;
00079 }
00080
00081 STDMETHODIMP CDX7SubPic::ClearDirtyRect(DWORD color)
00082 {
00083 if(m_rcDirty.IsRectEmpty())
00084 return S_FALSE;
00085
00086 DDBLTFX fx;
00087 INITDDSTRUCT(fx);
00088 fx.dwFillColor = color;
00089 m_pSurface->Blt(&m_rcDirty, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
00090
00091 m_rcDirty.SetRectEmpty();
00092
00093 return S_OK;
00094 }
00095
00096 STDMETHODIMP CDX7SubPic::Lock(SubPicDesc& spd)
00097 {
00098 DDSURFACEDESC2 ddsd;
00099 INITDDSTRUCT(ddsd);
00100 if(FAILED(m_pSurface->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT, NULL)))
00101 return E_FAIL;
00102
00103 spd.type = 0;
00104 spd.w = m_size.cx;
00105 spd.h = m_size.cy;
00106 spd.bpp = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount;
00107 spd.pitch = ddsd.lPitch;
00108 spd.bits = ddsd.lpSurface;
00109 spd.vidrect = m_vidrect;
00110
00111 return S_OK;
00112 }
00113
00114 STDMETHODIMP CDX7SubPic::Unlock(RECT* pDirtyRect)
00115 {
00116 m_pSurface->Unlock(NULL);
00117
00118 if(pDirtyRect)
00119 {
00120 m_rcDirty = *pDirtyRect;
00121 m_rcDirty.InflateRect(1, 1);
00122 m_rcDirty &= CRect(CPoint(0, 0), m_size);
00123 }
00124 else
00125 {
00126 m_rcDirty = CRect(CPoint(0, 0), m_size);
00127 }
00128
00129 return S_OK;
00130 }
00131
00132 STDMETHODIMP CDX7SubPic::AlphaBlt(RECT* pSrc, RECT* pDst, SubPicDesc* pTarget)
00133 {
00134 ASSERT(pTarget == NULL);
00135
00136 if(!m_pD3DDev || !m_pSurface || !pSrc || !pDst)
00137 return E_POINTER;
00138
00139 CRect src(*pSrc), dst(*pDst);
00140
00141 HRESULT hr;
00142
00143 do
00144 {
00145 DDSURFACEDESC2 ddsd;
00146 INITDDSTRUCT(ddsd);
00147 if(FAILED(hr = m_pSurface->GetSurfaceDesc(&ddsd)))
00148 break;
00149
00150 float w = (float)ddsd.dwWidth;
00151 float h = (float)ddsd.dwHeight;
00152
00153 struct
00154 {
00155 float x, y, z, rhw;
00156 float tu, tv;
00157 }
00158 pVertices[] =
00159 {
00160 {(float)dst.left, (float)dst.top, 0.5f, 2.0f, (float)src.left / w, (float)src.top / h},
00161 {(float)dst.right, (float)dst.top, 0.5f, 2.0f, (float)src.right / w, (float)src.top / h},
00162 {(float)dst.left, (float)dst.bottom, 0.5f, 2.0f, (float)src.left / w, (float)src.bottom / h},
00163 {(float)dst.right, (float)dst.bottom, 0.5f, 2.0f, (float)src.right / w, (float)src.bottom / h},
00164 };
00165
00166
00167
00168
00169
00170
00171
00172 hr = m_pD3DDev->SetTexture(0, m_pSurface);
00173
00174 m_pD3DDev->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
00175 m_pD3DDev->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
00176 m_pD3DDev->SetRenderState(D3DRENDERSTATE_BLENDENABLE, TRUE);
00177 m_pD3DDev->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE);
00178 m_pD3DDev->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA);
00179
00180 m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
00181 m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
00182 m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
00183
00184 m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
00185 m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
00186 m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
00187
00188 m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 if(FAILED(hr = m_pD3DDev->BeginScene()))
00204 break;
00205
00206 hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP,
00207 D3DFVF_XYZRHW | D3DFVF_TEX1,
00208 pVertices, 4, D3DDP_WAIT);
00209 m_pD3DDev->EndScene();
00210
00211
00212
00213 m_pD3DDev->SetTexture(0, NULL);
00214
00215 return S_OK;
00216 }
00217 while(0);
00218
00219 return E_FAIL;
00220 }
00221
00222
00223
00224
00225
00226 CDX7SubPicAllocator::CDX7SubPicAllocator(IDirect3DDevice7* pD3DDev, SIZE maxsize, bool fPow2Textures)
00227 : ISubPicAllocatorImpl(maxsize, true, fPow2Textures)
00228 , m_pD3DDev(pD3DDev)
00229 , m_maxsize(maxsize)
00230 {
00231 }
00232
00233
00234
00235 STDMETHODIMP CDX7SubPicAllocator::ChangeDevice(IUnknown* pDev)
00236 {
00237 CComQIPtr<IDirect3DDevice7, &IID_IDirect3DDevice7> pD3DDev = pDev;
00238 if(!pD3DDev) return E_NOINTERFACE;
00239
00240 CAutoLock cAutoLock(this);
00241 m_pD3DDev = pD3DDev;
00242
00243 return __super::ChangeDevice(pDev);
00244 }
00245
00246
00247
00248 bool CDX7SubPicAllocator::Alloc(bool fStatic, ISubPic** ppSubPic)
00249 {
00250 if(!ppSubPic)
00251 return(false);
00252
00253 CAutoLock cAutoLock(this);
00254
00255 DDSURFACEDESC2 ddsd;
00256 INITDDSTRUCT(ddsd);
00257 ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
00258 ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | (fStatic ? DDSCAPS_SYSTEMMEMORY : 0);
00259 ddsd.ddsCaps.dwCaps2 = fStatic ? 0 : (DDSCAPS2_TEXTUREMANAGE|DDSCAPS2_HINTSTATIC);
00260 ddsd.dwWidth = m_maxsize.cx;
00261 ddsd.dwHeight = m_maxsize.cy;
00262 ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
00263 ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_ALPHAPIXELS;
00264 ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
00265 ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
00266 ddsd.ddpfPixelFormat.dwRBitMask = 0x00FF0000;
00267 ddsd.ddpfPixelFormat.dwGBitMask = 0x0000FF00;
00268 ddsd.ddpfPixelFormat.dwBBitMask = 0x000000FF;
00269
00270 if(m_fPow2Textures)
00271 {
00272 ddsd.dwWidth = ddsd.dwHeight = 1;
00273 while(ddsd.dwWidth < m_maxsize.cx) ddsd.dwWidth <<= 1;
00274 while(ddsd.dwHeight < m_maxsize.cy) ddsd.dwHeight <<= 1;
00275 }
00276
00277
00278 CComPtr<IDirect3D7> pD3D;
00279 CComQIPtr<IDirectDraw7, &IID_IDirectDraw7> pDD;
00280 if(FAILED(m_pD3DDev->GetDirect3D(&pD3D)) || !pD3D || !(pDD = pD3D))
00281 return(false);
00282
00283 CComPtr<IDirectDrawSurface7> pSurface;
00284 if(FAILED(pDD->CreateSurface(&ddsd, &pSurface, NULL)))
00285 return(false);
00286
00287 if(!(*ppSubPic = new CDX7SubPic(m_pD3DDev, pSurface)))
00288 return(false);
00289
00290 (*ppSubPic)->AddRef();
00291
00292 return(true);
00293 }