Selaa lähdekoodia

Ensuring that texture fields are immutable (WIP for DX9 and DX11)

Marko Pintera 12 vuotta sitten
vanhempi
sitoutus
044b85e1e0

+ 7 - 3
CamelotCore/Include/CmRenderSystem.h

@@ -214,12 +214,16 @@ namespace CamelotFramework
 		 */
 		 */
 		virtual void swapBuffers(RenderTargetPtr target);
 		virtual void swapBuffers(RenderTargetPtr target);
 
 
-		/** Gets the capabilities of the render system. */
-		const RenderSystemCapabilities* getCapabilities(void) const;
+		/**
+		 * @brief	Gets the capabilities of the render system.
+		 *
+		 * @note	Thread safe.
+		 */
+		const RenderSystemCapabilities* getCapabilities() const;
 
 
 		/** Returns the driver version.
 		/** Returns the driver version.
 		*/
 		*/
-		virtual const DriverVersion& getDriverVersion(void) const;
+		virtual const DriverVersion& getDriverVersion() const;
 
 
 		/** Binds a given GpuProgram (but not the parameters). 
 		/** Binds a given GpuProgram (but not the parameters). 
 		@remarks Only one GpuProgram of each type can be bound at once, binding another
 		@remarks Only one GpuProgram of each type can be bound at once, binding another

+ 14 - 24
CamelotCore/Include/CmTexture.h

@@ -25,8 +25,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 THE SOFTWARE.
 -----------------------------------------------------------------------------
 -----------------------------------------------------------------------------
 */
 */
-#ifndef _Texture_H__
-#define _Texture_H__
+#pragma once
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
 #include "CmGpuResource.h"
 #include "CmGpuResource.h"
@@ -34,14 +33,8 @@ THE SOFTWARE.
 #include "CmPixelUtil.h"
 #include "CmPixelUtil.h"
 #include "CmTextureView.h"
 #include "CmTextureView.h"
 
 
-namespace CamelotFramework {
-
-	/** \addtogroup Core
-	*  @{
-	*/
-	/** \addtogroup Resources
-	*  @{
-	*/
+namespace CamelotFramework 
+{
 	/** Enum identifying the texture usage
 	/** Enum identifying the texture usage
     */
     */
     enum TextureUsage
     enum TextureUsage
@@ -250,18 +243,18 @@ namespace CamelotFramework {
     protected:
     protected:
 		friend class TextureManager;
 		friend class TextureManager;
 
 
-        UINT32 mHeight;
-        UINT32 mWidth;
-        UINT32 mDepth;
+        UINT32 mHeight; // Immutable
+        UINT32 mWidth; // Immutable
+        UINT32 mDepth; // Immutable
 
 
-		UINT32 mNumMipmaps;
-		bool mHwGamma;
-		UINT32 mFSAA;
-		String mFSAAHint;
+		UINT32 mNumMipmaps; // Immutable
+		bool mHwGamma; // Immutable
+		UINT32 mFSAA; // Immutable
+		String mFSAAHint; // Immutable
 
 
-        TextureType mTextureType;
-		PixelFormat mFormat;
-        int mUsage; // Bit field, so this can't be TextureUsage
+        TextureType mTextureType; // Immutable
+		PixelFormat mFormat; // Immutable
+        int mUsage; // Immutable
 
 
 		Texture();
 		Texture();
 
 
@@ -303,7 +296,4 @@ namespace CamelotFramework {
 			PixelFormat format, int usage = TU_DEFAULT,
 			PixelFormat format, int usage = TU_DEFAULT,
 			bool hwGammaCorrection = false, UINT32 fsaa = 0, const String& fsaaHint = StringUtil::BLANK);
 			bool hwGammaCorrection = false, UINT32 fsaa = 0, const String& fsaaHint = StringUtil::BLANK);
     };
     };
-	/** @} */
-}
-
-#endif
+}

+ 14 - 36
CamelotCore/Include/CmTextureManager.h

@@ -25,35 +25,19 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 THE SOFTWARE.
 -----------------------------------------------------------------------------
 -----------------------------------------------------------------------------
 */
 */
-#ifndef _TextureManager_H__
-#define _TextureManager_H__
+#pragma once
 
 
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
 
 
 #include "CmTexture.h"
 #include "CmTexture.h"
 #include "CmModule.h"
 #include "CmModule.h"
 
 
