⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 terrrender.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------


#include "terrain/terrData.h"
#include "game/fx/Celestial.h"//celestial
#include "math/mMath.h"
#include "dgl/dgl.h"
#include "console/console.h"
#include "console/consoleTypes.h"
#include "dgl/gBitmap.h"
#include "terrain/terrRender.h"
#include "dgl/materialList.h"
#include "sceneGraph/sceneState.h"
#include "terrain/waterBlock.h"
#include "terrain/blender.h"
#include "core/frameAllocator.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/sgUtil.h"
#include "platform/profiler.h"

struct LightTriangle {
   ColorF  color;

   Point2F texco1;
   Point3F point1;
   Point2F texco2;
   Point3F point2;
   Point2F texco3;
   Point3F point3;

   LightTriangle* next;
   U32            flags;  // 0 if inactive
};

static LightTriangle* sgCurrLightTris = NULL;


GBitmap* TerrainRender::mBlendBitmap = NULL;

S32 TerrainRender::mTextureMinSquareSize;

bool TerrainRender::mEnableTerrainDetails       = true;
// CW - stuff with bump maps
// So, this is how it works...
// There are 3 fields:
// 1) bumpScale: This is the size of the bumps.  It determines how much the bump texture is stretched
// 2) bumpOffset: How much the two textures are offset from each other.  This should be VERY close to
//    0.  An appropriate value is usually around 0.004 and 0.01.  Play around with it and see what
//    works best for your implementation.
// 3) zeroBumpScale: This is a bitshift value for how far the bumps are drawn.  The LESS the value
//    the FARTHER they will exist.  If you go above 7-8, the bumps tend to go a little wacky.
//    8 should be the max.  6-7 are good values.
bool TerrainRender::mEnableTerrainEmbossBumps   = true;
// This is only for win32
#ifdef TORQUE_OS_WIN32
bool TerrainRender::mRenderGL = false;
#endif
// CW - end bump map stuff
bool TerrainRender::mEnableTerrainDynLights     = true;

U32 TerrainRender::mNumClipPlanes = 4;
MatrixF TerrainRender::mCameraToObject;

AllocatedTexture TerrainRender::mTextureFrameListHead;
AllocatedTexture TerrainRender::mTextureFrameListTail;
AllocatedTexture TerrainRender::mTextureFreeListHead;
AllocatedTexture TerrainRender::mTextureFreeListTail;
AllocatedTexture TerrainRender::mTextureFreeBigListHead;
AllocatedTexture TerrainRender::mTextureFreeBigListTail;
AllocatedTexture *TerrainRender::mTextureGrid[AllocatedTextureCount];
AllocatedTexture **TerrainRender::mTextureGridPtr[5];
AllocatedTexture *TerrainRender::mCurrentTexture = NULL;
#if defined(TORQUE_OS_LINUX) || defined(TORQUE_OS_OPENBSD)
// Texture slop isn't necessary on Linux
U32 TerrainRender::mTextureSlopSize = 512;
#else
U32 TerrainRender::mTextureSlopSize = 220;
#endif

static bool sgTextureFreeListPrimed = false;
static U32  sgFreeListPrimeCount    = 32;
Vector<TextureHandle> TerrainRender::mTextureFreeList(__FILE__, __LINE__);

SceneState* TerrainRender::mSceneState;

TerrainBlock* TerrainRender::mCurrentBlock;
S32 TerrainRender::mSquareSize;
F32 TerrainRender::mScreenSize;
U32 TerrainRender::mFrameIndex;

Point2F TerrainRender::mBlockPos;
Point2I TerrainRender::mBlockOffset;
Point2I TerrainRender::mTerrainOffset;
PlaneF  TerrainRender::mClipPlane[MaxClipPlanes];
Point3F TerrainRender::mCamPos;

TextureHandle* TerrainRender::mGrainyTexture = NULL;
U32            TerrainRender::mDynamicLightCount;

F32 TerrainRender::mPixelError;

TerrLightInfo TerrainRender::mTerrainLights[MaxTerrainLights];
bool TerrainRender::mRenderingCommander = false;


F32 TerrainRender::mScreenError;
F32 TerrainRender::mMinSquareSize;
F32 TerrainRender::mFarDistance;
S32 TerrainRender::mDynamicTextureCount;
S32 TerrainRender::mStaticTextureCount;
S32 maxTerrPoints = 100;

ColorF TerrainRender::mFogColor;

bool TerrainRender::mRenderOutline;

U32 TerrainRender::mMaterialCount;

namespace {

Point4F sgTexGenS;
Point4F sgTexGenT;
Point4F sgLMGenS;
Point4F sgLMGenT;
Point4F bumpTexGenS;
Point4F bumpTexGenT;
Point2F bumpTextureOffset;
} // namespace {}


