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.