Java2D acelerado

2 respostas
Fox_McCloud

Pessoal, bom dia.

Faz algum tempo que eu estudo e pesquiso meios de fazer jogos em Java.

Usando janelinha JFrame, o melhor meio que encontrei foi desativar o repaint() e criar o meu próprio paint(), chamado de acordo com a Thread principal do jogo, fazendo um active rendering na mão usando uma BufferedImage como buffer...

Além disso, em tela cheia, o melhor jeito até agora é utilizar a FullScreen Exclusive Mode API. Com ela a JVM já usa automaticamente o que o sistema operacional disponibilizar de aceleração gráfica, e em conjunto com o uso de BufferStrategy, a renderização faz automaticamente o uso de um ou mais buffers na renderização ativa...

Entretanto, os dois jeitos têm um problema (grave, no meu entendimento). Imagens com transparência, sejam canal alpha ou imagens PNG, matam a aceleração. Principalmente no modo de tela cheia, que fornece um objeto Graphics, e não o Graphics2D relativo à BufferedImage, então perde-se também nesse modo as características fornecidas pela BufferedImage...

Eu percebi que a aceleração melhora quando setamos RenderingHints no objeto Graphics2D (código abaixo), o que é meio estranho, já que colocando anti-serrilhado e melhorando a qualidade da renderização, coisas que exigem mais processamento, a qualidade aumenta. É como se a JVM só percebesse que pode usar aceleração quando eu forço uma renderização mais pesada... Mas de qualquer forma o canal alpha arruina a aceleração assim mesmo.

public abstract class BufferManager {

	/* ... */

	private static final Map<Key, Object> hints = loadRenderingHints();
	private BufferedImage buffer;
	private Graphics2D g2;

	private void prepareBuffer(){
		buffer = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
		g2 = buffer.createGraphics();
		g2.setRenderingHints(hints);
	}

	private static Map<Key, Object> loadRenderingHints() {
		Map<Key, Object> hints = new HashMap<Key, Object>();
		
		hints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
		hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		hints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
		hints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DEFAULT);
		hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT);
		hints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
		hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
		hints.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
		hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		
		return hints;
	}

	/* ... */
	
}
Finalmente a pergunta... quem conhece meios de forçar a utilização de aceleração gráfica na renderização 2D? Ou seja, como usar um pipeline OpenGL pra renderizar 2D (algum tutorial), ou ainda quais melhorias o Java 6 oferece nesse sentido e como utilizá-las? Aceito conselhos em geral nesse sentido...

Obrigado.

2 Respostas

M

Tai uma coisa que também queria saber.

Fox_McCloud

O que eu sei é que no Java 6 update 10 (a partir dessa versão específica), devido ao Nimbus Look and Feel, que utiliza transparência acelerada com canal alpha real (incluindo renderização acelerada em tempo real de trensparências e imagens PNG com canal alpha), eles foram obrigados a elevar o nível do Java 2D, ou seja, o que está disponível no novo Nimbus é devido às melhorias da API.

Resumindo: Provavelmente o simples uso do Java 6 update 10 deve automagicamente resolver vários problemas de performance da API 2D, incluindo transparências. Claro que utilizando as técnicas adequadas como: Fullscreen Exclusive Mode API, Graphics2D, BufferedImage, BufferStrategy, Window.createBufferStrategy(numBuffers), Window.getBufferStrategy().getDrawGraphics() e afins… lembrando que em máquinas com aceleração gráfica disponível o objeto Graphics devolvido é um Graphics2D, tornando possível fazer um casting…

Exemplo de uso do getDrawGraphics (considerado que o createBufferStrategy() foi invocado):

Enfim… vale a pena estudar essas técnicas e experimentá-las usando o Java 6 update 10… deve dar uma bela turbinada nos gráficos acelerados 2D!

:wink:

obs: onde coloquei Window.metodo(), fique claro que tais métodos não são estáticos, fiz isso apenas pela praticidade de indicar que esse método é herdado da classe Window!

Criado 25 de fevereiro de 2008
Ultima resposta 10 de nov. de 2008
Respostas 2
Participantes 2