游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2199|回复: 0

???????????

[复制链接]

50

主题

69

帖子

69

积分

注册会员

Rank: 2

积分
69
发表于 2010-2-24 15:12:00 | 显示全部楼层 |阅读模式
?????????????,??????,?????????????????????????????????,????????,???????????????:

typedef void(G_CALL *InitParticleFn)(Particle* p,float time);
typedef void(G_CALL *UpdateParticleFn)(Particle* p,float time);  
   
////////////////////////////////////////////////////////////
/// ???????????
////////////////////////////////////////////////////////////
struct ParticleSystemDesc
{
    ParticleSystemDesc():texture_id(0),
                         init_fn(NULL),
                         update_fn(NULL),
                         particle_number(2000),
                         life_span(8.0f),
                         birth_interval(life_span/(float)particle_number),
                         batch_particles(1),
                         particle_size(1.0f)      
    {
    }
~ParticleSystemDesc(){}
   
    int              texture_id;  
    InitParticleFn   init_fn;
    UpdateParticleFn update_fn;   
    int              particle_number;
    float            life_span;
    float            birth_interval;
    int              batch_particles;
float            particle_size;
};  
  
////////////////////////////////////////////////////////////
/// ?????????
////////////////////////////////////////////////////////////  
class  ParticleSystem : NonCopyable, public Renderable  
{
public:
    ////////////////////////////////////////////////////////
    /// ????????(??????????????????????)
    ////////////////////////////////////////////////////////     
ParticleSystem(const ParticleSystemDesc &desc):desc(desc){}
~ParticleSystem(){}
public:
    void BeginRender(){}
    void AfterRender(){}

protected:
ParticleSystemDesc           desc;
};

??????:






??????:
#include <GEngine/Main.hpp>
#define WIN_WIDTH  640
#define WIN_HEIGHT 480
//! ????
static const unsigned char particle_texture[] =
{
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x11, 0x22, 0x22, 0x11, 0x00, 0x00,
    0x00, 0x11, 0x33, 0x88, 0x77, 0x33, 0x11, 0x00,
    0x00, 0x22, 0x88, 0xff, 0xee, 0x77, 0x22, 0x00,
    0x00, 0x22, 0x77, 0xee, 0xff, 0x88, 0x22, 0x00,
    0x00, 0x11, 0x33, 0x77, 0x88, 0x33, 0x11, 0x00,
    0x00, 0x00, 0x11, 0x33, 0x22, 0x11, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//! ????
#define PARTICLE_SIZE   0.7f
//! ???????
#define GRAVITY         9.8f
//! ???????
#define VELOCITY        8.0f
//! ??????
#define FOUNTAIN_HEIGHT 3.0f
//! ??????
#define FOUNTAIN_RADIUS 1.6f
//! ??????  
#define P_TEX_WIDTH  8   
#define P_TEX_HEIGHT 8
//! ???????????(1????,0?????)
#define FRICTION        0.75f
#define FOUNTAIN_R2 (FOUNTAIN_RADIUS+PARTICLE_SIZE/2)*(FOUNTAIN_RADIUS+PARTICLE_SIZE/2)
////////////////////////////////////////////////////////////
/// ????????????
////////////////////////////////////////////////////////////
void G_CALL InitParticle(core:article* p,float t);
////////////////////////////////////////////////////////////
/// ??????
////////////////////////////////////////////////////////////
void G_CALL UpdateParticle(core::Particle* p,float time);
////////////////////////////////////////////////////////////
/// ???????
////////////////////////////////////////////////////////////
float TransForm(double t);

////////////////////////////////////////////////////////////
/// ????
////////////////////////////////////////////////////////////  
void BuildTexture(GLuint& texture_id);
////////////////////////////////////////////////////////////
/// ????
////////////////////////////////////////////////////////////
void RenderScene();
core:evice* device = NULL;
libmath::TriTable* table = NULL;  

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);
    table = device->GetTriTable();

    core::ParticleSystemDesc desc;
   
    GLuint texture_id;
    BuildTexture(texture_id);
    desc.texture_id = texture_id;   
    desc.init_fn = &InitParticle;
    desc.update_fn = &UpdateParticle;
    desc.batch_particles = 80;
    desc.particle_size = 0.6f;
    desc.life_span = 8;
   
    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;
}

void BuildTexture(GLuint& texture_id)
{
    glGenTextures( 1, &texture_id );
    glBindTexture( GL_TEXTURE_2D, texture_id);
    glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, P_TEX_WIDTH, P_TEX_HEIGHT,
                 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, particle_texture);  
}
////////////////////////////////////////////////////////////
/// ???????
////////////////////////////////////////////////////////////
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)
{
    //! ???????
    p->position = Vector3f(0,0,FOUNTAIN_HEIGHT);

    //! ??????z???
    p->velocity.z = 0.7f + (0.3/4096.0) * (float) (rand() & 4095);
    //! ????xy??????
    float xy_angle = (2.0*M_PI/4096.0) * (float) (rand() & 4095);
    p->velocity.x = 0.45f * table->CosTable(xy_angle);
    p->velocity.y = 0.45f * table->SinTable(xy_angle);
    //! ????????????
    float velocity = VELOCITY*(0.8f + 0.1f*(float)(table->SinTable(0.5*t)+table->SinTable(0.31*t)));
    p->velocity.x *= velocity;
    p->velocity.y *= velocity;
    p->velocity.z *= velocity;
    //! ????????
    p->color.red   = 0.7f + 0.3f * table->SinTable(0.34*t + 0.1);
    p->color.green = 0.6f + 0.4f * table->SinTable(0.63*t + 1.1);
    p->color.blue  = 0.6f + 0.4f * table->SinTable(0.91*t + 2.1);
}
////////////////////////////////////////////////////////////
/// ??????
////////////////////////////////////////////////////////////
void G_CALL UpdateParticle(core::Particle* p,float time)
{
    float dt = time;
    //! ??????
    p->life = p->life - dt * (1.0f / 8.0f);
    //! ??????
    p->velocity.z = p->velocity.z - GRAVITY  *dt;
    p->position  += p->velocity * dt;

    //! ???????
    if( p->velocity.z < 0.0f )
    {
        if((p->position.x*p->position.x + p->position.y*p->position.y) < FOUNTAIN_R2 &&
            p->position.z < (FOUNTAIN_HEIGHT + PARTICLE_SIZE/2) )
        {
            p->velocity.z = -FRICTION * p->velocity.z;
            p->position.z  = FOUNTAIN_HEIGHT + PARTICLE_SIZE/2 +
                        FRICTION * (FOUNTAIN_HEIGHT +
                        PARTICLE_SIZE/2 - p->position.z);
        }
        //! ?????????????
        else if( p->position.z < PARTICLE_SIZE/2 )
        {
            p->velocity.z = -FRICTION * p->velocity.z;
            p->position.z  = PARTICLE_SIZE/2 + FRICTION * (PARTICLE_SIZE/2 - p->position.z);
        }
    }
}

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-10-15 01:23

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表