static S32 getPower(S32 x)
{
    // Returns 2^n (the highest bit).
    S32 i = 0;
    if (x)
        do
            i++;
        while (x >>= 1);
    return i;
}


void TerrainRender::init()
{
   S32 i;
   mTextureMinSquareSize = 0;

   mFrameIndex = 0;

   mScreenError = 4;
   mScreenSize = 45;
   mMinSquareSize = 4;
   mFarDistance = 500;
   mRenderOutline = false;
   mTextureFrameListHead.next = &mTextureFrameListTail;
   mTextureFrameListHead.previous = NULL;
   mTextureFrameListTail.next = NULL;
   mTextureFrameListTail.previous = &mTextureFrameListHead;

   mTextureFreeListHead.next = &mTextureFreeListTail;
   mTextureFreeListHead.previous = NULL;
   mTextureFreeListTail.next = NULL;
   mTextureFreeListTail.previous = &mTextureFreeListHead;

   mTextureFreeBigListHead.next = &mTextureFreeBigListTail;
   mTextureFreeBigListHead.previous = NULL;
   mTextureFreeBigListTail.next = NULL;
   mTextureFreeBigListTail.previous = &mTextureFreeBigListHead;

   for(i = 0; i < AllocatedTextureCount; i++)
      mTextureGrid[i] = 0;

   mTextureGridPtr[0] = mTextureGrid;
   mTextureGridPtr[1] = mTextureGrid + 4096;
   mTextureGridPtr[2] = mTextureGrid + 4096 + 1024;
   mTextureGridPtr[3] = mTextureGrid + 4096 + 1024 + 256;
   mTextureGridPtr[4] = mTextureGrid + 4096 + 1024 + 256 + 64;

/*   for(i = 0; i < 256; i++)
   {
      mSquareSeqAdd[i] = 0;
      for(S32 val = 0; val < 9; val++)
      {
         if(i & (1 << val))
            mSquareSeqAdd[i] += (1 << val) * (1 << val);
      }
   } */

   mBlendBitmap = new GBitmap(TerrainTextureSize, TerrainTextureSize, true, GBitmap::RGB5551);

   Con::addVariable("T2::dynamicTextureCount", TypeS32, &mDynamicTextureCount);
   Con::addVariable("T2::staticTextureCount", TypeS32, &mStaticTextureCount);

   Con::addVariable("screenSize", TypeF32, &mScreenSize);
   Con::addVariable("farDistance", TypeF32, &mFarDistance);
   Con::addVariable("pref::Terrain::texDetail", TypeS32, &mTextureMinSquareSize);
   Con::addVariable("pref::Terrain::enableDetails", TypeBool, &mEnableTerrainDetails);
// CW - stuff with bump maps
    Con::addVariable("pref::Terrain::enableEmbossBumps", TypeBool, &mEnableTerrainEmbossBumps);
    // CW - end bump map stuff
   Con::addVariable("pref::Terrain::dynamicLights", TypeBool, &mEnableTerrainDynLights);
   Con::addVariable("pref::Terrain::screenError", TypeF32, &mScreenError);
   Con::addVariable("pref::Terrain::textureCacheSize", TypeS32, &mTextureSlopSize);
}

void TerrainRender::shutdown()
{
   delete mBlendBitmap;
   mBlendBitmap = NULL;
   flushCache();
}

void TerrainRender::buildClippingPlanes(bool flipClipPlanes)
{
   F64 frustumParam[6];
   dglGetFrustum(&frustumParam[0], &frustumParam[1],
                 &frustumParam[2], &frustumParam[3],
                 &frustumParam[4], &frustumParam[5]);

   Point3F osCamPoint(0, 0, 0);
   mCameraToObject.mulP(osCamPoint);
   sgComputeOSFrustumPlanes(frustumParam,
                            mCameraToObject,
                            osCamPoint,
                            mClipPlane[4],
                            mClipPlane[0],
                            mClipPlane[1],
                            mClipPlane[2],
                            mClipPlane[3]);
   // no need
   mNumClipPlanes = 4;
   // near plane is needed as well...
   //PlaneF p(0, 1, 0, -frustumParam[4]);
   //mTransformPlane(mCameraToObject, Point3F(1,1,1), p, &mClipPlane[0]);

   if (flipClipPlanes) {
      mClipPlane[0].neg();
      mClipPlane[1].neg();
      mClipPlane[2].neg();
      mClipPlane[3].neg();
      mClipPlane[4].neg();
      mClipPlane[5].neg();
   }
}

