what is the function of the third parameter of 'CreateVertexBuffer'

Started by
4 comments, last by 21st Century Moose 10 years, 10 months ago

even specifying D3DFVF_XYZ | D3DFVF_XYZRHW, CreateVertexBuffer still works

Advertisement

That is your flexible vertex format. Google it for more information. If I remember correctly this only matters if you are using a fixed function pipeline, aka not using shaders and your own declared custom vertex format to draw. Someone correct me if I am wrong.

Edit: MSDN says if you set a valid flag then it becomes a FVF vertex buffer, other wise you can simply set to 0 if you are using your own vertex format.

Here's why calling CreateVertexBuffer with D3DFVF_XYZ | D3DFVF_XYZRHW still works:

As defined in d3d9types.h, D3DFVF_XYZ equals 2, and D3DFVF_XYZRHW equals 4. ORing them together results in 6, which is the value of D3DFVF_XYZB1. So D3DFVF_XYZ | D3DFVF_XYZRHW is equivalent to D3DFVF_XYZB1 - the function call still succeeds, but isn't necessarily doing what you expect.

In fact, D3DFVF_XYZ, D3DFVF_XYZRHW, D3DFVF_XYZB1, D3DFVF_XYZB2, D3DFVF_XYZB3, D3DFVF_XYZB4, and D3DFVF_XYZB5 are all theoretically mutually exclusive, but ORing together any combination of them will result in a valid format descriptor - just not necessarily one you want.

It's always good to remember that calling a function with an "invalid" combination of flags doesn't guarantee that the function call will fail - it may do something unexpected instead.

Here's why calling CreateVertexBuffer with D3DFVF_XYZ | D3DFVF_XYZRHW still works:

As defined in d3d9types.h, D3DFVF_XYZ equals 2, and D3DFVF_XYZRHW equals 4. ORing them together results in 6, which is the value of D3DFVF_XYZB1. So D3DFVF_XYZ | D3DFVF_XYZRHW is equivalent to D3DFVF_XYZB1 - the function call still succeeds, but isn't necessarily doing what you expect.

In fact, D3DFVF_XYZ, D3DFVF_XYZRHW, D3DFVF_XYZB1, D3DFVF_XYZB2, D3DFVF_XYZB3, D3DFVF_XYZB4, and D3DFVF_XYZB5 are all theoretically mutually exclusive, but ORing together any combination of them will result in a valid format descriptor - just not necessarily one you want.

It's always good to remember that calling a function with an "invalid" combination of flags doesn't guarantee that the function call will fail - it may do something unexpected instead.

then what 'FVF' value to specify can make CreateVertexBuffer fail

Using D3DFVF can be confusing to new comers. Especially you also have to know the specific order that it expect your vertices to be in. You are better off using VertexDeclaration to defined the layout of your vertex.

Unless you're using IDirect3DDevice9::ProcessVertices the FVF parameter has no purpose whatsoever. Setting the FVF parameter to non-zero (which must be a valid FVF code) creates what's known as an "FVF Vertex Buffer" which then allows it to be used as the destination buffer for a ProcessVertices call (the failure you expect would happen during the ProcessVertices call, not the CreateVertexBuffer call). Otherwise, there's no point in setting the FVF parameter to anything but zero.

In general you don't want to use ProcessVertices. On paper it looks like a nice API call - in theory allowing you to run your vertex shading ahead of time so you can distribute workload better, or read back the results of your transformations so that you can possibly do something interesting or useful with them.

In practice ProcessVertices is not that great.

Firstly, it does all vertex processing in software. Not only that, but it also requires you to set software vertex processing at startup (or mixed, then switch the render state to software) so using it will affect the performance of all of your vertex processing, not just the ProcessVertices call.

Secondly, by requiring your destination buffer to have a valid FVF code, you have restrictions on the type of the data that the vertex buffer can contain.

So, this API call may have made sense in the old shader-model 2 (or even fixed pipeline) days, and may have been useful in the old software T&L days (it may also be useful if you're writing a modelling program), but for anything else you should just forget it exists.

In other words, set the FVF parameter to CreateVertexBuffer to zero, and forget that the parameter exists or has any meaning.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement