前面介绍类LLFeatureManager的声明部分,现在继续前面的内容进行分析,来看看它的实现代码,到底是怎么获取文本文件里的内容。先来看看它需要分析显示特性文件的内容是怎么样的,如下:
version 10
// NOTE: This is mostly identical to featuretable_mac.txt with a few differences
// Should be combined into one table
//
// Generates lists of feature mask that can be applied on top of each other.
//
//
// Begin comments
//
list <name>
//
Starts a feature list named <name>
//
<name> <available> <recommended>
//
<name> is the name of a feature
//
<available> is 0 or 1, whether the feature is available
//
<recommended> is an S32 which is the recommended value
//
// For now, the first list read sets up all of the default values
//
//
// All contains everything at their default settings for high end machines
// NOTE: All settings are set to the MIN of applied values, including 'all'!
//
list all
RenderVBO
1 1
RenderAniso
1 0
RenderAvatarMode
1 2
RenderAvatarVP
1 1
RenderDistance
1 128
RenderLighting
1 1
RenderObjectBump
1 1
RenderParticleCount 1
4096
RenderRippleWater
1 1
RenderTerrainDetail 1
2
VertexShaderEnable
1 1
UseOcclusion
1 1
RenderCubeMap
1 1
//
// Class 0 Hardware (Unknown or just old)
//
list Class0
VertexShaderEnable
1 0
RenderVBO
1 0
RenderDistance
1 64
RenderAvatarVP
1 0
RenderAvatarMode
1 0
RenderLighting
1 0
RenderObjectBump
1 0
RenderRippleWater
1 0
//
// Class 1 Hardware
//
list Class1
VertexShaderEnable
1 0
RenderVBO
1 1
RenderDistance
1 96
RenderAvatarVP
1 1
RenderAvatarMode
1 0
RenderLighting
1 0
RenderObjectBump
1 0
RenderRippleWater
1 0
//
// Class 2 Hardware (make it purty)
//
list Class2
VertexShaderEnable
1 1
RenderAvatarVP
1 1
RenderAvatarMode
1 1
RenderLighting
1 1
RenderObjectBump
1 1
RenderRippleWater
1 1
//
// Class 3 Hardware (make it purty)
//
list Class3
VertexShaderEnable
1 1
RenderAvatarVP
1 1
RenderAvatarMode
1 1
RenderLighting
1 1
RenderObjectBump
1 1
RenderRippleWater
1 1
//
// No Pixel Shaders available
//
list NoPixelShaders
VertexShaderEnable
0 0
RenderAvatarVP
0 0
//
// No Vertex Shaders available
//
list NoVertexShaders
VertexShaderEnable
0 0
RenderAvatarVP
0 0
//
// "Default" setups for safe, low, medium, high
//
list safe
RenderVBO
1 0
RenderAniso
1 0
RenderAvatarVP
0 0
RenderLighting
1 0
RenderParticleCount 1
1024
RenderTerrainDetail 1
0
list low
RenderVBO
1 0
RenderAniso
1 0
RenderLighting
1 0
list medium
RenderLighting
1 0
//
// CPU based feature masks
//
// 1Ghz or less (equiv)
list CPUSlow
RenderParticleCount 1
1024
//
// RAM based feature masks
//
list RAM256MB
RenderObjectBump
0 0
//
// Graphics card based feature masks
//
list OpenGLPre15
RenderVBO
1 0
list Intel
RenderVBO
1 0
RenderAniso
1 0
RenderLighting
1 0
RenderTerrainDetail 1
0
list GeForce2
RenderVBO
1 1
RenderAniso
1 0
RenderLighting
1 0
RenderParticleCount 1
2048
RenderTerrainDetail 1
0
list ATI_Mobility_Radeon_X3xx
VertexShaderEnable
1 0
list ATI_Mobility_Radeon_X6xx
VertexShaderEnable
1 0
现在就来查看怎么样使用代码来分析上面的文件内容,加载和分析文件代码如下:
#001 void LLFeatureManager::init()
#002 {
下面函数就是打开文件,并分析文件数据。
#003
// load the tables
#004
loadFeatureTables();
#005
下面函数加载
GPU的类内容。
#006
// get the gpu class
#007
loadGPUClass();
#008
下面函数应用所有需要显示特性。
#009
// apply the base masks, so we know if anything is disabled
#010
applyBaseMasks();
#011 }
接着来分析函数
loadFeatureTables,它的代码如下:
#001 BOOL LLFeatureManager::loadFeatureTables()
#002 {
#003
// *TODO - if I or anyone else adds something else to the skipped list
#004
// make this data driven. Put it in the feature table and parse it
#005
// correctly
插入几个集合。
#006
mSkippedFeatures.insert("RenderAnisotropic");
#007
mSkippedFeatures.insert("RenderGamma");
#008
mSkippedFeatures.insert("RenderVBOEnable");
#009
mSkippedFeatures.insert("RenderFogRatio");
#010
获取文件所在的目录。
#011
std::string data_path = gDirUtilp->getAppRODataDir();
#012
获取目录分隔符。
#013
data_path += gDirUtilp->getDirDelimiter();
#014
获取显示特性文件的名称。
#015
data_path += FEATURE_TABLE_FILENAME;
#016
#017
#018
char name[MAX_STRING+1]; /*Flawfinder: ignore*/
#019
#020
llifstream file;
#021
U32 version;
#022
用
API函数打开文件featuretable.txt。
#023
file.open(data_path.c_str()); /*Flawfinder: ignore*/
#024
判断文件是否打开成功。
#025
if (!file)
#026
{
#027
llwarns << "Unable to open feature table!" << llendl;
#028
return FALSE;
#029
}
#030
读取文件第一行的版本并检查。
#031
// Check file version
#032
file >> name;
#033
file >> version;
#034
if (strcmp(name, "version"))
#035
{
#036
llwarns << data_path << " does not appear to be a valid feature table!" << llendl;
#037
return FALSE;
#038
}
#039
保存文件的版本。
#040
mTableVersion = version;
#041
下面循环地分析这个文件直到文件结束。
#042
LLFeatureList *flp = NULL;
#043
while (!file.eof())
#044
{
#045
char buffer[MAX_STRING]; /*Flawfinder: ignore*/
#046
name[0] = 0;
#047
读取一个集合的名称。
#048
file >> name;
#049
跳过一些没用的行内容。
#050
if (strlen(name) >= 2 && /*Flawfinder: ignore*/
#051
name[0] == '/' &&
#052
name[1] == '/')
#053
{
#054
// This is a comment.
#055
file.getline(buffer, MAX_STRING);
#056
continue;
#057
}
#058
#059
if (strlen(name) == 0) /*Flawfinder: ignore*/
#060
{
#061
// This is a blank line
#062
file.getline(buffer, MAX_STRING);
#063
continue;
#064
}
#065
判断是否读取一个列表特性字段。
#066
if (!strcmp(name, "list"))
#067
{
分析到
list一段内容了。
#068
if (flp)
#069
{
#070
//flp->dump();
#071
}
读取
list段的名称。
#072
// It's a new mask, create it.
#073
file >> name;
#074
if (mMaskList.count(name))
#075
{
#076
llerrs << "Overriding mask " << name << ", this is invalid!" << llendl;
#077
}
#078
创建保存整个
list段的列表管理。
#079
flp = new LLFeatureList(name);
#080
mMaskList[name] = flp;
#081
}
#082
else
#083
{
一行一行地读取
list中的元素。
#084
if (!flp)
#085
{
#086
llerrs << "Specified parameter before <list> keyword!" << llendl;
#087
}
#088
S32 available;
#089
F32 recommended;
#090
file >> available >> recommended;
把一行的元素特征保存到创建的
list里。
#091
flp->addFeature(name, available, recommended);
#092
}
#093
}
下面关闭文件。
#094
file.close();
#095
#096
return TRUE;
#097 }
上面这段代码是先分析
eaturetable.txt的版本,然后依次分析list段内容,直到把所有list段内容分析完成,最后把分析出来的特性内容保存到类LLFeatureList列表里面,其它类需要使用时,就可以直接从这个LLFeatureList类里读取相应的内容出来,达到判断显示卡是否满足运行这个游戏的目的。