Hi, I am using procedural generation to generate my heightmaps for TerrainQuads. I have a working rolling world generator working with procedural generated 8-bit heightmaps , which works perfectly.
However i needed taller mountains and deeper oceans. So i am converting my system to use 16 bit heightmaps to get the fidelity i need.
I thought it would be as simple as changing
Image im2 = new Image(Image.Format.RGB8, isize, isize, BufferUtils.createByteBuffer((isize) * (isize)* 3), null);
to
Image im2 = new Image(Image.Format.RGB16F, isize, isize, BufferUtils.createByteBuffer((isize) * (isize)* 3), null);
(The doco for ImageRaster says to stick toRBG16F rather than RGB16 , not sure why)
However when attempting to setPixel on the ImageRaster, an exception gets thrown:
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.IllegalArgumentException
at java.nio.Buffer.position(Buffer.java:236)
at com.jme3.texture.image.ByteAlignedImageCodec.writePixelRaw(ByteAlignedImageCodec.java:67)
at com.jme3.texture.image.ByteAlignedImageCodec.writeComponents(ByteAlignedImageCodec.java:125)
at com.jme3.texture.image.DefaultImageRaster.setPixel(DefaultImageRaster.java:111)
at Noise.RollingNoise.writeFaToImageRaster(RollingNoise.java:126)
at Noise.RollingNoise.FaToImage(RollingNoise.java:79)
etc
Obviously setPixel is expecting an 8bit canvas to draw on … couldn’t find anything in the doco which was immediately obvious to get this to work on 16bit images.
Relevant functions below. Heightmap is generated as an array float[513][513] before being converted from Float array → ImageRaster → Image → AbstractHeightmap
If someone can point me to any bit of code that generates a 16bit heightmap programatically rather than loading it from a RAW file that would probably be enough for me to crack the problem by myself.
Thanks
Arindrel
public Image FaToImage(float[][] faIn){
//isize is either 512 or 513 depending if we need fencepost (512 for minimap images, 513 for actual heightmaps)
int isize= faIn.length;
Texture tex = m.getAssetManager().loadTexture("Interface/"+(isize)+".png");
//Working code for 8 bit, trying to swicth to 16bit
//Image im2 = new Image(Image.Format.RGB8, isize, isize, BufferUtils.createByteBuffer((isize) * (isize)* 3), null);
Image im2 = new Image(Image.Format.RGB16F, isize, isize, BufferUtils.createByteBuffer((isize) * (isize)* 3), null);
tex.setImage(im2);
ImageRaster raster1 = ImageRaster.create(tex.getImage());
writeFaToImageRaster(faIn,raster1);
Image img1= tex.getImage();
return img1;
}
public void writeFaToImageRaster(float[][] data, ImageRaster r1){
//isize is either 512 or 513 depending on fencepost
int isize= data.length;
int xloop = isize;
int yloop = isize;
for (int y = 0; y < yloop; y++) {
for (int x = 0; x < xloop; x++) {
if ((y<isize)&&(x<isize)){
//clamp - at the last possible moment clamp
float value = data[x][y];
if (value>1.0f){value=1.0f;}
if (value<0.0f){value=0.0f;}
r1.setPixel(y, x, new ColorRGBA(value, value, value, 1));
}
else{
r1.setPixel(x, y, new ColorRGBA(1f,1f,1f, 1));
}
}
}
}