Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

speed of a particle engine

This topic is 5580 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hi! i would like to modify my particle engine so that it becomes faster. i''ve heard about vertexarray, and about gldrawelements: for each particle i do this: if (particle.Active) { float P[3]={particle[i].Coord.x, particle[i].Coord.y, particle[i].Coord.z}; glTranslatef(P[0],P[1],P[2]); BillBoardOn(); glBegin(GL_TRIANGLE_STRIP); glColor4f(particle[i].Color.r , particle[i].Color.g , particle[i].Color.b, particle[i].Alpha); glTexCoord2f(1.0f,1.0f); glVertex2f(+ particle[i].Size ,+ particle[i].Size ); glTexCoord2f(0.0f,1.0f); glVertex2f(- particle[i].Size ,+ particle[i].Size ); glTexCoord2f(1.0f,0.0f); glVertex2f(+ particle[i].Size ,- particle[i].Size ); glTexCoord2f(0.0f,0.0f); glVertex2f(- particle[i].Size ,- particle[i].Size ); glEnd(); BillBoardOff(); glTranslatef(-P[0],-P[1],-P[2]); } How could i optimize this? I could save in an array all the textures coordinates and the vertex and use gldrawelements, but how?? Thanks a lot

Share this post


Link to post
Share on other sites
Advertisement
First, stick all of the vertices needed to render the particles into an array. At the moment, I use the following structures:



//VERTEX - Ye standard vertex. Contains position in object space,
// vertex normal, and texture coordinates
typedef struct VERTEX
{
float u, v; //texture coordinates
float nx, ny, nz; //normal
float x, y, z; //position
VERTEX() : u(0), v(0), nx(0), ny(0), nz(0), x(0), y(0), z(0) { }
VERTEX(float x1, float y1, float z1, //constructor
float nx1, float ny1, float nz1,
float u1, float v1) : x(x1), y(y1), z(z1),
nx(nx1), ny(ny1), nz(nz1), u(u1), v(v1) { }

} VERTEX;

typedef struct TRIANGLE
{
unsigned int vertex1;
unsigned int vertex2;
unsigned int vertex3;
TRIANGLE() : vertex1(0), vertex2(0), vertex3(0) { }
TRIANGLE(unsigned int v1, unsigned int v2, unsigned int v3)
: vertex1(v1), vertex2(v2), vertex3(v3) { }
} TRIANGLE;

typedef vector vertexvector;
typedef vector<trIANGLE> trianglevector;



Then, when you''ve got all the vertices you need in a vertexvector called ''vertices'', and all the triangles you want to render in a trianglevector called ''triangles'', do this:


glInterleavedArrays(GL_T2F_N3F_V3F, 0, vertices.begin());
glDrawElements(GL_TRIANGLES, triangles.size()*3,
GL_UNSIGNED_INT, triangles.begin());


...of course, you can change the vertex structure etc. as described in the OpenGL docs.

Good luck!

Share this post


Link to post
Share on other sites
The big problem is that i use billboarding: so before drawing a triangle i use BillBoardOn!!
So, I can''t render all the particles at the same time because my bill board won''t work

Share this post


Link to post
Share on other sites
Don''t know if this will actually help very much, but couldn''t you store the positions of your particles in a coordinate frame relative to the center of the particle system itself(or just relative to the origin of world space, for that matter).

Then, instead of translating and de-translating for each particle, translate once at the start of the rendering to position the particle system. And render your particles relative to this position:


  
glTranslatef(ParticleSystem[0],ParticleSystem[1],ParticleSystem[2]);

for each particle i do this:

if (particle.Active)
{
float P[3]={particle[i].Coord.x, particle[i].Coord.y, particle[i].Coord.z};
BillBoardOn();
glBegin(GL_TRIANGLE_STRIP);

glColor4f(particle[i].Color.r , particle[i].Color.g , particle[i].Color.b, particle[i].Alpha);

glTexCoord2f(1.0f,1.0f); glVertex2f(P[0] + particle[i].Size , P[1] + particle[i].Size);

glTexCoord2f(0.0f,1.0f); glVertex2f(P[0] - particle[i].Size , P[1] + particle[i].Size);

glTexCoord2f(0.0f,0.0f); glVertex2f(P[0] - particle[i].Size , P[1] - particle[i].Size);

glTexCoord2f(1.0f,0.0f); glVertex2f(P[0] + particle[i].Size , P[1] - particle[i].Size);

glEnd();
BillBoardOff();
}


I don''t know how one would go about using vertex arrays together with billboarding. Perhaps it''s impossible?

Share this post


Link to post
Share on other sites
No! i can''t do that because if i do that, the center of the billboard will be the center of the particle system, and not the center of the particle.
I have ever tried what you say, and my billboarding was wrong..

Do you know a good program and source showing how to use particles with vertex array optimization??

Thanks

Share this post


Link to post
Share on other sites
You just have to do the billboarding yourself.
There are plenty of ways to do so... probably the simplest is to pull the camera''s up/right vectors from the current modelview matrix. How do you want your billboarded particles to behave? Always screen-aligned? Y-axis-aligned but facing the camera?

Share this post


Link to post
Share on other sites
what about these POINT sprites you can use them up to 64*64 on geforce cards and texture them

i personally haven t tested them yet but they sound like an alternative

Share this post


Link to post
Share on other sites
Point sprites are nice, but you can limit your options, as it''s hard to create effects that involve particle stretching or connectivity of particles.



Gamedev for learning.
libGDN for putting it all together.
An opensource, cross platform, cross API game development library.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I don''t know if this will help /* I''m a newbie */ but. . .

/***************************************************/
/* Fastest way I''ve found to move through an array */

particle *end = particles[MAX - 1]; // *p to last particle

// now iterate through the particles;
for (particle *cur = &particles[0]; cur < end; cur++)
{
/* draw particles here */
}

/*
Regardless of sizeof(MAX) you only dereference particles[] twice. if you have arrays in your (struct particle) than similar options can be implemented inside as well since the auto increment operator simply shifts your *p over 4 bytes (sizeof(unsigned __int32)) in Visual C++.

There is also a significant size overhead when using classes or structs with member functions.
Try to use simple C structs and
mem* functions : memset(), memcpy(), memcmp();
to manipulate them. This is more of a size optimization but in large blocks it can also increase the speed of your code.
*/
/* I hope this will help speed up your particle system */
/*******************************************************/

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!