|
刚给引擎设备新加了一个函数GetLuaStateOwner();
用于获取引擎中的lua上下文
看起来似乎没多大必要但是我有自己的考虑!
另外:我修改了粒子脚本
如下:
-- 这是盖莫引擎中使用lua脚本的测试粒子
-- 定义粒子池粒子个数
max_particles = 5000
-- 定义粒子初始位置
particle_position =
{
xpos = 0;
ypos = 0;
zpos = 4;
}
-- 定义粒子大小
particle_size = 0.7
-- 定义粒子寿命
particle_life = 9
-- 定义粒子批大小
batch_particles = 100
friction = 0.75
fountain_radius = 1.8
particle_r = (fountain_radius + particle_size/2)*(fountain_radius + particle_size/2)
-- 定义粒子速度
particle_vel = 8.0
function GetVelByTime(t)
return particle_vel*(0.6 + 0.1*(math.sin(0.5*t)+math.sin(0.31*t)));
end
function InitZVel()
return 0.5 + (0.3/4096.0) * (math.random(1,4095));
end
local function GetRandRotXY()
return (2.0*3.14159265/4096.0) * math.random(1,4095)
end
function InitXVel(t)
xy_angle = GetRandRotXY();
vt = GetVelByTime(t);
return 0.4 * math.cos(xy_angle)*vt;
end
function InitYVel(t)
xy_angle = GetRandRotXY();
vt = GetVelByTime(t);
return 0.4 * math.sin(xy_angle)*vt;
end
-- 粒子位置
xpos = particle_position[xpos];
ypos = particle_position[ypos];
zpos = particle_position[zpos];
function InitPosition()
xpos = 2*(particle_position.xpos + 1-math.random());
ypos = 3*(particle_position.ypos + 1-math.random());
zpos = particle_position.zpos + math.random() - 1;
end
function InitColorRed(t)
return 0.7 + 0.3 * math.sin(0.34*t + 0.1);
end
function InitColorGreen(t)
return 0.6 + 0.4 * math.sin(0.63*t + 1.1);
end
function InitColorBlue(t)
return 0.6 + 0.4 * math.sin(0.91*t + 2.1);
end
red = 0;
green = 0;
blue = 0;
xvel = 0;
yvel = 0;
zvel = 0;
function InitParticle(t)
InitPosition();
red = InitColorRed(t);
green = InitColorGreen(t);
blue = InitColorBlue(t);
zvel = InitZVel();
xvel = InitXVel(t);
yvel = InitYVel(t);
end
new_life = 1;
new_xpos = 0;
new_ypos = 0;
new_zpos = 0;
new_xvel = 1;
new_yvel = 1;
new_zvel = 1;
new_red = 0.2;
new_green = 0.3;
new_blue = 0.2;
-- 更新更新粒子颜色
function UpdateColor(red,green,blue)
if red > 0.2 or red < 0.2 then
red = red - (red - 0.2)*1/99.0;
if red > 1 or red < 0 then
red = 0.5;
new_red = red;
end
end
new_red = red;
new_green = green;
new_blue = blue;
end
-- 更新粒子状态
function UpdateParticles(life,xpos,ypos,zpos,xvel,yvel,zvel,dt)
-- 修正粒子生命
new_life = life - dt * (1.0 / particle_life);
-- 修正粒子速度
new_zvel = zvel;
new_xpos = xpos + xvel*dt/8*(math.random()-0.5);
new_ypos = ypos + yvel*dt/8*(math.random()-0.5);
new_zpos = zpos + new_zvel*dt;
end
在粒子初始化中,我让粒子的初始位置保持在一个盒子当中,这样其效果就相当于irr中的粒子盒状发射器了。
在粒子更新中变动粒子颜色,修改粒子生命和粒子位置,或者粒子速度
其c++代码如下:
#include <GEngine/Main.hpp>
#include <luaplus/luaplus.h>
#define WIN_WIDTH 640
#define WIN_HEIGHT 480
////////////////////////////////////////////////////////////
/// 给出一个初始化粒子的方法
////////////////////////////////////////////////////////////
void G_CALL InitParticle(core:article* p,float t);
////////////////////////////////////////////////////////////
/// 更新粒子函数
////////////////////////////////////////////////////////////
void G_CALL UpdateParticle(core::Particle* p,float time);
////////////////////////////////////////////////////////////
/// 场景旋转和偏移
////////////////////////////////////////////////////////////
float TransForm(double t);
////////////////////////////////////////////////////////////
/// 渲染场景
////////////////////////////////////////////////////////////
void RenderScene();
core:evice* device = NULL;
LuaPlus:uaStateOwner *state = NULL;
////////////////////////////////////////////////////////////
/// 初始化luaplus
////////////////////////////////////////////////////////////
void InitLua(const char* lua)
{
state = device->GetLuaStateOwner();
// 载入Lua脚本
(*state)->DoFile(lua);
}
////////////////////////////////////////////////////////////
/// 从脚本载入粒子描述数据
////////////////////////////////////////////////////////////
void LoadData(core::ParticleSystemDesc &desc);
int main(int argc, char **argv)
{
int i;
double t0, t;
core::VideoMode mode;
mode.width = WIN_WIDTH;
mode.height = WIN_HEIGHT;
device = core::InitDevice("盖莫引擎粒子系统",false,mode);
InitLua("..\\script\\particle.lua");
//! 获取资源管理器
core::ResourceManager* resourcemanager = device->GetResourceManager();
core::RefPtr<core::Image> particleimage = resourcemanager->GetImage("particle","..\\image//particle//flare.bmp");
core::RefPtr<core::Texture> particletexture = resourcemanager->GetTexture("particle",particleimage);
particletexture->Bind();
core::ParticleSystemDesc desc;
desc.texture_id = particletexture->GetTextureId();
desc.init_fn = &InitParticle;
desc.update_fn = &UpdateParticle;
LoadData(desc);
core::ParticleSystem* ps = device->GetParticleSystem(desc);
t0 = device->GetTime();
BEGIN_LOOP(device)
t = device->GetTime() - t0;
RenderScene();
float dt = TransForm(t);
ps->Render();
END_LOOP(device)
device->Close();
device->Drop();
return 0;
}
////////////////////////////////////////////////////////////
/// 场景旋转和偏移
////////////////////////////////////////////////////////////
float TransForm(double t)
{
double xpos, ypos, zpos, angle_x, angle_y, angle_z;
static double t_old = 0.0;
float dt = (float)(t-t_old);
t_old = t;
angle_x = 90.0 - 10.0;
angle_y = 10.0 * sin( 0.3 * t );
angle_z = 10.0 * t;
glRotated( -angle_x, 1.0, 0.0, 0.0 );
glRotated( -angle_y, 0.0, 1.0, 0.0 );
glRotated( -angle_z, 0.0, 0.0, 1.0 );
xpos = 15.0 * sin( (M_PI/180.0) * angle_z ) +
2.0 * sin( (M_PI/180.0) * 3.1 * t );
ypos = -15.0 * cos( (M_PI/180.0) * angle_z ) +
2.0 * cos( (M_PI/180.0) * 2.9 * t );
zpos = 4.0 + 2.0 * cos( (M_PI/180.0) * 4.9 * t );
glTranslated( -xpos, -ypos, -zpos );
return dt;
}
void RenderScene()
{
glViewport( 0, 0, WIN_WIDTH,WIN_HEIGHT);
glClearColor( 0.1f, 0.1f, 0.1f, 1.0f );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective(65.0, 640.0/480.0, 1.0, 60.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
////////////////////////////////////////////////////////////
/// 给出一个初始化粒子的方法(t为粒子系统启动时间(单位:秒))
////////////////////////////////////////////////////////////
void G_CALL InitParticle(core::Particle* p,float t)
{
//! 初始化粒子位置位置
LuaPlus::LuaFunction<void> initpos(*state,"InitParticle");
initpos(t);
float xpos =(*state)->GetGlobal("xpos").GetFloat(); //GetByName("xpos").
float ypos =(*state)->GetGlobal("ypos").GetFloat();
float zpos =(*state)->GetGlobal("zpos").GetFloat();
p->position = Vector3f(xpos,ypos,zpos);
//! 初始化粒子颜色
p->color.red = (*state)->GetGlobal("red").GetFloat();
p->color.green = (*state)->GetGlobal("green").GetFloat();
p->color.blue = (*state)->GetGlobal("blue").GetFloat();
//! 初始化粒子初始速度
float xvel =(*state)->GetGlobal("xvel").GetFloat();
float yvel =(*state)->GetGlobal("yvel").GetFloat();
float zvel =(*state)->GetGlobal("zvel").GetFloat();
p->velocity = Vector3f(xvel,yvel,zvel);
}
////////////////////////////////////////////////////////////
/// 更新粒子函数
////////////////////////////////////////////////////////////
void G_CALL UpdateParticle(core::Particle* p,float time)
{
LuaPlus::LuaFunction<void> update_fn(*state,"UpdateParticles");
float life = p->life;
float xpos = p->position.x;
float ypos = p->position.y;
float zpos = p->position.z;
float xvel = p->velocity.x;
float yvel = p->velocity.y;
float zvel = p->velocity.z;
update_fn(life,xpos,ypos,zpos,xvel,yvel,zvel,time);
//! 获取更新后的粒子颜色
LuaPlus::LuaFunction<void> update_color(*state,"UpdateColor");
update_color(p->color.red,p->color.green,p->color.blue);
p->color.red = (*state)->GetGlobal("new_red").GetFloat();
p->color.green = (*state)->GetGlobal("new_green").GetFloat();
p->color.blue = (*state)->GetGlobal("new_blue").GetFloat();
//! 获取粒子的更新后数据
p->life = (*state)->GetGlobal("new_life").GetFloat();
p->position.x = (*state)->GetGlobal("new_xpos").GetFloat();
p->position.y = (*state)->GetGlobal("new_ypos").GetFloat();
p->position.z = (*state)->GetGlobal("new_zpos").GetFloat();
p->velocity.x = (*state)->GetGlobal("new_xvel").GetFloat();
p->velocity.y = (*state)->GetGlobal("new_yvel").GetFloat();
p->velocity.z = (*state)->GetGlobal("new_zvel").GetFloat();
}
////////////////////////////////////////////////////////////
/// 从脚本载入粒子描述数据
////////////////////////////////////////////////////////////
void LoadData(core::ParticleSystemDesc &desc)
{
desc.batch_particles = (*state)->GetGlobal("batch_particles").GetInteger();
desc.particle_size = (*state)->GetGlobal("particle_size").GetFloat();
desc.life_span = (*state)->GetGlobal("particle_life").GetFloat();
int max_particles = (*state)->GetGlobal("max_particles").GetInteger();
desc.particle_number = max_particles;
}
当然代码中没有检测错误和异常.
其输出图形如下所示:
|
|