Let's say you want to store this data in each vertex in your 3D model:
```cs
public struct ExampleVertex
{
public Vector3F position;
public uint colour;
}
```
Rather than creating a VBO, VAO and setting attributes manually, you can override the [[TypedVertexBuffer]] class, which is a helper class built on top of [[VertexBuffer]].
```cs
public unsafe class ExampleVertexBuffer : TypedVertexBuffer<ExampleVertex>
{
public ExampleVertexBuffer() : base() { }
public ExampleVertexBuffer(int size, ExampleVertex* data, bool allocate) : base(size, data, allocate)
{
primitiveType = PrimitiveType.TriangleStrip;
}
public override void SetupAttributes()
{
SetAttrib(3, VertexAttribPointerType.Float, "aPosition");
SetAttrib(4, VertexAttribPointerType.UnsignedByte, "aColour", true);
}
}
```
In the constructor there are 3 parameters:
```
size - the size of the OpenGL buffer, i.e. how many ExampleVertex it can store
data - the data you would like to store in this buffer. Provide null if you'll populate the data later
allocate - whether or not to allocate an array on the CPU for you
```
In the `SetupAttributes` function, you tell OpenGL the structure of the buffer. It is also used to automatically generate this vertex shader code, so you don't need to write this in every vertex shader:
```cs
layout (location = 0) in vec3 aPosition;
loayout (location = 1) in vec4 aColour;
```
## Populating Data
The first way of populating data in a vertex buffer is via the constructor:
```cs
void Method1()
{
// Allocate
ExampleVertex* data = Allocator.Alloc<ExampleVertex>(64);
// Write to data
...
// Create VBO, VAO
var buffer = new ExampleVertexBuffer(64, data, false);
// Send data to the GPU
buffer.BufferData();
}
```
Method 2 - use the `allocate` helper, so the vertex buffer allocates an array of `ExampleVertex` for you, which is stored in the `data` field:
```cs
void Method2()
{
// Create VBO, VAO and allocate data
var buffer = new ExampleVertexBuffer(64, null, true);
var write = buffer.data;
// Write to data
write->position = Vector3F.Zero;
write->colour = Color.Cyan.Value;
...
// Send data to the GPU
buffer.BufferData();
}
```
Method 3 - don't allocate any data, instead write directly to the mapped buffer:
```cs
void Method3()
{
// Create VBO and VAO
var buffer = new ExampleVertexBuffer(64, null, false);
var write = buffer.MapBuffer();
// Write to mapped pointer
write->position = Vector3F.Zero;
write->colour = Color.Cyan.Value;
...
// Send data to the GPU
buffer.FlushMappedBufferRange();
}
```
## Vertex Attributes
You can read more about vertex attributes in the [[VertexAttribStrings]] class page.