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

📄 terrrender.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
   {
      pmid->z = fixedToFloat(mCurrentBlock->getHeight(x + dx + dx, y + dy + dy));
      if(maxLevel == 1) // interp the z and haze
         pmid->z = pmid->z + growFactor * (((p1->z + p2->z) * 0.5) - pmid->z);

      pmid->distance = (*pmid - mCamPos).len();
      gClientSceneGraph->getFogCoordPair(pmid->distance, pmid->z, pmid->fogRed, pmid->fogGreen);

      if(maxLevel == 1) // interp the z and haze
      {
         pmid->fogRed = pmid->fogRed + growFactor * (((p1->fogRed + p2->fogRed) * 0.5) - pmid->fogRed);
         pmid->fogGreen = pmid->fogGreen + growFactor * (((p1->fogGreen + p2->fogGreen) * 0.5) - pmid->fogGreen);
      }
      if(minLevel >= 0)
      {
         edge->pointCount = 1;
         return;
      }
   }
   // last case - minLevel == -1, midPoint calc'd
   edge->pointCount = 3;
   EdgePoint *pm1 = &edge->pt[0];
   EdgePoint *pm2 = &edge->pt[2];

   pm1->x = (p1->x + pmid->x) * 0.5;
   pm1->y = (p1->y + pmid->y) * 0.5;
   pm2->x = (p2->x + pmid->x) * 0.5;
   pm2->y = (p2->y + pmid->y) * 0.5;

   if(maxLevel != -1)
   {
      // clamp it:
      pm1->z = (p1->z + pmid->z) * 0.5;
      pm1->distance = (*pm1 - mCamPos).len();
      pm1->fogRed = (p1->fogRed + pmid->fogRed) * 0.5;
      pm1->fogGreen = (p1->fogGreen + pmid->fogGreen) * 0.5;

      pm2->z = (p2->z + pmid->z) * 0.5;
      pm2->distance = (*pm2 - mCamPos).len();
      pm2->fogRed = (p2->fogRed + pmid->fogRed) * 0.5;
      pm2->fogGreen = (p2->fogGreen + pmid->fogGreen) * 0.5;
      return;
   }
   // compute the real deals:
   pm1->z = fixedToFloat(mCurrentBlock->getHeight(x + dx, y + dy));
   pm2->z = fixedToFloat(mCurrentBlock->getHeight(x + dx + dx + dx, y + dy + dy + dy));

   if(growFactor)
   {
      pm1->z = pm1->z + growFactor * (((p1->z + pmid->z) * 0.5) - pm1->z);
      pm2->z = pm2->z + growFactor * (((p2->z + pmid->z) * 0.5) - pm2->z);
   }
   pm1->distance = (*pm1 - mCamPos).len();
   gClientSceneGraph->getFogCoordPair(pm1->distance, pm1->z, pm1->fogRed, pm1->fogGreen);

   pm2->distance = (*pm2 - mCamPos).len();
   gClientSceneGraph->getFogCoordPair(pm2->distance, pm2->z, pm2->fogRed, pm2->fogGreen);

   if(growFactor)
   {
      pm1->fogRed = pm1->fogRed + growFactor * (((p1->fogRed + pmid->fogRed) * 0.5) - pm1->fogRed);
      pm1->fogGreen = pm1->fogGreen + growFactor * (((p1->fogGreen + pmid->fogGreen) * 0.5) - pm1->fogGreen);

      pm2->fogRed = pm2->fogRed + growFactor * (((p2->fogRed + pmid->fogRed) * 0.5) - pm2->fogRed);
      pm2->fogGreen = pm2->fogGreen + growFactor * (((p2->fogGreen + pmid->fogGreen) * 0.5) - pm2->fogGreen);
   }
}

EdgePoint *mXFVertices = NULL;
U16 *mXFIndexBuffer;
U16 *mXFIndexPtr;
U32 mXFIndexCount;

U32 mXFPointCount;
U32 mXFIndex;

inline U32 clipPoint(EdgePoint *p1, EdgePoint *p2, F32 dist)
{
   F32 frac = (dist - p1->distance) / (p2->distance - p1->distance);
   F32 onefrac = 1.0 - frac;
   U32 clipIndex = mXFPointCount++;

   EdgePoint *ip = mXFVertices + clipIndex;
   ip->x = (p2->x * frac) + (p1->x * onefrac);
   ip->y = (p2->y * frac) + (p1->y * onefrac);
   ip->z = (p2->z * frac) + (p1->z * onefrac);
   ip->fogRed = (p2->fogRed * frac) + (p1->fogRed * onefrac);
   ip->fogGreen = (p2->fogGreen * frac) + (p1->fogGreen * onefrac);

   ip->distance = dist;
   return clipIndex;
}

void TerrainRender::clip(U32 indexStart)
{
   static U16 dest[16 * 3 * 2];


   U32 vertexCount = mXFIndexBuffer[indexStart + 1];
   U32 centerPoint = mXFIndexBuffer[indexStart + 2];
   U16 *source = mXFIndexBuffer + indexStart + 3;
   EdgePoint *center = mXFVertices + centerPoint;

   U32 destIndex = 0;

   if(mXFVertices[centerPoint].distance > mFarDistance)
   {
      // loop through all the tris and clip em:
      // there are vertexCount - 1 triangles.
      EdgePoint *p1 = mXFVertices + source[0];
      bool p1out = p1->distance >= mFarDistance;
      U32 p1idx = source[0];
      U32 clip1;
      if(!p1out)
         clip1 = clipPoint(p1, center, mFarDistance);
      for(U32 i = 0; i < vertexCount - 2; i++)
      {
         U32 p2idx = source[i+1];
         EdgePoint *p2 = mXFVertices + p2idx;
         bool p2out = p2->distance >= mFarDistance;
         if(!p2out)
         {
            U32 clip2 = clipPoint(p2, center, mFarDistance);
            if(p1out)
            {
               // p2 is the only "in" point:
               dest[destIndex++] = p2idx;
               dest[destIndex++] = clip2;
               dest[destIndex++] = clipPoint(p1, p2, mFarDistance);
            }
            else
            {
               dest[destIndex++] = clip2;
               dest[destIndex++] = clip1;
               dest[destIndex++] = p1idx;
               dest[destIndex++] = p2idx;
               dest[destIndex++] = clip2;
               dest[destIndex++] = p1idx;
            }
            clip1 = clip2;
         }
         else if(!p1out)
         {
            dest[destIndex++] = p1idx;
            dest[destIndex++] = clipPoint(p1, p2, mFarDistance);
            dest[destIndex++] = clip1;
         }
         p1idx = p2idx;
         p1out = p2out;
         p1 = p2;
      }
      if(destIndex)
      {
         // copy this in..
         mXFIndexBuffer[indexStart] = GL_TRIANGLES;
         mXFIndexBuffer[indexStart + 1] = destIndex;
         for(U32 i = 0; i < destIndex; i++)
            mXFIndexBuffer[indexStart + i + 2] = dest[i];
         mXFIndexCount = destIndex + indexStart + 2;
      }
      else
         mXFIndexCount = indexStart;
   }
   else
   {
      EdgePoint *prev = mXFVertices + source[0];
      bool prevIn = prev->distance <= mFarDistance;
      U32 i;

      for(i = 1; i < vertexCount - 1; i++)
      {
         EdgePoint *pt = mXFVertices + source[i];
         bool curIn = pt->distance <= mFarDistance;

         if((curIn && !prevIn) || (!curIn && prevIn))
            dest[destIndex++] = clipPoint(pt, prev, mFarDistance);
         if(curIn)
            dest[destIndex++] = source[i];
         else
            dest[destIndex++] = clipPoint(pt, center, mFarDistance);
         prev = pt;
         prevIn = curIn;
      }
      for(i = 0; i < destIndex; i++)
         mXFIndexBuffer[indexStart + i + 3] = dest[i];
      mXFIndexBuffer[indexStart + destIndex + 3] = dest[0];
      mXFIndexBuffer[indexStart + 1] = destIndex + 2;
      mXFIndexCount = indexStart + destIndex + 4;
   }
}

