Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensprite.c
Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2008 Tony Wasserka 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 * 00018 */ 00019 00020 #include "wine/debug.h" 00021 #include "d3dx9_36_private.h" 00022 00023 WINE_DEFAULT_DEBUG_CHANNEL(d3dx); 00024 00025 /* the combination of all possible D3DXSPRITE flags */ 00026 #define D3DXSPRITE_FLAGLIMIT 511 00027 00028 typedef struct _SPRITEVERTEX { 00029 D3DXVECTOR3 pos; 00030 DWORD col; 00031 D3DXVECTOR2 tex; 00032 } SPRITEVERTEX; 00033 00034 static HRESULT WINAPI ID3DXSpriteImpl_QueryInterface(LPD3DXSPRITE iface, REFIID riid, LPVOID *object) 00035 { 00036 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00037 00038 TRACE("(%p): QueryInterface from %s\n", This, debugstr_guid(riid)); 00039 if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ID3DXSprite)) { 00040 IUnknown_AddRef(iface); 00041 *object=This; 00042 return S_OK; 00043 } 00044 WARN("(%p)->(%s, %p): not found\n", iface, debugstr_guid(riid), *object); 00045 return E_NOINTERFACE; 00046 } 00047 00048 static ULONG WINAPI ID3DXSpriteImpl_AddRef(LPD3DXSPRITE iface) 00049 { 00050 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00051 ULONG ref=InterlockedIncrement(&This->ref); 00052 TRACE("(%p): AddRef from %d\n", This, ref-1); 00053 return ref; 00054 } 00055 00056 static ULONG WINAPI ID3DXSpriteImpl_Release(LPD3DXSPRITE iface) 00057 { 00058 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00059 ULONG ref=InterlockedDecrement(&This->ref); 00060 TRACE("(%p): ReleaseRef to %d\n", This, ref); 00061 00062 if(ref==0) { 00063 if(This->sprites) { 00064 int i; 00065 for(i=0;i<This->sprite_count;i++) 00066 if(This->sprites[i].texture) 00067 IDirect3DTexture9_Release(This->sprites[i].texture); 00068 00069 HeapFree(GetProcessHeap(), 0, This->sprites); 00070 } 00071 if(This->stateblock) IDirect3DStateBlock9_Release(This->stateblock); 00072 if(This->vdecl) IDirect3DVertexDeclaration9_Release(This->vdecl); 00073 if(This->device) IDirect3DDevice9_Release(This->device); 00074 HeapFree(GetProcessHeap(), 0, This); 00075 } 00076 return ref; 00077 } 00078 00079 static HRESULT WINAPI ID3DXSpriteImpl_GetDevice(LPD3DXSPRITE iface, LPDIRECT3DDEVICE9 *device) 00080 { 00081 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00082 TRACE("(%p): relay\n", This); 00083 00084 if(device==NULL) return D3DERR_INVALIDCALL; 00085 *device=This->device; 00086 IDirect3DDevice9_AddRef(This->device); 00087 00088 return D3D_OK; 00089 } 00090 00091 static HRESULT WINAPI ID3DXSpriteImpl_GetTransform(LPD3DXSPRITE iface, D3DXMATRIX *transform) 00092 { 00093 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00094 TRACE("(%p)\n", This); 00095 00096 if(transform==NULL) return D3DERR_INVALIDCALL; 00097 *transform=This->transform; 00098 00099 return D3D_OK; 00100 } 00101 00102 static HRESULT WINAPI ID3DXSpriteImpl_SetTransform(LPD3DXSPRITE iface, CONST D3DXMATRIX *transform) 00103 { 00104 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00105 TRACE("(%p)\n", This); 00106 00107 if(transform==NULL) return D3DERR_INVALIDCALL; 00108 This->transform=*transform; 00109 00110 return D3D_OK; 00111 } 00112 00113 static HRESULT WINAPI ID3DXSpriteImpl_SetWorldViewRH(LPD3DXSPRITE iface, CONST D3DXMATRIX *world, CONST D3DXMATRIX *view) 00114 { 00115 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00116 FIXME("(%p): stub\n", This); 00117 return E_NOTIMPL; 00118 } 00119 00120 static HRESULT WINAPI ID3DXSpriteImpl_SetWorldViewLH(LPD3DXSPRITE iface, CONST D3DXMATRIX *world, CONST D3DXMATRIX *view) 00121 { 00122 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00123 FIXME("(%p): stub\n", This); 00124 return E_NOTIMPL; 00125 } 00126 00127 /* Helper function */ 00128 static void set_states(ID3DXSpriteImpl *object) 00129 { 00130 D3DXMATRIX mat; 00131 D3DVIEWPORT9 vp; 00132 00133 /* Miscelaneous stuff */ 00134 IDirect3DDevice9_SetVertexShader(object->device, NULL); 00135 IDirect3DDevice9_SetPixelShader(object->device, NULL); 00136 IDirect3DDevice9_SetNPatchMode(object->device, 0.0f); 00137 00138 /* Render states */ 00139 IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHABLENDENABLE, TRUE); 00140 IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHAFUNC, D3DCMP_GREATER); 00141 IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHAREF, 0x00); 00142 IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHATESTENABLE, object->alphacmp_caps); 00143 IDirect3DDevice9_SetRenderState(object->device, D3DRS_BLENDOP, D3DBLENDOP_ADD); 00144 IDirect3DDevice9_SetRenderState(object->device, D3DRS_CLIPPING, TRUE); 00145 IDirect3DDevice9_SetRenderState(object->device, D3DRS_CLIPPLANEENABLE, FALSE); 00146 IDirect3DDevice9_SetRenderState(object->device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | 00147 D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); 00148 IDirect3DDevice9_SetRenderState(object->device, D3DRS_CULLMODE, D3DCULL_NONE); 00149 IDirect3DDevice9_SetRenderState(object->device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 00150 IDirect3DDevice9_SetRenderState(object->device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); 00151 IDirect3DDevice9_SetRenderState(object->device, D3DRS_ENABLEADAPTIVETESSELLATION, FALSE); 00152 IDirect3DDevice9_SetRenderState(object->device, D3DRS_FILLMODE, D3DFILL_SOLID); 00153 IDirect3DDevice9_SetRenderState(object->device, D3DRS_FOGENABLE, FALSE); 00154 IDirect3DDevice9_SetRenderState(object->device, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); 00155 IDirect3DDevice9_SetRenderState(object->device, D3DRS_LIGHTING, FALSE); 00156 IDirect3DDevice9_SetRenderState(object->device, D3DRS_RANGEFOGENABLE, FALSE); 00157 IDirect3DDevice9_SetRenderState(object->device, D3DRS_SEPARATEALPHABLENDENABLE, FALSE); 00158 IDirect3DDevice9_SetRenderState(object->device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD); 00159 IDirect3DDevice9_SetRenderState(object->device, D3DRS_SPECULARENABLE, FALSE); 00160 IDirect3DDevice9_SetRenderState(object->device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 00161 IDirect3DDevice9_SetRenderState(object->device, D3DRS_SRGBWRITEENABLE, FALSE); 00162 IDirect3DDevice9_SetRenderState(object->device, D3DRS_STENCILENABLE, FALSE); 00163 IDirect3DDevice9_SetRenderState(object->device, D3DRS_VERTEXBLEND, FALSE); 00164 IDirect3DDevice9_SetRenderState(object->device, D3DRS_WRAP0, 0); 00165 00166 /* Texture stage states */ 00167 IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 00168 IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); 00169 IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 00170 IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 00171 IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); 00172 IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); 00173 IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_TEXCOORDINDEX, 0); 00174 IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); 00175 IDirect3DDevice9_SetTextureStageState(object->device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); 00176 IDirect3DDevice9_SetTextureStageState(object->device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); 00177 00178 /* Sampler states */ 00179 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); 00180 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); 00181 00182 if(object->texfilter_caps & D3DPTFILTERCAPS_MAGFANISOTROPIC) 00183 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC); 00184 else IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 00185 00186 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MAXMIPLEVEL, 0); 00187 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MAXANISOTROPY, object->maxanisotropy); 00188 00189 if(object->texfilter_caps & D3DPTFILTERCAPS_MINFANISOTROPIC) 00190 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); 00191 else IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 00192 00193 if(object->texfilter_caps & D3DPTFILTERCAPS_MIPFLINEAR) 00194 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); 00195 else IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); 00196 00197 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MIPMAPLODBIAS, 0); 00198 IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_SRGBTEXTURE, 0); 00199 00200 /* Matrices */ 00201 D3DXMatrixIdentity(&mat); 00202 IDirect3DDevice9_SetTransform(object->device, D3DTS_WORLD, &mat); 00203 IDirect3DDevice9_SetTransform(object->device, D3DTS_VIEW, &mat); 00204 IDirect3DDevice9_GetViewport(object->device, &vp); 00205 D3DXMatrixOrthoOffCenterLH(&mat, vp.X+0.5f, (float)vp.Width+vp.X+0.5f, (float)vp.Height+vp.Y+0.5f, vp.Y+0.5f, vp.MinZ, vp.MaxZ); 00206 IDirect3DDevice9_SetTransform(object->device, D3DTS_PROJECTION, &mat); 00207 } 00208 00209 static HRESULT WINAPI ID3DXSpriteImpl_Begin(LPD3DXSPRITE iface, DWORD flags) 00210 { 00211 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00212 HRESULT hr; 00213 TRACE("(%p): relay\n", This); 00214 00215 if(flags>D3DXSPRITE_FLAGLIMIT || This->ready) return D3DERR_INVALIDCALL; 00216 00217 /* TODO: Implement flags: 00218 D3DXSPRITE_ALPHABLEND: enables alpha blending 00219 D3DXSPRITE_BILLBOARD: makes the sprite always face the camera 00220 D3DXSPRITE_DONOTMODIFY_RENDERSTATE: name says it all 00221 D3DXSPRITE_OBJECTSPACE: do not change device transforms 00222 D3DXSPRITE_SORT_DEPTH_BACKTOFRONT: sort by position 00223 D3DXSPRITE_SORT_DEPTH_FRONTTOBACK: sort by position 00224 D3DXSPRITE_SORT_TEXTURE: sort by texture (so that it doesn't change too often) 00225 */ 00226 if(This->vdecl==NULL) { 00227 static const D3DVERTEXELEMENT9 elements[] = 00228 { 00229 { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, 00230 { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, 00231 { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, 00232 D3DDECL_END() 00233 }; 00234 IDirect3DDevice9_CreateVertexDeclaration(This->device, elements, &This->vdecl); 00235 } 00236 00237 if(!(flags & D3DXSPRITE_DONOTSAVESTATE)) { 00238 if(This->stateblock==NULL) { 00239 /* Tell our state block what it must store */ 00240 hr=IDirect3DDevice9_BeginStateBlock(This->device); 00241 if(hr!=D3D_OK) return hr; 00242 00243 set_states(This); 00244 00245 IDirect3DDevice9_SetVertexDeclaration(This->device, This->vdecl); 00246 IDirect3DDevice9_SetStreamSource(This->device, 0, NULL, 0, sizeof(SPRITEVERTEX)); 00247 IDirect3DDevice9_SetIndices(This->device, NULL); 00248 IDirect3DDevice9_SetTexture(This->device, 0, NULL); 00249 00250 IDirect3DDevice9_EndStateBlock(This->device, &This->stateblock); 00251 } 00252 IDirect3DStateBlock9_Capture(This->stateblock); /* Save current state */ 00253 } 00254 00255 /* Apply device state */ 00256 set_states(This); 00257 00258 D3DXMatrixIdentity(&This->transform); 00259 D3DXMatrixIdentity(&This->view); 00260 00261 This->flags=flags; 00262 This->ready=TRUE; 00263 00264 return D3D_OK; 00265 } 00266 00267 static HRESULT WINAPI ID3DXSpriteImpl_Draw(LPD3DXSPRITE iface, LPDIRECT3DTEXTURE9 texture, CONST RECT *rect, CONST D3DXVECTOR3 *center, 00268 CONST D3DXVECTOR3 *position, D3DCOLOR color) 00269 { 00270 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00271 D3DSURFACE_DESC texdesc; 00272 TRACE("(%p): relay\n", This); 00273 00274 if(texture==NULL) return D3DERR_INVALIDCALL; 00275 if(!This->ready) return D3DERR_INVALIDCALL; 00276 00277 if(This->allocated_sprites==0) { 00278 This->sprites=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 32*sizeof(SPRITE)); 00279 This->allocated_sprites=32; 00280 } else if(This->allocated_sprites<=This->sprite_count) { 00281 This->allocated_sprites=This->allocated_sprites*3/2; 00282 This->sprites=HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->sprites, This->allocated_sprites*sizeof(SPRITE)); 00283 } 00284 This->sprites[This->sprite_count].texture=texture; 00285 if(!(This->flags & D3DXSPRITE_DO_NOT_ADDREF_TEXTURE)) 00286 IDirect3DTexture9_AddRef(texture); 00287 00288 /* Reuse the texture desc if possible */ 00289 if(This->sprite_count) { 00290 if(This->sprites[This->sprite_count-1].texture!=texture) { 00291 IDirect3DTexture9_GetLevelDesc(texture, 0, &texdesc); 00292 } else { 00293 texdesc.Width=This->sprites[This->sprite_count-1].texw; 00294 texdesc.Height=This->sprites[This->sprite_count-1].texh; 00295 } 00296 } else IDirect3DTexture9_GetLevelDesc(texture, 0, &texdesc); 00297 00298 This->sprites[This->sprite_count].texw=texdesc.Width; 00299 This->sprites[This->sprite_count].texh=texdesc.Height; 00300 00301 if(rect==NULL) { 00302 This->sprites[This->sprite_count].rect.left=0; 00303 This->sprites[This->sprite_count].rect.top=0; 00304 This->sprites[This->sprite_count].rect.right=texdesc.Width; 00305 This->sprites[This->sprite_count].rect.bottom=texdesc.Height; 00306 } else This->sprites[This->sprite_count].rect=*rect; 00307 00308 if(center==NULL) { 00309 This->sprites[This->sprite_count].center.x=0.0f; 00310 This->sprites[This->sprite_count].center.y=0.0f; 00311 This->sprites[This->sprite_count].center.z=0.0f; 00312 } else This->sprites[This->sprite_count].center=*center; 00313 00314 if(position==NULL) { 00315 This->sprites[This->sprite_count].pos.x=0.0f; 00316 This->sprites[This->sprite_count].pos.y=0.0f; 00317 This->sprites[This->sprite_count].pos.z=0.0f; 00318 } else This->sprites[This->sprite_count].pos=*position; 00319 00320 This->sprites[This->sprite_count].color=color; 00321 This->sprite_count++; 00322 00323 return D3D_OK; 00324 } 00325 00326 static HRESULT WINAPI ID3DXSpriteImpl_Flush(LPD3DXSPRITE iface) 00327 { 00328 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00329 SPRITEVERTEX *vertices; 00330 int i; 00331 TRACE("(%p): relay\n", This); 00332 00333 if(!This->ready) return D3DERR_INVALIDCALL; 00334 if(!This->sprite_count) return D3D_OK; 00335 00336 /* TODO: use of a vertex buffer here */ 00337 vertices=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SPRITEVERTEX)*4*This->sprite_count); 00338 00339 for(i=0;i<This->sprite_count;i++) { 00340 float spritewidth=(float)This->sprites[i].rect.right-(float)This->sprites[i].rect.left; 00341 float spriteheight=(float)This->sprites[i].rect.bottom-(float)This->sprites[i].rect.top; 00342 00343 vertices[4*i ].pos.x = This->sprites[i].pos.x - This->sprites[i].center.x; 00344 vertices[4*i ].pos.y = This->sprites[i].pos.y - This->sprites[i].center.y; 00345 vertices[4*i ].pos.z = This->sprites[i].pos.z - This->sprites[i].center.z; 00346 vertices[4*i+1].pos.x = spritewidth + This->sprites[i].pos.x - This->sprites[i].center.x; 00347 vertices[4*i+1].pos.y = This->sprites[i].pos.y - This->sprites[i].center.y; 00348 vertices[4*i+1].pos.z = This->sprites[i].pos.z - This->sprites[i].center.z; 00349 vertices[4*i+2].pos.x = spritewidth + This->sprites[i].pos.x - This->sprites[i].center.x; 00350 vertices[4*i+2].pos.y = spriteheight + This->sprites[i].pos.y - This->sprites[i].center.y; 00351 vertices[4*i+2].pos.z = This->sprites[i].pos.z - This->sprites[i].center.z; 00352 vertices[4*i+3].pos.x = This->sprites[i].pos.x - This->sprites[i].center.x; 00353 vertices[4*i+3].pos.y = spriteheight + This->sprites[i].pos.y - This->sprites[i].center.y; 00354 vertices[4*i+3].pos.z = This->sprites[i].pos.z - This->sprites[i].center.z; 00355 vertices[4*i ].col = This->sprites[i].color; 00356 vertices[4*i+1].col = This->sprites[i].color; 00357 vertices[4*i+2].col = This->sprites[i].color; 00358 vertices[4*i+3].col = This->sprites[i].color; 00359 vertices[4*i ].tex.x = (float)This->sprites[i].rect.left / (float)This->sprites[i].texw; 00360 vertices[4*i ].tex.y = (float)This->sprites[i].rect.top / (float)This->sprites[i].texh; 00361 vertices[4*i+1].tex.x = (float)This->sprites[i].rect.right / (float)This->sprites[i].texw; 00362 vertices[4*i+1].tex.y = (float)This->sprites[i].rect.top / (float)This->sprites[i].texh; 00363 vertices[4*i+2].tex.x = (float)This->sprites[i].rect.right / (float)This->sprites[i].texw; 00364 vertices[4*i+2].tex.y = (float)This->sprites[i].rect.bottom / (float)This->sprites[i].texh; 00365 vertices[4*i+3].tex.x = (float)This->sprites[i].rect.left / (float)This->sprites[i].texw; 00366 vertices[4*i+3].tex.y = (float)This->sprites[i].rect.bottom / (float)This->sprites[i].texh; 00367 } 00368 00369 D3DXVec3TransformCoordArray(&vertices[0].pos, sizeof(SPRITEVERTEX), &vertices[0].pos, sizeof(SPRITEVERTEX), &This->transform, 4*This->sprite_count); 00370 D3DXVec3TransformCoordArray(&vertices[0].pos, sizeof(SPRITEVERTEX), &vertices[0].pos, sizeof(SPRITEVERTEX), &This->view, 4*This->sprite_count); 00371 00372 IDirect3DDevice9_SetVertexDeclaration(This->device, This->vdecl); 00373 00374 for(i=0;i<This->sprite_count;i++) { 00375 if(!i) 00376 IDirect3DDevice9_SetTexture(This->device, 0, (LPDIRECT3DBASETEXTURE9)(This->sprites[i].texture)); 00377 else if(This->sprites[i].texture!=This->sprites[i-1].texture) 00378 IDirect3DDevice9_SetTexture(This->device, 0, (LPDIRECT3DBASETEXTURE9)(This->sprites[i].texture)); 00379 00380 IDirect3DDevice9_DrawPrimitiveUP(This->device, D3DPT_TRIANGLEFAN, 2, vertices+4*i, sizeof(SPRITEVERTEX)); 00381 } 00382 HeapFree(GetProcessHeap(), 0, vertices); 00383 00384 if(!(This->flags & D3DXSPRITE_DO_NOT_ADDREF_TEXTURE)) 00385 for(i=0;i<This->sprite_count;i++) 00386 IDirect3DTexture9_Release(This->sprites[i].texture); 00387 00388 This->sprite_count=0; 00389 00390 /* Flush may be called more than once, so we don't reset This->ready here */ 00391 00392 return D3D_OK; 00393 } 00394 00395 static HRESULT WINAPI ID3DXSpriteImpl_End(LPD3DXSPRITE iface) 00396 { 00397 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00398 TRACE("(%p): relay\n", This); 00399 00400 if(!This->ready) return D3DERR_INVALIDCALL; 00401 00402 ID3DXSprite_Flush(iface); 00403 00404 if(!(This->flags & D3DXSPRITE_DONOTSAVESTATE)) 00405 if(This->stateblock) IDirect3DStateBlock9_Apply(This->stateblock); /* Restore old state */ 00406 00407 This->ready=FALSE; 00408 00409 return D3D_OK; 00410 } 00411 00412 static HRESULT WINAPI ID3DXSpriteImpl_OnLostDevice(LPD3DXSPRITE iface) 00413 { 00414 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00415 TRACE("(%p)\n", This); 00416 00417 if(This->stateblock) IDirect3DStateBlock9_Release(This->stateblock); 00418 if(This->vdecl) IDirect3DVertexDeclaration9_Release(This->vdecl); 00419 This->vdecl=NULL; 00420 This->stateblock=NULL; 00421 00422 /* Reset some variables */ 00423 ID3DXSprite_OnResetDevice(iface); 00424 00425 return D3D_OK; 00426 } 00427 00428 static HRESULT WINAPI ID3DXSpriteImpl_OnResetDevice(LPD3DXSPRITE iface) 00429 { 00430 ID3DXSpriteImpl *This=(ID3DXSpriteImpl*)iface; 00431 int i; 00432 00433 TRACE("(%p)\n", This); 00434 00435 for(i=0;i<This->sprite_count;i++) 00436 if(This->sprites[i].texture) 00437 IDirect3DTexture9_Release(This->sprites[i].texture); 00438 00439 This->sprite_count=0; 00440 00441 This->flags=0; 00442 This->ready=FALSE; 00443 00444 /* keep matrices */ 00445 /* device objects get restored on Begin */ 00446 00447 return D3D_OK; 00448 } 00449 00450 static const ID3DXSpriteVtbl D3DXSprite_Vtbl = 00451 { 00452 /*** IUnknown methods ***/ 00453 ID3DXSpriteImpl_QueryInterface, 00454 ID3DXSpriteImpl_AddRef, 00455 ID3DXSpriteImpl_Release, 00456 /*** ID3DXSprite methods ***/ 00457 ID3DXSpriteImpl_GetDevice, 00458 ID3DXSpriteImpl_GetTransform, 00459 ID3DXSpriteImpl_SetTransform, 00460 ID3DXSpriteImpl_SetWorldViewRH, 00461 ID3DXSpriteImpl_SetWorldViewLH, 00462 ID3DXSpriteImpl_Begin, 00463 ID3DXSpriteImpl_Draw, 00464 ID3DXSpriteImpl_Flush, 00465 ID3DXSpriteImpl_End, 00466 ID3DXSpriteImpl_OnLostDevice, 00467 ID3DXSpriteImpl_OnResetDevice 00468 }; 00469 00470 HRESULT WINAPI D3DXCreateSprite(LPDIRECT3DDEVICE9 device, LPD3DXSPRITE *sprite) 00471 { 00472 ID3DXSpriteImpl *object; 00473 D3DCAPS9 caps; 00474 TRACE("(void): relay\n"); 00475 00476 if(device==NULL || sprite==NULL) return D3DERR_INVALIDCALL; 00477 00478 object=HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXSpriteImpl)); 00479 if(object==NULL) { 00480 *sprite=NULL; 00481 return E_OUTOFMEMORY; 00482 } 00483 object->lpVtbl=&D3DXSprite_Vtbl; 00484 object->ref=1; 00485 object->device=device; 00486 IUnknown_AddRef(device); 00487 00488 object->vdecl=NULL; 00489 object->stateblock=NULL; 00490 00491 D3DXMatrixIdentity(&object->transform); 00492 D3DXMatrixIdentity(&object->view); 00493 00494 IDirect3DDevice9_GetDeviceCaps(device, &caps); 00495 object->texfilter_caps=caps.TextureFilterCaps; 00496 object->maxanisotropy=caps.MaxAnisotropy; 00497 object->alphacmp_caps=caps.AlphaCmpCaps; 00498 00499 ID3DXSprite_OnResetDevice((ID3DXSprite*)object); 00500 00501 object->sprites=NULL; 00502 object->allocated_sprites=0; 00503 *sprite=(ID3DXSprite*)object; 00504 00505 return D3D_OK; 00506 } Generated on Sun May 27 2012 04:22:12 for ReactOS by
1.7.6.1
|