📄 canvas3d.java
字号:
fbConfig = Pipeline.getPipeline().getFbConfig(gcInfo); if (offScreen) { // Issue 131: set manual rendering flag based on whether this is // an auto-off-screen Canvas3D. manualRendering = !autoOffScreenCanvas3D; screen = new Screen3D(graphicsConfiguration, offScreen); // QUESTION: keep a list of off-screen Screen3D objects? // Does this list need to be grouped by GraphicsDevice? synchronized(dirtyMaskLock) { cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY; cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY; } // this canvas will not receive the paint callback, // so we need to set the necessary flags here firstPaintCalled = true; if (manualRendering) { // since this canvas will not receive the addNotify // callback from AWT, set the added flag here for // evaluateActive to work correctly added = true; } evaluateActive(); // create the rendererStructure object //rendererStructure = new RendererStructure(); offScreenCanvasLoc = new Point(0, 0); offScreenCanvasSize = new Dimension(0, 0); this.setLocation(offScreenCanvasLoc); this.setSize(offScreenCanvasSize); newSize = offScreenCanvasSize; newPosition = offScreenCanvasLoc; // Issue 131: create event catchers for auto-offScreen if (!manualRendering) { eventCatcher = new EventCatcher(this); canvasViewEventCatcher = new CanvasViewEventCatcher(this); } } else { GraphicsDevice graphicsDevice; graphicsDevice = graphicsConfiguration.getDevice(); eventCatcher = new EventCatcher(this); canvasViewEventCatcher = new CanvasViewEventCatcher(this); synchronized(VirtualUniverse.mc.deviceScreenMap) { screen = (Screen3D) VirtualUniverse.mc. deviceScreenMap.get(graphicsDevice); if (screen == null) { screen = new Screen3D(graphicsConfiguration, offScreen); VirtualUniverse.mc.deviceScreenMap.put(graphicsDevice, screen); } } } lights = new LightRetained[VirtualUniverse.mc.maxLights]; frameCount = new int[VirtualUniverse.mc.maxLights]; for (int i=0; i<frameCount.length;i++) { frameCount[i] = -1; } // Construct the drawing surface object for this Canvas3D drawingSurfaceObject = Pipeline.getPipeline().createDrawingSurfaceObject(this); // Get double buffer, stereo available, scene antialiasing // flags from graphics config GraphicsConfigTemplate3D.getGraphicsConfigFeatures(this); useDoubleBuffer = doubleBufferEnable && doubleBufferAvailable; useStereo = stereoEnable && stereoAvailable; useSharedCtx = VirtualUniverse.mc.isSharedCtx; // Issue 131: assert that only an off-screen canvas can be demand-driven assert (!offScreen && manualRendering) == false; // Assert that offScreen is *not* double-buffered or stereo assert (offScreen && useDoubleBuffer) == false; assert (offScreen && useStereo) == false; } /** * This method overrides AWT's handleEvent class... */ void sendEventToBehaviorScheduler(AWTEvent evt) { ViewPlatform vp; if ((view != null) && ((vp = view.getViewPlatform()) != null)) { VirtualUniverse univ = ((ViewPlatformRetained)(vp.retained)).universe; if (univ != null) { univ.behaviorStructure.handleAWTEvent(evt); } } } /** * Method to return whether or not the Canvas3D is recursively visible; * that is, whether the Canas3D is currently visible on the screen. Note * that we don't directly use isShowing() because that won't work for an * auto-offScreen Canvas3D. */ private boolean isRecursivelyVisible() { Container parent = getParent(); return isVisible() && parent != null && parent.isShowing(); } /** * Method to return whether the top-level Window parent is iconified */ private boolean isIconified() { if (windowParent instanceof Frame) { return (((Frame)windowParent).getExtendedState() & Frame.ICONIFIED) != 0; } return false; } // Issue 458 - evaluate this Canvas3D's visibility whenever we get a // Window or Component Event that could change it. void evaluateVisiblilty() { boolean nowVisible = isRecursivelyVisible() && !isIconified(); // Only need to reevaluate and repaint if visibility has changed if (this.visible != nowVisible) { this.visible = nowVisible; evaluateActive(); if (nowVisible) { if (view != null) { view.repaint(); } } } } /** * This version looks for the view and notifies it. */ void redraw() { if ((view != null) && active && isRunning) { view.repaint(); } } /** * Canvas3D uses the paint callback to track when it is possible to * render into the canvas. Subclasses of Canvas3D that override this * method need to call super.paint() in their paint method for Java 3D * to function properly. * @param g the graphics context */ public void paint(Graphics g) { if (!firstPaintCalled && added && validCanvas && validGraphicsMode()) { try { newSize = getSize(); newPosition = getLocationOnScreen(); } catch (IllegalComponentStateException e) { return; } synchronized (drawingSurfaceObject) { drawingSurfaceObject.getDrawingSurfaceObjectInfo(); } firstPaintCalled = true; visible = true; evaluateActive(); } redraw(); } // When this canvas is added to a frame, this notification gets called. We // can get drawing surface information at this time. Note: we cannot get // the X11 window id yet, unless it is a reset condition. /** * Canvas3D uses the addNotify callback to track when it is added * to a container. Subclasses of Canvas3D that override this * method need to call super.addNotify() in their addNotify() method for Java 3D * to function properly. */ public void addNotify() { // Return immediately if addNotify called twice with no removeNotify if (addNotifyCalled) { return; } addNotifyCalled = true; // Issue 131: This method is now being called by JCanvas3D for its // off-screen Canvas3D, so we need to handle off-screen properly here. // Do nothing for manually-rendered off-screen canvases if (manualRendering) { return; } Renderer rdr = null; if (isRunning && (screen != null)) { // If there is other Canvas3D in the same screen // rendering, stop it before JDK create new Canvas rdr = screen.renderer; if (rdr != null) { VirtualUniverse.mc.postRequest(MasterControl.STOP_RENDERER, rdr); while (!rdr.userStop) { MasterControl.threadYield(); } } } // Issue 131: Don't call super for off-screen Canvas3D if (!offScreen) { super.addNotify(); } screen.addUser(this); // Issue 458 - Add the eventCatcher as a component listener for each // parent container in the window hierarchy assert containerParentList.isEmpty(); windowParent = null; Container container = this.getParent(); while (container != null) { if (container instanceof Window) { windowParent = (Window)container; } container.addComponentListener(eventCatcher); container.addComponentListener(canvasViewEventCatcher); containerParentList.add(container); container = container.getParent(); } this.addComponentListener(eventCatcher); this.addComponentListener(canvasViewEventCatcher); if (windowParent != null) { windowParent.addWindowListener(eventCatcher); } synchronized(dirtyMaskLock) { cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY; cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY; } allocateCanvasId(); validCanvas = true; added = true; // Since we won't get a paint call for off-screen canvases, we need // to set the first paint and visible flags here. We also need to // call evaluateActive for the same reason. if (offScreen) { firstPaintCalled = true; visible = true; evaluateActive(); } // In case the same canvas is removed and add back, // we have to change isRunningStatus back to true; if (isRunning && !fatalError) { isRunningStatus = true; } ctxTimeStamp = 0; if ((view != null) && (view.universe != null)) { view.universe.checkForEnableEvents(); } if (rdr != null) { // Issue 84: Send a message to MC to restart renderer // Note that this also obviates the need for the earlier fix to // issue 131 which called redraw() for auto-off-screen Canvas3Ds // (and this is a more robust fix) VirtualUniverse.mc.postRequest(MasterControl.START_RENDERER, rdr); while (rdr.userStop) { MasterControl.threadYield(); } } } // When this canvas is removed a frame, this notification gets called. We // need to release the native context at this time. The underlying window // is about to go away. /** * Canvas3D uses the removeNotify callback to track when it is removed * from a container. Subclasses of Canvas3D that override this * method need to call super.removeNotify() in their removeNotify() * method for Java 3D to function properly. */ public void removeNotify() { // Return immediately if addNotify not called first if (!addNotifyCalled) { return; } addNotifyCalled = false; // Do nothing for manually-rendered off-screen canvases if (manualRendering) { return; } Renderer rdr = null; if (isRunning && (screen != null)) { // If there is other Canvas3D in the same screen // rendering, stop it before JDK create new Canvas rdr = screen.renderer; if (rdr != null) { VirtualUniverse.mc.postRequest(MasterControl.STOP_RENDERER, rdr); while (!rdr.userStop) { MasterControl.threadYield(); } } } // Note that although renderer userStop is true, // MasterControl can still schedule renderer to run through // runMonotor(RUN_RENDERER_CLEANUP) which skip userStop // thread checking. // For non-offscreen rendering the following call will // block waiting until all resources is free before // continue synchronized (drawingSurfaceObject) { validCtx = false; validCanvas = false; } removeCtx(); Pipeline.getPipeline().freeDrawingSurface(this, drawingSurfaceObject); // Clear first paint and visible flags firstPaintCalled = false; visible = false; screen.removeUser(this); evaluateActive(); freeCanvasId(); ra = null; graphicsContext3D = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -