How to use multiple vertex buffers?

Hi, I’m new to monogame or XNA, and is currently trying to switch from c++/Opengl to C#/Monogame.

The problem is that I have found the VertexBuffer.SetData can only support a single struct for all the data for a vertex. That is position, normal, color and UV are all bundled into the same struct, like VertexPositionColor.

In opengl, the glVertexAttribPointer can support multiple attributes, that are upload to GPU separately, e.g. position and normal could be allocated in different arrays. Because my major purpose is for mesh processing and separating these attributes in different arrays is more nature for me.

Is there a similar alternative for glVertexAttribPointer, which can do the separation?

Thanks,

Han

Hey @saedrna! Welcome to the forums :slight_smile:

A vertex buffer only supports a single struct, but you can use multiple vertex buffers, each with their own channels that you specify with the VertexBuffer.VertexDeclaration property. You can bind them with GraphicsDevice.SetVertexBuffers. Note that you need to wrap your vertex buffers in a VertexBufferBinding before you pass them in. Then you can render with GraphicsDevice.DrawPrimitives or GraphicsDevice.DrawIndexedPrimitives. The OpenGL backend uses glVertexAttribPointer to bind the channels. If you’re interested in how it’s implemented, you can check out the source code.

VertexBufferBinding has an InstanceFrequency property that you can set for instanced rendering. To use it you need to call GraphicsDevice.DrawInstancedPrimitives.

Hope that helps :slight_smile:

2 Likes

A good example would be to look at existing uses of custom vertex buffers - see for example from the official XNA Samples (cloned for monogame) here:

struct ParticleVertex
	{
		// Stores which corner of the particle quad this vertex represents.
		public Short2 Corner;

		// Stores the starting position of the particle.
		public Vector3 Position;

		// Stores the starting velocity of the particle.
		public Vector3 Velocity;

		// Four random values, used to make each particle look slightly different.
		public Color Random;

		// The time (in seconds) at which this particle was created.
		public float Time;


		// Describe the layout of this vertex structure.
		public static readonly VertexDeclaration VertexDeclaration = new VertexDeclaration
		(
			new VertexElement (0, VertexElementFormat.Short2,
					VertexElementUsage.Position, 0),
	
			new VertexElement (4, VertexElementFormat.Vector3,
					VertexElementUsage.Position, 1),
	
			new VertexElement (16, VertexElementFormat.Vector3,
					VertexElementUsage.Normal, 0),
	
			new VertexElement (28, VertexElementFormat.Color,
					VertexElementUsage.Color, 0),
	
			new VertexElement (32, VertexElementFormat.Single,
					VertexElementUsage.TextureCoordinate, 0)
		);


		// Describe the size of this vertex structure.
		public const int SizeInBytes = 36;
	}

`

3 Likes

@Jjagg @kosmonautgames, I think now I have figured out similar notations between vertex array, vertex buffers in opengl and those in monogame. Thanks:grinning:

1 Like