0
\$\begingroup\$

I have different vertex layouts I'm using to render things in DirectX and as of now I've just used the same vertex layout for every mesh I load in. But now I want to have the vertex layout change according to the mesh loaded in. If the mesh has a normal map I would like to have an vertex layout with tangents so I can render with the normal map. If I don't I would like to have an vertex layout without tangents to save me some time on my rendering. Right now in my mesh class I have...

std::vector<Vertex::PosNormalTexTan> vertices;

where PosNormalTexTan is the vertex layout. Then I have...

void Construct(ID3D11Device* device, UINT vCount, std::vector<Vertex::PosNormalTexTan> vertices, std::vector<UINT> indices);

Called when constructing the mesh. I would like the possibility of using

std::vector<Vertex::Basic32> vertices;

How could I do this without creating an overload for every vertex layout?

\$\endgroup\$
1
  • \$\begingroup\$ A template is one option, although you can also make your Construct just take a generic void* for the vertices and a size_t stride. See DirectXMesh for an example API that handles all the various vertex formats and 16-bit vs. 32-bit indices. In particular, see the VBReader/VBWRiter classes. \$\endgroup\$ – Chuck Walbourn Feb 10 '15 at 19:58
0
\$\begingroup\$

Edit:
This compiles (C#):

void createVertexBuffer<T>() where T : struct, IVertexType
{
  List<T> vertexList = new List<T>();
  VertexBuffer vb = new VertexBuffer(OpenCityComponent.GraphicsDevice, typeof(T), 10, BufferUsage.None);
  vb.SetData(vertexList.ToArray());
}

To move List<T> into the class, I'd have to move <T> to the class and enumerate them all, which is what you are wanting to avoid. Using an untyped list, I would have to know T ahead of time to be able to re-cast correctly....

I am "discouraged" from using pointers in C#, so there may just not be a C# analogue I can answer with. I will continue thinking on this while I read the DirectXMesh link.

\$\endgroup\$
7
  • \$\begingroup\$ I see how I can make the function take a generic T. But how could I have the std::vector<Vertex::PosNormalTexTan> vertices stored in the mesh class be template <typename T> std::vector<T> vertices without getting errors? \$\endgroup\$ – Andrew Wilson Feb 11 '15 at 4:08
  • \$\begingroup\$ revised my code; also consider Chuck Walbourn's comment above as I am not an expert outside of XNA. \$\endgroup\$ – Jon Feb 11 '15 at 4:22
  • \$\begingroup\$ I have a cpu copy of vertices. They aren't just put in the buffer and then disposed. \$\endgroup\$ – Andrew Wilson Feb 11 '15 at 4:26
  • \$\begingroup\$ How could I get the type that the generic turned out to be? \$\endgroup\$ – Andrew Wilson Feb 11 '15 at 5:24
  • \$\begingroup\$ That's the problem.. AFAIK, it would be complicated, using reflection and, ultimately, an enumeration of each VertexType for casting. I think, Chuck is saying that you can use a pointer with a non-generic method to achieve the same thing. In the end, the CPU just needs to know where the buffer sending begins and ends and in which order to feed bytes; only once it gets to the video card, does it "become" positions, normals, etc. Since you can use pointers, you can put data wherever you want without "having" to be type-safe. \$\endgroup\$ – Jon Feb 11 '15 at 5:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.