javauis/m3g_qt/javasrc/javax/microedition/m3g/Graphics3D.java
changeset 35 85266cc22c7f
child 40 c6043ea9b06a
child 78 71ad690e91f5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/m3g_qt/javasrc/javax/microedition/m3g/Graphics3D.java	Fri Jun 11 13:33:44 2010 +0300
@@ -0,0 +1,743 @@
+/*
+* 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 "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:
+*
+*/
+
+
+package javax.microedition.m3g;
+
+import javax.microedition.lcdui.Graphics;
+import java.util.Hashtable;
+import java.util.Vector;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.qt.graphics.*;
+import org.eclipse.swt.internal.qt.GCData;
+import com.nokia.mj.impl.rt.support.ShutdownListener;
+import com.nokia.mj.impl.rt.support.ApplicationUtils;
+import com.nokia.mj.impl.nokialcdui.LCDUIInvoker;
+
+
+public class Graphics3D
+{
+    //------------------------------------------------------------------
+    // Static data
+    //------------------------------------------------------------------
+
+    public static final int ANTIALIAS   = 2;
+    public static final int DITHER      = 4;
+    public static final int TRUE_COLOR  = 8;
+
+    // M3G 1.1
+    public static final int OVERWRITE   = 16;
+
+    // Singleton instances
+    static Graphics3D s_instance = null;
+
+    //------------------------------------------------------------------
+    // Instance data
+    //------------------------------------------------------------------
+
+    int handle;
+    int iSurfaceHandle;
+
+    private Camera camera = null;
+    private Vector lights = new Vector();
+
+    private java.lang.Object currentTarget = null;
+    private int offsetX, offsetY, hints = 0;
+    private boolean depthEnabled = true;
+    private Destroyer destroyer;
+    private Interface iInterface;
+
+    // this flag is for identification of image target types
+    // - True for mutable off-screen images
+    // - False for canvas/GameCanvas framebuffer
+    private boolean iIsImageTarget;
+
+    // this flag is for identification if MBX HW accelerator is present
+    // - True - MBX is NOT present
+    // - False - MBX is present
+    private boolean iIsProperRenderer;
+
+    private boolean iNativeInitialized = false;
+
+    // Shutdown listener
+    private class Destroyer implements ShutdownListener
+    {
+        Graphics3D target;
+
+        Destroyer(Graphics3D g3d)
+        {
+            target = g3d;
+            ApplicationUtils appUtils = ApplicationUtils.getInstance();
+            appUtils.addShutdownListener(this);
+        }
+
+        // This method gets called when application is shuttingdown
+        public void shuttingDown()
+        {
+
+            // Finalize native peer
+            Platform.finalizeObject(target.handle, target.iInterface);
+
+            // signal shutdown (set shutdown flag)
+            // and remove references
+            target.iInterface.signalShutdown();
+            target.iInterface = null;
+            target.camera = null;
+            //target.s_instance = null;
+
+            // All done, Call gc() and finalization to collect
+            // remaining objects, thus zeroying liveObjects count
+            // in interface instance
+
+        }
+    }
+
+    //------------------------------------------------------------------
+    // Constructor(s)
+    //------------------------------------------------------------------
+    public static final Graphics3D getInstance()
+    {
+
+        if (s_instance == null)
+        {
+            s_instance = new Graphics3D();
+        }
+        return s_instance;
+    }
+
+    private Graphics3D()
+    {
+        iInterface = Interface.getInstance();
+        initNativePeer();
+
+        // setup listener for singleton teardown
+        destroyer = new Destroyer(this);
+    }
+
+    //------------------------------------------------------------------
+    // Public methods
+    //------------------------------------------------------------------
+
+    /**
+     */
+    public void bindTarget(java.lang.Object target)
+    {
+        bindTarget(target, true, 0);
+    }
+
+    /**
+     *
+     */
+    public void bindTarget(java.lang.Object target, boolean depth, int flags)
+    {
+        integrityCheck();
+        if (currentTarget != null)
+        {
+            throw new IllegalStateException();
+        }
+
+        if (target == null)
+        {
+            throw new NullPointerException();
+        }
+
+        final int finalFlags = flags;
+        final boolean finalDepth = depth;
+
+        if (target instanceof org.eclipse.swt.graphics.GC)
+        {
+            Rectangle clip = ((org.eclipse.swt.graphics.GC)target).getClipping();
+            final int clipW = clip.width;
+            final int clipH = clip.height;
+            final int clipX = clip.x;
+            final int clipY = clip.y;
+
+            if (clipW > Defs.MAX_VIEWPORT_WIDTH ||
+                    clipH > Defs.MAX_VIEWPORT_HEIGHT)
+            {
+                throw new IllegalArgumentException();
+            }
+
+            final Object finalTarget = target;
+            Platform.executeInUIThread(
+                new M3gRunnable()
+            {
+                public void doRun()
+                {
+                    GCData gcData = ((org.eclipse.swt.graphics.GC)finalTarget).getGCData();
+                    iSurfaceHandle = gcData.internalGc.getWindowSurface().getHandle();
+                    iIsImageTarget = _bindGraphics(
+                                         handle,
+                                         iSurfaceHandle,
+                                         clipX, clipY,
+                                         clipW, clipH,
+                                         finalDepth, finalFlags,
+                                         iIsProperRenderer);
+                }
+            });
+            currentTarget = target;
+        }
+
+        else if (target instanceof Graphics)
+        {
+
+            Graphics g = (Graphics) target;
+            //Platform.sync(g);
+
+            if (g.getClipWidth() > Defs.MAX_VIEWPORT_WIDTH ||
+                    g.getClipHeight() > Defs.MAX_VIEWPORT_HEIGHT)
+            {
+                throw new IllegalArgumentException();
+            }
+
+            offsetX = g.getTranslateX();
+            offsetY = g.getTranslateY();
+
+            final Graphics finalG = g;
+
+            Platform.executeInUIThread(
+                new M3gRunnable()
+            {
+                public void doRun()
+                {
+                    LCDUIInvoker.startExternalRendering( finalG );
+                    iSurfaceHandle = LCDUIInvoker.getWindowSurface(finalG).getHandle();
+                    iIsImageTarget = _bindGraphics(
+                                         handle,
+                                         iSurfaceHandle,
+                                         finalG.getClipX() + offsetX, finalG.getClipY() + offsetY,
+                                         finalG.getClipWidth(), finalG.getClipHeight(),
+                                         finalDepth, finalFlags,
+                                         iIsProperRenderer);
+                }
+            });
+            currentTarget = g;
+        }
+        else if (target instanceof Image2D)
+        {
+            Image2D img = (Image2D) target;
+
+            offsetX = offsetY = 0;
+            final int imageHandle = img.handle;
+
+            Platform.executeInUIThread(
+                new M3gRunnable()
+            {
+                public void doRun()
+                {
+                    _bindImage(handle, imageHandle, finalDepth, finalFlags);
+                }
+            });
+            currentTarget = img;
+        }
+        else
+        {
+            throw new IllegalArgumentException();
+        }
+
+        hints = flags;
+        depthEnabled = depth;
+    }
+
+    /**
+     *
+     */
+    public void releaseTarget()
+    {
+        integrityCheck();
+        if (currentTarget == null)
+        {
+            return;
+        }
+
+        if (currentTarget instanceof org.eclipse.swt.graphics.GC)
+        {
+            Platform.executeInUIThread(
+                new M3gRunnable()
+            {
+                public void doRun()
+                {
+                    _releaseGraphics(handle,
+                                     iSurfaceHandle, iIsImageTarget, iIsProperRenderer);
+                }
+            });
+        }
+        else if (currentTarget instanceof Graphics)
+        {
+                final Graphics finalG = (Graphics)currentTarget;
+                Platform.executeInUIThread(
+                    new M3gRunnable()
+                {
+                    public void doRun()
+                    {
+                        _releaseGraphics(handle,
+                                         iSurfaceHandle, iIsImageTarget, iIsProperRenderer);
+                        LCDUIInvoker.endExternalRendering( finalG );
+                    }
+                });
+            /*
+            Graphics g = (Graphics) currentTarget;
+
+            //ToolkitInvoker invoker = ToolkitInvoker.getToolkitInvoker();
+
+            Platform.getUIThread().syncExec(
+                    new Runnable() {
+                        public void run() {
+                                        _releaseGraphics( handle,
+                                        invoker.graphicsGetHandle(g), iIsImageTarget, iIsProperRenderer );
+                                }
+                        });
+                        */
+        }
+        else if (currentTarget instanceof Image2D)
+        {
+            Platform.executeInUIThread(
+                new M3gRunnable()
+            {
+                public void doRun()
+                {
+                    _releaseImage(handle);
+                }
+            });
+        }
+        else
+        {
+            throw new Error();
+        }
+        currentTarget = null;
+        iSurfaceHandle = 0;
+    }
+
+    /**
+     *
+     */
+    public void setViewport(int x, int y, int width, int height)
+    {
+        integrityCheck();
+        if (width <= 0 || height <= 0
+                || width  > Defs.MAX_VIEWPORT_DIMENSION
+                || height > Defs.MAX_VIEWPORT_DIMENSION)
+        {
+            throw new IllegalArgumentException();
+        }
+        _setViewport(handle, x + offsetX, y + offsetY, width, height);
+    }
+
+    /**
+     *
+     */
+    public void clear(Background background)
+    {
+        integrityCheck();
+        final Background finalBackground = background;
+        Platform.executeInUIThread(
+            new M3gRunnable()
+        {
+            public void doRun()
+            {
+                _clear(handle, finalBackground != null ? finalBackground.handle : 0);
+            }
+        });
+    }
+
+    /**
+     *
+     */
+    public void render(World world)
+    {
+        integrityCheck();
+        final World finalWorld = world;
+        Platform.executeInUIThread(
+            new M3gRunnable()
+        {
+            public void doRun()
+            {
+                _renderWorld(handle, finalWorld.handle);
+            }
+        });
+    }
+
+    /**
+     *
+     */
+    public void render(VertexBuffer vertices,
+                       IndexBuffer primitives,
+                       Appearance appearance,
+                       Transform transform)
+    {
+        // Call rendering method with default visibility
+        integrityCheck();
+        render(vertices, primitives, appearance, transform, -1);
+    }
+
+    /**
+     *
+     */
+    public void render(VertexBuffer vertices,
+                       IndexBuffer primitives,
+                       Appearance appearance,
+                       Transform transform,
+                       int scope)
+    {
+
+        // null pointer exceptions thrown automatically below
+        integrityCheck();
+
+        final VertexBuffer finalVertices = vertices;
+        final IndexBuffer finalPrimitives = primitives;
+        final Appearance finalAppearance = appearance;
+        final Transform finalTransform = transform;
+        final int finalScope = scope;
+
+        Platform.executeInUIThread(
+            new M3gRunnable()
+        {
+            public void doRun()
+            {
+                _render(handle,
+                        finalVertices.handle,
+                        finalPrimitives.handle,
+                        finalAppearance.handle,
+                        finalTransform != null ? finalTransform.matrix : null,
+                        finalScope);
+            }
+        });
+    }
+
+    /**
+     *
+     */
+    public void render(Node node, Transform transform)
+    {
+        if (!(node instanceof Mesh
+                || node instanceof Sprite3D
+                || node instanceof Group)
+                && node != null)
+        {
+            throw new IllegalArgumentException();
+        }
+        integrityCheck();
+
+        final Node finalNode = node;
+        final Transform finalTransform = transform;
+
+        Platform.executeInUIThread(
+            new M3gRunnable()
+        {
+            public void doRun()
+            {
+                _renderNode(handle,
+                            finalNode.handle,
+                            finalTransform != null ? finalTransform.matrix : null);
+            }
+        });
+    }
+
+
+    public void setCamera(Camera camera, Transform transform)
+    {
+        integrityCheck();
+        _setCamera(handle,
+                   camera != null ? camera.handle : 0,
+                   transform != null ? transform.matrix : null);
+
+        this.camera = camera;
+    }
+
+    /**
+     */
+    public int addLight(Light light, Transform transform)
+    {
+        integrityCheck();
+        int index = _addLight(handle,
+                              light.handle,
+                              transform != null ? transform.matrix : null);
+        if (lights.size() < index + 1)
+        {
+            lights.setSize(index + 1);
+        }
+        lights.setElementAt(light, index);
+        return index;
+    }
+
+    /**
+     *
+     */
+    public void setLight(int index, Light light, Transform transform)
+    {
+        integrityCheck();
+        _setLight(handle,
+                  index,
+                  light != null ? light.handle : 0,
+                  transform != null ? transform.matrix : null);
+        lights.setElementAt(light, index);
+    }
+
+    /**
+     */
+    public void resetLights()
+    {
+        integrityCheck();
+        _resetLights(handle);
+        lights.removeAllElements();
+    }
+
+    /**
+     *
+     */
+    public static final Hashtable getProperties()
+    {
+        Hashtable props = new Hashtable();
+
+        props.put("supportAntialiasing",          new java.lang.Boolean(
+                      _isAASupported(Interface.getHandle())));
+        props.put("supportTrueColor",             new java.lang.Boolean(Defs.supportTrueColor));
+        props.put("supportDithering",             new java.lang.Boolean(Defs.supportDithering));
+        props.put("supportMipmapping",            new java.lang.Boolean(Defs.supportMipmapping));
+        props.put("supportPerspectiveCorrection", new java.lang.Boolean(Defs.supportPerspectiveCorrection));
+        props.put("supportLocalCameraLighting",   new java.lang.Boolean(Defs.supportLocalCameraLighting));
+        props.put("maxLights",                    new java.lang.Integer(Defs.MAX_LIGHTS));
+        props.put("maxViewportWidth",             new java.lang.Integer(Defs.MAX_VIEWPORT_WIDTH));
+        props.put("maxViewportHeight",            new java.lang.Integer(Defs.MAX_VIEWPORT_HEIGHT));
+        props.put("maxViewportDimension",         new java.lang.Integer(Defs.MAX_VIEWPORT_DIMENSION));
+        props.put("maxTextureDimension",          new java.lang.Integer(Defs.MAX_TEXTURE_DIMENSION));
+        props.put("maxSpriteCropDimension",       new java.lang.Integer(Defs.MAX_TEXTURE_DIMENSION));
+        props.put("numTextureUnits",              new java.lang.Integer(Defs.NUM_TEXTURE_UNITS));
+        props.put("maxTransformsPerVertex",       new java.lang.Integer(Defs.MAX_TRANSFORMS_PER_VERTEX));
+
+        // Extra properties
+        props.put("m3gRelease",                   new java.lang.String("04_wk49"));
+
+        return props;
+    }
+
+    /**
+     *
+     */
+    public void setDepthRange(float near, float far)
+    {
+        integrityCheck();
+        _setDepthRange(handle, near, far);
+    }
+
+    // M3G 1.1
+
+    public Camera getCamera(Transform transform)
+    {
+        integrityCheck();
+        if (transform != null)
+        {
+            _getViewTransform(handle, transform.matrix);
+        }
+
+        return (Camera) Object3D.getInstance(_getCamera(handle));
+    }
+
+    public float getDepthRangeFar()
+    {
+        integrityCheck();
+        return _getDepthRangeFar(handle);
+    }
+
+    public float getDepthRangeNear()
+    {
+        integrityCheck();
+        return _getDepthRangeNear(handle);
+    }
+
+    public Light getLight(int index, Transform transform)
+    {
+        integrityCheck();
+        if (index < 0 || index >= _getLightCount(handle))
+        {
+            throw new IndexOutOfBoundsException();
+        }
+
+        return (Light) Object3D.getInstance(_getLightTransform(handle,
+                                            index,
+                                            transform != null ? transform.matrix : null));
+    }
+
+    public int getLightCount()
+    {
+        integrityCheck();
+        return _getLightCount(handle);
+    }
+
+    public java.lang.Object getTarget()
+    {
+        return currentTarget;
+    }
+
+    public int getViewportHeight()
+    {
+        integrityCheck();
+        return _getViewportHeight(handle);
+    }
+
+    public int getViewportWidth()
+    {
+        integrityCheck();
+        return _getViewportWidth(handle);
+    }
+
+    public int getViewportX()
+    {
+        integrityCheck();
+        return _getViewportX(handle) - offsetX;
+    }
+
+    public int getViewportY()
+    {
+        integrityCheck();
+        return _getViewportY(handle) - offsetY;
+    }
+
+    public int getHints()
+    {
+        return hints;
+    }
+
+    public boolean isDepthBufferEnabled()
+    {
+        return depthEnabled;
+    }
+
+    // M3G 1.1 getters END
+
+    //------------------------------------------------------------------
+    // Private methods
+    //------------------------------------------------------------------
+
+    private void integrityCheck()
+    {
+        if (iInterface == null)
+        {
+            throw new RuntimeException("Graphics3D closed");
+        }
+        if (!iNativeInitialized)
+        {
+            // If native interface cannot be initialized we cannot recover from it
+            if (!initNativePeer())
+            {
+                throw new Error("UI thread not available");
+            }
+        }
+    }
+
+    /**
+     * Initializes native peer
+     * @return true if native interface was succesfully inialized otherwise false
+     */
+    private boolean initNativePeer()
+    {
+        if (iNativeInitialized)
+        {
+            return true;
+        }
+        if (iInterface.isFullyInitialized() && Platform.uiThreadAvailable())
+        {
+            handle = _ctor(iInterface.getHandle());
+            _addRef(handle);
+
+            Platform.executeInUIThread(
+                new M3gRunnable()
+            {
+                public void doRun()
+                {
+                    iIsProperRenderer = _isProperRenderer();
+                }
+            });
+            iNativeInitialized = true;
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    //------------------------------------------------------------------
+    // Native implementation methods
+    //------------------------------------------------------------------
+    private native static int _ctor(int hInterface);
+    private native static void _addRef(int hObject);
+    private native static int _addLight(int handle,
+                                        int hLight,
+                                        byte[] transform);
+    private native static boolean _bindGraphics(int handle,
+            int surfaceHandle,
+            int clipX, int clipY,
+            int clipW, int clipH,
+            boolean depth,
+            int hintBits,
+            boolean aIsProperRenderer);
+    private native static void _bindImage(int handle, int imgHandle, boolean depth, int hintBits);
+    private native static void _releaseGraphics(int handle,
+            int surfaceHandle,
+            boolean aIsImageTarget,
+            boolean aIsProperRenderer);
+    private native static void _releaseImage(int handle);
+    private native static void _resetLights(int handle);
+    private native static void _clear(int handle, int hBackground);
+    private native static void _render(int handle,
+                                       int hVtxBuffer,
+                                       int hIdxBuffer,
+                                       int hAppearance,
+                                       byte[] transform,
+                                       int scope);
+    private native static void _renderNode(int handle, int hNode, byte[] transform);
+    private native static void _renderWorld(int handle, int hWorld);
+    private native static void _setCamera(int handle,
+                                          int hCamera,
+                                          byte[] transform);
+    private native static void _setViewport(int handle,
+                                            int x, int y,
+                                            int width, int height);
+    private native static void _setLight(int handle,
+                                         int index,
+                                         int hLight,
+                                         byte[] transform);
+    private native static void _setDepthRange(int handle,
+            float near,
+            float far);
+
+    // M3G 1.1
+    // Maintenance release getters
+
+    private native static void _getViewTransform(int handle,
+            byte[] transform);
+    private native static int _getCamera(int handle);
+    private native static int _getLightTransform(int handle,
+            int index,
+            byte[] transform);
+    private native static int _getLightCount(int handle);
+    private native static float _getDepthRangeNear(int handle);
+    private native static float _getDepthRangeFar(int handle);
+    private native static int _getViewportX(int handle);
+    private native static int _getViewportY(int handle);
+    private native static int _getViewportWidth(int handle);
+    private native static int _getViewportHeight(int handle);
+
+    /* Statistics support, MUST be disabled in official releases! */
+    /*
+        public native static int getStatistics(int[] statistics);
+    */
+    private native static boolean _isAASupported(int handle);
+    private native static boolean _isProperRenderer();
+}