|
|
||
Chris Campbell's BlogJuly 2006 ArchivesJava 2D Trickery: Light and ShadowPosted by campbell on July 27, 2006 at 04:20 PM | Permalink | Comments (5)Note: The code snippets in this blog entry are intended to be used with Scott Violet's nifty Interactive Graphics Editor. Just cut and paste the code into that application, et voila: instant gratification. This allows you to tinker with the code and immediately see how your changes affect the rendering. In the first installment of my "Trickery" series, I demonstrated a technique for achieving a soft clipping effect. Now let's put it to good use. In this installment I'll show how to add a lighting effect to give your otherwise flat shapes a 3D-ish appearance. If you like your literature illustrated, perhaps a picture will help. I'll show you how to go from the boring, flat shape on the left to the slightly less boring, glossy shape on the right:
With the right colors, you can use this technique to simulate a colored light shining across your shape, producing a subtle glow. How do we achieve this effect? Check out the code below; the comments above the
Note that I've left a few "alternate" lines of code commented out in the example above. Feel free to try uncommenting those lines in IGE and see how they affect the rendering.
Bonus: Astute readers may notice that the same technique used in the Here's some more code you can insert into the above example to add a shadow border to that same shape:
And here's the resulting image:
Note that this is just a quick attempt at adding a drop shadow for demonstration purposes. If I wasn't so lazy, I'd probably use a lighter gray color and a non-linear ramp to achieve a more realistic effect. Also note that this is just one of many ways to add a drop shadow using Java 2D. Romain has discussed different drop shadow implementations in his blog here and here. The SwingLabs folks have a In the next installment of my "Trickery" series, I'll move away from low-level Java 2D effects and show you how to add animations to your applications using the SwingX Painters API and Chet's Timing Framework [tm]. In the meantime, let's see if Josh and Richard pick up the slack and turn some of the above code into stock painters (nudge nudge).
In my ears: Wire, "Chairs Missing" [for about the 3 billionth time in my life]
Five More Easy PiecesPosted by campbell on July 21, 2006 at 01:52 PM | Permalink | Comments (16)I'm sure you're all sick of reading my blogs at this point, because each time I state definitively that the OpenGL-based Java 2D pipeline is "now better than ever," only to follow it up a couple months later with a blog that says, "no really, this time it's even better," and so on. It reminds me of a nearby store called "Cheaper Then Cheaper Cigarettes" [sic]; can you really improve on "cheaper" like that? Anyway, at the risk of sounding like the boy who cried wolf, as of Mustang b92, the OGL pipeline is now "better than better", one might even say it's superfantastic. In the spirit of my recent "Five Easy Pieces" entry, here are five more reasons why the OGL pipeline is better than ever...
OGL: scrolling is extremely slow on Nvidia boards
This bug frustrated me for a number of months, but I was confident that the Nvidia driver engineers would be able to come up with a solution as they've done with so many other issues. Unfortunately, the problem is specific to the way data is laid out in texture memory on certain Nvidia hardware, so a simple driver fix wasn't possible. However, they were kind enough to offer a (somewhat odd) workaround of using the GL_ARB_texture_rectangle extension, since rectangular textures are laid out more efficiently on said hardware and therefore do not exhibit the performance issues reported in this bug. It took quite a bit of work, but the good news is that we were able to get support for the GL_ARB_texture_rectangle extension implemented for b92, so scrolling/dragging performance is back to normal on Nvidia hardware, for both pbuffers and framebuffer objects (FBOs). As an added bonus, the use of that extension allows us to use less texture memory since we no longer have to pad up to power-of-two sized textures on older hardware. (This is what Michael Scott would call a "win win win" situation.)
OGL: enable sun.java2d.opengl.fbobject by default
Another big benefit in fixing the previous scrolling performance bug is that it removed the last big barrier that prevented us from enabling the FBO codepath by default. (I mentioned the FBO codepath in a blog entry from last autumn. Note that since then, Ken Russell and I managed to get JOGL's GLJPanel working with the FBO codepath, so that is no longer a barrier.) So as of b92, we've enabled the FBO codepath by default, which has many benefits when compared to the existing pbuffer-based codepath:
If you've been been bitten by the OGL pipeline in the past (especially those folks with ATI hardware), I'd highly recommend installing b92 for this change alone.
OGL: use new AffineTransform methods in enableGradientPaint()
This one's not terribly exciting... Just a three-line change, but I wanted to mention it in case folks are not aware of some new convenience methods added to the AffineTransform class in Mustang. The first is AffineTransform.invert(), which is useful in those cases where you want to invert the transform matrix in place (hence no need to create a new AffineTransform object). The second is AffineTransform.rotate(vecx, vecy), which is helpful when you want to rotate about a vector (instead of using a relative angle value). In this particular case, the old code was not a major bottleneck in the gradient/texture acceleration path, so there wasn't a huge performance benefit. However, if you have some code that exercises AffineTransform heavily, you might want to check to see if these new methods give you a boost.
OGL: accelerate Gradient/TexturePaint when antialiasing is enabled
This one is terribly exciting, to me at least. We've had some nifty acceleration for GradientPaint and TexturePaint since the OGL pipeline was introduced in JDK 5, but it always came with the caveat that only non-antialiased primitives were accelerated. But as of Mustang b92, we've figured out a way to use multitexturing to combine the gradient/texture acceleration code with our existing antialiased rendering code, which means GradientPaint and TexturePaint are now fully accelerated by the OGL pipeline, regardless of whether antialiasing is enabled. The bug report has more details, but I'll include the executive summary here, because the numbers speak for themselves:
OGL: overlapping LCD glyphs not rendered properly
This was a visible problem caused by an obscure bug, but fortunately the fix was easy. It was the last known problem with the LCD text acceleration code mentioned in my last blog on the subject, and the driver bugs mentioned there have since been fixed as well.
So if you're a fan of LCD text (meaning everyone but Scott, wink wink) and you have shader level hardware (Nvidia GeForce FX/6/7 series, ATI Radeon 9500 and up, etc), please try Bonus: The Driver Report As I've mentioned in past blogs, we've been working with driver teams from Nvidia, ATI, and Sun to ensure that any remaining driver issues are resolved by the time Mustang ships. We have updated our basic acceptance test (BAT) suite with over 50 tests that said driver teams can use to prevent the introduction of new regressions and to test that their existing drivers work well with our OpenGL-based pipeline. For the past couple years, ATI's drivers have been in a sad state of affairs w.r.t. our OGL pipeline (lots of crashes and rendering artifacts). However, I'm now happy to report that ATI has fixed the remaining Linux-specific OpenGL driver bugs that affect our OGL pipeline, so our BAT suite now runs without failure on their forthcoming 8.27 series release. If you're a Linux user with ATI hardware, I'd suggest upgrading to 8.27 when it becomes available in the next couple weeks. As for ATI's OpenGL drivers for Windows, some bugs remain and we are continuing to push those with ATI. But as I mentioned above, the change in b92 that makes the FBO codepath the default means that most of those bugs are no longer reproducible for most newer boards. On the Nvidia and Sun fronts, things are looking really good. There were a couple driver bugs found recently on certain Nvidia laptop GPUs that have since been fixed. If your laptop has an Nvidia GPU and you've been seeing weird artifacts when enabling the OGL pipeline, please install Nvidia's 95.xx series driver when it becomes available in the near future.
In my ears: Viktor Vaughn, "Vaudeville Villain"
Java 2D Trickery: Soft ClippingPosted by campbell on July 19, 2006 at 10:59 PM | Permalink | Comments (10)Note: The code snippets in this blog entry are intended to be used with Scott Violet's nifty Interactive Graphics Editor. Just cut and paste the code into that application, et voila: instant gratification. This allows you to tinker with the code and immediately see how your changes affect the rendering. If you're familiar with Java 2D, you probably already know that you can clip out a portion of your rendering with any arbitrary shape. (If not, go check out the Java Tutorial.) For example, you can give the illusion of someone shining a flashlight on your application by setting a circular clip and then rendering your scene normally. When you clip using a complex shape, you will typically see jaggies around the edges of the region being clipped, which can uglify your app. To illustrate the effect that I'll call "hard clipping", try the following example:
Here's the resulting image:
Wouldn't it be nice if you could antialias those hard edges to remove the jaggies caused by clipping? Well, unfortunately Java 2D (or at least Sun's current implementation) does not support "soft clipping." Sidebar: I add the caveat about Sun's implementation because I was surprised to find that when I tried the above code on my Mac, there were no jaggies! What's going on here? Well, it turns out that Apple's Java 2D implementation uses Quartz under the hood, which appears to do soft clipping by default. In Mustang, Apple is planning to use Sun's software renderer instead of their Quartz renderer by default, so the tips in this blog entry should be relevant for Macs as well. You'd think there would be a RenderingHint to control this behavior, but sorry, no such luck. A few developers have asked for soft clipping in the past, but it doesn't seem to be common enough to warrant adding support for it in our implementation. (I was going to say that it's too much work, and it probably would be, but then my esteemed readers would probably say "well if Apple could implement it in Quartz, why can't you?" Damn those show-offs at Apple. But I digress...)
Fortunately, we've found a fairly simple way to achieve a soft clipping effect using an intermediate image (see Chet's article on that subject) and a little known
Compare the resulting image to the jaggy one above:
Looks better, no? I'll admit that this example is a bit contrived, and it might be hard to see the real world applicability. In the next installment of my "Trickery" series, I'll show you how to apply this technique when creating a lighting effect for arbitrary shapes.
In my ears: Asobi Seksu, "Citrus" [just got back from their show at the Bowery Ballroom no less]
| ||
|
|