Generating Texture Coordinates for Indexed Arrays

I’ve been having problems getting my textures to appear and I’m not sure if If I’m making the mistake in the actual generation of the texture coordinates or in applying them to the geom.

The following code generates the coordinates



      private void generateTextureCoordinates(int sizeX, int sizeZ){
            //SizeX is the number of coordinates in the X Direction
            //SizeZ is the number of coordinates in the Z Direction
            
            texCoords = new TexCoord2f[MAX_COORDINATES];
            int index=0;
            for(int z = 0; z < sizeZ; z++){
             for(int x = 0; x < sizeX; x++){
                    texCoords[index++] =  new TexCoord2f((float)x / (float)sizeX, (float)z / (float)sizeZ); 
              }
             }
      }


When I create the geometry I do the following.


      private void generateGeometry()      {
            geo = new IndexedTriangleArray(MAX_COORDINATES, TriangleArray.COORDINATES | 
                                                                                    TriangleArray.NORMALS |
                                                                                  TriangleArray.COLOR_3 |
                                                                                  TriangleArray.TEXTURE_COORDINATE_2, MAX_INDICES);
            geo.setValidVertexCount(MAX_COORDINATES);
            geo.setCoordinates(0, coordinates);
            geo.setValidIndexCount(MAX_INDICES);
            geo.setIndex(indices);
            geo.setNormals(0, normals);
            geo.setColors(0, colors);
            geo.setTexCoordRef2f(0,texCoords);
      }

Finally when I set up the texture I do the following …


                    TextureLoader.tf.registerPath(".");
                    TextureLoader.tf.registerPath("..");
                    texture = (Texture2D) TextureLoader.tf.getMinMapTexture("checkerboard.jpg");
                    TextureAttributes ta = new TextureAttributes();
                    ta.setTextureMode(TextureAttributes.MODULATE);
                    app = new Appearance();
                    app.setTexture(texture);
                                      app.setTextureAttributes(ta);


Of course I realize being just code fragments its probably difficult to figure out what is wrong. Hopefully, it’s something very obvious and someone can catch it right away. If not I’ll try to extract the relevant code into something executable. Thanks for the help!

I went ahead and took all the relevant code and made it it’s own program. You should be able to just copy and paste the following code. Right now it just displays the cube (From the getting started demo) and a plane which is an indexedTriangleArray. I can’t seem to get the stone texture to appear correctly on the plane.

Does anyone have any ideas? Does it look I’m calculating the texture coordinates correctly? Since it’s just a square arranged in a grid I figured it wasn’t that complicated.

I’m positive the indices and vertices are being calculated properly since they show up correctly when I just render lines. THanks for any help you can provide.


import javax.vecmath.*;

// Xith3D
import com.xith3d.scenegraph.*;
import com.xith3d.test.*;
import com.xith3d.loaders.texture.*;

// use Jogl
import com.xith3d.render.*;
import com.xith3d.render.jogl.*;

public class indexTest
{
      public Shape3D shape;
      IndexedTriangleArray geo;
      
      private Point3f[] coordinates; // = new int[];
      private Vector3f[] normals;
      private Color3f[] colors;
      
      private int[] indices;
      private TexCoord2f[] texCoords;
            
      private int MAX_INDICES;
      private int MAX_COORDINATES;
      
      public PolygonAttributes pa;
      private Texture2D texture;
      private ColoringAttributes ca;
      private Material mat;
      private Appearance app;
      
      
      public static void main(String[] args)
      {
            new indexTest();
      }
      
      public Shape3D createShape(){
            
            int size = 5; //Shape is a square with length 'size'
            MAX_COORDINATES = size * size; 
            MAX_INDICES = (size-1)*(size-1) * 6;
                              
            this.generateCoordinates(size);
            this.generateIndices(size);
            this.generateTextureCoordinates(size);
            this.generateGeometry();

//Create Shape based on above created geometry      
            shape = new Shape3D(geo);
            
//Load Texture
            TextureLoader.tf.registerPath(".");
            TextureLoader.tf.registerPath("..");
            texture = (Texture2D) TextureLoader.tf.getMinMapTexture("stone.jpg");
            
//Polygon Attributes                        
            pa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE,PolygonAttributes.CULL_NONE,0);
                      
//Creating Appearance
            app = new Appearance();
            app.setTexture(texture);
            app.setPolygonAttributes(pa);
            shape.setAppearance(app);
            shape.setBoundsAutoCompute(false);
            shape.setBounds(new BoundingSphere(new Point3f(0,0,0),100000));
            
            return shape;
      }
      
      /**
       * This function generates the Indices which are in the following format
       *       v1          v2
       *(x,0,z)    (x+1,0,z)
       *       0-----------0
       *       |                 |
       *       |                   |
       *       |           |
       *       |                |
       *       |             |
       *       0-----------0
       * v3                  v4
       * @param sizeX, Size of the Terrain in the X dimension
       * @param sizeZ, Size of the Terrain in the Z dimension
       */
      private void generateIndices(int size){
            indices = new int[MAX_INDICES];
            int index=0;
            for(int z = 0; z < size-1; z++){
                  for(int x = 0; x < size-1; x++){
                         indices[index++] = x +     ( z * size );                              //v1
                         indices[index++] = x + 1 + ( z * size);                              //v2
                          indices[index++] = x + 1 + ((z + 1) * (size));                  //v4

                          indices[index++] = x +     (z * size);                              //v1
                          indices[index++] = x + 1 + ((z + 1) * (size));                  //v4
                          indices[index++] = x +     ((z + 1) * (size));                  //v3
                   }
             }
      }
      
      private void generateTextureCoordinates(int size){
            texCoords = new TexCoord2f[MAX_COORDINATES];
            int index=0;
            for(int z = 0; z < size; z++)
                  for(int x = 0; x < size; x++)
                        texCoords[index++] =  new TexCoord2f((float)x / (float)(size-1), (float)z / (float)(size-1)); 
      }
            
      private void generateCoordinates(int size){
            coordinates = new Point3f[MAX_COORDINATES];
            int index=0;
            for(int z=0; z<size; z++)
                  for(int x=0; x<size; x++)
                        coordinates[index++] = new Point3f((float)x, 0.0f, (float)z);
      }      
      
      private void generateGeometry()      {
            geo = new IndexedTriangleArray(MAX_COORDINATES, TriangleArray.COORDINATES | 
                                                                                    TriangleArray.TEXTURE_COORDINATE_2,
                                                                                    MAX_INDICES);
            geo.setValidVertexCount(MAX_COORDINATES);
            geo.setCoordinates(0, coordinates);
            geo.setValidIndexCount(MAX_INDICES);
            geo.setIndex(indices);
            geo.setTexCoordRef2f(0,texCoords);
      }


      public void start(View view) {
            while (true){
                  Transform3D viewT = new Transform3D();
                  viewT.lookAt(new Point3f(5,5,-5),new Point3f(5,0,0),new Point3f(0,1,0));
                  view.setTransform(viewT);
                  
                  view.renderOnce();
                  try      {
                        Thread.sleep(10L);
                  }
                  catch (Exception e)      {
                  }
            }
      }

      public indexTest() {
            // create the virtual univers
            VirtualUniverse universe = new VirtualUniverse();

            // add a view to the universe
            View view = new View();
            universe.addView(view);

            // add a locale
            Locale locale = new Locale();
            universe.addLocale(locale);

            // create a BranchGroup
            BranchGroup scene = new BranchGroup();
            locale.addBranchGraph(scene);
                  
            // create Cube
            Shape3D plane = createShape();
            Geometry geo = Cube.createCubeViaTriangles(0, 0, 0, 1, true);
            Shape3D sh = new Shape3D(geo, new Appearance());
            scene.addChild(sh);
            scene.addChild(plane);

            // create a canvas for our graphics
            RenderPeer rp = new RenderPeerImpl();
            CanvasPeer cp = rp.makeCanvas(null, 640, 480, 32, false);
            Canvas3D canvas = new Canvas3D();
            canvas.set3DPeer(cp);

            // modify our view so we can see the cube
            view.addCanvas3D(canvas);
            start(view);
      }
}



use geo.setTextureCoordinates(0, 0,texCoords); instead of geo.setTexCoordRef2f(0,texCoords); - that should do it ( at least that is what I am seeing here )

Yep!
I just figured it out like 10 seconds ago and then came to the boards.

geo.setTextureCoordinates(0,0,texCoords);

That’s the key. Thanks for your help Daath!