引擎中的光照系統(tǒng)是在就存在了的只是感覺一直有點問題,索性重新設(shè)計了.
光照系統(tǒng)的有關(guān)對象和單元有:
渲染基類
RenderBase
對象基類
Object
光描述符
LightDesc
光類
Light
光管理器
LightManager
在引擎中我們認(rèn)識光是一種資源
所以光管理器是從資源管理器中獲得的也就是:
RefPtr<LightManager> lightmanager = resourcemanager->GetLightManager();
引擎的光管理器設(shè)計如下:
1 ////////////////////////////////////////////////////////////
2 //! 定義引擎光管理器
3 ////////////////////////////////////////////////////////////
4 class LightManager : public Manager<Light,std::string>, public Object
5 {
6 public:
7 ////////////////////////////////////////////////////////
8 //! 構(gòu)造,析構(gòu)材質(zhì)管理器
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 /// 根據(jù)腳本數(shù)據(jù)生成一個新的光對象
22 ////////////////////////////////////////////////////////
23 virtual RefPtr<Light> CreateObject(const std::string& name, const std::string& script, const std::string &key) = 0;
24
25 ////////////////////////////////////////////////////////
26 //! 設(shè)置,獲取全局環(huán)境光
27 ////////////////////////////////////////////////////////
28 virtual void SetGlobalAmbient(const Color &color) = 0;
29 virtual void GetGlobalAmbient(Color &color) = 0;
30
31 ////////////////////////////////////////////////////////
32 //! 應(yīng)用全局光
33 ////////////////////////////////////////////////////////
34 virtual void RenderGlobalAmbient(bool use = true) = 0;
35
36 ////////////////////////////////////////////////////////
37 //! 獲取最大支持光源個數(shù)
38 ////////////////////////////////////////////////////////
39 virtual uint8 GetMaxLightNumber()const = 0;
40
41 ////////////////////////////////////////////////////////
42 //! 啟用,關(guān)閉光源
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;
是根據(jù)腳本生成名叫name的光對象
再看光類
1 ////////////////////////////////////////////////////////////
2 /// 定義光源類
3 ////////////////////////////////////////////////////////////
4 class G_DLL_API Light : public RenderBase
5 {
6 public:
7 ////////////////////////////////////////////////////////
8 /// 構(gòu)造,析構(gòu)光源基類
9 ////////////////////////////////////////////////////////
10 Light();
11 Light(const LightDesc &desc);
12 virtual ~Light(){}
13
14 ////////////////////////////////////////////////////////
15 /// 光源類型設(shè)置和獲取
16 ////////////////////////////////////////////////////////
17 void SetLightType(LightType type){this->type = type;}
18 LightType GetLightType()const{return type;}
19
20 ////////////////////////////////////////////////////////
21 /// 光源光參數(shù)設(shè)置和獲取
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 /// 光源位置設(shè)置和獲取(對方向性光源無效)
32 ////////////////////////////////////////////////////////
33 void SetPosition(const Vector3f& pos){position = pos;}
34 Vector3f GetPosition()const{return position;}
35
36 ////////////////////////////////////////////////////////
37 /// 光衰減因子設(shè)置和獲取(對方向性光源無效)(c,l,q)
38 ////////////////////////////////////////////////////////
39 void SetAttenuation(const Vector3f &attenuation){this->attenuation = attenuation;}
40 Vector3f GetAttenuation()const{return attenuation;}
41
42 ////////////////////////////////////////////////////////
43 /// 聚光燈參數(shù)設(shè)置和獲取(僅僅對聚光燈有效)
44 ////////////////////////////////////////////////////////
45 ////////////////////////////////////////////////////////
46 /// 聚光燈方向設(shè)置和獲取
47 ////////////////////////////////////////////////////////
48 void SetSpotLightDirection(const Vector3f &direction){this->spotdirection = direction;}
49 Vector3f GetSpotLightDirection()const{return spotdirection;}
50 ////////////////////////////////////////////////////////
51 /// 聚光燈光錐角度設(shè)置和獲取
52 ////////////////////////////////////////////////////////
53 void SetSpotLightAngle(float angle = 180.0f){this->spotangle = angle;}
54 float GetSpotLightAngle()const{return spotangle;}
55 ////////////////////////////////////////////////////////
56 /// 聚光燈聚光指數(shù)設(shè)置和獲取
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 };
代碼功能都是很簡單的了,從軟工角度看該類是一個巨類并不符合嚴(yán)格的設(shè)計要求O(∩_∩)O~
再看簡單的光配置腳本:
1 -- 這是蓋莫游戲引擎demo中的材質(zhì)配置腳本
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 -- 聚光指數(shù)
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 -- 聚光指數(shù)
74 spot_exponent = 0.3;
75 };
76
當(dāng)前是采用簡單的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 //! 按鍵回調(diào)
14 void LightCallBack(int button,int status);
15 //! 輸入輸出更新
16 void UpdateInput(core::Device*);
17
18 int main(int argc, char **argv)
19 {
20
21 //! 初始化引擎設(shè)備并得到設(shè)備指針
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 //! 設(shè)置攝像機參數(shù)
30 camera->SetViewport(0,0,640,480);
31 camera->SetPerspective(45,640.0f/480.0f,3,300);
32 //! 攝像機渲染
33 camera->Render();
34
35 //! 設(shè)置清屏色
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 //! 設(shè)置環(huán)境光參數(shù)
44 lightmanager->SetGlobalAmbient(core::Color(0.2f,0.2f,0.2f,1.0f));
45 //! 啟用環(huán)境光
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 //! 獲取材質(zhì)管理器
55 core::RefPtr<core::MaterialManager> materialmanager = resourcemanager->GetMaterialManager();
56
57 //! 獲取一個材質(zhì)指針(我們從腳本中載入材質(zhì)數(shù)據(jù)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 //! 獲取文件系統(tǒng)指針
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 //! 讀取文件數(shù)據(jù)
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 //! 按鍵回調(diào)
125 void LightCallBack(int button1,int button2)
126 {
127 static int l1 =0;
128 static int l2 = 0;
129
130 //! 如果鼠標(biāo)左鍵被按下(鼠標(biāo)左鍵控制燈光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 //! 如果鼠標(biāo)右鍵被按下(鼠標(biāo)右鍵控制燈光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總是有點偏低)