Java3D - zmiana tła

0

Witam,

od pewnego czasu męczę się niemiłosiernie próbując zmienić istniejące już tło w moim SimpleUniverse. Wstawienie tła początkowego to żaden problem, problem pojawia się gdy chcę podmienić to tło w trakcie działania programu. Nie mam już pojęcia co robię źle. Napisałem funkcję, która po wybraniu pozycji w menu ma to tło zmieniać ale wyskakuje mi NullPointerException. Sprawdzałem więc czy wczytywany obraz do tła istnieje i istnieje... Bardzo proszę o pomoc. Gdzie popełniam błąd, może w złym miejscu wywołuję metodę setCapability?
Oto kody:

public class Panel3D extends JPanel {
	SimpleUniverse universe;
	Canvas3D canvas3D;
	Image ball = null;
	BufferedImage biBall = null;
	BufferedImage bi = null;
	BranchGroup scene;
	Background back;
	InputStream is;
	BranchGroup objRoot;
	
	
	Panel3D(){
		super();
        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
        canvas3D = new Canvas3D(config);
        canvas3D.setSize(new Dimension(640,480));
        add("Center", canvas3D);
        
        scene = szescian();
        universe = new SimpleUniverse(canvas3D);
        universe.getViewingPlatform().setNominalViewingTransform();
        universe.addBranchGraph(scene);
        this.setSize(640, 580);
	}
	
	
	public void zmien(BufferedImage i){
		//zakomentowana jest moja pierwsza wersja, też nie działa**foo**
		//bi = toBufferedImage(i);
		
        TextureLoader backgroundTexture = new TextureLoader(i, this);
        back.setImage(backgroundTexture.getImage());

		
		/*try{
		back.setImage(new ImageComponent2D(i.getType(), i));
		}catch (Exception e) {
			System.out.println("TUTAJ!");
			e.printStackTrace();
		}*/
	
	}
	
	
	
	
	public BufferedImage toBufferedImage(Image image) {
	    if (image instanceof BufferedImage) {
	        return (BufferedImage)image;
	    }

	    // This code ensures that all the pixels in the image are loaded
	    image = new ImageIcon(image).getImage();

	    // Determine if the image has transparent pixels; for this method's
	    // implementation, see Determining If an Image Has Transparent Pixels
	    boolean hasAlpha = true;

	    // Create a buffered image with a format that's compatible with the screen
	    BufferedImage bimage = null;
	    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
	    try {
	        // Determine the type of transparency of the new buffered image
	        int transparency = Transparency.OPAQUE;
	        if (hasAlpha) {
	            transparency = Transparency.BITMASK;
	        }
	        
	        // Create the buffered image
	        GraphicsDevice gs = ge.getDefaultScreenDevice();
	        GraphicsConfiguration gc = gs.getDefaultConfiguration();
	        bimage = gc.createCompatibleImage(
	            image.getWidth(null), image.getHeight(null), transparency);
	    } catch (HeadlessException e) {
	        // The system does not have a screen
	    }

	    if (bimage == null) {
	        // Create a buffered image using the default color model
	        int type = BufferedImage.TYPE_INT_RGB;
	        if (hasAlpha) {
	            type = BufferedImage.TYPE_INT_ARGB;
	        }
	        bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
	    }
	    // Copy image to buffered image
	    Graphics g = bimage.createGraphics();

	    // Paint the image onto the buffered image
	    g.drawImage(image, 0, 0, null);
	    g.dispose();

	    return bimage;
	}
	
	
	void obraz(){
		
		try {
			is = new BufferedInputStream(new FileInputStream("photo.png"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		try {
			ball = ImageIO.read(is);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		biBall = toBufferedImage(ball);
	}
		
	
BranchGroup szescian(){
		
		obraz();
		objRoot = new BranchGroup();
		objRoot.setCapability(Background.ALLOW_IMAGE_WRITE);

		// rotate object has composited transformation matrix
		Transform3D rotate = new Transform3D();
		Transform3D tempRotate = new Transform3D();
		Transform3D scale = new Transform3D();
		Transform3D vector = new Transform3D();
		

	        rotate.rotX(Math.PI/4.0d);
		tempRotate.rotY(Math.PI/5.0d);
		scale.setScale(0.5d);
		vector.set(new Vector3d(0.5, 1.0, 0.5));
	        rotate.mul(tempRotate);
	        rotate.mul(scale);
	        rotate.mul(vector);

		TransformGroup objRotate = new TransformGroup(rotate);

		objRoot.addChild(objRotate);
		objRotate.addChild(new ColorCube(0.4));
		// Let Java 3D perform optimizations on this scene graph.
		
		Background back = new Background(new ImageComponent2D(BufferedImage.TYPE_INT_ARGB, biBall));
		BoundingSphere b = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 50.0);
		    back.setApplicationBounds(b);
		    back.setCapability(Background.ALLOW_IMAGE_WRITE);

		    //back.setColor(0.17f, 0.65f, 0.92f);  
		                  // sky colour
	
		    objRoot.addChild( back );
	        objRoot.compile();

		return objRoot;
		

		

	}

}

Klasa korzystająca z tego panela:


public class Ramka3D extends JFrame implements ActionListener {
	private JMenuBar mb;
	private JMenu m;
	private JMenuItem i1;
	Panel3D p;
	private JFileChooser chooser;
	BufferedImage buf = null;
	
	
	Ramka3D(){
		super("Ramka3D");
		
		mb = new JMenuBar();		
		m = new JMenu("Menu");
		
		mb.add(m);
		i1 = new JMenuItem("Zmień tło");
		i1.addActionListener(this);
		m.add(i1);
		
		p = new Panel3D();
		this.add(p);
		
		chooser = new JFileChooser();
	    chooser.setCurrentDirectory(new File("."));
		
	    //ustawienia ramki:
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setSize(640, 580);
		this.setResizable(true);
		this.setJMenuBar(mb);	
		this.setVisible(true);	
		
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		
		if(e.getSource() == i1){
			int result = chooser.showOpenDialog(null);
			if (result == JFileChooser.APPROVE_OPTION)
             {
                String name = chooser.getSelectedFile().getPath();
        		try{
        			File flPlik =  new File(name);
        			buf =   ImageIO.read(flPlik);
        			}catch(IOException ex){
        				
        			}
        		System.out.println(buf);
        		p.zmien(buf);	
        
              
             }
		}

	}
	
	public static void main(String[] args){
		new Ramka3D();
	}
	
	

}
 
0

Poradziłem sobie:) Błąd był wręcz banalny. W funkcji szescian() dałem linijkę
Background back = new Background(new ImageComponent2D(BufferedImage.TYPE_INT_ARGB, biBall));
zamiast
back = new Background(new ImageComponent2D(BufferedImage.TYPE_INT_ARGB, biBall));
i w ten oto sposób stworzyłem sobie zmienną lokalną zamiast przypisać wartość do zmiennej globalnej.
Teraz już rozumiem skąd się wziął NullPointerException ;D

0

Znalazł się kolejny problem dotyczący tego programu.. Czy wie ktoś może jak stworzyć funkcję, której wywołanie spowoduje przesunięcie istniejącego obiektu o dany wektor? Czy w ogóle można taka funkcję napisań czy konieczne jest tworzenie klasy dziedziczącej po Behavior? Szukam, kombinuje i nie mogę tego okiełznać.

Stworzyłbym sobie taką klasę z zachowaniem, ale nie mogę znaleźć odpowiedniego WakeupCriterion. Ja chcę zwyczajnie wywoływać sobie metodę w dowolnym momencie. Chyba, że ktoś zna sposób na uruchomienie zachowania natychmiast po zmianie tła..

Pewnie nikt mi nie odpisze, ale liczę na cokolwiek, jakiś link przydatny(do tej pory korzystałem głównie z tutoriala Sun'a), dobrą radę..

0

Nie możesz po prostu użyć Transform3D?

0

Stworzyłem sobie jednak klasę dziedziczącą po Behavior. Trochę nakombinowałem, ale coś tam wyszło.. Ja próbowałem zmieniać transformacje w zwykłych metodach ale nie chciało to śmigać.. Może coś robiłem źle. Nie wiem tylko co..

Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1