m3g/m3gcore11/src/m3g_polygonmode.c
changeset 0 5d03bc08d59c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/m3g/m3gcore11/src/m3g_polygonmode.c	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,403 @@
+/*
+* 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: PolygonMode implementation
+*
+*/
+
+
+/*!
+ * \internal
+ * \file
+ * \brief PolygonMode implementation
+ */
+
+#ifndef M3G_CORE_INCLUDE
+#   error included by m3g_core.c; do not compile separately.
+#endif
+
+/*
+ * Uncomment this line to switch tracing on for this file's functions
+ */
+/* #define M3G_LOCAL_TRACEF_ON */
+
+#include "m3g_polygonmode.h"
+
+/*----------------------------------------------------------------------
+ * Internal functions
+ *--------------------------------------------------------------------*/
+
+/*!
+ * \internal
+ * \brief Applies default polygon mode to OpenGL.
+ */
+static void m3gApplyDefaultPolygonMode()
+{
+    /* cull = BACK */
+    glCullFace(GL_BACK);
+    glEnable(GL_CULL_FACE);
+
+    /* shading = M3G_SHADE_SMOOTH */
+    glShadeModel(GL_SMOOTH);
+
+    /*  winding = M3G_WINDING_CCW */
+    glFrontFace(GL_CCW);
+
+    /* perspective correction = false */
+    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+
+    /* lighting = ONE_SIDED */
+    glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+}
+
+/*!
+ * \internal
+ * \brief Applies polygon mode to OpenGL.
+ *
+ * \param polygonMode   PolygonMode object
+ */
+static void m3gApplyPolygonMode(PolygonMode *polygonMode)
+{
+    if (polygonMode != NULL) {
+        if (polygonMode->cullingMode == M3G_CULL_NONE) {
+            glDisable(GL_CULL_FACE);
+        }
+        else {
+            if (polygonMode->cullingMode == M3G_CULL_BACK) {
+                glCullFace(GL_BACK);
+            }
+            else {
+                glCullFace(GL_FRONT);
+            }
+            glEnable(GL_CULL_FACE);
+        }
+
+        if (m3gGetTwoSidedLightingWorkaround(M3G_INTERFACE(polygonMode))) {
+            glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+        }
+        else {
+            glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, polygonMode->enableTwoSidedLighting);
+        }
+
+        if (polygonMode->shadingMode == M3G_SHADE_FLAT) {
+            glShadeModel(GL_FLAT);
+        }
+        else {
+            glShadeModel(GL_SMOOTH);
+        }
+
+        if (polygonMode->windingMode == M3G_WINDING_CW) {
+            glFrontFace(GL_CW);
+        }
+        else {
+            glFrontFace(GL_CCW);
+        }
+
+        if (polygonMode->enablePerspectiveCorrection == GL_TRUE) {
+            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+        }
+        else {
+            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+        }
+    }
+    else {
+        m3gApplyDefaultPolygonMode();
+    }
+    M3G_ASSERT_GL;
+
+}
+
+/*!
+ * \internal
+ * \brief Overloaded Object3D method
+ *
+ * \param originalObj original PolygonMode object
+ * \param cloneObj pointer to cloned PolygonMode object
+ * \param pairs array for all object-duplicate pairs
+ * \param numPairs number of pairs
+ */
+static M3Gbool m3gPolygonModeDuplicate(const Object *originalObj,
+                                       Object **cloneObj,
+                                       Object **pairs,
+                                       M3Gint *numPairs)
+{
+    PolygonMode *original = (PolygonMode *)originalObj;
+    PolygonMode *clone;
+    M3G_ASSERT(*cloneObj == NULL); /* no derived classes */
+
+    /* Create the clone object */
+    
+    clone = (PolygonMode *)m3gCreatePolygonMode(originalObj->interface);
+    if (!clone) {
+        return M3G_FALSE;
+    }
+    *cloneObj = (Object *)clone;
+
+    /* Duplicate base class data */
+    
+    if (!m3gObjectDuplicate(originalObj, cloneObj, pairs, numPairs)) {
+        return M3G_FALSE;
+    }
+
+    /* Duplicate our own data */
+    
+    clone->enableLocalCameraLighting = original->enableLocalCameraLighting;
+    clone->enablePerspectiveCorrection = original->enablePerspectiveCorrection;
+    clone->cullingMode = original->cullingMode;
+    clone->windingMode = original->windingMode;
+    clone->shadingMode = original->shadingMode;
+    clone->enableTwoSidedLighting = original->enableTwoSidedLighting;
+
+    return M3G_TRUE;
+}
+
+/*----------------------------------------------------------------------
+ * Virtual function table
+ *--------------------------------------------------------------------*/
+
+static const ObjectVFTable m3gvf_PolygonMode = {
+    m3gObjectApplyAnimation,
+    m3gObjectIsCompatible,
+    m3gObjectUpdateProperty,
+    m3gObjectDoGetReferences,
+    m3gObjectFindID,
+    m3gPolygonModeDuplicate,
+    m3gDestroyObject
+};
+
+
+/*----------------------------------------------------------------------
+ * Public API functions
+ *--------------------------------------------------------------------*/
+
+/*!
+ * \brief Creates a new PolygonMode object.
+ *
+ * \param interface     M3G interface object
+ * \retval PolygonMode new PolygonMode object
+ * \retval NULL PolygonMode creating failed
+ */
+M3G_API M3GPolygonMode m3gCreatePolygonMode(M3GInterface interface)
+{
+    Interface *m3g = (Interface *) interface;
+    M3G_VALIDATE_INTERFACE(m3g);
+
+    {
+        PolygonMode *polygonMode = m3gAllocZ(m3g, sizeof(PolygonMode));
+
+        if (polygonMode != NULL) {
+            m3gInitObject(&polygonMode->object, m3g, M3G_CLASS_POLYGON_MODE);
+            polygonMode->enableLocalCameraLighting = GL_FALSE;
+            polygonMode->enablePerspectiveCorrection = GL_FALSE;
+            polygonMode->cullingMode = M3G_CULL_BACK;
+            polygonMode->windingMode = M3G_WINDING_CCW;
+            polygonMode->shadingMode = M3G_SHADE_SMOOTH;
+            polygonMode->enableTwoSidedLighting = GL_FALSE;
+        }
+
+        return (M3GPolygonMode)polygonMode;
+    }
+}
+
+/*!
+ * \brief Set local camera lightning.
+ *
+ * \param handle        PolygonMode object
+ * \param enable        enable flag
+ */
+M3G_API void m3gSetLocalCameraLightingEnable(M3GPolygonMode handle,
+                                             M3Gbool enable)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    polygonMode->enableLocalCameraLighting = (GLboolean) enable;
+}
+
+/*!
+ * \brief Set perspective correction.
+ *
+ * \param handle        PolygonMode object
+ * \param enable        enable flag
+ */
+void m3gSetPerspectiveCorrectionEnable(M3GPolygonMode handle, M3Gbool enable)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    polygonMode->enablePerspectiveCorrection = (GLboolean) enable;
+}
+
+/*!
+ * \brief Set culling mode.
+ *
+ * \param handle        PolygonMode object
+ * \param mode          culling mode
+ */
+void m3gSetCulling(M3GPolygonMode handle, M3Gint mode)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+
+    switch (mode) {
+    case M3G_CULL_BACK:
+    case M3G_CULL_FRONT:
+    case M3G_CULL_NONE:
+        polygonMode->cullingMode = mode;
+        break;
+    default:
+        m3gRaiseError(M3G_INTERFACE(polygonMode), M3G_INVALID_VALUE);
+        break;
+    }
+}
+
+/*!
+ * \brief Get culling mode.
+ *
+ * \param handle        PolygonMode object
+ * \return              culling mode
+ */
+M3G_API M3Gint m3gGetCulling(M3GPolygonMode handle)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    return polygonMode->cullingMode;
+}
+
+/*!
+ * \brief Set winding mode.
+ *
+ * \param handle        PolygonMode object
+ * \param mode          winding mode
+ */
+M3G_API void m3gSetWinding(M3GPolygonMode handle, M3Gint mode)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+
+    if (mode != M3G_WINDING_CCW && mode != M3G_WINDING_CW) {
+        m3gRaiseError(M3G_INTERFACE(polygonMode), M3G_INVALID_VALUE);
+    }
+    else {
+        polygonMode->windingMode = mode;
+    }
+}
+
+/*!
+ * \brief Get winding mode.
+ *
+ * \param handle        PolygonMode object
+ * \return              winding mode
+ */
+M3G_API M3Gint m3gGetWinding(M3GPolygonMode handle)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    return polygonMode->windingMode;
+}
+
+/*!
+ * \brief Set shading mode.
+ *
+ * \param handle        PolygonMode object
+ * \param mode          shading mode
+ */
+M3G_API void m3gSetShading(M3GPolygonMode handle, M3Gint mode)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+
+    if (mode != M3G_SHADE_FLAT && mode != M3G_SHADE_SMOOTH) {
+        m3gRaiseError(M3G_INTERFACE(polygonMode), M3G_INVALID_VALUE);
+    }
+    else {
+        polygonMode->shadingMode = mode;
+    }
+}
+
+/*!
+ * \brief Get shading mode.
+ *
+ * \param handle        PolygonMode object
+ * \return              shading mode
+ */
+M3G_API M3Gint m3gGetShading(M3GPolygonMode handle)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    return polygonMode->shadingMode;
+}
+
+/*!
+ * \brief Set two sided lighting.
+ *
+ * \param handle        PolygonMode object
+ * \param enable        enable flag
+ */
+M3G_API void m3gSetTwoSidedLightingEnable(M3GPolygonMode handle,
+                                          M3Gbool enable)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    polygonMode->enableTwoSidedLighting = (GLboolean) enable;
+}
+
+/*!
+ * \brief Get two sided lighting.
+ *
+ * \param handle        PolygonMode object
+ * \retval M3G_TRUE     enabled
+ * \retval M3G_FALSE    disabled
+ */
+M3G_API M3Gbool m3gIsTwoSidedLightingEnabled(M3GPolygonMode handle)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    return (M3Gbool) polygonMode->enableTwoSidedLighting;
+}
+
+/*!
+ * \brief Get local camera lighting.
+ *
+ * \param handle        PolygonMode object
+ * \retval M3G_TRUE     enabled
+ * \retval M3G_FALSE    disabled
+ */
+
+M3G_API M3Gbool m3gIsLocalCameraLightingEnabled(M3GPolygonMode handle)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    return (M3Gbool) polygonMode->enableLocalCameraLighting;
+}
+
+/*!
+ * \brief Get perspective correction.
+ *
+ * \param handle        PolygonMode object
+ * \retval M3G_TRUE     enabled
+ * \retval M3G_FALSE    disabled
+ */
+M3G_API M3Gbool m3gIsPerspectiveCorrectionEnabled(M3GPolygonMode handle)
+{
+    PolygonMode *polygonMode = (PolygonMode*)handle;
+    M3G_VALIDATE_OBJECT(polygonMode);
+    return (M3Gbool) polygonMode->enablePerspectiveCorrection;
+}
+
+/*
+ * Uncomment these lines' opening pair at the begining of the file
+ * if you want to switch tracing on for this file.
+ */
+#ifdef M3G_LOCAL_TRACEF_ON
+#undef M3G_LOCAL_TRACEF_ON
+#endif
+