TestIsland pictures

I was looking at the TestIsland pictures such as the terrainlod, lightmap, and alphas and I am wondering how do you make things which look like that?  Are there some programs which can create them?  I have taken a look at monkeyworld3d but it does not generate anything like those.

Having JUST finished this part of Fyrestone, I'd be happy to help you.



First you have to decide if your terrain should be the same every time, or if you want a randomly generated terrain each time.



If you want randomly generated terrain, you can look at the tutorials in the Wiki. If you don't, you're looking at either heightmap importing (efficient, easy) or model importing(not so efficient, harder in certain areas).



With heightmaps, you're going to have to create the heightmap in a program. Fyrestone's program of choice is Freeworld3D (freeworld3d.org). It is able to make beautiful terrains and allows you to export heightmaps in a multitude of formats and converts and exports your textures and their alphas (although 32-bit alphas are currently broken–hoping for a solution to that soon).



If you're looking at a LARGE terrain, you'll want to take a look at jmeTerra, but if you aren't then you can load a single, large heightmap into your program.



TestIsland also features a WaterRenderPass which makes the water reflect the scene. You'll need to look into skyboxes as well.



Start off by studying RawHeightMaps and how to import them, and once you've loaded the heightmaps into your program you can keep going from there.



You'll also like to know this: IF you buy Freeworld3D, you'll want to export your heightmaps in non power of 2, 16-bit raw format. When you set the scale of your world (in your game) you'll want to set it to X, 0.0007, X where X is how far you want it stretched sideways. Just note the .0007 is a REALLY small number. You can obviously change it, but if you change it too much you're going to be standing in ridiculous valleys.

FreeWorld3D's export is not broken. It exports grayscale maps. jME takes alpha maps. Here is a little code i fabricated to convert them. Put it into a static utility class and use it.





