This is the program that is used by Stardust Particle System:
public static function getProgram(texMipmap : Boolean = true,
texFormat : String = "bgra",
texSmoothing : String = "bilinear") : Program
{
var target : Starling = Starling.current;
var programName : String = getImageProgramName(texMipmap, texFormat, texSmoothing);
var program : Program = target.painter.getProgram(programName);
if (!program)
{
// this is the input data we'll pass to the shaders:
//
// va0 -> position
// va1 -> color
// va2 -> texCoords
// vc0 -> alpha
// vc1 -> mvpMatrix
// fs0 -> texture
var vertexShader : String = "m44 op, va0, vc1 \n" + // 4x4 matrix transform to output clipspace
"mul v0, va1, vc0 \n" + // multiply alpha (vc0) with color (va1)
"mov v1, va2 \n"; // pass texture coordinates to fragment program
var fragmentShader : String = "tex ft1, v1, fs0 <???> \n" + // sample texture 0
"mul oc, ft1, v0 \n"; // multiply color with texel color
fragmentShader = fragmentShader.replace("<???>", RenderUtil.getTextureLookupFlags(texFormat, texMipmap, false, texSmoothing));
program = Program.fromSource(vertexShader, fragmentShader);
target.painter.registerProgram(programName, program);
}
return program;
}
And this is how buffers are created:
protected static const ELEMENTS_PER_VERTEX:int = 5;
public static function createBuffers(numParticles : uint, numberOfVertexBuffers : int) : void
{
sNumberOfVertexBuffers = numberOfVertexBuffers;
_vertexBufferIdx = -1;
if(vertexBuffers)
{
for(var i : int = 0; i < vertexBuffers.length; ++i)
{
vertexBuffers[i].dispose();
}
}
if (indexBuffer)
{
indexBuffer.dispose();
}
var context:Context3D = Starling.context;
if(context === null) throw new MissingContextError();
if(context.driverInfo == "Disposed") return;
vertexBuffers = new Vector.<VertexBuffer3D>();
if(ApplicationDomain.currentDomain.hasDefinition("flash.display3D.Context3DBufferUsage"))
{
for(i = 0; i < sNumberOfVertexBuffers; ++i)
{
// Context3DBufferUsage.DYNAMIC_DRAW; hardcoded for FP 11.x compatibility
vertexBuffers[i] = context.createVertexBuffer.call(context, numParticles * 4, ELEMENTS_PER_VERTEX, "dynamicDraw");
}
}
else
{
for(i = 0; i < sNumberOfVertexBuffers; ++i)
{
vertexBuffers[i] = context.createVertexBuffer(numParticles * 4, ELEMENTS_PER_VERTEX);
}
}
var zeroBytes:ByteArray = new ByteArray();
zeroBytes.length = numParticles * 16 * ELEMENTS_PER_VERTEX;
for (i = 0; i < sNumberOfVertexBuffers; ++i)
{
vertexBuffers[i].uploadFromByteArray(zeroBytes, 0, 0, numParticles * 4);
}
zeroBytes.length = 0;
if(!indices)
{
//indices = new Vector.<uint>;
//var indexPosition:int = -1;
indicesBa = new ByteArray();
var numVertices:int = 0;
for (i = 0; i < numParticles; ++i)
{
/*
indices[++indexPosition] = numVertices;
indices[++indexPosition] = numVertices + 1;
indices[++indexPosition] = numVertices + 2;
indices[++indexPosition] = numVertices + 1;
indices[++indexPosition] = numVertices + 3;
indices[++indexPosition] = numVertices + 2;
*/
indicesBa.writeShort(numVertices);
indicesBa.writeShort(numVertices + 1);
indicesBa.writeShort(numVertices + 2);
indicesBa.writeShort(numVertices + 1);
indicesBa.writeShort(numVertices + 3);
indicesBa.writeShort(numVertices + 2);
numVertices += 4;
}
}
indexBuffer = context.createIndexBuffer(numParticles * 6);
//indexBuffer.uploadFromVector(indices, 0, numParticles * 6);
indexBuffer.uploadFromByteArray(indicesBa, 0, 0, numParticles * 6);
}