H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Posted
2005-03-04 01:06:14 » |
|
1 2 3 4 5 6 7 8 9
| Exception in thread "main" java.lang.NullPointerException at java.awt.geom.Area.<init>(Area.java:54) at sun.java2d.SunGraphics2D.intersectByArea(SunGraphics2D.java:628) at sun.java2d.SunGraphics2D.intersectShapes(SunGraphics2D.java:553) at sun.java2d.SunGraphics2D.clip(SunGraphics2D.java:2004) at Tracker.drawClippedImage(Tracker.java:475) at Tracker.render(Tracker.java:58) at JavaTactics.main_loop(JavaTactics.java:855) at JavaTactics.main(JavaTactics.java:87) |
and my drawClippedImage looks like this: 1 2 3 4 5
| public void drawClippedImage(Graphics2D g, String sck, int Xpx, int Ypx, int mapY) { g.clip(clips[mapY]); g.drawImage(j.sc.getImage(sck), Xpx, Ypx, null); g.clip(null); } |
here are some screenshots of the clip images: (areas are just filled and rendered to the screen right now)   My only guess is that the areas (created by area.add(tile.area)) are having some problems with clipping. I can make a clip with a normal rectangle... Any ideas?
|
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #1 - Posted
2005-03-04 02:38:40 » |
|
umm.... nevermind fixed it somehow... not sure how, but its working now!
|
|
|
|
|
trembovetski
|
 |
«
Reply #2 - Posted
2005-03-04 04:52:39 » |
|
you're not accessing the graphics object from different threads, are you?
|
|
|
|
|
Games published by our own members! Check 'em out!
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #3 - Posted
2005-03-04 10:50:33 » |
|
No. Instead I have some 3 rendering methods. 1: Do nothing, 2: ReRender the Actor Sprites 3: Render the Background image, and generate the clips
Then based on the return of my update() method run the the correct rendering...
Working great so far except one little problem: I can't seem to make areas have exact pixel values without having antialiased edges. I think that it might be caused by the internal storarage of the coorinates being double...
|
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #4 - Posted
2005-03-04 18:22:21 » |
|
I keep having the problem of not being able to get an area to cover by a per pixel basis. There are always antialiasing:  This is the basic tile:  Any ideas on how to make it not blur those edges? I've tried using rendering hints to turn off antialiasing, but no difference... I think that there is a way to dynamically gererate an area based on the transparency of a graphic with PixelGrabber... any help on how to change a BufferedImage to a area based on whether on not the pixels are transparent? Thanks!
|
|
|
|
|
Malohkan
|
 |
«
Reply #5 - Posted
2005-03-04 19:37:57 » |
|
why do you need to set clips at all? Why can't you just draw the tiles?
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #6 - Posted
2005-03-04 21:39:37 » |
|
This is how I'm working it: This is a Final Fantasy Tactics/Tactics Ogre clone. Tiles sit on top of blocks. When you go to draw actors, they have to be behind any blocks that are in front of him. So, I render everything in the Tile format, and make a new Area for every Y. Then, when I go to render a actor, I create a new area the size of the screen and subtract any areas that have a greater Y then the actors. When I do that, I get a clipped area so that it appears that the acctor is behind the blocking tiles. This prevents me from having to render the entire image, and allows me to draw just the Actors. With my current engine without clipping it looks like this: 
|
|
|
|
|
JuddMan
|
 |
«
Reply #7 - Posted
2005-03-05 07:20:27 » |
|
that looks very nice. if you are able, i'd really like to have a look at the whole source... also, what's the problem with the anti-aliasing? is it slow or is it making the edges look funny when in front of the actor?
|
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #8 - Posted
2005-03-06 02:56:53 » |
|
Its making the edges look funny. I found out that it is caused by Java2D storing the polygon as floating point coordinates. To get around this I started using the Rectangle class, but this is taking to long... I really need a way to use PixelGrabber to create an Area based off of an image's alpha channel.
Also, is there a way to translate an area?
Juddman: send me an email at: [backwards]moc.liamG AT snikpoh.m.ffej[/backwards] and I'll email you the source...
|
|
|
|
|
Linuxhippy
|
 |
«
Reply #9 - Posted
2005-03-06 16:57:27 » |
|
well, I would not use PixelGrabber since it destroys performance more or less...
|
|
|
|
|
Games published by our own members! Check 'em out!
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #10 - Posted
2005-03-06 17:30:58 » |
|
But I wouldn't be using it every frame. Once I created the area at startup, I could just store it and translate it when needed.
|
|
|
|
|
swpalmer
|
 |
