Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (499)
Games in Android Showcase (118)
games submitted by our members
Games in WIP (567)
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  
  Custom JPanel Faster then Custom Canvas  (Read 3175 times)
0 Members and 1 Guest are viewing this topic.
Offline StumpyStrust
« Posted 2012-03-22 10:54:37 »

So I normally use a JPanel when I want to do some custom drawing (games not just UI)

The JPanel sometimes gives a strange jitter just on certain images being draw which is why I thought maybe it was not being double buffered or it was doing a bad version of double buffering. So I try canvas and well the jitter is gone but it is slow.  Huh

I have tried using a canvas with double buffering and it runs at 1/3 the speed of my JPanel version.

The canvas code

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
    public void render()
    {
       long startTime = System.currentTimeMillis();
       g.setColor(Color.BLACK);
       g.fillRect(0,0,frame.getWidth(),frame.getHeight());
       g.setColor(Color.yellow);
       g.drawString("FPS: " + fps, 15, 15);
   long endTime = System.currentTimeMillis();
        g.drawString("Time Render: " + (endTime-startTime) + "ms", 15, 60);
        g.dispose();
        bufferstrat.show();
}
       


The JPanel Code

1  
2  
3  
4  
5  
6  
7  
8  
9  
   public void paintComponent(Graphics g)
       {
          long startTime = System.currentTimeMillis();
           g.drawString("FPS: " + fps, 15, 15);
           long endTime = System.currentTimeMillis();
                g.drawString("Time Render: " + (endTime-startTime) + "ms", 15, 60);
                g.dispose();
                System.out.println(pane.isDoubleBuffered());
        }


The JPanel Is indeed double buffered.

What gives? Am I doing something wrong?

I have to be doing something wrong but everything is setup the exact same. If anything, the JPanel code is more ugly.

Offline ReBirth
« Reply #1 - Posted 2012-03-22 13:20:41 »

how about the constructing part? for example when you add canvas to JPanel before JFrame.

Offline DruLeeParsec

Junior Member


Medals: 2
Projects: 1



« Reply #2 - Posted 2012-03-22 13:54:52 »