-
-namespace CamelotFramework {
-
-	/** \addtogroup Core
-	*  @{
-	*/
-	/** \addtogroup Resources
-	*  @{
-	*/
-	/** Class for loading & managing textures.
-        @remarks
-            Note that this class is abstract - the particular
-            RenderSystem that is in use at the time will create
-            a concrete subclass of this. Note that the concrete
-            class will be available via the abstract singleton
-            obtained from TextureManager::getSingleton(), but
-            you should not assume that it is available until you
-            have a) initialised Ogre (after selecting a RenderSystem
-            and calling initialise from the Root object), and b)
-            created at least one window - this may be done at the
-            same time as part a if you allow Ogre to autocreate one.
+namespace CamelotFramework 
+{
+    /**
+     * @brief	Class for loading and managing textures.
+     *
+     * @note	Must be initialized when RenderSystem is first started.
      */
      */
     class CM_EXPORT TextureManager : public Module<TextureManager>
     class CM_EXPORT TextureManager : public Module<TextureManager>
     {
     {
@@ -202,14 +186,12 @@ namespace CamelotFramework {
 		*/
 		*/
 		virtual bool isFormatSupported(TextureType ttype, PixelFormat format, int usage);
 		virtual bool isFormatSupported(TextureType ttype, PixelFormat format, int usage);
 
 
-		/** Returns whether this render system can support the texture format requested
-			with the given usage options, or another format with no quality reduction.
-		*/
-		virtual bool isEquivalentFormatSupported(TextureType ttype, PixelFormat format, int usage);
-
-		/** Gets the format which will be natively used for a requested format given the
-			constraints of the current device.
-		*/
+		/**
+		 * @brief	Gets the format which will be natively used for a requested format given the
+		 *			constraints of the current device.
+		 *
+		 * @note	Thread safe.
+		 */
 		virtual PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage) = 0;
 		virtual PixelFormat getNativeFormat(TextureType ttype, PixelFormat format, int usage) = 0;
 
 
 		HTexture getDummyTexture() const { return mDummyTexture; }
 		HTexture getDummyTexture() const { return mDummyTexture; }
@@ -223,8 +205,4 @@ namespace CamelotFramework {
 
 
 		virtual void onStartUp();
 		virtual void onStartUp();
     };
     };
-	/** @} */
-	/** @} */
-}// Namespace
-
-#endif
+}

+ 0 - 2
CamelotCore/Source/CmRenderSystem.cpp

@@ -94,8 +94,6 @@ namespace CamelotFramework {
 
 
 	const RenderSystemCapabilities* RenderSystem::getCapabilities(void) const 
 	const RenderSystemCapabilities* RenderSystem::getCapabilities(void) const 
 	{ 
 	{ 
-		THROW_IF_NOT_CORE_THREAD;
-
 		return mCurrentCapabilities; 
 		return mCurrentCapabilities; 
 	}
 	}
 
 

+ 10 - 10
CamelotCore/Source/CmTexture.cpp

@@ -34,13 +34,12 @@ THE SOFTWARE.
 #include "CmCoreThread.h"
 #include "CmCoreThread.h"
 #include "CmAsyncOp.h"
 #include "CmAsyncOp.h"
 
 
-
-namespace CamelotFramework {
-	//--------------------------------------------------------------------------
+namespace CamelotFramework 
+{
     Texture::Texture()
     Texture::Texture()
         : 
         : 
-            mHeight(512),
-            mWidth(512),
+            mHeight(32),
+            mWidth(32),
             mDepth(1),
             mDepth(1),
             mNumMipmaps(0),
             mNumMipmaps(0),
 			mHwGamma(false),
 			mHwGamma(false),
@@ -51,7 +50,7 @@ namespace CamelotFramework {
     {
     {
         
         
     }
     }
-	//-------------------------------------------------------------------------
+
 	void Texture::initialize(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps, 
 	void Texture::initialize(TextureType textureType, UINT32 width, UINT32 height, UINT32 depth, UINT32 numMipmaps, 
 		PixelFormat format, int usage, bool hwGamma, UINT32 fsaa, const String& fsaaHint)
 		PixelFormat format, int usage, bool hwGamma, UINT32 fsaa, const String& fsaaHint)
 	{
 	{
@@ -60,27 +59,28 @@ namespace CamelotFramework {
 		mHeight = height;
 		mHeight = height;
 		mDepth = depth;
 		mDepth = depth;
 		mNumMipmaps = numMipmaps;
 		mNumMipmaps = numMipmaps;
-		mFormat = format;
 		mUsage = usage;
 		mUsage = usage;
 		mHwGamma = hwGamma;
 		mHwGamma = hwGamma;
 		mFSAA = fsaa;
 		mFSAA = fsaa;
 		mFSAAHint = fsaaHint;
 		mFSAAHint = fsaaHint;
 
 
+		// Adjust format if required
+		mFormat = TextureManager::instance().getNativeFormat(mTextureType, format, mUsage);
 		mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
 		mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
 
 
 		Resource::initialize();
 		Resource::initialize();
 	}
 	}
-    //--------------------------------------------------------------------------
+
     bool Texture::hasAlpha(void) const
     bool Texture::hasAlpha(void) const
     {
     {
         return PixelUtil::hasAlpha(mFormat);
         return PixelUtil::hasAlpha(mFormat);
     }
     }
-    //--------------------------------------------------------------------------
+
 	UINT32 Texture::calculateSize(void) const
 	UINT32 Texture::calculateSize(void) const
 	{
 	{
         return getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
         return getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);
 	}
 	}
-	//--------------------------------------------------------------------------
+
 	UINT32 Texture::getNumFaces(void) const
 	UINT32 Texture::getNumFaces(void) const
 	{
 	{
 		return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;
 		return getTextureType() == TEX_TYPE_CUBE_MAP ? 6 : 1;

+ 0 - 8
CamelotCore/Source/CmTextureManager.cpp

@@ -129,12 +129,4 @@ namespace CamelotFramework
 	{
 	{
 		return getNativeFormat(ttype, format, usage) == format;
 		return getNativeFormat(ttype, format, usage) == format;
 	}
 	}
-
-	bool TextureManager::isEquivalentFormatSupported(TextureType ttype, PixelFormat format, int usage)
-	{
-		PixelFormat supportedFormat = getNativeFormat(ttype, format, usage);
-
-		// Assume that same or greater number of bits means quality not degraded
-		return PixelUtil::getNumElemBits(supportedFormat) >= PixelUtil::getNumElemBits(format);
-	}
 }
 }

+ 35 - 6
CamelotD3D11RenderSystem/Source/CmD3D11Texture.cpp

@@ -197,7 +197,11 @@ namespace CamelotFramework
 		// Determine which D3D11 pixel format we'll use
 		// Determine which D3D11 pixel format we'll use
 		HRESULT hr;
 		HRESULT hr;
 		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
 		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
-		mFormat = D3D11Mappings::_getPF(d3dPF);
+
+		if(mFormat != D3D11Mappings::_getPF(d3dPF))
+		{
+			CM_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+		}
 
 
 		D3D11_TEXTURE1D_DESC desc;
 		D3D11_TEXTURE1D_DESC desc;
 		desc.Width			= static_cast<UINT32>(mWidth);
 		desc.Width			= static_cast<UINT32>(mWidth);
@@ -253,7 +257,13 @@ namespace CamelotFramework
 		}
 		}
 
 
 		m1DTex->GetDesc(&desc);
 		m1DTex->GetDesc(&desc);
-		mNumMipmaps = desc.MipLevels - 1;
+
+		if(mNumMipmaps != (desc.MipLevels - 1))
+		{
+			CM_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
+				"Requested: " + toString(mNumMipmaps) + ". Got: " + toString(desc.MipLevels - 1) + ".");
+		}
+
 		mDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
 		mDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
 
 
 		// Create texture view
 		// Create texture view
@@ -281,7 +291,11 @@ namespace CamelotFramework
 		// Determine which D3D11 pixel format we'll use
 		// Determine which D3D11 pixel format we'll use
 		HRESULT hr;
 		HRESULT hr;
 		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
 		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
-		mFormat = D3D11Mappings::_getPF(d3dPF);
+
+		if(mFormat != D3D11Mappings::_getPF(d3dPF))
+		{
+			CM_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+		}
 
 
 		D3D11_TEXTURE2D_DESC desc;
 		D3D11_TEXTURE2D_DESC desc;
 		desc.Width			= static_cast<UINT32>(mWidth);
 		desc.Width			= static_cast<UINT32>(mWidth);
@@ -369,7 +383,12 @@ namespace CamelotFramework
 		}
 		}
 
 
 		m2DTex->GetDesc(&desc);
 		m2DTex->GetDesc(&desc);
