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

📄 gtexmanager.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 4 页
字号:
         {
            GBitmap * bmp2 = new GBitmap(w,h,false,GBitmap::RGBA);
            U8 * rgbBits = bmp->getWritableBits();
            U8 * alphaBits = bmpAlpha->getWritableBits();
            U8 * bmpBits = bmp2->getWritableBits();
            for (S32 wi=0; wi<w; wi++)
            {
               for (S32 hi=0; hi<h; hi++)
               {
                  bmpBits[wi*4 + hi*4*w + 0] = rgbBits[wi*3 + hi*3*w + 0];
                  bmpBits[wi*4 + hi*4*w + 1] = rgbBits[wi*3 + hi*3*w + 1];
                  bmpBits[wi*4 + hi*4*w + 2] = rgbBits[wi*3 + hi*3*w + 2];
                  bmpBits[wi*4 + hi*4*w + 3] = alphaBits[wi + hi*w];
               }
            }
            delete bmpAlpha;
            delete bmp;
            bmp = bmp2;
         }
      }
   }

   // If unable to load texture in current directory
   // look in the parent directory.  But never look in the root.
   fileNameBuffer[len] = 0;
   if (!bmp && recurse)
   {
      char *name = dStrrchr(fileNameBuffer, '/');
      if (name)
      {
         *name++ = 0;
         char *parent = dStrrchr(fileNameBuffer, '/');
         if (parent)
         {
            parent[1] = 0;
            dStrcat(fileNameBuffer, name);
            return loadBitmapInstance(fileNameBuffer);
         }
      }
   }
   return bmp;
}

//--------------------------------------

TextureObject *TextureManager::loadTexture(const char* textureName, TextureHandleType type, bool clampToEdge, bool checkOnly /* = false */)
{
   // Catch if we're trying to load a blank texture...
   if(!textureName || dStrlen(textureName) == 0)
      return NULL;

   textureName = StringTable->insert(textureName);

   TextureObject *ret = TextureDictionary::find(textureName, type, clampToEdge);

   GBitmap *bmp = NULL;

   if(!ret)
   {
      // Ok, no hit - is it in the current dir? If so then let's grab it
      // and use it.
      bmp = loadBitmapInstance(textureName, false);

      if(bmp)
         return registerTexture(textureName, bmp, type, clampToEdge);

      // Otherwise...
      // We want to check for previously loaded textures with the same
      // name in higher directories. loadBitmapInstance does this too
      // but we want to reuse the actual texture object, if possible,
      // not just load things many times into video memory!
      char fileNameBuffer[512];
      dStrcpy(fileNameBuffer, textureName);

      // If unable to load texture in current directory
      // look in the parent directory.  But never look in the root.
      char *name = dStrrchr(fileNameBuffer, '/');
      if (name)
      {
         *name++ = 0;
         char *parent = dStrrchr(fileNameBuffer, '/');
         if (parent)
         {
            parent[1] = 0;
            dStrcat(fileNameBuffer, name);
            ret = loadTexture(fileNameBuffer, type, clampToEdge, true);
         }
      }
   }

   if(ret)
      return ret;

   // If we're just checking, fail out so we eventually get around to
   // loading a real bitmap.
   if(checkOnly)
      return NULL;

   // Ok, no success so let's try actually loading a texture.
   bmp = loadBitmapInstance(textureName);

   if(!bmp)
   {
      Con::warnf("Could not locate texture: %s", textureName);
      return NULL;
   }

   return registerTexture(textureName, bmp, type, clampToEdge);
}


//--------------------------------------

void TextureHandle::setFilterNearest()
{
   if (object)
    {
        object->filterNearest = true;

        if(object->texGLName != 0)
        {
            glBindTexture(GL_TEXTURE_2D, object->texGLName);
           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
           glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        }
    }
}

