- 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-e03cc46cb475master
parent
1e8048f561
commit
03fceb34d3
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue