void COpenGLSLMaterialRenderer::OnSetMaterial(const video::SMaterial& material,
				const video::SMaterial& lastMaterial,
				bool resetAllRenderstates,
				video::IMaterialRendererServices* services)
{
	if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_ENABLE)
		Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE_TO_DISABLE);
	else
		Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE);

	COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();

	if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
	{
		if (Program2)
			Driver->irrGlUseProgram(Program2);
		else if (Program)
			Driver->extGlUseProgramObject(Program);
	}

	Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);

	if (Alpha)
	{
		cacheHandler->setBlend(true);
		cacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}
	else if (FixedBlending)
	{
		cacheHandler->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
		cacheHandler->setBlend(true);
	}
	else if (Blending)
	{
		E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
		E_MODULATE_FUNC modulate;
		u32 alphaSource;
		unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);

		if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
        {
			cacheHandler->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
                Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
        }
        else
        {
			cacheHandler->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
        }

		cacheHandler->setBlend(true);
	}
	else if (AlphaTest)
	{
		cacheHandler->setAlphaTest(true);
		cacheHandler->setAlphaFunc(GL_GREATER, 0.5f);
	}

	if (CallBack)
		CallBack->OnSetMaterial(material);
}
void COGLES2MaterialRenderer::OnSetMaterial(const video::SMaterial& material,
				const video::SMaterial& lastMaterial,
				bool resetAllRenderstates,
				video::IMaterialRendererServices* services)
{
	COGLES2CallBridge* bridgeCalls = Driver->getBridgeCalls();

	bridgeCalls->setProgram(Program);

	Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);

	if (Alpha)
	{
		bridgeCalls->setBlend(true);
		bridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}
	else if (FixedBlending)
	{
		bridgeCalls->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
		bridgeCalls->setBlend(true);
	}
	else if (Blending)
	{
		E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
		E_MODULATE_FUNC modulate;
		u32 alphaSource;
		unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);

		bridgeCalls->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
			Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));

		bridgeCalls->setBlend(true);
	}
	else
		bridgeCalls->setBlend(false);

	if (CallBack)
		CallBack->OnSetMaterial(material);
}
void COpenGLShaderMaterialRenderer::OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial,
	bool resetAllRenderstates, video::IMaterialRendererServices* services)
{
	if (Driver->getFixedPipelineState() == COpenGLDriver::EOFPS_ENABLE)
		Driver->setFixedPipelineState(COpenGLDriver::EOFPS_ENABLE_TO_DISABLE);
	else
		Driver->setFixedPipelineState(COpenGLDriver::EOFPS_DISABLE);

	COpenGLCacheHandler* cacheHandler = Driver->getCacheHandler();

	if (material.MaterialType != lastMaterial.MaterialType || resetAllRenderstates)
	{
		if (VertexShader)
		{
			// set new vertex shader
#ifdef GL_ARB_vertex_program
			Driver->extGlBindProgram(GL_VERTEX_PROGRAM_ARB, VertexShader);
			glEnable(GL_VERTEX_PROGRAM_ARB);
#elif defined(GL_NV_vertex_program)
			Driver->extGlBindProgram(GL_VERTEX_PROGRAM_NV, VertexShader);
			glEnable(GL_VERTEX_PROGRAM_NV);
#endif
		}

		// set new pixel shader
		if (PixelShader[0])
		{
			GLuint nextShader=PixelShader[0];
			if (material.FogEnable)
			{
				GLint curFogMode;
				glGetIntegerv(GL_FOG_MODE, &curFogMode);
//				if (Driver->LinearFog && PixelShader[1])
				if (curFogMode==GL_LINEAR && PixelShader[1])
					nextShader=PixelShader[1];
//				else if (!Driver->LinearFog && PixelShader[2])
				else if (curFogMode==GL_EXP && PixelShader[2])
					nextShader=PixelShader[2];
				else if (curFogMode==GL_EXP2 && PixelShader[3])
					nextShader=PixelShader[3];
			}
#ifdef GL_ARB_fragment_program
			Driver->extGlBindProgram(GL_FRAGMENT_PROGRAM_ARB, nextShader);
			glEnable(GL_FRAGMENT_PROGRAM_ARB);
#elif defined(GL_NV_fragment_program)
			Driver->extGlBindProgram(GL_FRAGMENT_PROGRAM_NV, nextShader);
			glEnable(GL_FRAGMENT_PROGRAM_NV);
#endif
		}
	}

	Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);

	if (Alpha)
	{
		cacheHandler->setBlend(true);
		cacheHandler->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}
	else if (FixedBlending)
	{
		cacheHandler->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
		cacheHandler->setBlend(true);
	}
	else if (Blending)
	{
		E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
		E_MODULATE_FUNC modulate;
		u32 alphaSource;
		unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);

		if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
        {
			cacheHandler->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
                Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
        }
        else
        {
			cacheHandler->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
        }

		cacheHandler->setBlend(true);
	}
	else if (AlphaTest)
	{
		cacheHandler->setAlphaTest(true);
		cacheHandler->setAlphaFunc(GL_GREATER, 0.5f);
	}

	if (CallBack)
		CallBack->OnSetMaterial(material);
}