public static BufferedImage grayScaleToAlpha(BufferedImage src) {
      // Create a pure grayscale image
        BufferedImage temp = ImageConverter.toBufferedImage(src,BufferedImage.TYPE_BYTE_GRAY);
        // Make a nice byte stream of it
        byte[] tempData=(byte[])temp.getRaster().getDataElements(0, 0, temp.getWidth(), temp.getHeight(), null);
        // Create our destination image
        BufferedImage dest = new BufferedImage(src.getWidth(), src.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
        // The other stream...
        int[] destData=(int[])dest.getRaster().getDataElements(0, 0, dest.getWidth(), dest.getHeight(), null);
        // How many bytes are stored per pixel
        int destBytesPerPixel=4;
        int tempBytesPerPixel=1;
       
        for(int h=0;h<dest.getHeight();h++) {
           for(int w=0;w<dest.getWidth();w++) {
              int destIndex=(h*destBytesPerPixel*dest.getHeight())+(w*destBytesPerPixel);
              int tempIndex=(h*tempBytesPerPixel*temp.getHeight())+(w*tempBytesPerPixel);
              set(dest,w,h,tempData[tempIndex]);
           }
        }
        return dest;
    }
   
   public static void set(BufferedImage img,int x, int y, int value) {
      int rgb = 0x00FFFFFF | (value << 24);
      img.setRGB(x, y, rgb);
   }

static private class ImageConverter
    {
        // Posted by DrLaszloJamf to Java Technology Forums
        //
        // Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved.
        // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
        //
        // Redistribution of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
        //
        // Redistribution in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
        //
        // Neither the name of Sun Microsystems, Inc. or the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
        //
        // This software is provided "AS IS," without a warranty of any kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
        //
        //
        // You acknowledge that this software is not designed, licensed or intended for use in the design, construction, operation or maintenance of any nuclear facility.

        //    preserves image's colormodel. Assumes image is loaded
        public static BufferedImage toBufferedImage(Image image)
        {
            if (image instanceof BufferedImage)
                return (BufferedImage)image;
            ColorModel cm = getColorModel(image);
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            return copy(createBufferedImage(cm, width, height), image);
        }

        public static BufferedImage toBufferedImage(Image image, int type)
        {
            if (image instanceof BufferedImage
                && ((BufferedImage)image).getType() == type)
                return (BufferedImage)image;
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            return copy(new BufferedImage(width, height, type), image);
        }

        //    Returns target. Assumes source is loaded
        public static BufferedImage copy(BufferedImage target, Image source)
        {
            Graphics2D g = target.createGraphics();
            g.drawImage(source, 0, 0, null);
            g.dispose();
            return target;
        }

        public static ColorModel getColorModel(Image image)
        {
            try
            {
                PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
                pg.grabPixels();
                return pg.getColorModel();
            }
            catch (InterruptedException e)
            {
                throw new RuntimeException("Unexpected interruption", e);
            }
        }

        public static BufferedImage createBufferedImage(
            ColorModel cm,
            int w,
            int h)
        {
            WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
            boolean isRasterPremultiplied = cm.isAlphaPremultiplied();
            return new BufferedImage(cm, raster, isRasterPremultiplied, null);
        }
    }

the 32-bit export of alphas is broken–it gives you an access error. but thank you so much for this code!!

I have created terrains using heightmaps and procedural texture generators but not in the way TestIsland does it with the lod, lightmaps, and alphas.  I just didn't know what I could use to create my own terrains like that.  Thanks for the info I will check out FreeWorld3D.

Trussell said:

the 32-bit export of alphas is broken--it gives you an access error. but thank you so much for this code!!


It exports only grayscale for me though. Never found any access violation error.

What OS do you use, and what version of FW3D?

XP auto-updates on(I know… nc), on an Acer Travelmate 5520G laptop.  FW3D 2.4.0

In jME 2.0 you don't need to convert the alphamaps to RGBA8, there's a specialized alpha format, Format.Alpha8, that causes GPU to use grayscale image as alpha.

I just found a list of terrain editors in the JME Wiki as well for some more options.

HouseMDave said:

FreeWorld3D's export is not broken. It exports grayscale maps. jME takes alpha maps. Here is a little code i fabricated to convert them. Put it into a static utility class and use it.



public static BufferedImage grayScaleToAlpha(BufferedImage src) {
      // Create a pure grayscale image
        BufferedImage temp = ImageConverter.toBufferedImage(src,BufferedImage.TYPE_BYTE_GRAY);
        // Make a nice byte stream of it
        byte[] tempData=(byte[])temp.getRaster().getDataElements(0, 0, temp.getWidth(), temp.getHeight(), null);
        // Create our destination image
        BufferedImage dest = new BufferedImage(src.getWidth(), src.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
        // The other stream...
        int[] destData=(int[])dest.getRaster().getDataElements(0, 0, dest.getWidth(), dest.getHeight(), null);
        // How many bytes are stored per pixel
        int destBytesPerPixel=4;
        int tempBytesPerPixel=1;
       
        for(int h=0;h<dest.getHeight();h++) {
           for(int w=0;w<dest.getWidth();w++) {
              int destIndex=(h*destBytesPerPixel*dest.getHeight())+(w*destBytesPerPixel);
              int tempIndex=(h*tempBytesPerPixel*temp.getHeight())+(w*tempBytesPerPixel);
              set(dest,w,h,tempData[tempIndex]);
           }
        }
        return dest;
    }
   
   public static void set(BufferedImage img,int x, int y, int value) {
      int rgb = 0x00FFFFFF | (value << 24);
      img.setRGB(x, y, rgb);
   }

static private class ImageConverter
    {
        // Posted by DrLaszloJamf to Java Technology Forums
        //
        // Copyright 1994-2004 Sun Microsystems, Inc. All Rights Reserved.
        // Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
        //
        // Redistribution of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
        //
        // Redistribution in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
        //
        // Neither the name of Sun Microsystems, Inc. or the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
        //
        // This software is provided "AS IS," without a warranty of any kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
        //
        //
        // You acknowledge that this software is not designed, licensed or intended for use in the design, construction, operation or maintenance of any nuclear facility.

        //    preserves image's colormodel. Assumes image is loaded
        public static BufferedImage toBufferedImage(Image image)
        {
            if (image instanceof BufferedImage)
                return (BufferedImage)image;
            ColorModel cm = getColorModel(image);
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            return copy(createBufferedImage(cm, width, height), image);
        }

        public static BufferedImage toBufferedImage(Image image, int type)
        {
            if (image instanceof BufferedImage
                && ((BufferedImage)image).getType() == type)
                return (BufferedImage)image;
            int width = image.getWidth(null);
            int height = image.getHeight(null);
            return copy(new BufferedImage(width, height, type), image);
        }

        //    Returns target. Assumes source is loaded
        public static BufferedImage copy(BufferedImage target, Image source)
        {
            Graphics2D g = target.createGraphics();
            g.drawImage(source, 0, 0, null);
            g.dispose();
            return target;
        }

        public static ColorModel getColorModel(Image image)
        {
            try
            {
                PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
                pg.grabPixels();
                return pg.getColorModel();
            }
            catch (InterruptedException e)
            {
                throw new RuntimeException("Unexpected interruption", e);
            }
        }

        public static BufferedImage createBufferedImage(
            ColorModel cm,
            int w,
            int h)
        {
            WritableRaster raster = cm.createCompatibleWritableRaster(w, h);
            boolean isRasterPremultiplied = cm.isAlphaPremultiplied();
            return new BufferedImage(cm, raster, isRasterPremultiplied, null);
        }
    }




How do I import my picture as a BufferedImage (sorry, I know it's probably really easy).

ImageIO.read, but it won't read DDS or TGA because those are jME side image readers.

There's one overloaded method of TextureManager.loadTexture that takes an imageType parameter, so you can pass Format.Alpha8 to that to have your image loaded correctly as an alphamap.

Momoko_Fan said:

ImageIO.read, but it won't read DDS or TGA because those are jME side image readers.
There's one overloaded method of TextureManager.loadTexture that takes an imageType parameter, so you can pass Format.Alpha8 to that to have your image loaded correctly as an alphamap.


Overloaded in jME 1.0?

EDIT: Here’s an application that does it for you (I wrote it).