Welcome to the first part of the “How to build a versatile 2D engine in Stage3D” series!

If you’re already familiar with what VertexBuffers are in other programming languages, this should be a brief recap of what you already know. Otherwise, if you’re freshly new to this topic, this tutorial will help you understand what they are and how they’re created.

Since this series is split up into multiple parts, it will require a bit of patience before you see any movement on the screen. But the more you grasp how each GPU resources interact between each other, the more prepared you will be to write a great 2D engine tailored to your needs.

Oh and before we start, here’s a quick poll I would like you to answer!

Please indicate why you're interested in this article series:

View Results

Loading ... Loading ...

What to expect:

This tutorial will cover mostly theory  regarding the usage of VertexBuffers to store and organize data on the GPU (Graphics Processing Unit). While code snippets will be kept to a minimum, this is what you can expect from this first article:

– Gain a better understanding of what VertexBuffers are;
– Know what type of information you can store in them;
– Understand that their data can be merged or used separately with other VertexBuffers;
– See how they are instantiated;

Alright, that should be plenty to cover in this first article, so let’s get started!

What ARE VertexBuffers?

VertexBuffers, also known as VBOs (Vertex Buffer Object), are a type of resource structure on your Graphics card (GPU) that gives you access to transfer a long list of data, typically numbers (floats, to be specific).

To be honest, VertexBuffers on their own can’t do much! But it is important to understand how the data is used from it, since uploading a bunch of numbers to it doesn’t necessarily mean the GPU will read it from start to finish (or know what to do with the data, for that matter!)

Alright, time to stop being vague and show an illustration!


As you can see, the code on the CPU  side tells the GPU to prepare a new VertexBuffer object. Once the resource is ready, you can populate it with lots of numeric data.

But how do you know how much data to send it?

Or better yet…

What will the data be used for?

What type of data does a VertexBuffer store?

This can be tricky to decide. When designing an engine or framework around GPU resources, you have to come up with some of this information yourself.

For instance, in a 3D engine, you may want to create a VertexBuffer to hold the position of each vertices of a mesh / model (X, Y and Z coordinates), so that’s 3 numbers per vertices. If you know the total of vertices in the mesh or model, let’s say… 50 vertices, then you know your VertexBuffer will need to hold at least 150 floats (50 vertices * 3 fields in the data-format).


What if you don’t know the total number of vertices?

This is often the case in dynamic engines where the meshes, models or sprites are batched  together in one VertexBuffer.

In a situation like this, you can prepare a huge VertexBuffer that is large enough to hold the maximum amount of sprites or meshes you intend to use at any given time in your project. Since this maximum value may vary from one project to another, you may want to expose this variable so it can be changed according to your needs.


This would work similarly to an Object Pooling system, but you would also need to keep track of which Vertex ID your Mesh starts at in the buffer and how many vertices it occupies – that way you know which Vertices to update if you move or alter the mesh at runtime.

Question: But how do I figure-out my maximum number of vertices for my own projects?

Answer: There’s a few factors that will influence how big or small you should make your maximum value. It depends on a case-by-case basis, but ask yourself:
– Will you be running your game / app on Mobile devices?
– Will it only be played on desktops?
– Will you have several hundreds sprites on screen, or thousands?
– Do you intend to implement Particle Emitters (ex: 1 particle/quad = 4 vertices)?
– Will you be conducting some stress-tests to measure your engine’s performance?
– and much more…

But generally, I would say it doesn’t hurt to set it to several thousands (ex: 16000) since it’s better to have more than enough to start off. Then, you may want to decrease your maximum value on an ongoing basis while developing a given project so you’re not wasting too much GPU resources.

This is why it’s a good idea to leave this property accessible outside your engine / framework.

Let’s take another example. Say… in a 2D engine, you could have VertexBuffer A) hold all the X and Y coordinates (2 fields), and VertexBuffer B) hold the color information of each vertices in RGBA channels (4 fields). If you know you won’t need more than 2000 vertices, then you could initialize your VertexBuffer A) with 4000 floats (2000 * 2 fields ), and VertexBuffer B) with 8000 floats (2000 * 4 fields ).


Makes sense? Hopefully!

Now, the fact that you can use more than one VertexBuffer in a given application may raise another question…

