Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (108)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
   Home   Help   Search   Login   Register   
  Show Posts
Pages: [1]
1  Discussions / Jobs and Resumes / Software engineer (graphics) at UNC-CH on: 2004-12-15 15:03:02
Looking for a software engineer with good background in graphics, OpenGL or DirectX, C++ and large software systems at University of North Carolina at Chapel Hill (UNC-CH) GAMMA Research Group. The person will be working on a DoD (department of defense) funded project on developing novel GPU (graphics processor)-based algorithms for simulation and geometric computations (including visibility, collision detection and path navigation). The person will work closely with graduate students and faculty at UNC-CH and also interact with industrial partners. Lots of potential for advanced learning, research, and publications. Flexible work schedule and open lab environment.

More information on the GAMMA Research Group at UNC-CH is available at:

<http://gamma.cs.unc.edu>

The GAMMA Research Group has developed a number of systems that are widely used in gaming and simulation industry. The person will be employed by the Department of Computer Science at UNC-CH, which has the number #1 ranked graduate program in computer graphics and user interaction in the U.S. (according to US News and World Report).

Length of position: 1-3 years.

Availability: January'05

Salary: Based on experience

Please contact Professor Dinesh Manocha <mailto://dm@cs.unc.edu> for more information.
2  Game Development / Performance Tuning / Re: NIO performance on: 2004-02-14 06:47:53
Oops! Error in above FastCopyFile.java code in main():

1  
copyFile(args[0], outfile);


should be:

1  
copyFile(args[0], args[1]);


Sorry 'bout that!

Craig
3  Game Development / Performance Tuning / Re: NIO performance on: 2004-02-14 06:41:37
Here's another example:

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  
/**
 * Program: FastCopyFile.java
 * Author : Craig Mattocks
 * Date   : April, 2003
 * Description: Test Java 1.4 NIO channels and buffers.
 * Based on Listing 1.2 from:
 * "JDK 1.4 Tutorial" by Gregory M. Travis, Manning
 * Note:  Direct buffers allocate their data directly in the
 * runtime environment memory, bypassing the JVM|OS boundary,
 * usually doubling file copy speed. However, they generally
 * cost more to allocate.
 */


import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.text.NumberFormat;

public class FastCopyFile
{
      public static void main( String args[] )
      {
            if (args.length != 2)
            {
                  System.out.println("Usage:  java FastCopyFile src_file dest_file");
                  System.exit(1);
            }

            System.out.println("Copying file " + args[0] + " to file " + args[1] + "...");

            long before = System.currentTimeMillis();            // Start timing
                 copyFile(args[0], outfile);
            long after  = System.currentTimeMillis();            // End timing

            double cputime = .001 * (after - before);

            NumberFormat digits = NumberFormat.getInstance();
            digits.setMaximumFractionDigits(3);

            System.out.println("Execution required " + digits.format(cputime) + " seconds.");
      }

      private static void copyFile(String infile, String outfile)
      {
            final boolean DIRECT   = true;      // Direct buffer?
           final boolean TRANSFER = true;      // Use fast transfer method?
           final int BUFFSIZE = 1024;
            ByteBuffer buffer;

            FileChannel in  = null;
            FileChannel out = null;

            try
            {
                  in  = (new FileInputStream (infile )).getChannel();
                  out = (new FileOutputStream(outfile)).getChannel();

                  if (DIRECT)
                        buffer = ByteBuffer.allocateDirect( BUFFSIZE );
                  else
                        buffer = ByteBuffer.allocate( BUFFSIZE );

                  if (TRANSFER)
                  {
                        /**
                         * transferTo is potentially much more efficient than a simple
                         * loop that reads from a source channel and writes to a target
                         * channel. Many operating systems can transfer bytes directly
                         * from the filesystem cache to the target channel without
                         * actually copying them by using special operating system
                         * features that support very fast file transfers. - Sun docs
                         */


                        in.transferTo(0, in.size(), out);
                  }
                  else
                  {
                        int ret;
                        while ((ret = in.read(buffer)) > -1) // Read from input channel, write to buffer
                       {
                              buffer.flip();                              // Flip buffer's read/write mode
                             out.write(buffer);                        // Read from buffer, write to output channel
                             buffer.clear();                              // Make room for the next read
                       }
                  }
            }
            catch (FileNotFoundException fnfx)
            {
                  System.err.println("File not found: " + fnfx);
            }
            catch (IOException iox)
            {
                  System.err.println("I/O problems: " + iox);
            }
            finally
            {
                  if (in != null)
                  {
                        try
                        {
                              in.close();
                        }
                        catch (IOException ignored) {}
                  }
                  if (out != null)
                  {
                        try
                        {
                              out.close();
                        }
                        catch (IOException ignored) {}
                  }
            }
      }
}
4  Game Development / Newbie & Debugging Questions / Re: Creating custom Button Class on: 2004-02-14 06:31:34
Here's a custom animated JButton class:

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  
// Animated JButton

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class HotButton extends JButton
{
      // Global class vars
     private final String imageNames[];      // names (URLs) of button's images
     private javax.swing.Timer t = null;      // animation control timer
     private int n = 0;                              // index of current image displayed

      // Constructor
     public HotButton(final String imageNames[], int speed)
      {
            super();
            setContentAreaFilled(false);
            setBorderPainted(false);
            setFocusPainted(false);
//            setSize( (new ImageIcon(imageNames[0])).getIconWidth(), (new ImageIcon(imageNames[0])).getIconHeight() );
           this.imageNames = imageNames;

            ActionListener timedAction = new ActionListener()
            {
                  public void actionPerformed(ActionEvent e)
                  {
                        setIcon( new ImageIcon(imageNames[n]) );
                        n = (n + 1) % imageNames.length;
                  }
            };

            t = new javax.swing.Timer(speed, timedAction);
            t.setInitialDelay(0);                        // Start up immediately
//            t.setCoalesce(true);                        // Prevent event flooding
//            t.start();                                          // Autostart
     } // end HotButton constructor

      // Can be invoked by any thread (since timer is thread-safe).
     public synchronized void start()
      {
            if ( !t.isRunning() )
            {
                  t.start();                  // Start animation!
           }
      }

      // Can be invoked by any thread (since timer is thread-safe).
     public synchronized void stop()
      {
            if ( t.isRunning() )
            {
                  t.stop();                  // Stop animation.
           }
      }

} // end class HotButton