inline U32 TerrainRender::constructPoint(S32 x, S32 y)
{
   U32 ret = mXFPointCount++;
   EdgePoint *pt = mXFVertices + ret;

   pt->x = x * mSquareSize;
   pt->y = y * mSquareSize;
   pt->z = fixedToFloat(mCurrentBlock->getHeight(x, y));

   pt->distance = (*pt - mCamPos).len();

   gClientSceneGraph->getFogCoordPair(pt->distance, pt->z, pt->fogRed, pt->fogGreen);

   return ret;
}

inline U32 TerrainRender::interpPoint(U32 p1, U32 p2, S32 x, S32 y, F32 growFactor)
{
   U32 ret = mXFPointCount++;
   EdgePoint *pt = mXFVertices + ret;

   pt->x = x * mSquareSize;
   pt->y = y * mSquareSize;
   pt->z = fixedToFloat(mCurrentBlock->getHeight(x, y));
   pt->z = pt->z + growFactor * (((mXFVertices[p1].z + mXFVertices[p2].z) * 0.5) - pt->z);

   pt->distance = (*pt - mCamPos).len();
   gClientSceneGraph->getFogCoordPair(pt->distance, pt->z, pt->fogRed, pt->fogGreen);

   return ret;
}

inline void TerrainRender::addEdge(ChunkEdge *edge)
{
   if(edge->pointCount == 1)
   {
      edge->pointIndex = mXFPointCount;
      mXFVertices[mXFPointCount++] = * ((EdgePoint *) &edge->pt[1]);
   }
   else if(edge->pointCount == 3)
   {
      edge->pointIndex = mXFPointCount;
      mXFVertices[mXFPointCount++] = *((EdgePoint *) &edge->pt[0]);
      mXFVertices[mXFPointCount++] = *((EdgePoint *) &edge->pt[1]);
      mXFVertices[mXFPointCount++] = *((EdgePoint *) &edge->pt[2]);
   }
   edge->xfIndex = mXFIndex;
}

inline void emitTri(U32 i1, U32 i2, U32 i3)
{
   mXFIndexBuffer[mXFIndexCount] = i1;
   mXFIndexBuffer[mXFIndexCount + 1] = i2;
   mXFIndexBuffer[mXFIndexCount + 2] = i3;
   mXFIndexCount += 3;
}

inline U32 emitCornerPoint(ChunkCornerPoint *p)
{
   if(p->xfIndex != mXFIndex)
   {
      p->pointIndex = mXFPointCount;
      p->xfIndex = mXFIndex;
      mXFVertices[mXFPointCount++] = *((EdgePoint *) p);
   }
   return p->pointIndex;
}

void buildLightTri(LightTriangle* pTri, TerrLightInfo* pInfo)
{
   // Get the plane normal
   Point3F normal;
   mCross((pTri->point1 - pTri->point2), (pTri->point3 - pTri->point2), &normal);
   if (normal.lenSquared() < 1e-7)
   {
      pTri->flags = 0;
      return;
   }


   PlaneF plane(pTri->point2, normal);  // Assumes that mPlane.h normalizes incoming point

   Point3F centerPoint;
   F32 d = plane.distToPlane(pInfo->pos);
   centerPoint = pInfo->pos - plane * d;
   d = mFabs(d);
   if (d >= pInfo->radius) {
      pTri->flags = 0;
      return;
   }

   F32 mr = mSqrt(pInfo->radiusSquared - d*d);

   Point3F normalS;
   Point3F normalT;
   mCross(plane, Point3F(0, 1, 0), &normalS);
   mCross(plane, normalS, &normalT);
   PlaneF splane(centerPoint, normalS); // Assumes that mPlane.h normalizes incoming point
   PlaneF tplane(centerPoint, normalT); // Assumes that mPlane.h normalizes incoming point

   pTri->color.red   = pInfo->r;
   pTri->color.green = pInfo->g;
   pTri->color.blue  = pInfo->b;
   pTri->color.alpha = (pInfo->radius - d) / pInfo->radius;

   pTri->texco1.set(((splane.distToPlane(pTri->point1) / mr) + 1.0) / 2.0,
                    ((tplane.distToPlane(pTri->point1) / mr) + 1.0) / 2.0);
   pTri->texco2.set(((splane.distToPlane(pTri->point2) / mr) + 1.0) / 2.0,
                    ((tplane.distToPlane(pTri->point2) / mr) + 1.0) / 2.0);
   pTri->texco3.set(((splane.distToPlane(pTri->point3) / mr) + 1.0) / 2.0,
                    ((tplane.distToPlane(pTri->point3) / mr) + 1.0) / 2.0);

   pTri->flags = 1;
}

