afTerrain.h
资源名称:AirForce.rar [点击查看]
上传用户:kaiguan
上传日期:2007-10-28
资源大小:1074k
文件大小:9k
源码类别:
其他游戏
开发平台:
Visual C++
- #ifndef AF_TERRAIN
- #define AF_TERRAIN
- #include "afImage.h"
- #include "afList.h"
- #include "afProfiler.h"
- #include "afPtrList.h"
- #include "afVec4.h"
- #include "afVec3.h"
- #include "af3DObject.h"
- #include "afTexture.h"
- #include "afTextureStage.h"
- #include "afTerrainPVS.h"
- #include "afTerrainPatch.h"
- #include <D3DX9.h>
- /// Terrain can render terrain by using geo-mipmapping
- /**
- * afTerrain uses geo-mipmapping in order to display large
- * landscapes at a high framerate. An arbitrary number of
- * texture passes can be applied. An alpha map defines,
- * where each texture is visible on the landscape and where not. */
- class afTerrain : public af3DObject
- {
- //friend class afTerrainPatch;
- friend class afTerrainPatch;
- public:
- inline bool SetupVertexShader();
- void DestroyVertexShader();
- bool BuildVertexShader();
- afTerrain();
- /// Sets a mipmap filter
- /**
- * Default filter is LINEAR.
- */
- void setMipmapFilter(afTextureStage::FILTER nFilter) { mipFilter = nFilter; }
- /// Adds a pass to the terrain.
- /**
- * This method works same as setBasePass, except that the lightmap has
- * to have an alpha channel, which defines, where the colortexture is
- * visible and where not.
- */
- void addPass(afTexture* nColorTexture, float nRepeatX, float nRepeatY, afTexture* nLightmap);
- /// Sets the height map
- /**
- * A height value of 0 will create a vertex at pos.y.
- * A height value of 255 will create a vertex at pos.y + sizeY
- */
- void setHeightMap(afImage* nImage);
- /// Defines the name of the pvs map file
- //
- void setPVSName(const afString& nName) { pvsName = nName; }
- /// Sets a texture which will be painted on the terrain to show cloud shadows.
- /**
- * nRepeatX and nRepeatY define of often the texture is repeated (wrapped).
- * nSpeedX and nSpeedY define how much (in texture coordinates) the texture
- * moves in one second.
- */
- void setSkyMap(afTexture* nSkyMap, float nRepeatX, float nRepeatY, float nSpeedX, float nSpeedY);
- /// Sets the size of the landscape in number of patches.
- /**
- * nX and nY must correlate to the image which was set as heightmap.
- * The heightmaps size must be (nX*16)+1 x (nY*16)+1.
- */
- void setNumPatches(int nX, int nY) { patchesX = nX; patchesY = nY; }
- /// Sets how large one patch is.
- /**
- * The size of the complete landscape can be calculated by:
- * patchesX*nSizeX x nSizeY x patchesY*nSizeZ
- */
- void setPatchSize(float nSizeX, float nSizeY, float nSizeZ);
- /// Sets the maximum error which is allowed for patch rendering
- /**
- * If the projected error of a patch on the render window exceeds
- * maxError, the next more detailed tesselation is used.
- */
- void setMaxError(float nErr) { maxError = nErr; }
- /// Returns the maximum error, which was set by setMaxError()
- float getMaxError() const { return maxError; }
- /// Sets the fog's range
- /**
- * If this method is not called no fog is used
- */
- void setFogRange(float nNear, float nFar) { fogNear = nNear; fogFar = nFar; }
- /// Sets the fog's color (default: (1.0, 1.0, 1.0, 1.0)
- void setFogColor(const afVec4& nCol) { fogColor = nCol; }
- /// Sets the fps which shall be achieved
- /**
- * If the value is not zero, the terrain will automatically
- * been drawn coarser or finer in order to achieve the
- * desired fps. Pass 0 in order to turn of fps achievment.
- */
- void setDesiredFPS(int nFPS) { desiredFPS = nFPS; }
- /// Returns the desired fps set with setDesiredFPS()
- /**
- * By default the automatic fps feature is disabled and
- * getDesiredFPS() will return 0.
- */
- int getDesiredFPS() const { return desiredFPS; }
- void setMergePatches(bool nSet) { mergeSmallPatches = nSet; }
- bool getMergePatches() const { return mergeSmallPatches; }
- /// Build the landscape after all properties have been set.
- void build();
- /// Renders the landscape.
- void render();
- /// Updates the landscapes tesselation.
- /**
- * It's important that the camera's final position for
- * the current frame has already been set, since it is
- * used to calculate the tesselation depth for each
- * patch.
- */
- void update();
- /// Does not yet work correctly
- bool intersectLine(const afVec3& nPos0, const afVec3& nPos1, float& nScalarPos) const;
- /// Calculates the position on landscape's surface below nPos
- /**
- * If nPos is not above the landscape false is returned.
- */
- bool projectDown(const afVec3& nPos, afVec3& nProjected) const;
- /// Moves nPos to stay above the surface.
- /**
- * (nGlideFactor is not used yet)
- */
- bool moveAboveSurface(afVec3& nPos, float nHeight, float nGlideFactor) const;
- /// Returns the number of patches which were rendered in the last frame
- int getNumPatchesRendered() { return numPatchesRendered; }
- afTerrainPatchPtr getPatch(int nX, int nY) { return patches[nY][nX]; }
- /// Fills a string with information about the last rendered terrain
- void fillInfoString(afString& nStr);
- void fillInfoString2(afString& nStr);
- virtual void setPosition(const afVec3& nPos) { pos = nPos; }
- virtual void setRotation(const afVec3& nRot) { rot = nRot; }
- virtual void deleteDeviceObjects();
- virtual bool restoreDeviceObjects();
- void addBufferCreateCount() { bufferCreateCount++; }
- protected:
- struct MultiPassInfo
- {
- MultiPassInfo() { texColor = texMod = NULL; repeatX = repeatY = 1.0f; }
- afTexturePtr texColor, texMod;
- float repeatX, repeatY;
- D3DXMATRIX matrix;
- // these members are only used for searching invisible patches...
- //
- unsigned char* visData;
- int visPitch;
- bool inVis,fullVis;
- };
- inline void updateSkyMatrix();
- void fillPassInfo(MultiPassInfo* nPass, afTexture* nTexture, float nX, float nY, afTexture* nLightmap);
- void calcPassVisibility(MultiPassInfo* nInfo, int nX, int nY);
- inline void setupTextureStages(MultiPassInfo* nPass, bool nBasePass,bool bForceSoftware);
- inline void setupTextureStagesForSky(bool bForceSoftware);
- inline void updateWorldMatrix();
- void checkBuffers();
- afTerrainPatchPtr& getActiveList() { return activePatches; }
- inline float getHeight(int nX, int nY) const;
- inline void getNormal(int nX, int nY, afVec3& nNormal) const;
- inline void getTexCoord(int nX, int nY, afVec2& nTCoord) const;
- float getHeightDif(int nX0, int nY0, int nX1, int nY1);
- void createNormals();
- afTerrainPatch* createPatch(int nX, int nY);
- afString pvsName;
- afTerrainPVS* pvs;
- afVec3 pos, rot;
- float sizeX, sizeY, sizeZ;
- float patchDX, patchDY, patchDZ;
- int minX, minY, maxX, maxY;
- float maxError;
- int desiredFPS;
- afTerrainPatchPtr **patches;
- afTerrainPatchPtr activePatches;
- int patchesX, patchesY;
- int numPatchesRendered, numPatchesPassesRendered, numPatchesProcessed;
- D3DXMATRIX worldMatrix;
- afPtrList<MultiPassInfo> multiPassInfos;
- MultiPassInfo skyPass;
- float skySpeedX,skySpeedY,
- skyPosX,skyPosY;
- float fogNear, fogFar;
- afVec4 fogColor;
- afImagePtr heightmap;
- unsigned char *hmData;
- int hmWidth, hmHeight;
- afVec3Ptr normals;
- int numNewVertices, numNewIndices,
- numVertices, numIndices;
- bool forceBufferCreate;
- PDIRECT3DINDEXBUFFER9 iBuffer;
- PDIRECT3DVERTEXBUFFER9 vBuffer;
- LPDIRECT3DVERTEXDECLARATION9 m_pTerrainDecl;
- LPDIRECT3DVERTEXSHADER9 m_pTerrainShader;
- afTextureStage::FILTER mipFilter;
- bool useUnitDistance, mergeSmallPatches;
- int patchCount[afTerrainPatch::MAX_SUBDIV+1], bufferCreateCount;
- protected:
- afProfiler profileUpdate, profileRender;
- };
- #define FLIP_Y
- inline float afTerrain::getHeight(int nX, int nY) const
- {
- assert(nX>=0 && nX<hmWidth);
- assert(nY>=0 && nY<hmHeight);
- #ifdef FLIP_Y
- return ((float)hmData[nX + (hmHeight-1-nY)*hmWidth])/255.0f;
- #else
- return ((float)hmData[nX + nY*hmWidth])/255.0f;
- #endif // FLIP_Y
- }
- inline void afTerrain::getNormal(int nX, int nY, afVec3& nNormal) const
- {
- assert(nX>=0 && nX<hmWidth);
- assert(nY>=0 && nY<hmHeight);
- //#ifdef FLIP_Y
- // nNormal = normals[nX + (hmHeight-1-nY)*hmWidth];
- //#else
- nNormal = normals[nX + nY*hmWidth];
- //#endif // FLIP_Y
- }
- inline void afTerrain::getTexCoord(int nX, int nY, afVec2& nTCoord) const
- {
- nTCoord.x = (float)nX/(float)(hmWidth-1);
- #ifdef FLIP_Y
- nTCoord.y = (float)(hmHeight-1-nY)/(float)(hmHeight-1);
- #else
- nTCoord.y = (float)nY/(float)(hmHeight-1);
- #endif // FLIP_Y
- }
- #endif