os/graphics/m3g/m3gcore11/src/m3g_compositingmode.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: CompositingMode implementation
    15 *
    16 */
    17 
    18 
    19 /*!
    20  * \internal
    21  * \file
    22  * \brief CompositingMode implementation
    23  */
    24 
    25 #ifndef M3G_CORE_INCLUDE
    26 #   error included by m3g_core.c; do not compile separately.
    27 #endif
    28 
    29 #include "m3g_compositingmode.h"
    30 #include "m3g_interface.h"
    31 
    32 /*----------------------------------------------------------------------
    33  * Internal functions
    34  *--------------------------------------------------------------------*/
    35 
    36 /*!
    37  * \internal
    38  * \brief Applies default CompositingMode to OpenGL.
    39  */
    40 static void m3gApplyDefaultCompositingMode(M3Gbool alphaWrite)
    41 {
    42     /* depth write = true */
    43     glDepthFunc(GL_LEQUAL);
    44     glDepthMask(GL_TRUE);
    45 
    46     /* colorWrite = true */
    47     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, alphaWrite);
    48 
    49     /* threshold = 0.0 */
    50     glAlphaFunc(GL_GEQUAL, 0.0f);
    51     glDisable(GL_ALPHA_TEST);
    52 
    53     /* blend = REPLACE */
    54     glDisable(GL_BLEND);
    55 
    56     /* factor = 0 && units = 0 */
    57     glDisable(GL_POLYGON_OFFSET_FILL);
    58 }
    59 
    60 /*!
    61  * \internal
    62  * \brief Applies CompositingMode to OpenGL.
    63  *
    64  * \param compositingMode CompositingMode object
    65  */
    66 static void m3gApplyCompositingMode(CompositingMode *compositingMode, RenderContext *ctx)
    67 {
    68 	M3Gbool alphaWrite = m3gGetAlphaWrite(ctx);
    69 
    70 	if (compositingMode != NULL) {
    71 
    72         glDepthFunc(compositingMode->depthTest ? GL_LEQUAL : GL_ALWAYS);
    73         glDepthMask(compositingMode->depthWrite);
    74 
    75         if (m3gGetColorMaskWorkaround(M3G_INTERFACE(compositingMode))) {
    76             glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    77         }
    78         else {
    79             glColorMask(compositingMode->colorWrite,
    80                         compositingMode->colorWrite,
    81                         compositingMode->colorWrite,
    82 						alphaWrite & compositingMode->alphaWrite);
    83         }
    84 
    85         if (compositingMode->alphaThreshold == 0.0f) {
    86             glDisable(GL_ALPHA_TEST);
    87         }
    88         else {
    89             glAlphaFunc(GL_GEQUAL, compositingMode->alphaThreshold);
    90             glEnable(GL_ALPHA_TEST);
    91         }
    92 
    93         if (compositingMode->blendingMode == M3G_REPLACE) {
    94             glDisable(GL_BLEND);
    95         }
    96         else {
    97             M3Gint src = GL_ONE;
    98             M3Gint dst = GL_ZERO;
    99             switch (compositingMode->blendingMode) {
   100                 case M3G_ALPHA_ADD:
   101                     src = GL_SRC_ALPHA;
   102                     dst = GL_ONE;
   103                     break;
   104                 case M3G_ALPHA_BLEND:
   105                     src = GL_SRC_ALPHA;
   106                     dst = GL_ONE_MINUS_SRC_ALPHA;
   107                     break;
   108                 case M3G_MODULATE:
   109                     src = GL_ZERO;
   110                     dst = GL_SRC_COLOR;
   111                     break;
   112                 case M3G_MODULATE_X2:
   113                     src = GL_DST_COLOR;
   114                     dst = GL_SRC_COLOR;
   115                     break;
   116             }
   117             glBlendFunc(src, dst);
   118             glEnable(GL_BLEND);
   119         }
   120 
   121         glPolygonOffset(compositingMode->factor, compositingMode->units);
   122         if (compositingMode->factor != 0 || compositingMode->units != 0) {
   123             glEnable(GL_POLYGON_OFFSET_FILL);
   124         }
   125         else {
   126             glDisable(GL_POLYGON_OFFSET_FILL);
   127         }
   128     }
   129     else {
   130 		m3gApplyDefaultCompositingMode(alphaWrite);
   131     }
   132     M3G_ASSERT_GL;
   133 }
   134 
   135 /*!
   136  * \internal
   137  * \brief Duplicates a CompositingMode object.
   138  *
   139  * \param originalObj original CompositingMode object
   140  * \param cloneObj pointer to cloned CompositingMode object
   141  * \param pairs array for all object-duplicate pairs
   142  * \param numPairs number of pairs
   143  */
   144 static M3Gbool m3gCompositingModeDuplicate(const Object *originalObj,
   145                                            Object **cloneObj,
   146                                            Object **pairs,
   147                                            M3Gint *numPairs)
   148 {
   149     CompositingMode *original = (CompositingMode *)originalObj;
   150     CompositingMode *clone =
   151         (CompositingMode *)m3gCreateCompositingMode(originalObj->interface);
   152     *cloneObj = (Object *)clone;
   153     if (*cloneObj == NULL) {
   154         return M3G_FALSE;
   155     }
   156 
   157     if(m3gObjectDuplicate(originalObj, cloneObj, pairs, numPairs)) {
   158         clone->blendingMode = original->blendingMode;
   159         clone->alphaThreshold = original->alphaThreshold;
   160         clone->depthTest = original->depthTest;
   161         clone->depthWrite = original->depthWrite;
   162         clone->colorWrite = original->colorWrite;
   163         clone->alphaWrite = original->alphaWrite;
   164         clone->factor = original->factor;
   165         clone->units = original->units;
   166         return M3G_TRUE;
   167     }
   168     else {
   169         return M3G_FALSE;
   170     }
   171 }
   172 
   173 /*----------------------------------------------------------------------
   174  * Virtual function table
   175  *--------------------------------------------------------------------*/
   176 
   177 static const ObjectVFTable m3gvf_CompositingMode = {
   178     m3gObjectApplyAnimation,
   179     m3gObjectIsCompatible,
   180     m3gObjectUpdateProperty,
   181     m3gObjectDoGetReferences,
   182     m3gObjectFindID,
   183     m3gCompositingModeDuplicate,
   184     m3gDestroyObject
   185 };
   186 
   187 
   188 /*----------------------------------------------------------------------
   189  * Public API functions
   190  *--------------------------------------------------------------------*/
   191 
   192 /*!
   193  * \brief Creates a new CompositingMode object.
   194  *
   195  * \param interface     M3G interface
   196  * \retval CompositingMode new CompositingMode object
   197  * \retval NULL CompositingMode creating failed
   198  */
   199 M3G_API M3GCompositingMode m3gCreateCompositingMode(M3GInterface interface)
   200 {
   201     Interface *m3g = (Interface *) interface;
   202     M3G_VALIDATE_INTERFACE(m3g);
   203 
   204     {
   205         CompositingMode *compositingMode = m3gAllocZ(m3g, sizeof(CompositingMode));
   206 
   207         if (compositingMode != NULL) {
   208             m3gInitObject(&compositingMode->object, m3g,
   209                           M3G_CLASS_COMPOSITING_MODE);
   210     
   211             compositingMode->blendingMode = M3G_REPLACE;
   212             compositingMode->alphaThreshold = 0.0f;
   213             compositingMode->depthTest = GL_TRUE;
   214             compositingMode->depthTest = GL_TRUE;
   215             compositingMode->depthWrite = GL_TRUE;
   216             compositingMode->colorWrite = GL_TRUE;
   217             compositingMode->alphaWrite = GL_TRUE;
   218             compositingMode->factor = 0.0f;
   219             compositingMode->units = 0.0f;
   220         }
   221 
   222         return (M3GCompositingMode) compositingMode;
   223     }
   224 }
   225 
   226 /*!
   227  * \brief Set blending mode.
   228  *
   229  * \param handle CompositingMode object
   230  * \param mode blending mode
   231  */
   232 M3G_API void m3gSetBlending(M3GCompositingMode handle, M3Gint mode)
   233 {
   234     CompositingMode *compositingMode = (CompositingMode*)handle;
   235     if (mode != M3G_REPLACE && mode != M3G_ALPHA_BLEND && mode != M3G_MODULATE && mode != M3G_MODULATE_X2 && mode != M3G_ALPHA_ADD) {
   236         m3gRaiseError(M3G_INTERFACE(compositingMode), M3G_INVALID_VALUE);
   237         return;
   238     }
   239     M3G_VALIDATE_OBJECT(compositingMode);
   240     compositingMode->blendingMode = mode;
   241 }
   242 
   243 /*!
   244  * \brief Get blending mode.
   245  *
   246  * \param handle CompositingMode object
   247  * \return blending mode
   248  */
   249 M3G_API M3Gint m3gGetBlending(M3GCompositingMode handle)
   250 {
   251     CompositingMode *compositingMode = (CompositingMode*)handle;
   252     M3G_VALIDATE_OBJECT(compositingMode);
   253     return compositingMode->blendingMode;
   254 }
   255 
   256 /*!
   257  * \brief Set alpha threshold [0, 1].
   258  *
   259  * \param handle CompositingMode object
   260  * \param threshold alpha threshold [0, 1]
   261  */
   262 M3G_API void m3gSetAlphaThreshold(M3GCompositingMode handle,
   263                                   M3Gfloat threshold)
   264 {
   265     CompositingMode *compositingMode = (CompositingMode*)handle;
   266     M3G_VALIDATE_OBJECT(compositingMode);
   267     if (!m3gInRangef(threshold, 0.0f, 1.0f)) {
   268         m3gRaiseError(M3G_INTERFACE(compositingMode), M3G_INVALID_VALUE);
   269         return;
   270     }
   271     compositingMode->alphaThreshold = threshold;
   272 }
   273 
   274 /*!
   275  * \brief Get alpha threshold.
   276  *
   277  * \param handle CompositingMode object
   278  * \return alpha threshold
   279  */
   280 M3G_API M3Gfloat m3gGetAlphaThreshold(M3GCompositingMode handle)
   281 {
   282     CompositingMode *compositingMode = (CompositingMode*)handle;
   283     M3G_VALIDATE_OBJECT(compositingMode);
   284     return compositingMode->alphaThreshold;
   285 }
   286 
   287 /*!
   288  * \brief Set depth test enable.
   289  *
   290  * \param handle CompositingMode object
   291  * \param enable depth test enable
   292  */
   293 M3G_API void m3gEnableDepthTest(M3GCompositingMode handle, M3Gbool enable)
   294 {
   295     CompositingMode *compositingMode = (CompositingMode*)handle;
   296     M3G_VALIDATE_OBJECT(compositingMode);
   297     compositingMode->depthTest = (GLboolean) enable;
   298 }
   299 
   300 /*!
   301  * \brief Set depth write enable.
   302  *
   303  * \param handle CompositingMode object
   304  * \param enable depth write enable
   305  */
   306 M3G_API void m3gEnableDepthWrite(M3GCompositingMode handle, M3Gbool enable)
   307 {
   308     CompositingMode *compositingMode = (CompositingMode*)handle;
   309     M3G_VALIDATE_OBJECT(compositingMode);
   310     compositingMode->depthWrite = (GLboolean) enable;
   311 }
   312 
   313 /*!
   314  * \brief Set color write enable.
   315  *
   316  * \param handle CompositingMode object
   317  * \param enable color write enable
   318  */
   319 M3G_API void m3gEnableColorWrite(M3GCompositingMode handle, M3Gbool enable)
   320 {
   321     CompositingMode *compositingMode = (CompositingMode*)handle;
   322     M3G_VALIDATE_OBJECT(compositingMode);
   323     compositingMode->colorWrite = (GLboolean) enable;
   324 }
   325 
   326 /*!
   327  * \brief Set depth offset with factor and units.
   328  *
   329  * \param handle CompositingMode object
   330  * \param factor slope dependent depth offset
   331  * \param units constant depth offset
   332  */
   333 M3G_API void m3gSetDepthOffset(M3GCompositingMode handle,
   334                                M3Gfloat factor, M3Gfloat units)
   335 {
   336     CompositingMode *compositingMode = (CompositingMode*)handle;
   337     M3G_VALIDATE_OBJECT(compositingMode);
   338     compositingMode->factor = factor;
   339     compositingMode->units = units;
   340 }
   341 
   342 /*!
   343  * \brief Get depth offset factor.
   344  *
   345  * \param handle CompositingMode object
   346  * \return slope dependent depth offset
   347  */
   348 M3G_API M3Gfloat m3gGetDepthOffsetFactor(M3GCompositingMode handle)
   349 {
   350     CompositingMode *compositingMode = (CompositingMode*)handle;
   351     M3G_VALIDATE_OBJECT(compositingMode);
   352     return compositingMode->factor;
   353 }
   354 
   355 /*!
   356  * \brief Get depth offset units.
   357  *
   358  * \param handle CompositingMode object
   359  * \return constant depth offset
   360  */
   361 M3G_API M3Gfloat m3gGetDepthOffsetUnits(M3GCompositingMode handle)
   362 {
   363     CompositingMode *compositingMode = (CompositingMode*)handle;
   364     M3G_VALIDATE_OBJECT(compositingMode);
   365     return compositingMode->units;
   366 }
   367 
   368 /*!
   369  * \brief Get alpha write enable.
   370  *
   371  * \param handle CompositingMode object
   372  * \retval M3G_TRUE alpha write enabled
   373  * \retval M3G_FALSE alpha write disabled
   374  */
   375 M3G_API M3Gbool m3gIsAlphaWriteEnabled(M3GCompositingMode handle)
   376 {
   377     CompositingMode *compositingMode = (CompositingMode*)handle;
   378     M3G_VALIDATE_OBJECT(compositingMode);
   379     return compositingMode->alphaWrite;
   380 }
   381 
   382 /*!
   383  * \brief Get color write enable.
   384  *
   385  * \param handle CompositingMode object
   386  * \retval M3G_TRUE color write enabled
   387  * \retval M3G_FALSE color  write disabled
   388  */
   389 M3G_API M3Gbool m3gIsColorWriteEnabled(M3GCompositingMode handle)
   390 {
   391     CompositingMode *compositingMode = (CompositingMode*)handle;
   392     M3G_VALIDATE_OBJECT(compositingMode);
   393     return compositingMode->colorWrite;
   394 }
   395 
   396 /*!
   397  * \brief Get depth test enable.
   398  *
   399  * \param handle CompositingMode object
   400  * \retval M3G_TRUE depth test enabled
   401  * \retval M3G_FALSE depth test disabled
   402  */
   403 M3G_API M3Gbool m3gIsDepthTestEnabled(M3GCompositingMode handle)
   404 {
   405     CompositingMode *compositingMode = (CompositingMode*)handle;
   406     M3G_VALIDATE_OBJECT(compositingMode);
   407     return compositingMode->depthTest;
   408 }
   409 
   410 /*!
   411  * \brief Get depth write enable.
   412  *
   413  * \param handle CompositingMode object
   414  * \retval M3G_TRUE depth write enabled
   415  * \retval M3G_FALSE depth write disabled
   416  */
   417 M3G_API M3Gbool m3gIsDepthWriteEnabled(M3GCompositingMode handle)
   418 {
   419     CompositingMode *compositingMode = (CompositingMode*)handle;
   420     M3G_VALIDATE_OBJECT(compositingMode);
   421     return compositingMode->depthWrite;
   422 }
   423 
   424 /*!
   425  * \brief Set alpha write enable.
   426  *
   427  * \param handle CompositingMode object
   428  * \param enable alpha write enable
   429  */
   430 M3G_API void m3gSetAlphaWriteEnable(M3GCompositingMode handle, M3Gbool enable)
   431 {
   432     CompositingMode *compositingMode = (CompositingMode*)handle;
   433     M3G_VALIDATE_OBJECT(compositingMode);
   434     compositingMode->alphaWrite = (GLboolean) enable;
   435 }
   436