⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 heightmap.java

📁 3D手机游戏开发实例源代码
💻 JAVA
字号:
import java.io.IOException;

import javax.microedition.lcdui.Image;
import javax.microedition.m3g.*;

public class HeightMap
{
    // The actual heightmap containing the Y-coords of our indexBuffer
    private short[] heightMap;
    private int[] data;

    
    // Map dimensions
    private int mapWidth;
    private int mapHeight;
    
    // Actual quads
    private Mesh[][] map;
    private static final String  TerrainImgFn ="/heightmap1.png" ;
    private float resolution = 0.25f;
    private int imgw, imgh;    
    // Local transform used for internal calculations
    private Transform localTransform = new Transform();
    
    /**
     * Allocates the internal heightmap and prepares it for rendering.
     * @param imageName The path to the actual heightmap BW image
     * @param resolution The resolution of the heightmap. A value of 1.0 means that each pixel is one quad.
     * @param waterLevel TODO
     * @throws IOException if any error occurs while loading the heightmap image or the texture images.
     */
    public HeightMap() throws IOException
    {
        // Check for invalid resolution values
        if(resolution <= 0.0001f || resolution > 1.0f)
            throw new IllegalArgumentException("Resolution too small or too large");
        
        // Load image and allocate the internal array
        loadMapImage();
        
        // Create quads
        createQuads();

    }
    public Mesh[][]getQuads(){
      return map;	
    	
    }
    public int getMapWidth(){
      return mapWidth;
    }

    public int getMapHeight(){
      return mapHeight;
    }
    /**
     * Create all quads (Triangle pairs) that our 
     */
    private void createQuads()
    {
        map = new Mesh[mapWidth][mapHeight];
        short[] heights = new short[4];
        
        for(int x = 0; x < (mapWidth - 1); x++)
        {
            for(int y = 0; y < (mapHeight - 1); y++)
            {
                // Set heights
               heights[0] = heightMap[x + y * mapWidth];
               heights[1] = heightMap[x + y * mapWidth + 1];
               heights[3] = heightMap[x + (y + 1) * mapWidth];
               heights[2] = heightMap[x + (y + 1) * mapWidth + 1];
                
                // Create mesh
                map[x][y] = createQuad(heights);
            }
        }
                
    }


    private void loadMapImage() throws IOException
    {
        // Load actual image
        Image img = Image.createImage(TerrainImgFn);
        
        // Allocate temporary memory to store pixels
        data = new int[img.getWidth() * img.getHeight()];
        
        // Get its rgb values
        img.getRGB(data, 0, img.getWidth(), 0, 0, img.getWidth(), img.getHeight());
        
        imgw = img.getWidth();
        imgh = img.getHeight();
        
        // Clear image
        img = null;
        System.gc();
        
        // Calculate new width and height
        mapWidth = (int)(resolution * imgw);
        mapHeight = (int)(resolution * imgh);
        
        // Allocate heightmap
        heightMap = new short[mapWidth * mapHeight];
        
        // Calculate height and width offset into image
        int xoff = imgw / mapWidth;
        int yoff = imgh / mapHeight;
        
        // Set height values
        for(int y = 0; y < mapHeight; y++)
        {
            for(int x = 0; x < mapWidth; x++)
            {
                heightMap[x + y * mapWidth] = (short)((data[x * xoff + y * yoff * imgw] & 0x000000ff) * 10);
            }
        }        

        // Clear data
        data = null;
        img = null;
        System.gc();
    }
    
    /**
     * Renders this heightmap using a specified graphics context and a transform.
     * @param g3d
     * @param t
     */
    public void setTransform(Transform t)
    {
        for(int x = 0; x < map.length - 1; x++)
        {
            for(int y = 0; y < map[x].length - 1; y++)
            {
                localTransform.setIdentity();
                
                localTransform.postTranslate(x * 5.1f, 0.0f, (mapHeight - y) * -5.1f);
                localTransform.postScale(0.01f, 0.01f, 0.01f);
                localTransform.postMultiply(t);
                map[x][y].setTransform(localTransform);
            }
        }



    }
        
    /**
     * Creates a colored quad consisting of two indexBuffer.
     * The heights parameter is an array that holds the heights of the new quad.
     * The array must have a length of 4 and goes counter-clockwise starting from the
     * northwestern position of the quad (-1, -1)
     * @param heights The height array, denoting the heights (y-coords) of the four corners.
     * @param cullFlags
     * @param texFilename
     * @return
     */
    public static Mesh createQuad(short[] heights)
    {
        // The POINTS of the quad
        short[] POINTS = {-255, heights[0], -255,
                255, heights[1], -255,
                255, heights[2], 255,
                -255, heights[3], 255}; 
        
        // The arrays
        VertexArray POSITION_ARRAY;
        IndexBuffer indexBuffer;

        // Create the model's POINTS
        POSITION_ARRAY = new VertexArray(POINTS.length/3, 3, 2);
        POSITION_ARRAY.set(0, POINTS.length/3, POINTS);
        
        // Allocate COLORS array
        byte[] COLORS = new byte[12];
        
        for(int i = 0; i < heights.length; i++)
        {
            int j = i * 3;
	        // Altitude check
            if(heights[i] >= 1000)
            {
                byte col = (byte)(57 + (heights[i] / 1550.0f) * 70);
                COLORS[j] = col;
                COLORS[j + 1] = col;
                COLORS[j + 2] = col;
            }
	        else
	        {
	            byte gCol = 110;
	            byte bCol = 25;
	            
	            COLORS[j] = 0;
	            COLORS[j + 1] = (byte)(gCol - (heights[i] / 1000.0f) * 85);
	            COLORS[j + 2] = (byte)(bCol - (heights[i] / 1000.0f) * 20);
	        }
        }
        
        // Create the model's vertex colors
        VertexArray COLOR_ARRAY = new VertexArray(COLORS.length/3, 3, 1);
        COLOR_ARRAY.set(0, COLORS.length / 3, COLORS);
        
        // Compose a VertexBuffer out of the previous POINTS and texture coordinates
        VertexBuffer vertexBuffer = new VertexBuffer();
        vertexBuffer.setPositions(POSITION_ARRAY, 1.0f, null);
        vertexBuffer.setColors(COLOR_ARRAY);
        
        // Create INDICES and face lengths
        int INDICES[] = new int[] {0, 1, 3, 2};
        int[] LENGTHS = new int[] {4};
        
        // Create the model's indexBuffer
        indexBuffer = new TriangleStripArray(INDICES, LENGTHS);

        // Create the appearance
        Appearance appearance = new Appearance();
        PolygonMode polygonmode = new PolygonMode();
        polygonmode.setCulling(PolygonMode.CULL_NONE);
        polygonmode.setPerspectiveCorrectionEnable(true);
        polygonmode.setShading(PolygonMode.SHADE_SMOOTH);
        appearance.setPolygonMode(polygonmode);
        
        // Finally create the Mesh
        Mesh mesh = new Mesh(vertexBuffer, indexBuffer, appearance);

        // All done
        return mesh;
    }
  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -