Re: [JAVA2D] Optimizing concentric arcs
YES! Why not FPU acceleration? That's what it's there for. Er... is StrictMath already FPU accelerated? If it is then, oh well... The current Math package is really not very good. Especially for low level graphics stuff where 5 significant digits is the minimum accuracy that is useful. [EMAIL PROTECTED] wrote: I've wanted to gripe about the slowness and inaccuracy of the Math package but who do I talk to? I totally agree. It would be great if the programmer could choose between the StrictMath implementation which is hard-wired now and maybe something like, call ist FastMath. FastMath could be implemented without any guarantees, and really 1:1 instrified in hotspot to a corresponding CPU instruction if there is any, that would be really cool :) lg Clemens [Message sent by forum member 'linuxhippy' (linuxhippy)] http://forums.java.net/jive/thread.jspa?messageID=301657 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help". === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
Well, lets clarify/assume a few things. You have some data source, constantly producing data, right? While that data source happily produces data the user is also looking at a representation of that data, right? And the user can interactively select (scrolling, zooming) which portion of the data he/she gets a representation of? Ok, first, I am not a big fan of rendering and rasterizing (drawing to an image) the data in the backgrond in such a case. For at least two reasons: Zooming on already rasterized data doesn't work well, so for zooming it is required to freshly rasterize that data. Second, if the plot is indeed very large you can not fully predict to which area the user might scroll next. So you can't reasonably well guess which area should be preferentially rendered in the background. Because of this two issues, a lot of CPU power used for background rendering is just wasted, since you render something you can't use. So, instead of rendering in the background, organize/store the incomming data in a way that it is easy to render in the background (in a thread). This, for example, might include to already decompose the data into primitive graphic elements like lines. You don't actually draw such lines, you just store easy to process information that you would draw a line. And provide a locking mechanism on the data, so that the maintenance of the data and the rendering (see below) are properly synchronized. Further, if the plot is really so large, spatially organize that graphic element data in the background in a way that you can quickly find all data within a particular rectangular 2D region (quadtree). If you have many overlapping graphic elements you might even want to organize the data in three dimensions (octree), so that you can easily cull details when the user has zoomed out very fare (because in this case many details would anyhow be lost when rendering the data). Now to the user interaction and actual rendering. You create an own Swing component based on a JComponent or JPanel. Creating an own Swing component has often been document, I won't go into this. Just make sure you get the basics and the nastier details right :-) Also implement the Scrollable interface. I assume you put that component in a JScrollPane. The paintComponent() method of your component will be called when Swing thinks your component or a part of your component needs to be redrawn. The key here is "part of your component". Swing indicates what part needs to be redrawn with the clipping region (don't forget to take the Graphics2D origin into account, it might not always be 0,0). So in your paintComponent() you use that information (and the current zoom factor) to identify the part of your graphic element data that needs rendering. That part should be much less then your whole data. Then, right in paintComponent() you render it to the provided Graphics2D. I assume you have some extra buttons for zooming in or out (or some mouse events). Anyhow, whenever the zoom factor changes you remember the new zoom factor, then call repaint(). At some point in time repaint() will result in a call to paintComponent(). And since your paintComponent() takes the zoom factor into account (well, it should), it will render the plot with the new zoom factor. Also, whenever the incomming data has changed significantly, you call repaint, too. Don't do it to often, and don't do it for every tiny change. Accumulate a bunch of changes, then call repaint(). However, if you really think you need 15fps and every tiny change in the data needs to be immediately visible, than forget everything I wrote and change to active rendering. That's the basic architecture. If that is still not responsive enough, consider caching the renderings you did in paintComponent() in BufferedImages. And before you render some area you check your cache if you have already all or parts of that area in your cache. If you have, you just copy that part from the cache to the screen. You need proper cache management, like remembering which zoom factor was used for a particular rendering, or if the incoming data would invalidate a cached rendering. Careful planning, a well designed data structure, knowing Swing's paint mechanism (with all its barely documented idiosyncrasies), a clear understanding of world, component and screen coordinate systems, and probably a thousand odds and ends are needed to make this fly. Or you drop that Java2D junk, where you are never sure if you get hardware acceleration or not, and use some commercial data visualization system or write directly for a particular OS and native graphics system, so you are not at the mercy of a VM with rubbish documentation. [Message sent by forum member 'ewin' (ewin)] http://forums.java.net/jive/thread.jspa?messageID=301687 === To unsubscribe, send email to [EMAIL PROTECTED] and in
[JAVA2D] Long-running rendering ...was Re: Drawing to an off screen buffer
I'm starting think my problem is knowing what solution applies to my situation. There are plenty of solutions for handling long-running tasks in Swing. (SwingWorker, etc.) There are solutions for double buffering for animations (BufferStrategy). But, I don't think either of those apply to long-running rendering tasks. Maybe a solution to that would be to drip-feed little subtasks onto the event queue such that there is only one rendering task on the queue at a time and user events will be interleaved in the queue between rendering tasks. Any other ideas or examples for maintaining a responsive UI in the presence of long-running rendering tasks? Thanks, -chris [Message sent by forum member 'cbare' (cbare)] http://forums.java.net/jive/thread.jspa?messageID=301678 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
I recommend using something similar to the Foxtrot API. It is not recommended to perform time intensive processes in the event queue. [Message sent by forum member 'bcorbett8769' (bcorbett8769)] http://forums.java.net/jive/thread.jspa?messageID=301665 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Optimizing concentric arcs
> I've wanted to gripe about the slowness and > inaccuracy of > the Math package but who do I talk to? I totally agree. It would be great if the programmer could choose between the StrictMath implementation which is hard-wired now and maybe something like, call ist FastMath. FastMath could be implemented without any guarantees, and really 1:1 instrified in hotspot to a corresponding CPU instruction if there is any, that would be really cool :) lg Clemens [Message sent by forum member 'linuxhippy' (linuxhippy)] http://forums.java.net/jive/thread.jspa?messageID=301657 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
You can render in a different thread. I do in my viewers and they remain responsive. http://pancyl.com/LakeMary_1.htm [EMAIL PROTECTED] wrote: Thanks for all the hints. The frame rate I'm getting using invokeLater is very slow (~5 seconds per frame). And, the event dispatch thread gets clogged with lots of rendering tasks and becomes unresponsive. So, that's no good. My rendering is happening in response to user actions - scrolling, zooming, and mouse selections. My goal for the UI to remain responsive even if rendering takes several seconds. [Message sent by forum member 'cbare' (cbare)] http://forums.java.net/jive/thread.jspa?messageID=301639 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help". === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Optimizing concentric arcs
My panorama viewers use a lot of the Math methods. They are really slow and not all that precise. http://pancyl.com/SittingRoom.htm The trig functions are inaccurate near a multiple of PI and zero. So much so that I have to check against an Epsilon value and if the absolute returned value is less than Epsilon then I manually set the value I need. I also had to develop -- with some help -- an approximation calculation for atan2() and I use a lookup table for asin(). I've found that lookup tables are not all that great near a multiple of PI especially if you are trying to use a look up table for tan/atan. They change very fast near their asymptote. I use lookup tables "in the middle" but revert to the real method near the poles with an Epsilon check. I've wanted to gripe about the slowness and inaccuracy of the Math package but who do I talk to? [EMAIL PROTECTED] wrote: Is there an alternate, faster way to do the maths? The problem here is Math.round and Math.atan2, the Math class is optimized for high precission but often sacrifices speed. Your original version took 205ms on my C2D, replacing atan2 with this unprecise version and removing the round braught it down to 35ms. Be sure to use the server-runtime if possible, it gave me a solid 40% speed boost :) [code] private final double aTan2(double y, double x) { double coeff_1 = Math.PI / 4d; double coeff_2 = 3d * coeff_1; double abs_y = Math.abs(y); double angle; if (x >= 0d) { double r = (x - abs_y) / (x + abs_y); angle = coeff_1 - coeff_1 * r; } else { double r = (x + abs_y) / (abs_y - x); angle = coeff_2 - coeff_1 * r; } return y < 0d ? -angle : angle; } [/code] However that method seems to be very unprecise, a slightly better looking result can be archived using this lookup-table based implementation, however its slower (45ms): [code] package waterfall; public class TableMath { private static final int TABLE_SIZE = 1; static double[] atanTable = initAtanTable(); private static double[] initAtanTable() { double[] table = new double[TABLE_SIZE]; for(int i=0; i < TABLE_SIZE; i++) { table[i] = Math.atan(((double)i) / TABLE_SIZE); } return table; } private static double atan_1(int y,int x) { int index; int vorz; double erg = 0; vorz = 1; if (((x < 0) && (y < 0)) || ((x > 0) && (y > 0))) {vorz = 0;} else x = -x; /*atan of y/x */ index =(int) (((y*(TABLE_SIZE-1)*10)/x+5)/10); //+5 for rounding erg = atanTable[index]; if (vorz == 0 ) return erg; else return -erg; } public static double atan2(int y, int x) { double result; if(Math.abs(x) > Math.abs(y)) result = atan_1(y,x); else { result = atan_1(x,y); if(result < 0) result = -Math.PI/2 - result; else result = Math.PI/2 - result; } if (x < 0) if(y < 0) result = result - Math.PI; else result = result + Math.PI; return result; } } [/code] I don't know if any of those two implementations fit your needs, but they are definitily faster ;) Another possible optimization would be multi-threading, so each thread could do a part of the total work - should be perfectly paralizeable. I am not sure if unsynchronized write-access is valid (if no one is reading), but I guess it is. That would bring the fastest version down to 20ms on my machine :) lg Clemens [Message sent by forum member 'linuxhippy' (linuxhippy)] http://forums.java.net/jive/thread.jspa?messageID=301636 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help". === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
Thanks for all the hints. The frame rate I'm getting using invokeLater is very slow (~5 seconds per frame). And, the event dispatch thread gets clogged with lots of rendering tasks and becomes unresponsive. So, that's no good. My rendering is happening in response to user actions - scrolling, zooming, and mouse selections. My goal for the UI to remain responsive even if rendering takes several seconds. [Message sent by forum member 'cbare' (cbare)] http://forums.java.net/jive/thread.jspa?messageID=301639 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
Looking at some BufferStrategy examples, it seems that the pattern is to do rendering in a timed loop, something like this: [code] // Render loop while (!done) { Graphics g = strategy.getDrawGraphics(); render(g); g.dispose(); strategy.show(); try { Thread.sleep(100); } catch (InterruptedException e) { done=true; } } [/code] I'm drawing in response to UI events (scrolling, zooming, mouse clicks for selecting objects). Does that mean BufferStrategy is not for my situation? Pointers to examples would be great. Thanks, -chris [Message sent by forum member 'cbare' (cbare)] http://forums.java.net/jive/thread.jspa?messageID=301637 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Optimizing concentric arcs
> Is there an alternate, faster way to do the maths? The problem here is Math.round and Math.atan2, the Math class is optimized for high precission but often sacrifices speed. Your original version took 205ms on my C2D, replacing atan2 with this unprecise version and removing the round braught it down to 35ms. Be sure to use the server-runtime if possible, it gave me a solid 40% speed boost :) [code] private final double aTan2(double y, double x) { double coeff_1 = Math.PI / 4d; double coeff_2 = 3d * coeff_1; double abs_y = Math.abs(y); double angle; if (x >= 0d) { double r = (x - abs_y) / (x + abs_y); angle = coeff_1 - coeff_1 * r; } else { double r = (x + abs_y) / (abs_y - x); angle = coeff_2 - coeff_1 * r; } return y < 0d ? -angle : angle; } [/code] However that method seems to be very unprecise, a slightly better looking result can be archived using this lookup-table based implementation, however its slower (45ms): [code] package waterfall; public class TableMath { private static final int TABLE_SIZE = 1; static double[] atanTable = initAtanTable(); private static double[] initAtanTable() { double[] table = new double[TABLE_SIZE]; for(int i=0; i < TABLE_SIZE; i++) { table[i] = Math.atan(((double)i) / TABLE_SIZE); } return table; } private static double atan_1(int y,int x) { int index; int vorz; double erg = 0; vorz = 1; if (((x < 0) && (y < 0)) || ((x > 0) && (y > 0))) {vorz = 0;} else x = -x; /*atan of y/x */ index =(int) (((y*(TABLE_SIZE-1)*10)/x+5)/10); //+5 for rounding erg = atanTable[index]; if (vorz == 0 ) return erg; else return -erg; } public static double atan2(int y, int x) { double result; if(Math.abs(x) > Math.abs(y)) result = atan_1(y,x); else { result = atan_1(x,y); if(result < 0) result = -Math.PI/2 - result; else result = Math.PI/2 - result; } if (x < 0) if(y < 0) result = result - Math.PI; else result = result + Math.PI; return result; } } [/code] I don't know if any of those two implementations fit your needs, but they are definitily faster ;) Another possible optimization would be multi-threading, so each thread could do a part of the total work - should be perfectly paralizeable. I am not sure if unsynchronized write-access is valid (if no one is reading), but I guess it is. That would bring the fastest version down to 20ms on my machine :) lg Clemens [Message sent by forum member 'linuxhippy' (linuxhippy)] http://forums.java.net/jive/thread.jspa?messageID=301636 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
Do you get reasonable animation with this method? How many frames a second do you get using invokeLater()? [EMAIL PROTECTED] wrote: You don't need a BufferStrategy or VolatileImage unless you are doing live animation. It was hard to tell from your message if that was the case. I usually use a BufferedImage that you get from createCompatibleImage and draw using Java2D to the graphics context you get from it. When the plot is ready hand it over to the event dispatch thread and tell some component to paint it with invokeLater(). Otherwise look for examples that use BufferStrategy... [Message sent by forum member 'swpalmer' (swpalmer)] http://forums.java.net/jive/thread.jspa?messageID=301594 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help". === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
I wouldn't be comfortable using a BufferStrategy outside of the event thread. That's mainly useful for reducing flicker in animations, anyway. If you have your heart set on rendering outside the event thread, a BufferedImage is the only option I would trust. Even then, you need to make sure that you are synchronizing correctly. Also, we should be clear that multithreading like this will *not* make your program faster (in fact, it will probably slow it down in this case). What it will accomplish is that it will allow the program to continue accepting user input while the drawing occurs. [Message sent by forum member 'afishionado' (afishionado)] http://forums.java.net/jive/thread.jspa?messageID=301628 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
Thanks swp. I'm drawing a long 2D plot. The user can scroll right and left along a very long X axis, and I'd like that to be responsive. I'm less concerned about rendering speed than responsiveness, but a high frame-rate certainly won't hurt either. So, my approach is to work on responsiveness first, and rendering speed later, which is why I want to do rendering off the event dispatch thread. Is it safe to share the BufferStrategy with another thread? If not, what's the proper way to handle a long-running rendering task? Thanks! [Message sent by forum member 'cbare' (cbare)] http://forums.java.net/jive/thread.jspa?messageID=301625 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
Use the Canvas if you need hardware double-buffering badly enough that you're willing to deal with the Z-ordering issues that you get from mixing Swing and AWT widgets. Otherwise, use a JPanel. You cannot use a Canvas inside of a JScrollPane, for one thing. Rendering outside of the event thread can be iffy. I wouldn't try using a VolatileImage outside the event thread, but a BufferedImage should work. One thing that we should make clear is that getting hardware acceleration (for things like blitting the image) and rendering outside the event thread will be pretty much mutually exclusive. (Unless you're doing some really deep AWT hacking.) Are we talking about rendering an animation, or rendering a graphic infrequently (say, in response to button clicks)? What you want to do really depends on the answer to that. [Message sent by forum member 'afishionado' (afishionado)] http://forums.java.net/jive/thread.jspa?messageID=301626 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Drawing to an off screen buffer
You don't need a BufferStrategy or VolatileImage unless you are doing live animation. It was hard to tell from your message if that was the case. I usually use a BufferedImage that you get from createCompatibleImage and draw using Java2D to the graphics context you get from it. When the plot is ready hand it over to the event dispatch thread and tell some component to paint it with invokeLater(). Otherwise look for examples that use BufferStrategy... [Message sent by forum member 'swpalmer' (swpalmer)] http://forums.java.net/jive/thread.jspa?messageID=301594 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] BufferedImage with transparent background
Hi Karys, On 25. sep.. 2008, at 10.16, [EMAIL PROTECTED] wrote: Nobody knows ? Nobody has the same problem ? [Message sent by forum member 'karys' (karys)] Did you try making your component transparent as suggested by Jim? You typically do this by calling setOpaque(false) for a JPanel, but I've heard that the "official" way form now on should be to set the background to a transparent color. Maybe you need to describe your problem in greater detail, because I you will get a transparent image from new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB). However, the background won't be transparent if you paint it white, or paint an image with a white background into it or similar. Also, if you paint your image into something that does't have a transparent background (like your panel for example), then it will not apear to be transparent, even though it technically is. Best regards, -- Harald K === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
[JAVA2D] Can someone please explain BufferedImages and premultiplied alpha?
Hi, I'm currently a little puzzled about how alpha premultiplication and BufferedImages work.. I'm implementing a reader for the Photoshop (PSD) format. From what I understand, this format uses color data with premultiplied alpha (is there a way to determine if data is premultiplied, looking at the data?). The way I read data, is first creating a BufferedImage of type TYPE_4BYTE_ABGR or TYPE_4BYTE_ABGR_PRE, then pushing the bytes into the databuffer directly (I know this might defeat some acceleration tricks, but I plan to deal with that later). Now, my first surprise is that neither of the above types seem to work: Both images are displayed with a white "halo" around the transparent parts (halo more visible with PRE version). I would think that if the data is really premultiplied, reading it to a TYPE_4BYTE_ABGR_PRE buffer should just work? Or, if the data was not premultiplied, TYPE_4BYTE_ABGR should work fine? So, my next surprise. As the halo is less visible in the non-PRE version, I go with that. But now my data does not match the color model's isPremultiplied state. So I figure I should use coerceData, right? I would think that getting a colormodel identical to the one I use with the isPremultiplied set to true, and then cm.coerceData(image.getRaster(), false) would do the trick. But this ends up with the semi-transparent parts being all cyan or magenta... So, just to see the difference, I tried using image.getColorModel().coerceData(image.getRaster(), true), which I believed would do exactly the opposite of what I wanted. But then that turned out to almost remove the haloes... Which leads me to the conclusion: I simply don't get it... If someone could explain where my logic or understanding is wrong I'd be very happy! Or simply describe the way to do it right would be more than good enough! ;-) Thanks in advance, -- Harald K [Message sent by forum member 'haraldk' (haraldk)] http://forums.java.net/jive/thread.jspa?messageID=301509 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] Optimizing concentric arcs
> A better optimized solution would be to look up for > the right color in setRGB depending on the angle of > the currently drawn pixel - this way you draw the > circle only once, altering the color is bascially > free :) > I modified the setRGB() method of your program as follows to get my optimized coloured concentrics arcs. Is there an alternate, faster way to do the maths? Thanks very much Ig for you input. [code] void setRGB(int x, int y, Color[] colors) { double angleInRadians = Math.atan2(y-cy, x-cx); double angle = angleInRadians < 0 ? Math.toDegrees(angleInRadians + (2*Math.PI)) : Math.toDegrees(angleInRadians); angle = Math.round(angle); angle = angle == 360 ? 0 : angle; int rgb = colors[(int)angle].getRGB(); int index = y * bimg.getWidth() + x; if (index < data.length) { data[index] = rgb; } } [/code] [Message sent by forum member 'ser207' (ser207)] http://forums.java.net/jive/thread.jspa?messageID=301499 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".
Re: [JAVA2D] BufferedImage with transparent background
Nobody knows ? Nobody has the same problem ? [Message sent by forum member 'karys' (karys)] http://forums.java.net/jive/thread.jspa?messageID=301487 === To unsubscribe, send email to [EMAIL PROTECTED] and include in the body of the message "signoff JAVA2D-INTEREST". For general help, send email to [EMAIL PROTECTED] and include in the body of the message "help".