void TextureHandle::setClamp(const bool c)
{
   if (object)
   {
      object->clamp = c;
      if (object->texGLName != 0)
      {
         glBindTexture(GL_TEXTURE_2D, object->texGLName);
         GLenum clamp;
         if (c)
            clamp = dglDoesSupportEdgeClamp() ? GL_CLAMP_TO_EDGE : GL_CLAMP;
         else
            clamp = GL_REPEAT;

         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
      }

      if (object->smallTexGLName != 0)
      {
         glBindTexture(GL_TEXTURE_2D, object->smallTexGLName);

         GLenum clamp;
         if (c)
            clamp = dglDoesSupportEdgeClamp() ? GL_CLAMP_TO_EDGE : GL_CLAMP;
         else
            clamp = GL_REPEAT;

         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
      }
   }
}

#define MAX_THOBJECT 1024
static TextureObject *thobject[MAX_THOBJECT];
static int htracked = 0;

void TextureHandle::lock()
{
   AssertFatal(TextureManager::isActive(), "TextureHandle::lock - TextureManager must be active to lock a texture.");

   if(object)
   {
#if defined(TORQUE_DEBUG)
        if (object->refCount>10000 || object->refCount<0) // some reasonable numbers.
        {
            for (int i=0; i<htracked; i++)
            {
                if (thobject[i]==object)
                    return;
            }
            Con::warnf(ConsoleLogEntry::Assert, "Texture refcount out of range: tex<%p> cnt<%d>", object, object->refCount);
            if (htracked<MAX_THOBJECT)
            {
                thobject[htracked] = object;
                htracked++;
            }
        }
        else
#endif
      object->refCount++;
    }
}

void TextureHandle::unlock()
{
   // Do nothing if the manager isn't active.
   if(!TextureManager::isActive())
      return;

   if(object)
   {
      object->refCount--;
      if (object->holding == false)
      {
         if(!object->refCount)
            TextureManager::freeTexture(object);
      }
      else
      {
#if defined(TORQUE_DEBUG)
         // dc - try outputting this error to console instead of assert box, and keep safe to continue.
         if (object->refCount<0)
         {
            Con::warnf(ConsoleLogEntry::Assert, "Texture holding out of balance: %d (0x%x)",
                                 object->refCount, object->refCount);
            object->refCount++; // put back for safety, in case we did something we shouldn't have.
         }
#else
         AssertISV(object->refCount >= 0, avar("Texture holding out of balance: %d (0x%x)",
                                               object->refCount, object->refCount));
#endif
      }

      object = NULL;
   }
}

void TextureHandle::refresh()
{
   TextureManager::refresh(object);
}

void TextureHandle::refresh(GBitmap* bmp)
{
   AssertFatal(object->type == TerrainTexture, "Error, only terrain textures may be refreshed in this manner!");
   TextureManager::refresh(object, bmp);
}

#ifdef TORQUE_GATHER_METRICS
F32 TextureManager::getResidentFraction()
{
   U32 resident = 0;
   U32 total    = 0;

   Vector<GLuint> names;

   TextureObject* pProbe = TextureDictionary::smTOList;
   while (pProbe != NULL) 
   {
      if (pProbe->texGLName != 0) 
      {
         total++;
         names.push_back(pProbe->texGLName);
      }

      pProbe = pProbe->next;
   }

   if (total == 0)
      return 1.0f;

   Vector<GLboolean> isResident;
   isResident.setSize(names.size());

   glAreTexturesResident(names.size(), names.address(), isResident.address());
   for (U32 i = 0; i < names.size(); i++)
      if (isResident[i] == GL_TRUE)
         resident++;

   return (F32(resident) / F32(total));
}
#endif

//-------------------------------------------------------------------------

ChunkedTextureObject *gChunkedTextureList = NULL;

ChunkedTextureObject* ChunkedTextureManager::loadTexture(const char *textureName)
{
   if(!textureName)
      return NULL;
   StringTableEntry tName = StringTable->insert(textureName);

   for(ChunkedTextureObject *walk = gChunkedTextureList; walk; walk = walk->next)
      if(walk->texFileName == tName)
         return walk;
   GBitmap *bmp = TextureManager::loadBitmapInstance(textureName);
   if(!bmp)
      return NULL;
   return registerTexture(textureName, bmp, false);
}

ChunkedTextureObject* ChunkedTextureManager::registerTexture(const char *textureName, GBitmap *data, bool keep)
{
   ChunkedTextureObject *ret = NULL;
   StringTableEntry tName = NULL;

   if(textureName)
   {
      tName = StringTable->insert(textureName);
      for(ChunkedTextureObject *walk = gChunkedTextureList; walk; walk = walk->next)
      {
         if(walk->texFileName == tName)
         {
            ret = walk;
            break;
         }
      }
   }

   if(ret && ret->bitmap)
   {
      delete ret->bitmap;
      ret->bitmap = data;
   }
   else
   {
      ret = new ChunkedTextureObject;
      ret->bitmap = data;
      ret->texFileName = tName;
      ret->next = gChunkedTextureList;
      gChunkedTextureList = ret;
      ret->texWidthCount = (data->getWidth() + 255) >> 8;
      ret->texHeightCount = (data->getHeight() + 255) >> 8;
      ret->width = data->getWidth();
      ret->height = data->getHeight();
      ret->textureHandles = NULL;
      ret->refCount = 0;
   }

   refresh(ret);

   if(!keep)
   {
      delete ret->bitmap;
      ret->bitmap = NULL;
   }

   return ret;
}

void ChunkedTextureManager::freeTexture(ChunkedTextureObject *to)
{
   // remove it from the linked list

   for(ChunkedTextureObject **walk = &gChunkedTextureList; *walk; walk = &((*walk)->next))
   {
      if(*walk == to)
      {
         *walk = to->next;
         delete[] to->textureHandles;
         delete to->bitmap;
         return;
      }
   }
}

void ChunkedTextureManager::refresh(ChunkedTextureObject *to)
{
   if(!to->bitmap)
      return;

   if(to->textureHandles)
   {
      delete[] to->textureHandles;
      to->textureHandles = NULL;
   }

   to->textureHandles = new TextureHandle[to->texWidthCount * to->texHeightCount];

   for(U32 j = 0; j < to->texHeightCount; j++)
   {
      U32 y = j * 256;
      U32 height = getMin(to->bitmap->getHeight() - y, U32(256));

      for(U32 i = 0; i < to->texWidthCount; i++)
      {
         U32 index = j * to->texWidthCount + i;
         U32 x = i * 256;
         U32 width = getMin(to->bitmap->getWidth() - x, U32(256));

         GBitmap *tempBitmap = new GBitmap(width, height, false, to->bitmap->getFormat());
         for(U32 lp = 0; lp < height; lp++)
         {
            const U8 *src = to->bitmap->getAddress(x, y + lp);
            U8 *dest = tempBitmap->getAddress(0, lp);
            dMemcpy(dest, src, width * to->bitmap->bytesPerPixel);
         }
         to->textureHandles[index] = TextureHandle(NULL, tempBitmap, BitmapTexture, true);

      }
   }
}

void ChunkedTextureManager::makeZombie()
{
   for(ChunkedTextureObject *walk = gChunkedTextureList; walk; walk = walk->next)
   {
      delete[] walk->textureHandles;
      walk->textureHandles = NULL;
   }
}

void ChunkedTextureManager::resurrect()
{
   for(ChunkedTextureObject *walk = gChunkedTextureList; walk; walk = walk->next)
   {
      GBitmap *bmp = walk->bitmap;
      if(!bmp)
         walk->bitmap = TextureManager::loadBitmapInstance(walk->texFileName);

      refresh(walk);

      if(!bmp)
      {
         delete walk->bitmap;
         walk->bitmap = NULL;
      }
   }
}

TextureHandle ChunkedTextureHandle::getSubTexture(U32 x, U32 y)
{
   if(!object || !object->textureHandles)
      return NULL;
   return object->textureHandles[x + y * object->texWidthCount];
}


void ChunkedTextureHandle::lock()
{
   if(object)
      object->refCount++;
}

void ChunkedTextureHandle::unlock()
{
   if(object)
   {
      object->refCount--;
      if(object->refCount == 0)
         ChunkedTextureManager::freeTexture(object);
   }
}

⌨️ 快捷键说明

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