Hello, I’m new to JME in general, so i decided to jump in at the front of the curve and start with the alpha of jme3.
I’m working on a terrain rendering subsystem for a game and have been moving ahead pretty steadily, but i still have this odd issue. The system i’ve been working on renders 10x10 “tile” blocks and then tiles those together to create a continuous terrain. Textures are mapped to these 10x10 chunks. The two issues i’m seeing are:
- At certain angles certain textures turn solid black.
- The first blocks texture is noticeably darker (and on this video card, half of it is black no matter what).
EDIT: the screenshots dont seem to be working, maybe it doesn’t allow PNGs, i’ll keep trying to get something to show up. Sorry.
Screen shots:
i71.photobucket.com/albums/i160/last_liven/Terrafirma/Example_of_tiling.jpg
i71.photobucket.com/albums/i160/last_liven/Terrafirma/Broken_Texturing.jpg
Related code:
This is the function that loads the source heightmap image and parses it, creating the terrain chunks.
public void loadTerrainFromHeightMap(AssetManager assetManager, String file){
if(logger.isInfoEnabled())logger.info("Loading height map from file: " + file);
Texture image = assetManager.loadTexture(file);
height = image.getImage().getHeight();
width = image.getImage().getWidth();
int numChunksWidth = ((width-1) / TerrainChunk.WIDTH_TILES);
int numChunksHeight = ((height-1) / TerrainChunk.HEIGHT_TILES);
chunks = new TerrainChunk[numChunksWidth][numChunksHeight];
ByteBuffer buffer = image.getImage().getData(0);
buffer.position(0);
short [] heightData = new short [buffer.limit()];
for(int i=0;i<buffer.limit();i++){
int y = i / width;
int x = i % width;
y = height - y -1;
int flippedYPos = y * width + x;
heightData[flippedYPos] = (short)(128 - (buffer.get() & 0xff));
}
// create a list of empty terrain chunks
List<short [][]> chunksDatas = new ArrayList<short [][]>();
for(int i=0;i<numChunksWidth * numChunksHeight;i++){
chunksDatas.add(TerrainChunk.getChunkDefinition());
}
for(int cy = 0; cy < numChunksHeight; cy++){
for(int cx = 0; cx < numChunksWidth; cx++){
short [][] currentChunkData = chunksDatas.get( cy * numChunksWidth + cx );
for(int ty = 0; ty <= TerrainChunk.HEIGHT_TILES; ty++){
for(int tx = 0; tx <= TerrainChunk.WIDTH_TILES; tx++){
int index = width * (cy * TerrainChunk.HEIGHT_VERTEXES + (cy * -1)) + (width * ty)
-
((cx * TerrainChunk.WIDTH_VERTEXES) + (cx * -1) + tx);
currentChunkData[tx][ty] = heightData[index];
}
}
TerrainChunk chunk = new TerrainChunk();
chunk.init(currentChunkData);
this.chunks[cx][cy] = chunk;
}
}
}
And this is the terrain chunk code that builds the actual mesh objects:
public void init(short [][] definition){
if(logger.isInfoEnabled())logger.info(“Loading terrain chunk”);
Vector3f[] verts = new Vector3f[WIDTH_VERTEXESHEIGHT_VERTEXES];
int numTiles = WIDTH_TILES * HEIGHT_TILES;
IntBuffer indices = BufferUtils.createIntBuffer(numTiles * 6);
FloatBuffer normals = BufferUtils.createFloatBuffer(numTiles * 6);
float [] texturepos = new float [WIDTH_VERTEXES * HEIGHT_VERTEXES * 2];
int y=0;
int x=0;
for(y = 0; y < HEIGHT_VERTEXES; y++){
for(x = 0; x < WIDTH_VERTEXES; x++){
int c = y * WIDTH_VERTEXES + x;
//logger.debug( definition[x][y] * heightScaleFactor);`
verts[c] = new Vector3f(x, definition[x][y] * heightScaleFactor, y);
BufferUtils.addInBuffer(verts[c], vertices, c);
texturepos[c2] = x * textureStepX;
texturepos[c*2+1] = y * textureStepY;
}
}
int c=0;
for(y=0;y<HEIGHT_TILES;y++){
for(x=0;x<WIDTH_TILES;x++){
c = y * WIDTH_VERTEXES + x;
indices.put©;
indices.put(c+WIDTH_VERTEXES);
indices.put(c+1);
indices.put(c+1);
indices.put(c+WIDTH_VERTEXES);
indices.put(c+WIDTH_VERTEXES+1);
Vector3f n0 = new Triangle(verts[c], verts[c+WIDTH_VERTEXES], verts[c+1]).getNormal();
Vector3f n1 = new Triangle(verts[c+1], verts[c+WIDTH_VERTEXES], verts[c+WIDTH_VERTEXES+1]).getNormal();
c = (y * (WIDTH_TILES) + x) * 2;
BufferUtils.addInBuffer(n0, normals, c);
BufferUtils.addInBuffer(n1, normals, c+1);
}
}
setBuffer(VertexBuffer.Type.Position, 3, vertices);
setBuffer(VertexBuffer.Type.Normal, 3, normals);
setBuffer(VertexBuffer.Type.Index, 1, indices);
setBuffer(VertexBuffer.Type.TexCoord, 2, texturepos);
}
Thanks for any help, i apologize if this is the wrong forum, and let me know if there’s any other information or code that would help to figure this out.