Details

    • Issuezilla Id:
      645

      Description

      Hi,

      I had a lot of trouble working with offscreen rendering, especially under Linux where I can't avoid
      crashes for a few users. I need offscreen rendering in Sweet Home 3D to create images of the current
      3D view and to display furniture seen from top in parallel projection.
      As I know many drivers simply don't support offscreen rendering, I programmed a isOffScreenImageSupported method at
      http://sweethome3d.cvs.sf.net/viewvc/sweethome3d/SweetHome3D/src/com/eteks/sweethome3d/j3d
      /Component3DManager.java?revision=1.7&view=markup#l_103
      that could be inlined like this:

      public boolean isOffScreenImageSupported() {
      SimpleUniverse universe = null;
      Viewer viewer = null;
      Canvas3D offScreenCanvas = null;
      RenderingErrorListener renderingErrorListener = null;
      try {
      // Retrieve graphics configuration once
      GraphicsConfigTemplate3D gc = new GraphicsConfigTemplate3D();
      // Try to get antialiasing
      gc.setSceneAntialiasing(GraphicsConfigTemplate3D.PREFERRED);
      GraphicsConfiguration configuration = GraphicsEnvironment
      .getLocalGraphicsEnvironment().getDefaultScreenDevice()
      .getBestConfiguration(gc);
      if (configuration == null)

      { configuration = GraphicsEnvironment .getLocalGraphicsEnvironment().getDefaultScreenDevice() .getBestConfiguration(new GraphicsConfigTemplate3D()); }

      // Create a universe bound to no canvas 3D
      ViewingPlatform viewingPlatform = new ViewingPlatform();
      viewer = new Viewer(new Canvas3D [0]);
      universe = new SimpleUniverse(viewingPlatform, viewer);

      // Add a rendering error listener that counts down a latch
      // to check further if a rendering error happened during off
      // screen rendering (rendering error
      // listener is called from a notification thread)
      final CountDownLatch latch = new CountDownLatch(1);
      renderingErrorListener = new RenderingErrorListener() {
      public void errorOccurred(RenderingError error)

      { latch.countDown(); }

      };
      VirtualUniverse.addRenderingErrorListener(renderingErrorListener);

      // Create a dummy 3D image to check if it can be rendered
      // in current Java 3D configuration
      offScreenCanvas = new Canvas3D(configuration, true);
      // Configure canvas 3D for offscreen
      Screen3D screen3D = offScreenCanvas.getScreen3D();
      screen3D.setSize(1, 1);
      screen3D.setPhysicalScreenWidth(2f);
      screen3D.setPhysicalScreenHeight(2f);
      BufferedImage image = new BufferedImage(1, 1,
      BufferedImage.TYPE_INT_RGB);
      ImageComponent2D imageComponent2D =
      new ImageComponent2D(ImageComponent2D.FORMAT_RGB, image);
      imageComponent2D.setCapability(
      ImageComponent2D.ALLOW_IMAGE_READ);
      offScreenCanvas.setOffScreenBuffer(imageComponent2D);
      viewer.getView().addCanvas3D(offScreenCanvas);

      // Render off screen canvas
      offScreenCanvas.renderOffScreenBuffer();
      offScreenCanvas.waitForOffScreenRendering();

      // If latch count becomes equal to 0 during the past
      // instructions or in the coming 10 milliseconds,
      // this means that a rendering error happened
      if (latch.await(10, TimeUnit.MILLISECONDS))

      { return false; }

      offScreenCanvas.getOffScreenBuffer().getImage();
      return true;
      } catch (InterruptedException ex)

      { // Off screen rendering interrupted return false; }

      catch (IllegalRenderingStateException ex)

      { return false; } catch (NullPointerException ex) { return false; }

      catch (IllegalArgumentException ex)

      { return false; }

      finally {
      if (offScreenCanvas != null) {
      viewer.getView().removeCanvas3D(offScreenCanvas);
      try

      { // Free off screen buffer and context offScreenCanvas.setOffScreenBuffer(null); }

      catch (NullPointerException ex)

      { // Java 3D 1.3 may throw an exception }

      }
      if (renderingErrorListener != null)

      { VirtualUniverse.removeRenderingErrorListener( renderingErrorListener); }

      if (universe != null)

      { universe.cleanup(); }

      }
      }

      This test method works well except that sometimes it crashes (mostly under Linux).

      See bug report about this issue here:
      http://sourceforge.net/tracker/?func=detail&aid=2811829&group_id=152568&atid=784665
      and the following crash reports:
      http://sourceforge.net/tracker/download.php?
      group_id=152568&atid=784665&file_id=332261&aid=2811829

      This report is probably about the same issue:
      http://sourceforge.net/tracker/?func=detail&aid=2928601&group_id=152568&atid=784665

      For your information, Sweet Home 3D with default renderer can be run with
      http://www.sweethome3d.eu/SweetHome3D.jnlp
      Sweet Home 3D with DirectX renderer can be run with
      http://www.sweethome3d.eu/SweetHome3D-DirectX.jnlp

        Activity

        There are no comments yet on this issue.

          People

          • Assignee:
            java3d-issues
            Reporter:
            puybaret
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: