- Added separate blending support to both OpenGL ES1.x and 2.0 drivers.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@4861 dfc29bdd-3216-0410-991c-e03cc46cb475
master
nadro 2014-05-10 21:47:14 +00:00
parent 1e8048f561
commit 03fceb34d3
9 changed files with 387 additions and 70 deletions

View File

@ -44,9 +44,9 @@ COGLES2Driver::COGLES2Driver(const SIrrlichtCreationParameters& params,
, CIrrDeviceIPhone* device
#endif
) : CNullDriver(io, params.WindowSize), COGLES2ExtensionHandler(),
BridgeCalls(0), CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0, 0), ColorFormat(ECF_R8G8B8)
RenderTargetTexture(0), CurrentRendertargetSize(0, 0), ColorFormat(ECF_R8G8B8), BridgeCalls(0)
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_WINDOWS_API_) || defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) || defined(_IRR_COMPILE_WITH_FB_DEVICE_)
, ContextManager(contextManager)
#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
@ -1691,7 +1691,7 @@ bool COGLES2Driver::endScene()
{
// Reset Texture Stages
BridgeCalls->setBlend(false);
BridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
BridgeCalls->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
ResetRenderStates = true;
}
@ -1812,10 +1812,8 @@ bool COGLES2Driver::endScene()
(material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
}
// Blend operation
if (resetAllRenderStates|| lastmaterial.BlendOperation != material.BlendOperation)
{
if (material.BlendOperation==EBO_NONE)
// Blend Equation
if (material.BlendOperation == EBO_NONE)
BridgeCalls->setBlend(false);
else
{
@ -1824,18 +1822,33 @@ bool COGLES2Driver::endScene()
switch (material.BlendOperation)
{
case EBO_ADD:
glBlendEquation(GL_FUNC_ADD);
BridgeCalls->setBlendEquation(GL_FUNC_ADD);
break;
case EBO_SUBTRACT:
glBlendEquation(GL_FUNC_SUBTRACT);
BridgeCalls->setBlendEquation(GL_FUNC_SUBTRACT);
break;
case EBO_REVSUBTRACT:
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
BridgeCalls->setBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
break;
default:
break;
}
}
// Blend Factor
if (material.BlendFactor != 0.f)
{
E_BLEND_FACTOR srcRGBFact = EBF_ZERO;
E_BLEND_FACTOR dstRGBFact = EBF_ZERO;
E_BLEND_FACTOR srcAlphaFact = EBF_ZERO;
E_BLEND_FACTOR dstAlphaFact = EBF_ZERO;
E_MODULATE_FUNC modulo = EMFN_MODULATE_1X;
u32 alphaSource = 0;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulo, alphaSource, material.BlendFactor);
BridgeCalls->setBlendFuncSeparate(getGLBlend(srcRGBFact), getGLBlend(dstRGBFact),
getGLBlend(srcAlphaFact), getGLBlend(dstAlphaFact));
}
// Anti aliasing
@ -2727,7 +2740,8 @@ bool COGLES2Driver::endScene()
}
COGLES2CallBridge::COGLES2CallBridge(COGLES2Driver* driver) : Driver(driver),
BlendSource(GL_ONE), BlendDestination(GL_ZERO), Blend(false),
BlendEquation(GL_FUNC_ADD), BlendSourceRGB(GL_ONE), BlendDestinationRGB(GL_ZERO),
BlendSourceAlpha(GL_ONE), BlendDestinationAlpha(GL_ZERO), Blend(false),
CullFaceMode(GL_BACK), CullFace(false),
DepthFunc(GL_LESS), DepthMask(true), DepthTest(false),
Program(0), ActiveTexture(GL_TEXTURE0), Viewport(core::rect<s32>(0, 0, 0, 0))
@ -2751,14 +2765,48 @@ bool COGLES2Driver::endScene()
glDisable(GL_DEPTH_TEST);
}
void COGLES2CallBridge::setBlendEquation(GLenum mode)
{
if (BlendEquation != mode)
{
glBlendEquation(mode);
BlendEquation = mode;
}
}
void COGLES2CallBridge::setBlendFunc(GLenum source, GLenum destination)
{
if (BlendSource != source || BlendDestination != destination)
if (BlendSourceRGB != source || BlendDestinationRGB != destination ||
BlendSourceAlpha != source || BlendDestinationAlpha != destination)
{
glBlendFunc(source, destination);
BlendSource = source;
BlendDestination = destination;
BlendSourceRGB = source;
BlendDestinationRGB = destination;
BlendSourceAlpha = source;
BlendDestinationAlpha = destination;
}
}
void COGLES2CallBridge::setBlendFuncSeparate(GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha)
{
if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)
{
if (BlendSourceRGB != sourceRGB || BlendDestinationRGB != destinationRGB ||
BlendSourceAlpha != sourceAlpha || BlendDestinationAlpha != destinationAlpha)
{
glBlendFuncSeparate(sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);
BlendSourceRGB = sourceRGB;
BlendDestinationRGB = destinationRGB;
BlendSourceAlpha = sourceAlpha;
BlendDestinationAlpha = destinationAlpha;
}
}
else
{
setBlendFunc(sourceRGB, destinationRGB);
}
}

View File

@ -364,9 +364,6 @@ namespace video
COGLES2CallBridge* getBridgeCalls() const;
private:
// Bridge calls.
COGLES2CallBridge* BridgeCalls;
void uploadClipPlane(u32 index);
//! inits the opengl-es driver
@ -450,6 +447,8 @@ namespace video
COGLES2Renderer2D* MaterialRenderer2D;
COGLES2CallBridge* BridgeCalls;
#if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
CIrrDeviceIPhone* Device;
GLuint ViewFramebuffer;
@ -470,8 +469,12 @@ namespace video
// Blending calls.
void setBlendEquation(GLenum mode);
void setBlendFunc(GLenum source, GLenum destination);
void setBlendFuncSeparate(GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha);
void setBlend(bool enable);
// Cull face calls.
@ -507,8 +510,11 @@ namespace video
private:
COGLES2Driver* Driver;
GLenum BlendSource;
GLenum BlendDestination;
GLenum BlendEquation;
GLenum BlendSourceRGB;
GLenum BlendDestinationRGB;
GLenum BlendSourceAlpha;
GLenum BlendDestinationAlpha;
bool Blend;
GLenum CullFaceMode;

View File

@ -217,6 +217,8 @@ namespace video
case EVDF_COLOR_MASK:
case EVDF_ALPHA_TO_COVERAGE:
case EVDF_POLYGON_OFFSET:
case EVDF_BLEND_OPERATIONS:
case EVDF_BLEND_SEPARATE:
case EVDF_TEXTURE_MATRIX:
case EVDF_TEXTURE_CUBE_MAP:
return true;
@ -229,8 +231,6 @@ namespace video
case EVDF_MRT_BLEND_FUNC:
case EVDF_OCCLUSION_QUERY:
return false;
case EVDF_BLEND_OPERATIONS:
return false;
case EVDF_TEXTURE_COMPRESSED_DXT:
return false; // NV Tegra need improvements here
case EVDF_TEXTURE_COMPRESSED_PVRTC:

View File

@ -160,32 +160,36 @@ void COGLES2MaterialRenderer::OnSetMaterial(const video::SMaterial& material,
bool resetAllRenderstates,
video::IMaterialRendererServices* services)
{
Driver->getBridgeCalls()->setProgram(Program);
COGLES2CallBridge* bridgeCalls = Driver->getBridgeCalls();
bridgeCalls->setProgram(Program);
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (Alpha)
{
Driver->getBridgeCalls()->setBlend(true);
Driver->getBridgeCalls()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
bridgeCalls->setBlend(true);
bridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (FixedBlending)
{
Driver->getBridgeCalls()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
Driver->getBridgeCalls()->setBlend(true);
bridgeCalls->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
bridgeCalls->setBlend(true);
}
else if (Blending)
{
E_BLEND_FACTOR srcFact,dstFact;
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFunc(srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam);
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcFact), Driver->getGLBlend(dstFact));
Driver->getBridgeCalls()->setBlend(true);
bridgeCalls->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
bridgeCalls->setBlend(true);
}
else
Driver->getBridgeCalls()->setBlend(false);
bridgeCalls->setBlend(false);
if (CallBack)
CallBack->OnSetMaterial(material);

View File

