diff --git a/particle.frag b/particle.frag index 5e4d633..f5cb9ec 100755 --- a/particle.frag +++ b/particle.frag @@ -8,14 +8,16 @@ layout (location=0) out vec4 FragColor; layout (location=1) out vec4 BrightColor; uniform sampler2D tex; -uniform vec4 color[507]; +uniform float lifePercentage[500]; +uniform vec4 startColor,endColor; +//uniform vec4 color[500]; void main(){ float alpha=texture(tex,texCoords).r; - vec4 c=color[id]; - c=vec4(c.x,c.y,c.z,c.w*alpha); + vec4 c=startColor+(endColor-startColor)*lifePercentage[id]; + c=vec4(c.x,c.y,c.z,alpha); float brightness = dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)); if(brightness>1) BrightColor=vec4(c.rgb,1); - FragColor=vec4(c.x,c.y,c.z,c.w*alpha); + FragColor=c; } diff --git a/particle.vert b/particle.vert index 52fb9cd..405c0fb 100755 --- a/particle.vert +++ b/particle.vert @@ -11,14 +11,18 @@ flat out int id; uniform mat4 proj; uniform mat4 view; //uniform mat4 model[4]; -uniform vec3 trans[507]; -uniform vec2 size[507]; +uniform float lifePercentage[500]; +uniform vec3 trans[500]; +//uniform vec2 size[500]; +uniform vec2 startSize; +uniform vec2 endSize; void main(){ vec3 camLeft=vec3(view[0][0],view[1][0],view[2][0]); vec3 camUp=vec3(view[0][1],view[1][1],view[2][1]); - vec2 s=size[gl_InstanceID]; + id=gl_InstanceID; + vec2 s=startSize+(endSize-startSize)*lifePercentage[id]; vec3 v=camLeft*s.x*aPos.x+camUp*s.y*aPos.y; mat4 model=aInstancedModel; model[3][0]=trans[gl_InstanceID].x; diff --git a/particleEmitter.cpp b/particleEmitter.cpp index 2760c9a..2d9c657 100755 --- a/particleEmitter.cpp +++ b/particleEmitter.cpp @@ -14,10 +14,12 @@ using namespace glm; using namespace std; namespace vb01{ + int n=0; + ParticleEmitter::ParticleEmitter(int numParticles){ this->numParticles=numParticles; - particles=new Particle[numParticles]; + particles=new Particle*[numParticles]; Vertex v1,v2,v3,v4,v5,v6; Vector2 size=Vector2(.5,.5); @@ -46,15 +48,12 @@ namespace vb01{ mat4 *matrices=new mat4[numParticles]; for(int i=0;idir=direction; particles[i]=p; - matrices[i]=mat; + matrices[i]=mat4(1.f); } - glGenVertexArrays(1,&VAO); glGenBuffers(1,&VBO); glGenBuffers(1,&EBO); @@ -94,6 +93,39 @@ namespace vb01{ delete[] particles; } + void ParticleEmitter::makeHeap(int offset){ + bool heap=false; + while(!heap){ + bool end=true; + for(int i=0;2*i+1+offsetdd||particles[i+offset]->dd)){ + bool leftChild=particles[2*i+1+offset]->d>particles[2*i+2+offset]->d; + swap(particles[i+offset],leftChild?particles[2*i+1+offset]:particles[2*i+2+offset]); + n++; + } + else if(2*i+2+offset==numParticles&&particles[i+offset]->dd){ + swap(particles[i+offset],particles[2*i+1+offset]); + n++; + } + } + for(int i=0;2*i+1dd||particles[i+offset]->dd)) + end=false; + else if(2*i+2+offset==numParticles&&particles[i+offset]->dd) + end=false; + } + if(end) + heap=true; + } + } + + void ParticleEmitter::heapSort(){ + n=0; + for(int i=0;igetCamera(); @@ -109,43 +141,49 @@ namespace vb01{ Shader *shader=material->getShader(); shader->setMat4(view,"view"); shader->setMat4(proj,"proj"); + shader->setVec4(startColor,"startColor"); + shader->setVec4(endColor,"endColor"); + shader->setVec2(startSize,"startSize"); + shader->setVec2(endSize,"endSize"); Vector3 nodePos=node->getWorldTransform().position; Vector3 nodeDir=node->getLocalAxis(2); Vector3 nodeUp=node->getLocalAxis(1); Vector3 nodeLeft=node->getLocalAxis(0); for(int i=0;i=particles[i].timeToLive){ - particles[i].time=getTime(); + Vector3 dir=particles[i]->dir; + if(getTime()-particles[i]->time>=particles[i]->timeToLive){ + particles[i]->time=getTime(); float factor=(float)(rand()%100)/100; float s1=float(rand()%(int)spread)/180*PI,s2=float(rand()%360)/180*PI; Vector3 ra1=(Vector3(0,1,0).cross(dir)).norm(),ra2=dir.norm(); if(ra1==Vector3::VEC_ZERO) ra1=Vector3(1,0,0); dir=Quaternion(s1,ra1)*dir; dir=Quaternion(s2,ra2)*dir; - particles[i].timeToLive=s64(1000*((highLife-lowLife)*factor+lowLife)); - particles[i].mat=translate(mat4(1.f),vec3(nodePos.x,nodePos.y,nodePos.z)); - particles[i].trans=nodePos; + particles[i]->timeToLive=s64(1000*((highLife-lowLife)*factor+lowLife)); + //particles[i].mat=translate(mat4(1.f),vec3(nodePos.x,nodePos.y,nodePos.z)); + particles[i]->trans=nodePos; } //dir=nodeLeft*dir.x+nodeUp*dir.y+nodeDir*dir.z; - particles[i].dir=dir.norm()*direction.getLengthSq()+gravity; - float lifePercentage=(float)(getTime()-particles[i].time)/particles[i].timeToLive; - particles[i].color=startColor+(endColor-startColor)*lifePercentage; - particles[i].size=startSize+(endSize-startSize)*lifePercentage; - particles[i].mat=translate(particles[i].mat,vec3(dir.x,dir.y,dir.z)); - particles[i].trans=particles[i].trans+dir; + particles[i]->dir=dir.norm()*direction.getLengthSq()+gravity; + float lifePercentage=(float)(getTime()-particles[i]->time)/particles[i]->timeToLive; + particles[i]->color=startColor+(endColor-startColor)*lifePercentage; + particles[i]->size=startSize+(endSize-startSize)*lifePercentage; + //particles[i].mat=translate(particles[i].mat,vec3(dir.x,dir.y,dir.z)); + particles[i]->trans=particles[i]->trans+dir; - shader->setVec3(particles[i].trans,"trans["+to_string(i)+"]"); - shader->setVec4(particles[i].color,"color["+to_string(i)+"]"); - shader->setVec2(particles[i].size,"size["+to_string(i)+"]"); + shader->setVec3(particles[i]->trans,"trans["+to_string(i)+"]"); + shader->setFloat(lifePercentage,"lifePercentage["+to_string(i)+"]"); + //shader->setVec2(particles[i]->size,"size["+to_string(i)+"]"); + + Vector3 v0=particles[i]->trans; + particles[i]->d=cos(camDir.getAngleBetween((v0-camPos).norm()))*camPos.getDistanceFrom(v0); } + heapSort(); /* for(int i=0;itrans,v2=particles[j+1]->trans; float d1=cos(camDir.getAngleBetween((v1-camPos).norm()))*camPos.getDistanceFrom(v1); float d2=cos(camDir.getAngleBetween((v2-camPos).norm()))*camPos.getDistanceFrom(v2); if(d1direction=dir; for(int i=0;idir=dir; } } diff --git a/particleEmitter.h b/particleEmitter.h index 4ebd833..8e7c4fa 100755 --- a/particleEmitter.h +++ b/particleEmitter.h @@ -35,16 +35,20 @@ namespace vb01{ }; struct Particle{ int VAO; - glm::mat4 mat; s64 time=0,timeToLive=0; Vector4 color; Vector3 dir,trans; Vector2 size; + float d; }; - unsigned int instanceVBO,VAO,VBO,EBO; + void makeHeap(int); + void heapSort(); + + unsigned int VAO,VBO,EBO,MBO; + glm::mat4 *matrices; int numParticles; - Particle *particles; + Particle **particles; Material *material=nullptr; Node *node=nullptr; Vector2 startSize=Vector2::VEC_IJ,endSize=Vector2::VEC_IJ; diff --git a/texture.cpp b/texture.cpp index 15685bd..17eb945 100755 --- a/texture.cpp +++ b/texture.cpp @@ -51,8 +51,6 @@ namespace vb01{ glBindTexture(GL_TEXTURE_2D,texture[i]); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);