引擎中的光照系统是在就存在了的只是感觉一直有点问题,索性重新设计了.
光照系统的有关对象和单元有:
渲染基类
RenderBase
对象基类
Object
光描述符
LightDesc
光类
Light
光管理器
LightManager
在引擎中我们认识光是一种资源
所以光管理器是从资源管理器中获得的也就是:
RefPtr<LightManager> lightmanager = resourcemanager->GetLightManager();
引擎的光管理器设计如下:
1 ////////////////////////////////////////////////////////////
2 //! 定义引擎光管理器
3 ////////////////////////////////////////////////////////////
4 class LightManager : public Manager<Light,std::string>, public Object
5 {
6 public:
7 ////////////////////////////////////////////////////////
8 //! 构造,析构材质管理器
9 ////////////////////////////////////////////////////////
10 LightManager(){}
11 ~LightManager(){}
12 public:
13
14 ////////////////////////////////////////////////////////
15 /// 生成一个新的对象
16 ////////////////////////////////////////////////////////
17 virtual RefPtr<Light> CreateObject(const std::string& name) = 0;
18 virtual RefPtr<Light> CreateObject(const std::string& name, const LightDesc &desc) = 0;
19
20 ////////////////////////////////////////////////////////
21 /// 根据脚本数据生成一个新的光对象
22 ////////////////////////////////////////////////////////
23 virtual RefPtr<Light> CreateObject(const std::string& name, const std::string& script, const std::string &key) = 0;
24
25 ////////////////////////////////////////////////////////
26 //! 设置,获取全局环境光
27 ////////////////////////////////////////////////////////
28 virtual void SetGlobalAmbient(const Color &color) = 0;
29 virtual void GetGlobalAmbient(Color &color) = 0;
30
31 ////////////////////////////////////////////////////////
32 //! 应用全局光
33 ////////////////////////////////////////////////////////
34 virtual void RenderGlobalAmbient(bool use = true) = 0;
35
36 ////////////////////////////////////////////////////////
37 //! 获取最大支持光源个数
38 ////////////////////////////////////////////////////////
39 virtual uint8 GetMaxLightNumber()const = 0;
40
41 ////////////////////////////////////////////////////////
42 //! 启用,关闭光源
43 ////////////////////////////////////////////////////////
44 virtual void EnableLight() = 0;
45 virtual void DisableLight() = 0;
46
47 ////////////////////////////////////////////////////////
48 //! 获检测是否启用了光源
49 ////////////////////////////////////////////////////////
50 virtual bool IsEnableLight()const = 0;
51
52 DECLARE_OBJECT(LightManager);
53 };
54
唯一需要说明的就是
virtual RefPtr<Light> CreateObject(const std::string& name, const std::string& script, const std::string &key) = 0;
是根据脚本生成名叫name的光对象
再看光类
1 ////////////////////////////////////////////////////////////
2 /// 定义光源类
3 ////////////////////////////////////////////////////////////
4 class G_DLL_API Light : public RenderBase
5 {
6 public:
7 ////////////////////////////////////////////////////////
8 /// 构造,析构光源基类
9 ////////////////////////////////////////////////////////
10 Light();
11 Light(const LightDesc &desc);
12 virtual ~Light(){}
13
14 ////////////////////////////////////////////////////////
15 /// 光源类型设置和获取
16 ////////////////////////////////////////////////////////
17 void SetLightType(LightType type){this->type = type;}
18 LightType GetLightType()const{return type;}
19
20 ////////////////////////////////////////////////////////
21 /// 光源光参数设置和获取
22 ////////////////////////////////////////////////////////
23 void SetAmbient(const Color &color){ambient = color;}
24 void SetDiffuse(const Color &color){diffuse = color;}
25 void SetSpecular(const Color &color){specular = color;}
26 Color GetAmbient()const{return ambient;}
27 Color GetDiffuse()const{return diffuse;}
28 Color GetSpecular()const{return specular;}
29
30 ////////////////////////////////////////////////////////
31 /// 光源位置设置和获取(对方向性光源无效)
32 ////////////////////////////////////////////////////////
33 void SetPosition(const Vector3f& pos){position = pos;}
34 Vector3f GetPosition()const{return position;}
35
36 ////////////////////////////////////////////////////////
37 /// 光衰减因子设置和获取(对方向性光源无效)(c,l,q)
38 ////////////////////////////////////////////////////////
39 void SetAttenuation(const Vector3f &attenuation){this->attenuation = attenuation;}
40 Vector3f GetAttenuation()const{return attenuation;}
41
42 ////////////////////////////////////////////////////////
43 /// 聚光灯参数设置和获取(仅仅对聚光灯有效)
44 ////////////////////////////////////////////////////////
45 ////////////////////////////////////////////////////////
46 /// 聚光灯方向设置和获取
47 ////////////////////////////////////////////////////////
48 void SetSpotLightDirection(const Vector3f &direction){this->spotdirection = direction;}
49 Vector3f GetSpotLightDirection()const{return spotdirection;}
50 ////////////////////////////////////////////////////////
51 /// 聚光灯光锥角度设置和获取
52 ////////////////////////////////////////////////////////
53 void SetSpotLightAngle(float angle = 180.0f){this->spotangle = angle;}
54 float GetSpotLightAngle()const{return spotangle;}
55 ////////////////////////////////////////////////////////
56 /// 聚光灯聚光指数设置和获取
57 ////////////////////////////////////////////////////////
58 void SetSpotExponent(float exponent = 0.0f){spotexponent = exponent;}
59 float GetSpotExponent()const{return spotexponent;}
60 protected:
61 Color ambient,diffuse,specular;
62 Vector3f position;
63 LightType type;
64 Vector3f attenuation;
65
66 //! 聚光灯参变量
67 Vector3f spotdirection;
68 float spotangle;
69 float spotexponent;
70
71 DECLARE_OBJECT(Light)
72 };
代码功能都是很简单的了,从软工角度看该类是一个巨类并不符合严格的设计要求O(∩_∩)O~
再看简单的光配置脚本:
1 -- 这是盖莫游戏引擎demo中的材质配置脚本
2 -- maker:核动力机器人
3
4 -- 定义一种光属性
5 light0 =
6 {
7 ambient_red = 0.4;
8 ambient_green = 0.3;
9 ambient_blue = 0.2;
10 ambient_alpha = 1.0;
11 diffuse_red = 0.3;
12 diffuse_green = 0.1;
13 diffuse_blue = 1.0;
14 diffuse_alpha = 1.0;
15 specular_red = 0.2;
16 specular_green = 0.3;
17 specular_blue = 0.2;
18 specular_alpha = 1.0;
19 -- 0 for 方向性光源
20 -- 1 for 位置性光源
21 -- 2 for 聚光灯
22 light_type = 0;
23 position_x = -10;
24 position_y = -10;
25 position_z = -10;
26 -- 光衰减
27 attenuation_x = 1.0;
28 attenuation_y = 0.0;
29 attenuation_z = 0.0;
30 -- 聚光灯聚光方向
31 spot_dirx = 1;
32 spot_diry = 1;
33 spot_dirz = -1;
34 -- 聚光灯光锥角
35 spot_angle = 180.0;
36 -- 聚光指数
37 spot_exponent = 0.0;
38 };
39
40
41 -- 定义一种光属性
42 light1 =
43 {
44 ambient_red = 0.5;
45 ambient_green = 0.3;
46 ambient_blue = 0.8;
47 ambient_alpha = 1.0;
48 diffuse_red = 0.3;
49 diffuse_green = 0.1;
50 diffuse_blue = 0.9;
51 diffuse_alpha = 1.0;
52 specular_red = 1.0;
53 specular_green = 1.0;
54 specular_blue = 1.0;
55 specular_alpha = 1.0;
56 -- 0 for 方向性光源
57 -- 1 for 位置性光源
58 -- 2 for 聚光灯
59 light_type = 2;
60 position_x = 60;
61 position_y = 60;
62 position_z = 0;
63 -- 光衰减
64 attenuation_x = 1.0;
65 attenuation_y = 0.0;
66 attenuation_z = 0.0;
67 -- 聚光灯聚光方向
68 spot_dirx = -1;
69 spot_diry = -1;
70 spot_dirz = -1;
71 -- 聚光灯光锥角
72 spot_angle = 29.0;
73 -- 聚光指数
74 spot_exponent = 0.3;
75 };
76
当前是采用简单的lua表显示配置光的(这样做的一个原因是我还对lua不太熟悉)
再上一段demo程序和贴图
(程序很简单的了只是为了说明问题)
1 #include <GEngine/Gaimo.hpp>
2 using namespace std;
3
4 //! 字体指针和字体初始化
5 core::RefPtr<core::Text> font;
6 bool InitFont(core::Device* device);
7
8 //! 光指针2个
9 core::RefPtr<core::Light> light[2];
10
11 //! 定义灯光控制器
12 sigc::signal<void,int,int> light_controller;
13 //! 按键回调
14 void LightCallBack(int button,int status);
15 //! 输入输出更新
16 void UpdateInput(core::Device*);
17
18 int main(int argc, char **argv)
19 {
20
21 //! 初始化引擎设备并得到设备指针
22 core::Device* device = core::InitDevice("盖莫引擎光照测试");
23 //! 获取场景管理器指针
24 core::RefPtr<core::SceneManager> scenemanager = device->GetSceneManager();
25 //! 获取摄像机指针
26 core::RefPtr<core::Camera> camera = scenemanager->GetGlobalCamera(Vector3f(100,100,0),
27 Vector3f(),
28 Vector3f(0,1,0));
29 //! 设置摄像机参数
30 camera->SetViewport(0,0,640,480);
31 camera->SetPerspective(45,640.0f/480.0f,3,300);
32 //! 摄像机渲染
33 camera->Render();
34
35 //! 设置清屏色
36 core::Render::SetClearColor(core::Color(0.3f,0.3f,0.6f));
37
38 //! 获取资源管理器
39 core::RefPtr<core::ResourceManager> resourcemanager = device->GetResourceManager();
40
41 //! 获取光管理器指针
42 core::RefPtr<core::LightManager> lightmanager = resourcemanager->GetLightManager();
43 //! 设置环境光参数
44 lightmanager->SetGlobalAmbient(core::Color(0.2f,0.2f,0.2f,1.0f));
45 //! 启用环境光
46 lightmanager->RenderGlobalAmbient(true);
47 //! 启用光源
48 lightmanager->EnableLight();
49
50 //! 获取光指针(2个)
51 light[0] = lightmanager->CreateObject("light1","..\\script//light.lua","light0");
52 light[1] = lightmanager->CreateObject("light2","..\\script//light.lua","light1");
53
54 //! 获取材质管理器
55 core::RefPtr<core::MaterialManager> materialmanager = resourcemanager->GetMaterialManager();
56
57 //! 获取一个材质指针(我们从脚本中载入材质数据O(∩_∩)O~)
58 core::RefPtr<core::RenderBase> material = materialmanager->CreateObject("material","..\\script//material.lua","material");
59
60 //! 字体初始化
61 bool flag = InitFont(device);
62 if(flag == false)
63 {
64 ShowMessage(初始化字体失败)
65 device->Close();
66 device->Drop();
67 return -1;
68 }
69
70 GLUquadric* obj = gluNewQuadric();
71
72 material->Enable();
73 material->Render();
74
75 glDepthFunc(GL_LESS);
76 glEnable(GL_DEPTH_TEST);
77
78 light_controller.connect(sigc::ptr_fun(&LightCallBack));
79
80 int fps;
81 char text[255];
82 BEGIN_LOOP(device)
83 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
84 fps = device->GetFPS();
85 sprintf(text,"fps is: %d",fps);
86 font->Render(540,0,text);
87 light[0]->Render();
88 light[1]->Render();
89 UpdateInput(device);
90 gluSphere(obj,16,100,100);
91 END_LOOP(device)
92
93 gluDeleteQuadric(obj);
94
95 device->Close();
96 device->Drop();
97
98 return 0;
99 }
100
101 bool InitFont(core::Device* device)
102 {
103 //! 获取文件系统指针
104 core::RefPtr<core::FileSystem> filesystem = device->GetFileSystem();
105
106 filesystem->AddToSearchPath("..\\font\\font.zip");
107 bool flag = filesystem->IsExists("accid.ttf");
108 if(flag == false)
109 {
110 return false;
111 }
112
113 //! 读取文件数据
114 core::RefPtr<core::ReadFile> file = filesystem->OpenRead("accid.ttf");
115
116 //! 使用给定字体文件(ttf)
117 font = device->GetResourceManager()->GetText("newfont",file,18);
118
119 (*device->GetLuaStateOwner())->DoFile("..\\script//light.lua");
120
121 return true;
122 }
123
124 //! 按键回调
125 void LightCallBack(int button1,int button2)
126 {
127 static int l1 =0;
128 static int l2 = 0;
129
130 //! 如果鼠标左键被按下(鼠标左键控制灯光1)
131 if(button1 == MOUSE_BUTTON_LEFT)
132 {
133 if(l1 % 2 == 0)
134 {
135 font->Render(10,10,"light1 is off");
136 light[0]->Disable();
137 }
138 else
139 {
140 font->Render(10,10,"light1 is on");
141 light[0]->Enable();
142 }
143 l1 ++;
144 }
145 //! 如果鼠标右键被按下(鼠标右键控制灯光2)
146 if(button2 == MOUSE_BUTTON_RIGHT)
147 {
148 if(l2 % 2 == 0)
149 {
150 light[1]->Disable();
151 }
152 else
153 {
154 light[1]->Enable();
155 }
156 l2 ++;
157 }
158
159 if(light[0]->IsEnable())
160 font->Render(10,10,"light1 is on");
161 else
162 font->Render(10,10,"light1 is off");
163 if(light[1]->IsEnable())
164 font->Render(10,35,"light2 is on");
165 else
166 font->Render(10,35,"light2 is off");
167 }
168
169 void UpdateInput(core::Device* device)
170 {
171 core::RefPtr<core::Input> input = device->GetInput();
172 if(input->IsPressedMouse(MOUSE_BUTTON_LEFT) == true)
173 {
174 light_controller.emit(MOUSE_BUTTON_LEFT,MOUSE_BUTTON_LEFT);
175 }
176 else if(input->IsPressedMouse(MOUSE_BUTTON_RIGHT) == true)
177 {
178 light_controller.emit(MOUSE_BUTTON_RIGHT,MOUSE_BUTTON_RIGHT);
179 }
180 else
181 {
182 light_controller.emit(MOUSE_BUTTON_MIDDLE,MOUSE_BUTTON_MIDDLE);
183 }
184 }
185
186
187
188
189
下面是其贴图(截屏的程序fps总是有点偏低)