📄 terrdata.cc
字号:
pBitmap = TextureManager::loadBitmapInstance(fileBuf);
if(pBitmap)
mMaterialFileName[i] = StringTable->insert(fileBuf, true);
if(!pBitmap)
{
// Try the default..
Con::errorf("Missing terrain texture: %s",fileBuf);
matsValid = false;
dStrcpyl(fileBuf, sizeof(fileBuf), mFile.getFilePath(), "/","default",NULL);
pBitmap = TextureManager::loadBitmapInstance(fileBuf);
if(!pBitmap)
pBitmap = new GBitmap(256,256);
}
}
pBitmap->extrudeMipLevels();
tweakTerrainBmp(pBitmap);
// Submit as material for group i
const U8* pMipmaps[5];
for (U32 j = 0; j < 5; j++)
pMipmaps[j] = pBitmap->getBits(j);
mBlender->addSourceTexture(i, pMipmaps);
delete pBitmap;
}
// ok, if the material list load failed...
// if this is a local connection, we'll assume that's ok
// and just have white textures...
// otherwise we want to return false.
return matsValid || bool(mServerObject);
}
void TerrainBlock::getMaterialAlpha(Point2I pos, U8 alphas[MaterialGroups])
{
pos.x &= BlockMask;
pos.y &= BlockMask;
U32 offset = pos.x + pos.y * BlockSize;
for(S32 i = 0; i < MaterialGroups; i++)
{
U8 *map = mFile->mMaterialAlphaMap[i];
if(map)
alphas[i] = map[offset];
else
alphas[i] = 0;
}
}
void TerrainBlock::setMaterialAlpha(Point2I pos, const U8 alphas[MaterialGroups])
{
pos.x &= BlockMask;
pos.y &= BlockMask;
U32 offset = pos.x + pos.y * BlockSize;
for(S32 i = 0; i < MaterialGroups; i++)
{
U8 *map = mFile->mMaterialAlphaMap[i];
if(map)
map[offset] = alphas[i];
}
}
S32 TerrainBlock::getMaterialAlphaIndex(const char *materialName)
{
for (S32 i = 0; i < MaterialGroups; i++)
if (mMaterialFileName[i] && *mMaterialFileName[i] && !dStricmp(materialName, mMaterialFileName[i]))
return i;
// ok, it wasn't in the list
// see if we can add it:
for (S32 i = 0; i < MaterialGroups; i++)
{
if (!mMaterialFileName[i] || !*mMaterialFileName[i])
{
mMaterialFileName[i] = StringTable->insert(materialName);
mFile->mMaterialAlphaMap[i] = new U8[TerrainBlock::BlockSize * TerrainBlock::BlockSize];
dMemset(mFile->mMaterialAlphaMap[i], 0, TerrainBlock::BlockSize * TerrainBlock::BlockSize);
buildMaterialMap();
return i;
}
}
return -1;
}
//------------------------------------------------------------------------------
void TerrainBlock::refreshMaterialLists()
{
}
//------------------------------------------------------------------------------
void TerrainBlock::onEditorEnable()
{
// need to load in the material base material lists
if(isClientObject())
refreshMaterialLists();
}
void TerrainBlock::onEditorDisable()
{
}
//------------------------------------------------------------------------------
bool TerrainBlock::onAdd()
{
if(!Parent::onAdd())
return false;
/// TGE_Collision, RPG模式下,把地形设为原点
#ifdef TGE_RPG
if(g_pTerrainBlock == 0)
g_pTerrainBlock = this;
setPosition(Point3F(0,0, 0));
/// TGE_TerrainScene
Resource<TerrainScene> terrScene = ResourceManager->load(mSceneFileName);
if(!bool(terrScene))
{
//if(isClientObject())
// NetConnection::setLastError("场景数据丢失,但还可以进入游戏...: %s", mSceneFileName);
if(mSceneFileName && mSceneFileName[0] && !dIsspace(mSceneFileName[0]))
{
TerrainScene* sceneNew = new TerrainScene();
ResourceManager->add(mSceneFileName, sceneNew);
terrScene = ResourceManager->load(mSceneFileName);
terrScene->initScene(this);
}
else
{
AssertFatal(0,"未指定场景数据...");
return false;
}
}
if(bool(terrScene))
setScene(terrScene);
#else
setPosition(Point3F(-squareSize * (BlockSize >> 1), -squareSize * (BlockSize >> 1), 0));
#endif
Resource<TerrainFile> terr = ResourceManager->load(mTerrFileName, true);
if(!bool(terr))
{
if(isClientObject())
NetConnection::setLastError("You are missing a file needed to play this mission: %s", mTerrFileName);
return false;
}
setFile(terr);
MaterialPropertyMap* pMatMap = static_cast<MaterialPropertyMap*>(Sim::findObject("MaterialPropertyMap"));
for (int i = 0; i < TerrainBlock::MaterialGroups; i++)
{
StringTableEntry fn = mMaterialFileName[i];
if (fn != NULL)
{
if(!dStrncmp(fn, "terrain.", 8))
fn += 8;
char nameBuff[512];
dStrcpy(nameBuff, mTerrFileName);
const char *p = dStrrchr(fn, '/');
if(p)
p++;
else
p = nameBuff;
mMPMIndex[i] = pMatMap->getIndexFromName( p );
}
else
mMPMIndex[i] = -1;
}
setGlobalBounds();
resetWorldBox();
setRenderTransform(mObjToWorld);
if (isClientObject())
{
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
if(mCRC != terr.getCRC())
{
NetConnection::setLastError("Your terrain file doesn't match the version that is running on the server.");
return false;
}
#endif
if(mDetailTextureName && mDetailTextureName[0])
mDetailTextureHandle = TextureHandle(mDetailTextureName, DetailTexture);
if (mBumpTextureName && mBumpTextureName[0])
{
mBumpTextureHandle = TextureHandle(mBumpTextureName, BumpTexture);
if (!mBumpTextureHandle.getGLName())
Con::errorf("Error: missing bump map texture\n%s", mBumpTextureName);
else
mInvertedBumpTextureHandle = TextureHandle(mBumpTextureName, InvertedBumpTexture);
}
lightMap = new GBitmap(LightmapSize, LightmapSize, false, GBitmap::RGB5551);
if (!buildMaterialMap())
return false;
mTextureCallbackKey = TextureManager::registerEventCallback(terrainTextureEventCB, this);
mDynLightTexture = TextureHandle("common/lighting/lightFalloffMono", BitmapTexture, true);
if (dglDoesSupportVertexBuffer())
mVertexBuffer = glAllocateVertexBufferEXT(VertexBufferSize,GL_V12MTVFMT_EXT,true);
else
mVertexBuffer = -1;
}
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
else
mCRC = terr.getCRC();
#endif
addToScene();
if(!unpackEmptySquares())
return(false);
return true;
}
#ifdef TGE_RPG /// TGE_Map
//--------------------------------------------
void TerrainBlock::setDetailTextureHandle(StringTableEntry sFileName)
{
if(sFileName && sFileName[0])
{
mDetailTextureName = sFileName;
if(isServerObject())
setMaskBits(TextureMask);
#ifdef TGE_RPGCLIENT2 /// TGE_RPGClient2
// make sure detail and bump textures are set correctly
if(sFileName && sFileName[0])
mDetailTextureHandle = TextureHandle(sFileName, DetailTexture);
else
mDetailTextureHandle = NULL;
#endif
}
}
void TerrainBlock::setBumpTextureHandle(StringTableEntry sFileName)
{
if (sFileName && sFileName[0])
{
mBumpTextureName = sFileName;
if(isServerObject())
setMaskBits(TextureMask);
#ifdef TGE_RPGCLIENT2 /// TGE_RPGClient2
// make sure detail and bump textures are set correctly
if(sFileName && sFileName[0])
{
mBumpTextureHandle = TextureHandle(sFileName, BumpTexture);
mInvertedBumpTextureHandle = TextureHandle(sFileName, InvertedBumpTexture);
}
else
{
mBumpTextureHandle = NULL;
mInvertedBumpTextureHandle = NULL;
}
#endif
}
}
#endif
//--------------------------------------
void TerrainBlock::onRemove()
{
#ifdef TGE_RPG /// TGE_Collision
g_pTerrainBlock = 0;
#endif
delete mBlender;
mBlender = NULL;
removeFromScene();
if (mVertexBuffer != -1)
{
if (dglDoesSupportVertexBuffer())
glFreeVertexBufferEXT(mVertexBuffer);
else
AssertFatal(false,"Vertex buffer should have already been freed!");
mVertexBuffer = -1;
}
TerrainRender::flushCache();
TextureManager::unregisterEventCallback(mTextureCallbackKey);
Parent::onRemove();
}
//--------------------------------------
void TerrainBlock::processTextureEvent(const U32 eventCode)
{
if (eventCode == TextureManager::BeginZombification) {
// Delete any textures we have built from the dmls...
TerrainRender::flushCache();
for(S32 i = 0; i < 16; i++)
baseTextures[i] = NULL;
if (mVertexBuffer != -1)
{
if (dglDoesSupportVertexBuffer())
glFreeVertexBufferEXT(mVertexBuffer);
else
AssertFatal(false,"Vertex buffer should have already been freed!");
mVertexBuffer = -1;
}
} else if (eventCode == TextureManager::CacheResurrected) {
if (dglDoesSupportVertexBuffer())
mVertexBuffer = glAllocateVertexBufferEXT(VertexBufferSize,GL_V12MTVFMT_EXT,true);
}
}
//--------------------------------------------------------------------------
bool TerrainBlock::prepRenderImage(SceneState* state, const U32 stateKey,
const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
if (isLastState(state, stateKey))
return false;
setLastState(state, stateKey);
// This should be sufficient for most objects that don't manage zones, and
// don't need to return a specialized RenderImage...
bool render = false;
if (state->isTerrainOverridden() == false)
render = state->isObjectRendered(this);
else
render = true;
if (render == true) {
SceneRenderImage* image = new SceneRenderImage;
image->obj = this;
image->sortType = SceneRenderImage::Terrain;
state->insertRenderImage(image);
}
return false;
}
void TerrainBlock::buildChunkDeviance(S32 x, S32 y)
{
mFile->buildChunkDeviance(x, y);
}
void TerrainBlock::buildGridMap()
{
mFile->buildGridMap();
}
//------------------------------------------------------------------------------
void TerrainBlock::setTransform(const MatrixF & mat)
{
Parent::setTransform(mat);
// Since the terrain is a static object, it's render transform changes 1 to 1
// with it's collision transform
setRenderTransform(mat);
}
void TerrainBlock::renderObject(SceneState* state, SceneRenderImage*)
{
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");
RectI viewport;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
dglGetViewport(&viewport);
if (state->isTerrainOverridden() == false)
{
state->setupObjectProjection(this);
}
else
{
state->setupBaseProjection();
}
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
dglMultMatrix(&mRenderObjToWorld);
glScalef(mObjScale.x, mObjScale.y, mObjScale.z);
TerrainRender::renderBlock(this, state);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
dglSetViewport(viewport);
dglSetCanonicalState();
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -