почему opengl не показывает мои частицы огня

Вопрос будет длинным, но информация необходима, так что со мной все в порядке, вот main.cpp:

class Vector3
{
private:
float x,y,z;
public:
Vector3(float thex=0,float they=0,float thez=0)
:x(thex),y(they),z(thez)
{
}
float X()const
{
return x;
}
float Y()const
{
return y;
}
float Z()const
{
return z;
}
Vector3 operator -(const Vector3 &other)const
{
return Vector3(x-other.x,y-other.y,z-other.z);
}
static Vector3 crossproduct(const Vector3 &v,const Vector3 &u)
{
Vector3 resVector;
resVector.x = u.y*v.z - u.z*v.y;
resVector.y = u.z*v.x - u.x*v.z;
resVector.z = u.x*v.y - u.y*v.x;

return resVector;
}
Vector3 operator *(const float &scale)const
{
return Vector3(x*scale,y*scale,z*scale);
}
Vector3 operator /(const float &scale)const
{
return Vector3(x/scale,y/scale,z/scale);
}
Vector3 &operator +=(const Vector3& other)
{
x+=other.x;
y+=other.y;
z+=other.z;
return *this;
}
const float *toArray()const
{
float *a=new float[3];
a[0]=x;
a[1]=y;
a[2]=z;
return a;
}
};
struct Force
{
private :
float strength;
Vector3 orentation;
public :
Force(const Vector3 &v,const float &s)
:strength(s),orentation(v)
{
}
Force(const Force &f)
:strength(f.strength),orentation(f.orentation)
{

}
float getStrength() const
{
return strength;
}
Vector3 getOrentation() const
{
return orentation;
}
};
class Camera
{
private:
Vector3 Position;
Vector3 View;
Vector3 Up;
Vector3 lineofsight;
public:
Camera(const Vector3 &pos, const float &lookatx, const float &lookaty):
Position(pos), View(Vector3(lookatx,lookaty,pos.Z()-1))
,Up(Vector3::crossproduct(lineofsight,Vector3(1,0,0))),lineofsight(View-pos)
{

}
void LookAt()
{
gluLookAt(Position.X(),Position.Y(),Position.Z(),View.X(),View.Y(),View.Z(),Up.X(),Up.Y(),Up.Z());
}
};
class Particle
{
public :
Vector3 velocity,position,color;
const float mass;
float *deltatime;
Particle(const Vector3 &pos,const Vector3 &col,const float &m,float *dt)
:velocity(Vector3()),position(pos),color(col),mass(m),deltatime(dt)
{

}

void applyforce(const Force &f)
{
Vector3 force=f.getOrentation()*f.getStrength();
Vector3 accleration=force/mass;
velocity+=accleration*(*deltatime);
proceedintime();
}
void proceedintime()
{
position+=velocity*(*deltatime);
}
virtual void draw()const=0;
virtual ~Particle()
{

}
};

class Emmiter;class ParticleSystem
{
friend class Emmiter;
private :
deque<Particle*> particles;
float elapsedtime;
float *deltatime;
float LifeOfParticles;
unsigned short particlesperframe;
void deleteparticles()
{
float div=fmod(elapsedtime,LifeOfParticles);
if(div==0)
{
deque<Particle*>::const_iterator begin=particles.begin();
deque<Particle*>::const_iterator end=particles.end();
for(deque<Particle*>::const_iterator it=begin;it!=end;it++)
delete (*it);
particles.clear();
}
}

public :
ParticleSystem(const float &life,float *dt)
:elapsedtime(0),deltatime(dt),LifeOfParticles(life)
{

}
void drawparticl1es()
{
deque<Particle*>::const_iterator begin=particles.begin();
deque<Particle*>::const_iterator end=particles.end();

for(deque<Particle*>::const_iterator it=begin;it!=end;it++)
{
(*it)->proceedintime();
(*it)->draw();
}
elapsedtime+=(*deltatime);
deleteparticles();
}
};

class Emmiter
{
public :
unsigned short ParticlesPerSecond;
Vector3 position;
ParticleSystem *ps;
unsigned char count;
float deltatime;
Particle *(*emitfunc)(const Emmiter &em);
Emmiter(const unsigned short &parpersec,const Vector3 &pos,ParticleSystem *p,const unsigned char &c)
:ParticlesPerSecond(parpersec),position(pos),ps(p),count(c)
{

}
unsigned short particlesperframe()const
{
return ParticlesPerSecond*deltatime;
}
void emitparticles()const
{
unsigned short numpars=deltatime*ParticlesPerSecond;
for(unsigned char i=0;i<count;i++)
{
for(unsigned short j=0;j<numpars;j++)
ps[i].particles.push_back(emitfunc(*this));
}
}
};
class BallParticle:public Particle
{
public :
float radius;
BallParticle(const Vector3 &pos,const Vector3 &col,const float &rad,const float &m,float *dt)
:Particle(pos,col,m,dt),radius(rad)
{}
void draw() const
{
glPushMatrix();
glColor3fv(color.toArray());
glTranslatef(position.X(), position.Y(), position.Z());
glutSolidSphere(radius, radius * 20, radius * 20);
glPopMatrix();
}
};
using namespace std;

float deltatime;
float oldtime;
float newtime;

ParticleSystem pars(2,&deltatime);
Emmiter emmiter(200,Vector3(0,0,8),&pars,1);

Camera camera(Vector3(0,0,3),0,0);
float myrand(const float &min,const float &max)
{
return min+(max-min)*(float(rand())/float(RAND_MAX));
}

