4 Replies Latest reply: Apr 28, 2011 1:15 PM by 858165 RSS

    postRender issues

    858165
      Hello All,

      I am attempting to do an overlay on top of a Canvas3D, but it seems that the perimeter of my overlay is getting clipped away (or something eliciting that effect is occurring). A screenshot of my application is here:

      http://www.cse.ohio-state.edu/~harveywi/clip.png

      The right-most panel has some white things drawn in it using the following postRender method. The code is written in scala; I hope it is not too cryptic:
                override def postRender(): Unit = {
                     val g2d = getGraphics2D()
      //               g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
                     g2d.setColor(Color.white)
                     val stroke = new java.awt.BasicStroke
                     for (x <- 0 until 300 by 25) {
                          g2d.drawString("HELLO", 10, x)
                          g2d.setStroke(new java.awt.BasicStroke(4))
                          val rect = new Rectangle2D.Double(x+4, getHeight() - 404, 20-4, 400)
                          g2d.draw(rect)
                     }
                     g2d.flush(true)
                }
      The text appears to render correctly, but the left-most and right-most rectangles are missing some of their sides. Also, the bottoms of the rectangles are cut off. If I change the stroke width to zero then the edges get completely eaten away. Any idea what is going on?

      Thanks!
        • 1. Re: postRender issues
          858165
          Hoorah, I figure out how to get this to work. Instead of drawing directly to the Canvas3D's J3DGraphics2D, I create a compatible BufferedImage with transparency, draw all of my 2D things on that image, then draw the image onto the canvas. As a bonus, I can cut down on the amount of 2D drawing that I have to do by updating that 2D image only when necessary.

          Here is the updated code if anyone is interested. The GraphicsUtilities class referenced here is from the most excellent code provided with the book Filthy Rich Clients by Chet Haase and Romain Guy. Obviously, creating and re-drawing to the transparent image within the postRender method won't be all that efficient, but it does the right thing. The next thing I plan to do is yank that code out of the postRender method and only redraw the transparent image when necessary.
                    override def postRender(): Unit = {
                         
                         val img = GraphicsUtilities.createTranslucentCompatibleImage(500, 500)
                         val g2d = img.createGraphics()
                         
                         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
                         g2d.setColor(Color.white)
                         val stroke = new java.awt.BasicStroke
                         for (x <- 0 until 300 by 25) {
                              g2d.drawString("HELLO2", 10, x)
                              g2d.setStroke(new java.awt.BasicStroke(1))
                              val rect = new RoundRectangle2D.Double(x+4, img.getHeight() - 204, 20-4, 200, 5, 5)
          //                    g2d.drawRect(x+4, img.getHeight() - 204, 20-4, 200)
                              g2d.draw(rect)
                         }
                         
                         getGraphics2D().drawAndFlushImage(img, 0, 0, null)
                    }
          • 2. Re: postRender issues
            858165
            Hmm, it seems that the problem still persists even after the above changes. Only half of my colorbar is appearing in the image here: http://www.cse.ohio-state.edu/~harveywi/clip2.png

            The bottom half of the colorbar seems to appear when I resize the window, but when I finish resizing the bottom half disappears. Any idea what is going on?

            Thanks!
            • 3. Re: postRender issues
              InteractiveMesh
              Hi,

              your code runs fine in the Java Swing environment as well as in the Scala Swing environment if applied to a lightweight Scala Swing Component.

              But I can reproduce your issue when the overlay code runs on top of a heavyweight Canvas3D in Scala Swing.

              As you assumed, the region of the overlay which has to be painted will not be determined correctly with the consequence that pixels get lost. After digging into 'javax.media.j3d.J3DGraphics2DImpl' my assumption is that the Scala Java compiler treats a BufferedImage's Graphics2D object differently concerning rounding. This is just a guess, because I found a work around for your issue.

              The rectangles will be painted correctly if the 'dirty' region is invisibly marked close to the lower and upper corner before the rectangles are drawn.
              import java.awt.BasicStroke
              import java.awt.geom.Rectangle2D
              
              override def postRender(): Unit = {
                            
                val g2d = getGraphics2D()
              
                val height = getHeight()
              
                g2d.setColor(Color.YELLOW)
              
                // Work around: 
                // draw an invisible rectangle of 'empty' size at the lower and 
                // upper corner of the union of all Rectangle2Ds, this will mark this
                // area as 'dirty' region correctly
                g2d.setStroke(new BasicStroke(0f))
                g2d.draw(new Rectangle2D.Float(0, height - 406, 0, 0))
                g2d.draw(new Rectangle2D.Float(310, height, 0, 0))
              
                g2d.setStroke(new BasicStroke(4f))
              
                for (x <- 0 until 300 by 25) {                                        
                  val rect = new Rectangle2D.Float(x+4, height - 404, 20-4, 400)
                  g2d.draw(rect)
                }
              
                g2d.flush(true)
              }       
              Screen shot: http://www.interactivemesh.org/off/img/Canvas3DOverlayRectangles.png

              Give it a try, August
              • 4. Re: postRender issues
                858165
                Thank you very much August for looking into this! I can't tell you how much I appreciate it. I tested your workaround on my setup and everything works perfectly. I suspected that there might be some problem with the dirty region not being updated properly, but I was really stumped when the image overlays were cut in half. Again, thank you for taking the time and effort to look into this. You just saved me a ton of time and headaches.

                Best,

                William Harvey