Автоматизированное редактирование частиц в компьютерной графике
Разработка редактора частиц "Easy Particles", позволяющего создавать несложные эффекты графики. Инсталляция программы, анализ ее надёжности. Модель и сборка приложения. Обоснование экономической целесообразности разработки программного средства.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | дипломная работа |
Язык | русский |
Дата добавления | 09.09.2010 |
Размер файла | 742,6 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
{
if( (layer < 0) || (layer >= (int)all_ps.size()) )
selectedSystemLayer = -1;
else
selectedSystemLayer = layer;
}
int ParticleSystemChain::GetSelectedSystemLayer() const
{
return selectedSystemLayer;
}
ParticleSystemChainWorkMode ParticleSystemChain::GetWorkMode() const
{
return workMode;
}
void ParticleSystemChain::SetWorkMode(ParticleSystemChainWorkMode mode)
{
vector<ParticleSystem*>::iterator begin_iter = all_ps.begin();
vector<ParticleSystem*>::iterator end_iter = all_ps.end();
vector<ParticleSystem*>::iterator iter = begin_iter;
if(mode == ParticleSystemChainWorkMode_PLAYBACK || mode == ParticleSystemChainWorkMode_PLAYBACK_LOOP)
{
while(iter != end_iter)
{
(*iter)->start();
++iter;
}
timer.reset();
}
else//if(mode == ParticleSystemChainWorkMode_STATIC)
{
while(iter != end_iter)
{
(*iter)->stopExtra();
++iter;
}
}
workMode = mode;
}
void ParticleSystemChain::CallbackSystems()
{
if(workMode == ParticleSystemChainWorkMode_STATIC)
return;
double sec_interval = timer.getMilliseconds() / 1000.0;
timer.reset();
vector<ParticleSystem*>::iterator iter = all_ps.begin();
bool chain_is_run = false;
while(iter != all_ps.end())
{
(*iter)->callback(sec_interval);
if(!(*iter)->isFinished())
chain_is_run = true;
++iter;
}
if(chain_is_run)
return;
//!chain_is_run
if(workMode == ParticleSystemChainWorkMode_PLAYBACK)
SetWorkMode(ParticleSystemChainWorkMode_STATIC);
else// if(workMode == ParticleSystemChainWorkMode_PLAYBACK_LOOP)
SetWorkMode(ParticleSystemChainWorkMode_PLAYBACK_LOOP);//just restart
}
void ParticleSystemChain::DrawSystems()
{
vector<ParticleSystem*>::iterator iter = all_ps.begin();
if(workMode != ParticleSystemChainWorkMode_STATIC)
{
glEnable(GL_BLEND);
glBlendFunc(blendModeSrc, blendModeDst);
while(iter != all_ps.end())
{
(*iter)->draw();
++iter;
}
glDisable(GL_BLEND);
}
else
{
int i = 0;
while(iter != all_ps.end())
{
ParticleSystem* curr_ps = (*iter);
if(i == selectedSystemLayer)
curr_ps->setBoundColor(PSBOUND_SELECTED_COLOR);
else if(i == choosedSystemLayer)
curr_ps->setBoundColor(PSBOUNS_CHOOSED_COLOR);
else
curr_ps->setBoundColor(PSBOUND_COLOR);
curr_ps->drawBound();
++iter, ++i;
}
}
}
int ParticleSystemChain::GetBlendModeSrc() const
{
return blendModeSrc;
}
int ParticleSystemChain::GetBlendModeDst() const
{
return blendModeDst;
}
void ParticleSystemChain::SetBlendModeSrc(int mode)
{
blendModeSrc = mode;
}
void ParticleSystemChain::SetBlendModeDst(int mode)
{
blendModeDst = mode;
}
ParticleSystem* ParticleSystemChain::GetSystemAtLayer(int layer)
{
if( layer < 0 || layer >= (int)all_ps.size() )
return NULL;
return all_ps.at(layer);
}
MYRect ParticleSystemChain::GetInitialSystemsRect(unsigned int *systems_counter) const//systems bound rect on gl
{
*systems_counter = (unsigned int)all_ps.size();
double min_x = 0.0;
double min_y = 0.0;
double max_x = 0.0;
double max_y = 0.0;
vector<ParticleSystem*>::const_iterator begin_iter = all_ps.begin();
vector<ParticleSystem*>::const_iterator end_iter = all_ps.end();
vector<ParticleSystem*>::const_iterator iter = begin_iter;
while(iter != end_iter)
{
bool thereis_begin_ps = (iter == begin_iter);
if(thereis_begin_ps || min_x > (*iter)->data.initialX)
min_x = (*iter)->data.initialX;
if(thereis_begin_ps || min_y > (*iter)->data.initialY)
min_y = (*iter)->data.initialY;
double new_max = (*iter)->data.initialX + (*iter)->data.pAppearBoxSize.width;
if(thereis_begin_ps || max_x < new_max)
max_x = new_max;
new_max = (*iter)->data.initialY + (*iter)->data.pAppearBoxSize.height;
if(thereis_begin_ps || max_y < new_max)
max_y = new_max;
++iter;
}
MYPoint2D pos = MYPoint2DMake(min_x, min_y);
MYSize2D sz = MYSize2DMake(max_x - min_x, max_y - min_y);
return(MYRectMake(pos,sz));
}
int ParticleSystemChain::GetNumofSystems() const
{
return (int)all_ps.size();
}
//internals
ParticleSystemChain::ParticleSystemChain()
{
workMode = DEFAULT_PARTICLE_SYSTEM_CHAIN_WORK_MODE;
blendModeSrc = GL_ONE;
blendModeDst = GL_ONE_MINUS_SRC_ALPHA;
selectedSystemLayer = choosedSystemLayer = -1;
}
ParticleSystemChain::~ParticleSystemChain()
{
RemoveAll();
}
bool ParticleSystemChain::saveSystems(TiXmlElement* root) const
{
TiXmlElement tmp("SYSTEMS_DATA");
TiXmlElement *sys_data = (TiXmlElement*)root->InsertEndChild(tmp);
if(!sys_data)
return false;
sys_data->SetAttribute(ITEM_SELECTED, selectedSystemLayer);
if(all_ps.size() == 0)
return true;
vector<ParticleSystem*>::const_iterator iter = all_ps.end();
do
{
--iter;
if(!(*iter)->save(root))
return false;
}
while(iter != all_ps.begin());
return true;
}
bool ParticleSystemChain::loadSystems(TiXmlElement* root)
{
TiXmlElement *systems_data_ptr = (TiXmlElement*)root->FirstChild("SYSTEMS_DATA");
int selected_system_layer = -1;
if(systems_data_ptr)//new format file (ver. above 1.0)
systems_data_ptr->Attribute(ITEM_SELECTED, &selected_system_layer);
vector<ParticleSystem*> tmp_all_ps;
ParticleSystem *tmp_ps_ptr = new ParticleSystem();
while(bool is_success = tmp_ps_ptr->load(root))
{
tmp_all_ps.insert(tmp_all_ps.begin(), tmp_ps_ptr);
tmp_ps_ptr = new ParticleSystem();
}
delete tmp_ps_ptr;
if(tmp_all_ps.size() > 0 && selected_system_layer < 0)
selectedSystemLayer = 0;
else
selectedSystemLayer = selected_system_layer;
//remove all old-created and add new
vector<ParticleSystem*>::iterator iter = all_ps.begin();
while(iter != all_ps.end())
{
delete((ParticleSystem*)*iter);
++iter;
}
all_ps.clear();
tmp_all_ps.swap(all_ps);
workMode = ParticleSystemChainWorkMode_STATIC;
return true;
}
//ParticleSystem.cpp (эмиттер)
#include "ParticleSystem.h"
#include "MYSpinCtrld.h"
#define PS_BOUNDED_RECT_COLOR wxColour(150, 150, 150, 255)
//XML element's attributes of PSs
#define TEXTURE_ATTR "texture_file_name"
#define LIFE_TIME_ATTR "life_time"
#define APPEAR_DELAY_ATTR "appear_delay"
#define PARTICLE_SPEED_X_ATTR "particle_speed_x"
#define PARTICLE_SPEED_Y_ATTR "particle_speed_y"
#define GRAVITY_X_ATTR "gravity_x"
#define GRAVITY_Y_ATTR "gravity_y"
#define MAX_COUNT_ATTR "max_count"
#define START_COUNT_ATTR "start_count"
#define APPEAR_BOX_W_ATTR "appear_box_w"
#define APPEAR_BOX_H_ATTR "appear_box_h"
#define RED_BEGIN_ATTR "red_begin"
#define RED_END_ATTR "red_end"
#define GREEN_BEGIN_ATTR "green_begin"
#define GREEN_END_ATTR "green_end"
#define BLUE_BEGIN_ATTR "blue_begin"
#define BLUE_END_ATTR "blue_end"
#define ALPHA_BEGIN_ATTR "alpha_begin"
#define ALPHA_END_ATTR "alpha_end"
#define SCALE_BEGIN_W_ATTR "scale_begin_w"
#define SCALE_BEGIN_H_ATTR "scale_begin_h"
#define SCALE_END_W_ATTR "scale_end_w"
#define SCALE_END_H_ATTR "scale_end_h"
#define DISPERSION_X_ATTR "dispersion_x"
#define DISPERSION_Y_ATTR "dispersion_y"
#define PS_X_ATTR "ps_x"
#define PS_Y_ATTR "ps_y"
#define PS_SPEED_X_ATTR "ps_speed_x"
#define PS_SPEED_Y_ATTR "ps_speed_y"
#define START_DELAY_ATTR "start_delay"
#define STOP_DELAY_ATTR "stop_delay"
#define ROTATE_ATTR "rotate"
//ctors, destructors, ...
ParticleSystem::ParticleSystem()
{
data.pLifeTime= 1.0;
data.pMaxCount = EXPL_MAX;
data.pCountOnStart = 1;
data.pGravityX = data.pGravityY = 0.0;
//p.speed, dispersion page
data.pMoveSpeedX = 0.0;
data.pMoveSpeedY = 0.0;
data.pKFDispersionX = 0.0;
data.pKFDispersionY = 0.0;
//p.scale page
data.pKFScaleBeginW = 1.0;
data.pKFScaleBeginH = 1.0;
data.pKFScaleEndW = 1.0;
data.pKFScaleEndH = 1.0;
//p.color page
data.pRedBegin = 1.0;
data.pGreenBegin = 1.0;
data.pBlueBegin = 1.0;
data.pAlphaBegin = 1.0;
data.pRedEnd = 1.0;
data.pGreenEnd = 1.0;
data.pBlueEnd = 1.0;
data.pAlphaEnd = 1.0;
//rotate
data.pAngleRotate = 0.0;
//start in, stop in page
data.startDelay = 0.0;
data.stopDelay = 1800.0;
data.pAppearDelay = 0.0;
//PS settings page
MYSize2D sz = {100.0,100.0};
data.pAppearBoxSize = sz;
data.speedChangeX = 0;
data.speedChangeY = 0;
data.initialX = currentX = BOUND_DIMENSION;
data.initialY = currentY = BOUND_DIMENSION;
boundedRectColor = PS_BOUNDED_RECT_COLOR;
particleTexPtr = NULL;
setDefaultParticleTex();
isRunb = false;
isFinishedb = false;
viewMatrixCache = (GLdouble*)malloc(sizeof(GLdouble) * 16);
assert(viewMatrixCache != NULL);
}
ParticleSystem::~ParticleSystem()
{
free(viewMatrixCache);
if(particleTexPtr)
delete particleTexPtr;
}
int ParticleSystem::setParticleTex(const wxString &texture_path)
{
MYTexture* tmp_tex = new MYTexture(texture_path);
int res = tmp_tex->getState();
if(res != TEX_OK)
{
delete tmp_tex;
return res;
}
if(particleTexPtr)
delete particleTexPtr;
particleTexPtr = tmp_tex;
data.particleTexFileName = texture_path;
MYTexCoordPoint *ptrTex = texCoord;
for(int i = 0; i < EXPL_MAX; i++)
{
ptrTex->x = 0.0; ptrTex->y = 0.0;
ptrTex++;
ptrTex->x = particleTexPtr->getMaxS(); ptrTex->y = 0.0;
ptrTex++;
ptrTex->x = particleTexPtr->getMaxS(); ptrTex->y = particleTexPtr->getMaxT();
ptrTex++;
ptrTex->x = 0.0; ptrTex->y = 0.0;
ptrTex++;
ptrTex->x = particleTexPtr->getMaxS(); ptrTex->y = particleTexPtr->getMaxT();
ptrTex++;
ptrTex->x = 0.0; ptrTex->y = particleTexPtr->getMaxT();
ptrTex++;
}
return TEX_OK;
}
void ParticleSystem::setDefaultParticleTex()
{
if(particleTexPtr)
delete particleTexPtr;
GLubyte *buffer = new GLubyte[8 * 8 * 4];
memset(buffer, 255, 8*8*4);//white colour
particleTexPtr = new MYTexture(32,16711680/*third byte pattern*/,65280/*second byte pattern*/,255/*first byte pattern*/
,8,8,buffer);
delete[] buffer;
data.particleTexFileName = wxString("");
}
double ParticleSystem::getX() const
{
return currentX;
}
double ParticleSystem::getY() const
{
return currentY;
}
void ParticleSystem::setX(double x)
{
data.initialX = currentX = x;
}
void ParticleSystem::setY(double y)
{
data.initialY = currentY = y;
}
double ParticleSystem::getSpeedChangeX() const
{
return data.speedChangeX;
}
double ParticleSystem::getSpeedChangeY() const
{
return data.speedChangeY;
}
void ParticleSystem::setSpeedChangeX(double speed)
{
data.speedChangeX = speed;
}
void ParticleSystem::setSpeedChangeY(double speed)
{
data.speedChangeY = speed;
}
double ParticleSystem::getStopDelay() const
{
return data.stopDelay;
}
double ParticleSystem::getStartDelay() const
{
return data.startDelay;
}
void ParticleSystem::setStopDelay(double time)
{
data.stopDelay = time;
}
void ParticleSystem::setStartDelay(double time)
{
data.startDelay = time;
}
double ParticleSystem::getLifeTime() const
{
return data.pLifeTime;
}
void ParticleSystem::setLifeTime(double time)
{
data.pLifeTime = time;
}
double ParticleSystem::getParticleAppearDelay() const
{
return data.pAppearDelay;
}
void ParticleSystem::setParticleAppearDelay(double time)
{
data.pAppearDelay = time;
}
double ParticleSystem::getMoveSpeedX() const
{
return data.pMoveSpeedX;
}
double ParticleSystem::getMoveSpeedY() const
{
return data.pMoveSpeedY;
}
void ParticleSystem::setMoveSpeedX(double speed)
{
data.pMoveSpeedX = speed;
}
void ParticleSystem::setMoveSpeedY(double speed)
{
data.pMoveSpeedY = speed;
}
double ParticleSystem::getGravityX() const
{
return data.pGravityX;
}
double ParticleSystem::getGravityY() const
{
return data.pGravityY;
}
void ParticleSystem::setGravityX(double gravity)
{
data.pGravityX = gravity;
}
void ParticleSystem::setGravityY(double gravity)
{
data.pGravityY = gravity;
}
int ParticleSystem::getMaxCount() const
{
return data.pMaxCount;
}
void ParticleSystem::setMaxCount(int count)
{
data.pMaxCount = count;
if(data.pCountOnStart > data.pMaxCount)
data.pCountOnStart = data.pMaxCount;
}
int ParticleSystem::getCountOnStart() const
{
return data.pCountOnStart;
}
void ParticleSystem::setCountOnStart(int count)
{
data.pCountOnStart = count;
}
MYSize2D ParticleSystem::getAppearBoxSize() const
{
return data.pAppearBoxSize;
}
void ParticleSystem::setAppearBoxSize(MYSize2D box)
{
data.pAppearBoxSize = box;
}
double ParticleSystem::getRedBegin() const
{
return data.pRedBegin;
}
double ParticleSystem::getGreenBegin() const
{
return data.pGreenBegin;
}
double ParticleSystem::getBlueBegin() const
{
return data.pBlueBegin;
}
double ParticleSystem::getAlphaBegin() const
{
return data.pAlphaBegin;
}
void ParticleSystem::setRedBegin(double red)
{
data.pRedBegin = red;
}
void ParticleSystem::setGreenBegin(double green)
{
data.pGreenBegin = green;
}
void ParticleSystem::setBlueBegin(double blue)
{
data.pBlueBegin = blue;
}
void ParticleSystem::setAlphaBegin(double alpha)
{
data.pAlphaBegin = alpha;
}
double ParticleSystem::getRedEnd() const
{
return data.pRedEnd;
}
double ParticleSystem::getGreenEnd() const
{
return data.pGreenEnd;
}
double ParticleSystem::getBlueEnd() const
{
return data.pBlueEnd;
}
double ParticleSystem::getAlphaEnd() const
{
return data.pAlphaEnd;
}
void ParticleSystem::setRedEnd(double red)
{
data.pRedEnd = red;
}
void ParticleSystem::setGreenEnd(double green)
{
data.pGreenEnd = green;
}
void ParticleSystem::setBlueEnd(double blue)
{
data.pBlueEnd = blue;
}
void ParticleSystem::setAlphaEnd(double alpha)
{
data.pAlphaEnd = alpha;
}
double ParticleSystem::getRotateAngle() const
{
return data.pAngleRotate;
}
void ParticleSystem::setRotateAngle(double angle)
{
data.pAngleRotate = angle;
}
double ParticleSystem::getKFScaleBeginW() const
{
return data.pKFScaleBeginW;
}
double ParticleSystem::getKFScaleBeginH() const
{
return data.pKFScaleBeginH;
}
void ParticleSystem::setKFScaleBeginW(double scale)
{
data.pKFScaleBeginW = scale;
}
void ParticleSystem::setKFScaleBeginH(double scale)
{
data.pKFScaleBeginH = scale;
}
double ParticleSystem::getKFScaleEndW() const
{
return data.pKFScaleEndW;
}
double ParticleSystem::getKFScaleEndH() const
{
return data.pKFScaleEndH;
}
void ParticleSystem::setKFScaleEndW(double scale)
{
data.pKFScaleEndW = scale;
}
void ParticleSystem::setKFScaleEndH(double scale)
{
data.pKFScaleEndH = scale;
}
double ParticleSystem::getKFDispersionX() const
{
return data.pKFDispersionX;
}
double ParticleSystem::getKFDispersionY() const
{
return data.pKFDispersionY;
}
void ParticleSystem::setKFDispersionX(double disp)
{
data.pKFDispersionX = disp;
}
void ParticleSystem::setKFDispersionY(double disp)
{
data.pKFDispersionY = disp;
}
wxString ParticleSystem::getParticleTexFileName() const
{
return data.particleTexFileName;
}
void ParticleSystem::copyDataFromParticleSystem(ParticleSystem* sys_from)
{
if(!sys_from)
return;
data.pLifeTime = sys_from->data.pLifeTime;
data.pMaxCount = sys_from->data.pMaxCount;
data.pCountOnStart = sys_from->data.pCountOnStart;
data.pGravityX = sys_from->data.pGravityX;
data.pGravityY = sys_from->data.pGravityY;
//p.speed, dispersion page
data.pMoveSpeedX = sys_from->data.pMoveSpeedX;
data.pMoveSpeedY = sys_from->data.pMoveSpeedY;
data.pKFDispersionX = sys_from->data.pKFDispersionX;
data.pKFDispersionY = sys_from->data.pKFDispersionY;
//p.scale page
data.pKFScaleBeginW = sys_from->data.pKFScaleBeginW;
data.pKFScaleBeginH = sys_from->data.pKFScaleBeginH;
data.pKFScaleEndW = sys_from->data.pKFScaleEndW;
data.pKFScaleEndH = sys_from->data.pKFScaleEndH;
//p.color page
data.pRedBegin = sys_from->data.pRedBegin;
data.pGreenBegin = sys_from->data.pGreenBegin;
data.pBlueBegin = sys_from->data.pBlueBegin;
data.pAlphaBegin = sys_from->data.pAlphaBegin;
data.pRedEnd = sys_from->data.pRedEnd;
data.pGreenEnd = sys_from->data.pGreenEnd;
data.pBlueEnd = sys_from->data.pBlueEnd;
data.pAlphaEnd = sys_from->data.pAlphaEnd;
//rotate
data.pAngleRotate = sys_from->data.pAngleRotate;
//start in, stop in page
data.startDelay = sys_from->data.startDelay;
data.stopDelay = sys_from->data.stopDelay;
data.pAppearDelay = sys_from->data.pAppearDelay;
//PS settings page
data.pAppearBoxSize = sys_from->data.pAppearBoxSize;
data.speedChangeX = sys_from->data.speedChangeX;
data.speedChangeY = sys_from->data.speedChangeY;
setX(sys_from->data.initialX);
setY(sys_from->data.initialY);
if(sys_from->data.particleTexFileName == "")
setDefaultParticleTex();
else
setParticleTex(sys_from->data.particleTexFileName);
}
bool ParticleSystem::isRun() const
{
return isRunb;
}
bool ParticleSystem::isFinished() const
{
return isFinishedb;
}
void ParticleSystem::start()
{
isRunb = true;
isFinishedb = false;
restart();
}
void ParticleSystem::stop()
{
isRunb = false;
}
void ParticleSystem::stopExtra()
{
isRunb = false;
finish();
}
void ParticleSystem::finish()
{
isFinishedb = true;
currentX = data.initialX;
currentY = data.initialY;
}
void ParticleSystem::restart()
{
startInTime = data.startDelay;
stopInTime = data.stopDelay;
timeForNextParticle = data.pAppearDelay;
int count = data.pCountOnStart;
for (int i=0; i<EXPL_MAX; i++)
{
if (count > 0)
{
initParticleAtIndex(i);
count--;
}
else
{
pTM[i] = 0;
}
}
}
void ParticleSystem::initParticleAtIndex(int i)
{
assert(i >= 0 && i < EXPL_MAX);
pTM[i] = data.pLifeTime;
pX[i] = fmod(rand(), data.pAppearBoxSize.width);
pY[i] = fmod(rand(), data.pAppearBoxSize.height);
double speedDeltaX = fmod(rand(), data.pKFDispersionX * 2 + 1) - data.pKFDispersionX;
pDx[i] = data.pMoveSpeedX + speedDeltaX;
double speedDeltaY = fmod(rand(), data.pKFDispersionY * 2 + 1) - data.pKFDispersionY;
pDy[i] = data.pMoveSpeedY + speedDeltaY;
}
void ParticleSystem::drawBound()
{
double appear_w = data.pAppearBoxSize.width;
double appear_h = data.pAppearBoxSize.height;
//draw bound itself
glColor4d(boundColor.Red()/255.0, boundColor.Green()/255.0, boundColor.Blue()/255.0, boundColor.Alpha()/255.0);
glBegin(GL_POLYGON);
glVertex2d(currentX - BOUND_DIMENSION, currentY - BOUND_DIMENSION);
glVertex2d(currentX + appear_w + BOUND_DIMENSION, currentY - BOUND_DIMENSION);
glVertex2d(currentX + appear_w + BOUND_DIMENSION, currentY + appear_h + BOUND_DIMENSION);
glVertex2d(currentX - BOUND_DIMENSION, currentY + appear_h + BOUND_DIMENSION);
glEnd();
//draw inner part of bound
glColor4d(boundedRectColor.Red()/255.0, boundedRectColor.Green()/255.0, boundedRectColor.Blue()/255.0,
boundedRectColor.Alpha()/255.0);
glBegin(GL_POLYGON);
glVertex2d(currentX, currentY);
glVertex2d(currentX + appear_w, currentY);
glVertex2d(currentX + appear_w, currentY + appear_h);
glVertex2d(currentX, currentY + appear_h);
glEnd();
if(!particleTexPtr)
return;
//draw texture on left-top
double tex_w = particleTexPtr->getWidth();
double tex_h = particleTexPtr->getHeight();
glEnable(GL_TEXTURE_2D);
GLint binded;
glGetIntegerv(GL_TEXTURE_BINDING_2D,&binded);
glBindTexture(GL_TEXTURE_2D, particleTexPtr->getName());
glColor4d(1.0,1.0,1.0,1.0);
double real_tex_w, real_tex_h;
real_tex_w = min(appear_w, tex_w);
real_tex_h = min(appear_h, tex_h);
double real_tex_s, real_tex_t;
real_tex_s = particleTexPtr->getMaxS() * ((double)real_tex_w) / ((double)tex_w);
real_tex_t = particleTexPtr->getMaxT() * ((double)real_tex_h) / ((double)tex_h);
glBegin(GL_POLYGON);
glTexCoord2d(0.0, 0.0);
glVertex2d(currentX, currentY);
glTexCoord2d(real_tex_s, 0.0);//texCoord[0].x,texCoord[0].y);
glVertex2d(currentX + real_tex_w, currentY);
glTexCoord2d(real_tex_s, real_tex_t);//texCoord[1].x,texCoord[1].y);
glVertex2d(currentX + real_tex_w, currentY + real_tex_h);
glTexCoord2d(0.0, real_tex_t);
glVertex2d(currentX, currentY + real_tex_h);
glEnd();
glBindTexture(GL_TEXTURE_2D, binded);
glDisable(GL_TEXTURE_2D);
}
void ParticleSystem::draw()
{
if(!particleTexPtr)
return;
if (isFinishedb)
return;
//if (int(startInTime*maj_kof) > 0)
if(startInTime > 0.0)
return;
glMatrixMode(GL_MODELVIEW);
MYPoint2D *ptrVert = verCoord;
MYParticleColor *ptrColor = color;
int count = 0;
double progress, x, y, w, h, r, g, b, a;
bool is_rotate = (data.pAngleRotate != 0.0);
for (int i = 0; i < EXPL_MAX; ++i)
{
progress = pTM[i];
x = pX[i];
y = pY[i];
if(progress > 0.0)
{
progress /= data.pLifeTime;
w = (data.pKFScaleEndW + progress * (data.pKFScaleBeginW - data.pKFScaleEndW)) * particleTexPtr->getWidth();
h = (data.pKFScaleEndH + progress * (data.pKFScaleBeginH - data.pKFScaleEndH)) * particleTexPtr->getHeight();
if(is_rotate)
{
double real_alpha = fmod(data.pAngleRotate * 360.0 * progress, 360.0);
glPushMatrix();
glTranslated(x, y, 0.0);
glRotated(real_alpha, 0.0, 0.0, 1.0);//clock wise direction
x = y = 0.0;
}
x -= w/2.0;//only CENTERS of particles initially placed in AppearingBox (0.5,0.5 origin)
y -= h/2.0;//only CENTERS of particles initially placed in AppearingBox (0.5,0.5 origin)
r = data.pRedEnd + progress * (data.pRedBegin - data.pRedEnd);
g = data.pGreenEnd + progress * (data.pGreenBegin - data.pGreenEnd);
b = data.pBlueEnd + progress * (data.pBlueBegin - data.pBlueEnd);
a = data.pAlphaEnd + progress * (data.pAlphaBegin - data.pAlphaEnd);
ptrColor->r = r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r = r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r = r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r = r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r = r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
ptrColor->r = r; ptrColor->g = g; ptrColor->b = b; ptrColor->a = a; ptrColor++;
if(is_rotate)
{
double* m = viewMatrixCache;
glGetDoublev(GL_MODELVIEW_MATRIX, m);
double x2 = x + w;
double y2 = y + h;
double* tp = (double*)ptrVert;
ptrVert->x = m[0]*x + m[4]*y + m[12];ptrVert->y = m[1]*x + m[5]*y + m[13];ptrVert++;
ptrVert->x = m[0]*x2 + m[4]*y + m[12];ptrVert->y = m[1]*x2 + m[5]*y + m[13];ptrVert++;
ptrVert->x = m[0]*x2 + m[4]*y2 + m[12];ptrVert->y = m[1]*x2 + m[5]*y2 + m[13]; ptrVert++;
ptrVert->x = tp[0]; ptrVert->y = tp[1]; ptrVert++;
ptrVert->x = tp[4]; ptrVert->y = tp[5]; ptrVert++;
ptrVert->x = m[0]*x + m[4]*y2 + m[12];ptrVert->y = m[1]*x + m[5]*y2 + m[13];ptrVert++;
glPopMatrix();
}
else
{
ptrVert->x = x;ptrVert->y = y;ptrVert++;
ptrVert->x = x+w;ptrVert->y = y;ptrVert++;
ptrVert->x = x+w;ptrVert->y = y+h;ptrVert++;
ptrVert->x = x;ptrVert->y = y;ptrVert++;
ptrVert->x = x+w;ptrVert->y = y+h;ptrVert++;
ptrVert->x = x;ptrVert->y = y+h;ptrVert++;
}
count++;
}
}
glPushMatrix();
glTranslated(currentX, currentY, 0.0);
glEnable(GL_TEXTURE_2D);
GLint binded;
glGetIntegerv(GL_TEXTURE_BINDING_2D,&binded);
glBindTexture(GL_TEXTURE_2D, particleTexPtr->getName());
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_DOUBLE, 0, verCoord);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_DOUBLE, 0, texCoord);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_DOUBLE, 0, color);
glDrawArrays(GL_TRIANGLES, 0, count*6);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glBindTexture(GL_TEXTURE_2D,binded);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
bool ParticleSystem::save(TiXmlElement* root_ptr) const
{
TiXmlElement element("PS");
element.SetAttribute(TEXTURE_ATTR, data.particleTexFileName);
element.SetDoubleAttribute(LIFE_TIME_ATTR, data.pLifeTime);
element.SetDoubleAttribute(APPEAR_DELAY_ATTR, data.pAppearDelay);
element.SetDoubleAttribute(PARTICLE_SPEED_X_ATTR, data.pMoveSpeedX);
element.SetDoubleAttribute(PARTICLE_SPEED_Y_ATTR, data.pMoveSpeedY);
element.SetDoubleAttribute(GRAVITY_X_ATTR, data.pGravityX);
element.SetDoubleAttribute(GRAVITY_Y_ATTR, data.pGravityY);
element.SetAttribute(MAX_COUNT_ATTR, data.pMaxCount);
element.SetAttribute(START_COUNT_ATTR, data.pCountOnStart);
element.SetDoubleAttribute(APPEAR_BOX_W_ATTR, data.pAppearBoxSize.width);
element.SetDoubleAttribute(APPEAR_BOX_H_ATTR, data.pAppearBoxSize.height);
element.SetDoubleAttribute(RED_BEGIN_ATTR, data.pRedBegin);
element.SetDoubleAttribute(RED_END_ATTR, data.pRedEnd);
element.SetDoubleAttribute(GREEN_BEGIN_ATTR, data.pGreenBegin);
element.SetDoubleAttribute(GREEN_END_ATTR, data.pGreenEnd);
element.SetDoubleAttribute(BLUE_BEGIN_ATTR, data.pBlueBegin);
element.SetDoubleAttribute(BLUE_END_ATTR, data.pBlueEnd);
element.SetDoubleAttribute(ALPHA_BEGIN_ATTR, data.pAlphaBegin);
element.SetDoubleAttribute(ALPHA_END_ATTR, data.pAlphaEnd);
element.SetDoubleAttribute(SCALE_BEGIN_W_ATTR, data.pKFScaleBeginW);
element.SetDoubleAttribute(SCALE_BEGIN_H_ATTR, data.pKFScaleBeginH);
element.SetDoubleAttribute(SCALE_END_W_ATTR, data.pKFScaleEndW);
element.SetDoubleAttribute(SCALE_END_H_ATTR, data.pKFScaleEndH);
element.SetDoubleAttribute(DISPERSION_X_ATTR, data.pKFDispersionX);
element.SetDoubleAttribute(DISPERSION_Y_ATTR, data.pKFDispersionY);
element.SetDoubleAttribute(PS_X_ATTR, data.initialX);
element.SetDoubleAttribute(PS_Y_ATTR, data.initialY);
element.SetDoubleAttribute(PS_SPEED_X_ATTR, data.speedChangeX);
element.SetDoubleAttribute(PS_SPEED_Y_ATTR, data.speedChangeY);
element.SetDoubleAttribute(START_DELAY_ATTR, data.startDelay);
element.SetDoubleAttribute(STOP_DELAY_ATTR, data.stopDelay);
element.SetDoubleAttribute(ROTATE_ATTR, data.pAngleRotate);
TiXmlElement* ptr_element = (TiXmlElement*)root_ptr->InsertEndChild(element);
return((bool)(ptr_element != NULL));
}
bool ParticleSystem::load(TiXmlElement*& element_ptr)
{
TiXmlElement *next_element_ptr = (TiXmlElement*)element_ptr->FirstChild("PS");
if(!next_element_ptr)
{
next_element_ptr = (TiXmlElement*)element_ptr->NextSibling("PS");
if(!next_element_ptr)
return false;
}
//read version 1.1 parameters
if(next_element_ptr->QueryIntAttribute(MAX_COUNT_ATTR, &data.pMaxCount) != TIXML_SUCCESS)
data.pMaxCount = EXPL_MAX;
//read all version parameters (obligatory)
if(next_element_ptr->QueryIntAttribute(START_COUNT_ATTR, &data.pCountOnStart) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(LIFE_TIME_ATTR, &data.pLifeTime) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(APPEAR_DELAY_ATTR, &data.pAppearDelay) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PARTICLE_SPEED_X_ATTR, &data.pMoveSpeedX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PARTICLE_SPEED_Y_ATTR, &data.pMoveSpeedY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(GRAVITY_X_ATTR, &data.pGravityX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(GRAVITY_Y_ATTR, &data.pGravityY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(APPEAR_BOX_W_ATTR, &data.pAppearBoxSize.width) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(APPEAR_BOX_H_ATTR, &data.pAppearBoxSize.height) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(RED_BEGIN_ATTR, &data.pRedBegin) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(RED_END_ATTR, &data.pRedEnd) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(GREEN_BEGIN_ATTR, &data.pGreenBegin) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(GREEN_END_ATTR, &data.pGreenEnd) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(BLUE_BEGIN_ATTR, &data.pBlueBegin) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(BLUE_END_ATTR, &data.pBlueEnd) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(ALPHA_BEGIN_ATTR, &data.pAlphaBegin) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(ALPHA_END_ATTR, &data.pAlphaEnd) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(SCALE_BEGIN_W_ATTR, &data.pKFScaleBeginW) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(SCALE_BEGIN_H_ATTR, &data.pKFScaleBeginH) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(SCALE_END_W_ATTR, &data.pKFScaleEndW) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(SCALE_END_H_ATTR, &data.pKFScaleEndH) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(DISPERSION_X_ATTR, &data.pKFDispersionX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(DISPERSION_Y_ATTR, &data.pKFDispersionY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PS_X_ATTR, &data.initialX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PS_Y_ATTR, &data.initialY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PS_SPEED_X_ATTR, &data.speedChangeX) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(PS_SPEED_Y_ATTR, &data.speedChangeY) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(START_DELAY_ATTR, &data.startDelay) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(STOP_DELAY_ATTR, &data.stopDelay) != TIXML_SUCCESS ||
next_element_ptr->QueryDoubleAttribute(ROTATE_ATTR, &data.pAngleRotate) != TIXML_SUCCESS)
return false;
currentX = data.initialX;
currentY = data.initialY;
setParticleTex(next_element_ptr->Attribute(TEXTURE_ATTR));
element_ptr = next_element_ptr;
return true;
}
void ParticleSystem::callback(double sec_interval)
{
if(isFinishedb)
return;
//check for startInTime
startInTime -= sec_interval;
//if (((int)startInTime*maj_kof) > 0)
if(startInTime > 0.0)
return;
else
startInTime = 0.0;
//change DX DY
currentX += data.speedChangeX* sec_interval;
currentY += data.speedChangeY* sec_interval;
//check for the next particle
timeForNextParticle -= sec_interval;
double addParticleTime = 1.0;
if (timeForNextParticle <= 0.0)
{
addParticleTime = timeForNextParticle;
timeForNextParticle = data.pAppearDelay;
}
bool need_to_finish = true;
if(isRunb)
{
need_to_finish = false;
stopInTime -= sec_interval;
//if (((int)stopInTime*maj_kof) <= 0)
if(stopInTime <= 0.0)
stop();
}
//calculate entire number of particles alive
int curr_numof_particles = 0;
for(int i=0; i<EXPL_MAX; i++)
if(pTM[i] > 0.0)
++curr_numof_particles;
//process particles
for (int i=0; i<EXPL_MAX; i++)
{
pTM[i] -= sec_interval;
if (pTM[i] <= 0.0)
{
if (addParticleTime <= 0.0 && curr_numof_particles < data.pMaxCount && isRunb)
{
//add new particle
addParticleTime += data.pAppearDelay;
++curr_numof_particles;
initParticleAtIndex(i);
}
}
else
{
need_to_finish = false;
pX[i] += sec_interval * pDx[i];
pY[i] += sec_interval * pDy[i];
pDx[i] += sec_interval * data.pGravityX;
pDy[i] += sec_interval * data.pGravityY;
}
}
if(need_to_finish)
finish();
}
void ParticleSystem::setBoundColor(wxColour color)
{
boundColor = color;
}
wxColour ParticleSystem::getBoundColor()
{
return boundColor;
}
Подобные документы
Разработка веб-приложения, позволяющего создавать и редактировать проекты с коллективным взаимодействием для совместного редактирования проектов HTML, CSS, JS. Обоснование выбора архитектуры программного изделия. Принцип организации обмена данными.
дипломная работа [1,9 M], добавлен 19.06.2013Рзработка библиотеки, которая позволит моделировать динамику частиц в трехмерной графики. Выбор средств и методов разработки. Варианты моделирования систем частиц. Моделирование на вершинном шейдере. Диаграммы класса Particle System и PSBehavior.
курсовая работа [4,4 M], добавлен 07.02.2016Суть принципа точечной графики. Изображения в растровой графике, ее достоинства. Обзор наиболее известных редакторов векторной графики. Средства для работы с текстом. Программы фрактальной графики. Форматы графических файлов. Трехмерная графика (3D).
дипломная работа [764,7 K], добавлен 16.07.2011Построение математической модели движения заряженных частиц, реализация на алгоритмическом языке с помощью ЭВМ. Описание предметной области. Имитация взаимодействия двух разноименно заряженных частиц. Результаты работы программы, руководство пользователя.
курсовая работа [824,0 K], добавлен 26.02.2015Разработка и цели внедрения свободного программного обеспечения в образовательные учреждения. Основные понятия векторной графики на примере редактора Inkscape, интерфейс программы. Разработка серии практических заданий с использованием Inkscape.
курсовая работа [4,1 M], добавлен 15.01.2011Создание учебного пособия по компьютерной графике, представленного в электронной форме. Внешние спецификации: интерфейс, входные, выходные данные. Алгоритм и код программы. Руководство пользователя. Принципы организации тестирования программного продукта.
дипломная работа [2,1 M], добавлен 04.07.2013Проектирование программного обеспечения, позволяющего создавать и вести множество электронных словарей. Обоснование выбора программных средств решения задачи. Разработка формы входных и выходных данных. Описание модулей программы и процесса отладки.
дипломная работа [1007,7 K], добавлен 03.07.2015Применение гетерогенных вычислительных систем в задачах молекулярной динамики. Потенциалы взаимодействия частиц. Процесс разработки приложения с использованием Altera Open CL Compiler. Сравнение архитектур ГУ и ПЛИС, их пиковая производительность.
дипломная работа [2,0 M], добавлен 22.08.2017Редактирование текста как очень важная часть оформления документов. Разработка программы по работе с текстом "Текстовый редактор" в среде разработки C++Builder 6 как приложения, использующегося в качестве замены встроенного редактора "WordPad".
курсовая работа [256,7 K], добавлен 08.12.2010Принцип работы регулятора громкости в ОС Windows. Требования к интерфейсу программного продукта, программному и техническому обеспечению. Выбор ядра для разработки приложения. Инсталляция и выполнение программы. Контекстная диаграмма и листинг приложения.
курсовая работа [978,4 K], добавлен 18.06.2015