TexturePaint

Olá!

Apliquei uma textura em um grid e o programa ficou MUITO lerdo…

Gostaria de saber se há alguma forma de torná-lo mais eficiente.

Obrigada!

Como vc fez para aplicar essa textura?

O texture paint do java não é mesmo um grande modelo de eficiência. =(

Olá novamente ViniGodoy!

Fiz esse método para carregar a imagem…

[code]public BufferedImage textura(String filename)
throws IOException, ImageFormatException {

     // Carrega o arquivo JPEG
  InputStream in = getClass().getResourceAsStream(filename);

  JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(in);
   mImage = decoder.decodeAsBufferedImage();
   in.close();
   return mImage;

}[/code]

E esse daqui desenha o grid…

 public void draw(Graphics2D g2) throws IOException {

        Rectangle2D tr = new Rectangle2D.Double(rect.getX(), rect.getX(),rect.getWidth(),rect.getHeight());
        BufferedImage image = textura("img.jpg");
        BufferedImage barco1 = textura ("trirreme.jpg");
   
        TexturePaint tp = new TexturePaint(image, tr);
        TexturePaint barco1_txt = new TexturePaint(barco1, tr);



        g2.setPaint(selected ? barco1_txt :tp);
        g2.fill(rect);
        g2.setPaint(color);
        g2.draw(rect);
         
       }

Funciona legal, redimensiona com a textura e tal…
O problema é que ficou tãoooo lerdo… :frowning:

Obrigada!

Uma coisa que você pode fazer é tentar aumentar as chances de aceleração da imagem. Para isso, você precisa convertê-la em uma imagem que seja compatível com a tela.

Mude seu método de carga para:

public BufferedImage textura(String filename) {  
   // Carrega o arquivo JPEG  
   try {
      BufferedImage img = ImageIO.read(getClass().getResourceAsStream(filename));

      //Criamos uma área com as mesmas configurações gráficas da tela
      BufferedImage compatible = GraphicsEnvironment
         .getLocalGraphicsEnvironment()
         .getDefaultScreenDevice().getDefaultConfiguration()
         .createCompatibleImage(img.getWidth(), img.getHeigth(),
         Transparency.OPAQUE);
      //Copiamos a imagem para essa nova área. O java fará a conversão, se necessário.
      Graphics2D g2d = compatible.createGraphics();
      g2d.drawImage(0,0, img, null);
      g2d.dispose();
      //Retornamos a imagem com as mesmas configurações da tela
      return compatible;
   } catch (Exception e) {
      //Como vc carregar do jar, e tudo vai existir, é melhor converter a exception para Runtime
      //Assim você evita que o java fique te pentelhando. 
      //Deixa as exception só para quando for carregar do disco.
      throw new RuntimeException("Não foi possível criar a imagem", e);
   }
}  

Na prática, o java é obrigado a fazer essa conversão sempre que a imagem estiver fora do formato da tela. Porém, sem esse código, ele fará a cada pintura. A idéia aqui é fazer a conversão previamente, e deixar que na etapa de pintura ele só se preocupe em desenhar a imagem.

Isso faz com que o java aumente as chances de desenhar usando a placa de vídeo, o que é centenas de vezes mais rápido do que pintar pixel-a-pixel.

Outra coisa. Você deve evitar que seus métodos baguncem o objeto graphics. Senão eles passarão a afetar outros métodos.

Adicione na linha 2:

Graphics2D g2d = (Graphics2D) g2.create();

E na linha 16:

g2d.dispose();

E use o g2d para desenhar no lugar do g2.

Isso vai evitar que esse método “suje” o graphics2D e o java saia aplicando texture paint no que vier depois dele.
Aliás, acostume-se a fazer essa cópia sempre que for alterar algum atributo do Graphics2D (ou seja, sempre que for usar um “set”).

Por que vc está pintando com Graphics2D? Está fazendo algum jogo?

Fiz umas correçõezinhas ali, erros que eram frutos de CTRLC+CTRLV. :oops:

Aquele código é o mesmo que uso para acelerar o desenho das partículas no meu Particles.

É sim!
Pensei que dava pra perceber pelas imagens água e barco.jpg…heehehe

Estou fazendo um jogo de batalha naval!
:shock:

Obrigada de novo pela ajuda! :wink:
Vou testar aqui.

Ops, o seu método draw também tem outro erro. E dessa vez bem crasso.

JAMAIS, NUNCA, NEVER, carregue arquivos no método draw(). Isso fará com que a imagem seja recarragada do disco sempre, no meio do ciclo de pintura, e seu FPS vai despencar. Entenda que o draw é chamado diversas vezes. Ele é chamado sempre que a imagem precisa ser redesenhada. Se você tive um game loop, ele vai precisar ser chamado mais de 20 vezes por segundo (o ideal é umas 60 vezes).

O disco é extremamente lento. Leva-se muito tempo para carregar a imagem delá.
Por isso, você precisa carregar a textura na memória, e no método draw só usar o que está na memória.

Na classe que desenha o grid, crie os atributos separadamente:

public class ClasseDoGrid {
   BufferedImage image = textura("img.jpg");
   BufferedImage barco1 = textura("trirreme.jpg");

Isso fará que as texturas sejam carregadas do disco apenas uma única vez.

Depois, no método draw, só desenhe:

[code] public void draw(Graphics2D g2) throws IOException {
Rectangle2D tr = new Rectangle2D.Double(rect.getX(), rect.getX(),rect.getWidth(),rect.getHeight());
Graphics2D g2d = (Graphics2D) g2.create();

    g2d.setPaint(selected ? barco1_txt :tp);
    g2d.fill(rect);
    g2d.setPaint(color);
    g2d.draw(rect);         

    g2d.dispose();

}
[/code]

Como as imagens agora estão pré-carregadas nos atributos (ou seja, na memória), não se perde tempo puxando coisas do disco.

PS: Você já leu os artigos de java 2D do meu portal? Dão diversas dicas de pintura, inclusive essas.

Ahhhhh siimm…

hhehe…tava desenhando umas 200X :shock: …heheh

Muito muito muito obrigada novamente!!

RespPS: essa página http://www.pontov.com.br/site/index.php/java/48-java2d/111-trabalhando-com-imagens ?

[quote=flanoriko]Ahhhhh siimm…

hhehe…tava desenhando umas 200X :shock: …heheh

Muito muito muito obrigada novamente!!

RespPS: essa página http://www.pontov.com.br/site/index.php/java/48-java2d/111-trabalhando-com-imagens ?
[/quote]

Pior que isso, vc tava carregando do disco várias vezes.

Sim, mas tem vários artigos de Java por lá.
Eu estou terminando a série de OpenGL (blending será o último tópico) aí pretendo voltar a falar mais do Java 2D.