#include "texture_d3d9.h" using namespace std; TextureD3D9::TextureD3D9(LPDIRECT3DDEVICE9 dev,Pixelmap *image, SamplerState samp,unsigned int flags): Texture(image,samp,flags), dev(dev), forcenonpow2conditionals(false) { if (!is_valid) return; InitTex(); } TextureD3D9::~TextureD3D9() { if (is_valid) { // free all this shit tex->Release(); } } void TextureD3D9::InitTex() { D3DCAPS9 caps; dev->GetDeviceCaps(&caps); maxaniso=caps.MaxAnisotropy; if (!(is_pow2(image->Width())&&is_pow2(image->Height()))) { if (caps.TextureCaps&D3DPTEXTURECAPS_POW2) { if (caps.TextureCaps&D3DPTEXTURECAPS_NONPOW2CONDITIONAL) forcenonpow2conditionals=true; else { is_valid=false; return; } } } if (dev->CreateTexture(image->Width(),image->Height(),0,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,&tex,NULL)!=D3D_OK) { is_valid=false; return; } D3DLOCKED_RECT lockrect; // surface locked image rect (to copy stuff to) D3DSURFACE_DESC surfdesc; // surface descriptor (for information) tex->GetLevelDesc(0,&surfdesc); tex->GetSurfaceLevel(0,&surface); if (surface->LockRect(&lockrect,NULL,0)==D3D_OK) { Pixelmap *tmpimg=image->Convert(PixelsR8G8B8A8); tmpimg->SwapChannels(0,2); register unsigned int w=surfdesc.Width<(UINT)tmpimg->Width()?surfdesc.Width:(UINT)tmpimg->Width(); register unsigned int h=surfdesc.Height<(UINT)tmpimg->Height()?surfdesc.Height:(UINT)tmpimg->Height(); for (register int y=0; y<(int)h; y++) PixelBufferCopy((unsigned char *)tmpimg->PixPtr(0,y),(unsigned char *)lockrect.pBits+lockrect.Pitch*y,tmpimg->Format(),w); delete tmpimg; if (surface->UnlockRect()!=D3D_OK) { tex->Release(); is_valid=false; return; } } else { tex->Release(); is_valid=false; return; } } void *TextureD3D9::GetID() { return (void *)tex; } static DWORD d3d_texfilter[]= { D3DTEXF_LINEAR, D3DTEXF_POINT, D3DTEXF_LINEAR }; static DWORD d3d_texwrap[]= { D3DTADDRESS_WRAP, D3DTADDRESS_BORDER, D3DTADDRESS_CLAMP }; void TextureD3D9::Bind(int stage) { dev->SetTexture(stage,tex); dev->SetTextureStageState(stage,D3DTSS_COLOROP,D3DTOP_MODULATE); dev->SetTextureStageState(stage,D3DTSS_COLORARG1,D3DTA_CURRENT); dev->SetTextureStageState(stage,D3DTSS_COLORARG2,D3DTA_TEXTURE); dev->SetTextureStageState(stage,D3DTSS_ALPHAOP,D3DTOP_MODULATE); dev->SetTextureStageState(stage,D3DTSS_ALPHAARG1,D3DTA_CURRENT); dev->SetTextureStageState(stage,D3DTSS_ALPHAARG2,D3DTA_TEXTURE); if (forcenonpow2conditionals) { dev->SetRenderState((D3DRENDERSTATETYPE)((int)D3DRS_WRAP0+stage),FALSE); dev->SetSamplerState(stage,D3DSAMP_MAGFILTER,d3d_texfilter[samp.magmode]); dev->SetSamplerState(stage,D3DSAMP_MINFILTER,D3DTEXF_POINT); dev->SetSamplerState(stage,D3DSAMP_MIPFILTER,D3DTEXF_NONE); dev->SetSamplerState(stage,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP); dev->SetSamplerState(stage,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP); } else { dev->SetSamplerState(stage,D3DSAMP_MAGFILTER,d3d_texfilter[samp.magmode]); dev->SetSamplerState(stage,D3DSAMP_MINFILTER,samp.aniso?(DWORD)D3DTEXF_ANISOTROPIC:d3d_texfilter[samp.minmode]); dev->SetSamplerState(stage,D3DSAMP_MIPFILTER,(samp.minmode==RAVEN_MIPMAP_SAMPLE)?D3DTEXF_LINEAR:D3DTEXF_NONE); dev->SetSamplerState(stage,D3DSAMP_ADDRESSU,d3d_texwrap[samp.wraps]); dev->SetSamplerState(stage,D3DSAMP_ADDRESSV,d3d_texwrap[samp.wrapt]); dev->SetSamplerState(stage,D3DSAMP_MAXANISOTROPY,min(maxaniso,samp.aniso)); } }