and here's a demo which uses it:

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  
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

public class AnimatedButtonDemo extends JFrame
{
      // Global class vars
     int speed = 100;      // button refresh rate in ms
     String[] imageNames = {"images/duck0.jpg", "images/duck1.jpg", "images/duck2.jpg", "images/duck3.jpg"};
      HotButton button;
      boolean startstop = false;      // animation toggle flag

      // Constructor
     public AnimatedButtonDemo()
      {
            super("Animated Button Demo");

            button = new HotButton(imageNames, speed);
            button.addActionListener
            (
                  new ActionListener()
                  {
                        public void actionPerformed(ActionEvent e)
                        {
                              if (startstop)
                              {
                                    startstop = false;
                                    button.start();
                                    System.out.println("<< button started >>");
                              }
                              else
                              {
                                    button.stop();
                                    startstop = true;
                                    System.out.println("|| button stopped ||");
                              }
                        }
                  }
            );
            button.start();      // Autostart

            Container c = getContentPane();
            c.setLayout(null);                              // We'll do the layout ourselves
           button.setBounds(150,100, 93,90);
            c.add(button);

      } // end constructor

      public static void main(String[] args)
      {
            JFrame f = new AnimatedButtonDemo();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setSize(400,300);
            f.setVisible(true);
      }
}


Have fun!
Craig
5  Java Game APIs & Engines / JOGL Development / Re: Can't Get Jogl to work on Mac OS X on: 2003-12-12 00:42:15
You may need to install Panther (10.3). Lots of important Carbon --> Cocoa graphics/threading changes were implemented post-Jaguar.

Both lessons 2 and 3 run fine for me in windowed mode but fullscreen mode gives me a black empty screen. When I press the escape key, I see the images display correctly but just for a moment.

Of course, I am running on a very old, slow iMac without enough VRAM for hardware acceleration. Mac OS X 10.3.1 (7C107)

Craig
6  Game Development / Newbie & Debugging Questions / Re: System.out.print|ln(..) to null - how? on: 2003-12-11 23:46:38
http://developer.apple.com/qa/java/java11.html
7  Java Game APIs & Engines / Java 2D / Re: Disappointing performance with OS X on: 2003-06-05 19:46:03
AFAIK, hardware acceleration isn't fully implemented yet.

Longshot -- have you tried passing the runtime flag:

-Dcom.apple.awt.hwaccel=true

?
8  Java Game APIs & Engines / Java 2D / Re: JTextField in fullscreen game on: 2003-06-05 05:35:23
Perhaps this link is relevant:

http://www.milk.com/java-rants/bug01-awt-event.html

Excerpt:

"The case is that a user thread calls JFrame.setVisible(true) on a frame which contains a text field. The act of visible-izing causes an attempt to acquire a read lock on the document of the text field. At the same time, the user is typing in the field, and a text insertion event is being processed, which has already caused a write lock to be acquired on the same document. Given that the write lock has already been acquired, the read lock acquisition is stalled. However, the thread doing the setVisible() has already managed to acquire the anonymous universal lock (which I suspect is java.awt.Component.LOCK). Soon, the AWT event thread tries to acquire that same lock (i.e. synchronize on it). Oops! Deadlock: the event queue has the document lock and wants the anonymous lock; the user thread has the anonymous lock and wants the document lock."
9  Java Game APIs & Engines / Java 2D / Re: JTextField in fullscreen game on: 2003-06-04 13:59:33
Hmmm...

