Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Graphics2D clipping error  (Read 2260 times)
0 Members and 1 Guest are viewing this topic.
Offline 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]);//THIS IS AN AREA
           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?
Offline 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!
Offline trembovetski

Senior Member




If only I knew what I'm talking about!


« 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!
Legends of Yore - The Casual Retro Roguelike
Offline 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...
Offline 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!  
Offline Malohkan

Senior Member




while (true) System.out.println("WOO!!!!");


« 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?

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline 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:
Offline JuddMan

Senior Member


Medals: 1


Your Ad Here


« 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?
Offline 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...
Offline Linuxhippy

Senior Member


Medals: 1


Java games rock!


« 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!
Legends of Yore - The Casual Retro Roguelike
Offline 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.
Offline swpalmer

JGO Coder




Where's the Kaboom?


« 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...

Offline H_o_p_s

Senior Newbie




Java games rock!


« Reply #12 - Posted 2005-03-07 02:47:26 »

Yup, both. No success.  Sad

Thanks though!
Offline Malohkan

Senior Member




while (true) System.out.println("WOO!!!!");


« 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.

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline 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.
Offline Malohkan

Senior Member




while (true) System.out.println("WOO!!!!");


« 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.

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline 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.
Offline Malohkan

Senior Member




while (true) System.out.println("WOO!!!!");


« 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 Wink  If you want to make it this intricate perhaps you could just use a better rendering engine like LWJGL.

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline swpalmer

JGO Coder




Where's the Kaboom?


« 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.

Offline H_o_p_s

Senior Newbie




Java games rock!


« Reply #19 - Posted 2005-03-10 03:03:06 »

Quote
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....
Offline Malohkan

Senior Member




while (true) System.out.println("WOO!!!!");


« 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 Smiley
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 Wink  Coding in here is tough!

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline JuddMan

Senior Member


Medals: 1


Your Ad Here


« 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.
Offline 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. Wink

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!
Offline Malohkan

Senior Member




while (true) System.out.println("WOO!!!!");


« 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.

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline 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] = //IMAGE FROM RESOURCES
  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...
Offline Malohkan

Senior Member




while (true) System.out.println("WOO!!!!");


« 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.

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline 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!
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

E.R. Fleming (10 views)
2014-07-29 03:07:13

E.R. Fleming (4 views)
2014-07-29 03:06:25

pw (38 views)
2014-07-24 01:59:36

Riven (39 views)
2014-07-23 21:16:32

Riven (26 views)
2014-07-23 21:07:15

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21

Zero Volt (50 views)
2014-07-17 23:47:54

danieldean (42 views)
2014-07-17 23:41:23

MustardPeter (44 views)
2014-07-16 23:30:00
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!