S32 TerrainRender::TestSquareVisibility(Point3F &min, Point3F &max, S32 mask, F32 expand)
{
   S32 retMask = 0;
   Point3F minPoint, maxPoint;
   for(S32 i = 0; i < mNumClipPlanes; i++)
   {
      if(mask & (1 << i))
      {
         if(mClipPlane[i].x > 0)
         {
            maxPoint.x = max.x;
            minPoint.x = min.x;
         }
         else
         {
            maxPoint.x = min.x;
            minPoint.x = max.x;
         }
         if(mClipPlane[i].y > 0)
         {
            maxPoint.y = max.y;
            minPoint.y = min.y;
         }
         else
         {
            maxPoint.y = min.y;
            minPoint.y = max.y;
         }
         if(mClipPlane[i].z > 0)
         {
            maxPoint.z = max.z;
            minPoint.z = min.z;
         }
         else
         {
            maxPoint.z = min.z;
            minPoint.z = max.z;
         }
         F32 maxDot = mDot(maxPoint, mClipPlane[i]);
         F32 minDot = mDot(minPoint, mClipPlane[i]);
         F32 planeD = mClipPlane[i].d;
         if(maxDot <= -(planeD + expand))
            return -1;
         if(minDot <= -planeD)
            retMask |= (1 << i);
      }
   }
   return retMask;
}

ChunkCornerPoint *TerrainRender::allocInitialPoint(Point3F pos)
{

   ChunkCornerPoint *ret = (ChunkCornerPoint *) FrameAllocator::alloc(sizeof(ChunkCornerPoint));
   ret->x = pos.x;
   ret->y = pos.y;
   ret->z = pos.z;
   ret->distance = (*ret - mCamPos).len();
   gClientSceneGraph->getFogCoordPair(ret->distance, ret->z, ret->fogRed, ret->fogGreen);
   ret->xfIndex = 0;
   return ret;
}

ChunkCornerPoint *TerrainRender::allocPoint(Point2I pos)
{
   ChunkCornerPoint *ret = (ChunkCornerPoint *) FrameAllocator::alloc(sizeof(ChunkCornerPoint));
   ret->x = pos.x * mSquareSize + mBlockPos.x;
   ret->y = pos.y * mSquareSize + mBlockPos.y;
   ret->z = fixedToFloat(mCurrentBlock->getHeight(pos.x, pos.y));
   ret->distance = (*ret - mCamPos).len();
   gClientSceneGraph->getFogCoordPair(ret->distance, ret->z, ret->fogRed, ret->fogGreen);

   ret->xfIndex = 0;
   return ret;
}

void TerrainRender::allocRenderEdges(U32 edgeCount, EdgeParent **dest, bool renderEdge)
{
   if(renderEdge)
   {
      for(U32 i = 0; i < edgeCount; i++)
      {
         ChunkEdge *edge = (ChunkEdge *) FrameAllocator::alloc(sizeof(ChunkEdge));
         edge->c1 = NULL;
         edge->c2 = NULL;
         edge->xfIndex = 0;
         dest[i] = edge;
      }
   }
   else
   {
      for(U32 i = 0; i < edgeCount; i++)
      {
         ChunkScanEdge *edge = (ChunkScanEdge *) FrameAllocator::alloc(sizeof(ChunkScanEdge));
         edge->mp = NULL;
         dest[i] = edge;
      }
   }
}

void TerrainRender::subdivideChunkEdge(ChunkScanEdge *e, Point2I pos, bool chunkEdge)
{
   if(!e->mp)
   {
      allocRenderEdges(2, &e->e1, chunkEdge);
      e->mp = allocPoint(pos);

      e->e1->p1 = e->p1;
      e->e1->p2 = e->mp;
      e->e2->p1 = e->mp;
      e->e2->p2 = e->p2;
   }
}

F32 TerrainRender::getSquareDistance(const Point3F& minPoint, const Point3F& maxPoint, F32* zDiff)
{
   Point3F vec;
   if(mCamPos.z < minPoint.z)
      vec.z = minPoint.z - mCamPos.z;
   else if(mCamPos.z > maxPoint.z)
      vec.z = maxPoint.z - mCamPos.z;
   else
      vec.z = 0;

   if(mCamPos.x < minPoint.x)
      vec.x = minPoint.x - mCamPos.x;
   else if(mCamPos.x > maxPoint.x)
      vec.x = mCamPos.x - maxPoint.x;
   else
      vec.x = 0;

   if(mCamPos.y < minPoint.y)
      vec.y = minPoint.y - mCamPos.y;
   else if(mCamPos.y > maxPoint.y)
      vec.y = mCamPos.y - maxPoint.y;
   else
      vec.y = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -