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

📄 tsshapeinstance.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 5 页
字号:
void TSShapeInstance::render(S32 dl, F32 intraDL, const Point3F * objectScale)
{
   // if dl==-1, nothing to do
   if (dl==-1)
      return;

   AssertFatal(dl>=0 && dl<mShape->details.size(),"TSShapeInstance::render");

   S32 i;

   const TSDetail * detail = &mShape->details[dl];
   S32 ss = detail->subShapeNum;
   S32 od = detail->objectDetailNum;

   // set up static data
   setStatics(dl,intraDL,objectScale);

   // if we're a billboard detail, draw it and exit
   PROFILE_START(TSShapeInstanceRenderBillboards);
   if (ss<0)
   {
      if (!smNoRenderTranslucent)
         mShape->billboardDetails[dl]->render(mAlphaAlways ? mAlphaAlwaysValue : 1.0f, smRenderData.fogOn);
      PROFILE_END();
      return;
   }
   PROFILE_END();

   PROFILE_START(TSShapeInstanceMaterials);
   // set up animating ifl materials
   for (i=0; i<mIflMaterialInstances.size(); i++)
   {
      IflMaterialInstance  * iflMaterialInstance = &mIflMaterialInstances[i];
      const TSShape::IflMaterial * iflMaterial = iflMaterialInstance->iflMaterial;
      mMaterialList->remap(iflMaterial->materialSlot, iflMaterial->firstFrame + iflMaterialInstance->frame);
   }

   // decide how to use gl resources
   setupTexturing(dl,intraDL);

   // set up gl environment for drawing mesh materials
   TSMesh::initMaterials();
   PROFILE_END();

   S32 start;
   S32 end;

   bool supportBuffers = dglDoesSupportVertexBuffer();
   if (!supportBuffers || !renderMeshesX(ss,od))
   {
      // run through the meshes
      smRenderData.currentTransform = NULL;
      S32 start = smNoRenderNonTranslucent ? mShape->subShapeFirstTranslucentObject[ss] : mShape->subShapeFirstObject[ss];
      S32 end   = smNoRenderTranslucent ? mShape->subShapeFirstTranslucentObject[ss] : mShape->subShapeFirstObject[ss] + mShape->subShapeNumObjects[ss];
      for (i=start; i<end; i++)
         mMeshObjects[i].render(od,mMaterialList);
   }

   // if we have a matrix pushed, pop it now
   if (smRenderData.currentTransform)
      glPopMatrix();

   // restore gl state
   TSMesh::resetMaterials();

   // render detail maps using a second pass?
   if (twoPassDetailMap())
      renderDetailMap();

   // render environment map using second pass?
   if (twoPassEnvironmentMap())
      renderEnvironmentMap();

   if (!supportBuffers || !renderDecalsX(ss,od))
   {
      start = mShape->subShapeFirstDecal[ss];
      end   = mShape->subShapeNumDecals[ss] + start;
      if( smRenderData.renderDecals && !smNoRenderTranslucent && start<end)
      {
         // set up gl environment for decals...
         TSDecalMesh::initDecalMaterials();

         // render decals...
         smRenderData.currentTransform = NULL;
         for (i=start; i<end; i++)
            mDecalObjects[i].render(od,mMaterialList);

         // if we have a matrix pushed, pop it now
         if (smRenderData.currentTransform)
            glPopMatrix();

         // restore gl state
         TSDecalMesh::resetDecalMaterials();
      }
   }

   // render fog if 2-passing it
   if (twoPassFog())
      renderFog();

   // restore gl state
   TSMesh::resetMaterials();

   clearStatics();
}

bool TSShapeInstance::fillVB()
{
   S32 i,start,end,vb;

   if ((vb = mShape->mVertexBuffer) == -1)
   {
      // find out before we calc the needed buffer size if there are any free
      if (!glAvailableVertexBufferEXT())
      {
         PROFILE_END();
         return false;
      }

      GLsizei size = 0;

      start = mShape->subShapeFirstObject[0];
      end = mShape->subShapeFirstObject[0] + mShape->subShapeNumObjects[0];
      for (i = start; i < end; ++i)
         size += mMeshObjects[i].getSizeVB(size);

      mShape->mMorphable = false;
      for (i = start; i < end; ++i)
         if (mMeshObjects[i].hasMergeIndices())
         {
            mShape->mMorphable = true;
            break;
         }

      vb = mShape->mVertexBuffer = glAllocateVertexBufferEXT(size,GL_V12MTNVFMT_EXT,true);
      if (vb == -1)
      {
         PROFILE_END();
         return false;
      }
      if (mShape->mCallbackKey == -1)
         mShape->mCallbackKey = TextureManager::registerEventCallback(tsShapeTextureEventCB, mShape);

      // run through the meshes -- fill vertex buffer
      glLockVertexBufferEXT(vb,0);
      for (i = start; i < end; ++i)
         mMeshObjects[i].fillVB(vb,mMaterialList);
      glUnlockVertexBufferEXT(vb);
   }

   return true;
}

bool TSShapeInstance::renderMeshesX(S32 ss, S32 od)
{
   // TODO: find out why this case doesn't work
   if (smRenderData.vertexAlpha.current < 1.0)
      return false;

   PROFILE_START(TSShapeInstanceMeshes);

   S32 i,start,end,vb;

   if ((vb = mShape->mVertexBuffer) == -1)
   {
      // find out before we calc the needed buffer size if there are any free
      if (!glAvailableVertexBufferEXT())
      {
         PROFILE_END();
         return false;
      }

      GLsizei size = 0;

      start = mShape->subShapeFirstObject[0];
      end = mShape->subShapeFirstObject[0] + mShape->subShapeNumObjects[0];
      for (i = start; i < end; ++i)
         size += mMeshObjects[i].getSizeVB(size);

      mShape->mMorphable = false;
      for (i = start; i < end; ++i)
         if (mMeshObjects[i].hasMergeIndices())
         {
            mShape->mMorphable = true;
            break;
         }

      vb = mShape->mVertexBuffer = glAllocateVertexBufferEXT(size,GL_V12MTNVFMT_EXT,true);
      if (vb == -1)
      {
         PROFILE_END();
         return false;
      }
      if (mShape->mCallbackKey == -1)
         mShape->mCallbackKey = TextureManager::registerEventCallback(tsShapeTextureEventCB, mShape);

      // run through the meshes -- fill vertex buffer
      glLockVertexBufferEXT(vb,0);
      for (i = start; i < end; ++i)
         mMeshObjects[i].fillVB(vb,mMaterialList);
      glUnlockVertexBufferEXT(vb);
   }

   // run through the meshes
   start = smNoRenderNonTranslucent ? mShape->subShapeFirstTranslucentObject[ss] : mShape->subShapeFirstObject[ss];
   end   = smNoRenderTranslucent ? mShape->subShapeFirstTranslucentObject[ss] : mShape->subShapeFirstObject[ss] + mShape->subShapeNumObjects[ss];

   if (mShape->mMorphable)
   {
      PROFILE_START(TSShapeInstanceMorphVB);
      glLockVertexBufferEXT(vb,0);
      for (i = start; i < end; ++i)
         mMeshObjects[i].morphVB(vb,mShape->mPreviousMerge[i],od,mMaterialList);
      glUnlockVertexBufferEXT(vb);
      PROFILE_END();
   }

   smRenderData.currentTransform = NULL;
   PROFILE_START(TSShapeInstanceRenderVB);
   for (i = start; i < end; ++i)
      mMeshObjects[i].renderVB(vb,od,mMaterialList);
   PROFILE_END();

   PROFILE_END();
   return true;
}

bool TSShapeInstance::renderDecalsX(S32 ss, S32 od)
{
   return false;

   ss,od;
// I don't know why, but this doesn't quite work -- no time to fix
#if 0
   if (supportBuffers)
   {
      S32 i,start,end,vb;
      vb = mShape->mVertexBuffer;

      start = mShape->subShapeFirstDecal[ss];
      end   = mShape->subShapeNumDecals[ss] + start;
      if (smRenderData.renderDecals && start<end)
      {
         // set up gl environment for decals...
         TSDecalMesh::initDecalMaterials();

         // render decals...
         smRenderData.currentTransform = NULL;
         for (i=start; i<end; i++)
         {
            TSDecalMesh *decal0 = mDecalObjects[i].getDecalMesh(0);

            if (!decal0)
               continue;

            TSMesh *target0 = decal0->targetMesh;
            TSDecalMesh *decal;


            if (!target0 ||
                mDecalObjects[i].targetObject->visible <= 0.01f ||
                !(decal = mDecalObjects[i].getDecalMesh(od)) ||
                mDecalObjects[i].frame < 0 ||
                !decal->targetMesh ||
                decal->texgenS.empty() ||
                decal->texgenT.empty())
               continue;

            GLuint foffset = mDecalObjects[i].frame*target0->numMatFrames*target0->vertsPerFrame;

            glSetVertexBufferEXT(vb);
            glOffsetVertexBufferEXT(vb,target0->vbOffset+foffset);
            mDecalObjects[i].render(od,mMaterialList);
         }

         // if we have a matrix pushed, pop it now
         if (smRenderData.currentTransform)
            glPopMatrix();

         // restore gl state
         TSDecalMesh::resetDecalMaterials();
      }
   }
   else
#endif
}