«
Reply #11 - Posted
2005-03-07 02:25:29 » |
|
Re: anti-aliasing...
Have you tried setting rendering hints to force OFF anti-aliasing and perhaps LOWER render quality (use SPEED hints instead of QUALITY hints).
Just a shot in the dark...
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #12 - Posted
2005-03-07 02:47:26 » |
|
Yup, both. No success.  Thanks though!
|
|
|
|
|
Malohkan
|
 |
«
Reply #13 - Posted
2005-03-07 04:55:30 » |
|
anti-aliasing rendering hints do nothing for images. Those only affect Strokes or Shapes being drawn. What you want for your image to retain its anti-aliased quality is to save them as png's with full translucency. If the space around the isometric tile has a 0 for it's alpha value, you should never have any need for setting Clips or using Areas because when you draw with the tile, it should only use its colored portion.
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #14 - Posted
2005-03-07 15:06:06 » |
|
I know that when I display my tiles that the alpha is... well alpha. And I know that when drawing without using clipping that it works fine.
What I want to do is make it so that if I want to display an Actor behind a tile that I don't have to rerender the entire map (I can't use the standard dirty rect logic because there are layering issues).
So in order to redraw an actor to the background I need to clip out of the actor's graphic where the tiles are that are over the character. For instance if the character is half visible behind a low wall, you don't want to render the entire actor, just his top half.
I fixed the antaliasing issue by resorting to a bunch of Rectangles (because they store their coords in int). But the issue with this is that it takes too much cpu to clip with an Area of 20 rectangles per tile.
The solution to my problem would be able to make a pixel acurate Area from a given png.
|
|
|
|
|
Malohkan
|
 |
«
Reply #15 - Posted
2005-03-07 16:09:25 » |
|
how bout you buffer layers? Have a BufferedImage for a layer, re-draw the ones you need to, and don't ever worry about Areas and Clips? Then your render loop looks like this: 1 2 3 4 5 6
| for (int i = 0; i < topLayer; i++) { layers[i].render(g2d); for (int j = 0; j < characters.length; j++) if (characters[i].layer == i) characters[i].render(g2d); } |
That would work, right? You could even enhance it to know more about which layers have changed and perhaps combine buffered layers if possible so that fewer have to draw.
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #16 - Posted
2005-03-07 19:01:53 » |
|
I've tried that also, the problem again is that because it is isometric the layers are in diagonal lines, causing the BufferedImage for each layer to be the size of the window. This gets increasingly more taxing on the system because you can't just redraw one of those layers, you have to draw every layer above the one you want to redraw.
Lets say that I have an actor on Y:3. And lets also say that the screen is big enough to handle 20 Y. This means that in order to redraw Y:3 you also have to redraw (to the screen, not the actual tiles) everything between 3 and 20.
I found it more taxing on the system to redraw 17 buffered Images then to just redraw the entire thing tile by tile, actor by actor.
With doing it by clipping and Areas I can make it so that a minimal amount of drawing is going on no matter the screen size. It would all be based on how many actors were being refreshed.
|
|
|
|
|
Malohkan
|
 |
«
Reply #17 - Posted
2005-03-08 02:28:11 » |
|
ahh I wasn't talking about y layers, I was talking z layers, so like in ff tactics the most buffers you would ever have would be perhaps 5 layers. I don't know why your image shows areas so tall... but hey, it's your game  If you want to make it this intricate perhaps you could just use a better rendering engine like LWJGL.
|
|
|
|
swpalmer
|
 |
«
Reply #18 - Posted
2005-03-09 23:51:23 » |
|
Instead of using clipping, how about draw a separate alpha channel based on the foreground/background separation. Then when you blit your player, change the compositing rule to use the alpha that you created.
E.g.: Assuming you only blit one pass to draw the terrain. - Clear the screen so the screens alpha is 0 - Blit background objects with compositing rules that copy the alpha channel to the background image. - Blit foreground objects such that the background alpha is left at 0 - Blit the player so it only shows through where the dest alpha is 1
I'm not certain the rules on AlphaComposite cover all the needed cases.. but it might be an approach that works out.
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #19 - Posted
2005-03-10 03:03:06 » |
|
Instead of using clipping, how about draw a separate alpha channel based on the foreground/background separation. The problem comes with actually generating the alpha channels... if I could generate seperate alpha channels I could just apply the clippings this way also... Okay, I have a quick question that might solve all of this.... I have an object called a Sprite_Cache. His job is to store all the graphics as Images and provide keys in String format. In order to store these Images he uses a HashMap, and put()s the image in there... This way when I want the Sprite named "Actor_001_d_1" I just go: Image AnImage = (Image)sprites.get("Actor_001_d_1"); Is this accelerated? Because I store my tiles in there, and for every tile being drawn it gets its image this way....
|
|
|
|
|
Malohkan
|
 |
