初步做完粒子系統(tǒng)想著如何從腳本中載入數(shù)據(jù),配送方法這樣不是很好
腳本我打算首先支持lua和天使腳本等引擎成熟了再支持python
首先來看使用lua語言改寫上篇的粒子系統(tǒng)代碼.
(不過鄙人的lua,python都很菜的,其原因就是一直沒有練習(xí)的機會)
對于Lua,其擴展有l(wèi)uabind,tolua++,luaplus,前2著都與boost有關(guān)
所以就使用luaplus,簡單些
開始了先上lua腳本代碼(我把lua當(dāng)成了c++,開始書寫很不習(xí)慣,居然不知道lua中的邏輯符號是not and or 而非 !&& || 呵呵)
1
2 -- 這是蓋莫引擎中使用lua腳本的測試粒子
3
4 -- 定義粒子池粒子個數(shù)
5 max_particles = 2400
6
7 -- 定義粒子初始位置
8 particle_pos_x = 0.0
9 particle_pos_y = 0.0
10 particle_pos_z = 3.0
11
12 -- 定義重力加速度
13 gravity = 9.8
14
15 -- 定義粒子大小
16 particle_size = 0.8
17
18 -- 定義粒子壽命
19 particle_life = 8.2
20
21 -- 定義批處理粒子個數(shù)
22 batch_particles = 80
23
24 -- 定義粒子和地面之間的摩擦力
25 friction = 0.75
26
27 -- 定義粒子系統(tǒng)發(fā)射半徑
28 fountain_radius = 1.6
29
30 -- 定義粒子范圍半徑
31 particle_r = (fountain_radius + particle_size/2)*(fountain_radius + particle_size/2)
32
33 -- 初始化隨機種子
34 function InitRand()
35 math.randomseed(os.time());
36 end
37
38 -- 初始化粒子顏色red,green,blue
39 function InitColorRed(t)
40 return 0.7 + 0.3 * math.sin(0.34*t + 0.1);
41 end
42 function InitColorGreen(t)
43 return 0.6 + 0.4 * math.sin(0.63*t + 1.1);
44 end
45 function InitColorBlue(t)
46 return 0.6 + 0.4 * math.sin(0.91*t + 2.1);
47 end
48
49 -- 定義粒子速度
50 particle_vel = 8.0
51
52 -- 獲取時間對應(yīng)的速度值
53 function GetVelByTime(t)
54 return particle_vel*(0.8 + 0.1*(math.sin(0.5*t)+math.sin(0.31*t)));
55 end
56
57 -- 獲取粒子初始速度
58 function InitZVel()
59 return 0.7 + (0.3/4096.0) * (math.random(1,4095));
60 end
61
62 -- 獲取xy平面隨機轉(zhuǎn)角
63 function GetRandRotXY()
64 return (2.0*3.14159265/4096.0) * math.random(1,4095)
65 end
66
67 -- 獲取粒子隨機速度x分量
68 function InitXVel(t)
69 xy_angle = GetRandRotXY();
70 vt = GetVelByTime(t);
71 return 0.45 * math.cos(xy_angle)*vt;
72 end
73
74 -- 獲取粒子隨機速度y分量
75 function InitYVel(t)
76 xy_angle = GetRandRotXY();
77 vt = GetVelByTime(t);
78 return 0.45 * math.sin(xy_angle)*vt;
79 end
80
81 -- 定義更新粒子后的全局變量
82 new_life = 0;
83 new_xpos = 0;
84 new_ypos = 0;
85 new_zpos = 0;
86 new_xvel = 1;
87 new_yvel = 1;
88 new_zvel = 1;
89
90 -- 更新粒子狀態(tài)
91 function UpdateParticles(life,xpos,ypos,zpos,xvel,yvel,zvel,dt)
92 -- 修正粒子生命
93 new_life = life - dt * (1.0 / particle_life);
94 -- 修正粒子速度
95 new_zvel = zvel - gravity *dt;
96 new_xpos = xpos + xvel*dt;
97 new_ypos = ypos + yvel*dt;
98 new_zpos = zpos + new_zvel*dt;
99 if new_zvel < 0.0 then
100 if new_xpos*new_xpos + new_ypos*new_ypos < particle_r and new_zpos < particle_pos_z + particle_size/2 then
101 new_zvel = -friction * new_zvel;
102 new_zpos = particle_pos_z + particle_size/2 + friction * (particle_pos_z + particle_size/2 - new_zpos);
103 -- 當(dāng)粒子碰撞到地面應(yīng)該跳起來
104 elseif new_zpos < particle_size/2 then
105 new_zvel = -friction * new_zvel;
106 new_zpos = particle_size/2 + friction * (particle_size/2 - new_zpos);
107 end
108 end
109 end
cppblog居然沒有l(wèi)ua的代碼高亮...
然后其關(guān)聯(lián)的c++代碼如下:
1
2 #include <GEngine/Main.hpp>
3 #include <luaplus/luaplus.h>
4
5 #define WIN_WIDTH 640
6 #define WIN_HEIGHT 480
7
8 //! 粒子紋理
9 static const unsigned char particle_texture[] =
10 {
11 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12 0x00, 0x00, 0x11, 0x22, 0x22, 0x11, 0x00, 0x00,
13 0x00, 0x11, 0x33, 0x88, 0x77, 0x33, 0x11, 0x00,
14 0x00, 0x22, 0x88, 0xff, 0xee, 0x77, 0x22, 0x00,
15 0x00, 0x22, 0x77, 0xee, 0xff, 0x88, 0x22, 0x00,
16 0x00, 0x11, 0x33, 0x77, 0x88, 0x33, 0x11, 0x00,
17 0x00, 0x00, 0x11, 0x33, 0x22, 0x11, 0x00, 0x00,
18 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
19 };
20
21 //! 粒子紋理大小
22 #define P_TEX_WIDTH 8
23 #define P_TEX_HEIGHT 8
24
25 ////////////////////////////////////////////////////////////
26 /// 給出一個初始化粒子的方法
27 ////////////////////////////////////////////////////////////
28 void G_CALL InitParticle(core::Particle* p,float t);
29
30 ////////////////////////////////////////////////////////////
31 /// 更新粒子函數(shù)
32 ////////////////////////////////////////////////////////////
33 void G_CALL UpdateParticle(core::Particle* p,float time);
34
35 ////////////////////////////////////////////////////////////
36 /// 場景旋轉(zhuǎn)和偏移
37 ////////////////////////////////////////////////////////////
38 float TransForm(double t);
39
40 ////////////////////////////////////////////////////////////
41 /// 構(gòu)造紋理
42 ////////////////////////////////////////////////////////////
43 void BuildTexture(GLuint& texture_id);
44
45 ////////////////////////////////////////////////////////////
46 /// 渲染場景
47 ////////////////////////////////////////////////////////////
48 void RenderScene();
49
50 core::Device* device = NULL;
51 libmath::TriTable* table = NULL;
52
53 LuaPlus::LuaStateOwner *state = NULL;
54
55 ////////////////////////////////////////////////////////////
56 /// 初始化luaplus
57 ////////////////////////////////////////////////////////////
58 void InitLua(const char* lua)
59 {
60 state = new LuaPlus::LuaStateOwner;
61 // 載入Lua腳本
62 (*state)->DoFile(lua);
63 LuaPlus::LuaFunction<void> initrand(*state,"InitRand");
64 initrand();
65 }
66
67 void DeinitLua()
68 {
69 delete state;
70 }
71
72 ////////////////////////////////////////////////////////////
73 /// 從腳本載入粒子描述數(shù)據(jù)
74 ////////////////////////////////////////////////////////////
75 void LoadData(core::ParticleSystemDesc &desc);
76
77 int main(int argc, char **argv)
78 {
79 InitLua("particle.lua");
80 int i;
81 double t0, t;
82
83 core::VideoMode mode;
84 mode.width = WIN_WIDTH;
85 mode.height = WIN_HEIGHT;
86
87 device = core::InitDevice("蓋莫引擎粒子系統(tǒng)",false,mode);
88 table = device->GetTriTable();
89
90 core::ParticleSystemDesc desc;
91
92 GLuint texture_id;
93 BuildTexture(texture_id);
94 desc.texture_id = texture_id;
95 desc.init_fn = &InitParticle;
96 desc.update_fn = &UpdateParticle;
97 LoadData(desc);
98 core::ParticleSystem* ps = device->GetParticleSystem(desc);
99
100 t0 = device->GetTime();
101 BEGIN_LOOP(device)
102 t = device->GetTime() - t0;
103 RenderScene();
104 float dt = TransForm(t);
105 ps->Render();
106 END_LOOP(device)
107
108 device->Close();
109 device->Drop();
110
111 DeinitLua();
112 return 0;
113 }
114
115 void BuildTexture(GLuint& texture_id)
116 {
117 glGenTextures( 1, &texture_id );
118 glBindTexture( GL_TEXTURE_2D, texture_id);
119 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
120 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
121 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
122 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
123 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
124 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, P_TEX_WIDTH, P_TEX_HEIGHT,
125 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, particle_texture);
126 }
127
128 ////////////////////////////////////////////////////////////
129 /// 場景旋轉(zhuǎn)和偏移
130 ////////////////////////////////////////////////////////////
131 float TransForm(double t)
132 {
133 double xpos, ypos, zpos, angle_x, angle_y, angle_z;
134 static double t_old = 0.0;
135 float dt = (float)(t-t_old);
136 t_old = t;
137
138 angle_x = 90.0 - 10.0;
139 angle_y = 10.0 * sin( 0.3 * t );
140 angle_z = 10.0 * t;
141 glRotated( -angle_x, 1.0, 0.0, 0.0 );
142 glRotated( -angle_y, 0.0, 1.0, 0.0 );
143 glRotated( -angle_z, 0.0, 0.0, 1.0 );
144
145 xpos = 15.0 * sin( (M_PI/180.0) * angle_z ) +
146 2.0 * sin( (M_PI/180.0) * 3.1 * t );
147 ypos = -15.0 * cos( (M_PI/180.0) * angle_z ) +
148 2.0 * cos( (M_PI/180.0) * 2.9 * t );
149 zpos = 4.0 + 2.0 * cos( (M_PI/180.0) * 4.9 * t );
150 glTranslated( -xpos, -ypos, -zpos );
151 return dt;
152 }
153
154 void RenderScene()
155 {
156 glViewport( 0, 0, WIN_WIDTH,WIN_HEIGHT);
157 glClearColor( 0.1f, 0.1f, 0.1f, 1.0f );
158 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
159 glMatrixMode( GL_PROJECTION );
160 glLoadIdentity();
161 gluPerspective(65.0, 640.0/480.0, 1.0, 60.0 );
162 glMatrixMode( GL_MODELVIEW );
163 glLoadIdentity();
164 }
165
166 ////////////////////////////////////////////////////////////
167 /// 給出一個初始化粒子的方法(t為粒子系統(tǒng)啟動時間(單位:秒))
168 ////////////////////////////////////////////////////////////
169 void G_CALL InitParticle(core::Particle* p,float t)
170 {
171 //! 初始化粒子位置位置
172 float xpos = (*state)->GetGlobal("particle_pos_x").GetFloat();
173 float ypos = (*state)->GetGlobal("particle_pos_y").GetFloat();
174 float zpos = (*state)->GetGlobal("particle_pos_z").GetFloat();
175 p->position = Vector3f(xpos,ypos,zpos);
176
177 //! 初始化粒子顏色
178 LuaPlus::LuaFunction<float> red(*state,"InitColorRed");
179 LuaPlus::LuaFunction<float> green(*state,"InitColorGreen");
180 LuaPlus::LuaFunction<float> blue(*state,"InitColorBlue");
181 p->color.red = red(t);
182 p->color.green = green(t);
183 p->color.blue = blue(t);
184
185 //! 初始化粒子初始速度
186 LuaPlus::LuaFunction<float> xvel(*state,"InitXVel");
187 LuaPlus::LuaFunction<float> yvel(*state,"InitYVel");
188 LuaPlus::LuaFunction<float> zvel(*state,"InitZVel");
189 p->velocity = Vector3f(xvel(t),yvel(t),zvel(t));
190 }
191
192 ////////////////////////////////////////////////////////////
193 /// 更新粒子函數(shù)
194 ////////////////////////////////////////////////////////////
195 void G_CALL UpdateParticle(core::Particle* p,float time)
196 {
197 LuaPlus::LuaFunction<void> update_fn(*state,"UpdateParticles");
198 float life = p->life;
199 float xpos = p->position.x;
200 float ypos = p->position.y;
201 float zpos = p->position.z;
202 float xvel = p->velocity.x;
203 float yvel = p->velocity.y;
204 float zvel = p->velocity.z;
205 update_fn(life,xpos,ypos,zpos,xvel,yvel,zvel,time);
206
207 //! 獲取粒子的更新后數(shù)據(jù)
208 p->life = (*state)->GetGlobal("new_life").GetFloat();
209 p->position.x = (*state)->GetGlobal("new_xpos").GetFloat();
210 p->position.y = (*state)->GetGlobal("new_ypos").GetFloat();
211 p->position.z = (*state)->GetGlobal("new_zpos").GetFloat();
212 p->velocity.x = xvel;
213 p->velocity.y = yvel;
214 p->velocity.z = (*state)->GetGlobal("new_zvel").GetFloat();
215 }
216
217 ////////////////////////////////////////////////////////////
218 /// 從腳本載入粒子描述數(shù)據(jù)
219 ////////////////////////////////////////////////////////////
220 void LoadData(core::ParticleSystemDesc &desc)
221 {
222 desc.batch_particles = (*state)->GetGlobal("batch_particles").GetInteger();
223 desc.particle_size = (*state)->GetGlobal("particle_size").GetFloat();
224 desc.life_span = (*state)->GetGlobal("particle_life").GetFloat();
225 int max_particles = (*state)->GetGlobal("max_particles").GetInteger();
226 desc.particle_number = max_particles;
227 }
228
對應(yīng)的貼圖如下:

不過剛開始做的時候?qū)憀ua的時候有點問題其結(jié)果變成了下圖,看來要熟悉Lua只有多多練習(xí)啊

那么下一步要做的就是把lua集成進引擎中了