How Type.texCoord work?

Hello all,



I’m trying to understand how the terrain system work. For that, I try to recreate the system which is already in place and try to improve performance. But i’ve a problem as for the texture coordinates given To The Vertex Buffer.



My class:



[java]

package mygame;



import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.scene.Mesh;

import com.jme3.scene.Mesh.Mode;

import com.jme3.scene.VertexBuffer.Type;

import com.jme3.util.BufferUtils;



public class TerrainGenerator



{



protected int size;

protected Mesh m;



public TerrainGenerator(String name, float[] heightMap, int s){



size = s;

Vector3f[] positions = createPosition(heightMap);

Vector2f[] texCoord = createTexture();

//Vector2f[] texCoord = {new Vector2f(0,0), new Vector2f(0,size), new Vector2f(size,0), new Vector2f(size,size)};

int[] index = createIndex();



m = new Mesh();

m.setMode(Mode.Triangles);



m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(positions));

m.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));

m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(index));

m.updateBound();



}



public Mesh getMesh(){



return m;



}



private Vector3f[] createPosition(float[] heightMap) {



Vector3f[] vertices = new Vector3f[sizesize];



for(int x = 0; x<size; x++){

for(int z = 0; z<size; z++){



//vertices[x
size+z] = new Vector3f(x, heightMap[x512+z] ,z);

vertices[x
size+z] = new Vector3f(x, 1 ,z);



}

}



return vertices;



}



private Vector2f[] createTexture() {



Vector2f[] texCoord = new Vector2f[sizesize];



for(int x = 0; x<size;x++){

for(int z = 0; z<size; z++){



texCoord[x
size+z] = new Vector2f(x, z);



}

}



return texCoord;



}



private int[] createIndex() {



int[] index = new int[((sizesize)6)-(size12-6)];



int bouclage = 0;

int y = 0;



for(int i = 0; i < (((size
size)6)-(size12-6)); i++){

if((y%size) == size-1){



y++;



}

switch (bouclage) {



case 0:

index = y;

break;

case 1:

index = y+1;

break;

case 2:

index = y+size+1;

break;

case 3:

index = y+size+1;

break;

case 4:

index = y+size;

break;

case 5:

index = y;

break;

}



bouclage++;

if(bouclage == 6){



bouclage = 0;

y++;



}



}



return index;



}



}

[/java]



Position buffer work like this:







And now when i apply my texCoord to the vertexBuffer my terrain was textured like this:







What’s wrong ?



{my texCoord:



(0.0, 0.0)

(0.0, 1.0)

(0.0, 2.0)

(0.0, 3.0)

(0.0, 4.0)

(0.0, 5.0)

(0.0, 6.0)

(0.0, 7.0)

(0.0, 8.0)

(0.0, 9.0)

(0.0, 10.0)

(0.0, 11.0)



}

Texture coordinates should be a percentage of the total size. So if your terrain is 10 wide, each tex coord should be the last one +10%.

so it should look like this for the first row: (0,0),(0.1,0),(0.2,0),(0.3,0)…(1,0)



Also, what material are you using? Make sure the textures are set to wrap, or else you will see the artifacts like in your screenshot.

Yes it was just the texture mode wich was not set to wrap ^^. Thanks : )



I implement a fonction to setHeight in a radius and it work with a hight performance

[java]

package mygame;



import com.jme3.math.FastMath;

import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.scene.Mesh;

import com.jme3.scene.Mesh.Mode;

import com.jme3.scene.VertexBuffer.Type;

import com.jme3.util.BufferUtils;



public class TerrainGenerator



{



protected final int size;

protected Mesh m;

private final int imageSize;

private float[] heightMap;



public TerrainGenerator(String name, float[] heightmap, int s, int iS){



size = s;

imageSize = iS;

heightMap = heightmap;

Vector3f[] positions = createPosition(heightmap);

Vector2f[] texCoord = createTexture();

//Vector2f[] texCoord = {new Vector2f(0,0), new Vector2f(0,size), new Vector2f(size,0), new Vector2f(size,size)};

int[] index = createIndex();



m = new Mesh();

m.setMode(Mode.Triangles);



m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(positions));

m.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));

m.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(index));

m.updateBound();



}



public Mesh getMesh(){



return m;



}



private Vector3f[] createPosition(float[] heightMap) {



Vector3f[] vertices = new Vector3f[sizesize];



for(int x = 0; x<size; x++){

for(int z = 0; z<size; z++){



vertices[x
size+z] = new Vector3f(x, heightMap[ximageSize+z] ,z);

//vertices[x
size+z] = new Vector3f(x, 1 ,z);



}

}



return vertices;



}



public void setHeight(int x, int y, int height, int radius){



for (int i=x-radius; i<x+radius; i++) {

for (int j=y-radius; j<y+radius; j++) {

if (FastMath.sqr(x-i)+FastMath.sqr(y-j) <= FastMath.sqr(radius)) {



if(!( i > 511 || j > 511 || j < 0 || i < 0)){



heightMap[i*imageSize+j] = height;



}

}

}

}



m.clearBuffer(Type.Position);

m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(createPosition(heightMap)));



}



public void adjustHeight(int x, int y, float height, int radius){



for (int i=x-radius; i<x+radius; i++) {

for (int j=y-radius; j<y+radius; j++) {

if (FastMath.sqr(x-i)+FastMath.sqr(y-j) <= FastMath.sqr(radius)) {



if(!( i > 511 || j > 511 || j < 0 || i < 0)){



heightMap[i*imageSize+j] = height+heightMap[i*imageSize+j];



}

}

}

}



m.clearBuffer(Type.Position);

m.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(createPosition(heightMap)));



}



private Vector2f[] createTexture() {



Vector2f[] texCoord = new Vector2f[sizesize];



for(int x = 0; x<size;x++){

for(int z = 0; z<size; z++){



texCoord[x
size+z] = new Vector2f(x0.05f, z0.05f);



}

}



return texCoord;



}



private int[] createIndex() {



int[] index = new int[((sizesize)6)-(size12-6)];



int bouclage = 0;

int y = 0;



for(int i = 0; i < (((size
size)6)-(size12-6)); i++){

if((y%size) == size-1){



y++;



}

switch (bouclage) {



case 0:

index = y;

break;

case 1:

index = y+1;

break;

case 2:

index = y+size+1;

break;

case 3:

index = y+size+1;

break;

case 4:

index = y+size;

break;

case 5:

index = y;

break;

}



bouclage++;

if(bouclage == 6){



bouclage = 0;

y++;



}



}



return index;



}



}

[/java]