«
Reply #20 - Posted
2005-03-10 14:38:54 » |
|
well first off, I don't think Image's are accelerated period. If you're asking about the .get() and the type cast, I don't think any optimization happens there. Even Generics which make it look better don't even optimize (my biggest peeve) it. What I do with my stuff is something like this: 1 2 3 4 5 6 7 8 9 10 11 12 13
| private static final int Actor_001_d_1 = 0, Actor_002_d_1 = 1, Actor_003_d_1 = 2, Actor_004_d_1 = 3; public void loadImages() { images = new BufferedImage[4]; for (int i = 0; i < images.length; i++) images[i] = getResource("Actor_00" + (i+1) + "_d_1.png"); } public void render(Graphics2D g2d) { g2d.drawImage(images[index], x, y, null); } |
kinda like that  so that I can load them by ints from an array, but still have a uniqueness about them that's easy for me to read. EDIT: forgot a curly brace  Coding in here is tough!
|
|
|
|
JuddMan
|
 |
«
Reply #21 - Posted
2005-03-10 23:08:01 » |
|
i would perhaps try clipping the sprite graphic when you draw it rather than clipping the terrain. then you could use just one large buffer for the entire background / foreground. the tricky part might be making the formula that generates a polygon to use as the clip bounds.
i'm not sure how this would affect performance but i think calculating a polygon that represents the area that is in front of the player sprite and clipping just the sprite(s) when you draw it (or them) should be faster as its a much smaller image you're clipping, and the anti-aliasing shouldn't be as much of a problem, and in fact might look nice. as they say, logic is 1000 times cheaper than rendering in games, so adding complexity to the logic in order to reduce the amount of rendering done almost always pays off in performance.
i'm just throwing ideas around now, and i'll probably even test a couple when i get your source, but one way to do it would be to calculate a polygon for each layer and clip the sprite based on a combination of all layers in front of it when you draw it.
|
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #22 - Posted
2005-03-10 23:24:24 » |
|
Just to clarify, I meant BufferedImage not Image.  So I went through and changed it over to using a BufferedImage[], and there wasn't any change between the two as far as the performance... I was rather hoping that this would speed everthing up... Thanks though!
|
|
|
|
|
Malohkan
|
 |
«
Reply #23 - Posted
2005-03-11 05:04:34 » |
|
oh yeah the difference definitely isn't going to be significant. Accessor methods from your list was never your bottleneck obviously, it's the rendering that's your bottleneck.
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #24 - Posted
2005-03-11 15:13:09 » |
|
Its kind of funny, I used something like this: 1 2 3 4 5 6 7 8 9 10 11 12 13
| HashMap array_keys = new HashMap() BufferedImage[] images = new BufferedImage[1000]; int current_index = 0;
public void addImage(String filename, String sck) { array_keys.put(filename, new String(""+current_index)); images[current_index] = current_index++; }
public BufferedImage getImage(String sck) { return images[Integer.parseInt(array_keys.get(sck))]; } |
This way I would have the speed of taking it from a BufferedImage[], and also the ability to have better naming... But my hope of putting it into a BufferedImage[] was that it wasn't getting accelerated in the HashMap...
|
|
|
|
|
Malohkan
|
 |
«
Reply #25 - Posted
2005-03-12 03:43:20 » |
|
Objects that have references to BufferedImages don't affect how it gets accelerated. Having it stored in an array or Hashtable don't make a bit of difference in that department. Am I understanding you correctly? I don't think I know what it is you're asking now.
|
|
|
|
H_o_p_s
Senior Newbie 
Java games rock!
|
 |
«
Reply #26 - Posted
2005-03-12 05:00:09 » |
|
Yeah, thats what I figured out. I was hoping that storing the reference in a hashtable was causing the BufferedImages to not be accelerated...
But any way I think I can say that you for all your guys's input! This thread keeps going on and on, and I don't see any point to continue it. If I have more questions I'll post in a new thread.
Thanks!
|
|
|
|
|
|