ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

sprite.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.