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.
An offset buffer is a vector array.
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]
.
Normals is stored in a normal buffer and each point holds an index of the normal buffer.
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?
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;