初步做完粒子系统想着如何从脚本中载入数据,配送方法这样不是很好
脚本我打算首先支持lua和天使脚本等引擎成熟了再支持python
首先来看使用lua语言改写上篇的粒子系统代码.
(不过鄙人的lua,python都很菜的,其原因就是一直没有练习的机会)
对于Lua,其扩展有luabind,tolua++,luaplus,前2着都与boost有关
所以就使用luaplus,简单些
开始了先上lua脚本代码(我把lua当成了c++,开始书写很不习惯,居然不知道lua中的逻辑符号是not and or 而非 !&& || 呵呵)
1
2 -- 这是盖莫引擎中使用lua脚本的测试粒子
3
4 -- 定义粒子池粒子个数
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 -- 定义批处理粒子个数
22 batch_particles = 80
23
24 -- 定义粒子和地面之间的摩擦力
25 friction = 0.75
26
27 -- 定义粒子系统发射半径
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 -- 获取时间对应的速度值
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平面随机转角
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 -- 更新粒子状态
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 -- 当粒子碰撞到地面应该跳起来
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居然没有lua的代码高亮...
然后其关联的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 /// 更新粒子函数
32 ////////////////////////////////////////////////////////////
33 void G_CALL UpdateParticle(core::Particle* p,float time);
34
35 ////////////////////////////////////////////////////////////
36 /// 场景旋转和偏移
37 ////////////////////////////////////////////////////////////
38 float TransForm(double t);
39
40 ////////////////////////////////////////////////////////////
41 /// 构造纹理
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 /// 从脚本载入粒子描述数据
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("盖莫引擎粒子系统",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 /// 场景旋转和偏移
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为粒子系统启动时间(单位:秒))
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 /// 更新粒子函数
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 //! 获取粒子的更新后数据
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 /// 从脚本载入粒子描述数据
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
对应的贴图如下:
不过刚开始做的时候写lua的时候有点问题其结果变成了下图,看来要熟悉Lua只有多多练习啊
那么下一步要做的就是把lua集成进引擎中了