游戏中的光的种类有三种:
环境光,平行光,点源光
灯光种类的实现使用了枚举表示,灯光定义的结构体把所有的灯光属性都集合在一起,根据不同的灯光属性,填充不同的参数.
结构体表示如下:
struct ELight
{
EInt id; //灯光的ID,全局唯一
EBool lightOn; //设置灯光开 默认开启
LIGHT_TYPE lightType; //灯光的类型
EFloat power; //灯光强度 默认1.0f
EFloat shadowFactor; //灯光背面强度 默认0.05f
EColor ambient; //灯光的环境色 默认(255,255,255)
EColor diffuse; //灯光漫反射颜色 默认(255,255,255)
EColor specular; //灯光高光颜色
EVector4D position; //灯光世界坐标位置 默认(0,0,0)
EVector4D direction; //灯光朝向 默认(0,0,1)
EVector4D transPosition; //灯光摄像机坐标系位置
EVector4D transDirection; //摄像机坐标系光源朝向
EFloat kc, kl, kq; //衰减因子
EFloat spot_inner; //聚灯光内锥角 默认(45.0f)
EFloat spot_outer; //内聚灯光外锥角 默认(60.0f)
EFloat pf; //聚灯光指数因子
ELight(EInt lightId, LIGHT_TYPE type); //构造函数
};
游戏中的灯光很多,为统一管理,可以使用vector
可以通过灯光ID获取不同的灯光
灯光的创建函数如下:
EInt CreateLight(LIGHT_TYPE lightType) {
if (GLights == NULL)
GLights = new std::vector<ELight *>; //如果列表无初始化 则初始化一个列表
if ((EInt)GLights->size() > MAX_LIGHTS) //如果达到上限 则无法继续添加灯光
return -1;
EInt id = (EInt)GLights->size();
GLights->push_back(new ELight(id, lightType)); //插入一个vector
return id;
}
根据列表获取一个灯光:
如果灯光列表不存在,或是列表已满,则无法获取灯光
灯光ID不在范围内也要排除
//获得一个灯光
ELight* GetLight(EInt id) {
if (GLights == NULL || (EInt)GLights->size() > MAX_LIGHTS || id < 0 || id >(EInt)GLights->size() - 1)
return NULL;
return GLights->at(id);
}
删除所有灯光:
通过vector的迭代器遍历所有灯光并删除
//删除所有灯光
void DestoryAllLight() {
for(LightItr itr = GLights->begin(); itr != GLights->end(); ++itr)
SafeDelete((*itr));
GLights->clear();
SafeDelete(GLights);
}