| 25 | | |
|---|
| 26 | | this() |
|---|
| 27 | | { |
|---|
| 28 | | } |
|---|
| 29 | | |
|---|
| 30 | | /** |
|---|
| 31 | | * Sets the shape of the terrain. |
|---|
| 32 | | * Params: |
|---|
| 33 | | * heightMap = A grayscale image used as the heightmap of the Terrain. |
|---|
| 34 | | * func = A function used to generate the heightmap of the terrain. It's given x and y values between 0 and 1 |
|---|
| 35 | | * and it returns a 3d coordinate for that part of the Terrain grid. The heightMap image values are then |
|---|
| 36 | | * used to displace the values generated by this function. |
|---|
| 37 | | * Both the heightMap and func parameters are optional. |
|---|
| 38 | | * resolution = The number of points in the x and y directions that make up the terrain grid. |
|---|
| 39 | | * size = The x, y, and z dimentions of the generated terrain. */ |
|---|
| 40 | | void setGeometry(T)(Image2!(T, 1) heightMap=null, Vec3f delegate(float x, float y) func=null, Vec2f resolution=Vec2f(256), Vec3f size=Vec3f(1)) |
|---|
| 41 | | { |
|---|
| 42 | | // Mipmaps will be laid out something like this. |
|---|
| 43 | | mipmaps.length = 3; // I wonder how many levels we should generate? |
|---|
| 44 | | mipmaps[0].length = 1; // A single 64x64 block |
|---|
| 45 | | mipmaps[1].length = 4; // Four 64x64 blocks, etc. |
|---|
| 46 | | mipmaps[2].length = 16; |
|---|
| 47 | | |
|---|
| 48 | | assert(image || func); |
|---|
| 49 | | |
|---|
| 50 | | /// TODO |
|---|
| 51 | | } |
|---|
| 52 | | |
|---|
| 53 | | |
|---|
| 54 | | /** |
|---|
| 55 | | * Set the Textures used for rendering the terrain. |
|---|
| 56 | | * Params: |
|---|
| | 25 | |
|---|
| | 26 | /** |
|---|
| | 27 | * Provide a class that sets the shape and textures of the terrain. |
|---|
| | 28 | * Params: |
|---|
| | 29 | * generator = Instance of TerrainGenerator. |
|---|
| 60 | | * Internally, multitexturing is used to render the terrain in as few passes as necessary. |
|---|
| 61 | | * blending = Array of grayscale images the same length as textures which determines the amount |
|---|
| 62 | | * to show each texture at each point in the terrain. |
|---|
| 63 | | * lightmap = If specified, this Texture will be used as a lightmap and the Terrain's materials |
|---|
| 64 | | * will have lighting disabled. |
|---|
| 65 | | */ |
|---|
| 66 | | void setTextures(T)(Texture[] textures, Image2!(T, 1)[] blending, Texture* lightmap=null) |
|---|
| 67 | | { assert(textures.length==blending.length); |
|---|
| 68 | | |
|---|
| | 33 | * min = The minimum x and y value of the range of coordinates passed to generator's getPoint() function. |
|---|
| | 34 | * max = The maximum x and y value of the range of coordinates passed to generator's getPoint() function. |
|---|
| | 35 | * resolution = The number of points (grid resolution) in the x and y directions passed |
|---|
| | 36 | * to generator's getPoint() function. */ |
|---|
| | 37 | this(TerrainGenerator generator, Texture[] textures, Vec2f min=Vec2f(-128), Vec2f max=Vec2f(127), Vec2f resolution=Vec2f(256)) |
|---|
| | 38 | { |
|---|
| 97 | | |
|---|
| 98 | | |
|---|
| 99 | | /** |
|---|
| 100 | | * Load geometry from Earth Sculptor, available at http://earthsculptor.com */ |
|---|
| 101 | | void load(char[] filename) |
|---|
| 102 | | { // Lower priority than the other functions. Perhaps another terrain file format is better? |
|---|
| 103 | | } |
|---|
| 104 | | |
|---|
| | 65 | } |
|---|
| | 66 | |
|---|
| | 67 | /** |
|---|
| | 68 | * Defines functions a class must provide in order for TerrainNode to use it to generate Terrain. */ |
|---|
| | 69 | interface TerrainGenerator |
|---|
| | 70 | { |
|---|
| | 71 | /// Data structure for a single vertex in the Terrain Geometry. |
|---|
| | 72 | struct TerrainPoint |
|---|
| | 73 | { Vec3f position; /// xyz position of the terrain point |
|---|
| | 74 | Vec3f normal; /// Normal vector for this point on the terrain, used for lighting |
|---|
| | 75 | Vec2f textureCoordinate; /// Texture coordinates for this point on the terrain |
|---|
| | 76 | float[] textureBlend; /// Normalized vector of arbitrary length specifying the amount of each texture to |
|---|
| | 77 | /// use at this point. TerrainNode.setTextures() specifies the textures themselves. |
|---|
| | 78 | } |
|---|
| | 79 | |
|---|
| | 80 | /** |
|---|
| | 81 | * Get the values needed for a single vertex in the Terrain Geometry. */ |
|---|
| | 82 | TerrainPoint getPoint(Vec2f coordinate); |
|---|
| | 83 | |
|---|
| | 84 | /** |
|---|
| | 85 | * Get a lightmap Texture to use across the range of coordinates. |
|---|
| | 86 | * If no lightmap is desired, this function can return a Texture without a GPUTexture. |
|---|
| | 87 | * The same GPU Texture can be reused across multiple calls with different values, |
|---|
| | 88 | * if the Textures' texture matrix adjusted as needed. |
|---|
| | 89 | * Params: |
|---|
| | 90 | * min = Minumum xy coordinate of the rectangle needing a lightmap. |
|---|
| | 91 | * max = Maximum xy coordinate of the rectangle needing a lightmap. |
|---|
| | 92 | * Returns: An RGB texture to use as a baked light-map. It's color values will be modulated with the terrain. */ |
|---|
| | 93 | Texture getLightmap(Vec2f min, Vec2f max); |
|---|
| | 94 | } |
|---|
| | 95 | |
|---|
| | 96 | /** |
|---|
| | 97 | * A sample TerrainGenerator that uses a heightmap image to specify elevation and a color texture |
|---|
| | 98 | * to specify which textures to use at a given point. */ |
|---|
| | 99 | class HeightmapGenerator : TerrainGenerator |
|---|
| | 100 | { |
|---|
| | 101 | Image2!(ubyte, 1) heightMap; |
|---|
| | 102 | Image2!(ubyte, 4)[] textures; |
|---|
| | 103 | |
|---|
| | 104 | /** |
|---|
| | 105 | * |
|---|
| | 106 | * Params: |
|---|
| | 107 | * heightMap = |
|---|
| | 108 | * textures = The red component of the first textureBlend specifies how much of the first texture to use at this |
|---|
| | 109 | * point, The green for the second texture, blue for the third, and alpha for the fourth. |
|---|
| | 110 | * If more than four textures are used, the red component of the second textureBlend is used for the fifth, |
|---|
| | 111 | * and so on. */ |
|---|
| | 112 | this(Image2!(ubyte, 1) heightMap, Image2!(ubyte, 4)[] textureBlend) |
|---|
| | 113 | { this.heightMap = heightMap; |
|---|
| | 114 | this.textures = textures; |
|---|
| | 115 | } |
|---|
| | 116 | |
|---|
| | 117 | /** |
|---|
| | 118 | * Load heightmap and textureBlends from Earth Sculptor, available at http://earthsculptor.com */ |
|---|
| | 119 | this(char[] filename) |
|---|
| | 120 | { |
|---|
| | 121 | } |
|---|
| | 122 | |
|---|
| | 123 | TerrainPoint getPoint(Vec2f coordinate) |
|---|
| | 124 | { TerrainPoint result; |
|---|
| | 125 | |
|---|
| | 126 | result.position.x = coordinate.x; |
|---|
| | 127 | result.position.y = coordinate.y; /// TODO: [below] It would be better to interpolate values. |
|---|
| | 128 | result.position.z = 0; // heightMap[coordinate.x*heightMap.width, coordinate.y*heightMap.height]; |
|---|
| | 129 | |
|---|
| | 130 | // TODO texture coordinates, normals, and textureBlend |
|---|
| | 131 | |
|---|
| | 132 | return result; |
|---|
| | 133 | } |
|---|
| | 134 | |
|---|
| | 135 | Texture getLightmap(Vec2f min, Vec2f max) |
|---|
| | 136 | { Texture texture; |
|---|
| | 137 | return texture; // return no lightmap for now. |
|---|
| | 138 | } |
|---|