PDA

View Full Version : Texture in Java 3D


PUMA81
10-11-2006, 16:08
Salve a tutti, avrei bisogno di un aiutino...
Come faccio ad applicare una texture su un'altra? mi spiego meglio: ho un parallelepipedo dove ho applicato una texture di mattoni e adesso vorrei applicare in un punto specifico una texture per le finestre. Come si fa?
Grazie e ciao.

PGI-Bis
11-11-2006, 11:41
Se usi almeno la versione 1.3 (siamo alla 1.4 è in dirittura d'arrivo la 1.5) puoi passare per:

setSubImage(java.awt.image.RenderedImage image, int width, int height, int srcX, int srcY, int dstX, int dstY)

di ImageComponent2D.

setSubimage è l'omologo dell'openg-elliano glTexSubimage2D

PUMA81
13-11-2006, 09:35
Non sono molto pratico, potresti spiegarti meglio?
Questo è quello che io ho scritto:


Appearance appB = new Appearance();
TextureLoader tl = new TextureLoader("muro.jpg",null); //Applico una textura in maniera ripetuta
TextureAttributes myTex = new TextureAttributes();
Transform3D myT = new Transform3D();
myT.set(4.0);
myTex.setTextureTransform(myT);
Texture tex = tl.getTexture();
appB.setTextureAttributes(myTex);
appB.setTexture(tex);


//Crea l'aspetto del piano
Appearance appear=new Appearance();

//Carica la texture
TextureLoader loader=new TextureLoader("finestra.jpg",null);
ImageComponent2D image=loader.getImage();

//Crea la texture
Texture2D texture=new Texture2D(Texture.BASE_LEVEL,Texture.RGBA,image.getWidth(),image.getHeight());
texture.setImage(0,image);

//Crea un piano
QuadArray plane=new QuadArray(4,GeometryArray.COORDINATES|GeometryArray.TEXTURE_COORDINATE_2);
Point3f p=new Point3f(-1.0f,1.0f,0.0f);
plane.setCoordinate(0,p);
p.set(-1.0f,-1.0f,0.0f);
plane.setCoordinate(1,p);
p.set(1.0f,-1.0f,0.0f);
plane.setCoordinate(2,p);
p.set(1.0f,1.0f,0.0f);
plane.setCoordinate(3,p);

TexCoord2f q=new TexCoord2f(0.0f,1.0f);
q.set(0,1);
plane.setTextureCoordinate(0,0,q);
q.set(0,0);
plane.setTextureCoordinate(0,1,q);
q.set(1,0);
plane.setTextureCoordinate(0,2,q);
q.set(1,1);
plane.setTextureCoordinate(0,3,q);


//Imposta la texture nell'aspetto
appB.setTexture(texture);


Come faccio a "mettere" la finestra?
Grazie e ciao

PGI-Bis
13-11-2006, 12:51
Ho fatto zic anzichè zac col registro di windows e al momento sono un po' precario. Ti "indirizzo".

Allora, tex è la texture del muro e image è lo ImageComponent2D della finestra.

Quello che dovresti fare è copiare "image" nell'ImageComponent2D di "tex".

ImageComponent2D texImage = (ImageComponent2D)tex.getImage(0);
RenderedImage windowImage = image.getRenderedImage();
textImage.setSubImage(
windowImage,
altezzaFinestra,
larghezzaFinestra,
0, 0, //"origine" della porzione di finestra da copiare
posizioneXFinestraSullImmagineDelMuro,
posizioneYFinestraSullImmagineDelMuro);

Teoricamente non fa una piega ma al momento non posso fare una prova preliminare.

PGI-Bis
14-11-2006, 22:23
PUMA81, ti rispondo "al pubblico ludibrio".

Supponendo di avere due immagini, wall.png e window.png, appiccico window su wall.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import javax.imageio.*;
import com.sun.j3d.utils.universe.*;

public class Main extends WindowAdapter implements Runnable {

public static void main(String[] args) {
SwingUtilities.invokeLater(new Main());
}

private Frame frame = new Frame("3D");
private Canvas3D canvas;

public void run() {
int vertexFormat =
GeometryArray.COORDINATES |
GeometryArray.NORMALS |
GeometryArray.TEXTURE_COORDINATE_2;
float[] coords = {
0, 0, 0,
1, 0, 0,
1, 1, 0,
0, 1, 0,
};
//Dritto negli occhi (z+)
float[] normals = {
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
};
//U = X + Z
//V = Y
float[] uv = {
0, 0,
1, 0,
1, 1,
0, 1,
};
QuadArray tile = new QuadArray(4, vertexFormat);
tile.setCoordinates(0, coords);
tile.setNormals(0, normals);
tile.setTextureCoordinates(0, 0, uv);

/* Il muro */
BufferedImage wallImage = getImage("/wall.png"); //64*64
/* La finestra */
BufferedImage windowImage = getImage("/window.png"); //16*32

/* ImageComponent2D del muro... */
ImageComponent2D wallImageComponent =
new ImageComponent2D(ImageComponent.FORMAT_RGB, wallImage);

/* Spiaccica la finestra sul muro... */
wallImageComponent.setSubImage(
windowImage,
windowImage.getWidth(),
windowImage.getHeight(),
0,
0,
24,
4);

/* Crea la texture del muro (che ha la finestra appiccicata) */
Texture2D wallTexture = new Texture2D(
Texture2D.BASE_LEVEL,
Texture2D.RGB,
wallImage.getWidth(),
wallImage.getHeight());

/* Imposta la texture del muro al livello mip map 0 */
wallTexture.setImages(new ImageComponent[] { wallImageComponent });

/* Multitexturing... con una texture sola =) */
TextureUnitState wallTextureUnit = new TextureUnitState();
wallTextureUnit.setTexture(wallTexture);
TextureUnitState[] stateArray = { wallTextureUnit };

Appearance tileApp = new Appearance();
tileApp.setTextureUnitState(stateArray);

Shape3D tileShape = new Shape3D(tile, tileApp);

Transform3D tileLocation = new Transform3D();
tileLocation.setTranslation(new Vector3d(-0.5f, -0.5f, -5));
TransformGroup tileGroup = new TransformGroup(tileLocation);
tileGroup.addChild(tileShape);

Background bg = new Background(new Color3f(0.5f, 0.5f, 0.5f));
BoundingSphere bounds = new BoundingSphere(new Point3d(0, 0, 0), 1000);
bg.setApplicationBounds(bounds);
BranchGroup root = new BranchGroup();
root.addChild(bg);
root.addChild(tileGroup);
root.compile();

GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
canvas = new Canvas3D(config);
SimpleUniverse universe = new SimpleUniverse(canvas);
universe.addBranchGraph(root);
//universe.getViewingPlatform().setNominalViewingTransform();

frame.addWindowListener(this);
frame.setLayout(new GridLayout(1, 1));
frame.add(canvas);
frame.setSize(400, 400);
frame.setVisible(true);
}

private BufferedImage getImage(String path) {
try {
return ImageIO.read(getClass().getResource(path));
} catch(Exception ex) {
throw new RuntimeException(ex);
}
}

public void windowClosing(WindowEvent e) {
System.exit(-1);
}

}

Praticamente a te interessa solo la parte colorata, il resto è fuffa sperimentale.

PUMA81
15-11-2006, 09:47
Grazie PGI-Bis, sei un grande!!! :D :D :D
E' quello che serviva a me :p
Ancora grazie e ciao.

PUMA81
24-11-2006, 15:50
Ciao, volevo chiederti ancora una cosa, però non riguarda direttamente le texture...
Allora:

BoundingSphere bounds=new BoundingSphere(new Point3d(),1500.0);
ImageComponent2D image = new TextureLoader("cielo.jpg",this).getScaledImage(larg,altez);
//Aggiunge uno sfondo
Background background=new Background(image);
background.setApplicationBounds(bounds);
//aggiungiamo l'istanza dello sfondo alla scena 3D
objRoot.addChild(background);

Avrei creato un BoundingSphere e messo una immagine di sfondo.
Adesso nella mia applicazione ho il terreno e subito attaccato il cielo.
Io vorrei fare una cosa un pochino più bellina e cioè mettere tra la terra e il cielo, ad esempio, delle montagne.
Ho provato a replicare ciò che ho scritto sopra passando diverse coordinate rispetto a quelle che passo nel getScaledImage() ma non va, cioè visualizzo solo la prima immagine caricata.
Volevo chiederti: è possibile fare quello che ti ho appena descritto??

Grazie e ciao.

PGI-Bis
24-11-2006, 16:00
Non puoi usare come sfondo un'immagine in cui ci siano già sia le montagne che il cielo?

PUMA81
24-11-2006, 16:35
Non puoi usare come sfondo un'immagine in cui ci siano già sia le montagne che il cielo?

Dici che mi conviene??
ma se volessi fare come ti ho scritto è molto complicato??
Il fatto è che la nostra applicazione è sospesa nella sfera e al di sotto di essa si vede tutto cielo...
magari volevo provare a mettere un'immagine che si adattava bene all'applicazione...
cmq se dici che non ne vale la pena... :p

PGI-Bis
24-11-2006, 16:43
So che esiste la possibilità di fare "sfondi carini" usando delle geometrie come sfondi ma non conosco la teoria che ci sta dietro per cui direi al 101% una cialtroneria :D.

dupa
24-11-2006, 17:28
So che esiste la possibilità di fare "sfondi carini" usando delle geometrie come sfondi ma non conosco la teoria che ci sta dietro per cui direi al 101% una cialtroneria :D.
ma senti un po' ma di che ti occupi? ne sai di ogni linguaggio e di tutte le librerie possibili e immaginabili :D