c++openglglslparticlesbilliards

Rendering points (particles) with OpenGL 3+


OpenGL 3 Render points: The points are stored within a space partition tree. The tree has points with colour and normal information attributes.

The point information and its attributes is stored as a set of buffers.

  1. An offset buffer is a vector array.

  2. The points are stored in memory as a center and offset index. The offset index points to the offset buffer Point = center + OffSetBuffer[offset index].

  3. Normals is stored in a normal buffer and each point holds an index of the normal buffer.

  4. Colour is stored in a colour buffer and each point holds an index of the colour buffer.

I have some room to change the buffer layout but holding information as above reduce repetitive or redundant information.

My question is how do I render the above Points using OpenGL 3+ APIs efficiently?


Solution

  • You don't need additional offset buffer and offset index, just pass the textures coords. Here is what you should do in a vertex program:

    1) Calculate the particle basis from the ModelView matrix:

    vec3 X = vec3(ModelView[0][0], ModelView[1][0], ModelView[2][0]);
    vec3 Y = vec3(ModelView[0][1], ModelView[1][1], ModelView[2][1]);
    

    2) Calculate corner points based on particle size (can be uniform or attribute):

       vec3 A1 = -X*SizeX - Y*SizeY;
       vec3 B1 =  X*SizeX - Y*SizeY;
       vec3 C1 =  X*SizeX + Y*SizeY;
       vec3 D1 = -X*SizeX + Y*SizeY;
    

    3) Move the center point into the appropriate corner:

       if (TexCoord == vec2(0.0, 0.0)) Position += A1;
       if (TexCoord == vec2(1.0, 0.0)) Position += B1;
       if (TexCoord == vec2(1.0, 1.0)) Position += C1;
       if (TexCoord == vec2(0.0, 1.0)) Position += D1;
    

    or more efficient branchless code:

    vec3 O1 = ( 1.0 - TexCoord.y ) * ( A1 * ( 1.0 - TexCoord.x ) + B1 * TexCoord.x );
    vec3 O2 = TexCoord.y * ( C1 * TexCoord.x + D1 * (1.0 - TexCoord.x ) );
    Position += O1 + O2;