sl@0: /*
sl@0: * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
sl@0: * All rights reserved.
sl@0: * This component and the accompanying materials are made available
sl@0: * under the terms of the License "Eclipse Public License v1.0"
sl@0: * which accompanies this distribution, and is available
sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: *
sl@0: * Initial Contributors:
sl@0: * Nokia Corporation - initial contribution.
sl@0: *
sl@0: * Contributors:
sl@0: *
sl@0: * Description: Appearance interface
sl@0: *
sl@0: */
sl@0: 
sl@0: #ifndef __M3G_APPEARANCE_H__
sl@0: #define __M3G_APPEARANCE_H__
sl@0: 
sl@0: /*!
sl@0:  * \internal
sl@0:  * \file
sl@0:  * \brief Appearance interface
sl@0:  */
sl@0: 
sl@0: #include "m3g_object.h"
sl@0: #include "m3g_compositingmode.h"
sl@0: #include "m3g_polygonmode.h"
sl@0: #include "m3g_material.h"
sl@0: #include "m3g_texture.h"
sl@0: #include "m3g_fog.h"
sl@0: #include "m3g_rendercontext.h"
sl@0: 
sl@0: /* Limits for user settable layer */
sl@0: #define M3G_APPEARANCE_MIN_LAYER      -63
sl@0: #define M3G_APPEARANCE_MAX_LAYER       63
sl@0: #define M3G_APPEARANCE_HARD_SORT_BITS   8
sl@0: 
sl@0: typedef /*@dependent@*//*@null@*/ Texture *TexturePtr;
sl@0: 
sl@0: /*!
sl@0:  * \internal
sl@0:  * \brief Appearance object
sl@0:  */
sl@0: struct M3GAppearanceImpl
sl@0: {
sl@0:     Object object;
sl@0: 
sl@0:     /*@dependent@*//*@null@*/
sl@0:     Material *material;
sl@0: 
sl@0:     /*@dependent@*//*@null@*/
sl@0:     CompositingMode *compositingMode;
sl@0: 
sl@0:     /*@dependent@*//*@null@*/
sl@0:     PolygonMode *polygonMode;
sl@0: 
sl@0:     /*@dependent@*//*@null@*/
sl@0:     Fog *fog;
sl@0: 
sl@0:     TexturePtr texture[M3G_NUM_TEXTURE_UNITS];
sl@0: 
sl@0:     M3Guint sortKey;
sl@0:     
sl@0:     M3Gshort layer;
sl@0:     M3Gushort vertexMask;
sl@0: };
sl@0: 
sl@0: /*----------------------------------------------------------------------
sl@0:  * Internal functions
sl@0:  *--------------------------------------------------------------------*/
sl@0: 
sl@0: static void m3gApplyAppearance(const Appearance *appearance,
sl@0: 							   RenderContext *ctx,
sl@0:                                M3Gint alphaFactor);
sl@0: 
sl@0: /*!
sl@0:  * \internal
sl@0:  * \brief Get vertex mask
sl@0:  *
sl@0:  * \param app Appearance object
sl@0:  * \return vertex mask
sl@0:  */
sl@0: static M3G_INLINE M3Gbitmask m3gGetVertexMask(const Appearance *app)
sl@0: {
sl@0:     return app->vertexMask;
sl@0: }
sl@0: 
sl@0: /*!
sl@0:  * \internal
sl@0:  * \brief Shortcut getter for color mask
sl@0:  */
sl@0: static M3G_INLINE M3Gbool m3gColorMask(const Appearance *app)
sl@0: {
sl@0:     if (app) {
sl@0:         const CompositingMode *cm = app->compositingMode;
sl@0:         return !cm || cm->colorWrite;
sl@0:     }
sl@0:     return M3G_FALSE;
sl@0: }
sl@0: 
sl@0: /*!
sl@0:  * \internal
sl@0:  * \brief Shortcut getter for alpha mask
sl@0:  */
sl@0: static M3G_INLINE M3Gbool m3gAlphaMask(const Appearance *app)
sl@0: {
sl@0:     if (app) {
sl@0:         const CompositingMode *cm = app->compositingMode;
sl@0:         return !cm || cm->alphaWrite;
sl@0:     }
sl@0:     return M3G_FALSE;
sl@0: }
sl@0: 
sl@0: /*!
sl@0:  * \internal
sl@0:  * \brief Get sortkey for render queue
sl@0:  *
sl@0:  * Sort key is a combination of user settable layer and
sl@0:  * blending mode. Blended objects are always drawn last.
sl@0:  *
sl@0:  * \param appearance    Appearance object
sl@0:  * \return              sort key
sl@0:  */
sl@0: static M3G_INLINE M3Guint m3gGetAppearanceSortKey(const Appearance *appearance)
sl@0: {
sl@0:     if (appearance) {
sl@0:         M3Guint key = appearance->sortKey;
sl@0: 
sl@0:         /* The blending state bit is set dynamically, as it may change
sl@0:          * without changing the appearance (we have no signaling from
sl@0:          * CompositingMode for that) */
sl@0:         
sl@0:         if (appearance->compositingMode != NULL
sl@0:             && appearance->compositingMode->blendingMode != M3G_REPLACE) {
sl@0:             key |= (1u << (32 - M3G_APPEARANCE_HARD_SORT_BITS));
sl@0:         }
sl@0: 
sl@0:         if (m3gGetColorMaskWorkaround(M3G_INTERFACE(appearance))) {
sl@0:             /* Override the top 2 bits of the sorting key so that ColorMask
sl@0:              * changes are minimized */
sl@0:             if (appearance) {
sl@0:                 key &= ~(0x03 << 22);
sl@0:                 key |= (((M3Guint) m3gColorMask(appearance)) & 1) << 23;
sl@0:                 key |= (((M3Guint) m3gAlphaMask(appearance)) & 1) << 22;
sl@0:             }
sl@0:         }
sl@0: 
sl@0:         return key;
sl@0:     } 
sl@0: 
sl@0:     return M3G_FALSE;
sl@0: }
sl@0: 
sl@0: /*!
sl@0:  * \internal
sl@0:  * \brief Release the textures bound for this appearance
sl@0:  */
sl@0: static void m3gReleaseTextures(const Appearance *appearance);
sl@0: 
sl@0: #endif /*__M3G_APPEARANCE_H__*/