diff -r 000000000000 -r bde4ae8d615e os/graphics/m3g/m3gcore11/src/m3g_compositingmode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/m3g/m3gcore11/src/m3g_compositingmode.c Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,436 @@ +/* +* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: CompositingMode implementation +* +*/ + + +/*! + * \internal + * \file + * \brief CompositingMode implementation + */ + +#ifndef M3G_CORE_INCLUDE +# error included by m3g_core.c; do not compile separately. +#endif + +#include "m3g_compositingmode.h" +#include "m3g_interface.h" + +/*---------------------------------------------------------------------- + * Internal functions + *--------------------------------------------------------------------*/ + +/*! + * \internal + * \brief Applies default CompositingMode to OpenGL. + */ +static void m3gApplyDefaultCompositingMode(M3Gbool alphaWrite) +{ + /* depth write = true */ + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + + /* colorWrite = true */ + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, alphaWrite); + + /* threshold = 0.0 */ + glAlphaFunc(GL_GEQUAL, 0.0f); + glDisable(GL_ALPHA_TEST); + + /* blend = REPLACE */ + glDisable(GL_BLEND); + + /* factor = 0 && units = 0 */ + glDisable(GL_POLYGON_OFFSET_FILL); +} + +/*! + * \internal + * \brief Applies CompositingMode to OpenGL. + * + * \param compositingMode CompositingMode object + */ +static void m3gApplyCompositingMode(CompositingMode *compositingMode, RenderContext *ctx) +{ + M3Gbool alphaWrite = m3gGetAlphaWrite(ctx); + + if (compositingMode != NULL) { + + glDepthFunc(compositingMode->depthTest ? GL_LEQUAL : GL_ALWAYS); + glDepthMask(compositingMode->depthWrite); + + if (m3gGetColorMaskWorkaround(M3G_INTERFACE(compositingMode))) { + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } + else { + glColorMask(compositingMode->colorWrite, + compositingMode->colorWrite, + compositingMode->colorWrite, + alphaWrite & compositingMode->alphaWrite); + } + + if (compositingMode->alphaThreshold == 0.0f) { + glDisable(GL_ALPHA_TEST); + } + else { + glAlphaFunc(GL_GEQUAL, compositingMode->alphaThreshold); + glEnable(GL_ALPHA_TEST); + } + + if (compositingMode->blendingMode == M3G_REPLACE) { + glDisable(GL_BLEND); + } + else { + M3Gint src = GL_ONE; + M3Gint dst = GL_ZERO; + switch (compositingMode->blendingMode) { + case M3G_ALPHA_ADD: + src = GL_SRC_ALPHA; + dst = GL_ONE; + break; + case M3G_ALPHA_BLEND: + src = GL_SRC_ALPHA; + dst = GL_ONE_MINUS_SRC_ALPHA; + break; + case M3G_MODULATE: + src = GL_ZERO; + dst = GL_SRC_COLOR; + break; + case M3G_MODULATE_X2: + src = GL_DST_COLOR; + dst = GL_SRC_COLOR; + break; + } + glBlendFunc(src, dst); + glEnable(GL_BLEND); + } + + glPolygonOffset(compositingMode->factor, compositingMode->units); + if (compositingMode->factor != 0 || compositingMode->units != 0) { + glEnable(GL_POLYGON_OFFSET_FILL); + } + else { + glDisable(GL_POLYGON_OFFSET_FILL); + } + } + else { + m3gApplyDefaultCompositingMode(alphaWrite); + } + M3G_ASSERT_GL; +} + +/*! + * \internal + * \brief Duplicates a CompositingMode object. + * + * \param originalObj original CompositingMode object + * \param cloneObj pointer to cloned CompositingMode object + * \param pairs array for all object-duplicate pairs + * \param numPairs number of pairs + */ +static M3Gbool m3gCompositingModeDuplicate(const Object *originalObj, + Object **cloneObj, + Object **pairs, + M3Gint *numPairs) +{ + CompositingMode *original = (CompositingMode *)originalObj; + CompositingMode *clone = + (CompositingMode *)m3gCreateCompositingMode(originalObj->interface); + *cloneObj = (Object *)clone; + if (*cloneObj == NULL) { + return M3G_FALSE; + } + + if(m3gObjectDuplicate(originalObj, cloneObj, pairs, numPairs)) { + clone->blendingMode = original->blendingMode; + clone->alphaThreshold = original->alphaThreshold; + clone->depthTest = original->depthTest; + clone->depthWrite = original->depthWrite; + clone->colorWrite = original->colorWrite; + clone->alphaWrite = original->alphaWrite; + clone->factor = original->factor; + clone->units = original->units; + return M3G_TRUE; + } + else { + return M3G_FALSE; + } +} + +/*---------------------------------------------------------------------- + * Virtual function table + *--------------------------------------------------------------------*/ + +static const ObjectVFTable m3gvf_CompositingMode = { + m3gObjectApplyAnimation, + m3gObjectIsCompatible, + m3gObjectUpdateProperty, + m3gObjectDoGetReferences, + m3gObjectFindID, + m3gCompositingModeDuplicate, + m3gDestroyObject +}; + + +/*---------------------------------------------------------------------- + * Public API functions + *--------------------------------------------------------------------*/ + +/*! + * \brief Creates a new CompositingMode object. + * + * \param interface M3G interface + * \retval CompositingMode new CompositingMode object + * \retval NULL CompositingMode creating failed + */ +M3G_API M3GCompositingMode m3gCreateCompositingMode(M3GInterface interface) +{ + Interface *m3g = (Interface *) interface; + M3G_VALIDATE_INTERFACE(m3g); + + { + CompositingMode *compositingMode = m3gAllocZ(m3g, sizeof(CompositingMode)); + + if (compositingMode != NULL) { + m3gInitObject(&compositingMode->object, m3g, + M3G_CLASS_COMPOSITING_MODE); + + compositingMode->blendingMode = M3G_REPLACE; + compositingMode->alphaThreshold = 0.0f; + compositingMode->depthTest = GL_TRUE; + compositingMode->depthTest = GL_TRUE; + compositingMode->depthWrite = GL_TRUE; + compositingMode->colorWrite = GL_TRUE; + compositingMode->alphaWrite = GL_TRUE; + compositingMode->factor = 0.0f; + compositingMode->units = 0.0f; + } + + return (M3GCompositingMode) compositingMode; + } +} + +/*! + * \brief Set blending mode. + * + * \param handle CompositingMode object + * \param mode blending mode + */ +M3G_API void m3gSetBlending(M3GCompositingMode handle, M3Gint mode) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + if (mode != M3G_REPLACE && mode != M3G_ALPHA_BLEND && mode != M3G_MODULATE && mode != M3G_MODULATE_X2 && mode != M3G_ALPHA_ADD) { + m3gRaiseError(M3G_INTERFACE(compositingMode), M3G_INVALID_VALUE); + return; + } + M3G_VALIDATE_OBJECT(compositingMode); + compositingMode->blendingMode = mode; +} + +/*! + * \brief Get blending mode. + * + * \param handle CompositingMode object + * \return blending mode + */ +M3G_API M3Gint m3gGetBlending(M3GCompositingMode handle) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + return compositingMode->blendingMode; +} + +/*! + * \brief Set alpha threshold [0, 1]. + * + * \param handle CompositingMode object + * \param threshold alpha threshold [0, 1] + */ +M3G_API void m3gSetAlphaThreshold(M3GCompositingMode handle, + M3Gfloat threshold) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + if (!m3gInRangef(threshold, 0.0f, 1.0f)) { + m3gRaiseError(M3G_INTERFACE(compositingMode), M3G_INVALID_VALUE); + return; + } + compositingMode->alphaThreshold = threshold; +} + +/*! + * \brief Get alpha threshold. + * + * \param handle CompositingMode object + * \return alpha threshold + */ +M3G_API M3Gfloat m3gGetAlphaThreshold(M3GCompositingMode handle) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + return compositingMode->alphaThreshold; +} + +/*! + * \brief Set depth test enable. + * + * \param handle CompositingMode object + * \param enable depth test enable + */ +M3G_API void m3gEnableDepthTest(M3GCompositingMode handle, M3Gbool enable) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + compositingMode->depthTest = (GLboolean) enable; +} + +/*! + * \brief Set depth write enable. + * + * \param handle CompositingMode object + * \param enable depth write enable + */ +M3G_API void m3gEnableDepthWrite(M3GCompositingMode handle, M3Gbool enable) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + compositingMode->depthWrite = (GLboolean) enable; +} + +/*! + * \brief Set color write enable. + * + * \param handle CompositingMode object + * \param enable color write enable + */ +M3G_API void m3gEnableColorWrite(M3GCompositingMode handle, M3Gbool enable) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + compositingMode->colorWrite = (GLboolean) enable; +} + +/*! + * \brief Set depth offset with factor and units. + * + * \param handle CompositingMode object + * \param factor slope dependent depth offset + * \param units constant depth offset + */ +M3G_API void m3gSetDepthOffset(M3GCompositingMode handle, + M3Gfloat factor, M3Gfloat units) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + compositingMode->factor = factor; + compositingMode->units = units; +} + +/*! + * \brief Get depth offset factor. + * + * \param handle CompositingMode object + * \return slope dependent depth offset + */ +M3G_API M3Gfloat m3gGetDepthOffsetFactor(M3GCompositingMode handle) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + return compositingMode->factor; +} + +/*! + * \brief Get depth offset units. + * + * \param handle CompositingMode object + * \return constant depth offset + */ +M3G_API M3Gfloat m3gGetDepthOffsetUnits(M3GCompositingMode handle) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + return compositingMode->units; +} + +/*! + * \brief Get alpha write enable. + * + * \param handle CompositingMode object + * \retval M3G_TRUE alpha write enabled + * \retval M3G_FALSE alpha write disabled + */ +M3G_API M3Gbool m3gIsAlphaWriteEnabled(M3GCompositingMode handle) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + return compositingMode->alphaWrite; +} + +/*! + * \brief Get color write enable. + * + * \param handle CompositingMode object + * \retval M3G_TRUE color write enabled + * \retval M3G_FALSE color write disabled + */ +M3G_API M3Gbool m3gIsColorWriteEnabled(M3GCompositingMode handle) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + return compositingMode->colorWrite; +} + +/*! + * \brief Get depth test enable. + * + * \param handle CompositingMode object + * \retval M3G_TRUE depth test enabled + * \retval M3G_FALSE depth test disabled + */ +M3G_API M3Gbool m3gIsDepthTestEnabled(M3GCompositingMode handle) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + return compositingMode->depthTest; +} + +/*! + * \brief Get depth write enable. + * + * \param handle CompositingMode object + * \retval M3G_TRUE depth write enabled + * \retval M3G_FALSE depth write disabled + */ +M3G_API M3Gbool m3gIsDepthWriteEnabled(M3GCompositingMode handle) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + return compositingMode->depthWrite; +} + +/*! + * \brief Set alpha write enable. + * + * \param handle CompositingMode object + * \param enable alpha write enable + */ +M3G_API void m3gSetAlphaWriteEnable(M3GCompositingMode handle, M3Gbool enable) +{ + CompositingMode *compositingMode = (CompositingMode*)handle; + M3G_VALIDATE_OBJECT(compositingMode); + compositingMode->alphaWrite = (GLboolean) enable; +} +