I know that Cavas supports public void createBufferStrategy(int numBuffers) while JPanel does not.  I just changed the code in a game project of mine from JPanel to Canvas.  I was using the image style double buffering as taught in the book "Killer Java Game Programming" inside a JPanel.  I was getting shaky graphics at 30 FPS once my large background images became more complex.  With a double buffered Canvas I set my max FPS to 150 (which is faster than my monitor's refresh rate) and it still ran smoothly

In the Canvas I use createBufferStrategy(2) to create 2 buffers.  Then in my paintScreen() method I get the Graphics this way:

Graphics2D g = (Graphics2D) getBufferStrategy().getDrawGraphics();

I draw to g and then call getBufferStrategy().show(); and g.dispose();

My guess is that the setDoubleBuffered and isDoubleBuffered in JPanel is saying that the JPanel is double buffered, but it's still painting when the OS tells the panel to repaint.  It's just telling you that behind the scenes the OS is using double buffering to draw the JPanel.

An interesting test would be to call setIgnoreRepaint(true) in your JPanel constructor and then call Toolkit.getDefaultToolkit().sync(); right before the g.dispose() in your JPanel code.  That should cause the JPanel to repaint when you want it to, not when the OS wants it to. 

My experience was that using createBufferStrategy and getDrawGraphics on the Canvas was vastly faster than using the JPanel.  But I was also using a clunky Imaged based double buffering technique which was suggested in that book and that may have been slowing me down quite a bit as well.  I wouldn't recommend his technique at all.  He's creating and throwing away a BufferedImage object for every frame.  Think of the memory usage of tossing away a megabyte image 60 times a second!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Z-Man
« Reply #3 - Posted 2012-03-22 14:45:10 »

Your measuring the time it takes to set a color, fill a rectangle, set a color and draw a string (this is your canvas code) against the time it takes to draw a string (your JPanel code). If this is what your referring to as running slower then this is probably the cause.

Also (depending on your other code) drawing to a Canvas is active rendering, and overriding a JPanel's paintComponent() is passive rendering. I wouldn't use passive rendering for a game because it's best to have control over when rendering occurs (active rendering)
Offline StumpyStrust
« Reply #4 - Posted 2012-03-22 19:55:15 »

@ReBirth
The Canvas and JPanel are not added to the same Frame.
Here is my JPanel construction code.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
frame = new JFrame();
        frame.setBounds(0, 0, 800, 500);
        frame.setTitle("HappyFunTime");
        Container cp = frame.getContentPane();
        pane = new MyPanel();

        pane.setDoubleBuffered(true);
        frame.setBackground(Color.black);
        pane.setLayout(null);
        cp.add(pane, "Center");


And the Canvas

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
        frame = new JFrame();
        frame.setBounds(0, 0, 800, 500);
        frame.setTitle("EffectTester");
        Container cp = frame.getContentPane();
        rend = new Canvas();
        cp.add(rend, "Center");
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        rend.createBufferStrategy(2);
        bufferstrat = rend.getBufferStrategy();


@ DruLeeParsec
I am creating two buffers and basically do what you do. I have found out that the actual render time is almost the exact same for both of them but for some reason my canvas fps is much slower.
I tried the setIgnoreRepaint(true); and the performance was the same and still said doublebuffered.

@Z-Man
I removed the draw command that both use do draw everything which is SystemX.render(Graphics g);
The rectangle is trivial when compared to what SystemX is rendering. And when just rendering the rectangle and some text both get 60 fps. Nice and smooth.
I think my JPanel code is active rendering as in, I say when to render. I maybe wrong thought as I am a noob. :?



Offline Z-Man
« Reply #5 - Posted 2012-03-22 20:40:18 »

@Z-Man
I removed the draw command that both use do draw everything which is SystemX.render(Graphics g);
The rectangle is trivial when compared to what SystemX is rendering. And when just rendering the rectangle and some text both get 60 fps. Nice and smooth.
I think my JPanel code is active rendering as in, I say when to render. I maybe wrong thought as I am a noob. :?
I was just referring to the original code you posted, I don't know anything about SystemX (I assume it's code you wrote?). In the code from your first post your measuring how long rendering takes with System.currentTimeMillis() (I'd use System.nanoTime() by the way, because it's implementation is more accurate), but your measuring different amounts of rendering. In the render code for your Canvas you are measuring how long it takes for two setColor() calls, a drawString(), and a fillRect(), but in your JPanel render code your only measuring a drawString(). I currently use a Canvas for my games, but I've used JPanels and I don't really notice much of a performance difference between the two. That might just be my computer though. As for the active rendering, with the code you posted I can't really tell if your JPanel is being actively rendered. Simply overriding the paintComponent() of a JPanel is NOT active rendering, but you can kind of force it to render when you want to.
Offline StumpyStrust
« Reply #6 - Posted 2012-03-23 07:27:46 »

@Z-man
So SystemX is my particle system and it renders particles that, in the case of the test, are images. The jpanel could get 2-3.5k particles with no fps drop while the canvas would drop at 500 but after testing the nano time the actual rendering time is the same. So I must have implemented something else in there wrong. I know is was miss leading in the original post but I hate posting unessential stuff. The drawing is not what I thought the problem was it was whether I was properly double buffering.

I am still not quite sure if I am actually active rendering. I have over written the JPanel's paintComponent() and I have set this flag setIgnoreRepaint(true).

With the canvas I was drawing the rect over the whole screen because the canvas was not clearing the old drawing commands. (like in opengl when you forget to clear the screen)
but when I used this method clearRect() it cleared the drawing surface but got even slower. I am now thinking that it is not swapping buffers properly.

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.

Pippogeek (39 views)
2014-09-24 16:13:29

Pippogeek (30 views)
2014-09-24 16:12:22

Pippogeek (19 views)
2014-09-24 16:12:06

Grunnt (45 views)
2014-09-23 14:38:19

radar3301 (27 views)
2014-09-21 23:33:17

BurntPizza (63 views)
2014-09-21 02:42:18

BurntPizza (33 views)
2014-09-21 01:30:30

moogie (41 views)
2014-09-21 00:26:15

UprightPath (50 views)
2014-09-20 20:14:06

BurntPizza (54 views)
2014-09-19 03:14:18
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!