/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/ Copyright (c) 2000-2005 The OGRE Team Also see acknowledgements in Readme.html This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt. ----------------------------------------------------------------------------- */ #ifndef _D3DTexture_H__ #define _D3DTexture_H__ #include "OgreD3D7Prerequisites.h" #include "OgreTexture.h" #include "OgreRenderTarget.h" #include "OgreRenderTexture.h" #include "OgreRenderTargetListener.h" #include "OgreD3D7HardwarePixelBuffer.h" namespace Ogre { /** Direct3D7-specific texture resource implementation. */ class D3DTexture : public Texture { public: // Constructor, called from D3DTextureManager D3DTexture(ResourceManager* creator, const String& name, ResourceHandle handle, const String& group, bool isManual, ManualResourceLoader* loader, IDirect3DDevice7 * lpDirect3dDevice); virtual ~D3DTexture(); virtual void loadImage( const Image &img ); virtual void loadImage3D( const Image imgs[]); virtual void copyToTexture(TexturePtr& target ); /// D3D-specific member that returns the underlying surface. LPDIRECTDRAWSURFACE7 getDDSurface(void); /// @copydoc Texture::getBuffer HardwarePixelBufferSharedPtr getBuffer(size_t face, size_t mipmap); /// Static pixelformat functions static D3DX_SURFACEFORMAT OgreFormat_to_D3DXFormat( PixelFormat format ); static PixelFormat closestD3DXFormat( PixelFormat format ); static bool OgreFormat_to_DDPixelFormat( PixelFormat format, DDPIXELFORMAT & out ); /// Restore this texture from a lost device void restoreFromLostDevice(void); protected: IDirect3DDevice7 * mD3DDevice; ///< A pointer to the Direct3D device. IDirectDrawSurface7 * mSurface; ///< Surface of the (first) device-specific texture. /// cube texture individual face names String mCubeFaceNames[6]; /// Vector of pointers to subsurfaces typedef std::vector SurfaceList; SurfaceList mSurfaceList; /// Are we restoring from a lost device? bool mRestoring; /// @copydoc Resource::loadImpl void loadImpl(void); /// @copydoc Texture::createInternalResourcesImpl void createInternalResourcesImpl(void); /// @copydoc Resource::freeInternalResourcesImpl void freeInternalResourcesImpl(void); void createSurface2D(void); void createSurface3D(void); /// internal method, return a D3D pixel format for texture creation void _chooseD3DFormat(DDPIXELFORMAT &ddpf); /// internal method, construct full cube texture face names from a given string void _constructCubeFaceNames(const String name); /// internal method, the cube map face name for the spec. face index String _getCubeFaceName(unsigned char face) const { assert(face < 6); return mCubeFaceNames[face]; } // Create the list of surfaces void _createSurfaceList(); }; /** Specialisation of SharedPtr to allow SharedPtr to be assigned to D3DTexturePtr @note Has to be a subclass since we need operator=. We could templatise this instead of repeating per Resource subclass, except to do so requires a form VC6 does not support i.e. ResourceSubclassPtr : public SharedPtr */ class D3DTexturePtr : public SharedPtr { public: D3DTexturePtr() : SharedPtr() {} explicit D3DTexturePtr(D3DTexture* rep) : SharedPtr(rep) {} D3DTexturePtr(const D3DTexturePtr& r) : SharedPtr(r) {} D3DTexturePtr(const ResourcePtr& r) : SharedPtr() { // lock & copy other mutex pointer OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME) OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME) pRep = static_cast(r.getPointer()); pUseCount = r.useCountPointer(); if (pUseCount) { ++(*pUseCount); } } /// Operator used to convert a ResourcePtr to a D3DTexturePtr D3DTexturePtr& operator=(const ResourcePtr& r) { if (pRep == static_cast(r.getPointer())) return *this; release(); // lock & copy other mutex pointer OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME) OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME) pRep = static_cast(r.getPointer()); pUseCount = r.useCountPointer(); if (pUseCount) { ++(*pUseCount); } return *this; } /// Operator used to convert a TexturePtr to a D3DTexturePtr D3DTexturePtr& operator=(const TexturePtr& r) { if (pRep == static_cast(r.getPointer())) return *this; release(); pRep = static_cast(r.getPointer()); pUseCount = r.useCountPointer(); if (pUseCount) { ++(*pUseCount); } return *this; } }; /// D3D7 implementation of RenderTexture class D3D7RenderTexture : public RenderTexture { public: D3D7RenderTexture( const String & name, unsigned int width, unsigned int height, TextureType texType, PixelFormat internalFormat, const NameValuePairList *misc ) : RenderTexture( name, width, height, texType, internalFormat ) { mPrivateTex = TextureManager::getSingleton().createManual(mName + "_PRIVATE##", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, texType, mWidth, mHeight, 0, internalFormat, TU_RENDERTARGET); mPrivateTex->createInternalResources(); } virtual ~D3D7RenderTexture() { mPrivateTex->unload(); TextureManager::getSingleton().remove(mPrivateTex->getName()); } bool requiresTextureFlipping() const { return false; } virtual void getCustomAttribute( const String& name, void* pData ) { if( name == "DDBACKBUFFER" ) { LPDIRECTDRAWSURFACE7 *pSurf = (LPDIRECTDRAWSURFACE7*)pData; *pSurf = mPrivateTex->getDDSurface(); return; } else if( name == "DDFRONTBUFFER" ) { LPDIRECTDRAWSURFACE7 *pSurf = (LPDIRECTDRAWSURFACE7*)pData; *pSurf = mPrivateTex->getDDSurface(); return; } else if( name == "HWND" ) { HWND *pHwnd = (HWND*)pData; *pHwnd = NULL; return; } else if( name == "isTexture" ) { bool *b = reinterpret_cast< bool * >( pData ); *b = true; return; } } virtual void writeContentsToFile( const String & filename ) {} #ifdef GTP_VISIBILITY_MODIFIED_OGRE uchar *getBufferContents(int &dimx, int &dimy) { dimx = dimy = 0; return NULL; }; #endif // GTP_VISIBILITY_MODIFIED_OGRE protected: /// The texture to which rendering takes place. D3DTexturePtr mPrivateTex; protected: virtual void _copyToTexture() { // Copy the newly-rendered data to the public texture surface. mPrivateTex->copyToTexture( mTexture ); } }; } #endif