Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
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  
  How to speedup my Java2D framework?  (Read 1629 times)
0 Members and 1 Guest are viewing this topic.
Offline relminator
« Posted 2013-03-01 13:11:46 »

Hello guys, I'm just over a week learning Java and for some crazy reason I am learning Java2D(which is weird since I've been coding in OpenGL for years now and have developed an OpenGL framework http://rel.phatcode.net/junk.php?id=133 )


Anyways, here's the source and binary for the Java2D framework:

http://rel.phatcode.net/junk.php?id=131



Somehow disabling sprite transparency by composition speeds things up quite a bit.  Any thoughts on why that happens or any way to speed things up?

Does Java2D do stuff in software via GDI?

Thanks!


Java2DFramework.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
import javax.swing.JFrame;

public class Java2DFramework extends JFrame
{

   private static final long serialVersionUID = 1L;

   
   public Java2DFramework()
    {

        add( new Screen() );

        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        setSize( Globals.SCREEN_WIDTH, Globals.SCREEN_HEIGHT );
        setLocationRelativeTo( null );
        setTitle( "Relminator's Java 2D Framework" );
        setResizable( false );
        setVisible( true );
       
    }

    public static void main(String[] args)
    {
        new Java2DFramework();
    }
}



screen.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.Font;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.Dimension;
import java.awt.BasicStroke;
import java.awt.geom.*;
import java.awt.AlphaComposite;


import javax.swing.JPanel;


public class Screen extends JPanel implements Runnable  
{

   private static final long serialVersionUID = 1L;
   
   private Thread animator;
       
    private double accumulator = 0;
   
    private int fps = 0;
    private int framesPerSecond = 0;
    private double previousTime = 0;
    private double oldTime = 0;
    private double secondsElapsed = 0;
   
    private Starfield stars = new Starfield();
    private Picture picture = new Picture();
   
    public Screen()
    {

        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);
       
    }

    public void addNotify()
    {
        super.addNotify();
        animator = new Thread( this );
        animator.start();
    }
   
    public void paint( Graphics g )
    {
        super.paint(g);
       
        Graphics2D g2D = (Graphics2D)g;

        render( g2D );
       
        Toolkit.getDefaultToolkit().sync();
        g.dispose();
       
    }

    private class TAdapter extends KeyAdapter
    {

        public void keyReleased( KeyEvent e )
        {
           picture.keyReleased( e );
        }

        public void keyPressed( KeyEvent e )
        {
           picture.keyPressed( e );
        }
       
    }
   
   
    public void update()
    {

       stars.update();
       picture.move();
       repaint();

    }

    public void render( Graphics2D g2D )
    {
       
       
       AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f);
       g2D.setComposite(ac);
       
       g2D.setFont(new Font("Courier New", Font.BOLD, 24));
       g2D.setColor( Color.BLUE );
        g2D.drawString( "FPS :" + fps, 0, 24 );
       
        stars.render( g2D, secondsElapsed );
       
        Dimension size = getSize();
        double w = size.getWidth();
        double h = size.getHeight();

        Rectangle2D e = new Rectangle2D.Double(-10, -10, 20, 20);
        g2D.setStroke(new BasicStroke(1));
       
       
       
        double hw = w/2;
        double hh = h/2;
       
        double scale = 0;
        float color = 0;
       
       
        double posX = hw + ( Math.cos(secondsElapsed * 0.5) + Math.sin(secondsElapsed * 1.25) ) * hw/2;
        double posY = hh + ( Math.sin(secondsElapsed * 2.5) + Math.sin(secondsElapsed * 0.25) ) * hh/2;
       
        for( int deg = 0; deg < (360*4); deg += 25)
        {
           
            AffineTransform at = AffineTransform.getTranslateInstance( posX, posY );
            at.rotate( Math.toRadians(deg * 5 + secondsElapsed * 150) );
            at.scale( scale + Math.abs(Math.sin(secondsElapsed * 0.9) * 10),
                    scale + Math.abs(Math.sin(secondsElapsed * 1.5) * 10));
           
            scale += 0.2;
            color = (float)Math.abs( Math.sin(secondsElapsed * 2.5 + deg) );
            g2D.setColor( new Color(color, 1.0f - color, color/2.0f) );
           
            g2D.draw( at.createTransformedShape(e) );
             
         }
       
        g2D.drawImage( picture.getImage(), picture.getX(), picture.getY(), this );
       
    }

   public void run()
   {
     
      double dt = getDeltaTime( getSystemTime() );
     
        while( true )
        {

           dt = getDeltaTime( getSystemTime() );
         if( dt > Globals.FIXED_TIME_STEP ) dt = Globals.FIXED_TIME_STEP;
         accumulator += dt;
         secondsElapsed += dt;
         
         while( accumulator >= Globals.FIXED_TIME_STEP )
         {
            update();
            accumulator -= Globals.FIXED_TIME_STEP;
           
         }
         
            try
            {
                Thread.sleep(15);
            }
            catch (InterruptedException e)
            {
                System.out.println("interrupted");
            }

        }
       
   }
   
   
   
   public double getSystemTime()
   {
      return System.currentTimeMillis() / (double)1000.0;
   }

   public double getDeltaTime( double timerInSeconds )
   {
     
      double currentTime = timerInSeconds;
      double elapsedTime = currentTime - oldTime;
      oldTime = currentTime;
     
      framesPerSecond++;
     
      if( (currentTime - previousTime) > 1.0 )
      {
         previousTime = currentTime;
         fps = framesPerSecond;
         framesPerSecond = 0;
      }
     
      return elapsedTime;
   }
   
   
}


Starfield.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;


public class Starfield
{
   private static final int NUMSTARS = 512;
   
   private ArrayList<Star> stars = new ArrayList<Star>();
   
   public Starfield()
   {
   
      for( int i = 0; i < NUMSTARS; i++ )
      {
         Star star = new Star( -Globals.SCREEN_WIDTH/2.0f + (float)Math.random() * Globals.SCREEN_WIDTH/1.0f,
                             -Globals.SCREEN_HEIGHT/2.0f + (float)Math.random() * Globals.SCREEN_HEIGHT/1.0f,
                             -(float)Math.random() * 255,
                             01.f + (float)Math.random() * 2);
         stars.add( star );
      }
     
   }
   
   public void update()
   {
     
      for( int i = 0; i < stars.size(); i++ )
      {
         Star star = stars.get(i);
         star.move();
      }
     
   }
   
   public void render( Graphics2D g2D, double secondsElapsed )
   {
     
      float color = (float)Math.abs( Math.sin(secondsElapsed * 0.5) );
        g2D.setColor( new Color(1.0f - color, color, color) );
       
     
      for( int i = 0; i < stars.size(); i++ )
      {
         Star star = stars.get( i );
         int sx = star.getScreenX();
         int sy = star.getScreenY();
         g2D.drawLine( sx, sy, sx, sy );
      }
     
     
   }
   
   
}  // end class


Star.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
public class Star 
{
   private float x;
   private float y;
   private float z;
   private float speed;
   private float screenX;
   private float screenY;
   
   public Star()
   {
      x = 0;
      y = 0;
      z = 0;
      speed = 0;
   }

   public Star( float x, float y, float z, float speed )
   {
      this.x = x;
      this.y = y;
      this.z = z;
      this.speed = speed;
   }

   public int getScreenX()
   {
      return (int)screenX;
   }
   
   public int getScreenY()
   {
      return (int)screenY;
   }
   
   public float getDistance()
   {
      return (Globals.LENS - z);
   }
   
   public void init( float x, float y, float z, float speed )
   {
      this.x = x;
      this.y = y;
      this.z = z;
      this.speed = speed;
   }
   
   public void move()
   {
     
      z += speed;
      if( z > Globals.LENS )
      {
         z = 0;
      }
     
      float sx = x;
      float sy = y;
      float sz = z;
      float distance = Globals.LENS - sz;
      if( distance > 0 )
      {
         screenX = Globals.SCREEN_WIDTH/2 + (Globals.LENS * sx / distance);
            screenY = Globals.SCREEN_HEIGHT/2 - (Globals.LENS * sy / distance);
      }
     
     
   }
   
}


Picture.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
import javax.swing.ImageIcon;
import java.awt.Image;
import java.awt.event.KeyEvent;

public class Picture
{
   private String fileName = "gfx/fairy.png";
   private Image image;

   private float x;
   private float y;
   
   private float dx;
   private float dy;
   
   private float speed = 2.5f;
   
   Picture()
   {
     
      ImageIcon ii = new ImageIcon(this.getClass().getResource(fileName));
       
      image = ii.getImage();
       
        x = Globals.SCREEN_WIDTH/2.0f - image.getWidth(null)/2.0f;
        y = Globals.SCREEN_HEIGHT/2.0f - image.getHeight(null)/2.0f;
       
   }
   
