/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2006 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main programmer: Marco Biasini */ #ifndef _TERRAIN_H #define _TERRAIN_H #define USE_VBO #ifdef USE_VBO #include "buffer_broker.h" #endif #include "types.h" #include "terrain_page.h" #include "terrain_quad.h" #include #include #include #include "texture.h" #include "frustum.h" class Terrain; typedef Terrain *pTerrain; struct Heightfield { int width; int height; int pitch; UByte *data; }; struct LayerInfo { int envmode; float repeatX, repeatZ; Texture *alpha; Texture *detail; }; struct BufferInfo { BufferInfo( unsigned int _vb, unsigned int _ib, unsigned int _numV, unsigned int _numI ) { vbIdentifier = _vb; ibIdentifier = _ib; numIndices = _numI; numVertices =_numV; } BufferInfo() { vbIdentifier = ibIdentifier = numIndices = numVertices = 0; } unsigned int vbIdentifier, ibIdentifier, numIndices, numVertices; }; class Terrain { public: const static int PAGE_SIZE = 17; const static int MAX_VERTICES = PAGE_SIZE*PAGE_SIZE; const static int MAX_INDICES = 2*( PAGE_SIZE*PAGE_SIZE + PAGE_SIZE -2 ); /** * The amount of geometry rendered is largely depending on this constant. So chose a * reasonable value... */ inline float getDetail() { return 0.02f; } inline bool debug() { return false; } inline pTerrainPage getActiveList() { return activePages; } inline void setCameraPosition( const Triple& _cameraPosition ) { cameraPosition = _cameraPosition; } inline const Triple& getCameraPosition() const { return cameraPosition; } void getAltitude( Triple& _alt, Triple& _normal ); inline void setLightmap( Texture *_lightmap ) { lightmap = _lightmap; } //What a bad name: Need to rename that :( void addLevelFourPage( int _numVertices, Vertex *_vertices, int _numIndices, unsigned short *_indices ); void showPages( int _x0, int _z0, int _width, int _height ); /** * Create a new terrain. */ Terrain( ) { pageSize = 17; scale = Triple( 1.0f, 3.0f, 1.0f ); frustum = new Frustum(); activatedCount = deactivatedCount = 0; vertices = new Vertex[MAX_VERTICES]; indices = new unsigned short[MAX_INDICES]; #ifdef USE_VBO broker = new BufferBroker( 200, MAX_VERTICES*sizeof( Vertex ), MAX_INDICES*sizeof( short ) ); #endif } /** * Draws the terrain. */ void draw( ); void setPageSize( const Triple& _page ) { } void build(); inline void setActiveList( pTerrainPage _page ) { activePages = _page; } inline pFrustum getViewingFrustum() { return frustum; } /** * Returns the normalized ( range from [0..1] ) altitude from the heightmap for the given * coordinates. */ inline void incActivated() { activatedCount++; } inline void incDeactivated() { deactivatedCount++; } inline float getAltitude( int _x, int _z ) const; inline void addMaterialLayer( LayerInfo *_layer ) { layers.push_back( _layer ); } inline void setHeightmap( const std::string &_heightmap ) { heightmapSource = _heightmap; } inline void setPageSize( int _pageSize ) { pageSize = _pageSize; } inline const Triple getScale() const { return scale; } inline int getPageSize() const { return pageSize; } inline void getCoord( int _x, int _z, TexCoord& _coord) const { _coord.u = ( ( float )_x )/( heightfield.width-1 ); _coord.v = ( ( float )_z )/( heightfield.height-1 ); } inline void setScale( const Triple& _scale ) { scale = _scale; } #ifdef USE_VBO inline pBufferBroker getBufferBroker() { return broker; } #endif inline TerrainPage *getPage( int _x, int _z ) { return pages[pagesX*_z+_x]; } protected: /** * convenience method to create a new terrain page at position offset * p = ( _xOffset, _zOffset ). */ pTerrainPage createPage( int _xOffset, int _zOffset ) const; /** * Creates the quad tree structure for fast culling of the terrain pages. */ pTerrainQuad createQuadTree( int _x0, int _z0, int _x1, int _z1, int _depth = 0 ); /** * Walks the quad tree to determine which pages are visible, e.g. are in the viewing * frustum of the camera. */ void determineVisiblePages( pTerrainQuad _node ); #ifdef USE_VBO pBufferBroker broker; #endif pTerrainQuad root; // The quad-tree root node. pTerrainPage *pages; // the references to all pages std::string heightmapSource; Texture *lightmap; Heightfield heightfield; Triple scale; int pagesX, pagesZ; int pageSize; int cullCount; int activatedCount, deactivatedCount; // For debugging and statistics //The next five members are for the level 4 pages. Vertex *vertices; unsigned short *indices; int current; std::vector buffers; Triple cameraPosition; pFrustum frustum; pTerrainPage activePages; std::vector layers; }; inline float Terrain::getAltitude( int _x, int _z ) const { return heightfield.data[heightfield.pitch*_z+_x]/255.0f; } #endif