刚给引擎设备新加了一个函数GetLuaStateOwner();
用于获取引擎中的lua上下文
看起来似乎没多大必要但是我有自己的考虑!
另外:我修改了粒子脚本
如下:
1
2 -- 这是盖莫引擎中使用lua脚本的测试粒子
3
4 -- 定义粒子池粒子个数
5 max_particles = 5000
6
7 -- 定义粒子初始位置
8 particle_position =
9 {
10 xpos = 0;
11 ypos = 0;
12 zpos = 4;
13 }
14
15 -- 定义粒子大小
16 particle_size = 0.7
17
18 -- 定义粒子寿命
19 particle_life = 9
20
21 -- 定义粒子批大小
22 batch_particles = 100
23
24 friction = 0.75
25
26 fountain_radius = 1.8
27 particle_r = (fountain_radius + particle_size/2)*(fountain_radius + particle_size/2)
28
29 -- 定义粒子速度
30 particle_vel = 8.0
31
32 function GetVelByTime(t)
33 return particle_vel*(0.6 + 0.1*(math.sin(0.5*t)+math.sin(0.31*t)));
34 end
35 function InitZVel()
36 return 0.5 + (0.3/4096.0) * (math.random(1,4095));
37 end
38 local function GetRandRotXY()
39 return (2.0*3.14159265/4096.0) * math.random(1,4095)
40 end
41 function InitXVel(t)
42 xy_angle = GetRandRotXY();
43 vt = GetVelByTime(t);
44 return 0.4 * math.cos(xy_angle)*vt;
45 end
46 function InitYVel(t)
47 xy_angle = GetRandRotXY();
48 vt = GetVelByTime(t);
49 return 0.4 * math.sin(xy_angle)*vt;
50 end
51
52 -- 粒子位置
53 xpos = particle_position[xpos];
54 ypos = particle_position[ypos];
55 zpos = particle_position[zpos];
56
57 function InitPosition()
58 xpos = 2*(particle_position.xpos + 1-math.random());
59 ypos = 3*(particle_position.ypos + 1-math.random());
60 zpos = particle_position.zpos + math.random() - 1;
61 end
62
63 function InitColorRed(t)
64 return 0.7 + 0.3 * math.sin(0.34*t + 0.1);
65 end
66 function InitColorGreen(t)
67 return 0.6 + 0.4 * math.sin(0.63*t + 1.1);
68 end
69 function InitColorBlue(t)
70 return 0.6 + 0.4 * math.sin(0.91*t + 2.1);
71 end
72
73 red = 0;
74 green = 0;
75 blue = 0;
76 xvel = 0;
77 yvel = 0;
78 zvel = 0;
79
80 function InitParticle(t)
81 InitPosition();
82 red = InitColorRed(t);
83 green = InitColorGreen(t);
84 blue = InitColorBlue(t);
85 zvel = InitZVel();
86 xvel = InitXVel(t);
87 yvel = InitYVel(t);
88 end
89
90 new_life = 1;
91 new_xpos = 0;
92 new_ypos = 0;
93 new_zpos = 0;
94 new_xvel = 1;
95 new_yvel = 1;
96 new_zvel = 1;
97 new_red = 0.2;
98 new_green = 0.3;
99 new_blue = 0.2;
100
101
102 -- 更新更新粒子颜色
103 function UpdateColor(red,green,blue)
104 if red > 0.2 or red < 0.2 then
105 red = red - (red - 0.2)*1/99.0;
106 if red > 1 or red < 0 then
107 red = 0.5;
108 new_red = red;
109 end
110 end
111 new_red = red;
112 new_green = green;
113 new_blue = blue;
114 end
115
116 -- 更新粒子状态
117 function UpdateParticles(life,xpos,ypos,zpos,xvel,yvel,zvel,dt)
118 -- 修正粒子生命
119 new_life = life - dt * (1.0 / particle_life);
120 -- 修正粒子速度
121 new_zvel = zvel;
122 new_xpos = xpos + xvel*dt/8*(math.random()-0.5);
123 new_ypos = ypos + yvel*dt/8*(math.random()-0.5);
124 new_zpos = zpos + new_zvel*dt;
125 end
126
127
128
在粒子初始化中,我让粒子的初始位置保持在一个盒子当中,这样其效果就相当于irr中的粒子盒状发射器了。
在粒子更新中变动粒子颜色,修改粒子生命和粒子位置,或者粒子速度
其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 /// 给出一个初始化粒子的方法
10 ////////////////////////////////////////////////////////////
11 void G_CALL InitParticle(core::Particle* p,float t);
12
13 ////////////////////////////////////////////////////////////
14 /// 更新粒子函数
15 ////////////////////////////////////////////////////////////
16 void G_CALL UpdateParticle(core::Particle* p,float time);
17
18 ////////////////////////////////////////////////////////////
19 /// 场景旋转和偏移
20 ////////////////////////////////////////////////////////////
21 float TransForm(double t);
22
23 ////////////////////////////////////////////////////////////
24 /// 渲染场景
25 ////////////////////////////////////////////////////////////
26 void RenderScene();
27
28 core::Device* device = NULL;
29
30 LuaPlus::LuaStateOwner *state = NULL;
31
32 ////////////////////////////////////////////////////////////
33 /// 初始化luaplus
34 ////////////////////////////////////////////////////////////
35 void InitLua(const char* lua)
36 {
37 state = device->GetLuaStateOwner();
38 // 载入Lua脚本
39 (*state)->DoFile(lua);
40 }
41
42 ////////////////////////////////////////////////////////////
43 /// 从脚本载入粒子描述数据
44 ////////////////////////////////////////////////////////////
45 void LoadData(core::ParticleSystemDesc &desc);
46
47 int main(int argc, char **argv)
48 {
49 int i;
50 double t0, t;
51
52 core::VideoMode mode;
53 mode.width = WIN_WIDTH;
54 mode.height = WIN_HEIGHT;
55
56 device = core::InitDevice("盖莫引擎粒子系统",false,mode);
57 InitLua("..\\script\\particle.lua");
58
59 //! 获取资源管理器
60 core::ResourceManager* resourcemanager = device->GetResourceManager();
61 core::RefPtr<core::Image> particleimage = resourcemanager->GetImage("particle","..\\image//particle//flare.bmp");
62 core::RefPtr<core::Texture> particletexture = resourcemanager->GetTexture("particle",particleimage);
63 particletexture->Bind();
64
65 core::ParticleSystemDesc desc;
66 desc.texture_id = particletexture->GetTextureId();
67 desc.init_fn = &InitParticle;
68 desc.update_fn = &UpdateParticle;
69 LoadData(desc);
70 core::ParticleSystem* ps = device->GetParticleSystem(desc);
71
72 t0 = device->GetTime();
73 BEGIN_LOOP(device)
74 t = device->GetTime() - t0;
75 RenderScene();
76 float dt = TransForm(t);
77 ps->Render();
78 END_LOOP(device)
79
80 device->Close();
81 device->Drop();
82
83 return 0;
84 }
85
86 ////////////////////////////////////////////////////////////
87 /// 场景旋转和偏移
88 ////////////////////////////////////////////////////////////
89 float TransForm(double t)
90 {
91 double xpos, ypos, zpos, angle_x, angle_y, angle_z;
92 static double t_old = 0.0;
93 float dt = (float)(t-t_old);
94 t_old = t;
95
96 angle_x = 90.0 - 10.0;
97 angle_y = 10.0 * sin( 0.3 * t );
98 angle_z = 10.0 * t;
99 glRotated( -angle_x, 1.0, 0.0, 0.0 );
100 glRotated( -angle_y, 0.0, 1.0, 0.0 );
101 glRotated( -angle_z, 0.0, 0.0, 1.0 );
102
103 xpos = 15.0 * sin( (M_PI/180.0) * angle_z ) +
104 2.0 * sin( (M_PI/180.0) * 3.1 * t );
105 ypos = -15.0 * cos( (M_PI/180.0) * angle_z ) +
106 2.0 * cos( (M_PI/180.0) * 2.9 * t );
107 zpos = 4.0 + 2.0 * cos( (M_PI/180.0) * 4.9 * t );
108 glTranslated( -xpos, -ypos, -zpos );
109 return dt;
110 }
111
112 void RenderScene()
113 {
114 glViewport( 0, 0, WIN_WIDTH,WIN_HEIGHT);
115 glClearColor( 0.1f, 0.1f, 0.1f, 1.0f );
116 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
117 glMatrixMode( GL_PROJECTION );
118 glLoadIdentity();
119 gluPerspective(65.0, 640.0/480.0, 1.0, 60.0 );
120 glMatrixMode( GL_MODELVIEW );
121 glLoadIdentity();
122 }
123
124 ////////////////////////////////////////////////////////////
125 /// 给出一个初始化粒子的方法(t为粒子系统启动时间(单位:秒))
126 ////////////////////////////////////////////////////////////
127 void G_CALL InitParticle(core::Particle* p,float t)
128 {
129 //! 初始化粒子位置位置
130 LuaPlus::LuaFunction<void> initpos(*state,"InitParticle");
131 initpos(t);
132
133 float xpos =(*state)->GetGlobal("xpos").GetFloat(); //GetByName("xpos").
134 float ypos =(*state)->GetGlobal("ypos").GetFloat();
135 float zpos =(*state)->GetGlobal("zpos").GetFloat();
136 p->position = Vector3f(xpos,ypos,zpos);
137
138 //! 初始化粒子颜色
139 p->color.red = (*state)->GetGlobal("red").GetFloat();
140 p->color.green = (*state)->GetGlobal("green").GetFloat();
141 p->color.blue = (*state)->GetGlobal("blue").GetFloat();
142
143 //! 初始化粒子初始速度
144 float xvel =(*state)->GetGlobal("xvel").GetFloat();
145 float yvel =(*state)->GetGlobal("yvel").GetFloat();
146 float zvel =(*state)->GetGlobal("zvel").GetFloat();
147 p->velocity = Vector3f(xvel,yvel,zvel);
148 }
149
150 ////////////////////////////////////////////////////////////
151 /// 更新粒子函数
152 ////////////////////////////////////////////////////////////
153 void G_CALL UpdateParticle(core::Particle* p,float time)
154 {
155 LuaPlus::LuaFunction<void> update_fn(*state,"UpdateParticles");
156 float life = p->life;
157 float xpos = p->position.x;
158 float ypos = p->position.y;
159 float zpos = p->position.z;
160 float xvel = p->velocity.x;
161 float yvel = p->velocity.y;
162 float zvel = p->velocity.z;
163 update_fn(life,xpos,ypos,zpos,xvel,yvel,zvel,time);
164
165 //! 获取更新后的粒子颜色
166 LuaPlus::LuaFunction<void> update_color(*state,"UpdateColor");
167 update_color(p->color.red,p->color.green,p->color.blue);
168
169 p->color.red = (*state)->GetGlobal("new_red").GetFloat();
170 p->color.green = (*state)->GetGlobal("new_green").GetFloat();
171 p->color.blue = (*state)->GetGlobal("new_blue").GetFloat();
172
173 //! 获取粒子的更新后数据
174 p->life = (*state)->GetGlobal("new_life").GetFloat();
175 p->position.x = (*state)->GetGlobal("new_xpos").GetFloat();
176 p->position.y = (*state)->GetGlobal("new_ypos").GetFloat();
177 p->position.z = (*state)->GetGlobal("new_zpos").GetFloat();
178 p->velocity.x = (*state)->GetGlobal("new_xvel").GetFloat();
179 p->velocity.y = (*state)->GetGlobal("new_yvel").GetFloat();
180 p->velocity.z = (*state)->GetGlobal("new_zvel").GetFloat();
181 }
182
183 ////////////////////////////////////////////////////////////
184 /// 从脚本载入粒子描述数据
185 ////////////////////////////////////////////////////////////
186 void LoadData(core::ParticleSystemDesc &desc)
187 {
188 desc.batch_particles = (*state)->GetGlobal("batch_particles").GetInteger();
189 desc.particle_size = (*state)->GetGlobal("particle_size").GetFloat();
190 desc.life_span = (*state)->GetGlobal("particle_life").GetFloat();
191 int max_particles = (*state)->GetGlobal("max_particles").GetInteger();
192 desc.particle_number = max_particles;
193 }
194
195
196
当然代码中没有检测错误和异常.
其输出图形如下所示:
另外一幅截图
看得使用盖莫游戏引擎设计粒子效果足够简单吧
最后上盖莫引擎的logo(当然这是题外图O(∩_∩)O~)