@ -33,7 +33,7 @@ COGLES1Driver::COGLES1Driver(const SIrrlichtCreationParameters& params,
) : CNullDriver(io, params.WindowSize), COGLES1ExtensionHandler(),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8)
RenderTargetTexture(0), CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8), BridgeCalls(0)
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_WINDOWS_API_) || defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
, ContextManager(contextManager)
#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
@ -99,6 +99,8 @@ COGLES1Driver::~COGLES1Driver()
deleteMaterialRenders();
deleteAllTextures();
delete BridgeCalls;
#if defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_WINDOWS_API_) || defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_)
if (ContextManager)
{
@ -143,6 +145,10 @@ bool COGLES1Driver::genericDriverInit(const core::dimension2d<u32>& screenSize,
CurrentTexture[i]=0;
// load extensions
initExtensions(this, stencilBuffer);
if (!BridgeCalls)
BridgeCalls = new COGLES1CallBridge(this);
StencilBuffer=stencilBuffer;
DriverAttributes->setAttribute("MaxTextures", MaxTextureUnits);
@ -1639,9 +1645,9 @@ void COGLES1Driver::setRenderStates3DMode()
if (CurrentRenderMode != ERM_3D)
{
// Reset Texture Stages
glDisable(GL_BLEND);
BridgeCalls->setBlend(false);
glDisable(GL_ALPHA_TEST);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
BridgeCalls->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
// switch back the matrices
glMatrixMode(GL_MODELVIEW);
@ -2013,6 +2019,61 @@ void COGLES1Driver::setBasicRenderStates(const SMaterial& material, const SMater
(material.ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
}
// Blend Equation
if (material.BlendOperation == EBO_NONE)
BridgeCalls->setBlend(false);
else
{
BridgeCalls->setBlend(true);
if (queryFeature(EVDF_BLEND_OPERATIONS))
{
switch (material.BlendOperation)
{
case EBO_ADD:
#if defined(GL_OES_blend_subtract)
BridgeCalls->setBlendEquation(GL_FUNC_ADD_OES);
#endif
break;
case EBO_SUBTRACT:
#if defined(GL_OES_blend_subtract)
BridgeCalls->setBlendEquation(GL_FUNC_SUBTRACT_OES);
#endif
break;
case EBO_REVSUBTRACT:
#if defined(GL_OES_blend_subtract)
BridgeCalls->setBlendEquation(GL_FUNC_REVERSE_SUBTRACT_OES);
#endif
break;
default:
break;
}
}
}
// Blend Factor
if (material.BlendFactor != 0.f)
{
E_BLEND_FACTOR srcRGBFact = EBF_ZERO;
E_BLEND_FACTOR dstRGBFact = EBF_ZERO;
E_BLEND_FACTOR srcAlphaFact = EBF_ZERO;
E_BLEND_FACTOR dstAlphaFact = EBF_ZERO;
E_MODULATE_FUNC modulo = EMFN_MODULATE_1X;
u32 alphaSource = 0;
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulo, alphaSource, material.BlendFactor);
if (queryFeature(EVDF_BLEND_SEPARATE))
{
BridgeCalls->setBlendFuncSeparate(getGLBlend(srcRGBFact), getGLBlend(dstRGBFact),
getGLBlend(srcAlphaFact), getGLBlend(dstAlphaFact));
}
else
{
BridgeCalls->setBlendFunc(getGLBlend(srcRGBFact), getGLBlend(dstRGBFact));
}
}
// thickness
if (resetAllRenderStates || lastmaterial.Thickness != material.Thickness)
{
@ -2109,7 +2170,6 @@ void COGLES1Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
setBasicRenderStates(InitMaterial2D, LastMaterial, true);
LastMaterial = InitMaterial2D;
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
if (OverrideMaterial2DEnabled)
{
@ -2120,13 +2180,14 @@ void COGLES1Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaCh
if (alphaChannel || alpha)
{
glEnable(GL_BLEND);
BridgeCalls->setBlend(true);
BridgeCalls->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.f);
}
else
{
glDisable(GL_BLEND);
BridgeCalls->setBlend(false);
glDisable(GL_ALPHA_TEST);
}
@ -3021,6 +3082,113 @@ core::dimension2du COGLES1Driver::getMaxTextureSize() const
return core::dimension2du(MaxTextureSize, MaxTextureSize);
}
GLenum COGLES1Driver::getGLBlend(E_BLEND_FACTOR factor) const
{
GLenum r = 0;
switch (factor)
{
case EBF_ZERO: r = GL_ZERO; break;
case EBF_ONE: r = GL_ONE; break;
case EBF_DST_COLOR: r = GL_DST_COLOR; break;
case EBF_ONE_MINUS_DST_COLOR: r = GL_ONE_MINUS_DST_COLOR; break;
case EBF_SRC_COLOR: r = GL_SRC_COLOR; break;
case EBF_ONE_MINUS_SRC_COLOR: r = GL_ONE_MINUS_SRC_COLOR; break;
case EBF_SRC_ALPHA: r = GL_SRC_ALPHA; break;
case EBF_ONE_MINUS_SRC_ALPHA: r = GL_ONE_MINUS_SRC_ALPHA; break;
case EBF_DST_ALPHA: r = GL_DST_ALPHA; break;
case EBF_ONE_MINUS_DST_ALPHA: r = GL_ONE_MINUS_DST_ALPHA; break;
case EBF_SRC_ALPHA_SATURATE: r = GL_SRC_ALPHA_SATURATE; break;
}
return r;
}
COGLES1CallBridge* COGLES1Driver::getBridgeCalls() const
{
return BridgeCalls;
}
COGLES1CallBridge::COGLES1CallBridge(COGLES1Driver* driver) : Driver(driver),
#if defined(GL_OES_blend_subtract)
BlendEquation(GL_FUNC_ADD_OES),
#endif
BlendSourceRGB(GL_ONE), BlendDestinationRGB(GL_ZERO),
BlendSourceAlpha(GL_ONE), BlendDestinationAlpha(GL_ZERO),
Blend(false)
{
// Initial OpenGL ES1.x values from specification.
if (Driver->queryFeature(EVDF_BLEND_OPERATIONS))
{
#if defined(GL_OES_blend_subtract)
Driver->extGlBlendEquation(GL_FUNC_ADD_OES);
#endif
}
glBlendFunc(GL_ONE, GL_ZERO);
glDisable(GL_BLEND);
}
void COGLES1CallBridge::setBlendEquation(GLenum mode)
{
if (BlendEquation != mode)
{
Driver->extGlBlendEquation(mode);
BlendEquation = mode;
}
}
void COGLES1CallBridge::setBlendFunc(GLenum source, GLenum destination)
{
if (BlendSourceRGB != source || BlendDestinationRGB != destination ||
BlendSourceAlpha != source || BlendDestinationAlpha != destination)
{
glBlendFunc(source, destination);
BlendSourceRGB = source;
BlendDestinationRGB = destination;
BlendSourceAlpha = source;
BlendDestinationAlpha = destination;
}
}
void COGLES1CallBridge::setBlendFuncSeparate(GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha)
{
if (sourceRGB != sourceAlpha || destinationRGB != destinationAlpha)
{
if (BlendSourceRGB != sourceRGB || BlendDestinationRGB != destinationRGB ||
BlendSourceAlpha != sourceAlpha || BlendDestinationAlpha != destinationAlpha)
{
Driver->extGlBlendFuncSeparate(sourceRGB, destinationRGB, sourceAlpha, destinationAlpha);
BlendSourceRGB = sourceRGB;
BlendDestinationRGB = destinationRGB;
BlendSourceAlpha = sourceAlpha;
BlendDestinationAlpha = destinationAlpha;
}
}
else
{
setBlendFunc(sourceRGB, destinationRGB);
}
}
void COGLES1CallBridge::setBlend(bool enable)
{
if (Blend != enable)
{
if (enable)
glEnable(GL_BLEND);
else
glDisable(GL_BLEND);
Blend = enable;
}
}
} // end namespace
} // end namespace

View File

@ -26,6 +26,7 @@ namespace irr
{
namespace video
{
class COGLES1CallBridge;
class COGLES1Texture;
class COGLES1Driver : public CNullDriver, public IMaterialRendererServices, public COGLES1ExtensionHandler
@ -282,8 +283,13 @@ namespace video
ITexture* createDepthTexture(ITexture* texture, bool shared=true);
void removeDepthTexture(ITexture* texture);
private:
//! Convert E_BLEND_FACTOR to OpenGL equivalent
GLenum getGLBlend(E_BLEND_FACTOR factor) const;
//! Get bridge calls.
COGLES1CallBridge* getBridgeCalls() const;
private:
void uploadClipPlane(u32 index);
//! inits the opengl-es driver
@ -366,6 +372,8 @@ namespace video
};
core::array<RequestedLight> RequestedLights;
COGLES1CallBridge* BridgeCalls;
#if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_)
CIrrDeviceIPhone* Device;
GLuint ViewFramebuffer;
@ -376,6 +384,35 @@ namespace video
#endif
};
//! This bridge between Irlicht pseudo OpenGL ES1.x calls
//! and true OpenGL ES1.x calls.
class COGLES1CallBridge
{
public:
COGLES1CallBridge(COGLES1Driver* driver);
// Blending calls.
void setBlendEquation(GLenum mode);
void setBlendFunc(GLenum source, GLenum destination);
void setBlendFuncSeparate(GLenum sourceRGB, GLenum destinationRGB, GLenum sourceAlpha, GLenum destinationAlpha);
void setBlend(bool enable);
private:
COGLES1Driver* Driver;
GLenum BlendEquation;
GLenum BlendSourceRGB;
GLenum BlendDestinationRGB;
GLenum BlendSourceAlpha;
GLenum BlendDestinationAlpha;
bool Blend;
};
} // end namespace video
} // end namespace irr

View File

@ -128,6 +128,7 @@ COGLES1ExtensionHandler::COGLES1ExtensionHandler() :
#if defined(_IRR_OGLES1_USE_EXTPOINTER_)
pGlDrawTexiOES(0), pGlDrawTexfOES(0),
pGlDrawTexivOES(0), pGlDrawTexfvOES(0),
pGlBlendEquationOES(0), pGlBlendFuncSeparateOES(0),
pGlBindRenderbufferOES(0), pGlDeleteRenderbuffersOES(0),
pGlGenRenderbuffersOES(0), pGlRenderbufferStorageOES(0),
pGlBindFramebufferOES(0), pGlDeleteFramebuffersOES(0),
@ -248,6 +249,14 @@ void COGLES1ExtensionHandler::initExtensions(COGLES1Driver* driver, bool withSte
pGlDrawTexivOES = (PFNGLDRAWTEXIVOES) eglGetProcAddress("glDrawTexivOES");
pGlDrawTexfvOES = (PFNGLDRAWTEXFVOES) eglGetProcAddress("glDrawTexfvOES");
}
if (FeatureAvailable[IRR_OES_blend_subtract])
{
pGlBlendEquationOES = (PFNGLBLENDEQUATIONOESPROC) eglGetProcAddress("glBlendEquationOES");
}
if (FeatureAvailable[IRR_OES_blend_func_separate])
{
pGlBlendFuncSeparateOES = (PFNGLBLENDFUNCSEPARATEOESPROC) eglGetProcAddress("glBlendFuncSeparateOES");
}
if (FeatureAvailable[IRR_OES_framebuffer_object])
{
pGlBindRenderbufferOES = (PFNGLBINDRENDERBUFFEROES) eglGetProcAddress("glBindRenderbufferOES");

View File

@ -200,6 +200,12 @@ namespace video
return Version>100; // Supported in version 1.1
case EVDF_STENCIL_BUFFER:
return StencilBuffer;
case EVDF_BLEND_OPERATIONS:
return FeatureAvailable[IRR_OES_blend_subtract];
case EVDF_BLEND_SEPARATE:
return FeatureAvailable[IRR_OES_blend_func_separate];
case EVDF_FRAMEBUFFER_OBJECT:
return FeatureAvailable[IRR_OES_framebuffer_object];
case EVDF_TEXTURE_NSQUARE:
return true; // non-square is always supported
case EVDF_TEXTURE_NPOT:
@ -224,6 +230,30 @@ namespace video
void initExtensions(COGLES1Driver* driver, bool withStencil);
public:
void extGlBlendEquation(GLenum mode)
{
#ifdef _IRR_OGLES1_USE_EXTPOINTER_
if (pGlBlendEquationOES)
pGlBlendEquationOES(mode);
#elif defined(GL_OES_blend_subtract)
glBlendEquationOES(mode);
#else
os::Printer::log("glBlendEquation not supported", ELL_ERROR);
#endif
}
void extGlBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
#ifdef _IRR_OGLES1_USE_EXTPOINTER_
if (pGlBlendFuncSeparateOES)
pGlBlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);
#elif defined(GL_OES_blend_func_separate)
glBlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);
#else
os::Printer::log("glBlendFuncSeparate not supported", ELL_ERROR);
#endif
}
void extGlBindFramebuffer(GLenum target, GLuint framebuffer)
{
#ifdef _IRR_OGLES1_USE_EXTPOINTER_
@ -439,6 +469,8 @@ namespace video
typedef void (GL_APIENTRYP PFNGLDRAWTEXIVOES) (const GLint* coords);
typedef void (GL_APIENTRYP PFNGLDRAWTEXFOES) (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height);
typedef void (GL_APIENTRYP PFNGLDRAWTEXFVOES) (const GLfloat* coords);
typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONOESPROC) (GLenum mode);
typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEOESPROC) (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFEROES) (GLuint renderbuffer);
typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFEROES) (GLenum target, GLuint renderbuffer);
typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSOES) (GLsizei n, const GLuint* renderbuffers);
@ -459,6 +491,8 @@ namespace video
PFNGLDRAWTEXFOES pGlDrawTexfOES;
PFNGLDRAWTEXIVOES pGlDrawTexivOES;
PFNGLDRAWTEXFVOES pGlDrawTexfvOES;
PFNGLBLENDEQUATIONOESPROC pGlBlendEquationOES;
PFNGLBLENDFUNCSEPARATEOESPROC pGlBlendFuncSeparateOES;
PFNGLBINDRENDERBUFFEROES pGlBindRenderbufferOES;
PFNGLDELETERENDERBUFFERSOES pGlDeleteRenderbuffersOES;
PFNGLGENRENDERBUFFERSOES pGlGenRenderbuffersOES;

