K-Bal wrote:I go into more detail. You should save the particle centers as vertices in a VBO. Then render everything with the point sprite extension. However, since you are not using any textures, you could just render the VBO as GL_POINTS.
GroundUpEngine wrote:
K-Bal wrote:You are using immediate mode which is very slow. You should try using vertex buffer objects with index buffers and object batching. Ask GroundUpEngine
I would help, but I have no idea how vertex buffer objects work...
Sorry!
Are you serious? You did your terrain with VBOs and you don't know how they work?
Just kidding... But seriously, I've only just learned how to use them effectively and I havent tryed anything Dynamic like particles, data mapping ..etc
Actually if you are creating a particle system I would opt. for point sprites over the use of VBO's. Here are some samples, go a little down the page.
Re: Particle System bugs
Posted: Sun May 23, 2010 11:54 am
by K-Bal
zeid wrote:I would opt. for point sprites over the use of VBO's.
This is not mutually exclusive. It's actually pretty straight forward to combine both.
Re: Particle System bugs
Posted: Mon May 24, 2010 11:27 am
by GroundUpEngine
K-Bal wrote:
zeid wrote:I would opt. for point sprites over the use of VBO's.
This is not mutually exclusive. It's actually pretty straight forward to combine both.
/agreed
Re: Particle System bugs
Posted: Tue May 25, 2010 10:15 am
by GroundUpEngine
Double post :P
@mv2112
Here's the basic point sprite technique, it's faster because you only have to pass 1 vertice per Particle, for my particle system I got 1000% performance increase! For this snippet I have used Intermediate mode with one call to glBegin/glEnd. For VBO technique you would have to update the position data buffer every frame using GL_STREAM_DRAW and render using glDrawArrays, or whatever
glPushMatrix();
// Properties of Particle
glPointSize(ParticleSize);
// Bind Texture
glBlendFunc(GL_ONE, GL_ONE);
Texture->Bind();
// Use Point Sprite
glEnable(GL_POINT_SPRITE);
glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
// Render Particles (Intermidiate Mode)
glBegin(GL_POINTS);
for(int i = 0; i < numParticles; i++) {
glVertex3f(Particles[i].Pos.x, Particles[i].Pos.y, Particles[i].Pos.z);
}
glEnd();
glDisable(GL_POINT_SPRITE);
glPointSize(1);
glPopMatrix();
Re: Particle System bugs
Posted: Tue May 25, 2010 10:28 am
by zeid
This is not mutually exclusive. It's actually pretty straight forward to combine both.
Nice, I personally haven't looked into using them as a particle system, just new they would be faster (I assumed GL_POINTS was limited to immediate mode as I have only used it for debugging things). Now that you mention it, it seems obvious that you could put the data in a VBO and makes me feel a little silly for saying otherwise. :P
Re: Particle System bugs
Posted: Tue May 25, 2010 11:06 am
by K-Bal
zeid wrote:
This is not mutually exclusive. It's actually pretty straight forward to combine both.
Nice, I personally haven't looked into using them as a particle system, just new they would be faster (I assumed GL_POINTS was limited to immediate mode as I have only used it for debugging things). Now that you mention it, it seems obvious that you could put the data in a VBO and makes me feel a little silly for saying otherwise. :P
If you are using a shader to update positions you don't even have to copy data between CPU and GPU once the particles are emitted. I'm doing this for a thesis and I can handle ~200,000 particles (billboards) with inter-partical collision and ~1,000,000 without at ~60 frames with a gtx8800. Keywords: transform feedback, texture buffer objects, geometry shader
Re: Particle System bugs
Posted: Tue May 25, 2010 11:58 am
by zeid
If you are using a shader to update positions you don't even have to copy data between CPU and GPU once the particles are emitted. I'm doing this for a thesis and I can handle ~200,000 particles (billboards) with inter-partical collision and ~1,000,000 without at ~60 frames with a gtx8800. Keywords: transform feedback, texture buffer objects, geometry shader
That is some pretty clever stuff for optimisation, and sounds like an awesome thesis topic.
Re: Particle System bugs
Posted: Tue May 25, 2010 6:53 pm
by mv2112
Ok, here is how it's set up, it still lags more than the SDL version does.
Does anything stand out that could be fixed or that is causing lag?
void Particle::Draw()
{
glColor3f(Color.r,Color.g,Color.b); //Color is mvColor{float r;float g; float b};
glVertex3f(Coordinates.Get(0),Coordinates.Get(1),0);
//Coordinates is a really crappy vector template i put together, ingeniously making it's members private for un-easy access
}
Re: Particle System bugs
Posted: Tue May 25, 2010 10:14 pm
by short
Iterators instead of for loops may help a little bit.
Re: Particle System bugs
Posted: Wed May 26, 2010 4:14 am
by K-Bal
The first thing is, you are using PointSprites without texturing and with probably very small particles. So consider not rendering sprites but only points. Next thing is, turn of blending if you don't use alpha values.
For a whole lot of particles it would be better to batch particles with the same color. And put vertex data and color data in one array each rather than using a class for particles, it saves a 10000 function calls (good thing). Now you are able to use glDrawArrays (see also glVertexPointer, glColorPointer, glEnableClientState), which will give a good performance boost (since it's saving about 20000 function calls, vertex and color for each particle). I'm talking about 10000 particles here.
Furthermore, maybe your graphics card is not that fancy as your CPU.
short wrote:Iterators instead of for loops may help a little bit.
Iterators in an standard array? He also implied that the rendering is making trouble.
Edit: Just saw you have a vector class with Get functions, that's another 20000 function calls each frame. Make x and y public.
Re: Particle System bugs
Posted: Sun Jun 20, 2010 12:08 am
by mv2112
Ok, so i've started learning openGL a little bit now. I FINALY was able to make a VBO and store the particle positions in it, however it is SLOW AS HELL! I'm new at this so this code may be a little screwed up. First, i generate the buffer in the particle system constructor, and delete it in the destructor. This is my render function:
glBindBuffer(GL_ARRAY_BUFFER,PB); //PB is the VBO
glBufferData(GL_ARRAY_BUFFER,sizeof(GLfloat)*pos.size(),&pos[0],GL_STATIC_DRAW); //pos is the vector that holds the x and y's
glBindBuffer(1,PB);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(s);
glVertexPointer(2,GL_FLOAT,0,BUFFER_OFFSET(0));
glEnableClientState(GL_VERTEX_ARRAY);
for(int i=0;i<pos.size()/2;i++)
{
glDrawArrays(GL_POINTS,i,1);
}
glDisableClientState(GL_VERTEX_ARRAY);
pos.clear(); //pos gets refilled when the particles are updated
EDIT: SUPER slow in debug mode, slower than my SDL version in release mode
Why would this be so slow?
Re: Particle System bugs
Posted: Sun Jun 20, 2010 12:58 am
by mv2112
I took the draw arrays out of the for loop and it runs faster now. Does anyone know any good optimization tips?
Re: Particle System bugs
Posted: Sun Jun 20, 2010 4:48 am
by K-Bal
Draw the whole buffer with ONE call to glDrawArrays and very much more important: don't copy the data into you buffer every frame. You are grilling your bus Get yourself a pointer to the buffer memory and update only what you need to update. Or use shaders to update the buffer on the GPU.
I know from my own experience that the latter is highly performant. Here is a little demo I put together:
30000 is not even the limit and remember that I'm simultaneously capturing 30 full frames per second of video.
If you don't want to have the data on the GPU, use glVertexPointer to point to your raw data and draw this with glDrawArrays. Otherwise you won't gain anything from the VBO.
Re: Particle System bugs
Posted: Sun Jun 20, 2010 4:09 pm
by mv2112
K-Bal wrote:Draw the whole buffer with ONE call to glDrawArrays and very much more important: don't copy the data into you buffer every frame. You are grilling your bus Get yourself a pointer to the buffer memory and update only what you need to update. Or use shaders to update the buffer on the GPU.
I made it use one call to glDrawArrays and it is alot faster now, but how would i not copy the data into the buffer each frame when all the particles are constantly changing position? I would need to update every particle's vertices every frame, right?