afTerrain.h
上传用户:kaiguan
上传日期:2007-10-28
资源大小:1074k
文件大小:9k
源码类别:

其他游戏

开发平台:

Visual C++

  1. #ifndef AF_TERRAIN
  2. #define AF_TERRAIN
  3. #include "afImage.h"
  4. #include "afList.h"
  5. #include "afProfiler.h"
  6. #include "afPtrList.h"
  7. #include "afVec4.h"
  8. #include "afVec3.h"
  9. #include "af3DObject.h"
  10. #include "afTexture.h"
  11. #include "afTextureStage.h"
  12. #include "afTerrainPVS.h"
  13. #include "afTerrainPatch.h"
  14. #include <D3DX9.h>
  15. /// Terrain can render terrain by using geo-mipmapping
  16. /**
  17.  *  afTerrain uses geo-mipmapping in order to display large
  18.  *  landscapes at a high framerate. An arbitrary number of
  19.  *  texture passes can be applied. An alpha map defines,
  20.  *  where each texture is visible on the landscape and where not. */
  21. class afTerrain : public af3DObject
  22. {
  23. //friend class afTerrainPatch;
  24. friend class afTerrainPatch;
  25. public:
  26. inline bool SetupVertexShader();
  27. void DestroyVertexShader();
  28. bool BuildVertexShader();
  29. afTerrain();
  30. /// Sets a mipmap filter
  31. /**
  32.  *  Default filter is LINEAR.
  33.  */
  34. void setMipmapFilter(afTextureStage::FILTER nFilter)  {  mipFilter = nFilter;  }
  35. /// Adds a pass to the terrain.
  36.     /**
  37.  *  This method works same as setBasePass, except that the lightmap has
  38.  *  to have an alpha channel, which defines, where the colortexture is
  39.  *  visible and where not.
  40.  */
  41. void addPass(afTexture* nColorTexture, float nRepeatX, float nRepeatY, afTexture* nLightmap);
  42. /// Sets the height map
  43. /**
  44.  *  A height value of 0 will create a vertex at pos.y.
  45.  *  A height value of 255 will create a vertex at pos.y + sizeY
  46.  */
  47. void setHeightMap(afImage* nImage);
  48. /// Defines the name of the pvs map file
  49. //
  50. void setPVSName(const afString& nName)  {  pvsName = nName;  }
  51. /// Sets a texture which will be painted on the terrain to show cloud shadows.
  52. /**
  53.  *  nRepeatX and nRepeatY define of often the texture is repeated (wrapped).
  54.  *  nSpeedX and nSpeedY define how much (in texture coordinates) the texture
  55.  *  moves in one second.
  56.  */
  57. void setSkyMap(afTexture* nSkyMap, float nRepeatX, float nRepeatY, float nSpeedX, float nSpeedY);
  58. /// Sets the size of the landscape in number of patches.
  59. /**
  60.  *  nX and nY must correlate to the image which was set as heightmap.
  61.  *  The heightmaps size must be (nX*16)+1 x (nY*16)+1.
  62.  */
  63. void setNumPatches(int nX, int nY)  {  patchesX = nX;  patchesY = nY;  }
  64. /// Sets how large one patch is.
  65. /**
  66.  *  The size of the complete landscape can be calculated by:
  67.  *  patchesX*nSizeX x nSizeY x patchesY*nSizeZ
  68.  */
  69. void setPatchSize(float nSizeX, float nSizeY, float nSizeZ);
  70. /// Sets the maximum error which is allowed for patch rendering
  71. /**
  72.  *  If the projected error of a patch on the render window exceeds
  73.  *  maxError, the next more detailed tesselation is used.
  74.  */
  75. void setMaxError(float nErr)  {  maxError = nErr;  }
  76. /// Returns the maximum error, which was set by setMaxError()
  77. float getMaxError() const  {  return maxError;  }
  78. /// Sets the fog's range
  79. /**
  80.  *  If this method is not called no fog is used
  81.  */
  82. void setFogRange(float nNear, float nFar)  {  fogNear = nNear;  fogFar = nFar;  }
  83. /// Sets the fog's color (default: (1.0, 1.0, 1.0, 1.0)
  84. void setFogColor(const afVec4& nCol)  {  fogColor = nCol;  }
  85. /// Sets the fps which shall be achieved
  86. /**
  87.  *  If the value is not zero, the terrain will automatically
  88.  *  been drawn coarser or finer in order to achieve the
  89.  *  desired fps. Pass 0 in order to turn of fps achievment.
  90.  */
  91. void setDesiredFPS(int nFPS)  {  desiredFPS = nFPS;  }
  92. /// Returns the desired fps set with setDesiredFPS()
  93. /**
  94.  *  By default the automatic fps feature is disabled and
  95.  *  getDesiredFPS() will return 0.
  96.  */
  97. int getDesiredFPS() const  {  return desiredFPS;  }
  98. void setMergePatches(bool nSet)  {  mergeSmallPatches = nSet;  }
  99. bool getMergePatches() const  {  return mergeSmallPatches;  }
  100. /// Build the landscape after all properties have been set.
  101. void build();
  102. /// Renders the landscape.
  103. void render();
  104. /// Updates the landscapes tesselation.
  105. /**
  106.  *  It's important that the camera's final position for
  107.  *  the current frame has already been set, since it is
  108.  *  used to calculate the tesselation depth for each
  109.  *  patch.
  110.  */
  111. void update();
  112. /// Does not yet work correctly
  113. bool intersectLine(const afVec3& nPos0, const afVec3& nPos1, float& nScalarPos) const;
  114. /// Calculates the position on landscape's surface below nPos
  115. /**
  116.  *  If nPos is not above the landscape false is returned.
  117.  */
  118. bool projectDown(const afVec3& nPos, afVec3& nProjected) const;
  119. /// Moves nPos to stay above the surface.
  120. /**
  121.  *  (nGlideFactor is not used yet)
  122.  */
  123. bool moveAboveSurface(afVec3& nPos, float nHeight, float nGlideFactor) const;
  124. /// Returns the number of patches which were rendered in the last frame
  125. int getNumPatchesRendered()  {  return numPatchesRendered;  }
  126. afTerrainPatchPtr getPatch(int nX, int nY)  {  return patches[nY][nX];  }
  127. /// Fills a string with information about the last rendered terrain
  128. void fillInfoString(afString& nStr);
  129. void fillInfoString2(afString& nStr);
  130. virtual void setPosition(const afVec3& nPos)  {  pos = nPos;  }
  131. virtual void setRotation(const afVec3& nRot)  {  rot = nRot;  }
  132. virtual void deleteDeviceObjects();
  133. virtual bool restoreDeviceObjects();
  134. void addBufferCreateCount()  {  bufferCreateCount++;  }
  135. protected:
  136. struct MultiPassInfo
  137. {
  138. MultiPassInfo()  {  texColor = texMod = NULL;  repeatX = repeatY = 1.0f;  }
  139. afTexturePtr texColor, texMod;
  140. float repeatX, repeatY;
  141. D3DXMATRIX matrix;
  142. // these members are only used for searching invisible patches...
  143. //
  144. unsigned char* visData;
  145. int visPitch;
  146. bool inVis,fullVis;
  147. };
  148. inline void updateSkyMatrix();
  149. void fillPassInfo(MultiPassInfo* nPass, afTexture* nTexture, float nX, float nY, afTexture* nLightmap);
  150. void calcPassVisibility(MultiPassInfo* nInfo, int nX, int nY);
  151. inline void setupTextureStages(MultiPassInfo* nPass, bool nBasePass,bool bForceSoftware);
  152. inline void setupTextureStagesForSky(bool bForceSoftware);
  153. inline void updateWorldMatrix();
  154. void checkBuffers();
  155. afTerrainPatchPtr& getActiveList()  {  return activePatches;  }
  156. inline float getHeight(int nX, int nY) const;
  157. inline void getNormal(int nX, int nY, afVec3& nNormal) const;
  158. inline void getTexCoord(int nX, int nY, afVec2& nTCoord) const;
  159. float getHeightDif(int nX0, int nY0, int nX1, int nY1);
  160. void createNormals();
  161. afTerrainPatch* createPatch(int nX, int nY);
  162. afString pvsName;
  163. afTerrainPVS* pvs;
  164. afVec3 pos, rot;
  165. float sizeX, sizeY, sizeZ;
  166. float patchDX, patchDY, patchDZ;
  167. int minX, minY, maxX, maxY;
  168. float maxError;
  169. int desiredFPS;
  170. afTerrainPatchPtr **patches;
  171. afTerrainPatchPtr activePatches;
  172. int patchesX, patchesY;
  173. int numPatchesRendered, numPatchesPassesRendered, numPatchesProcessed;
  174. D3DXMATRIX worldMatrix;
  175. afPtrList<MultiPassInfo> multiPassInfos;
  176. MultiPassInfo skyPass;
  177. float skySpeedX,skySpeedY,
  178. skyPosX,skyPosY;
  179. float fogNear, fogFar;
  180. afVec4 fogColor;
  181. afImagePtr heightmap;
  182. unsigned char *hmData;
  183. int hmWidth, hmHeight;
  184. afVec3Ptr normals;
  185. int numNewVertices, numNewIndices,
  186. numVertices, numIndices;
  187. bool forceBufferCreate;
  188. PDIRECT3DINDEXBUFFER9 iBuffer;
  189. PDIRECT3DVERTEXBUFFER9 vBuffer;
  190. LPDIRECT3DVERTEXDECLARATION9 m_pTerrainDecl;
  191. LPDIRECT3DVERTEXSHADER9      m_pTerrainShader;
  192. afTextureStage::FILTER mipFilter;
  193. bool useUnitDistance, mergeSmallPatches;
  194. int patchCount[afTerrainPatch::MAX_SUBDIV+1], bufferCreateCount;
  195. protected:
  196. afProfiler profileUpdate, profileRender;
  197. };
  198. #define FLIP_Y
  199. inline float afTerrain::getHeight(int nX, int nY) const
  200. {
  201. assert(nX>=0 && nX<hmWidth);
  202. assert(nY>=0 && nY<hmHeight);
  203. #ifdef FLIP_Y
  204. return ((float)hmData[nX + (hmHeight-1-nY)*hmWidth])/255.0f;
  205. #else
  206. return ((float)hmData[nX + nY*hmWidth])/255.0f;
  207. #endif // FLIP_Y
  208. }
  209. inline void afTerrain::getNormal(int nX, int nY, afVec3& nNormal) const
  210. {
  211. assert(nX>=0 && nX<hmWidth);
  212. assert(nY>=0 && nY<hmHeight);
  213. //#ifdef FLIP_Y
  214. // nNormal = normals[nX + (hmHeight-1-nY)*hmWidth];
  215. //#else
  216. nNormal = normals[nX + nY*hmWidth];
  217. //#endif // FLIP_Y
  218. }
  219. inline void afTerrain::getTexCoord(int nX, int nY, afVec2& nTCoord) const
  220. {
  221. nTCoord.x = (float)nX/(float)(hmWidth-1);
  222. #ifdef FLIP_Y
  223. nTCoord.y = (float)(hmHeight-1-nY)/(float)(hmHeight-1);
  224. #else
  225. nTCoord.y = (float)nY/(float)(hmHeight-1);
  226. #endif // FLIP_Y
  227. }
  228. #endif