-		mNumMipmaps = desc.MipLevels - 1;
+
+		if(mNumMipmaps != (desc.MipLevels - 1))
+		{
+			CM_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
+				"Requested: " + toString(mNumMipmaps) + ". Got: " + toString(desc.MipLevels - 1) + ".");
+		}
 
 
 		mDXGIFormat = desc.Format;
 		mDXGIFormat = desc.Format;
 
 
@@ -438,7 +457,11 @@ namespace CamelotFramework
 		// Determine which D3D11 pixel format we'll use
 		// Determine which D3D11 pixel format we'll use
 		HRESULT hr;
 		HRESULT hr;
 		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
 		DXGI_FORMAT d3dPF = D3D11Mappings::_getPF(D3D11Mappings::_getClosestSupportedPF(mFormat));
-		mFormat = D3D11Mappings::_getPF(d3dPF);
+		
+		if(mFormat != D3D11Mappings::_getPF(d3dPF))
+		{
+			CM_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+		}
 
 
 		D3D11_TEXTURE3D_DESC desc;
 		D3D11_TEXTURE3D_DESC desc;
 		desc.Width			= static_cast<UINT32>(mWidth);
 		desc.Width			= static_cast<UINT32>(mWidth);
@@ -496,7 +519,13 @@ namespace CamelotFramework
 
 
 		// Create texture view
 		// Create texture view
 		m3DTex->GetDesc(&desc);
 		m3DTex->GetDesc(&desc);
-		mNumMipmaps = desc.MipLevels - 1;
+
+		if(mNumMipmaps != (desc.MipLevels - 1))
+		{
+			CM_EXCEPT(RenderingAPIException, "Driver returned different number of mip maps than requested. " \
+               "Requested: " + toString(mNumMipmaps) + ". Got: " + toString(desc.MipLevels - 1) + ".");
+		}
+
 		mDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
 		mDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
 
 
 		if((mUsage & TU_DEPTHSTENCIL) == 0)
 		if((mUsage & TU_DEPTHSTENCIL) == 0)

+ 18 - 10
CamelotD3D9Renderer/Source/CmD3D9Texture.cpp

@@ -395,7 +395,11 @@ namespace CamelotFramework
 		
 		
 		// let's D3DX check the corrected pixel format
 		// let's D3DX check the corrected pixel format
 		hr = D3DXCheckTextureRequirements(d3d9Device, NULL, NULL, NULL, 0, &d3dPF, mD3DPool);
 		hr = D3DXCheckTextureRequirements(d3d9Device, NULL, NULL, NULL, 0, &d3dPF, mD3DPool);
-		mFormat = D3D9Mappings::_getPF(d3dPF);
+		
+		if(mFormat != D3D9Mappings::_getPF(d3dPF))
+		{
+			CM_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+		}
 
 
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		UINT numMips = (mNumMipmaps == MIP_UNLIMITED) ? D3DX_DEFAULT : mNumMipmaps + 1;
 		UINT numMips = (mNumMipmaps == MIP_UNLIMITED) ? D3DX_DEFAULT : mNumMipmaps + 1;
@@ -446,8 +450,7 @@ namespace CamelotFramework
 		// check if mip maps are supported on hardware
 		// check if mip maps are supported on hardware
 		if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) || (mUsage & TU_RENDERTARGET) != 0 || (mUsage & TU_DEPTHSTENCIL) != 0)
 		if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) || (mUsage & TU_RENDERTARGET) != 0 || (mUsage & TU_DEPTHSTENCIL) != 0)
 		{
 		{
-			// no mip map support for this kind of textures :(
-			mNumMipmaps = 0;
+			CM_EXCEPT(InvalidParametersException, "Invalid number of mipmaps. Maximum allowed is: 0");
 			numMips = 1;
 			numMips = 1;
 		}
 		}
 
 
