Hardware Graphics Acceleration in Applet

I’ve found the following thread http://www.java-gaming.org/index.php/topic,21919.0.html. It definitely uses hardware for rendering since I get arounf 500 fps (without the limiter). However, I want my game to be running as an applet on www. But when I try to make an applet from that tutorial code I get errors:

“java.lang.reflect.InvocationTargetException
at com.sun.deploy.util.DeployAWTUtil.invokeAndWait(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.runOnEDT(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkExit(Unknown Source)
at javax.swing.JFrame.setDefaultCloseOperation(Unknown Source)
at thegame.Game.(Game.java:43)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$12.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception: java.lang.reflect.InvocationTargetException”

I see some problem with access. Is this even possible to use full hardware in applet? (so far I’ve managed to use Graphics2D to speed up rendering and it works, but not as fast as code from the above-mentioned tutorial).

The stack trace clearly shows what is causing the SecurityException, and the line of your code that is responsible for it.


   at javax.swing.JFrame.setDefaultCloseOperation(Unknown Source)
   at thegame.Game.<init>(Game.java:43)

Line 43 of your class thegame.Game is invoking JFrame#setDefaultCloseOperation(…), a security restricted method - but completely unrelated to graphics hardware acceleration.

Remove this line & it’ll work fine (or fail somewhere else).

Thanks. I mislooked that cause I was in a hurry when I was testing it.
So, I’ve made some changes in the code and now it can also run as an applet but… nothing renders. Isn’t it that an applet must use paint method and draw something with Graphics object? But afaik it doesn’t use hardware and I really need full hardware support in applet.

I’ll post the whole code. I know I shouldn’t but I’ve made clean and short and I think someone who already dealt with all these canvases and buffer strategies will easily find problem:


package thegame;

import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JApplet;
import javax.swing.JFrame;

public class Game extends JApplet implements Runnable
{
	final int WIDTH = 1000;
	final int HEIGHT = 700;
	public Canvas canvas;
	public BufferStrategy bufferStrategy;

	public void start1()
	{
		canvas = new Canvas();
		canvas.setBounds(0, 0, WIDTH, HEIGHT);
		canvas.setIgnoreRepaint(true);
		this.add(canvas);
	}

	public void start2()
	{
		canvas.createBufferStrategy(2);
		bufferStrategy = canvas.getBufferStrategy();
		canvas.requestFocus();
	}

	long desiredFPS = 120;
	long desiredDeltaLoop = (1000 * 1000 * 1000) / desiredFPS;
	boolean running = true;

	public void run()
	{
		long beginLoopTime;
		long endLoopTime;
		long currentUpdateTime = System.nanoTime();
		long lastUpdateTime;
		long deltaLoop;

		while (running)
		{
			beginLoopTime = System.nanoTime();

			lastUpdateTime = currentUpdateTime;
			currentUpdateTime = System.nanoTime();

			update((int) ((currentUpdateTime - lastUpdateTime) / (1000 * 1000)));
			render();

			endLoopTime = System.nanoTime();
			deltaLoop = endLoopTime - beginLoopTime;

			/*
			if(deltaLoop > desiredDeltaLoop){
			//Do nothing. We are already late.
			}else{
			try{
			Thread.sleep((desiredDeltaLoop - deltaLoop)/(1000*1000));
			}catch(InterruptedException e){
			//Do nothing
			}
			}*/
		}
	}

	private void render()
	{
		Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
		g.clearRect(0, 0, WIDTH, HEIGHT);
		g.fillRect((int) x, 0, 200, 200);
		g.dispose();
		bufferStrategy.show();
	}

	private double x = 0.0;

	protected void update(int deltaTime)
	{
		System.out.println(deltaTime);
		x += deltaTime * 0.2;
		while (x > 500) {
			x -= 500;
		}
	}

	public void init()
	{
	}

	public void start()
	{
	}

	public static void main(String[] args)
	{
		Game ex = new Game();
		ex.init();
		ex.start1();

		JFrame mainFrame = new JFrame("NetCrush");
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setBounds(0, 0, ex.WIDTH, ex.HEIGHT);
		mainFrame.setVisible(true);
		mainFrame.add(ex);

		ex.start2();
		ex.start();
		new Thread(ex).start();
	}
}


Hello,

here is the code that I use for rendering on applet.

public class BasicApplet extends Applet implements Runnable{
	
	final int width = 800;
	final int height = 600;

	Canvas canvas;
	BufferStrategy bufferStrategy;
	
	public void start(){
		if(bufferStrategy == null){
			setPreferredSize(new Dimension(width, height));
			this.setSize(new Dimension(width, height));
			this.setIgnoreRepaint(true);

			canvas = new Canvas();
			canvas.setBounds(0, 0, width, height);
			add(canvas);
			canvas.setIgnoreRepaint(true);

			canvas.createBufferStrategy(2);
			bufferStrategy = canvas.getBufferStrategy();

			canvas.addMouseListener(new MouseControl());
			canvas.addMouseMotionListener(new MouseControl());
			canvas.requestFocus();
			
			
		}
		new Thread(this).start();
	}
	
	private class MouseControl extends MouseAdapter{
		
	}
	
	long desiredFPS = 600;
    long desiredDeltaLoop = (1000*1000*1000)/desiredFPS;
    
	boolean running = true;
	
	public void run(){
		
		long beginLoopTime;
		long endLoopTime;
		long currentUpdateTime = System.nanoTime();
		long lastUpdateTime;
		long deltaLoop;
		
		while(!isActive()){
			Thread.yield();
		}
		while(running){
			beginLoopTime = System.nanoTime();
			
			render();
			
			lastUpdateTime = currentUpdateTime;
			currentUpdateTime = System.nanoTime();
			update((int) ((currentUpdateTime - lastUpdateTime)/(1000*1000)));
			
			endLoopTime = System.nanoTime();
			deltaLoop = endLoopTime - beginLoopTime;
	        
	        if(deltaLoop > desiredDeltaLoop){
	            //Do nothing. We are already late.
	        }else{
	            try{
	                Thread.sleep((desiredDeltaLoop - deltaLoop)/(1000*1000));
	            }catch(InterruptedException e){
	                //Do nothing
	            }
	        }
	        if(!isActive()){
	        	System.out.println("Inactive");
	        	return;
	        }
		}
	}
	
	private void render() {
		try{
			Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
			g.clearRect(0, 0, width, height);
			render(g);
			g.dispose();
			bufferStrategy.show();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	//TESTING
	private double x = 0;
	
	/**
	 * Overwrite this method in subclass
	 */
	protected void update(int deltaTime){
		x += deltaTime * 0.2;
		while(x > 500){
			x -= 500;
		}
	}
	
	/**
	 * Overwrite this method in subclass
	 */
	protected void render(Graphics2D g){
		g.fillRect((int)x, 0, 200, 200);
	}

}

It might not be the best code because I’m not very experimented with applet but it work (for now).

There is 2 principals things to note : first there is no main method and no constructor. Put this code in the start method. Second when you start the game, wait until the applet is active or it will stop the running method. This is why I add this code

while(!isActive()){
			Thread.yield();
		}

Thanks for your template, Guadradain. I totally forgot that applet doesn’t perform any code from main so my initializaing functions start1 and start2 were in fact never called. I’ve put their code to applet’s start and now it works fine.