From e4ae88ef1532840499c84b2c64e8ddb62657a177 Mon Sep 17 00:00:00 2001 From: tangziwen Date: Fri, 3 Apr 2015 09:11:09 +0800 Subject: [PATCH 1/3] add new line at end of file --- cocos/renderer/ccShader_3D_Terrain.vert | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos/renderer/ccShader_3D_Terrain.vert b/cocos/renderer/ccShader_3D_Terrain.vert index 19a366b67c..396cc117fb 100644 --- a/cocos/renderer/ccShader_3D_Terrain.vert +++ b/cocos/renderer/ccShader_3D_Terrain.vert @@ -16,4 +16,4 @@ void main() v_texCoord = a_texCoord; v_normal = a_normal; } -); \ No newline at end of file +); From 8a7b318c1ad102f54a0e9d52d8a4ce0ba348b30b Mon Sep 17 00:00:00 2001 From: tangziwen Date: Fri, 3 Apr 2015 13:49:07 +0800 Subject: [PATCH 2/3] Add some helper function to detect the heightMap size,refact Terrain::Create, fix typo ,add doxygen comment --- cocos/3d/CCTerrain.cpp | 374 ++++++++++-------- cocos/3d/CCTerrain.h | 221 +++++++---- .../Classes/TerrainTest/TerrainTest.h | 6 +- 3 files changed, 373 insertions(+), 228 deletions(-) diff --git a/cocos/3d/CCTerrain.cpp b/cocos/3d/CCTerrain.cpp index 4a109ed485..732cf8bcf8 100644 --- a/cocos/3d/CCTerrain.cpp +++ b/cocos/3d/CCTerrain.cpp @@ -1,6 +1,32 @@ +/**************************************************************************** +Copyright (c) 2015 Chukong Technologies Inc. + +http://www.cocos2d-x.org + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +****************************************************************************/ + #include "CCTerrain.h" -#include + USING_NS_CC; +#include +#include #include "renderer/CCGLProgram.h" #include "renderer/CCGLProgramCache.h" #include "renderer/CCGLProgramState.h" @@ -9,77 +35,45 @@ USING_NS_CC; #include "renderer/ccGLStateCache.h" #include "base/CCDirector.h" #include "2d/CCCamera.h" -#include + NS_CC_BEGIN + +// check a number is power of two. +static bool isPOT(int number) +{ + bool flag = false; + if((number>0)&&(number&(number-1))==0) + flag = true; + return flag; +} + Terrain * Terrain::create(TerrainData ¶meter, CrackFixedType fixedType) { Terrain * terrain = new (std::nothrow)Terrain(); - terrain->setSkirtHeightRatio(1.0f); + terrain->setSkirtHeightRatio(parameter.skirtHeightRatio); terrain->_terrainData = parameter; terrain->_crackFixedType = fixedType; terrain->_isCameraViewChanged = true; //chunksize terrain->_chunkSize = parameter.chunkSize; - //heightmap - terrain->initHeightMap(parameter.heightMapSrc.c_str()); - Texture2D::TexParams texParam; - texParam.wrapS = GL_REPEAT; - texParam.wrapT = GL_REPEAT; - if(!parameter.alphaMapSrc) - { - auto textImage = new (std::nothrow)Image(); - textImage->initWithImageFile(parameter.detailMaps[0].detailMapSrc); - auto texture = new (std::nothrow)Texture2D(); - texture->initWithImage(textImage); - texture->generateMipmap(); - terrain->_detailMapTextures[0] = texture; - texParam.minFilter = GL_LINEAR_MIPMAP_LINEAR; - texParam.magFilter = GL_LINEAR; - texture->setTexParameters(texParam); - delete textImage; - }else - { - //alpha map - auto image = new (std::nothrow)Image(); - image->initWithImageFile(parameter.alphaMapSrc); - terrain->_alphaMap = new (std::nothrow)Texture2D(); - terrain->_alphaMap->initWithImage(image); - texParam.wrapS = GL_CLAMP_TO_EDGE; - texParam.wrapT = GL_CLAMP_TO_EDGE; - texParam.minFilter = GL_LINEAR; - texParam.magFilter = GL_LINEAR; - terrain->_alphaMap->setTexParameters(texParam); - delete image; + bool initResult =true; - for(int i =0;i<4;i++) - { - auto textImage = new (std::nothrow)Image(); - textImage->initWithImageFile(parameter.detailMaps[i].detailMapSrc); - auto texture = new (std::nothrow)Texture2D(); - texture->initWithImage(textImage); - delete textImage; - texture->generateMipmap(); - terrain->_detailMapTextures[i] = texture; - - texParam.wrapS = GL_REPEAT; - texParam.wrapT = GL_REPEAT; - texParam.minFilter = GL_LINEAR_MIPMAP_LINEAR; - texParam.magFilter = GL_LINEAR; - texture->setTexParameters(texParam); - } - } - terrain->init(); - terrain->setAnchorPoint(Vec2(0,0)); + //init heightmap + initResult &= terrain->initHeightMap(parameter.heightMapSrc.c_str()); + //init textures alpha map,detail Maps + initResult &= terrain->initTextures(); + initResult &= terrain->initProperties(); terrain->autorelease(); + if(!initResult) + { + CC_SAFE_DELETE(terrain); + } return terrain; } -bool Terrain::init() +bool Terrain::initProperties() { - _lodDistance[0]=64; - _lodDistance[1]=128; - _lodDistance[2]=196; auto shader = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_3D_TERRAIN); auto state = GLProgramState::create(shader); @@ -87,13 +81,7 @@ bool Terrain::init() _normalLocation = glGetAttribLocation(this->getGLProgram()->getProgram(),"a_normal"); setDrawWire(false); setIsEnableFrustumCull(true); - - _alphaMapLocation = -1; - for(int i =0;i<4;i++) - { - _detailMapLocation[i] = -1; - _detailMapSizeLocation[i] = -1; - } + setAnchorPoint(Vec2(0,0)); return true; } @@ -186,42 +174,53 @@ void Terrain::onDraw(const Mat4 &transform, uint32_t flags) } } -void Terrain::initHeightMap(const char * heightMap) +bool Terrain::initHeightMap(const char * heightMap) { _heightMapImage = new Image(); _heightMapImage->initWithImageFile(heightMap); _data = _heightMapImage->getData(); _imageWidth =_heightMapImage->getWidth(); _imageHeight =_heightMapImage->getHeight(); - int chunk_amount_y = _imageHeight/_chunkSize.height; - int chunk_amount_x = _imageWidth/_chunkSize.width; - loadVertices(); - calculateNormal(); - memset(_chunkesArray, 0, sizeof(_chunkesArray)); - for(int m =0;m_terrain = this; - _chunkesArray[m][n]->_size = _chunkSize; - _chunkesArray[m][n]->generate(_imageWidth,_imageHeight,m,n,_data); - } - } + int chunk_amount_y = _imageHeight/_chunkSize.height; + int chunk_amount_x = _imageWidth/_chunkSize.width; + loadVertices(); + calculateNormal(); + memset(_chunkesArray, 0, sizeof(_chunkesArray)); - //calculate the neighbor - for(int m =0;m=0) _chunkesArray[m][n]->left = _chunkesArray[m][n-1]; - if(n+1right = _chunkesArray[m][n+1]; - if(m-1>=0) _chunkesArray[m][n]->back = _chunkesArray[m-1][n]; - if(m+1front = _chunkesArray[m+1][n]; + for(int n =0; n_terrain = this; + _chunkesArray[m][n]->_size = _chunkSize; + _chunkesArray[m][n]->generate(_imageWidth,_imageHeight,m,n,_data); + } } + + //calculate the neighbor + for(int m =0;m=0) _chunkesArray[m][n]->_left = _chunkesArray[m][n-1]; + if(n+1_right = _chunkesArray[m][n+1]; + if(m-1>=0) _chunkesArray[m][n]->_back = _chunkesArray[m-1][n]; + if(m+1_front = _chunkesArray[m+1][n]; + } + } + _quadRoot = new QuadTree(0,0,_imageWidth,_imageHeight,this); + setLODDistance(_chunkSize.width,2*_chunkSize.width,3*_chunkSize.width); + return true; + }else + { + CCLOG("warning: the height map size is not POT or POT + 1"); + return false; } - _quadRoot = new QuadTree(0,0,_imageWidth,_imageHeight,this); } Terrain::Terrain() @@ -672,6 +671,12 @@ void Terrain::onEnter() void Terrain::cacheUniformLocation() { + _alphaMapLocation = -1; + for(int i =0;i<4;i++) + { + _detailMapLocation[i] = -1; + _detailMapSizeLocation[i] = -1; + } auto glProgram = getGLProgram(); _alphaIsHasAlphaMapLocation = glGetUniformLocation(glProgram->getProgram(),"u_has_alpha"); if(!_alphaMap) @@ -693,6 +698,58 @@ void Terrain::cacheUniformLocation() } } +bool Terrain::initTextures() +{ + Texture2D::TexParams texParam; + texParam.wrapS = GL_REPEAT; + texParam.wrapT = GL_REPEAT; + if(!_terrainData.alphaMapSrc) + { + auto textImage = new (std::nothrow)Image(); + textImage->initWithImageFile(_terrainData.detailMaps[0].detailMapSrc); + auto texture = new (std::nothrow)Texture2D(); + texture->initWithImage(textImage); + texture->generateMipmap(); + _detailMapTextures[0] = texture; + texParam.minFilter = GL_LINEAR_MIPMAP_LINEAR; + texParam.magFilter = GL_LINEAR; + texture->setTexParameters(texParam); + delete textImage; + }else + { + //alpha map + auto image = new (std::nothrow)Image(); + image->initWithImageFile(_terrainData.alphaMapSrc); + _alphaMap = new (std::nothrow)Texture2D(); + _alphaMap->initWithImage(image); + texParam.wrapS = GL_CLAMP_TO_EDGE; + texParam.wrapT = GL_CLAMP_TO_EDGE; + texParam.minFilter = GL_LINEAR; + texParam.magFilter = GL_LINEAR; + _alphaMap->setTexParameters(texParam); + delete image; + + for(int i =0;i<_terrainData._detailMapAmount;i++) + { + auto textImage = new (std::nothrow)Image(); + textImage->initWithImageFile(_terrainData.detailMaps[i].detailMapSrc); + auto texture = new (std::nothrow)Texture2D(); + texture->initWithImage(textImage); + delete textImage; + texture->generateMipmap(); + _detailMapTextures[i] = texture; + + texParam.wrapS = GL_REPEAT; + texParam.wrapT = GL_REPEAT; + texParam.minFilter = GL_LINEAR_MIPMAP_LINEAR; + texParam.magFilter = GL_LINEAR; + texture->setTexParameters(texParam); + } + } + setMaxDetailMapAmount(_terrainData._detailMapAmount); + return true; +} + void Terrain::Chunk::finish() { //genearate two VBO ,the first for vertices, we just setup datas once ,won't changed at all @@ -846,10 +903,10 @@ void Terrain::Chunk::generate(int imgWidth, int imageHei, int m, int n, const un Terrain::Chunk::Chunk() { _currentLod = 0; - left = nullptr; - right = nullptr; - back = nullptr; - front = nullptr; + _left = nullptr; + _right = nullptr; + _back = nullptr; + _front = nullptr; _oldLod = -1; for(int i =0;i<4;i++) { @@ -860,21 +917,21 @@ Terrain::Chunk::Chunk() void Terrain::Chunk::updateIndicesLOD() { int currentNeighborLOD[4]; - if(left) + if(_left) { - currentNeighborLOD[0] = left->_currentLod; + currentNeighborLOD[0] = _left->_currentLod; }else{currentNeighborLOD[0] = -1;} - if(right) + if(_right) { - currentNeighborLOD[1] = right->_currentLod; + currentNeighborLOD[1] = _right->_currentLod; }else{currentNeighborLOD[1] = -1;} - if(back) + if(_back) { - currentNeighborLOD[2] = back->_currentLod; + currentNeighborLOD[2] = _back->_currentLod; }else{currentNeighborLOD[2] = -1;} - if(front) + if(_front) { - currentNeighborLOD[3] = front->_currentLod; + currentNeighborLOD[3] = _front->_currentLod; }else{currentNeighborLOD[3] = -1;} if(_oldLod == _currentLod &&(memcmp(currentNeighborLOD,_neighborOldLOD,sizeof(currentNeighborLOD))==0) ) @@ -893,8 +950,8 @@ void Terrain::Chunk::updateIndicesLOD() int gridX = _size.width; int step = int(powf(2.0f, float(_currentLod))); - if((left&&left->_currentLod > _currentLod) ||(right&&right->_currentLod > _currentLod) - ||(back&&back->_currentLod > _currentLod) || (front && front->_currentLod > _currentLod)) + if((_left&&_left->_currentLod > _currentLod) ||(_right&&_right->_currentLod > _currentLod) + ||(_back&&_back->_currentLod > _currentLod) || (_front && _front->_currentLod > _currentLod)) //need update indices. { //t-junction inner @@ -915,7 +972,7 @@ void Terrain::Chunk::updateIndicesLOD() } //fix T-crack int next_step = int(powf(2.0f, float(_currentLod+1))); - if(left&&left->_currentLod > _currentLod)//left + if(_left&&_left->_currentLod > _currentLod)//left { for(int i =0;i_currentLod > _currentLod) end -=step; - if(back&&back->_currentLod > _currentLod) start +=step; + if(_front&&_front->_currentLod > _currentLod) end -=step; + if(_back&&_back->_currentLod > _currentLod) start +=step; for(int i =start;i_currentLod > _currentLod)//LEFT + if(_right&&_right->_currentLod > _currentLod)//LEFT { for(int i =0;i_currentLod > _currentLod) end -=step; - if(back&&back->_currentLod > _currentLod) start +=step; + if(_front&&_front->_currentLod > _currentLod) end -=step; + if(_back&&_back->_currentLod > _currentLod) start +=step; for(int i =start;i_currentLod > _currentLod)//front + if(_front&&_front->_currentLod > _currentLod)//front { for(int i =0;i_currentLod > _currentLod)//back + if(_back&&_back->_currentLod > _currentLod)//back { for(int i =0;i=2 && abs(slope)>1.2) + if(_currentLod>=2 && abs(_slope)>1.2) { int step = int(powf(2.0f, float(_currentLod))); for(int i =step;iheight = h; - this->width = w; - if(width> terrain->_chunkSize.width &&height >terrain->_chunkSize.height) //subdivision + _parent = nullptr; + _tl =nullptr; + _tr =nullptr; + _bl =nullptr; + _br =nullptr; + _posX = x; + _posY = y; + this->_height = h; + this->_width = w; + if(_width> terrain->_chunkSize.width &&_height >terrain->_chunkSize.height) //subdivision { _isTerminal = false; - this->tl = new QuadTree(x,y,width/2,height/2,terrain); - this->tl->parent = this; - this->tr = new QuadTree(x+width/2,y,width/2,height/2,terrain); - this->tr->parent = this; - this->bl = new QuadTree(x,y+height/2,width/2,height/2,terrain); - this->bl->parent = this; - this->br = new QuadTree(x+width/2,y+height/2,width/2,height/2,terrain); - this->br->parent = this; + this->_tl = new QuadTree(x,y,_width/2,_height/2,terrain); + this->_tl->_parent = this; + this->_tr = new QuadTree(x+_width/2,y,_width/2,_height/2,terrain); + this->_tr->_parent = this; + this->_bl = new QuadTree(x,y+_height/2,_width/2,_height/2,terrain); + this->_bl->_parent = this; + this->_br = new QuadTree(x+_width/2,y+_height/2,_width/2,_height/2,terrain); + this->_br->_parent = this; - _aabb.merge(tl->_aabb); - _aabb.merge(tr->_aabb); - _aabb.merge(bl->_aabb); - _aabb.merge(br->_aabb); + _aabb.merge(_tl->_aabb); + _aabb.merge(_tr->_aabb); + _aabb.merge(_bl->_aabb); + _aabb.merge(_br->_aabb); }else // is terminal Node { - int m = pos_y/terrain->_chunkSize.height; - int n = pos_x/terrain->_chunkSize.width; + int m = _posY/terrain->_chunkSize.height; + int n = _posX/terrain->_chunkSize.width; _chunk = terrain->_chunkesArray[m][n]; _isTerminal = true; _aabb = _chunk->_aabb; @@ -1267,10 +1324,10 @@ void Terrain::QuadTree::draw() this->_chunk->bindAndDraw(); }else { - this->tl->draw(); - this->tr->draw(); - this->br->draw(); - this->bl->draw(); + this->_tl->draw(); + this->_tr->draw(); + this->_br->draw(); + this->_bl->draw(); } } @@ -1279,10 +1336,10 @@ void Terrain::QuadTree::resetNeedDraw(bool value) this->_needDraw = value; if(!_isTerminal) { - tl->resetNeedDraw(value); - tr->resetNeedDraw(value); - bl->resetNeedDraw(value); - br->resetNeedDraw(value); + _tl->resetNeedDraw(value); + _tr->resetNeedDraw(value); + _bl->resetNeedDraw(value); + _br->resetNeedDraw(value); } } @@ -1294,10 +1351,10 @@ void Terrain::QuadTree::cullByCamera(const Camera * camera, const Mat4 & worldTr }else { if(!_isTerminal){ - tl->cullByCamera(camera,worldTransform); - tr->cullByCamera(camera,worldTransform); - bl->cullByCamera(camera,worldTransform); - br->cullByCamera(camera,worldTransform); + _tl->cullByCamera(camera,worldTransform); + _tr->cullByCamera(camera,worldTransform); + _bl->cullByCamera(camera,worldTransform); + _br->cullByCamera(camera,worldTransform); } } } @@ -1305,22 +1362,22 @@ void Terrain::QuadTree::cullByCamera(const Camera * camera, const Mat4 & worldTr void Terrain::QuadTree::preCalculateAABB(const Mat4 & worldTransform) { - _worldSpaceAABB = _aabb; - _worldSpaceAABB.transform(worldTransform); + _worldSpaceAABB = _aabb; + _worldSpaceAABB.transform(worldTransform); if(!_isTerminal){ - tl->preCalculateAABB(worldTransform); - tr->preCalculateAABB(worldTransform); - bl->preCalculateAABB(worldTransform); - br->preCalculateAABB(worldTransform); + _tl->preCalculateAABB(worldTransform); + _tr->preCalculateAABB(worldTransform); + _bl->preCalculateAABB(worldTransform); + _br->preCalculateAABB(worldTransform); } } Terrain::QuadTree::~QuadTree() { - if(tl) delete tl; - if(tr) delete tr; - if(bl) delete bl; - if(br) delete br; + if(_tl) delete _tl; + if(_tr) delete _tr; + if(_bl) delete _bl; + if(_br) delete _br; } Terrain::TerrainData::TerrainData(const char * heightMapsrc , const char * textureSrc, const Size & chunksize, float height, float scale) @@ -1331,6 +1388,7 @@ Terrain::TerrainData::TerrainData(const char * heightMapsrc , const char * textu this->chunkSize = chunksize; this->mapHeight = height; this->mapScale = scale; + skirtHeightRatio = 1; } Terrain::TerrainData::TerrainData(const char * heightMapsrc, const char * alphamap, const DetailMap& detail1, const DetailMap& detail2, const DetailMap& detail3, const DetailMap& detail4, const Size & chunksize, float height, float scale) @@ -1345,6 +1403,7 @@ Terrain::TerrainData::TerrainData(const char * heightMapsrc, const char * alpham this->mapHeight = height; this->mapScale = scale; _detailMapAmount = 4; + skirtHeightRatio = 1; } Terrain::TerrainData::TerrainData(const char* heightMapsrc, const char * alphamap, const DetailMap& detail1, const DetailMap& detail2, const DetailMap& detail3, const Size & chunksize /*= Size(32,32)*/, float height /*= 2*/, float scale /*= 0.1*/) @@ -1359,6 +1418,7 @@ Terrain::TerrainData::TerrainData(const char* heightMapsrc, const char * alphama this->mapHeight = height; this->mapScale = scale; _detailMapAmount = 3; + skirtHeightRatio = 1; } Terrain::TerrainData::TerrainData() diff --git a/cocos/3d/CCTerrain.h b/cocos/3d/CCTerrain.h index 016f275dd9..aacd6c761d 100644 --- a/cocos/3d/CCTerrain.h +++ b/cocos/3d/CCTerrain.h @@ -39,12 +39,12 @@ NS_CC_BEGIN * @{ */ - /* - * the maximum amount of the chunkes - **/ + /** + * the maximum amount of the chunkes + **/ #define MAX_CHUNKES 256 - /* + /** * Terrain * Defines a Terrain that is capable of rendering large landscapes from 2D heightmap images. * Terrains can be constructed from several different internal formats heightmap sources: @@ -84,12 +84,13 @@ class CC_DLL Terrain :public Node { public: + /**the crack fix type. use to fix the gaps between different LOD chunks */ enum class CrackFixedType{ SKIRT, INCREASE_LOWER, }; - /* + /** *DetailMap *this struct maintain a detail map data ,including source file ,detail size. *the DetailMap can use for terrain splatting @@ -104,32 +105,38 @@ public: float detailMapSize; }; - /* + /** *TerrainData *This TerrainData struct warp all parameter that Terrain need to create */ struct CC_DLL TerrainData { - /*Constructors*/ + /**empty constructor*/ TerrainData(); + /**constructor, this constructor construct a simple terrain which only have 1 detailmap*/ TerrainData(const char* heightMapsrc, const char * textureSrc, const Size & chunksize = Size(32,32), float mapHeight = 2, float mapScale = 0.1); + /**constructor, this constructor construct a terrain which have 4 detailmaps, 1 alpha map*/ TerrainData(const char* heightMapsrc, const char * alphamap, const DetailMap& detail1,const DetailMap& detail2, const DetailMap& detail3, const DetailMap& detail4, const Size & chunksize = Size(32,32), float mapHeight = 2, float mapScale = 0.1); + /**constructor, this constructor construct a terrain which have 3 detailmaps, 1 alpha map*/ TerrainData(const char* heightMapsrc, const char * alphamap, const DetailMap& detail1,const DetailMap& detail2, const DetailMap& detail3, const Size & chunksize = Size(32,32), float mapHeight = 2, float mapScale = 0.1); - /* + /** *deterimine the chunk size,chunk is the minimal subdivision of the Terrain */ Size chunkSize; - /*height Map source path*/ + /**height Map source path*/ std::string heightMapSrc; - /*the source path of the alpha map*/ + /**the source path of the alpha map*/ char* alphaMapSrc; - /*detail maps*/ + /**detail maps*/ DetailMap detailMaps[4]; - /*terrain Maximum height*/ + /**terrain Maximum height*/ float mapHeight; - /*terrain scale factor*/ + /**terrain scale factor,you can combine setScale later.*/ float mapScale; + /**the amount of detailmap*/ int _detailMapAmount; + /**the skirt height ratio, only effect when terrain use skirt to fix crack*/ + float skirtHeightRatio; }; private: @@ -175,8 +182,9 @@ private: **/ struct Chunk { - /*Constructor*/ + /**Constructor*/ Chunk(); + /**destructor*/ ~Chunk(); /*vertices*/ std::vector vertices; @@ -186,100 +194,139 @@ private: }; GLuint vbo[2]; ChunkIndices _chunkIndices; - /*we now have four levels of detail*/ + /**we now support four levels of detail*/ LOD _lod[4]; - /*AABB in local space*/ + /**AABB in local space*/ AABB _aabb; - /*setup Chunk data*/ + /**setup Chunk data*/ void generate(int map_width, int map_height, int m, int n, const unsigned char * data); - /*calculateAABB*/ + /**calculateAABB*/ void calculateAABB(); - /*internal use draw function*/ + /**internal use draw function*/ void bindAndDraw(); - /*finish opengl setup*/ + /**finish opengl setup*/ void finish(); /*use linear-sample vertices for LOD mesh*/ void updateVerticesForLOD(); - /*updateIndices for every frame*/ + /*updateIndices */ void updateIndicesLOD(); void updateIndicesLODSkirt(); + /**calculate the average slop of chunk*/ void calculateSlope(); - /*current LOD of the chunk*/ + /**current LOD of the chunk*/ int _currentLod; int _oldLod; int _neighborOldLOD[4]; /*the left,right,front,back neighbors*/ - Chunk * left; - Chunk * right; - Chunk * front; - Chunk * back; + Chunk * _left; + Chunk * _right; + Chunk * _front; + Chunk * _back; QuadTree * _parent; - //the position + /**the position X in terrain space*/ int pos_x; + /**the position Y in terrain space*/ int pos_y; - /*parent terrain*/ + /**parent terrain*/ Terrain * _terrain; - /*chunk size*/ + /**chunk size*/ Size _size; - /*chunk's estimated slope*/ - float slope; + /**chunk's estimated slope*/ + float _slope; std::vector vertices_tmp; }; - /* + /** *QuadTree - *use to frustum culling and set LOD + * @breif use to hierarchically frustum culling and set LOD **/ struct QuadTree { + /**constructor*/ QuadTree(int x, int y, int width, int height, Terrain * terrain); + /**destructor*/ ~QuadTree(); + /**recursively draw*/ void draw(); + /**recursively set itself and its children is need to draw*/ void resetNeedDraw(bool value); + /**recursively potential visible culling*/ void cullByCamera(const Camera * camera, const Mat4 & worldTransform); + /**precalculate the AABB(In world space) of each quad*/ void preCalculateAABB(const Mat4 & worldTransform); - QuadTree * tl; - QuadTree * tr; - QuadTree * bl; - QuadTree * br; + QuadTree * _tl; + QuadTree * _tr; + QuadTree * _bl; + QuadTree * _br; + /**A flag present current quadTree node whether a terminal node,the terminal node is de facto the chunck*/ bool _isTerminal; Chunk * _chunk; - int pos_x; - int pos_y; - int height; - int width; - QuadTree * parent; + int _posX; + int _posY; + int _height; + int _width; + QuadTree * _parent; AABB _aabb; + /**AABB's cache (in world space)*/ AABB _worldSpaceAABB; Terrain * _terrain; + /** a flag determine whether a quadTree node need draw*/ bool _needDraw; }; friend QuadTree; friend Chunk; public: /*init function*/ - bool init(); - void initHeightMap(const char* heightMap); - /*create entry*/ + /**initialize all Properties which terrain need */ + bool initProperties(); + /**initialize heightMap data */ + bool initHeightMap(const char* heightMap); + /**initialize alphaMap ,detailMaps textures*/ + bool initTextures(); + /**create entry*/ static Terrain * create(TerrainData ¶meter, CrackFixedType fixedType = CrackFixedType::INCREASE_LOWER); - /*get specified position's height mapping to the terrain*/ + /**get specified position's height mapping to the terrain,use bi-linear interpolation method + * @param x the X position + * @param y the Z position + * @param normal the specified position's normal vector in terrain . if this argument is NULL or nullptr,Normal calculation shall be skip. + * @return the height value of the specified position of the terrain, if the (X,Z) position is out of the terrain bounds,it shall return 0; + **/ float getHeight(float x, float z, Vec3 * normal= nullptr); + + /**get specified position's height mapping to the terrain,use bi-linear interpolation method + * @param pos the position (X,Z) + * @param normal the specified position's normal vector in terrain . if this argument is NULL or nullptr,Normal calculation shall be skip. + * @return the height value of the specified position of the terrain, if the (X,Z) position is out of the terrain bounds,it shall return 0; + **/ float getHeight(Vec2 pos, Vec3*Normal = nullptr); - Vec3 getNormal(int pixel_x, int pixel_y); - /*get height from the raw height map*/ - float getImageHeight(int pixel_x, int pixel_y); - /*Debug Use only, show the wireline instead of the surface. only support desktop platform*/ - void setDrawWire(bool bool_value); - /*Set threshold distance of each LOD level,must equal or gereater than the chunk size*/ - void setLODDistance(float lod_1, float lod_2, float lod_3); - /*Switch frustumCulling Flag*/ - void setIsEnableFrustumCull(bool bool_value); + + /**get the normal of the specified pistion in terrain + * @return the normal vector of the specified position of the terrain. + * @note the fast normal calculation may not get precise normal vector. + **/ + Vec3 getNormal(int pixelX, int pixelY); + /**get height from the raw height filed*/ + float getImageHeight(int pixelX, int pixelY); + /**show the wireline instead of the surface,Debug Use only. + * @Note only support desktop platform + **/ + void setDrawWire(bool boolValue); + /** + * Set threshold distance of each LOD level,must equal or gereater than the chunk size + * @Note when invoke initHeightMap, the LOD distance will be automatic calculated. + */ + void setLODDistance(float lod1, float lod2, float lod3); + + /**Switch frustum Culling Flag + * @Note frustum culling will remarkable improve your terrain rendering performance. + */ + void setIsEnableFrustumCull(bool boolValue); /** set the alpha map*/ void setAlphaMap(cocos2d::Texture2D * newAlphaMapTexture); @@ -288,51 +335,89 @@ public: // Overrides, internal use only virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4 &transform, uint32_t flags) override; - //Ray-Terrain intersection. + /** + * Ray-Terrain intersection. + * @return the intersection point + */ Vec3 getIntersectionPoint(const Ray & ray); - void setMaxDetailMapAmount(int max_value); - //conver to Terrain space. + /** + * set the MaxDetailAmount. + */ + void setMaxDetailMapAmount(int maxValue); + + /** + * Convert a world Space position (X,Z) to terrain space position (X,Z) + */ Vec2 convertToTerrainSpace(Vec2 worldSpace); - //reset the heightmap data + /** + * reset the heightmap data. + */ void resetHeightMap(const char * heightMap); - // get the terrain's mininal height. + /** + * get the terrain's mininal height. + */ float getMinHeight(); - // get the terrain's maximum height. + /** + * get the terrain's maximum height. + */ float getMaxHeight(); - //get terrain's AABB + /** + * get the terrain's AABB(in world space) + */ AABB getAABB(); - //get the terrain's quad tree which is also the root node + /** + * set the skirt height ratio + */ + void setSkirtHeightRatio(float ratio); + + /** + * get the terrain's quad tree which is also the root node. + */ QuadTree * getQuadTree(); + //following methods are internal use only ChunkIndices lookForIndicesLODSkrit(int selfLod, bool * result); + ChunkIndices lookForIndicesLOD(int neighborLod[4], int selfLod, bool * result); ChunkIndices insertIndicesLOD(int neighborLod[4], int selfLod, GLushort * indices, int size); ChunkIndices insertIndicesLODSkirt(int selfLod, GLushort * indices, int size); - void setSkirtHeightRatio(float ratio); - protected: Terrain(); virtual ~Terrain(); void onDraw(const Mat4 &transform, uint32_t flags); - //set each chunk's LOD + + /** + * recursively set each chunk's LOD + * @param cameraPos the camera postion in world space + **/ void setChunksLOD(Vec3 cameraPos); - //load vertices for whole height map + + /** + * load Vertices from height filed for the whole terrain. + **/ void loadVertices(); - //calculate Normal Line for each Vertex + + /** + * calculate Normal Line for each Vertex + **/ void calculateNormal(); + //override virtual void onEnter() override; + /** + * cache all unifrom loactions in GLSL. + **/ void cacheUniformLocation(); protected: std::vector _chunkLodIndicesSet; diff --git a/tests/cpp-tests/Classes/TerrainTest/TerrainTest.h b/tests/cpp-tests/Classes/TerrainTest/TerrainTest.h index 09cb06a243..994d3625e8 100644 --- a/tests/cpp-tests/Classes/TerrainTest/TerrainTest.h +++ b/tests/cpp-tests/Classes/TerrainTest/TerrainTest.h @@ -65,9 +65,9 @@ public: float _headingAngle; Vec3 _headingAxis; private: -Terrain * _terrain; -Camera * _cam; -int _playerState; + Terrain * _terrain; + Camera * _cam; + int _playerState; }; From ee41c9b3f14cf74315fc4b311ebbe0ae4f0a7ae0 Mon Sep 17 00:00:00 2001 From: tangziwen Date: Fri, 3 Apr 2015 14:36:29 +0800 Subject: [PATCH 3/3] add win rt support --- .../libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems | 2 ++ .../libcocos2d_8_1.Shared.vcxitems.filters | 8 +++++++- .../cpp-tests.Shared/cpp-tests.Shared.vcxitems | 2 ++ .../cpp-tests.Shared/cpp-tests.Shared.vcxitems.filters | 9 +++++++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems index 339ff0ab88..24f873310a 100644 --- a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems +++ b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems @@ -222,6 +222,7 @@ + @@ -807,6 +808,7 @@ + NotUsing diff --git a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters index be937fc075..7020b4128d 100644 --- a/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters +++ b/cocos/2d/libcocos2d_8_1/libcocos2d_8_1/libcocos2d_8_1.Shared/libcocos2d_8_1.Shared.vcxitems.filters @@ -1,4 +1,4 @@ - + @@ -1743,6 +1743,9 @@ 3d + + 3d + @@ -3312,6 +3315,9 @@ 3d + + 3d + diff --git a/tests/cpp-tests/proj.win8.1-universal/cpp-tests.Shared/cpp-tests.Shared.vcxitems b/tests/cpp-tests/proj.win8.1-universal/cpp-tests.Shared/cpp-tests.Shared.vcxitems index 84eb9ac57a..cec6b7926f 100644 --- a/tests/cpp-tests/proj.win8.1-universal/cpp-tests.Shared/cpp-tests.Shared.vcxitems +++ b/tests/cpp-tests/proj.win8.1-universal/cpp-tests.Shared/cpp-tests.Shared.vcxitems @@ -144,6 +144,7 @@ + @@ -407,6 +408,7 @@ + diff --git a/tests/cpp-tests/proj.win8.1-universal/cpp-tests.Shared/cpp-tests.Shared.vcxitems.filters b/tests/cpp-tests/proj.win8.1-universal/cpp-tests.Shared/cpp-tests.Shared.vcxitems.filters index d44bae8c7e..5cae463ddc 100644 --- a/tests/cpp-tests/proj.win8.1-universal/cpp-tests.Shared/cpp-tests.Shared.vcxitems.filters +++ b/tests/cpp-tests/proj.win8.1-universal/cpp-tests.Shared/cpp-tests.Shared.vcxitems.filters @@ -775,6 +775,9 @@ Classes\PerformanceTest + + Classes\TerrainTest + @@ -1677,6 +1680,9 @@ {65d0104d-321a-41f7-99af-de609183f206} + + {56386912-b41e-4559-bd2c-b256434179d4} + @@ -1707,5 +1713,8 @@ Classes\PerformanceTest + + Classes\TerrainTest + \ No newline at end of file