   public int getX()
   {
      return (int)x;
   }
   
   public int getY()
   {
      return (int)y;
   }
   
   public Image getImage()
    {
        return image;
    }

   public void move()
    {
        x += dx;
        y += dy;
    }

   public void keyPressed( KeyEvent e )
    {

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT)
        {
            dx = -speed;
        }

        if (key == KeyEvent.VK_RIGHT)
        {
            dx = speed;
        }

        if (key == KeyEvent.VK_UP)
        {
            dy = -speed;
        }

        if (key == KeyEvent.VK_DOWN)
        {
            dy = speed;
        }
    }

    public void keyReleased(KeyEvent e)
    {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT)
        {
            dx = 0;
        }

        if (key == KeyEvent.VK_RIGHT)
        {
            dx = 0;
        }

        if (key == KeyEvent.VK_UP)
        {
            dy = 0;
        }

        if (key == KeyEvent.VK_DOWN)
        {
            dy = 0;
        }
    }
}


Globals.java
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public class Globals 
{
   
     public static final double FIXED_TIME_STEP = 1/60.0;
     
     public final static int SCREEN_WIDTH = 640;
     public final static int SCREEN_HEIGHT = 480;
   
     public final static int LENS = 256;
     
}


Offline Danny02
« Reply #1 - Posted 2013-03-01 13:33:41 »

java2D is a magic box which will use your graphic card for stuff if it can. For example it will cache some images as textures if you arn't changing them.

There are already some topics which discuss this, also others with more knowledge with this might answer as well Smiley
Offline relminator
« Reply #2 - Posted 2013-03-01 13:50:16 »

Thanks!  But if you could peruse the source for the Java2D project and point out some glaring mistakes (I know I made lots), I would be very thankful.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Grunnt

JGO Kernel


Medals: 95
Projects: 8
Exp: 5 years


Complex != complicated


« Reply #3 - Posted 2013-03-01 14:21:42 »

Somehow disabling sprite transparency by composition speeds things up quite a bit.  Any thoughts on why that happens or any way to speed things up?

It might be easier for people to give you feedback if you put your code in a public online repository, e.g. GitHub or Google Code. Or just in a pastebin.

About the sprite transparency by composition: AFAIK drawing a sprite without transparency is pretty simple and fast: pixels just get written directly to the backbuffer. Drawing with transparency is more complicated as the value of the pixel that is currently in the buffer (i.e. the one that "shines through" the transparent pixel) need to be combined using a calculation with the pixel value of the sprite. That takes more processing time, and hence is slower.

You may try explicitly enabling OpenGL as the rendering pipeline, described here as a hint, but I've never tried:
1  
System.setProperty("sun.java2d.opengl","True");

Offline relminator
« Reply #4 - Posted 2013-03-02 07:14:30 »

Added this code but still the same issue:
1  
System.setProperty("sun.java2d.opengl","True");


I fixed it now. Thanks!

I put the blending code after drawing the primitives and before drawing the image.  Seems like compositing is also applied to primitives.

I get ~900 FPS (with Thread.sleep(1)) on my dinosaur laptop with intel gfx,  LOL

Updated the binaries.

Offline badlogicgames

« JGO Bitwise Duke »


Medals: 74
Projects: 2



« Reply #5 - Posted 2013-03-02 10:46:49 »

My god, Rel, is that you? QB45, FreeBasic, etc. Not sure if you remember me, marzec here. Man, it's been 10 years. Glad you are still active Smiley

http://www.badlogicgames.com - musings on Android and Java game development
Offline relminator
« Reply #6 - Posted 2013-03-04 11:27:24 »

Yes my friend!  I posted a message on your forums (which you never answered BTW. LOL)

BTW, I've been telling everybody I know to buy your book.

Good job on libGDX!!!  Will use it once I get onto droid (using the NDK for now since I'm a Java noob).
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.

rwatson462 (36 views)
2014-12-15 09:26:44

Mr.CodeIt (29 views)
2014-12-14 19:50:38

BurntPizza (61 views)
2014-12-09 22:41:13

BurntPizza (98 views)
2014-12-08 04:46:31

JscottyBieshaar (58 views)
2014-12-05 12:39:02

SHC (74 views)
2014-12-03 16:27:13

CopyableCougar4 (76 views)
2014-11-29 21:32:03

toopeicgaming1999 (137 views)
2014-11-26 15:22:04

toopeicgaming1999 (127 views)
2014-11-26 15:20:36

toopeicgaming1999 (37 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

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