1 /*! 2 @file 3 @author Losev Vasiliy aka bool 4 @date 06/2009 5 */ 6 7 #include <d3dx9.h> 8 #include "MyGUI_DirectXTexture.h" 9 #include "MyGUI_DirectXDataManager.h" 10 #include "MyGUI_DirectXRTTexture.h" 11 #include "MyGUI_DirectXDiagnostic.h" 12 13 namespace MyGUI 14 { 15 DirectXTexture(const std::string & _name,IDirect3DDevice9 * _device)16 DirectXTexture::DirectXTexture(const std::string& _name, IDirect3DDevice9* _device) : 17 mName(_name), 18 mpD3DDevice(_device), 19 mpTexture(nullptr), 20 mNumElemBytes(0), 21 mLock(false), 22 mRenderTarget(nullptr), 23 mInternalPool(D3DPOOL_MANAGED), 24 mInternalFormat(D3DFMT_UNKNOWN), 25 mInternalUsage(0) 26 { 27 } 28 ~DirectXTexture()29 DirectXTexture::~DirectXTexture() 30 { 31 destroy(); 32 } 33 getName() const34 const std::string& DirectXTexture::getName() const 35 { 36 return mName; 37 } 38 createManual(int _width,int _height,TextureUsage _usage,PixelFormat _format)39 void DirectXTexture::createManual(int _width, int _height, TextureUsage _usage, PixelFormat _format) 40 { 41 destroy(); 42 43 mInternalUsage = 0; 44 mInternalFormat = D3DFMT_UNKNOWN; 45 46 mSize.set(_width, _height); 47 mTextureUsage = _usage; 48 mPixelFormat = _format; 49 mInternalPool = D3DPOOL_MANAGED; 50 51 if (mTextureUsage == TextureUsage::RenderTarget) 52 { 53 mInternalUsage |= D3DUSAGE_RENDERTARGET; 54 mInternalPool = D3DPOOL_DEFAULT; 55 } 56 else if (mTextureUsage == TextureUsage::Dynamic) 57 mInternalUsage |= D3DUSAGE_DYNAMIC; 58 else if (mTextureUsage == TextureUsage::Stream) 59 mInternalUsage |= D3DUSAGE_DYNAMIC; 60 61 if (mPixelFormat == PixelFormat::R8G8B8A8) 62 { 63 mInternalFormat = D3DFMT_A8R8G8B8; 64 mNumElemBytes = 4; 65 } 66 else if (mPixelFormat == PixelFormat::R8G8B8) 67 { 68 mInternalFormat = D3DFMT_R8G8B8; 69 mNumElemBytes = 3; 70 } 71 else if (mPixelFormat == PixelFormat::L8A8) 72 { 73 mInternalFormat = D3DFMT_A8L8; 74 mNumElemBytes = 2; 75 } 76 else if (mPixelFormat == PixelFormat::L8) 77 { 78 mInternalFormat = D3DFMT_L8; 79 mNumElemBytes = 1; 80 } 81 else 82 { 83 MYGUI_PLATFORM_EXCEPT("Creating texture with unknown pixel formal."); 84 } 85 86 HRESULT result = mpD3DDevice->CreateTexture(mSize.width, mSize.height, 1, mInternalUsage, mInternalFormat, mInternalPool, &mpTexture, nullptr); 87 if (FAILED(result)) 88 { 89 MYGUI_PLATFORM_EXCEPT("Failed to create texture (error code " << result <<"): size '" << mSize << 90 "' internal usage '" << mInternalUsage << 91 "' internal format '" << mInternalFormat << "'." 92 ); 93 } 94 95 } 96 loadFromFile(const std::string & _filename)97 void DirectXTexture::loadFromFile(const std::string& _filename) 98 { 99 destroy(); 100 mTextureUsage = TextureUsage::Default; 101 mPixelFormat = PixelFormat::R8G8B8A8; 102 mNumElemBytes = 4; 103 104 std::string fullname = DirectXDataManager::getInstance().getDataPath(_filename); 105 106 D3DXIMAGE_INFO info; 107 D3DXGetImageInfoFromFile(fullname.c_str(), &info); 108 109 if (info.Format == D3DFMT_A8R8G8B8) 110 { 111 mPixelFormat = PixelFormat::R8G8B8A8; 112 mNumElemBytes = 4; 113 } 114 else if (info.Format == D3DFMT_R8G8B8) 115 { 116 mPixelFormat = PixelFormat::R8G8B8; 117 mNumElemBytes = 3; 118 } 119 else if (info.Format == D3DFMT_A8L8) 120 { 121 mPixelFormat = PixelFormat::L8A8; 122 mNumElemBytes = 2; 123 } 124 else if (info.Format == D3DFMT_L8) 125 { 126 mPixelFormat = PixelFormat::L8; 127 mNumElemBytes = 1; 128 } 129 130 mSize.set(info.Width, info.Height); 131 HRESULT result = D3DXCreateTextureFromFile(mpD3DDevice, fullname.c_str(), &mpTexture); 132 if (FAILED(result)) 133 { 134 MYGUI_PLATFORM_EXCEPT("Failed to load texture '" << _filename << 135 "' (error code " << result << 136 "): size '" << mSize << 137 "' format '" << info.Format << "'." 138 ); 139 } 140 } 141 destroy()142 void DirectXTexture::destroy() 143 { 144 if (mRenderTarget != nullptr) 145 { 146 delete mRenderTarget; 147 mRenderTarget = nullptr; 148 } 149 150 if (mpTexture != nullptr) 151 { 152 int nNewRefCount = mpTexture->Release(); 153 154 if (nNewRefCount > 0) 155 { 156 MYGUI_PLATFORM_EXCEPT("The texture object failed to cleanup properly.\n" 157 "Release() returned a reference count of '" << nNewRefCount << "'." 158 ); 159 } 160 161 mpTexture = nullptr; 162 } 163 } 164 getWidth()165 int DirectXTexture::getWidth() 166 { 167 return mSize.width; 168 } 169 getHeight()170 int DirectXTexture::getHeight() 171 { 172 return mSize.height; 173 } 174 lock(TextureUsage _access)175 void* DirectXTexture::lock(TextureUsage _access) 176 { 177 D3DLOCKED_RECT d3dlr; 178 int lockFlag = (_access == TextureUsage::Write) ? D3DLOCK_DISCARD : D3DLOCK_READONLY; 179 180 HRESULT result = mpTexture->LockRect(0, &d3dlr, nullptr, lockFlag); 181 if (FAILED(result)) 182 { 183 MYGUI_PLATFORM_EXCEPT("Failed to lock texture (error code " << result << ")."); 184 } 185 186 mLock = true; 187 return d3dlr.pBits; 188 } 189 unlock()190 void DirectXTexture::unlock() 191 { 192 HRESULT result = mpTexture->UnlockRect(0); 193 if (FAILED(result)) 194 { 195 MYGUI_PLATFORM_EXCEPT("Failed to unlock texture (error code " << result << ")."); 196 } 197 198 mLock = false; 199 } 200 isLocked()201 bool DirectXTexture::isLocked() 202 { 203 return mLock; 204 } 205 getFormat()206 PixelFormat DirectXTexture::getFormat() 207 { 208 return mPixelFormat; 209 } 210 getNumElemBytes()211 size_t DirectXTexture::getNumElemBytes() 212 { 213 return mNumElemBytes; 214 } 215 getUsage()216 TextureUsage DirectXTexture::getUsage() 217 { 218 return mTextureUsage; 219 } 220 getRenderTarget()221 IRenderTarget* DirectXTexture::getRenderTarget() 222 { 223 if (mpTexture == nullptr) 224 return nullptr; 225 226 if (mRenderTarget == nullptr) 227 mRenderTarget = new DirectXRTTexture(mpD3DDevice, mpTexture); 228 229 return mRenderTarget; 230 } 231 deviceLost()232 void DirectXTexture::deviceLost() 233 { 234 if (mInternalPool == D3DPOOL_DEFAULT) 235 { 236 destroy(); 237 } 238 } 239 deviceRestore()240 void DirectXTexture::deviceRestore() 241 { 242 if (mInternalPool == D3DPOOL_DEFAULT) 243 { 244 HRESULT result = mpD3DDevice->CreateTexture(mSize.width, mSize.height, 1, mInternalUsage, mInternalFormat, D3DPOOL_DEFAULT, &mpTexture, nullptr); 245 if (FAILED(result)) 246 { 247 MYGUI_PLATFORM_EXCEPT("Failed to recreate texture on device restore (error code " << result << ")."); 248 } 249 } 250 } 251 252 } // namespace MyGUI 253