@@ -574,7 +577,11 @@ namespace CamelotFramework
 
 
 		// let's D3DX check the corrected pixel format
 		// let's D3DX check the corrected pixel format
 		hr = D3DXCheckCubeTextureRequirements(d3d9Device, NULL, NULL, 0, &d3dPF, mD3DPool);
 		hr = D3DXCheckCubeTextureRequirements(d3d9Device, NULL, NULL, 0, &d3dPF, mD3DPool);
-		mFormat = D3D9Mappings::_getPF(d3dPF);
+		
+		if(mFormat != D3D9Mappings::_getPF(d3dPF))
+		{
+			CM_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+		}
 
 
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
 		DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
@@ -610,8 +617,7 @@ namespace CamelotFramework
 		// check if mip map cube textures are supported
 		// check if mip map cube textures are supported
 		if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
 		if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
 		{
 		{
-			// no mip map support for this kind of textures :(
-			mNumMipmaps = 0;
+			CM_EXCEPT(InvalidParametersException, "Invalid number of mipmaps. Maximum allowed is: 0");
 			numMips = 1;
 			numMips = 1;
 		}
 		}
 
 
@@ -681,7 +687,11 @@ namespace CamelotFramework
 
 
 		// let's D3DX check the corrected pixel format
 		// let's D3DX check the corrected pixel format
 		hr = D3DXCheckVolumeTextureRequirements(d3d9Device, NULL, NULL, NULL, NULL, 0, &d3dPF, mD3DPool);
 		hr = D3DXCheckVolumeTextureRequirements(d3d9Device, NULL, NULL, NULL, NULL, 0, &d3dPF, mD3DPool);
-		mFormat = D3D9Mappings::_getPF(d3dPF);
+		
+		if(mFormat != D3D9Mappings::_getPF(d3dPF))
+		{
+			CM_EXCEPT(RenderingAPIException, "Provided pixel format is not supported by the driver: " + toString(mFormat));
+		}
 
 
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		// Use D3DX to help us create the texture, this way it can adjust any relevant sizes
 		DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
 		DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