View File

@ -76,10 +76,22 @@ public:
// material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
// resetAllRenderstates)
{
E_BLEND_FACTOR srcFact,dstFact;
E_BLEND_FACTOR srcRGBFact,dstRGBFact,srcAlphaFact,dstAlphaFact;
E_MODULATE_FUNC modulate;
u32 alphaSource;
unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSource, material.MaterialTypeParam );
unpack_textureBlendFuncSeparate(srcRGBFact, dstRGBFact, srcAlphaFact, dstAlphaFact, modulate, alphaSource, material.MaterialTypeParam);
Driver->getBridgeCalls()->setBlend(true);
if (Driver->queryFeature(EVDF_BLEND_SEPARATE))
{
Driver->getBridgeCalls()->setBlendFuncSeparate(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact),
Driver->getGLBlend(srcAlphaFact), Driver->getGLBlend(dstAlphaFact));
}
else
{
Driver->getBridgeCalls()->setBlendFunc(Driver->getGLBlend(srcRGBFact), Driver->getGLBlend(dstRGBFact));
}
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
@ -88,12 +100,11 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, (f32) modulate );
glBlendFunc( getGLBlend(srcFact), getGLBlend(dstFact) );
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.f);
glEnable(GL_BLEND);
if ( textureBlendFunc_hasAlpha(srcFact) || textureBlendFunc_hasAlpha(dstFact) )
if (textureBlendFunc_hasAlpha(srcRGBFact) || textureBlendFunc_hasAlpha(dstRGBFact) ||
textureBlendFunc_hasAlpha(srcAlphaFact) || textureBlendFunc_hasAlpha(dstAlphaFact))
{
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
@ -109,7 +120,7 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 1.f );
glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
glDisable(GL_ALPHA_TEST);
}
@ -207,15 +218,15 @@ public:
if ((material.MaterialType != lastMaterial.MaterialType) || resetAllRenderstates)
{
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
Driver->getBridgeCalls()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(true);
}
}
virtual void OnUnsetMaterial()
{
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.
@ -252,8 +263,8 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR );
glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
Driver->getBridgeCalls()->setBlend(true);
}
}
@ -268,7 +279,7 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE );
glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.
@ -305,8 +316,8 @@ public:
glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Driver->getBridgeCalls()->setBlend(true);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, material.MaterialTypeParam);
@ -316,7 +327,7 @@ public:
virtual void OnUnsetMaterial()
{
glDisable(GL_ALPHA_TEST);
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.
@ -602,8 +613,8 @@ public:
// glEnable(GL_TEXTURE_GEN_S);
// glEnable(GL_TEXTURE_GEN_T);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
glEnable(GL_BLEND);
Driver->getBridgeCalls()->setBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
Driver->getBridgeCalls()->setBlend(true);
}
}
@ -620,7 +631,7 @@ public:
{
Driver->extGlActiveTexture(GL_TEXTURE0);
}
glDisable(GL_BLEND);
Driver->getBridgeCalls()->setBlend(false);
}
//! Returns if the material is transparent.