Show Terrain.h syntax highlighted
// Demeter Terrain Visualization Library by Clay Fowler
// Copyright (C) 2002 Clay Fowler
// $ID$
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef _TERRAIN_DEMETER_H_
#define _TERRAIN_DEMETER_H_
namespace Demeter
{
class ReloadMaskRequest;
/// \brief Enumerated values that are used in the TerrainLattice to
/// identify neighboring Terrain objects in a grid of Terrain objects.
/// These values are used by TerrainLattice.
enum DIRECTION
{
/// Offset along the positive y axis
DIR_NORTH = 0,
/// Offset along positive x and y axes
DIR_NORTHEAST = 1,
/// Offset along positive x axis
DIR_EAST = 2,
/// Offset along positive x and negative y axes
DIR_SOUTHEAST = 3,
/// Offset along negative y axis
DIR_SOUTH = 4,
/// Offset along negative x and y axes
DIR_SOUTHWEST = 5,
/// Offset along negative x axis
DIR_WEST = 6,
/// Offset along negative x and positive y axes
DIR_NORTHWEST = 7,
/// No offset
DIR_CENTER = 8,
/// Placeholder for uninitialized and maximum values
DIR_INVALID = 9
};
class TerrainBlock;
class Terrain;
class Texture;
class TextureSet;
class TextureCell;
class Vector;
class Box;
class DetailTexture;
}
#include "Demeter/Globals.h"
#include "Demeter/DemeterException.h"
#include "Demeter/Settings.h"
#include "Demeter/Texture.h"
#include "Demeter/Box.h"
#include "Demeter/TextureCell.h"
#include "Demeter/TextureSet.h"
#include "Demeter/TerrainBlock.h"
#include "Demeter/Vector.h"
#include "Demeter/TerrainLattice.h"
#include "Demeter/TerrainVertex.h"
#include "Demeter/Shader.h"
#include "Demeter/Triangle.h"
#include <vector>
/// \brief The Demeter Terrain Engine.
namespace Demeter
{
class TrianglePair
{
public:
Demeter::Triangle* m_pTriangle1;
Demeter::Triangle* m_pTriangle2;
};
class TERRAIN_API TessellationListener
{
public:
// Ideally, this would be pure virtual, but Visual Studio chokes...
virtual void HandleTessellationComplete(Terrain* pTerrain) {}
};
/// \brief This class represents a single, contiguous chunk of terrain and is the primary public interface to Demeter.
/// Most applications will create a single instance of this class to represent the terrain in the application,
/// but multiple instances can be used to stitch together a very large world comprised of multiple terrains using
/// the TerrainLattice class. The simplest way to use this class to make a new instance using the constructor that
/// takes no params and then use an ElevationLoader and a TextureLoader to give it vertices and textures. Alternatively,
/// you can use the constructor that takes arrays of floats and bytes if you wish to load your own elevation and texture data.
class TERRAIN_API Terrain
{
public:
/// \brief Constructs a (mostly) empty terrain suitable for use by an ElevationLoader.
Terrain();
/// \brief Constructs a new terrain from raw elevation and image data in memory buffers.
/// By using this constructor, you are specifying the layout of all of the vertices in the Terrain's mesh.
/// These vertices are always a rectangular grid of 3D points at regularly spaced intervals. You are also specifying
/// what the overall terrain texture looks like.
/// \param pElevations An array of floating point values representing the elevation (z value) of each vertex in the terrain's mesh.
/// The size of this array must be equal to elevWidth * elevHeight
/// \param elevWidth The number of vertices along the x-axis (width) of the grid of vertices in pElevations.
/// \param elevHeight The number of vertices along the y-axis (height) of the grid of vertices in pElevations.
/// \param pTextureImage An array of byte values representing the texture image that will be draped across the entire
/// surface of the Terrain (this is the "overall" texture.) The array must contain 3 bytes per pixel - the red, green, and blue color values of the pixel respectively.
/// It is assumed that the array does not contain any extra padding per image row. Therefore, if your image is 1024x1024 pixels, then
/// this array should be 9,437,184 bytes in size. You can pass NULL for this parameter to build a Terrain with no texture.
/// \param textureWidth The width of the texture image in pixels.
/// \param textureHeight The height of the texture image in pixels.
/// \param pDetailTextureImage This is similar to the pTextureImage parameter, but instead of describing the overall terrain texture, this buffer
/// buffer describes the "common" texture. See Terrain::SetCommonTexture() for details. You can pass NULL for this parameter to build a Terrain with no common texture.
/// \param detailWidth The width of the detail texture image in pixels.
/// \param detailHeight The height of the detail texture image in pixels.
/// \param vertexSpacing The distance, in world modelling units, between vertices in the Terrain's mesh.
/// This distance is constant in both the horizontal and vertical directions. For example, if your pass in an array
/// of 1024x1024 vertices for the pElevations and elevWidth and elevHeight parameters, and pass a value of 10.0 for the
/// vertexSpacing parameter, then the resulting Terrain will be 10240 x 10240 world units in size.
/// \param elevationScale A scaling factor that is applied to all of the values in the pElevations array. Most
/// applications will pass a 1.0 for this value since presumably pElevations was built by the application.
/// \param offsetX Horizontal translation of this Terrain in world units. See Terrain::SetOffserX().
/// \param offsetY Vertical translation of this Terrain in world units. See Terrain::SetOffserY().
Terrain(const float *pElevations, int elevWidth, int elevHeight, const Uint8 * pTextureImage, int textureWidth, int textureHeight, const Uint8 * pDetailTextureImage, int detailWidth, int detailHeight, float vertexSpacing, float elevationScale, float offsetX = 0.0f, float offsetY = 0.0f);
/// By using this constructor, you are specifying the layout of all of the vertices in the Terrain's mesh. This version
/// of the constructor creates a Terrain that is a flat plane with elevations of zero at all vertices. Otherwise, it is identical
/// to the constructor that takes pElevations.
/// \param widthVertices The number of vertices along the x-axis (width) of the grid of vertices in the mesh.
/// \param heightVertices The number of vertices along the y-axis (height) of the grid of vertices in the mesh.
/// \param vertexSpacing The distance, in world modelling units, between vertices in the Terrain's mesh.
/// This distance is constant in both the horizontal and vertical directions. For example, if your pass in an array
/// of 1024x1024 vertices for the pElevations and elevWidth and elevHeight parameters, and pass a value of 10.0 for the
/// vertexSpacing parameter, then the resulting Terrain will be 10240 x 10240 world units in size.
Terrain(int widthVertices, int heightVertices, float vertexSpacing,bool useRaytracing = true);
/// \brief Constructs a (mostly) empty terrain suitable for use by an ElevationLoader.
/// \param offsetX Horizontal translation of this Terrain in world units. See Terrain::SetOffserX().
/// \param offsetY Vertical translation of this Terrain in world units. See Terrain::SetOffserY().
Terrain(float offsetX, float offsetY);
~Terrain();
/// \brief Breaks the Terrain down into renderable triangles.
/// Based on the current viewing parameters, this method breaks the terrain down into a
/// visually optimum set of triangles that can be rendered. Normally, an application will never
/// call this method directly, but will instead call the method ModelViewMatrixChanged() to allow
/// Demeter to take care of this automatically.
void Tessellate();
/// \brief Renders the terrain to the current OpenGL surface.
/// Applications should always call ModelViewMatrixChanged() at least once prior to calling
/// Render(), so that Demeter will have a chance to tessellate the terrain.
void Render();
/// \brief Sets the "detail theshold", which controls how much Demeter simplifies the terrain.
/// Higher thresholds will increase performance but make the terrain look worse, while lower
/// thresholds will reduce performance and increase visual quality. Extremely high thresholds
/// can cause significant visual artifacts.
/// \param threshold An error metric, measured in screen pixels. Any terrain blocks smaller than this threshold will be simplified.
void SetDetailThreshold(float threshold);
/// \brief Returns the "detail threshold."
float GetDetailThreshold() const;
/// \brief Sets the maximum size of blocks that can be simplified when the terrain is tessellated.
/// This setting can be used by applications that allow much of the terrain to be visible from above,
/// such as flight simulators, to prevent oversimplification of terrain in the distance.
/// Setting this value too low will adversely affect performance.
/// \param stride Specifies the number of vertices along one edge of the block (blocks are always square.)
void SetMaximumVisibleBlockSize(int stride);
/// \brief Returns the width of the terrain in vertices (this is the count of vertices along the world's x-axis.)
int GetWidthVertices() const;
/// \brief Returns the height of the terrain in vertices (this is the count of vertices along the world's y-axis.)
int GetHeightVertices() const;
/// \brief Returns the width of the terrain in world units (this is the length of the terrain along the world's x-axis.)
float GetWidth() const;
/// \brief Returns the height of the terrain in world units (this is the length of the terrain along the world's y-axis.)
float GetHeight() const;
/// \brief Returns the number of real units between vertices in the terrain's mesh.
float GetVertexSpacing() const;
/// \brief Returns the elevation (z-coordinate) in real units of the specified point on the terrain.
/// \param x The x location of the point on the Terrain's surface in world units.
/// \param y The y location of the point on the Terrain's surface in world units.
float GetElevation(float x, float y) const;
/// \brief Returns the elevation (z-coordinate) in real units of the specified terrain vertex.
/// \param index The index of the vertex in the Terrain's mesh to get the elevation of.
float GetElevation(int index) const;
/// \brief Returns the surface normal of the terrain at the specified point.
/// \param x The x location of the point on the Terrain's surface in world units.
/// \param y The y location of the point on the Terrain's surface in world units.
/// \param normalX Gets filled with the surface normal x component
/// \param normalY Gets filled with the surface normal y component
/// \param normalZ Gets filled with the surface normal z component
void GetNormal(float x, float y, float &normalX, float &normalY, float &normalZ) const;
/// \brief Returns the elevation (z-coordinate) in real units of the highest point on the terrain.
float GetMaxElevation() const;
/// \brief Returns the index of the vertex closest to the specified point.
/// \param x The x location of the point on the Terrain's surface in world units.
/// \param y The y location of the point on the Terrain's surface in world units.
int GetVertex(float x, float y) const;
/// \brief Returns the elevation (z-coordinate) in real units of the specified vertex on the terrain.
/// \param index The index of the vertex in the Terrain's mesh to get the elevation of.
float GetVertexElevation(int index) const;
/// \brief Sets the elevation (z-coordinate) in real units of the specified vertex on the terrain.
/// \param index The index of the vertex in the Terrain's mesh to set the elevation of.
/// \param newElevation The new z-value (elevation) of the vertex to be set.
/// \param recalculate_geometry Specified whether or not terrain block bounding boxes should be updated as a result of this vertex changed. You would pass false here only when you are sequentially setting many vertices, in which case you would pass true only on the last vertex changed (this prevents redundant recalculation for each vertex changed.)
void SetVertexElevation(int index, float newElevation, bool recalculate_geometry = true);
/// \brief Sets the elevation (z-coordinate) in real units of the nearest vertex to the specified point.
/// \param x The x location of the point on the Terrain's surface in world units.
/// \param y The y location of the point on the Terrain's surface in world units.
/// \param newElevation The new z-value (elevation) of the vertex to be set.
void SetVertexElevation(float x, float y, float newElevation);
/// \brief Recalculates bounding box for the quad spanning from vertex 1 to vertex 2
/// \param index1 The index of the top-left vertex
/// \param index2 The index of the bottom-right vertex
void RecalcGeometry(int index1, int index2);
/// \brief Recalculates all bounding boxes
void RecalcGeometry();
/// \brief Recalculates the normal vector of the vertex closes to the specified point.
/// \param x The x location of the point on the Terrain's surface in world units.
/// \param y The y location of the point on the Terrain's surface in world units.
void RecalcNormal(float x, float y);
/// \brief Recalculates the normal vector of the specified vertex.
/// \param vertexIndex The index of the vertex in the Terrain's mesh.
void RecalcNormal(int vertexIndex);
/// \brief Replaces all of the Terrain's vertices with a new set of vertices.
/// \param pElevations An array of floating point values representing the elevation (z value) of each vertex in the terrain's mesh.
/// The size of this array must be equal to elevWidth * elevHeight
/// \param elevWidth The number of vertices along the x-axis (width) of the grid of vertices in pElevations.
/// \param elevHeight The number of vertices along the y-axis (height) of the grid of vertices in pElevations.
/// \param vertexSpacing The distance, in world modelling units, between vertices in the Terrain's mesh.
/// This distance is constant in both the horizontal and vertical directions. For example, if your pass in an array
/// of 1024x1024 vertices for the pElevations and elevWidth and elevHeight parameters, and pass a value of 10.0 for the
/// vertexSpacing parameter, then the resulting Terrain will be 10240 x 10240 world units in size.
/// \param elevationScale A scaling factor that is applied to all of the values in the pElevations array. Most
/// applications will pass a 1.0 for this value since presumably pElevations was built by the application.
void SetAllElevations(const float *pElevations, int elevWidth, int elevHeight, float vertexSpacing, float elevationScale = 1.0f);
/// \brief Returns the total number of vertices in the terrain's mesh.
int GetNumberOfVertices() const;
/// \brief Returns the width (in vertices) of the terrain's texture cells. See the TextureCell class.
float GetTextureTileWidth() const;
/// \brief Returns the height (in vertices) of the terrain's texture cells. See the TextureCell class.
float GetTextureTileHeight() const;
/// \brief Returns the number of texture cells along the terrain's x-axis. See the TextureCell class.
int GetNumberOfTextureTilesWidth() const;
/// \brief Returns the number of texture cells along the terrain's y-axis. See the TextureCell class.
int GetNumberOfTextureTilesHeight() const;
/// \brief Applies the specified graphics image as a texture to the terrain.
/// This is done by breaking the specified image up into smaller textures of 256x256 called
/// TextureCells and mapping these contiguously onto the terrain's surface.
/// Textures are automatically applied by TextureLoaders and by the byte
/// array constructors, so use of this method is entirely optional.
/// \param pTextureImage An array of byte values representing the texture image that will be draped across the entire
/// surface of the Terrain (this is the "overall" texture.) The array must contain 3 bytes per pixel - the red, green, and blue color values of the pixel respectively.
/// It is assumed that the array does not contain any extra padding per image row. Therefore, if your image is 1024x1024 pixels, then
/// this array should be 9,437,184 bytes in size. You can pass NULL for this parameter to build a Terrain with no texture.
/// \param width The width of the texture image in pixels.
/// \param height The height of the texture image in pixels.
bool SetTexture(const Uint8 * pTextureImage, int width, int height);
/// \brief Uses the specified graphics image to apply a "common" texture to the entire surface of
/// the terrain.
/// A common texture is repeated across the entire terrain and is blended with the
/// terrain's overall texture (if blending is supported by the user's hardware.)
/// This is used to provide a texture to give the ground some definition when the camera is
/// close to the ground, but is an inferior to alternative to the use of specific DetailTexture instances.
/// \param pImage An array of byte values representing the texture image that will be draped across the entire
/// surface of the Terrain (this is the "overall" texture.) The array must contain 3 bytes per pixel - the red, green, and blue color values of the pixel respectively.
/// It is assumed that the array does not contain any extra padding per image row. Therefore, if your image is 1024x1024 pixels, then
/// this array should be 9,437,184 bytes in size. You can pass NULL for this parameter to build a Terrain with no texture.
/// \param width The width of the texture image in pixels.
/// \param height The height of the texture image in pixels.
bool SetCommonTexture(const Uint8 * pImage, int width, int height);
/// \brief Uses the specified Texture to apply a "common" texture to the entire surface of
/// the terrain.
/// A common texture is repeated across the entire terrain and is blended with the
/// terrain's overall texture (if blending is supported by the user's hardware.)
/// This is used to provide a texture to give the ground some definition when the camera is
/// close to the ground, but is an inferior to alternative to the use of specific DetailTexture instances.
/// \param pTexture A Texture object to use as the common texture.
void SetCommonTexture(Texture * pTexture);
/// \brief Returns the Texture object representing the common texture that has been applied to the Terrain, if any.
Texture *GetCommonTexture() const;
/// \brief Gets the filename tag of the common Texture object.
/// \param szFilename A buffer to fill with the texture filename. This buffer must have already been allocated by the caller.
/// \param bufferSize The size of the buffer. If the value is larger than the buffer can handle a DemeterException will be thrown.
void GetCommonTextureFilename(char *szFilename, int bufferSize);
/// \brief Notifies Demeter that OpenGL's modelview matrix has been modified, allowing Demeter
/// to tessellate the terrain based on the new modelview matrix.
/// It is IMPERATIVE that this method be called every time the modelview matrix is changed, even
/// if this is in every single rendering cycle of the application. Based on the current viewing
/// parameters, the terrain will be broken down into a visually optimum set of triangles that can
/// be rendered.
void ModelViewMatrixChanged();
/// \brief Indicates whether or not the specified cuboid is inside of the viewing frustum
/// (as defined at the previous call to ModelViewMatrixChanged().)
/// \param cuboid The box to test.
bool CuboidInFrustum(const Box & cuboid) const;
/// \brief Casts a ray from the specified point, in the specified direction, and calculates the ray's point of intersection with the terrain.
/// This method makes use of the terrain's quad tree to optimize the ray-tracing.
/// \return The distance from the starting point to the intersection. A negative value is returned if the ray misses the Terrain.
/// \param startX The starting point of the ray.
/// \param startY The starting point of the ray.
/// \param startZ The starting point of the ray.
/// \param dirX The direction of the ray - this vector should be normalized.
/// \param dirY The direction of the ray - this vector should be normalized.
/// \param dirZ The direction of the ray - this vector should be normalized.
/// \param length The length of the ray.
/// \param intersectX Filled with the intersection point of this ray with the Terrain surface.
/// \param intersectY Filled with the intersection point of this ray with the Terrain surface.
/// \param intersectZ Filled with the intersection point of this ray with the Terrain surface.
float IntersectRay(float startX, float startY, float startZ, float dirX, float dirY, float dirZ, float length, float &intersectX, float &intersectY, float &intersectZ);
/// \brief An overload of IntersectRay that also provides information about the texture coordinates of the intersected point in addition the position of the point.
/// \return The distance from the starting point to the intersection. A negative value is returned if the ray misses the Terrain.
/// \param startX The starting point of the ray.
/// \param startY The starting point of the ray.
/// \param startZ The starting point of the ray.
/// \param dirX The direction of the ray - this vector should be normalized.
/// \param dirY The direction of the ray - this vector should be normalized.
/// \param dirZ The direction of the ray - this vector should be normalized.
/// \param length The length of the ray.
/// \param intersectX Filled with the intersection point of this ray with the Terrain surface.
/// \param intersectY Filled with the intersection point of this ray with the Terrain surface.
/// \param intersectZ Filled with the intersection point of this ray with the Terrain surface.
/// \param textureCellX Filled with the X position of the intersected TextureCell object in the Terrain's grid of TextureCells.
/// \param textureCellY Filled with the Y position of the intersected TextureCell object in the Terrain's grid of TextureCells.
/// \param texU Filled with the coordinate within the TextureCell where the intersection point is (range from 0.0 to 1.0.)
/// \param texV Filled with the coordinate within the TextureCell where the intersection point is (range from 0.0 to 1.0.)
float IntersectRay(float startX, float startY, float startZ, float dirX, float dirY, float dirZ, float length, float &intersectX, float &intersectY, float &intersectZ, int &textureCellX, int &textureCellY, float &texU, float &texV);
bool GetPenetration(float x,float y,float z,float& penetrationX,float& penetrationY,float& penetrationZ,float& penetrationDepth);
/// \brief Quickly find the 3D point on the terrain where a given point on the screen is (for example, for mouse picking.)
/// This is cheaper and faster than using the ray tracing methods, but far less accurate.
/// The accuracy of this method depends upon the z-buffer depth and the screen resolution.
/// \param screenX The X position of the pixel on the screen that was "clicked"
/// \param screenY the Y position of the pixel on the screen that was "clicked" - you will often
/// to invert this value since the OpenGL screen Y-axis runs opposite that of most window systems.
/// For example, you may need to pass <Code>Settings::GetInstance()->GetScreenHeight() - mouseY</Code> instead of just passing <Code>mouseY</Code>.
/// \param pickedX Filled with the picked point on Terrain surface.
/// \param pickedY Filled with the picked point on Terrain surface.
/// \param pickedZ Filled with the picked point on Terrain surface.
/// \return Returns false is the picked point is not on the Terrain.
bool Pick(int screenX, int screenY, float &pickedX, float &pickedY, float &pickedZ) const;
/// \brief Quickly find the 3D point on the terrain where a given point on the screen is (for example, for mouse picking.)
/// This is cheaper and faster than using the ray tracing methods, but far less accurate.
/// The accuracy of this method depends upon the z-buffer depth and the screen resolution.
/// \param screenX The X position of the pixel on the screen that was "clicked"
/// \param screenY the Y position of the pixel on the screen that was "clicked" - you will often
/// to invert this value since the OpenGL screen Y-axis runs opposite that of most window systems.
/// For example, you may need to pass <Code>Settings::GetInstance()->GetScreenHeight() - mouseY</Code> instead of just passing <Code>mouseY</Code>.
/// \param pickedX Filled with the picked point on Terrain surface.
/// \param pickedY Filled with the picked point on Terrain surface.
/// \param pickedZ Filled with the picked point on Terrain surface.
/// \param textureCellX Filled with the X position of the intersected TextureCell object in the Terrain's grid of TextureCells.
/// \param textureCellY Filled with the Y position of the intersected TextureCell object in the Terrain's grid of TextureCells.
/// \param texU Filled with the coordinate within the TextureCell where the intersection point is (range from 0.0 to 1.0.)
/// \param texV Filled with the coordinate within the TextureCell where the intersection point is (range from 0.0 to 1.0.)
/// \return Returns false is the picked point is not on the Terrain.
bool Pick(int screenX, int screenY, float &pickedX, float &pickedY, float &pickedZ, int &textureCellX, int &textureCellY, float &texU, float &texV) const;
/// \brief Returns the texture coordinates of a given point on the terrain in world coordinates.
/// \param x The x location of the point on the Terrain's surface in world units.
/// \param y The y location of the point on the Terrain's surface in world units.
/// \param textureCellX Filled with the X position of the intersected TextureCell object in the Terrain's grid of TextureCells.
/// \param textureCellY Filled with the Y position of the intersected TextureCell object in the Terrain's grid of TextureCells.
/// \param texU Filled with the coordinate within the TextureCell where the intersection point is (range from 0.0 to 1.0.)
/// \param texV Filled with the coordinate within the TextureCell where the intersection point is (range from 0.0 to 1.0.)
void GetTextureCoordinates(float x, float y, int &textureCellX, int &textureCellY, float &texU, float &texV) const;
/// \brief Paints a "splat" of the specified shared texture at the specified position on the terrain in world coordinates.
/// See the TextureSet class for details on how to get a detailTextureIndex for painting.
/// \param detailTextureIndex The shared index of a Texture object that is part of this Terrain object's TextureSet.
/// \param brushWidth The width of the brush to paint with in DetailTexture layer pixels. There are typically 256 of these pixels across a TextureCell.
/// \param brushIntensity The intensity with which to paint, ranging from 0.0 to 1.0. This determines how opaque the painted "splat" will be.
/// \param maxIntensity The maximum intensity of the painted splat, ranging from 0.0 to 1.0, accounting for mixing with a splat that may already reside on the surface.
/// \param erase Specifies whether to add the splat to the surface or remove existing splat texels already on the surface (pass false to paint and pass true to erase existing splats)
/// \param x The x location of the point to paint on the Terrain's surface in world units.
/// \param y The y location of the point to paint on the Terrain's surface in world units.
void Paint(int detailTextureIndex, int brushWidth, float brushIntensity, float maxIntensity, bool erase, float x, float y);
/// \brief Paints the entire terrain surface with the specified shared texture using the intensities in pPixels
/// This method is useful for painting the entire terrain surface in one fell swoop, such as when loading mask data from image files where the image files contain the entire detail texture map for the terrain.
/// \param detailTextureIndex The shared index of a Texture object that is part of this Terrain object's TextureSet.
/// \param pPixels An array of byte values (0-255). The array is a rectangular array of texels where each value specifies the intensity of the detail texture at that texel on the terrain surface.
void Paint(int detailTextureIndex, Uint8* pPixels);
/// \brief Indicates whether or not OpenGL multitexture extensions are available from the OpenGL driver that this terrain instance is currently rendering against (as determined at the time the terrain instance was first constructed.)
bool IsMultiTextureSupported() const;
/// \brief Sets this Terrain object's location within a lattice of Terrains that are being managed by a TerrainLattice object.
/// \param x The position within a TerrainLattice object's grid of Terrains that this object will fill.
/// \param y The position within a TerrainLattice object's grid of Terrains that this object will fill.
void SetLatticePosition(int x, int y);
/// \brief Gets this Terrain object's location within a lattice of Terrains that are being managed by a TerrainLattice object.
/// \param x Filled with the position within a TerrainLattice object's grid of Terrains that this object fills.
/// \param y Filled with the position within a TerrainLattice object's grid of Terrains that this object fills.
void GetLatticePosition(int &x, int &y);
/// \brief Gets the TextureCell at the specified position within this Terrain's grid of cells.
/// \param index The index of the TextureCell within this Terrain's grid of TextureCells.
TextureCell *GetTextureCell(int index);
/// \brief Gets the TextureCell at the specified position within this Terrain's grid of cells.
/// \param textureCellX The x position of the TextureCell within this Terrain's grid of TextureCells.
/// \param textureCellY The y position of the TextureCell within this Terrain's grid of TextureCells.
TextureCell* GetTextureCell(int textureCellX, int textureCellY);
TextureCell* GetTextureCellByPosition(float worldX,float worldY);
/// \brief Writes a binary "surface" file for fine-grained detail textures.
/// \deprecated This file format has been replaced by the Demeter Texture Editor XML format.
/// \param szFilename A filename to write to. The media path will be prepended to this file. See Settings::SetMediaPath().
void Write(char *szFilename);
/// \brief Reads a binary "surface" file for fine-grained detail textures. NOTE: the format of this file will be changed soon.
/// \deprecated This file format has been replaced by the Demeter Texture Editor XML format.
/// \param szFilename A filename to read from. The media path will be prepended to this file. See Settings::SetMediaPath().
void Read(char *szFilename);
/// \brief Gets the TextureSet that represents this Terrain object's pool of shared Textures.
TextureSet *GetTextureSet();
/// \brief Sets the TextureSet that represents this Terrain object's pool of shared Textures.
/// replacing the default one that was created automatically.
/// \param pTextureSet The new TextureSet, presumably one that was created by your application.
void SetTextureSet(TextureSet * pTextureSet);
/// \brief Installs a new TextureCell at the specified position within this Terrain's grid of
/// TextureCells.
/// \param index The index of the TextureCell within this Terrain's grid of TextureCells.
/// \param pCell The new TextureCell to install, presumably one that was created by your application.
void SetTextureCell(int index, TextureCell * pCell);
/// \brief Write all of this Terrain's textures to raw binary files.
/// \param szTerrainName A filename to write to. The media path will be prepended to this file. See Settings::SetMediaPath().
void WriteRawTextures(const char *szTerrainName);
/// \brief Write all of this Terrain's vertices to a raw binary file.
/// \param szFilename A filename to write to. The media path will be prepended to this file. See Settings::SetMediaPath().
void WriteRawElevations(const char *szFilename);
/// \brief Sets the size of this Terrain's grid of TextureCell objects.
/// You must specify a number of cells such that the following equation evalues to integral values for
/// <Code>tw</Code> and <Code>tv</Code>, otherwise your Terrain will show seams between textures:<Code>\par
/// vx = number of terrain mesh vertices x\par
/// vy = number of terrain mesh vertices y\par
/// nx = numTextureCellsX\par
/// ny = numTextureCellsY\par
/// vs = terrain's vertex spacing\par
/// tw = width of a TextureCell in vertices\par
/// th = height of a TextureCell in vertices\par
/// tw = ((vx + nx - 1) / nx - 1) / vs\par
/// th = ((vy + ny - 1) / ny - 1) / vs</Code>\par
/// See the TextureCell class for details.
/// \param numTextureCellsX The number of cells in the X direction of this Terrain's grid of TextureCells.
/// \param numTextureCellsY The number of cells in the Y direction of this Terrain's grid of TextureCells.
void AllocateTextureCells(int numTextureCellsX, int numTextureCellsY);
/// \brief Returns the width of the overall terrain texture in pixels.
int GetBaseTextureWidth();
/// \brief Returns the height of the overall terrain texture in pixels.
int GetBaseTextureHeight();
/// \brief If reload mask enqueuing is active (via Settings::SetMaskReloadQueueActive()) then this method services all pending mask reloads that have been enqueued. Generally, applications should call this method once per cycle (when using mask enqueuing.)
void FinishPaints();
/// \brief Increment the reference count by one, indicating that this object has another pointer which is referencing it.
/// This method is provided for use of Demeter with the Open Scene Graph.
void ref() const;
/// \brief Decrement the reference count by one, indicating that a pointer to this object is referencing it.
/// If the reference count goes to zero, it is assumed that this object is no longer referenced
/// and is automatically deleted. This method is provided for use of Demeter with the
/// Open Scene Graph.
void unref() const;
/// \brief Gets the raw bits of the alpha mask of the specified detail texture within the specified TextureCell.
Uint8 *GetMaskBits(int textureCellX, int textureCellY, int detailIndex, int &maskWidth, int &maskHeight);
/// \brief Unbinds and rebinds the alpha mask of the specified TextureCell so that changes to the mask become visible when rendering.
void ReloadMask(int textureCellX, int textureCellY, int detailIndex);
/// \brief Set this Terrain object's origin.
/// This is used by the TerrainLattice class when a grid of Terrains is being managed, but can also be used as a simple way to apply translation to a Terrain.
void SetOffset(float x, float y);
/// \brief Gets this Terrain object's origin.
/// This is used by the TerrainLattice class when a grid of Terrains is being managed, but can also be used as a simple way to apply translation to a Terrain.
float GetOffsetX() const;
/// \brief Gets this Terrain object's origin.
/// This is used by the TerrainLattice class when a grid of Terrains is being managed, but can also be used as a simple way to apply translation to a Terrain.
float GetOffsetY() const;
/// Experimental. Use at your own risk.
void CalculateHeightfieldLighting(float sunDirectionX,float sunDirectionY,float sunDirectionZ,float diffuseRed,float diffuseGreen,float diffuseBlue,float ambientRed,float ambientGreen,float ambientBlue,Uint8** ppLightMap,int& lightMapWidth,int& lightMapHeight);
/// Experimental. Use at your own risk.
void SetHeightfieldLighting(Uint8* pLightMap);
/// \brief Digs a crater.
/// Digs a crater of the specified size at the specified location, optionally painting a splat of a detail texture at that position (this splat might be a "broken earth" or "scorch mark" texture, for example). This is simply one way to dig a crater in the terrain. For maximum control it is best to modify terrain vertices yourself from your application.
/// \param centerX The location of the center of the crater.
/// \param centerY The location of the center of the crater.
/// \param radius The radius of the crater.
/// \param textureId The texture ID of the detail texture to splat at the texture's position. This is the id that was returned in a prior call to TextureSet::AddTexture().
void DigCrater(float centerX, float centerY, float radius, int textureId = -1);
/// \brief Get the terrain's vertex data.
/// Fetches the vertices from the specified area of the terrain.
/// \param centerX The location of the center of the area from which to fetch vertices.
/// \param centerY The location of the center of the area from which to fetch vertices.
/// \param radius The size of the area to fetch vertices from.
/// \param vertices A reference to a std::vector that will be filled with the requested vertices.
void GetVertices(float centerX, float centerY, float radius, std::vector < TerrainVertex > &vertices);
/// \brief Specifies whether or not to use VBO's for the terrain's vertices, texture coordinates, and normals.
/// Turns use of VBO's on or off for the terrain. Using VBO's dramatically increases performance when using any detail textures at all. The only time you would want to turn this off would be to support very low-end video hardware and in that case it's probably best to make this setting optional for the user of your application.
/// \param use True to enable VBO's, false to disable them.
void SetUseVertexBufferObjects(bool use);
/// \brief Indicates whether or not the terrain will use VBO's for rendering.
/// Indicates whether or not the terrain will use VBO's for rendering.
bool UseVertexBufferObjects();
/// \brief Specifies whether or not Demeter should vertically flip textures.
/// Specifies whether or not Demeter should vertically flip textures. You would turn this on if your textures are in a format that loads upside down, such as when loading .png images with the SDLTextureLoader.
void SetNeedsTextureFlip(bool needsFlip);
/// \brief Indicates whether or not Demeter will vertically flip textures.
bool NeedsTextureFlip();
/// \brief Specifies whether or not Demeter will set GL state regarding the Z buffer while rendering.
/// Specifies whether or not Demeter will set GL state regarding the Z buffer while rendering. You can turn this off if you want Demeter to simply obey the Z buffer state your application has already setup at render time (such as when using Demeter with OSG and you want it to simply obey the current StateSet).
/// \param controls True to allow Demeter to set Z buffer state itself, false to tell Demeter to leave Z buffer state alone.
void SetControlsZBuffer(bool controls);
/// \brief Specifies whether or not Demeter will set GL state regarding face culling while rendering.
/// Specifies whether or not Demeter will set GL state regarding face culling while rendering. You can turn this off if you want Demeter to simply obey the face culling state your application has already setup at render time (such as when using Demeter with OSG and you want it to simply obey the current StateSet).
/// \param cullFaces True to allow Demeter to set face culling state itself, false to tell Demeter to leave face culling state alone.
void SetCullFaces(bool cullFaces);
/// \brief Gets the current OpenGL modelview matrix as fetched in the current frame.
double* GetModelViewMatrix();
/// \brief Gets the current OpenGL projection matrix as fetched in the current frame.
double* GetProjectionMatrix();
/// \brief Gets the current OpenGL viewport matrix as fetched in the current frame.
GLint* GetViewport();
/// Experimental. Use at your own risk.
void SetShaderLight(float ambientLevel,float x,float y,float z);
/// \brief Sets the base texture for the terrain when using the experimental Shader option.
void SetBaseTexture(Texture* pTexture);
/// \brief Sets the mask texture for the terrain when using the experimental Shader option.
void SetMask(Texture* pTexture);
/// \brief Sets the first detail texture for the terrain when using the experimental Shader option.
void SetDetail0(Texture* pTexture);
/// \brief Sets the second detail texture for the terrain when using the experimental Shader option.
void SetDetail1(Texture* pTexture);
/// \brief Sets the third detail texture for the terrain when using the experimental Shader option.
void SetDetail2(Texture* pTexture);
/// \brief Experimental. Use at your own risk.
void CalculateShadowMap(Uint8** ppLightMap,int lightMapWidth,int lightMapHeight);
/// \brief Experimental. Use at your own risk.
void SetShadowMap(Texture* pTexture);
/// \brief Specifies whether or not to calculate and render with normals for this terrain.
void SetUseNormals(bool useNormals);
/// \brief Specifies whether or not Demeter should bind and render with any textures at all while rendering.
/// Specifies whether or not Demeter should bind and render with any textures at all while rendering. You might want to turn this off if you're using your own shaders to render the terrain or if you want the terrain to simply obey whatever texture state your application has already setup prior to rendering.
/// \param useTextures True to let Demeter set texture state, false to tell Demeter to leave texture state alone.
void SetUseTextures(bool useTextures);
/// \brief Installs a callback so your application can do custom processing when the terrain has finished tessellating.
/// Installs a callback so your application can do custom processing when the terrain has finished tessellating. This can be useful for such things as rendering water, when you want to set some per-vertex state after you know which vertices are visible.
/// \param pListener A pointer to an instance of your own class derived from TessellationListener.
void AddTessellationListener(TessellationListener* pListener);
/// \brief Uninstalls a callback that was previously installed by calling AddTessellationListener.
/// Uninstalls a callback that was previously installed by calling AddTessellationListener. Be sure to remove your listener before deleting it, so Demeter won't try to call a method on a deleted object.
/// \param pListener The listener to uninstall.
void RemoveTessellationListener(TessellationListener* pListener);
/// \brief Indicates whether this terrain supports raytracing.
bool UsesRaytracing();
/// \brief Sets boundaries in the x-y plane beyond which vertices are always considered to be insignificant during CLOD processing.
/// Sets boundaries in the x-y plane beyond which vertices are always considered to be insignificant during CLOD processing. This means that any vertices which fall outside of this area are always simplified, yielding flat triangles for those parts of the quadtree. This can be a useful optimization when doing things like water rendering or any time you know part of the terrain will never be visible to the user.
void SetClipExtents(float minX,float minY,float maxX,float maxY);
/// \brief Specifies whether or not the normals for all visible vertices should be recalculated after tessellation each frame.
/// Specifies whether or not the normals for all visible vertice should be recalculated after tessellation each frame. This can be useful when doing things water rendering or other effects where the terrain's vertices are animated. This will cause lighting to remain correct as the terrain surface moves and as the user's camera moves.
/// \param useVisible True to tell the terrain to recalculate normals based on visible vertices after tessellation, false to leave normals alone.
void SetCalculateVisibleNormals(bool useVisible);
/// \brief Sets the camera position so that the local shadow map texture is position properly for the current frame.
int UpdateLocalShadows(float camX,float camY,float camZ);
/// \brief Gets the size of the local shadow map in vertices.
int GetLocalShadowAreaWidthVertices();
/// \brief Sets the size of the local shadow map in vertices.
void SetLocalShadowAreaWidthVertices(int numVertices);
/// \brief Gets the base texture when using the experimental Shader option.
Texture* GetBaseTexture();
/// \brief Specifies the position of the camera on the world x-y plane for the current frame. This method should be called once per cycle before rendering, much like ModelViewMatrixChanged() is called once per cycle (typically).
void SetCameraPosition(float posX,float posY);
/// \brief The terrain's vertices as a raw array. If you modify these vertices then be sure to call RecalcGeometry afterward for the changes to be properly registered.
Vector *m_pVertices;
private:
void Init(float offX, float offY);
void Init(const Uint8 * pTextureImage, int textureWidth, int textureHeight, const Uint8 * pDetailTextureImage, int detailWidth, int detailHeight, float offsetX = 0.0f, float offsetY = 0.0f);
void UpdateNeighbor(Terrain * pTerrain, DIRECTION direction);
void GenerateTextureCoordinates();
void SetVertexStatus(int index, bool status);
bool GetVertexStatus(int index);
void BuildBlocks();
void ChopTexture(const Uint8 * pImage, int width, int height, int tileSize, bool isLightMap);
void ExtractFrustum();
void FlipTexturesForMapping();
void PreloadTextures();
void BuildVertices(int widthVertices, int heightVertices, float vertexSpacing);
void ReloadMaskImmediate(int textureCellX, int textureCellY, int detailIndex);
void UploadVertices();
int m_WidthVertices;
int m_HeightVertices;
float m_DetailThreshold;
float m_VertexSpacing;
TerrainBlock *m_pRootBlock;
int m_NumberOfVertices;
std::vector < TextureCell * >m_TextureCells;
float m_TextureTileWidth, m_TextureTileHeight;
unsigned int m_NumberOfTextureTilesWidth;
unsigned int m_NumberOfTextureTilesHeight;
int m_TileSize;
Uint8 **m_pTiles;
unsigned int m_NumberOfTextureTiles;
Texture *m_pCommonTexture;
float m_FogColorRed, m_FogColorGreen, m_FogColorBlue, m_FogColorAlpha;
int m_MaximumVisibleBlockSize;
float m_Frustum[6][4];
bool m_bMultiTextureSupported;
float m_MaxElevation;
float m_OffsetX, m_OffsetY;
int m_LatticePositionX, m_LatticePositionY;
TextureSet *m_pTextureSet;
float* m_pTextureMain;
float* m_pTextureDetail;
float* m_pShadowTexCoords;
//float* m_pVertexColors;
bool m_UseHeightfieldLighting;
Vector *m_pNormals;
mutable int m_refCount;
GLuint m_VertexBufferObject;
GLuint m_TextureBufferObject;
GLuint m_DetailTextureBufferObject;
GLuint m_NormalBufferObject;
GLuint m_ShadowTextureBufferObject;
bool m_UseVertexBufferObjects;
Uint32 m_NumberOfTerrainBlocks;
Shader* m_pShader;
GLint m_ShadowMapParam,m_AmbientParam,m_LightDirParam,m_BaseParam,m_MaskParam,m_Detail0Param,m_Detail1Param,m_Detail2Param;
Texture* m_pShadowMapTexture;
Texture* m_pBaseTexture;
Texture* m_pMaskTexture;
Texture* m_pDetail0Texture;
Texture* m_pDetail1Texture;
Texture* m_pDetail2Texture;
Vector m_LightDir;
float m_AmbientLevel;
Uint32 m_MinimumModifiedVertexIndex,m_MaximumModifiedVertexIndex;
bool m_UseNormals;
bool m_UseTextures;
bool m_UseRaytracing;
Demeter::Vector m_ClipMin,m_ClipMax;
Demeter::Vector m_CameraPosition;
bool m_CalculateVisibleNormals;
bool m_ControlsZBuffer;
bool m_CullFaces;
#ifdef _WIN32
std::vector < HGLRC > m_SharedContexts;
#endif
int m_BaseTextureWidth, m_BaseTextureHeight;
std::map < std::string, ReloadMaskRequest * >m_ReloadMaskRequests;
bool m_HasRendered;
bool* m_pVertexStatus;
bool m_NeedsTextureFlip;
double m_pMatModelview[16];
double m_pMatProjection[16];
GLint m_pViewport[4];
std::vector<TessellationListener*> m_TessellationListeners;
TrianglePair* m_pTrianglePairs;
friend class Triangle;
friend class TerrainBlock;
friend class TerrainLattice;
friend class TextureCell;
};
class ReloadMaskRequest
{
public:
ReloadMaskRequest(int textureCellX, int textureCellY, int detailIndex);
~ReloadMaskRequest();
int m_TextureCellX, m_TextureCellY, m_DetailIndex;
};
}
/// \mainpage The Demeter Terrain Engine
/// \section API Reference
/// This is a reference document for the classes and functions comprising Demeter. This document
/// is for detailed information at the code level. If you need more general information such as tutorials,
/// explanation of features, etc. then see the documentation and forums at http://www.terrainengine.com instead.
/// \section intro Using this Reference
/// \par
/// For overall browsing, try going to the Classes List. The Terrain class is the primary public interface to Demeter.
/// \par
/// To find docs on a specific class, go to the Class List and click the class.
#endif
See more files for this project here