diff -r dc7c549001d5 -r 85266cc22c7f javauis/m3g_qt/javasrc/javax/microedition/m3g/Graphics3D.java --- /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(); +}