Topic: Using Vertex Arrays

I've been having a play around with this particle system. I'm slowly getting somewhere, however it's currently crashing after a while. It seems to be possibly that it might be a buffer overrun or something. Just a few questions.

Firstly, is drawArray a synchronous call or does it get batched up? If that's the problem then that would potentially be the problem as I don't think the arrays I'm giving it are necessarily going to live that long. Secondly, there shouldn't be any theoretical maximum to the size of the array, should there? It's currently trying to draw 500 particles and complaining.

I think I'm going to have to do some serious rewriting on this particle system to get it to do anything sensible, "just for fun" I decided to render only 1 particle, but update 10,000 of them and the framerate dropped to a slideshow. Now, most particle systems shouldn't need that many particles, but potentially, over an entire scene, that's not an overly obscene amount.

Also, I'm not entirely sure if this is normal, but when I "GetParticlePointer" then it returns one giant array with all the information about the particle stored in it, with offsets to each of the different information within each particle. Much as this would be incredibly useful if the particle calculations are to be moved to the GPU, I think sending all of this in a giant array may be overkill for rendering.

        cnt = m_Context.GetParticlePointer(ptr, flstride, pos3Ofs, posB3Ofs,
            size3Ofs, vel3Ofs, velB3Ofs, color3Ofs, alpha1Ofs, age1Ofs,
            up3Ofs, rvel3Ofs, upB3Ofs, mass1Ofs, data1Ofs);
        if(cnt < 1) return;
        
        render->enableColorArray();
        render->setColorPointer(M_FLOAT, int(flstride) * sizeof(float), ptr + color3Ofs);
        
        render->enableVertexArray();
        render->setVertexPointer(M_FLOAT, int(flstride) * sizeof(float), ptr + pos3Ofs);
        
        render->drawArray(M_PRIMITIVE_POINTS, 0, cnt);
        render->disableVertexArray();
        render->disableColorArray();

Is this correct or am I making a stupid mistake somewhere? I will try and look for answers myself too smile

Last edited by Nistur (2012-04-04 09:56:23)

Re: Using Vertex Arrays

Hi,
I don't understand how your handle your data pointer, it's a bit obscure,
but if "ptr + pos3Ofs" is pointing to your vertices array your problem is "int(flstride) * sizeof(float)"

the number you are supposed to put here is the number of components, so "3" if your vertices are a list of 3d floats like that : x, y, z, x, y, z...
(it can also be an array of MVector3)

you should do : render->setVertexPointer(M_FLOAT, 3, ptr + pos3Ofs);

to give an example, here is a code to draw a 2d quad :

MVector2 vertices[4];
MVector2 texCoords[4];

render->disableNormalArray();
render->disableColorArray();
render->enableVertexArray();
render->enableTexCoordArray();

render->setVertexPointer(M_FLOAT, 2, vertices);
render->setTexCoordPointer(M_FLOAT, 2, texCoords);

render->drawArray(M_PRIMITIVE_TRIANGLE_STRIP, 0, 4);

Re: Using Vertex Arrays

Thank you, I will try that. As may be obvious at this point, I'm getting quite confused at this point with this library. I'm seriously considering starting again from scratch tongue

It seems to be that the array it gives back in ptr is the array of particle structs, which have all the information within them you could need. The idea is that you just use that array, pull out the bits you want each time and stride over the rest of the information. This seems insane, to send all this information to the GPU for rendering, when it would never need the mass of the specific particle, or it's age. I just did a quick check and sizeof(PAPI::Particle_t) comes up as 136. At the moment, I'm just trying to use the colour and position, that's 24 bytes per particle we need to send, I think right now it will actually send 136*2, right?

I should also point out that it's currently using the rendering code from the Particle Systems API example, just with GL calls translated to MGui renderer calls. Can't wait to get rid of points and put alpha images there...

Last edited by Nistur (2012-04-04 12:29:37)

Re: Using Vertex Arrays

are you sure "ptr + pos3Ofs" is pointing to an aligned array of floats ?
because if it's not aligned, you might be forced to repack the data into a separate array...

Re: Using Vertex Arrays

I will take a look, but pos3Ofs is 0, and pos is the first member of the struct, so it looks sensible.

I've cast ptr to what it's meant to be (from reading the code) and it definitely looks like the array isn't corrupt. I guess it's just the fact that all the data's packed together.
http://nistur.com/maratis/particles.png

I guess I'll have to repack all the positions. Ahh well.

Heh, it seems that the particles are kept in a std::vector, and it gets uses &list.begin() as the start to the array and then &(list.begin() + 1) - &list.begin() as the stride. That would explain why it was coming out as 144 rather than 136, the sizeof(PAPI::Particle_t). I think that's enough, I'm going to give up on this particle system, maybe look for another one to replace it, but probably just write my own.

Last edited by Nistur (2012-04-04 13:00:28)

Re: Using Vertex Arrays

So, I've started writing my own particle system now. It's coming along pretty well. I have everything fairly neatly working together.

So that's not a problem. The issue now is that I'm using M_PRIMITIVE_POINTS, which gets me nice, 1px sized dots. Not entirely useful for a particle system. It would seem that OpenGL, at least has an extension allows you to glEnable(GL_POINT_SPRITE). It's currently not exposed in Maratis. I was wondering whether there is a reason for this, before I look into potentially adding this to the renderer.

Re: Using Vertex Arrays

Hi,
I was not using point sprite previously (I was manually drawing quads in view space for particles) so I guess some init is missing in MGLContext, try adding "glEnable(GL_POINT_SPRITE);" in MGLContext constructor, if it's enough.

What might need to be added is a wrapper to glPointParameter and glPointSize in MRenderingContext

Re: Using Vertex Arrays

I will probably end up drawing some particles as quads or tri lists, in order to allow for rotations, which I don't think point sprites can support. But I like the idea of being able to potentially have more particles for cheaper in some situations. A simple flag should take care of that I think.

Anyway, thanks. I'll see what I can do about that. Hopefully it will be that simple wink

Edit: On second thoughts, I'm not sure whether we want to put glEnable(GL_POINT_SPRITE) in init, potentially people might want to be able to draw points without sprites? Not sure... I'll put it there for now anyway

Last edited by Nistur (2012-04-06 12:34:33)

Re: Using Vertex Arrays

It's ok to put it on the init, when textures are disabled it draw a normal point,
also, glEnable(GL_POINT_SPRITE) has been removed in openGL 3 (always on).

If you want I can add this point sprite functions, it's fast to do.

Re: Using Vertex Arrays

Hmmm, that might be why I found it difficult to find documentation on it. I'm currently still busy with some of the particle functunality so I have no immediate need right now. I don't mind adding them myself either.

Re: Using Vertex Arrays

ok, I let you doing your tests with it, and let me know if you want me to add something if MRenderingContext is too obscure.