void TerrainRender::renderChunkCommander(EmitChunk *chunk)
{
   U32 ll = mXFPointCount;
   for(U32 y = 0; y <= 64; y += 4)
      for(U32 x = (y & 4) ? 4 : 0; x <= 64; x += 8)
         constructPoint(chunk->x + x,chunk->y + y);

   for(U32 y = 0; y < 8; y++)
   {
      for(U32 x = 0; x < 8; x++)
      {
         U16 *ib = mXFIndexBuffer + mXFIndexCount;
         ib[0] = GL_TRIANGLE_FAN;
         ib[1] = 6;
         ib[2] = ll + 9;
         ib[3] = ll;
         ib[4] = ll + 17;
         ib[5] = ll + 18;
         ib[6] = ll + 1;
         ib[7] = ll;
         mXFIndexCount += 8;
         ll++;
      }
      ll += 9;
   }
}

void TerrainRender::renderChunkOutline(EmitChunk *chunk)
{
   U32 startXFIndex = mXFIndexCount;

   ChunkEdge *e0 = chunk->edge[0];
   ChunkEdge *e1 = chunk->edge[1];
   ChunkEdge *e2 = chunk->edge[2];
   ChunkEdge *e3 = chunk->edge[3];

   if(e0->xfIndex != mXFIndex)
   {
      if(!e0->xfIndex)
         fixEdge(e0, chunk->x, chunk->y + 4, 1, 0);
      addEdge(e0);
   }
   if(e1->xfIndex != mXFIndex)
   {
      if(!e1->xfIndex)
         fixEdge(e1, chunk->x + 4, chunk->y + 4, 0, -1);
      addEdge(e1);
   }
   if(e2->xfIndex != mXFIndex)
   {
      if(!e2->xfIndex)
         fixEdge(e2, chunk->x, chunk->y, 1, 0);
      addEdge(e2);
   }
   if(e3->xfIndex != mXFIndex)
   {
      if(!e3->xfIndex)
         fixEdge(e3, chunk->x, chunk->y + 4, 0, -1);
      addEdge(e3);
   }
   U32 p0 = emitCornerPoint(e0->p1);
   U32 p1 = emitCornerPoint(e0->p2);
   U32 p2 = emitCornerPoint(e2->p2);
   U32 p3 = emitCornerPoint(e2->p1);

   // build the interior points:
   U32 ip0 = constructPoint(chunk->x + 2, chunk->y + 2);
   F32 growFactor = chunk->growFactor;

   if(chunk->subDivLevel >= 1)
   {
      // just emit the fan for the whole square:
      S32 i;
      mXFIndexBuffer[mXFIndexCount++] = GL_TRIANGLE_FAN;
      U32 indexStart = mXFIndexCount++;
      mXFIndexBuffer[mXFIndexCount++] = ip0;

      mXFIndexBuffer[mXFIndexCount++] = p0;
      for(i = 0; i < e0->pointCount; i++)
         mXFIndexBuffer[mXFIndexCount++] = e0->pointIndex + i;

⌨️ 快捷键说明

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