Since JTextField is a subclass of JTextComponent, it *should* be thread safe. However, the JavaDocs say:

"The swing text components provide some support of thread safe operations.  Because of the high level of configurability of the text components, it is possible to circumvent the protection provided. The protection primarily comes from the model, so the documentation of AbstractDocument describes the assumptions of the protection provided."

Have you tried using a shortcut for invoking non-thread-safe methods to modify your GUI:

EventQueue.invokeLater
(or better)
SwingUtilities.invokeLater
(
     new Runnable()
     {
           public void run()
           {
                 field.setText("Hola, Gringo!");
           }
     }
);

or:

SwingUtilities.invokeLater
(
     new Runnable()
     {
           public void run()
           {
                 try
                 {
                       // Some GUI modifying method which throws InterruptedException
                 }
                 catch (InterruptedException x)
                 {
                       x.printStackTrace();
                 }
           }
     }
);

See the discussion of the AbstractDocument class for further clues. There are read/write locks firing...
10  Java Game APIs & Engines / Java 2D / Re: Disappointing performance with OS X on: 2003-06-04 05:53:49
What type of graphics images are being displayed? This is often system/video dependent. Try running this performance test on both platforms:

// Program    :  TestGraphics.java
// Description:  Test performance of graphics types.
// Notes      :  Use 'java -Xcomp' to run this app. This option will
//               force JIT-compilation at startup, instead of letting
//               HotSpot decide when and what to compile.  Without it,
//               HotSpot may trigger compilation at an unknown or
//               unexpected point, invalidating the elapsed times due
//               to a flurry of JITC-ing. It may also be useful to run
//               with -Xint and -Xmixed to show how much is interpreter
//               cost and how much is graphics rendering cost.

import java.awt.*;
import java.awt.image.*;

public class TestGraphics
{
     static final int WIDTH  = 700,
                      HEIGHT = 700;

     static final int COUNT = Math.min(WIDTH,HEIGHT)/2;

     static final String[] sImageNames =
     {
           "TYPE_INT_RGB (HotSpot warm-up, throw away)",
           "TYPE_INT_RGB",
           "TYPE_INT_ARGB",
           "TYPE_INT_ARGB_PRE",
           "TYPE_INT_BGR",
           "TYPE_3BYTE_BGR",
           "TYPE_4BYTE_ABGR",
           "TYPE_4BYTE_ABGR_PRE",
           "TYPE_USHORT_565_RGB",
           "TYPE_USHORT_555_RGB",
           "TYPE_BYTE_GRAY",
           "TYPE_USHORT_GRAY",
           "TYPE_BYTE_BINARY",
           "TYPE_BYTE_INDEXED",
           "native CompatibleImage"
     };

     static final int[] sImageConstants =
     {
           BufferedImage.TYPE_INT_RGB,
           BufferedImage.TYPE_INT_RGB,
           BufferedImage.TYPE_INT_ARGB,
           BufferedImage.TYPE_INT_ARGB_PRE,
           BufferedImage.TYPE_INT_BGR,
           BufferedImage.TYPE_3BYTE_BGR,
           BufferedImage.TYPE_4BYTE_ABGR,
           BufferedImage.TYPE_4BYTE_ABGR_PRE,
           BufferedImage.TYPE_USHORT_565_RGB,
           BufferedImage.TYPE_USHORT_555_RGB,
           BufferedImage.TYPE_BYTE_GRAY,
           BufferedImage.TYPE_USHORT_GRAY,
           BufferedImage.TYPE_BYTE_BINARY,
           BufferedImage.TYPE_BYTE_INDEXED
      };

     // This is a simple test that does setColors and fillRects
     static void recTest(BufferedImage bi)
     {
           Graphics g2D = (Graphics2D) bi.getGraphics();
           for (int i=0; i<COUNT; i++)
           {
                 if (i%2 == 0 )
                 {
                       g2D.setColor(Color.black);
                 }
                 else
                 {
                       g2D.setColor(Color.red);
                 }      
                 g2D.fillRect(i,i, WIDTH-i,HEIGHT-i);
           }
     }

     public static void main(String[] args)
     {
         long startTime;
         long[] elapsedTime = new long[sImageConstants.length + 1];

           // Allocate 14 different buffered images to cross-compare
           BufferedImage[] bis = new BufferedImage[sImageConstants.length + 1];
           for (int i=0; i<sImageConstants.length; i++)
                 bis = new BufferedImage(WIDTH, HEIGHT, sImageConstants);

           // Include native type:
           bis[sImageConstants.length] = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(WIDTH, HEIGHT);

           // Compute and print performance
           System.out.println("Simple Graphics Performance Example");
           System.out.println("Time\tImage Type\n----\t----------");
           for (int i=0; i<=sImageConstants.length; i++)
           {
                 startTime = System.currentTimeMillis();
                       recTest(bis);
                 elapsedTime = System.currentTimeMillis() - startTime;
                 System.out.println(elapsedTime + "\t" + sImageNames);
           }

           // Doing graphics may start the AWT event-thread, thereby preventing
           // a return from main() from causing an exit.  So, always force an exit.
           System.exit(0);
     }
}
11  Game Development / Game Mechanics / Re: This may not be correct forum. ┬áR-T Tornado re on: 2003-05-14 07:10:35
http://www.kilty.com/t_model.htm
12  Java Game APIs & Engines / Java 3D / Re: Army wants 3D game engine on: 2003-05-14 06:10:28
> mattocks, are you concerned with that yourself?
> Related somehow?

Nope, not at all.  I've written SBIR proposals in other topic areas but this one is beyond my current capability.

I thought perhaps some of the 3D experts on this list might want to spin up a company or work together and get paid for developing a 3D API.  A nice opportunity!

Just trying to be helpful,
Craig
13  Java Game APIs & Engines / Java 3D / Army wants 3D game engine on: 2003-05-13 06:01:13
Anyone want to get paid for developing a 3D game engine for the US Army?

See the new SBIR (Small Business Innovative Research) solicitations (requests for proposals):

https://www.dodsbir.net/solicitation/default.htm

Proposals are due August 14, 2003.

Phase I       :  $70,000 for 6 months
Phase I option:  $50,000 for 4 months
Phase II      : $730,000 for 2 years
Phase III     : transition to private sector
Matching funds: $250,000 if available

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
A03-083 TITLE: Military 3-D Visualization Utilizing Gaming Technology

TECHNOLOGY AREAS: Information Systems, Human Systems

ACQUISITION PROGRAM: PM, Future Combat Systems

OBJECTIVE: Develop a standardized application programming interface (API) for a military 3-D gaming simulation tool that will facilitate the integration of a gaming environment with planned military C2 applications (such as the Commanders Support Environment, Combined Arms Planning and Execution System, DaVinci Toolkit).

DESCRIPTION: This 3-D visualization interface will be required to work with a standard C2 Data Model and associated XML Schema and DTD to render 3-D visualizations of military units, as well as have the desired capability to render 3-D terrains and environments from standard NIMA maps and imagery. The simulation tool should be capable of taking live feeds from the associated military planning tools in a networked environment (multiple feeds desired) and rendering a 3-D virtual environment in near real-time for war-gaming scenarios. The API developed as part of this effort should be robust and extensible to allow for integration of live sensor feeds at a later date. Currently, no standard gaming API exists in the industry, which hampers the rapid development and application of gaming technology to large-scale simulation systems and trainers. (Each system becomes a custom environment.) The system should leverage commercial standards to the maximum extent and leverage existing gaming engine technology. It is desired that the system be capable of running on a current Windows 2000 environment, but Unix/Linux based systems will be considered. Development of such a system will directly support all Future Combat System experiments, which currently employ the Commanders Support Environment. Commercial applications include the use of such a system for Homeland Security, both in stand-alone exercises of non-military emergency personnel, as well as joint operations between civilian authorities and NORTHCOM. Commercial applications also allow gaming manufacturers to develop an industry-standard interface to allow for gaming applications to be used as simulation trainers for various commercial environments.

PHASE I: Research current 3-D visualization techniques that are generated in real-time on desktop computing platforms utilizing commercial gaming engines and develop a systems architecture to incorporate these systems into Future Combat Systems C2 operational software. The systems should have the capability of interoperating with a command and control object model based on the DaVinci architecture, along with the ability to read XML data streams as input drivers to the system to effect movement of the objects during an operation.

PHASE II: Develop a prototype 3-D visualization system and API that can be integrated into the Future Combat System C2 application based on the DaVinci architecture and its associated object model, XML Schema and DTD. As part of this effort, verify the validity of the API by demonstrating a working prototype where the existing the C2 application input/output effects are displayed in 3-D form using the visualization engine in a laboratory environment over a wired network.

PHASE III: Future Combat System applications. This 3-D visualization system can also be used in commercial simulation scenarios for Homeland Security and Disaster Relief and Recovery systems for both civil defense and corporate applications.

REFERENCES:

1) Future Combat System - See http://www.darpa.mil/fcs/index.html

2) DaVinci Architecture - See
http://call-ditt.leavenworth.army.mil/docs/CECOMBAA001.htm;

3) DaVinci Architecture - Also see
diicoe.disa.mil/coe/aog_twg/twg/mstwg/agile_brief.ppt

KEYWORDS: 3-D visualization, game engines, gaming technology, XML, DaVinci, C2, command and control, Future Combat Systems

TPOC: M. Zieniewicz, P. E.
Phone: (732) 427-3143
Fax: (732) 427-3645
Email: matthew.zieniewicz@us.army.mil

2nd TPOC: R. Szymanski
Phone: (732) 427-3698
Fax: (732) 427-3645
Email: ron.szymanski@us.army.mil
14  Java Game APIs & Engines / Java 2D / Re: Image compositing using black/white mask and i on: 2003-05-11 06:16:44
See example 11-12 CompositeEffects.java from the O'Reilly "Java Examples in a Nutshell" book:

http://examples.oreilly.com/jenut2/2nd_edition/

The last effect uses a complex shape for a clipping region.

- Craig
15  Game Development / Game Mechanics / Re: Drag calculations on: 2003-05-09 17:47:41
I have experience running fluid dynamics simulations based on the Navier-Stokes equations.

The key question is:  how much resolution do you need? Do you want to simulate the turbulent motion in the logarithmic sublayer under different Richardson number (stability) regimes or do you just want to make a lumpy, rough object like a lounge chair fly differently than a streamlined airfoil?

You can use a very simple parameterization (equation) to increase your drag coefficient as the surface roughness of an object increases. In flow over mountains, for example, something simple like this is used:

Cd = .001 + .006*z/(1+z)

where z is the surface elevation in km. This accounts for the increased form drag/surface roughness as you ascend the mountain. (This is a cloud's point of view. In your case, the object will be moving instead of the air, unless you want winds.)

I would advise using some simple equation - it will also run faster!

Best of luck,
Craig
16  Java Game APIs & Engines / Java 2D / Re: How to get the clip rectangle of a Graphics ob on: 2003-05-04 05:30:01
Something like this?

public void render(Graphics g)
{
   Rectangle oldClip = g.getClipBounds();
   g.setClip(left, top, width,height);
   . . . draw stuff . . .
   g.setClip(oldClip);
}

- Craig
17  Java Game APIs & Engines / Java 2D / Re: GAGE Engine Early Access on: 2003-04-03 04:05:17
> Honestly, for the purpose of games, is the extra 300-400 nanoseconds
> that important?

No, that was the difference between C resolution and Java resolution using my native timer.

> 1000 ticks per second should be more than enough to time a
> hundred or so frames per second.

Good point, especially since the thread resolution is not very accurate. Perhaps a more experienced game programmer than I could coment?

1500 nanoseconds => 1/(1500 * 10^-9) = 666,666 ticks per second

> I'm not quite sure what you mean here. If the HotSpot compiler
> doesn't think it should be compiled, then there's a good bet that it
> doesn't need to be.

From what I've read, HotSpot compiles methods that are called more than 1,000 times or so. Calling a timer once (interpreted mode) will give you a much slower response (larger time resolution measurement) than calling it thousands of times (compiled mode) and averaging the results. I find a speedup in performance of 20x (interpreted/compiled ratio), which is significant.

> Well, I don't have a Mac (yet), so I can't create one. But if someone out
> there has the time and the need, I'd happily accept a donation. Smiley

I'll try this when I get some spare time.

Nice work!
Craig
18  Java Game APIs & Engines / Java 2D / Re: GAGE Engine Early Access on: 2003-04-03 01:42:03
> Excellent! And Macs even manage to give a full 1000 ticks per second!
> I knew I liked those machines for a reason... Smiley

My Mac OS X native C timer gives a resolution of about 1100 nanoseconds (1.1 microseconds = .0011 milliseconds).

When I use it in Java via JNI, the resolution is about 1500 nanoseconds, so I lose 300-400 nanoseconds going across the interface.

Note that your resolution algorithm does not adequately "warm up" HotSpot, so the code will not be forced to compile (it will be interpreted).  When using System.currentTimeMillis() on the Mac this is not an issue since the apparent JVM timer resolution is 1 millisecond, but if you used a native timer you would obtain inconsistent results.

Are you planning to build in native timer support in future releases?

Craig
19  Java Game APIs & Engines / Java 2D / Re: GAGE Engine Early Access on: 2003-04-01 23:30:36
How are you calculating resolution?

Are you exercising HotSpot enough to force it to compile the code? I've read that this requires at least 1000 calls to a method. How about something like:

// Error expected in measured elapsed time in nanoseconds
public long getResolution()
{
     final byte NTIMES = 10;
     long t1, t2;
     long dt = 0L;

       // Warm up JIT/HotSpot compiler
     for (short s=0; s<3000; ++s)
           t1 = getCounter();

       for (byte b=0; b<NTIMES; ++b)
       {
           t1 = getCounter();
           t2 = getCounter();
           while (t1 == t2)
                 t2 = getCounter();
           dt += (t2 - t1);
     }
         return dt/NTIMES;
}

- Craig
20  Game Development / Performance Tuning / Native hi-rez timer for Mac on: 2003-03-28 19:12:23
1. Grab these 3 classes (slightly modified) from the book "Java 1.4 Game Programming":
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// File:        BaseClock.java
// Description: Define a clock's capabilities
// From:        Chapter 12, "Java 1.4 Game Programming"
//              by Mulholland & Murphy, ISBN 1-55622-963-1

public abstract class BaseClock
{
     public abstract long getTime();
     public abstract int  getDefaultUnit();
     public abstract void stampTime();
     public abstract long getElapsedTime();
     public abstract long getElapsedTime(int unit);      

     public long stampTime;

     public static final int UNIT_SECONDS =          1;      //      10^0
     public static final int UNIT_MILLIS  =       1000;      //      10^3
     public static final int UNIT_MICROS  =    1000000;      //      10^6
     public static final int UNIT_NANOS   = 1000000000;      //      10^9
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// File:        StandardClock.java
// Description: A standard pure Java clock
// From:        Chapter 12, "Java 1.4 Game Programming"
//              by Mulholland & Murphy, ISBN 1-55622-963-1

public class StandardClock extends BaseClock
{      
     public long getTime()
     {
           return System.currentTimeMillis();
     }

     public int getDefaultUnit()
     {
           return UNIT_MILLIS;
     }

     public void stampTime()
     {
           stampTime = System.currentTimeMillis();
     }

     public long getElapsedTime()
     {
           return System.currentTimeMillis() - stampTime;
     }

     public long getElapsedTime(int unit)
     {
           return ((System.currentTimeMillis() - stampTime) * unit) / UNIT_MILLIS;
     }
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// File:        HiresTimeExample.java
// Description: Test hi-rez native clocks
// From:        Chapter 12, "Java 1.4 Game Programming"
//              by Mulholland & Murphy, ISBN 1-55622-963-1

public class HiresTimeExample
{
     public static void main(String[] args)
     {
           BaseClock clock = null;

//            if ( NativeWinClock.isAvailable() )
           if ( NativeMacClock.isAvailable() )
           {
                 System.out.println("Using native clock");
//                  clock = new NativeWinClock();
                 clock = new NativeMacClock();
           }
           else
           {
                 System.out.println("Using standard clock");
                 clock = new StandardClock();
           }

           // Constant velocity vector (u,v) = (dx/dt, dy/dt)
           // is defined in pixels per microsecond.
           // Magnitudes 160 and 240 represent pixels per second.      
           double u = (double)160 / BaseClock.UNIT_MICROS;
           double v = (double)240 / BaseClock.UNIT_MICROS;

           // current position to update with movement
           double x = 0;
           double y = 0;

           long dt;      // elapsed time

           long counter = 0L;
           int secondsCounter = 0;

           clock.stampTime();

           while (secondsCounter<10) // if not passed 10 seconds
           {
                 // get elasped time
                 dt = clock.getElapsedTime(BaseClock.UNIT_MICROS);

                 // stamp clock
                 clock.stampTime();

                 // increase elasped time counter
                 counter += dt;

                 // update world (move sprite)
                 x += (u * dt);
                 y += (v * dt);

                 if (counter >= BaseClock.UNIT_MICROS) // if 1 second has elapsed
                 {
                       System.out.println("Time (seconds): " + clock.getTime());
                       System.out.println("Elapsed time counter = " + counter);
                       counter -= BaseClock.UNIT_MICROS;
                       System.out.println("Pos = " + x + ", " + y);
                       secondsCounter++;
                 }

                 // Note: sleep() is not high-resolution,
                 //       it is a source of timing error.
                 try
                 {
                       Thread.sleep(5);
                 }
                 catch (Exception e) {}
           }
     }
}

2. Write a Java program 'NativeMacClock.java' (similar to 'NativeWinClock.java') which calls the native timer:

// File:        NativeMacClock.java
// Author:      Craig A. Mattocks
// Date:        March 2003
// Description: Native hi-rez Apple Macintosh clock
// Reference:   Chapter 12, "Java 1.4 Game Programming"
//              by Mulholland & Murphy, ISBN 1-55622-963-1

public class NativeMacClock extends BaseClock
{
     // JNI timer method. Keyword 'native' --> C function.
     // Method declaration only, implementation is in file 'MacClock.c'
     private native long getCounter();

     // Global class instance vars
     private long frequency;
     private static boolean available;

     // Constructor
     public NativeMacClock()
     {
           frequency = UNIT_NANOS;      // Macintosh clock has nanosecond precision
     }

     // Class methods
     public long getTime()
     {
           return getCounter() / frequency;      // Time returned in seconds
     }

     public int getDefaultUnit()
     {
           return UNIT_SECONDS;
     }

     public void stampTime()
     {
           stampTime = getCounter();

//            System.out.println("Time stamp: " + stampTime);      // Verify precision
     }

     public long getElapsedTime()
     {
           return ((getCounter() - stampTime) * UNIT_MILLIS) / frequency;
     }

     public long getElapsedTime(int unit)
     {
           return ((getCounter() - stampTime) * unit) / frequency;
     }

     public static boolean isAvailable()
     {
           return available;
     }

     // Static initializer executes once, when
     // class is loaded by runtime system.
     // Loads compiled C shared library:  libMacClock.jnilib (Mac OS X)
     static
     {
           try
           {
                 System.loadLibrary("MacClock");
                 available = true;
           }
           catch (UnsatisfiedLinkError ulp) {}
           catch (SecurityException sex)       {}
     }
}

3. Compile the Java class that calls the native method:

javac -O NativeMacClock.java

4. Generate a header file for the native method using javah with the native interface flag -jni:

javah -jni NativeMacClock

5. Examine the header file and grab the JNIEXPORT signature for the native method:

more NativeMacClock.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class NativeMacClock */

#ifndef _Included_NativeMacClock
#define _Included_NativeMacClock
#ifdef __cplusplus
extern "C" {
#endif
#undef NativeMacClock_UNIT_SECONDS
#define NativeMacClock_UNIT_SECONDS 1L
#undef NativeMacClock_UNIT_MILLIS
#define NativeMacClock_UNIT_MILLIS 1000L
#undef NativeMacClock_UNIT_MICROS
#define NativeMacClock_UNIT_MICROS 1000000L
#undef NativeMacClock_UNIT_NANOS
#define NativeMacClock_UNIT_NANOS 1000000000L
/* Inaccessible static: available */
/*
* Class:     NativeMacClock
* Method:    getCounter
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_NativeMacClock_getCounter
 (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

6. Create the C source file 'MacClock.c' which contains the native timer method. Include the header and insert the above JNIEXPORT method signature (with appropriate parameters!):

// File:        MacClock.c
// Author:      Craig A. Mattocks
// Date:        March 2003
// Description: Native hi-rez Apple Macintosh timer
//              Returns elapsed time in nanoseconds
//              since the machine was last booted.

#include <Carbon/Carbon.h>
#include "NativeMacClock.h"

JNIEXPORT jlong JNICALL Java_NativeMacClock_getCounter(JNIEnv *env, jobject this)
{
     union
     {
           Nanoseconds ns;
           UInt64 i;
     } time;

     time.ns = AbsoluteToNanoseconds( UpTime() );
     return time.i;
}

7. Compile the header and implementation files, building the JNI library as a bundle:

cc -bundle -I/System/Library/Frameworks/JavaVM.framework/Headers -o libMacClock.jnilib -framework JavaVM -framework CoreServices MacClock.c

8. Move the JNI library to an appropriate place (optional):

mv libMacClock.jnilib /Library/Java/Extensions/

then let Java know where it can be found, either by using the:

-Djava.library.path="/Library/Java/Extensions"

option on the command line or in your information property list, or by setting the environment variables:

setenv DYLD_LIBRARY_PATH .:/Library/Java/Extensions:/usr/local/lib
setenv LD_LIBRARY_PATH .:/Library/Java/Extensions

9. Compile and run the timer example:

javac -O HiresTimeExample.java
java HiresTimeExample

Hooray, it works!
Craig
21  Game Development / Shared Code / Re: Beginners drawing on: 2003-02-28 06:58:25
Hi juddman,

Nice code examples - thank you!!!

I hacked on your DrawingBasics source to include a start/stop animation capability, as per Sun's timer examples:

/*
* @(#)DrawingLessons.java 1.0 03/01/11
*
* You can modify the template of this file in the
* directory ..\JCreator\Templates\Template_1\Project_Name.java
*
* You can also create your own project template by making a new
* folder in the directory ..\JCreator\Template\. Use the other
* templates as examples.
*
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

class DrawingBasics extends JFrame
{
     BubbleSprite[] sprites = new BubbleSprite[1000];
     
     JmGraphicsPanel gpane = new JmGraphicsPanel();
     int curFill = 0;
     JPanel cp;
     JButton addSpr = new JButton("Add sprite");
     JButton startButton = new JButton("Start");
     JButton stopButton  = new JButton("Stop");

     Timer timer;
     boolean frozen = true;      // Animation frozen?

     ActionListener timedAction = new ActionListener()
     {
           public void actionPerformed(ActionEvent e)
           {
                 go();
           }
     };

//--------------------------------------------------------------------//

     // Constructor
     public DrawingBasics(int fps, String windowTitle)
     {
           super(windowTitle);

           // Compute frame delay
           int delay = (fps > 0) ? (1000 / fps) : 100;      // Milliseconds

           // Set up a timer that calls this object's action handler.
           timer = new Timer(delay, timedAction);
           timer.setInitialDelay(0);      // Start up immediately
           timer.setCoalesce(true);      // Prevent event flooding

           for (int i = 0; i < sprites.length; i++)
                 sprites = null;

           // Sprite #1
           BubbleSprite tmp = new BubbleSprite( 80, 100, 30, 70);
           addSprite(tmp);
           
           // Sprite #2
            tmp = new BubbleSprite( 40, 40, 80, 50);
           tmp.setFillColor (Color.green);
           tmp.setLineColor(Color.yellow);
           addSprite(tmp);

           // Sprite #3
            tmp = new BubbleSprite( 45, 45, Math.random()*100, Math.random()*100);
           tmp.setFillColor (Color.orange);
           tmp.setLineColor(Color.magenta);
           addSprite(tmp);
           
           // Create user interface
           cp = (JPanel)getContentPane();
           cp.setLayout(new BorderLayout());
           
           cp.add(gpane, BorderLayout.CENTER);

           JPanel controlPanel = new JPanel();
           controlPanel.setLayout( new GridLayout(1,3) ); // GridLayout (rows, cols, dx, dy)
           controlPanel.add(addSpr);
           controlPanel.add(startButton);
           controlPanel.add(stopButton);

           cp.add(controlPanel, BorderLayout.SOUTH);
           
           gpane.setGraphicArray(sprites);
           
           addSpr.addActionListener
           (
                 new ActionListener()
                 {
                       public void actionPerformed(ActionEvent e)
                       {
                             addRandomSprite();
                       }
                 }
           );

           startButton.addActionListener
           (
                 new ActionListener()
                 {
                       public void actionPerformed(ActionEvent e)
                       {
                             if (frozen)
                             {
                                   frozen = false;
                                   startButton.setEnabled(false);
                                   stopButton.setEnabled(true);
                                   startAnimation();
                             }
                       }
                 }
           );

           stopButton.addActionListener
           (
                 new ActionListener()
                 {
                       public void actionPerformed(ActionEvent e)
                       {
                             if (! frozen)
                             {
                                   stopAnimation();
                                   frozen = true;
                                   startButton.setEnabled(true);
                                   stopButton.setEnabled(false);
                             }
                       }
                 }
           );

//            timer.start();      // Autostart (disabled)
           
           // Window closing listener
           addWindowListener
           (
                 new WindowAdapter()
                 {
                       public void windowDeiconified(WindowEvent e)
                       {
                             if (frozen)
                             {
                                   frozen = false;
                                   startButton.setEnabled(false);
                                   stopButton.setEnabled(true);
                                   startAnimation();
                             }
                       }
                       public void windowIconified(WindowEvent e)
                       {
                             if (! frozen)
                             {
                                   stopAnimation();
                                   frozen = true;
                                   startButton.setEnabled(true);
                                   stopButton.setEnabled(false);
                             }
                       }
                       public void windowClosing(WindowEvent e)
                       {
                             stopAnimation();
                             dispose();
                             System.exit(0);
                       }  
                 }
           );

     }

//--------------------------------------------------------------------//

     public void go()
     {
           for (int i=0; i<sprites.length; i++)
           {
                 if (sprites != null)
                 sprites.randomMotion();
                 else break;
           }
           //System.out.print(".");
           gpane.repaint();
     }

//--------------------------------------------------------------------//

     // Can be invoked by any thread (since timer is thread-safe).
     public synchronized void startAnimation()
     {
           if (frozen)
           {
                 // Do nothing.  The user has requested
                 // that we stop changing the image.
           }
           else
           {
                 // Start animating!
                 if ( !timer.isRunning() )
                 {
                       timer.start();
                 }
           }
     }

//--------------------------------------------------------------------//

     // Can be invoked by any thread (since timer is thread-safe).
     public synchronized void stopAnimation()
     {
           // Stop the animating thread.
           if ( timer.isRunning() )
           {
                 timer.stop();
           }
     }

//--------------------------------------------------------------------//

     public void addSprite(BubbleSprite in)
     {
           sprites[curFill] = in;
           curFill ++;
     }

//--------------------------------------------------------------------//

     public void addRandomSprite()
     {
            BubbleSprite tmp = new BubbleSprite( 45, 45, Math.random()*100, Math.random()*100);
            int col1 = (int)(Math.random()*255);
            int col2 = (int)(Math.random()*255);
            int col3 = (int)(Math.random()*255);
            System.out.print ("" + col1 + col2 + col3);
           tmp.setFillColor (new Color(col1, col2, col3));
           tmp.setLineColor(Color.magenta);
           addSprite(tmp);
     }

//--------------------------------------------------------------------//

     public static void main(String args[])
     {
           System.out.println("Starting DrawingBasics...");

           int fps = 10;      // 1000 ms = 1 sec so we expect 10 fps.

           // Get frames per second from the command line argument.
           if (args.length > 0)
           {
                 try
                 {
                       fps = Integer.parseInt(args[0]);
                 }
                 catch (Exception e) {}
           }

           DrawingBasics mainFrame = new DrawingBasics(fps, "Sprite Animator");
           mainFrame.setSize(400, 400);
           mainFrame.setTitle("DrawingBasics");
           mainFrame.setVisible(true);
     }

}

- Craig
Pages: [1]
 

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

The first screenshot will be displayed as a thumbnail.

CogWheelz (16 views)
2014-07-30 21:08:39

Riven (22 views)
2014-07-29 18:09:19

Riven (14 views)
2014-07-29 18:08:52

Dwinin (12 views)
2014-07-29 10:59:34

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

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

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

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

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

Riven (31 views)
2014-07-23 20:56:16
List of Learning Resources
by SilverTiger
2014-07-31 13:54:12

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