2010-01-19 2 views
0

이중 버퍼링 페인팅을 호출하는 데 루프를 사용하고 있습니다. 이 메소드는 내 유일한 Panel의 repaint 메소드를 재정의 (override)하는 것과 함께 다시 그리기를 완벽하게 제어하여 내 루프에 전달하고 필요한 경우에만 렌더링합니다 (예 : GUI에서 일부 변경).Java - Graphics.drawImage() 및 2 화면 버퍼 전략으로 많은 이미지 그리기

이 내 렌더링 루틴 :

당신이 볼 수 있듯이
Log.write("renderer painting"); 

    setNeedsRendering(false); 

    Graphics g = frame.getBufferStrategy().getDrawGraphics(); 

    g.setFont(font); 
    g.setColor(Color.BLACK); 
    g.fillRect(0, 0, window.getWidth(),window.getHeight()); 

    if(frame != null) 
     window.paint(g); 

    g.dispose(); 

    frame.getBufferStrategy().show(); 

, 꽤 표준입니다. grpahics 객체를 버퍼 전략 (2로 초기화 됨)에서 가져 와서 모든 검정색으로 만들어 내 "window"객체의 페인트 메서드에 전달합니다.

그래픽 개체를 사용하여 창을 완료 한 후에는 해당 가상 개체의 내용을 처리하고 가상 버퍼의 내용을 표시하는 버퍼 전략에 대해 show를 호출합니다.

윈도우는 그래픽 객체를 다른 많은 하위 구성 요소로 전달하므로 윈도우를 채우고 각 인스턴스는 그래픽 객체의 동일한 인스턴스를 사용하여 텍스트, 모양, 또는 이미지.

시스템이 실행 중이고 큰 이미지가 렌더링 될 때 제 문제가 나타나기 시작합니다. 이미지는 조각으로 절단 된 것처럼 보이고 이미지가 렌더링 될 것으로 예상되는 내부의 다른 오프셋을 사용하여 몇 번 (3-4 회) 그려집니다. 내 첨부 된 이미지를 참조하십시오

을이 원본 이미지 것은 : alt text http://img109.imageshack.us/img109/8308/controller.png

이것은 내가 무엇을 얻을 : 두 번째 사진에서 나는 사진을 통해 모양을 렌더링 오전 alt text http://img258.imageshack.us/img258/3248/probv.png

주 -이 있습니다 항상 올바른 위치에 있어야합니다.

왜 이런 일이 발생하는지 알고 싶습니다. g.drawImage (...) 호출 직전에 메모리에있는 것처럼 이미지를 파일에 저장하면 원본과 동일합니다.

답변

2

어, 스윙을 사용하고 있습니까?
일반적으로 을 스윙하여 이미지를 렌더링하면 사용자가 이미지를 표시 할 수 없습니다. 메서드는 AWT 위젯과 몇 가지 최적화에 대한 메서드 호환성, (포함), 드로잉 (Drawing only), 필요한 경우에만 으로 인해 매우 복잡한 렌더링 루틴을 가지고 있기 때문에 범위를 벗어났습니다! 고속 드로잉 API를 사용하려면 JFrame 및 Window와 같은 BufferStrategy 이있는 구성 요소를 사용하고

setIgnoreRepaint (false);

스윙 렌더링을 끄고 그리기 루프를 설정하고 콘텐츠 자체를 페인트합니다. 또는 OpenGL 렌더링 용 JOGL을 사용할 수 있습니다. 사용중인 메소드는 완전히 올바른 Java2D 사용에 대한 과 같습니다.

여기에 올바른 사용 : 당신의 응답을

public final class FastDraw extends JFrame { 
    private static final transient double NANO = 1.0e-9; 


private BufferStrategy bs; 

private BufferedImage frontImg; 

private BufferedImage backImg; 

private int PIC_WIDTH, 
      PIC_HEIGHT; 

    private Timer timer; 

    public FastDraw() { 
    timer = new Timer(true); 
    JMenu menu = new JMenu("Dummy"); 
    menu.add(new JMenuItem("Display me !")); 
    menu.add(new JMenuItem("Display me, too !")); 
    JMenuBar menuBar = new JMenuBar(); 
    menuBar.add(menu); 
    setJMenuBar(menuBar); 

    setIgnoreRepaint(true); 
    setVisible(true); 
    addWindowListener(new WindowAdapter() { 
     public void windowClosing(WindowEvent evt) { 
     super.windowClosing(evt); 
     timer.cancel(); 
     dispose(); 
     System.exit(0); 
     } 
    }); 
    try { 
     backImg = javax.imageio.ImageIO.read(new File("MyView")); 
     frontImg = javax.imageio.ImageIO.read(new File("MyView")); 
    } 
    catch (IOException e) { 
     System.out.println(e.getMessage()); 
    } 
    PIC_WIDTH = backImg.getWidth(); 
    PIC_HEIGHT = backImg.getHeight(); 
    setSize(PIC_WIDTH, PIC_HEIGHT); 


    createBufferStrategy(1); // Double buffering 
    bs = getBufferStrategy(); 
    timer.schedule(new Drawer(),0,20); 
    } 
    public static void main(String[] args) { 
    new FastDraw(); 
    } 

    private class Drawer extends TimerTask { 

    private VolatileImage img; 

    private int count = 0; 

    private double time = 0; 

    public void run() { 
     long begin = System.nanoTime(); 
     Graphics2D g = (Graphics2D) bs.getDrawGraphics(); 
     GraphicsConfiguration gc = g.getDeviceConfiguration(); 
     if (img == null) 
     img = gc.createCompatibleVolatileImage(PIC_WIDTH, PIC_HEIGHT); 
     Graphics2D g2 = img.createGraphics(); 
     // Zeichenschleife 
     do { 
     int valStatus = img.validate(gc); 
     if (valStatus == VolatileImage.IMAGE_OK) 
      g2.drawImage(backImg,0,0,null); 
     else { 
      g.drawImage(frontImg, 0, 0, null); 
     } 
     // volatile image is ready 
     g.drawImage(img,0,50,null); 
     bs.show(); 
     } while (img.contentsLost()); 
     time = NANO*(System.nanoTime()-begin); 
     count++; 
     if (count % 100 == 0) 
     System.out.println(1.0/time); 
    } 
    } 
+0

감사합니다. 휘발성 이미지의 상태를 확인하는 부분을 이해하지 못합니다. 괜찮 으면 g2로 그립니다. 그렇지 않으면 g로 그립니다. 왜? frontImg와 backImg는이 코드를 디버깅하는 데 사용하는 두 개의 서로 다른 이미지라고 생각하십니까? 또한 휘발성 이미지의 내용이 손실되는 동안 왜 그림을 반복하고 있습니까? – Warlax

+0

귀하의 제안을 구현했지만 문제는 계속 발생합니다. – Warlax

관련 문제