/* 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 "vector.h" #include "terrain_page.h" #include "terrain_quad.h" #include #include #include #include "texture.h" #include "frustum.h" class Texture; class Terrain; typedef Terrain *pTerrain; class Terrain { public: const static unsigned int PAGE_SIZE = 17; const static unsigned int MAX_VERTICES = PAGE_SIZE*PAGE_SIZE; const static unsigned 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 Vector& _cameraPosition ) { cameraPosition = _cameraPosition; } inline const Vector& getCameraPosition() const { return cameraPosition; } void getAltitude( Vector& _alt, Vector& _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; pagesX = pagesZ = 0; lightmap = NULL; heightmapSource = ""; root = NULL; current = 0; activePages = NULL; scale = Vector( 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( 300, MAX_VERTICES*sizeof( Vertex ), MAX_INDICES*sizeof( short ) ); #endif } ~Terrain( ) { //The pages are deleted through the SAVE_DELETE( root ) call. SAVE_DELETE_ARRAY( pages ); SAVE_DELETE_ARRAY( vertices ); SAVE_DELETE_ARRAY( indices ); SAVE_DELETE( lightmap ); SAVE_DELETE( root ); #ifdef USE_VBO SAVE_DELETE( broker ); #endif } /** * Draws the terrain. */ void draw( ); void setPageSize( const Vector& _page ) { } void build(); void tick( float _dt ); 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 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 Vector 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 Vector& _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 ); void determineLayerVisibility( int _layer ); #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; Vector 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; Vector cameraPosition; pFrustum frustum; pTerrainPage activePages; std::vector layers; }; inline float Terrain::getAltitude( int _x, int _z ) const { assert( heightfield.data ); if ( _x < 0 || _x >= heightfield.width || _z < 0 || _z >= heightfield.height ) { return 0.0f; printf( "outside!\n" ); } return heightfield.data[heightfield.pitch*_z+_x]/255.0f; } #endif