I want to texture the surface of my terrain.
I have created the ground mesh and surface mesh separately and everything is okay for ground mesh. But I couldn't texture the surface mesh correctly.
As below, the first one is what I want exactly and the second one is my output:
And my surface texture image looks like this:
My fragment shader:
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
varying vec2 v_texCoords;
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, v_texCoords);
}
My vertex shader:
attribute vec4 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec2 v_texCoords;
void main() {
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
Here is how I create my textures and draw my meshes:
private void initializeTextures() {
groundTexture = new Texture(Gdx.files.internal(Constants.SIMPLE_GROUND_FN));
groundTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
surfaceTexture = new Texture(Gdx.files.internal(Constants.SIMPLE_GROUND_SURFACE_FN));
surfaceTexture.setWrap(Texture.TextureWrap.ClampToEdge, Texture.TextureWrap.Repeat);
surfaceTexture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
}
public void draw(SpriteBatch batch){
batch.setShader(shader);
shapeRenderer.setProjectionMatrix(GameScreen.getCamera().combined);
shader.begin();
shader.setUniformMatrix("u_projTrans", GameScreen.getCamera().combined);
groundTexture.bind(0);
shader.setUniformi("u_texture", 0);
groundMesh.render(shader, GL20.GL_TRIANGLES);
surfaceTexture.bind(0);
shader.setUniformi("u_texture", 0);
shader.setUniformMatrix("u_projTrans", GameScreen.getCamera().combined);
surfaceMesh.render(shader, GL20.GL_TRIANGLES);
shader.end();
}
And here is the method that generates mesh data:
public void createMeshes(int res) {
Random r = new Random();
int LENGTH = 15;
//res (resolution) is the number of height-points
//minimum is 2, which will result in a box (under each height-point there is another vertex)
if (res < 2)
res = 2;
groundMesh = new Mesh(Mesh.VertexDataType.VertexArray, true, 2 * res, (2*res-1)*6,
new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_position"),
new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, 2, "a_texCoord0"));
surfaceMesh = new Mesh(Mesh.VertexDataType.VertexArray, true, 2 * res, (2*res-1)*6,
new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_position"),
new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, 2, "a_texCoord0"));
float x = 0f; //current position to put vertices
float med = 0.3f; //starting y
float y = med;
float slopeWidth = (float) (LENGTH / ((float) (res - 1)))/25; //horizontal distance between 2 heightpoints
slopeWidth=0.1f;
// VERTICES
float[] tempVer = new float[2*2*2*res]; //hold vertices before setting them to the mesh
float[] tempVerSurface = new float[2*2*2*res]; //hold vertices before setting them to the mesh
int offset = 0; //offset to put it in tempVer
int offset2 = 0;
float[] tempVer2 = new float[2*res];
int flahUp = 0;
for (int i = 0; i<res; i++) {
tempVer[offset+0] = x; tempVer[offset+1] = 0; // below height
tempVer[offset+2] = x; tempVer[offset+3] = 0; // below height
tempVer[offset+4] = x; tempVer[offset+5] = y; // height
tempVer[offset+6] = x; tempVer[offset+7] = y; // height
tempVerSurface[offset+0] = x; tempVerSurface[offset+1] = y- .02f; // below height
tempVerSurface[offset+2] = x; tempVerSurface[offset+3] = y-0.02f; // below height
tempVerSurface[offset+4] = x; tempVerSurface[offset+5] = y+0.015f; // height
tempVerSurface[offset+6] = x; tempVerSurface[offset+7] = y+0.015f; // height
//tempVer2[offset2+0] = x; tempVer2[offset2+1] = 0f; // below height
tempVer2[offset2+0] = x; tempVer2[offset2+1] = y; // below height
//next position:
x += slopeWidth;
if(flahUp < 20) {
y += (r.nextFloat()*10)/200;
}else {
y -= (r.nextFloat()*6)/200;
}
flahUp++;
if(flahUp > 35) flahUp = 0;
offset +=8;
offset2 +=2;
}
groundShape.createChain(tempVer2);
groundMesh.setVertices(tempVer);
surfaceMesh.setVertices(tempVerSurface);
// INDICES
short[] tempIn = new short[(2*res-1)*6];
offset = 0;
for (int i = 0; i<2*res-2; i+=2) {
tempIn[offset + 0] = (short) (i); // below height
tempIn[offset + 1] = (short) (i + 2); // below next height
tempIn[offset + 2] = (short) (i + 1); // height
tempIn[offset + 3] = (short) (i + 1); // height
tempIn[offset + 4] = (short) (i + 2); // below next height
tempIn[offset + 5] = (short) (i + 3); // next height
offset+=6;
}
groundMesh.setIndices(tempIn);
surfaceMesh.setIndices(tempIn);
return;
}
So, maybe there is a very different way; this is actually my first game project and I don't know how to achieve this. What should I do to make my surface like the first one?
Thanks.