Просто посмотрите на pmviewer.sourceforge.net, код использует точечные спрайты, и каждая точка имеет свой цвет и размер для имитации объемного рендеринга
Вершинный шейдер:
vertexShader
// with ATI hardware, uniform variable MUST be used by output
// variables. That's why win_height is used by gl_FrontColor
attribute float a_hsml1;
uniform float win_height;
uniform vec4 cameralocin;
void main()
{
vec4 position=gl_ModelViewMatrix*gl_Vertex;
vec4 cameraloc=gl_ModelViewMatrix*cameralocin;
float d=distance(vec3(cameraloc),vec3(position));
float a_hsml=gl_Normal.x;
float pointSize=win_height*a_hsml/d; // <- point diameter in
//pixels (drops like sqrt(1/r^2))
gl_PointSize=pointSize;
gl_TexCoord[0]=gl_MultiTexCoord0;
gl_Position=ftransform();
gl_FrontColor=vec4(gl_Color.r,gl_Color.g,gl_Color.b,gl_Color.a);
}
Pixelshader
uniform sampler2D splatTexture;
void main()
{
vec4 color = gl_Color * texture2D(splatTexture, gl_TexCoord[0].st);
gl_FragColor = color;\n"
}
Просто чтобы отправить частицы в gpu:
void PutOneArrayToGPU(unsigned int m_vbo, float *hArray, unsigned int num)
{
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * num, hArray, GL_STATIC_DRAW);
int size = 0;
glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
if ((unsigned)size != (sizeof(float) *num))
{
fprintf(stderr, "WARNING: Pixel Buffer Object allocation failed!\n");
fprintf(stderr, "TurningOff the GPU accelerated rendering\n");
flag_GpuRender=false;
}
return flag_GpuRender;
}
Затем визуализируйте их:
void DrawPointsByGPU()
{
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, m_vboPos);
glVertexPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, m_vboColor);
glColorPointer(4, GL_FLOAT, 0, 0);
glEnableClientState(GL_NORMAL_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, m_vboHSML);
glNormalPointer( GL_FLOAT, 3*sizeof(float), 0);
glDrawArrays(GL_POINTS, 0, m_numParticles);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
};