@@ -715,9 +725,7 @@ namespace CamelotFramework
 		// check if mip map volume textures are supported
 		// check if mip map volume textures are supported
 		if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
 		if (!(rkCurCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
 		{
 		{
-			// no mip map support for this kind of textures :(
-			mNumMipmaps = 0;
-			numMips = 1;
+			CM_EXCEPT(InvalidParametersException, "Invalid number of mipmaps. Maximum allowed is: 0");
 		}
 		}
 
 
 		// derive the pool to use
 		// derive the pool to use

+ 4 - 0
CamelotGLRenderer/Include/CmGLPixelFormat.h

@@ -78,6 +78,10 @@ namespace CamelotFramework {
 		*/
 		*/
 		static PixelFormat getClosestEngineFormat(GLenum fmt);
 		static PixelFormat getClosestEngineFormat(GLenum fmt);
 
 
+		/**	Function to get the closest valid matching engine format to another engine format. 
+		*/
+		static PixelFormat getClosestValidFormat(PixelFormat fmt);
+
 		/**
 		/**
 		 * @brief	Gets OpenGL format based on a compressed OpenGL internal format.
 		 * @brief	Gets OpenGL format based on a compressed OpenGL internal format.
 		 * 			e.g. GL_COMPRESSED_RGBA_S3TC_DXT1_EXT will return GL_RGBA
 		 * 			e.g. GL_COMPRESSED_RGBA_S3TC_DXT1_EXT will return GL_RGBA

+ 15 - 6
CamelotGLRenderer/Include/CmGLRenderTexture.h

@@ -67,24 +67,33 @@ namespace CamelotFramework
 		GLFrameBufferObject* mFB;
 		GLFrameBufferObject* mFB;
     };
     };
 
 
-    /** Manager/factory for RenderTextures.
-    */
+    /**
+     * @brief	Manager/factory for RenderTextures.
+     * 			
+	 * @note	Must be initialized when RenderSystem is first started.
+     */
     class CM_RSGL_EXPORT GLRTTManager : public Module<GLRTTManager>
     class CM_RSGL_EXPORT GLRTTManager : public Module<GLRTTManager>
     {
     {
     public:
     public:
         GLRTTManager();
         GLRTTManager();
 		~GLRTTManager();
 		~GLRTTManager();
         
         
-        /** Check if a certain format is usable as FBO rendertarget format
-        */
+        /**
+         * @brief	Check if a certain format is usable as FBO rendertarget format.
+         *
+         * @note	Thread safe.
+         */
         bool checkFormat(PixelFormat format) { return mProps[format].valid; }
         bool checkFormat(PixelFormat format) { return mProps[format].valid; }
         
         
         /** Get a FBO without depth/stencil for temporary use, like blitting between textures.
         /** Get a FBO without depth/stencil for temporary use, like blitting between textures.
         */
         */
         GLuint getTemporaryFBO() { return mTempFBO; }
         GLuint getTemporaryFBO() { return mTempFBO; }
 
 
-		/** Get the closest supported alternative format. If format is supported, returns format.
-        */
+        /**
+         * @brief	Get the closest supported alternative format. If format is supported, returns format.
+         *
+         * @note	Thread safe
+         */
         virtual PixelFormat getSupportedAlternative(PixelFormat format);
         virtual PixelFormat getSupportedAlternative(PixelFormat format);
     private:
     private:
         /** Frame Buffer Object properties for a certain texture format.
         /** Frame Buffer Object properties for a certain texture format.

+ 59 - 0
CamelotGLRenderer/Source/CmGLPixelFormat.cpp

@@ -279,10 +279,69 @@ namespace CamelotFramework  {
 		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
 		case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
 		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
 		case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
 			return PF_DXT5;
 			return PF_DXT5;
+		case GL_DEPTH_COMPONENT16:
+			return PF_D16;
+		case GL_DEPTH_COMPONENT32F:
+			return PF_D32;
+		case GL_DEPTH24_STENCIL8:
+			return PF_D24S8;
+		case GL_DEPTH32F_STENCIL8:
+			return PF_D32_S8X24;
 		default:
 		default:
 			return PF_R8G8B8A8;
 			return PF_R8G8B8A8;
 		};
 		};
 	}
 	}
+	//----------------------------------------------------------------------------- 	
+	PixelFormat GLPixelUtil::getClosestValidFormat(PixelFormat fmt)
+	{
+		switch(fmt) 
+		{
+		case PF_R8:
+			return PF_R8;
+		case PF_R8G8:
+			return PF_R8G8;
+		case PF_R8G8B8:
+		case PF_B8G8R8:
+		case PF_B8G8R8X8:
+		case PF_R8G8B8X8:
+			return PF_R8G8B8X8;
+		case PF_B8G8R8A8:
+		case PF_R8G8B8A8:
+			return PF_R8G8B8A8;
+		case PF_FLOAT16_R:
+			return PF_FLOAT16_R;
+		case PF_FLOAT16_RGB:
+			return PF_FLOAT16_RGB;
+		case PF_FLOAT16_RG: 
+			return PF_FLOAT16_RG;
+		case PF_FLOAT16_RGBA:
+			return PF_FLOAT16_RGBA;
+		case PF_FLOAT32_R:
+			return PF_FLOAT32_R;
+		case PF_FLOAT32_RG:
+			return PF_FLOAT32_RG;
+		case PF_FLOAT32_RGB:
+			return PF_FLOAT32_RGB;
+		case PF_FLOAT32_RGBA:
+			return PF_FLOAT32_RGBA;
+		case PF_DXT1:
+			return PF_DXT1;
+		case PF_DXT3:
+			return PF_DXT3;
+		case PF_DXT5:
+			return PF_DXT5;
+		case PF_D16:
+			return PF_D16;
+		case PF_D32:
+			return PF_D32;
+		case PF_D24S8:
+			return PF_D24S8;
+		case PF_D32_S8X24:
+			return PF_D32_S8X24;
+		default:
+			return PF_UNKNOWN;
+		}
+	}
 	//----------------------------------------------------------------------------- 
 	//----------------------------------------------------------------------------- 
 	UINT32 GLPixelUtil::getMaxMipmaps(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format)
 	UINT32 GLPixelUtil::getMaxMipmaps(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format)
 	{
 	{

+ 10 - 11
CamelotGLRenderer/Source/CmGLTexture.cpp

@@ -62,18 +62,10 @@ namespace CamelotFramework {
 
 
 	void GLTexture::initialize_internal()
 	void GLTexture::initialize_internal()
 	{
 	{
-		// Convert to nearest power-of-two size if required
-		mWidth = GLPixelUtil::optionalPO2(mWidth);      
-		mHeight = GLPixelUtil::optionalPO2(mHeight);
-		mDepth = GLPixelUtil::optionalPO2(mDepth);
-
-		// Adjust format if required
-		mFormat = TextureManager::instance().getNativeFormat(mTextureType, mFormat, mUsage);
-
 		// Check requested number of mipmaps
 		// Check requested number of mipmaps
 		UINT32 maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
 		UINT32 maxMips = GLPixelUtil::getMaxMipmaps(mWidth, mHeight, mDepth, mFormat);
-		if(mNumMipmaps>maxMips)
-			mNumMipmaps = maxMips;
+		if(mNumMipmaps > maxMips)
+			CM_EXCEPT(InvalidParametersException, "Invalid number of mipmaps. Maximum allowed is: " + toString(maxMips));
 
 
 		if((mUsage & TU_RENDERTARGET) != 0)
 		if((mUsage & TU_RENDERTARGET) != 0)
 		{
 		{
@@ -186,8 +178,15 @@ namespace CamelotFramework {
 
 
 		PixelBufferPtr buffer = getBuffer(0, 0);
 		PixelBufferPtr buffer = getBuffer(0, 0);
 
 
+#if CM_DEBUG_MODE
 		if(buffer != nullptr)
 		if(buffer != nullptr)
-			mFormat = buffer->getFormat();
+		{
+			if(mFormat != buffer->getFormat())
+			{
+				CM_EXCEPT(InternalErrorException, "Could not create a texture buffer with wanted format: " + toString(mFormat));
+			}
+		}
+#endif
 
 
 		Texture::initialize_internal();
 		Texture::initialize_internal();
 	}
 	}

+ 8 - 9
CamelotGLRenderer/Source/CmGLTextureManager.cpp

@@ -30,6 +30,7 @@ THE SOFTWARE.
 #include "CmRenderSystem.h"
 #include "CmRenderSystem.h"
 #include "CmGLRenderTexture.h"
 #include "CmGLRenderTexture.h"
 #include "CmGLMultiRenderTexture.h"
 #include "CmGLMultiRenderTexture.h"
+#include "CmGLPixelFormat.h"
 
 
 namespace CamelotFramework
 namespace CamelotFramework
 {
 {
@@ -68,18 +69,17 @@ namespace CamelotFramework
 	PixelFormat GLTextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage)
 	PixelFormat GLTextureManager::getNativeFormat(TextureType ttype, PixelFormat format, int usage)
 	{
 	{
 		// Adjust requested parameters to capabilities
 		// Adjust requested parameters to capabilities
-        const RenderSystemCapabilities *caps = CamelotFramework::RenderSystem::instancePtr()->getCapabilities();
+        const RenderSystemCapabilities *caps = RenderSystem::instancePtr()->getCapabilities();
 
 
 		// Check compressed texture support
 		// Check compressed texture support
-		// if a compressed format not supported, revert to PF_A8R8G8B8
-		if(PixelUtil::isCompressed(format) &&
-            !caps->hasCapability( RSC_TEXTURE_COMPRESSION_DXT ))
+		// If a compressed format not supported, revert to PF_A8R8G8B8
+		if(PixelUtil::isCompressed(format) && !caps->hasCapability(RSC_TEXTURE_COMPRESSION_DXT))
 		{
 		{
 			return PF_A8R8G8B8;
 			return PF_A8R8G8B8;
 		}
 		}
-		// if floating point textures not supported, revert to PF_A8R8G8B8
-		if(PixelUtil::isFloatingPoint(format) &&
-            !caps->hasCapability( RSC_TEXTURE_FLOAT ))
+
+		// If floating point textures not supported, revert to PF_A8R8G8B8
+		if(PixelUtil::isFloatingPoint(format) && !caps->hasCapability(RSC_TEXTURE_FLOAT))
 		{
 		{
 			return PF_A8R8G8B8;
 			return PF_A8R8G8B8;
 		}
 		}
@@ -92,7 +92,6 @@ namespace CamelotFramework
             return GLRTTManager::instance().getSupportedAlternative(format);
             return GLRTTManager::instance().getSupportedAlternative(format);
         }
         }
 
 
-		// Supported
-		return format;
+		return GLPixelUtil::getClosestValidFormat(format);
 	}
 	}
 }
 }