How long can my VertexBuffer’s data-format be?

The data-format (ex: X and Y coordinates, color RGBA channels) of a VertexBuffer can vary depending on how you intend to populate the numbers in the VertexBuffer.

By that, I mostly mean how frequently  you believe you will be changing the data.
(yes! the VertexBuffer’s data can be updated!)

If you were to use a VertexBuffer mostly for static objects (sprites that are not moving ), then you could merge some of it’s data-formats together, like the position (XY) and color information (RGBA) for instance. So in total, you would have 6 floats per vertices to take into account
(2 fields for position + 4 fields for color).

If, however, your project mostly requires something more dynamic for updating the position on each frame, but NOT the color – then it would probably be a better idea to use two separate VertexBuffers to upload only the necessary changes in one (only positions, in this case), and leave the other one unaltered.


NOTE: It might be tempting to ponder on the idea of using a hybrid system where both static VertexBuffers (with merged data) and dynamic VertexBuffers (with separated data) can run in your engine.

But consider this:
Each time your engine will iterate through your sprites / meshes that use either the static or dynamic VBOs, a state-change will be required on the GPU when you set which VBOs are in-use during a given render pass (meaning extra draw-calls, potentially slower performance). However, if the order of your sprites is well-organized to minimize the switches between the static and dynamic VBOs, you shouldn’t have to worry too much.

(More about state-changes in later articles…)

So how do you create a VertexBuffer?

Now that we got some theory out of the way, lets see how we instantiate a new VertexBuffer object! This does require a reference to a Context3D object, so be sure to store it somewhere you can have easy access to.

For example, you can prepare it like so:

package  {
	import flash.display.Sprite;
	import flash.display.Stage3D;
	import flash.display3D.Context3D;

	 * A simple class to prepare a Stage3D / Context3D object.
	 * @author Pierre Chamberlain
	public class Stage3DMain extends Sprite {
		public static var STAGE3D:Stage3D;
		public static var CONTEXT:Context3D;
		public function Stage3DMain() {
			stage ? init() : addEventListener(Event.ADDED_TO_STAGE, init );
		private function init(e:Event=null):void {
			e && removeEventListener(Event.ADDED_TO_STAGE, init);
			//Pick the first Stage3D object:
			STAGE3D = stage.stage3Ds[0];
			STAGE3D.addEventListener(Event.CONTEXT3D_CREATE, onContextCreated );
			STAGE3D.requestContext3D("auto", "baseline");
		private function onContextCreated(e:Event):void {
			CONTEXT = STAGE3D.context3D;
			if (!CONTEXT) {
				throw new Error("The context could not be requested.");
			CONTEXT.configureBackBuffer(stage.stageWidth, stage.stageHeight, 0 );
			stage.addEventListener(Event.ENTER_FRAME, onRender);
		private function prepareGPUResources():void {
			// Instantiate GPU resources here...
		private function onRender(e:Event):void {
			CONTEXT.clear(0.0, 0.2, 0.8);
			// Bind / Draw from GPU resources here...

This way you can refer to your Context3D  object via Stage3DMain.CONTEXT, although you can rename or set this up any way you want.

Let’s now create that VertexBuffer!

First create a property in your class to hold the reference of our VBO:

private var _vertex:VertexBuffer3D;

And then, let’s instantiate it with our Context3D object inside the prepareGPUResources() method:

private function prepareGPUResources():void {
	var numVertices:int = 2000;
	var numOfFields:int = 6;
	_vertex = CONTEXT.createVertexBuffer(numVertices, numOfFields);
You cannot simply use the statement:
new VertexBuffer3D()

Every GPU resources must be created from a specific Context3D object. Think of the Context3D object as a sandbox  and the entire Graphic-Card as the school yard , you’re “borrowing” a section of it to run your application / game on.

This way, if your system is running other hardware-accelerated Graphics application or games, they won’t step on each others’ toes.

What now?

Although the code *should*  compile, this VertexBuffer3D object won’t be very useful on it’s own. We need to create other important resources from the GPU, such as an IndexBuffer3D and Program3D object.

It will take a bit more work to see anything on the screen, but stay tuned!

We’ll go over the IndexBuffer3D object next.

Ciao for now!

Continue to Part 2: Using IndexBuffers