# GeometryInfo will TexturAttribute Modulate nicht akzeptieren



## Lusi (26. Nov 2004)

Hi 

Ich habe zwei Klassen geschrieben, mit dennen ich Wände konstruieren kann, und zwar so, dass ich für das Texturmapping mehrere Divisions mitgeben kann, damit die Texturen beliebig oftmals wiederholt werden können. 

Mein Problem ist nun folgendes: 

Da ich einen Lichtschalter in meinem Raum habe, sollten sich nun die Wände den Lichtkoeffizienten anpassen, wenn ich das Licht "ausschalte". Dies mache ich mit dem TexturAttribute "Modulate". In der Klasse, wo ich die Wand mit einem GeometryArray baue, funtkioniert dies bestens. Benutze ich jedoch ein GeometryInfo(GeometryInfo.QUAD_ARRAY), passiert überhaupt nichts. Ich brauche jedoch beide Klassen. 

Hat jemand eine Idee, wo das Problem liegen könnte?

Hier die beiden Hauptmethoden der Klassen:


mit dem QuadArray, wo es funktioniert:

```
public void construct(){
        Appearance appearance = new Appearance();
        
        TextureAttributes texAttr = new TextureAttributes();
        texAttr.setTextureMode( TextureAttributes.MODULATE );
        appearance.setTextureAttributes(texAttr);
        
        Color3f diffAmb = new Color3f(0.3f, 0.3f, 0.3f); 
        Color3f emittedLight = new Color3f(0.0f, 0.0f, 0.0f);
        Color3f reflDiff = new Color3f(0.8f, 0.8f, 0.8f); 	     
        Color3f reflSpec = new Color3f(0.5f, 0.5f, 0.5f);
        
        appearance.setMaterial( new Material(diffAmb, emittedLight, reflDiff, reflSpec, 20.0f ) );
        // Load the texture
        NewTextureLoader newTextureLoader = new NewTextureLoader( texName );
        newTextureLoader.setImageObserver( NewTextureLoader.getImageObserver() );
        Texture texture = newTextureLoader.getTexture();
        // Create the QuadArray
        QuadArray geom = new QuadArray(verts.length, QuadArray.COORDINATES |
        QuadArray.NORMALS | QuadArray.TEXTURE_COORDINATE_2);
        geom.setCoordinates(0, verts);
        // Compute the normals
        Vector3f normal = new Vector3f();
        Vector3f v1 = new Vector3f();
        Vector3f v2 = new Vector3f();
        Point3f [] pts = new Point3f[4];
        for (int i=0;i<4;i++) pts[i]=new Point3f();
        geom.getCoordinates(0, pts);
        v1.sub(pts[1],pts[0]);
        v2.sub(pts[2],pts[0]);
        normal.cross(v1,v2);
        normal.normalize();
        for(int i=0;i<verts.length;i++){
            geom.setNormal(i,normal);
        }
        appearance.setTexture(texture);
        // Set the texture for each point in the Table
        for (int i=0;i<verts.length;i++){
            geom.setTextureCoordinate(0,i,textCoord[i%4]);
        }
        setAppearance(appearance);
        this.setGeometry(geom);
    }
```


und hier mit dem GeometryInfo, wo das Modulate (die ganze Beleuchtung überhaupt) keinen Einfluss hat:


```
public Shape3D myWall(){
   	
   		
   	 Appearance appearance = new Appearance();
        
 	 TextureAttributes texAttr = new TextureAttributes();
 	 texAttr.setTextureMode( TextureAttributes.MODULATE );
 	 appearance.setTextureAttributes(texAttr);
 	        
 	Color3f diffAmb = new Color3f(0.0f, 0.0f, 0.0f); 
 	Color3f emittedLight = new Color3f(0.0f, 0.0f, 0.0f);
 	Color3f reflDiff = new Color3f(0.8f, 0.8f, 0.8f); 	     
 	Color3f reflSpec = new Color3f(0.5f, 0.5f, 0.5f);
 	        
 	appearance.setMaterial( new Material(diffAmb, emittedLight, reflDiff, reflSpec, 8.0f ) );
 	       
 	NewTextureLoader newTextureLoader = new NewTextureLoader( tex );
 	newTextureLoader.setImageObserver( NewTextureLoader.getImageObserver() );
 	Texture texture = newTextureLoader.getTexture();
 	        
   	
//	Calculating the # of vertices and inizialise the Point3f Array vertices[] with this number
   	
   	numberOfVertices = (xDIV + 1) * (yDIV + 1);
   	vertices = new Point3f[numberOfVertices];			
   		
//	Calculating the difference between the single vertices  
   		
   	toNextX = x/xDIV;		
                toNextY = y/yDIV;
        
// 	Calculating all the vertice coordinates and fill in the Point3f Array vertices[]
        
                for(int j = 0; j <= xDIV ; j++) {         
                     for(int i = 0; i <= yDIV ; i++) {
           	           vertices[j*(yDIV+1)+i] = new Point3f(-x/2 + j*toNextX,-y/2 + i*toNextY, 0.0f);
                     }
                }
             
//             Computation of the polygon's indices for the plane.

                lengthWallPieceIndices = 4 * yDIV * xDIV;  

                wallPieceIndices = new int[lengthWallPieceIndices]; 

                for(int j = 0; j < xDIV ; j++) {
        
                   for(int i = 0; i < yDIV ; i++){
  	 
           	        wallPieceIndices[4*(j*yDIV+i)  ] = j*(yDIV+1)+i  ;
           	        wallPieceIndices[4*(j*yDIV+i)+1] = j*(yDIV+1)+i+1;
           	        wallPieceIndices[4*(j*yDIV+i)+2] = j*(yDIV+1)+i+yDIV+2;
           	        wallPieceIndices[4*(j*yDIV+i)+3] = j*(yDIV+1)+i+yDIV+1;	    
                   }   
                }
    
//              Creation of the GeometryInfo instance using a QUAD_ARRAY and adding coordinates and indices
        
                wall_geometryInfo = new GeometryInfo(GeometryInfo.QUAD_ARRAY);
                wall_geometryInfo.setCoordinates(vertices);  
                wall_geometryInfo.setCoordinateIndices(wallPieceIndices);  
  		   
            
//     	Set the parameters for the texture's coordinates (1 texture with dimension 2D)
        
	wall_geometryInfo.setTextureCoordinateParams(1, 2);
        
//	The coordinates of the 4 points for the 2D texture of each wall piece.
        
	textCoord2f    = new TexCoord2f[4]; 	       
	textCoord2f[0] = new TexCoord2f(0.0f, 0.0f);
	textCoord2f[1] = new TexCoord2f(1.0f, 0.0f);
	textCoord2f[2] = new TexCoord2f(1.0f, 1.0f);
	textCoord2f[3] = new TexCoord2f(0.0f, 1.0f);
		
		
//	Initalise the int array for the texture coordinate indieces and fill in with 0,1,2,3,0,1,2,3,... 
	       
	textCoord2fIndices = new int[lengthWallPieceIndices]; 
	               	        
	for (int i = 0; i<lengthWallPieceIndices; i++){
			textCoord2fIndices[i]= i%4;
	}

 
//	Adding the texture informations to the GeometryInfo object
        
	wall_geometryInfo.setTextureCoordinates(0, textCoord2f);  	        
	wall_geometryInfo.setTextureCoordinateIndices(0, textCoord2fIndices);
		
		
//	Get the informations from the GeometryArray        
        
                oneWall = wall_geometryInfo.getIndexedGeometryArray();

//	Generating normals and stripify the the wall
        
                normalGenerator = new NormalGenerator();        
                normalGenerator.generateNormals(wall_geometryInfo); 

                stripifier = new Stripifier();
                stripifier.stripify(wall_geometryInfo);
        		        
//	Passing the geometry and the appearance to the instance this of the Shape3D myWall.		        
  
	appearance.setTexture(texture);
                setAppearance(appearance); 
                this.setGeometry(oneWall);

   	return this;
   }
```

Habe keine Ahnung, wo das Problem liegen könnte...


greetz Lusi


----------



## Oxygenic (26. Nov 2004)

Lusi hat gesagt.:
			
		

> Da ich einen Lichtschalter in meinem Raum habe, sollten sich nun die Wände den Lichtkoeffizienten anpassen, wenn ich das Licht "ausschalte"



Wozu diese Umstände? Eine reale Lichtquelle erledigt das für dich automagisch, ohne das du sämtliche Objekte modifizieren müsstest.

Ich habe mir deinen Code jetzt nicht angesehen, aber die Verwendung von GeometryInfo-Objekten für die Texturierung ist meiner Meinung nach etwas seltsam. Funktioniert denn der offizielle Weg, Geometry-Objekte aus den GeometryInfos zu holen und mit diesen dann ganz normale Shape3Ds zu erstellen?

Nachtrag: Der Code sieht gut aus, aber musst du beim Erstellen des GeometryInfo-Objektes nicht auch die Flags für die Texturierung mit setzen?


----------



## Lusi (26. Nov 2004)

Eine reale Lichtquelle? Ich habe jetzt zwei SpotLights, ein DirectionalLight und ein AmbiantLight.
Muss ich nicht sowieso für jedes Shape3D in den Materialsettings die Lichtattribute übergeben?

Die Flags für die Texturierung setzte ich mit Hilfe von TextureAttributes und übergebe dies der Appearance.

Du meinst, das Problem könnte auftauchen, weil ich eine GeometryInfo Instanz benutze? Sieht beinahe aus, als müsste ich die Klasse neu schreiben, ohje ;] (ohje, weil unter Zeitdruck)


----------



## Oxygenic (27. Nov 2004)

OK, wenn du Lichtquellen hast dann ist das OK, ich dachte, du simulierst die Helligkeiten evtl. mit speziellen Texturen.

Die GeometryInfo kann nicht die Ursache für das Problem sein, die habe ich selber mehrfach verwendet und das Licht wird korrekt reflektiert.

Ich vermute, du hast noch wo anders einen Bug drin, der hier gepostete Code sieht jedenfalls gut aus.


----------



## Lusi (29. Nov 2004)

Das Problem war folgendes:

ich musste die folgende Zeile, wo ich den GeometryArray bilde, nach dem NormalGenerator und dem Stripifier aufrufen, ja nicht vorher:


```
//		Generating normals and stripify the the wall
        
        normalGenerator = new NormalGenerator();        
        normalGenerator.generateNormals(wall_geometryInfo); 

        stripifier = new Stripifier();
        stripifier.stripify(wall_geometryInfo);
        
//		Passing the geometry and the appearance to the instance this of the Shape3D myWall.
        
        this.setAppearance(appearance); 
        
        GeometryArray oneWall = wall_geometryInfo.getIndexedGeometryArray();        
        this.setGeometry(oneWall);
        
   		return this;
```

so funktionierts. Aber ist wirklich ein fieser Fehler :]

Danke fürs Antworten/Intresse, 

greetz Lusi


----------



## Lusi (22. Dez 2004)

Wir konnten unsere Arbeit fertig stellen, hier der Link, falls es jemand interessiert:

http://satin3d.dyndns.org/


Danke für die Tipps und Hilfe, 

Lusi


----------