void TSShapeInstance::setStatics(S32 dl, F32 intraDL, const Point3F * objectScale)
{
   ObjectInstance::smTransforms = mNodeTransforms.address();
   smRenderData.objectScale = objectScale;
   smRenderData.detailLevel = dl;
   smRenderData.intraDetailLevel = intraDL;
   smRenderData.alwaysAlpha = mAlphaAlways;
   smRenderData.alwaysAlphaValue = getAlphaAlwaysValue();
   smRenderData.balloonShape = mBalloonShape;
   smRenderData.balloonValue = getBalloonValue();

   smRenderData.useOverride = mUseOverrideTexture;
   smRenderData.override    = mOverrideTexture;

   S32 ss = mShape->details[dl].subShapeNum;
   S32 od = mShape->details[dl].objectDetailNum;
   TSMesh::smSaveVerts.setSize(mShape->mMergeBufferSize);
   TSMesh::smSaveTVerts.setSize(mShape->mMergeBufferSize);

   // If we have a billboard, skip the rest
   if (ss < 0)
      return;

   S32 start = smNoRenderNonTranslucent ? mShape->subShapeFirstTranslucentObject[ss] : mShape->subShapeFirstObject[ss];
   S32 end   = smNoRenderTranslucent ? mShape->subShapeFirstTranslucentObject[ss] : mShape->subShapeFirstObject[ss] + mShape->subShapeNumObjects[ss];

   for (S32 i=start; i<end; i++)
   {
      TSMesh * mesh = mMeshObjects[i].getMesh(od);
      if (mesh)
         mesh->saveMergeVerts();
   }
}

void TSShapeInstance::clearStatics()
{
   ObjectInstance::smTransforms = NULL;
   smRenderData.override = NULL;

   S32 ss = mShape->details[smRenderData.detailLevel].subShapeNum;
   S32 od = mShape->details[smRenderData.detailLevel].objectDetailNum;
   S32 start = smNoRenderNonTranslucent ? mShape->subShapeFirstTranslucentObject[ss] : mShape->subShapeFirstObject[ss];
   S32 end   = smNoRenderTranslucent ? mShape->subShapeFirstTranslucentObject[ss] : mShape->subShapeFirstObject[ss] + mShape->subShapeNumObjects[ss];
   for (S32 i=start; i<end; i++)
   {
      TSMesh * mesh = mMeshObjects[i].getMesh(od);
      if (mesh)
         mesh->restoreMergeVerts();
   }
}

void TSShapeInstance::setupTexturing(S32 dl, F32 intraDL)
{
   // first we'll decide what maps we want
   // then we'll decide how we can implement them (1-pass or 2-pass or not at all)

   // we need to set up these variables
   S32 & emapMethod = smRenderData.environmentMapMethod;
   S32 & dmapMethod = smRenderData.detailMapMethod;
   S32 & fogMethod  = smRenderData.fogMethod;
   S32 & dmapTE     = smRenderData.detailMapTE;
   S32 & emapTE     = smRenderData.environmentMapTE;
   S32 & baseTE     = smRenderData.baseTE;
   S32 & fogTE      = smRenderData.fogTE;

   baseTE = 0; // initially assume base texture will go in first TE

   // -------------------------------------------------
   // what do we want to do?

   bool wantEMap = ((mShape->mExportMerge && dl<=mShape->mSmallestVisibleDL/2) ||
                    (!mShape->mExportMerge && dl<=mMaxEnvironmentMapDL)) &&
                   mEnvironmentMapOn && (TextureObject*)mEnvironmentMap && mEnvironmentMapAlpha>0.01f;
   bool wantDMap = dl<=mMaxDetailMapDL;
   bool wantFog  = smRenderData.fogOn && !smSkipFog;
   smRenderData.detailMapAlpha = (dl<mMaxDetailMapDL || intraDL>0.5f) ? 1.0f : 2.0f * intraDL;
   smRenderData.environmentMapAlpha = mEnvironmentMapAlpha *
                                      (
                                        (((mShape->mExportMerge && dl<mShape->mSmallestVisibleDL/2) ||
                                            (!mShape->mExportMerge && dl<mMaxEnvironmentMapDL)) ||
                                           intraDL>0.5f) ? 1.0f : 2.0f * intraDL );
   smRenderData.environmentMapGLName = wantEMap ? mEnvironmentMap.getGLName() : 0;

   // -------------------------------------------------
   // what can we do?

   if (!dglDoesSupportARBMultitexture())
   {
      // we don't support multitexturing -- early out
      emapMethod = NO_ENVIRONMENT_MAP;
      dmapMethod = (wantDMap && mAllowTwoPassDetailMap) ? DETAIL_MAP_TWO_PASS : NO_DETAIL_MAP;
      fogMethod  = wantFog ? FOG_TWO_PASS : NO_FOG;

      return;
   }

   // how many texture environments (TE's) do we have?
   GLint numTE = 1, numUsedTE = 1;
   if (dglDoesSupportARBMultitexture())
      glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&numTE);

   // what we do with the TE's will depend on whether the following extension is supported
   if (dglDoesSupportTextureEnvCombine())
   {
      // environment map...
      if (wantEMap)
      {
         if (mAlphaIsReflectanceMap)
         {
            emapMethod = ENVIRONMENT_MAP_MULTI_1;
            emapTE = numUsedTE;
            numUsedTE++;
         }

⌨️ 快捷键说明

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