Particle *emitfunction(const Emmiter &em)
{
float x=em.position.X(),y=em.position.Y(),z=em.position.Z();
BallParticle *b=new BallParticle(Vector3(myrand(x-5,x+5),y,myrand(z-5,z+5)),Vector3(myrand(0,1),myrand(0,1),myrand(0,1)),4,0.02,&deltatime);
b->velocity=Vector3(0,4,0);
return b;
}
void resize(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,(4/3),2,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camera.LookAt();
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
newtime=glutGet(GLUT_ELAPSED_TIME)/1000;
deltatime=newtime-oldtime;
oldtime=newtime;
emmiter.deltatime=deltatime;
emmiter.emitparticles();
pars.drawparticl1es();
glutSwapBuffers();
}
void idle()
{
glutPostRedisplay();
}
void init()
{
glClearColor(1, 1, 1, 1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(300,200);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Fire");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutIdleFunc(idle);
init();
oldtime=glutGet(GLUT_ELAPSED_TIME)/1000;
emmiter.emitfunc=&emitfunction;
glutMainLoop();
return EXIT_SUCCESS;
}

Я пытаюсь построить простую систему частиц огня в opengl с freeglut, у меня есть Nvidia 9400GT и я работаю над linux mint 17.1 64bit.

Я попробовал apitrace, но он ничего не показал, я отладил свою программу, кажется, что emmiter работает, потому что система частиц заполнена, но пока ничего не показывает.

Большую часть времени это камера, но я не ошибаюсь, так в чем же проблема?

2

Решение

Ваша камера была выключена в $ DEITY-знает-где и ваш glutSolidSphere()были слишком большими. И чрезмерно подразделенный.

Не изобретай vec3 класс, использовать GLM, собственный, или что-то подобное.

У вас есть несколько мест, где вы делите целое число на целое и надеетесь на число с плавающей точкой. Принудительно делить делитель через f суффикс.

Все вместе:

#include <GL/glut.h>

// http://glm.g-truc.net/
#include <glm/glm.hpp>

#include <deque>
using namespace std;

typedef glm::vec3 Vector3;

struct Force
{
private :
float strength;
Vector3 orentation;
public :
Force(const Vector3 &v,const float &s)
:strength(s),orentation(v)
{
}
Force(const Force &f)
:strength(f.strength),orentation(f.orentation)
{

}
float getStrength() const
{
return strength;
}
Vector3 getOrentation() const
{
return orentation;
}
};

class Particle
{
public :
Vector3 velocity,position,color;
const float mass;
float *deltatime;
Particle(const Vector3 &pos,const Vector3 &col,const float &m,float *dt)
:velocity(Vector3()),position(pos),color(col),mass(m),deltatime(dt)
{

}

void applyforce(const Force &f)
{
Vector3 force=f.getOrentation()*f.getStrength();
Vector3 accleration=force/mass;
velocity+=accleration*(*deltatime);
proceedintime();
}
void proceedintime()
{
position+=velocity*(*deltatime);
}
virtual void draw()const=0;
virtual ~Particle()
{

}
};

class Emmiter;class ParticleSystem
{
friend class Emmiter;
private :
deque<Particle*> particles;
float elapsedtime;
float *deltatime;
float LifeOfParticles;
unsigned short particlesperframe;
void deleteparticles()
{
float div=fmod(elapsedtime,LifeOfParticles);
if(div==0)
{
deque<Particle*>::const_iterator begin=particles.begin();
deque<Particle*>::const_iterator end=particles.end();
for(deque<Particle*>::const_iterator it=begin;it!=end;it++)
delete (*it);
particles.clear();
}
}

public :
ParticleSystem(const float &life,float *dt)
:elapsedtime(0),deltatime(dt),LifeOfParticles(life)
{

}
void drawparticl1es()
{
deque<Particle*>::const_iterator begin=particles.begin();
deque<Particle*>::const_iterator end=particles.end();

for(deque<Particle*>::const_iterator it=begin;it!=end;it++)
{
(*it)->proceedintime();
(*it)->draw();
}
elapsedtime+=(*deltatime);
deleteparticles();
}
};

class Emmiter
{
public :
unsigned short ParticlesPerSecond;
Vector3 position;
ParticleSystem *ps;
unsigned char count;
float deltatime;
Particle *(*emitfunc)(const Emmiter &em);
Emmiter(const unsigned short &parpersec,const Vector3 &pos,ParticleSystem *p,const unsigned char &c)
:ParticlesPerSecond(parpersec),position(pos),ps(p),count(c)
{

}
unsigned short particlesperframe()const
{
return ParticlesPerSecond*deltatime;
}
void emitparticles()const
{
unsigned short numpars=deltatime*ParticlesPerSecond;
for(unsigned char i=0;i<count;i++)
{
for(unsigned short j=0;j<numpars;j++)
ps[i].particles.push_back(emitfunc(*this));
}
}
};

class BallParticle:public Particle
{
public :
float radius;
BallParticle(const Vector3 &pos,const Vector3 &col,const float &rad,const float &m,float *dt)
:Particle(pos,col,m,dt),radius(rad)
{
}

void draw() const
{
glPushMatrix();
glColor3fv( (GLfloat*)&color );
glTranslatef(position.x, position.y, position.z);
glutSolidSphere(radius, 10, 10);
glPopMatrix();
}
};

float deltatime;
float oldtime;
float newtime;

ParticleSystem pars(2,&deltatime);
Emmiter emmiter(200,Vector3(0,0,8),&pars,1);

float myrand(const float &min,const float &max)
{
return min+(max-min)*(float(rand())/float(RAND_MAX));
}

Particle *emitfunction(const Emmiter &em)
{
float x=em.position.x,y=em.position.y,z=em.position.z;
BallParticle *b=new BallParticle
(
Vector3(myrand(x-5,x+5),y,myrand(z-5,z+5)),
Vector3(myrand(0,1),myrand(0,1),myrand(0,1)),
0.2,
0.02,
&deltatime
);
b->velocity=Vector3(0,4,0);
return b;
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,(4/3.0f),2,100);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 20, 20, 20, 0, 0, 0, 0, 0, 1 );

newtime=glutGet(GLUT_ELAPSED_TIME)/1000.0f;
deltatime=newtime-oldtime;
oldtime=newtime;
emmiter.deltatime=deltatime;
emmiter.emitparticles();
pars.drawparticl1es();

glutSwapBuffers();
}

void timer( int value )
{
glutTimerFunc( 16, timer, 0 );
glutPostRedisplay();
}

void init()
{
glClearColor(1, 1, 1, 1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
}

int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitWindowPosition(300,200);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Fire");
glutDisplayFunc(display);
glutTimerFunc(0, timer, 0);
init();
oldtime=glutGet(GLUT_ELAPSED_TIME)/1000.0f;
emmiter.emitfunc=&emitfunction;
glutMainLoop();
return EXIT_SUCCESS;
}
0

Другие решения


По вопросам рекламы [email protected]