static void device_state_capture(IDirect3DDevice9 *device, struct device_state *state) { HRESULT hr; unsigned int i; IDirect3DDevice9_GetViewport(device, &state->viewport); for (i = 0; i < state->num_render_targets; i++) { hr = IDirect3DDevice9_GetRenderTarget(device, i, &state->render_targets[i]); if (FAILED(hr)) state->render_targets[i] = NULL; } hr = IDirect3DDevice9_GetDepthStencilSurface(device, &state->depth_stencil); if (FAILED(hr)) state->depth_stencil = NULL; }
static HRESULT WINAPI ID3DXLineImpl_Begin(ID3DXLine* iface) { ID3DXLineImpl *This = impl_from_ID3DXLine(iface); HRESULT hr; D3DXMATRIX identity, projection; D3DVIEWPORT9 vp; TRACE ("(%p)->()\n", This); if (This->state != NULL) /* We already began. Return error. */ return D3DERR_INVALIDCALL; hr = IDirect3DDevice9_CreateStateBlock(This->device, D3DSBT_ALL, &This->state); if (FAILED(hr)) return D3DXERR_INVALIDDATA; hr = IDirect3DDevice9_GetViewport(This->device, &vp); if (FAILED(hr)) goto failed; D3DXMatrixIdentity(&identity); D3DXMatrixOrthoOffCenterLH(&projection, 0.0, vp.Width, /* Min and max x */ vp.Height, 0.0, /* Min and max y. Screen y is on top so this is inverted */ 0.0, 1.0); /* Min and max z */ hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_WORLD, &identity); if (FAILED(hr)) goto failed; hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_VIEW, &identity); if (FAILED(hr)) goto failed; hr = IDirect3DDevice9_SetTransform(This->device, D3DTS_PROJECTION, &projection); if (FAILED(hr)) goto failed; /* Windows sets similar states so we do the same */ hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_LIGHTING, FALSE); if (FAILED(hr)) goto failed; hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_FOGENABLE, FALSE); if (FAILED(hr)) goto failed; hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_SHADEMODE, D3DSHADE_FLAT); if (FAILED(hr)) goto failed; hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_ALPHABLENDENABLE, TRUE); if (FAILED(hr)) goto failed; hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); if (FAILED(hr)) goto failed; hr = IDirect3DDevice9_SetRenderState(This->device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); if (FAILED(hr)) goto failed; return D3D_OK; failed: IDirect3DStateBlock9_Apply(This->state); IDirect3DStateBlock9_Release(This->state); This->state = NULL; return D3DXERR_INVALIDDATA; }
static void test_ID3DXSprite(IDirect3DDevice9 *device) { ID3DXSprite *sprite; IDirect3D9 *d3d; IDirect3DDevice9 *cmpdev; IDirect3DTexture9 *tex1, *tex2; D3DXMATRIX mat, cmpmat; D3DVIEWPORT9 vp; RECT rect; D3DXVECTOR3 pos, center; HRESULT hr; IDirect3DDevice9_GetDirect3D(device, &d3d); hr = IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_DYNAMIC, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8); IDirect3D9_Release(d3d); ok (hr == D3D_OK, "D3DFMT_A8R8G8B8 not supported\n"); if (FAILED(hr)) return; hr = IDirect3DDevice9_CreateTexture(device, 64, 64, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex1, NULL); ok (hr == D3D_OK, "Failed to create first texture (error code: %#x)\n", hr); if (FAILED(hr)) return; hr = IDirect3DDevice9_CreateTexture(device, 32, 32, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tex2, NULL); ok (hr == D3D_OK, "Failed to create second texture (error code: %#x)\n", hr); if (FAILED(hr)) { IDirect3DTexture9_Release(tex1); return; } /* Test D3DXCreateSprite */ hr = D3DXCreateSprite(device, NULL); ok (hr == D3DERR_INVALIDCALL, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXCreateSprite(NULL, &sprite); ok (hr == D3DERR_INVALIDCALL, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = D3DXCreateSprite(device, &sprite); ok (hr == D3D_OK, "D3DXCreateSprite returned %#x, expected %#x\n", hr, D3D_OK); /* Test ID3DXSprite_GetDevice */ hr = ID3DXSprite_GetDevice(sprite, NULL); ok (hr == D3DERR_INVALIDCALL, "GetDevice returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = ID3DXSprite_GetDevice(sprite, &cmpdev); /* cmpdev == NULL */ ok (hr == D3D_OK, "GetDevice returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_GetDevice(sprite, &cmpdev); /* cmpdev != NULL */ ok (hr == D3D_OK, "GetDevice returned %#x, expected %#x\n", hr, D3D_OK); IDirect3DDevice9_Release(device); IDirect3DDevice9_Release(device); /* Test ID3DXSprite_GetTransform */ hr = ID3DXSprite_GetTransform(sprite, NULL); ok (hr == D3DERR_INVALIDCALL, "GetTransform returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = ID3DXSprite_GetTransform(sprite, &mat); ok (hr == D3D_OK, "GetTransform returned %#x, expected %#x\n", hr, D3D_OK); if(SUCCEEDED(hr)) { D3DXMATRIX identity; D3DXMatrixIdentity(&identity); check_mat(mat, identity); } /* Test ID3DXSprite_SetTransform */ /* Set a transform and test if it gets returned correctly */ U(mat).m[0][0]=2.1f; U(mat).m[0][1]=6.5f; U(mat).m[0][2]=-9.6f; U(mat).m[0][3]=1.7f; U(mat).m[1][0]=4.2f; U(mat).m[1][1]=-2.5f; U(mat).m[1][2]=2.1f; U(mat).m[1][3]=5.5f; U(mat).m[2][0]=-2.6f; U(mat).m[2][1]=0.3f; U(mat).m[2][2]=8.6f; U(mat).m[2][3]=8.4f; U(mat).m[3][0]=6.7f; U(mat).m[3][1]=-5.1f; U(mat).m[3][2]=6.1f; U(mat).m[3][3]=2.2f; hr = ID3DXSprite_SetTransform(sprite, NULL); ok (hr == D3DERR_INVALIDCALL, "SetTransform returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = ID3DXSprite_SetTransform(sprite, &mat); ok (hr == D3D_OK, "SetTransform returned %#x, expected %#x\n", hr, D3D_OK); if(SUCCEEDED(hr)) { hr=ID3DXSprite_GetTransform(sprite, &cmpmat); if(SUCCEEDED(hr)) check_mat(cmpmat, mat); else skip("GetTransform returned %#x\n", hr); } /* Test ID3DXSprite_SetWorldViewLH/RH */ todo_wine { hr = ID3DXSprite_SetWorldViewLH(sprite, &mat, &mat); ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_SetWorldViewLH(sprite, NULL, &mat); ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_SetWorldViewLH(sprite, &mat, NULL); ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_SetWorldViewLH(sprite, NULL, NULL); ok (hr == D3D_OK, "SetWorldViewLH returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_SetWorldViewRH(sprite, &mat, &mat); ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_SetWorldViewRH(sprite, NULL, &mat); ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_SetWorldViewRH(sprite, &mat, NULL); ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_SetWorldViewRH(sprite, NULL, NULL); ok (hr == D3D_OK, "SetWorldViewRH returned %#x, expected %#x\n", hr, D3D_OK); } IDirect3DDevice9_BeginScene(device); /* Test ID3DXSprite_Begin*/ hr = ID3DXSprite_Begin(sprite, 0); ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK); IDirect3DDevice9_GetTransform(device, D3DTS_WORLD, &mat); D3DXMatrixIdentity(&cmpmat); check_mat(mat, cmpmat); IDirect3DDevice9_GetTransform(device, D3DTS_VIEW, &mat); check_mat(mat, cmpmat); IDirect3DDevice9_GetTransform(device, D3DTS_PROJECTION, &mat); IDirect3DDevice9_GetViewport(device, &vp); D3DXMatrixOrthoOffCenterLH(&cmpmat, 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); check_mat(mat, cmpmat); /* Test ID3DXSprite_Flush and ID3DXSprite_End */ hr = ID3DXSprite_Flush(sprite); ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_End(sprite); ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Flush(sprite); /* May not be called before next Begin */ ok (hr == D3DERR_INVALIDCALL, "Flush returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = ID3DXSprite_End(sprite); ok (hr == D3DERR_INVALIDCALL, "End returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); /* Test ID3DXSprite_Draw */ hr = ID3DXSprite_Begin(sprite, 0); ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK); if(FAILED(hr)) skip("Couldn't ID3DXSprite_Begin, can't test ID3DXSprite_Draw\n"); else { /* Feed the sprite batch */ int texref1, texref2; SetRect(&rect, 53, 12, 142, 165); pos.x = 2.2f; pos.y = 4.5f; pos.z = 5.1f; center.x = 11.3f; center.y = 3.4f; center.z = 1.2f; texref1 = get_ref((IUnknown*)tex1); texref2 = get_ref((IUnknown*)tex2); hr = ID3DXSprite_Draw(sprite, NULL, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255)); ok (hr == D3DERR_INVALIDCALL, "Draw returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); hr = ID3DXSprite_Draw(sprite, tex1, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255)); ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Draw(sprite, tex2, &rect, ¢er, &pos, D3DCOLOR_XRGB( 3, 45, 66)); ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Draw(sprite, tex1, NULL, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255)); ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Draw(sprite, tex1, &rect, NULL, &pos, D3DCOLOR_XRGB(255, 255, 255)); ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Draw(sprite, tex1, &rect, ¢er, NULL, D3DCOLOR_XRGB(255, 255, 255)); ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Draw(sprite, tex1, NULL, NULL, NULL, 0); ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); check_ref((IUnknown*)tex1, texref1+5); check_ref((IUnknown*)tex2, texref2+1); hr = ID3DXSprite_Flush(sprite); ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Flush(sprite); /* Flushing twice should work */ ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK); check_ref((IUnknown*)tex1, texref1); check_ref((IUnknown*)tex2, texref2); hr = ID3DXSprite_End(sprite); ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK); } /* Test ID3DXSprite_OnLostDevice and ID3DXSprite_OnResetDevice */ /* Both can be called twice */ hr = ID3DXSprite_OnLostDevice(sprite); ok (hr == D3D_OK, "OnLostDevice returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_OnLostDevice(sprite); ok (hr == D3D_OK, "OnLostDevice returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_OnResetDevice(sprite); ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_OnResetDevice(sprite); ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK); /* Make sure everything works like before */ hr = ID3DXSprite_Begin(sprite, 0); ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Draw(sprite, tex2, &rect, ¢er, &pos, D3DCOLOR_XRGB(255, 255, 255)); ok (hr == D3D_OK, "Draw returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_Flush(sprite); ok (hr == D3D_OK, "Flush returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_End(sprite); ok (hr == D3D_OK, "End returned %#x, expected %#x\n", hr, D3D_OK); /* OnResetDevice makes the interface "forget" the Begin call */ hr = ID3DXSprite_Begin(sprite, 0); ok (hr == D3D_OK, "Begin returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_OnResetDevice(sprite); ok (hr == D3D_OK, "OnResetDevice returned %#x, expected %#x\n", hr, D3D_OK); hr = ID3DXSprite_End(sprite); ok (hr == D3DERR_INVALIDCALL, "End returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL); IDirect3DDevice9_EndScene(device); check_release((IUnknown*)sprite, 0); check_release((IUnknown*)tex2, 0); check_release((IUnknown*)tex1, 0); }
/* Helper function */ static void set_states(ID3DXSpriteImpl *object) { D3DXMATRIX mat; D3DVIEWPORT9 vp; /* Miscellaneous stuff */ IDirect3DDevice9_SetVertexShader(object->device, NULL); IDirect3DDevice9_SetPixelShader(object->device, NULL); IDirect3DDevice9_SetNPatchMode(object->device, 0.0f); /* Render states */ IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHABLENDENABLE, TRUE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHAFUNC, D3DCMP_GREATER); IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHAREF, 0x00); IDirect3DDevice9_SetRenderState(object->device, D3DRS_ALPHATESTENABLE, object->alphacmp_caps); IDirect3DDevice9_SetRenderState(object->device, D3DRS_BLENDOP, D3DBLENDOP_ADD); IDirect3DDevice9_SetRenderState(object->device, D3DRS_CLIPPING, TRUE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_CLIPPLANEENABLE, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); IDirect3DDevice9_SetRenderState(object->device, D3DRS_CULLMODE, D3DCULL_NONE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); IDirect3DDevice9_SetRenderState(object->device, D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); IDirect3DDevice9_SetRenderState(object->device, D3DRS_ENABLEADAPTIVETESSELLATION, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_FILLMODE, D3DFILL_SOLID); IDirect3DDevice9_SetRenderState(object->device, D3DRS_FOGENABLE, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_LIGHTING, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_RANGEFOGENABLE, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_SEPARATEALPHABLENDENABLE, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_SHADEMODE, D3DSHADE_GOURAUD); IDirect3DDevice9_SetRenderState(object->device, D3DRS_SPECULARENABLE, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); IDirect3DDevice9_SetRenderState(object->device, D3DRS_SRGBWRITEENABLE, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_STENCILENABLE, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_VERTEXBLEND, FALSE); IDirect3DDevice9_SetRenderState(object->device, D3DRS_WRAP0, 0); /* Texture stage states */ IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_TEXCOORDINDEX, 0); IDirect3DDevice9_SetTextureStageState(object->device, 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); IDirect3DDevice9_SetTextureStageState(object->device, 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); IDirect3DDevice9_SetTextureStageState(object->device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); /* Sampler states */ IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); if(object->texfilter_caps & D3DPTFILTERCAPS_MAGFANISOTROPIC) IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC); else IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MAXMIPLEVEL, 0); IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MAXANISOTROPY, object->maxanisotropy); if(object->texfilter_caps & D3DPTFILTERCAPS_MINFANISOTROPIC) IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC); else IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); if(object->texfilter_caps & D3DPTFILTERCAPS_MIPFLINEAR) IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); else IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MIPFILTER, D3DTEXF_POINT); IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_MIPMAPLODBIAS, 0); IDirect3DDevice9_SetSamplerState(object->device, 0, D3DSAMP_SRGBTEXTURE, 0); /* Matrices */ D3DXMatrixIdentity(&mat); IDirect3DDevice9_SetTransform(object->device, D3DTS_WORLD, &mat); IDirect3DDevice9_SetTransform(object->device, D3DTS_VIEW, &object->view); IDirect3DDevice9_GetViewport(object->device, &vp); 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); IDirect3DDevice9_SetTransform(object->device, D3DTS_PROJECTION, &mat); }