644 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			644 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (C) 2015 Patryk Nadrowski
 | |
| // This file is part of the "Irrlicht Engine".
 | |
| // For conditions of distribution and use, see copyright notice in irrlicht.h
 | |
| 
 | |
| #ifndef __C_OGLCORE_CACHE_HANDLER_H_INCLUDED__
 | |
| #define __C_OGLCORE_CACHE_HANDLER_H_INCLUDED__
 | |
| 
 | |
| 
 | |
| #include "SMaterial.h"
 | |
| #include "ITexture.h"
 | |
| 
 | |
| namespace irr
 | |
| {
 | |
| namespace video
 | |
| {
 | |
| 
 | |
| enum ESetTextureActive
 | |
| {
 | |
| 	EST_ACTIVE_ALWAYS,		// texture unit always active after set call
 | |
| 	EST_ACTIVE_ON_CHANGE	// texture unit only active after call when texture changed in cache
 | |
| };
 | |
| 
 | |
| 
 | |
| template <class TOpenGLDriver, class TOpenGLTexture>
 | |
| class COpenGLCoreCacheHandler
 | |
| {
 | |
| 	class STextureCache
 | |
| 	{
 | |
| 	public:
 | |
| 		STextureCache(COpenGLCoreCacheHandler& cacheHandler, E_DRIVER_TYPE driverType, u32 textureCount) :
 | |
| 			CacheHandler(cacheHandler), DriverType(driverType), TextureCount(textureCount)
 | |
| 		{
 | |
| 			for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
 | |
| 			{
 | |
| 				Texture[i] = 0;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		~STextureCache()
 | |
| 		{
 | |
| 			clear();
 | |
| 		}
 | |
| 
 | |
| 		const TOpenGLTexture* operator[](int index) const
 | |
| 		{
 | |
| 			if (static_cast<u32>(index) < MATERIAL_MAX_TEXTURES)
 | |
| 				return Texture[static_cast<u32>(index)];
 | |
| 
 | |
| 			return 0;
 | |
| 		}
 | |
| 
 | |
| 		const TOpenGLTexture* get(u32 index) const
 | |
| 		{
 | |
| 			if (index < MATERIAL_MAX_TEXTURES)
 | |
| 				return Texture[index];
 | |
| 
 | |
| 			return 0;
 | |
| 		}
 | |
| 
 | |
| 		bool set(u32 index, const ITexture* texture, ESetTextureActive esa=EST_ACTIVE_ALWAYS)
 | |
| 		{
 | |
| 			bool status = false;
 | |
| 
 | |
| 			E_DRIVER_TYPE type = DriverType;
 | |
| 
 | |
| 			if (index < MATERIAL_MAX_TEXTURES && index < TextureCount)
 | |
| 			{
 | |
| 				if ( esa == EST_ACTIVE_ALWAYS )
 | |
| 					CacheHandler.setActiveTexture(GL_TEXTURE0 + index);
 | |
| 
 | |
| 				const TOpenGLTexture* prevTexture = Texture[index];
 | |
| 
 | |
| 				if (texture != prevTexture)
 | |
| 				{
 | |
| 					if ( esa == EST_ACTIVE_ON_CHANGE )
 | |
| 						CacheHandler.setActiveTexture(GL_TEXTURE0 + index);
 | |
| 
 | |
| 					if (texture)
 | |
| 					{
 | |
| 						type = texture->getDriverType();
 | |
| 
 | |
| 						if (type == DriverType)
 | |
| 						{
 | |
| 							texture->grab();
 | |
| 
 | |
| 							const TOpenGLTexture* curTexture = static_cast<const TOpenGLTexture*>(texture);
 | |
| 							const GLenum curTextureType = curTexture->getOpenGLTextureType();
 | |
| 							const GLenum prevTextureType = (prevTexture) ? prevTexture->getOpenGLTextureType() : curTextureType;
 | |
| 
 | |
| 							if (curTextureType != prevTextureType)
 | |
| 							{
 | |
| 								glBindTexture(prevTextureType, 0);
 | |
| 
 | |
| #if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) )
 | |
| 								glDisable(prevTextureType);
 | |
| 								glEnable(curTextureType);
 | |
| #endif
 | |
| 							}
 | |
| #if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) )
 | |
| 							else if (!prevTexture)
 | |
| 								glEnable(curTextureType);
 | |
| #endif
 | |
| 
 | |
| 							glBindTexture(curTextureType, static_cast<const TOpenGLTexture*>(texture)->getOpenGLTextureName());
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							texture = 0;
 | |
| 
 | |
| 							os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
 | |
| 							os::Printer::log("Texture type", irr::core::stringc((int)type), ELL_ERROR);
 | |
| 							os::Printer::log("Driver (or cache handler) type", irr::core::stringc((int)DriverType), ELL_ERROR);
 | |
| 						}
 | |
| 					}
 | |
| 
 | |
| 					if (!texture && prevTexture)
 | |
| 					{
 | |
| 						const GLenum prevTextureType = prevTexture->getOpenGLTextureType();
 | |
| 
 | |
| 						glBindTexture(prevTextureType, 0);
 | |
| 
 | |
| #if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) )
 | |
| 						glDisable(prevTextureType);
 | |
| #endif
 | |
| 					}
 | |
| 
 | |
| 					Texture[index] = static_cast<const TOpenGLTexture*>(texture);
 | |
| 
 | |
| 					if (prevTexture)
 | |
| 						prevTexture->drop();
 | |
| 				}
 | |
| 
 | |
| 				status = true;
 | |
| 			}
 | |
| 
 | |
| 			return (status && type == DriverType);
 | |
| 		}
 | |
| 
 | |
| 		void remove(ITexture* texture)
 | |
| 		{
 | |
| 			if (!texture)
 | |
| 				return;
 | |
| 
 | |
| 			for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
 | |
| 			{
 | |
| 				if (Texture[i] == texture)
 | |
| 				{
 | |
| 					Texture[i] = 0;
 | |
| 
 | |
| 					texture->drop();
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		void clear()
 | |
| 		{
 | |
| 			for (u32 i = 0; i < MATERIAL_MAX_TEXTURES; ++i)
 | |
| 			{
 | |
| 				if (Texture[i])
 | |
| 				{
 | |
| 					const TOpenGLTexture* prevTexture = Texture[i];
 | |
| 
 | |
| 					Texture[i] = 0;
 | |
| 
 | |
| 					prevTexture->drop();
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 	private:
 | |
| 		COpenGLCoreCacheHandler& CacheHandler;
 | |
| 
 | |
| 		E_DRIVER_TYPE DriverType;
 | |
| 
 | |
| 		const TOpenGLTexture* Texture[MATERIAL_MAX_TEXTURES];
 | |
| 		u32 TextureCount;
 | |
| 	};
 | |
| 
 | |
| public:
 | |
| 	COpenGLCoreCacheHandler(TOpenGLDriver* driver) :
 | |
| 		Driver(driver),
 | |
| #if defined(_MSC_VER)
 | |
| #pragma warning(push)
 | |
| #pragma warning(disable: 4355)	// Warning: "'this' : used in base member initializer list. ". It's OK, we don't use the reference in STextureCache constructor.
 | |
| #endif
 | |
| 		TextureCache(STextureCache(*this, driver->getDriverType(), driver->getFeature().MaxTextureUnits)),
 | |
| #if defined(_MSC_VER)
 | |
| #pragma warning(pop)
 | |
| #endif
 | |
| 		FrameBufferCount(0), BlendEquation(0), BlendSourceRGB(0),
 | |
| 		BlendDestinationRGB(0), BlendSourceAlpha(0), BlendDestinationAlpha(0), Blend(0), BlendEquationInvalid(false), BlendFuncInvalid(false), BlendInvalid(false),
 | |
| 		ColorMask(0), ColorMaskInvalid(false), CullFaceMode(GL_BACK), CullFace(false), DepthFunc(GL_LESS), DepthMask(true), DepthTest(false), FrameBufferID(0),
 | |
| 		ProgramID(0), ActiveTexture(GL_TEXTURE0), ViewportX(0), ViewportY(0)
 | |
| 	{
 | |
| 		const COpenGLCoreFeature& feature = Driver->getFeature();
 | |
| 
 | |
| 		FrameBufferCount = core::max_(static_cast<GLuint>(1), static_cast<GLuint>(feature.MultipleRenderTarget));
 | |
| 
 | |
| 		BlendEquation = new GLenum[FrameBufferCount];
 | |
| 		BlendSourceRGB = new GLenum[FrameBufferCount];
 | |
| 		BlendDestinationRGB = new GLenum[FrameBufferCount];
 | |
| 		BlendSourceAlpha = new GLenum[FrameBufferCount];
 | |
| 		BlendDestinationAlpha = new GLenum[FrameBufferCount];
 | |
| 		Blend = new bool[FrameBufferCount];
 | |
| 		ColorMask = new u8[FrameBufferCount];
 | |
| 
 | |
| 		// Initial OpenGL values from specification.
 | |
| 
 | |
| 		if (feature.BlendOperation)
 | |
| 		{
 | |
| 			Driver->irrGlBlendEquation(GL_FUNC_ADD);
 | |
| 		}
 | |
| 
 | |
| 		for (u32 i = 0; i < FrameBufferCount; ++i)
 | |
| 		{
 | |
| 			BlendEquation[i] = GL_FUNC_ADD;
 | |
| 
 | |
| 			BlendSourceRGB[i] = GL_ONE;
 | |
| 			BlendDestinationRGB[i] = GL_ZERO;
 | |
| 			BlendSourceAlpha[i] = GL_ONE;
 | |
| 			BlendDestinationAlpha[i] = GL_ZERO;
 | |
| 
 | |
| 			Blend[i] = false;
 | |
| 			ColorMask[i] = ECP_ALL;
 | |
| 		}
 | |
| 
 | |
| 		glBlendFunc(GL_ONE, GL_ZERO);
 | |
| 		glDisable(GL_BLEND);
 | |
| 
 | |
| 		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 | |
| 
 | |
| 		glCullFace(CullFaceMode);
 | |
| 		glDisable(GL_CULL_FACE);
 | |
| 
 | |
| 		glDepthFunc(DepthFunc);
 | |
| 		glDepthMask(GL_TRUE);
 | |
| 		glDisable(GL_DEPTH_TEST);
 | |
| 
 | |
| 		Driver->irrGlActiveTexture(ActiveTexture);
 | |
| 
 | |
| #if ( defined(IRR_COMPILE_GL_COMMON) || defined(IRR_COMPILE_GLES_COMMON) )
 | |
| 		glDisable(GL_TEXTURE_2D);
 | |
| #endif
 | |
| 
 | |
| 		const core::dimension2d<u32> ScreenSize = Driver->getScreenSize();
 | |
| 		ViewportWidth = ScreenSize.Width;
 | |
| 		ViewportHeight = ScreenSize.Height;
 | |
| 		glViewport(ViewportX, ViewportY, ViewportWidth, ViewportHeight);
 | |
| 	}
 | |
| 
 | |
| 	virtual ~COpenGLCoreCacheHandler()
 | |
| 	{
 | |
| 		delete[] BlendEquation;
 | |
| 		delete[] BlendSourceRGB;
 | |
| 		delete[] BlendDestinationRGB;
 | |
| 		delete[] BlendSourceAlpha;
 | |
| 		delete[] BlendDestinationAlpha;
 | |
| 		delete[] Blend;
 | |
| 
 | |
| 		delete[] ColorMask;
 | |
| 	}
 | |
| 
 | |
| 	E_DRIVER_TYPE getDriverType() const
 | |
| 	{
 | |
| 		return Driver->getDriverType();
 | |
| 	}
 | |
| 
 | |
| 	STextureCache& getTextureCache()
 | |
| 	{
 | |
| 		return TextureCache;
 | |
| 	}
 | |
| 
 | |
| 	// Blending calls.
 | |
| 
 | |
| 	void setBlendEquation(GLenum mode)
 | |
| 	{
 | |
| 		if (BlendEquation[0] != mode || BlendEquationInvalid)
 | |
| 		{
 | |
| 			Driver->irrGlBlendEquation(mode);
 | |
| 
 | |
| 			for (GLuint i = 0; i < FrameBufferCount; ++i)
 | |
| 				BlendEquation[i] = mode;
 | |
| 
 | |
| 			BlendEquationInvalid = false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setBlendEquationIndexed(GLuint index, GLenum mode)
 | |
| 	{
 | |
| 		if (index < FrameBufferCount && BlendEquation[index] != mode)
 | |
| 		{
 | |
| 			Driver->irrGlBlendEquationIndexed(index, mode);
 | |
| 
 | |
| 			BlendEquation[index] = mode;
 | |
| 			BlendEquationInvalid = true;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setBlendFunc(GLenum source, GLenum destination)
 | |
| 	{
 | |
| 		if (BlendSourceRGB[0] != source || BlendDestinationRGB[0] != destination ||
 | |
| 			BlendSourceAlpha[0] != source || BlendDestinationAlpha[0] != destination ||
 | |
| 			BlendFuncInvalid)
 | |
| 		{
 | |
| 			glBlendFunc(source, destination);
 | |
| 
 | |
| 			for (GLuint i = 0; i < FrameBufferCount; ++i)
 | |
| 			{
 | |
| 				BlendSourceRGB[i] = source;
 | |
| 				BlendDestinationRGB[i] = destination;
 | |
| 				BlendSourceAlpha[i] = source;
 | |
| 				BlendDestinationAlpha[i] = destination;
 | |
| 			}
 | |
| 
 | |
| 			BlendFuncInvalid = false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setBlendFuncSeparate(GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha)
 | |
| 	{
 | |
| 		if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)
 | |
| 		{
 | |
| 			if (BlendSourceRGB[0] != sourceRGB || BlendDestinationRGB[0] != destinationRGB ||
 | |
| 				BlendSourceAlpha[0] != sourceAlpha || BlendDestinationAlpha[0] != destinationAlpha ||
 | |
| 				BlendFuncInvalid)
 | |
| 			{
 | |
| 				Driver->irrGlBlendFuncSeparate(sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);
 | |
| 
 | |
| 				for (GLuint i = 0; i < FrameBufferCount; ++i)
 | |
| 				{
 | |
| 					BlendSourceRGB[i] = sourceRGB;
 | |
| 					BlendDestinationRGB[i] = destinationRGB;
 | |
| 					BlendSourceAlpha[i] = sourceAlpha;
 | |
| 					BlendDestinationAlpha[i] = destinationAlpha;
 | |
| 				}
 | |
| 
 | |
| 				BlendFuncInvalid = false;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			setBlendFunc(sourceRGB, destinationRGB);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setBlendFuncIndexed(GLuint index, GLenum source, GLenum destination)
 | |
| 	{
 | |
| 		if (index < FrameBufferCount && (BlendSourceRGB[index] != source || BlendDestinationRGB[index] != destination ||
 | |
| 			BlendSourceAlpha[index] != source || BlendDestinationAlpha[index] != destination))
 | |
| 		{
 | |
| 			Driver->irrGlBlendFuncIndexed(index, source, destination);
 | |
| 
 | |
| 			BlendSourceRGB[index] = source;
 | |
| 			BlendDestinationRGB[index] = destination;
 | |
| 			BlendSourceAlpha[index] = source;
 | |
| 			BlendDestinationAlpha[index] = destination;
 | |
| 			BlendFuncInvalid = true;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setBlendFuncSeparateIndexed(GLuint index, GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha)
 | |
| 	{
 | |
| 		if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)
 | |
| 		{
 | |
| 			if (index < FrameBufferCount && (BlendSourceRGB[index] != sourceRGB || BlendDestinationRGB[index] != destinationRGB ||
 | |
| 				BlendSourceAlpha[index] != sourceAlpha || BlendDestinationAlpha[index] != destinationAlpha))
 | |
| 			{
 | |
| 				Driver->irrGlBlendFuncSeparateIndexed(index, sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);
 | |
| 
 | |
| 				BlendSourceRGB[index] = sourceRGB;
 | |
| 				BlendDestinationRGB[index] = destinationRGB;
 | |
| 				BlendSourceAlpha[index] = sourceAlpha;
 | |
| 				BlendDestinationAlpha[index] = destinationAlpha;
 | |
| 				BlendFuncInvalid = true;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			setBlendFuncIndexed(index, sourceRGB, destinationRGB);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setBlend(bool enable)
 | |
| 	{
 | |
| 		if (Blend[0] != enable || BlendInvalid)
 | |
| 		{
 | |
| 			if (enable)
 | |
| 				glEnable(GL_BLEND);
 | |
| 			else
 | |
| 				glDisable(GL_BLEND);
 | |
| 
 | |
| 			for (GLuint i = 0; i < FrameBufferCount; ++i)
 | |
| 				Blend[i] = enable;
 | |
| 
 | |
| 			BlendInvalid = false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setBlendIndexed(GLuint index, bool enable)
 | |
| 	{
 | |
| 		if (index < FrameBufferCount && Blend[index] != enable)
 | |
| 		{
 | |
| 			if (enable)
 | |
| 				Driver->irrGlEnableIndexed(GL_BLEND, index);
 | |
| 			else
 | |
| 				Driver->irrGlDisableIndexed(GL_BLEND, index);
 | |
| 
 | |
| 			Blend[index] = enable;
 | |
| 			BlendInvalid = true;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Color Mask.
 | |
| 
 | |
| 	void getColorMask(u8& mask)
 | |
| 	{
 | |
| 		mask = ColorMask[0];
 | |
| 	}
 | |
| 
 | |
| 	void setColorMask(u8 mask)
 | |
| 	{
 | |
| 		if (ColorMask[0] != mask || ColorMaskInvalid)
 | |
| 		{
 | |
| 			glColorMask((mask & ECP_RED) ? GL_TRUE : GL_FALSE, (mask & ECP_GREEN) ? GL_TRUE : GL_FALSE, (mask & ECP_BLUE) ? GL_TRUE : GL_FALSE, (mask & ECP_ALPHA) ? GL_TRUE : GL_FALSE);
 | |
| 
 | |
| 			for (GLuint i = 0; i < FrameBufferCount; ++i)
 | |
| 				ColorMask[i] = mask;
 | |
| 
 | |
| 			ColorMaskInvalid = false;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setColorMaskIndexed(GLuint index, u8 mask)
 | |
| 	{
 | |
| 		if (index < FrameBufferCount && ColorMask[index] != mask)
 | |
| 		{
 | |
| 			Driver->irrGlColorMaskIndexed(index, (mask & ECP_RED) ? GL_TRUE : GL_FALSE, (mask & ECP_GREEN) ? GL_TRUE : GL_FALSE, (mask & ECP_BLUE) ? GL_TRUE : GL_FALSE, (mask & ECP_ALPHA) ? GL_TRUE : GL_FALSE);
 | |
| 
 | |
| 			ColorMask[index] = mask;
 | |
| 			ColorMaskInvalid = true;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Cull face calls.
 | |
| 
 | |
| 	void setCullFaceFunc(GLenum mode)
 | |
| 	{
 | |
| 		if (CullFaceMode != mode)
 | |
| 		{
 | |
| 			glCullFace(mode);
 | |
| 			CullFaceMode = mode;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void setCullFace(bool enable)
 | |
| 	{
 | |
| 		if (CullFace != enable)
 | |
| 		{
 | |
| 			if (enable)
 | |
| 				glEnable(GL_CULL_FACE);
 | |
| 			else
 | |
| 				glDisable(GL_CULL_FACE);
 | |
| 
 | |
| 			CullFace = enable;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Depth calls.
 | |
| 
 | |
| 	void setDepthFunc(GLenum mode)
 | |
| 	{
 | |
| 		if (DepthFunc != mode)
 | |
| 		{
 | |
| 			glDepthFunc(mode);
 | |
| 			DepthFunc = mode;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	void getDepthMask(bool& depth)
 | |
| 	{
 | |
| 		depth = DepthMask;
 | |
| 	}
 | |
| 
 | |
| 	void setDepthMask(bool enable)
 | |
| 	{
 | |
| 		if (DepthMask != enable)
 | |
| 		{
 | |
| 			if (enable)
 | |
| 				glDepthMask(GL_TRUE);
 | |
| 			else
 | |
| 				glDepthMask(GL_FALSE);
 | |
| 
 | |
| 			DepthMask = enable;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
|     void getDepthTest(bool& enable)
 | |
|     {
 | |
|         enable = DepthTest;
 | |
|     }
 | |
| 
 | |
| 	void setDepthTest(bool enable)
 | |
| 	{
 | |
| 		if (DepthTest != enable)
 | |
| 		{
 | |
| 			if (enable)
 | |
| 				glEnable(GL_DEPTH_TEST);
 | |
| 			else
 | |
| 				glDisable(GL_DEPTH_TEST);
 | |
| 
 | |
| 			DepthTest = enable;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// FBO calls.
 | |
| 
 | |
| 	void getFBO(GLuint& frameBufferID) const
 | |
| 	{
 | |
| 		frameBufferID = FrameBufferID;
 | |
| 	}
 | |
| 
 | |
| 	void setFBO(GLuint frameBufferID)
 | |
| 	{
 | |
| 		if (FrameBufferID != frameBufferID)
 | |
| 		{
 | |
| 			Driver->irrGlBindFramebuffer(GL_FRAMEBUFFER, frameBufferID);
 | |
| 			FrameBufferID = frameBufferID;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Shaders calls.
 | |
| 
 | |
| 	void getProgram(GLuint& programID) const
 | |
| 	{
 | |
| 		programID = ProgramID;
 | |
| 	}
 | |
| 
 | |
| 	void setProgram(GLuint programID)
 | |
| 	{
 | |
| 		if (ProgramID != programID)
 | |
| 		{
 | |
| 			Driver->irrGlUseProgram(programID);
 | |
| 			ProgramID = programID;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Texture calls.
 | |
| 
 | |
| 	void getActiveTexture(GLenum& texture) const
 | |
| 	{
 | |
| 		texture = ActiveTexture;
 | |
| 	}
 | |
| 
 | |
| 	void setActiveTexture(GLenum texture)
 | |
| 	{
 | |
| 		if (ActiveTexture != texture)
 | |
| 		{
 | |
| 			Driver->irrGlActiveTexture(texture);
 | |
| 			ActiveTexture = texture;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Viewport calls.
 | |
| 
 | |
| 	void getViewport(GLint& viewportX, GLint& viewportY, GLsizei& viewportWidth, GLsizei& viewportHeight) const
 | |
| 	{
 | |
| 		viewportX = ViewportX;
 | |
| 		viewportY = ViewportY;
 | |
| 		viewportWidth = ViewportWidth;
 | |
| 		viewportHeight = ViewportHeight;
 | |
| 	}
 | |
| 
 | |
| 	void setViewport(GLint viewportX, GLint viewportY, GLsizei viewportWidth, GLsizei viewportHeight)
 | |
| 	{
 | |
| 		if (ViewportX != viewportX || ViewportY != viewportY || ViewportWidth != viewportWidth || ViewportHeight != viewportHeight)
 | |
| 		{
 | |
| 			glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
 | |
| 			ViewportX = viewportX;
 | |
| 			ViewportY = viewportY;
 | |
| 			ViewportWidth = viewportWidth;
 | |
| 			ViewportHeight = viewportHeight;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	//! Compare material to current cache and update it when there are differences
 | |
| 	// Some material renderers do change the cache beyond the original material settings
 | |
| 	// This corrects the material to represent the current cache state again.
 | |
| 	void correctCacheMaterial(irr::video::SMaterial& material)
 | |
| 	{
 | |
| 		// Fix textures which got removed
 | |
| 		for ( u32 i=0; i < MATERIAL_MAX_TEXTURES; ++i )
 | |
| 		{
 | |
| 			if ( material.TextureLayer[i].Texture && !TextureCache[i] )
 | |
| 			{
 | |
| 				material.TextureLayer[i].Texture = 0;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| protected:
 | |
| 	TOpenGLDriver* Driver;
 | |
| 
 | |
| 	STextureCache TextureCache;
 | |
| 
 | |
| 	GLuint FrameBufferCount;
 | |
| 
 | |
| 	GLenum* BlendEquation;
 | |
| 	GLenum* BlendSourceRGB;
 | |
| 	GLenum* BlendDestinationRGB;
 | |
| 	GLenum* BlendSourceAlpha;
 | |
| 	GLenum* BlendDestinationAlpha;
 | |
| 	bool* Blend;
 | |
| 	bool BlendEquationInvalid;
 | |
| 	bool BlendFuncInvalid;
 | |
| 	bool BlendInvalid;
 | |
| 
 | |
| 
 | |
| 	u8* ColorMask;
 | |
| 	bool ColorMaskInvalid;
 | |
| 
 | |
| 	GLenum CullFaceMode;
 | |
| 	bool CullFace;
 | |
| 
 | |
| 	GLenum DepthFunc;
 | |
| 	bool DepthMask;
 | |
| 	bool DepthTest;
 | |
| 
 | |
| 	GLuint FrameBufferID;
 | |
| 
 | |
| 	GLuint ProgramID;
 | |
| 
 | |
| 	GLenum ActiveTexture;
 | |
| 
 | |
| 	GLint ViewportX;
 | |
| 	GLint ViewportY;
 | |
| 	GLsizei ViewportWidth;
 | |
| 	GLsizei ViewportHeight;
 | |
| };
 | |
| 
 | |
| }
 | |
| }
 | |
| 
 | |
| #endif
 |