📄 gtexmanager.cc
字号:
if ((to->type == InteriorTexture || to->type == MeshTexture) &&
pDL->getNumMipLevels() > 4)
{
//
if (!to->smallTexGLName)
glGenTextures(1,&to->smallTexGLName);
glBindTexture(GL_TEXTURE_2D, to->smallTexGLName);
glBindTexture(GL_TEXTURE_2D, to->smallTexGLName);
if (pDL->getFormat() == GBitmap::Palettized)
{
glColorTableEXT(GL_TEXTURE_2D,
pDL->getPalette()->getPaletteType() == GPalette::RGB ? GL_RGB : GL_RGBA,
256,
GL_RGBA,
GL_UNSIGNED_BYTE,
pDL->getPalette()->getColors());
}
if (sgDisableSubImage)
{
for (U32 i = 4; i < maxDownloadMip; i++)
{
glTexImage2D(GL_TEXTURE_2D,
i - 4,
destFormat,
pDL->getWidth(i), pDL->getHeight(i),
0,
sourceFormat,
byteFormat,
pDL->getBits(i));
}
}
else
{
for (U32 i = 4; i < maxDownloadMip; i++)
{
glTexSubImage2D(GL_TEXTURE_2D,
i - 4,
0, 0,
pDL->getWidth(i), pDL->getHeight(i),
sourceFormat,
byteFormat,
pDL->getBits(i));
}
}
}
else
{
if (to->smallTexGLName != 0)
glDeleteTextures(1, &to->smallTexGLName);
to->smallTexGLName = 0;
}
if(pDL != pBitmap)
delete pDL;
}
//--------------------------------------
bool TextureManager::createGLName(GBitmap* pBitmap,
bool clampToEdge,
U32 firstMip,
TextureHandleType type,
TextureObject* to)
{
if (!(gDGLRender || sgResurrect))
return 0;
glGenTextures(1, &to->texGLName);
glBindTexture(GL_TEXTURE_2D, to->texGLName);
U32 sourceFormat, destFormat, byteFormat;
getSourceDestByteFormat(pBitmap, &sourceFormat, &destFormat, &byteFormat);
GBitmap *pDL = createPaddedBitmap(pBitmap);
U32 maxDownloadMip = pDL->getNumMipLevels();
if (type == BitmapTexture ||
type == BitmapKeepTexture ||
type == BitmapNoDownloadTexture)
{
maxDownloadMip = firstMip + 1;
}
if (pDL->getFormat() == GBitmap::Palettized)
{
glColorTableEXT(GL_TEXTURE_2D,
pDL->getPalette()->getPaletteType() == GPalette::RGB ? GL_RGB : GL_RGBA,
256,
GL_RGBA,
GL_UNSIGNED_BYTE,
pDL->getPalette()->getColors());
}
for (U32 i = firstMip; i < maxDownloadMip; i++)
{
glTexImage2D(GL_TEXTURE_2D,
i - firstMip,
destFormat,
pDL->getWidth(i), pDL->getHeight(i),
0,
sourceFormat,
byteFormat,
pDL->getBits(i));
}
if(to->filterNearest)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if(pBitmap->getNumMipLevels() != 1 &&
type != BitmapTexture &&
type != BitmapKeepTexture &&
type != BitmapNoDownloadTexture)
{
if (sgTextureTrilinear || type == BumpTexture || type == InvertedBumpTexture)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
if (dglDoesSupportTexAnisotropy())
{
F32 val = 1.0f + sgTextureAnisotropy * dglGetMaxAnisotropy();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, val);
}
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}
U32 clamp = GL_REPEAT;
if (clampToEdge)
clamp = dglDoesSupportEdgeClamp() ? GL_CLAMP_TO_EDGE : GL_CLAMP;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
if ((type == InteriorTexture || type == MeshTexture) &&
(pDL->getNumMipLevels() - firstMip) > 4)
{
glGenTextures(1, &to->smallTexGLName);
glBindTexture(GL_TEXTURE_2D, to->smallTexGLName);
if (pDL->getFormat() == GBitmap::Palettized)
{
glColorTableEXT(GL_TEXTURE_2D,
pDL->getPalette()->getPaletteType() == GPalette::RGB ? GL_RGB : GL_RGBA,
256,
GL_RGBA,
GL_UNSIGNED_BYTE,
pDL->getPalette()->getColors());
}
for (U32 i = firstMip + 4; i < maxDownloadMip; i++)
{
glTexImage2D(GL_TEXTURE_2D,
i - (firstMip + 4),
destFormat,
pDL->getWidth(i), pDL->getHeight(i),
0,
sourceFormat,
byteFormat,
pDL->getBits(i));
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (sgTextureTrilinear)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
if (dglDoesSupportTexAnisotropy())
{
F32 val = 1.0f + sgTextureAnisotropy * dglGetMaxAnisotropy();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, val);
}
U32 clamp = GL_REPEAT;
if (clampToEdge)
clamp = dglDoesSupportEdgeClamp() ? GL_CLAMP_TO_EDGE : GL_CLAMP;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
}
if(pDL != pBitmap)
delete pDL;
return to->texGLName != 0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
TextureObject* TextureManager::registerTexture(const char* textureName, const GBitmap* data, bool clampToEdge)
{
//WARNING: since there's no texture type here, there's no way to tell
//if it is an inverted bump texture, which would cause it NOT to invert!
//but, this appears to only be used for RegisteredTextures
//so it shouldn't make a difference.
// if there is no textureName, it isn't inserted into the hash
// table... merely tracked by the texture manager
TextureObject *ret = NULL;
if(textureName)
{
textureName = StringTable->insert(textureName);
ret = TextureDictionary::find(textureName, RegisteredTexture, clampToEdge);
}
if(ret)
{
// Crucial conditionals for the flush case...
if (ret->bitmap != data)
delete ret->bitmap;
if (ret->texGLName)
glDeleteTextures(1, (const GLuint*)&ret->texGLName);
if (ret->smallTexGLName)
glDeleteTextures(1, (const GLuint*)&ret->smallTexGLName);
ret->texGLName = 0;
ret->smallTexGLName = 0;
#ifdef TORQUE_GATHER_METRICS
AssertFatal(ret->textureSpace <= smTextureSpaceLoaded, "Error, that shouldn't happen!");
smTextureSpaceLoaded -= ret->textureSpace;
ret->textureSpace = 0;
#endif
}
else
{
ret = new TextureObject;
ret->texFileName = textureName;
ret->texGLName = 0;
ret->smallTexGLName = 0;
ret->refCount = 0;
ret->type = RegisteredTexture;
ret->holding = false;
ret->filterNearest = false;
TextureDictionary::insert(ret);
}
ret->bitmap = (GBitmap *) data;
ret->bitmapWidth = data->getWidth();
ret->bitmapHeight = data->getHeight();
ret->texWidth = getNextPow2(ret->bitmapWidth);
ret->texHeight = getNextPow2(ret->bitmapHeight);
ret->downloadedWidth = ret->texWidth;
ret->downloadedHeight = ret->texHeight;
ret->clamp = clampToEdge;
#ifdef TORQUE_GATHER_METRICS
ret->textureSpace = ret->downloadedWidth * ret->downloadedHeight;
smTextureSpaceLoaded += ret->textureSpace;
#endif
createGLName(ret->bitmap, clampToEdge, 0, ret->type, ret);
return ret;
}
//--------------------------------------
TextureObject* TextureManager::registerTexture(const char* textureName, GBitmap* bmp, TextureHandleType type, bool clampToEdge)
{
//Get this done and out of the way first - if it's an inverted texture,
//then invert it! Do it in this function because resurrect() calls this directly
if( type == InvertedBumpTexture )
{
// Get pixel address (0,0) of bitmap data for mip level 0.
U8* pImageBits = bmp->getAddress(0,0,0);
// Fetch total pixel count for bitmap.
U32 PixelCount = bmp->getWidth(0) * bmp->getHeight(0) * bmp->bytesPerPixel;
// Invert only the RGB components of the bitmap (leave alpha alone).
for (U32 index = 0; index < PixelCount; ++index)
pImageBits[index] ^= 0x00ffffff;
}
// In order to get the right blending, all of the pixels have to be at half intensity.
// Would normally do this using glPixelTransferf(), but that function is not
// supported in the D3D wrapper.
// BUG: detect the case where we're using the D3D wrapper, and use this slower code only in that case.
if (type == BumpTexture || type == InvertedBumpTexture)
{
U8* pImageBits = bmp->getAddress(0,0,0);
U32 PixelCount = bmp->getWidth(0) * bmp->getHeight(0) * bmp->bytesPerPixel;
for (U32 index = 0; index < PixelCount; index++)
pImageBits[index] /= 2;
}
TextureObject *ret = NULL;
if(textureName)
{
textureName = StringTable->insert(textureName);
ret = TextureDictionary::find(textureName, type, clampToEdge);
}
if(ret)
{
// Crucial conditionals for the flush case...
if (ret->bitmap != bmp)
delete ret->bitmap;
if (ret->texGLName)
glDeleteTextures(1, (const GLuint*)&ret->texGLName);
if (ret->smallTexGLName)
glDeleteTextures(1, (const GLuint*)&ret->smallTexGLName);
ret->texGLName = 0;
ret->smallTexGLName = 0;
#ifdef TORQUE_GATHER_METRICS
AssertFatal(ret->textureSpace <= smTextureSpaceLoaded, "Error, that shouldn't happen!");
smTextureSpaceLoaded -= ret->textureSpace;
ret->textureSpace = 0;
#endif
}
else
{
ret = new TextureObject;
ret->texFileName = textureName;
ret->texGLName = 0;
ret->smallTexGLName = 0;
ret->refCount = 0;
ret->type = type;
ret->filterNearest= false;
TextureDictionary::insert(ret);
}
ret->bitmap = bmp;
ret->bitmapWidth = bmp->getWidth();
ret->bitmapHeight = bmp->getHeight();
ret->texWidth = getNextPow2(ret->bitmapWidth);
ret->texHeight = getNextPow2(ret->bitmapHeight);
ret->clamp = clampToEdge;
ret->holding = (type == MeshTexture) && ENABLE_HOLDING;
if ((ret->type == DetailTexture || ret->type == BumpTexture || ret->type == InvertedBumpTexture) &&
bmp->getFormat() != GBitmap::Palettized)
bmp->extrudeMipLevels();
else if (ret->type != TerrainTexture &&
ret->type != BitmapTexture &&
ret->type != BitmapKeepTexture &&
ret->type != BitmapNoDownloadTexture &&
bmp->getFormat() != GBitmap::Palettized)
bmp->extrudeMipLevels(ret->type==ZeroBorderTexture);
if(!ret->texGLName)
{
U32 firstMip = 0;
if (ret->bitmap->getNumMipLevels() > 1 &&
type != DetailTexture &&
type != BumpTexture &&
type != InvertedBumpTexture &&
type != TerrainTexture &&
type != BitmapTexture &&
type != BitmapKeepTexture &&
type != BitmapNoDownloadTexture)
{
if (type == SkyTexture)
{
firstMip = getMin(sgSkyTextureDetailLevel, ret->bitmap->getNumMipLevels() - 1);
}
else if (type == InteriorTexture)
{
firstMip = getMin(sgInteriorTextureDetailLevel, ret->bitmap->getNumMipLevels() - 1);
}
else
{
firstMip = getMin(sgTextureDetailLevel, ret->bitmap->getNumMipLevels() - 1);
}
}
ret->downloadedWidth = ret->bitmapWidth >> firstMip;
ret->downloadedHeight = ret->bitmapHeight >> firstMip;
if (ret->downloadedWidth == 0) ret->downloadedWidth = 1;
if (ret->downloadedHeight == 0) ret->downloadedHeight = 1;
#ifdef TORQUE_GATHER_METRICS
ret->textureSpace = 0;
for (U32 i = firstMip; i < ret->bitmap->getNumMipLevels(); i++)
ret->textureSpace += ret->bitmap->getWidth(i) * ret->bitmap->getHeight(i);
smTextureSpaceLoaded += ret->textureSpace;
#endif
if(ret->type != BitmapNoDownloadTexture)
createGLName(bmp, clampToEdge, firstMip, ret->type, ret);
}
if (ret->type == BitmapKeepTexture || ret->type == BitmapNoDownloadTexture)
{
// do nothing
}
else if (ret->type == TerrainTexture)
{
// Don't delete the bitmap
ret->bitmap = NULL;
}
else
{
delete ret->bitmap;
ret->bitmap = NULL;
}
return ret;
}
//--------------------------------------
GBitmap *TextureManager::loadBitmapInstance(const char *textureName, bool recurse /* = true */)
{
char fileNameBuffer[512];
dStrcpy(fileNameBuffer, textureName);
GBitmap *bmp = NULL;
// Loop through the supported extensions to find the file.
U32 len = dStrlen(fileNameBuffer);
for (U32 i = 0; i < EXT_ARRAY_SIZE && bmp == NULL; i++)
{
if (sgForcePalettedTexture == true && dglDoesSupportPalettedTexture())
dStrcpy(fileNameBuffer + len, extArray_8[i]);
else
dStrcpy(fileNameBuffer + len, extArray[i]);
bmp = (GBitmap*)ResourceManager->loadInstance(fileNameBuffer);
// CAF: if a jpg, and RGB, look for file.alpha.jpg as alpha channel
if ( (!sgForcePalettedTexture || !dglDoesSupportPalettedTexture()) && !dStricmp(extArray[i],".jpg") && bmp && bmp->getFormat()==GBitmap::RGB)
{
dStrcpy(fileNameBuffer + len, ".alpha.jpg");
GBitmap * bmpAlpha = (GBitmap*)ResourceManager->loadInstance(fileNameBuffer);
S32 w = bmp->getWidth();
S32 h = bmp->getHeight();
if (bmpAlpha && bmpAlpha->getWidth() == w && bmpAlpha->getHeight() == h && bmpAlpha->bytesPerPixel==1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -