Jump to content
  • Advertisement
Sign in to follow this  
kimt

Creating a vertex buffer within a structure

This topic is 4148 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I am currently writing an application using DirectX9 that needs to graphically display a network of nodes. I would like to indicate the presence of a connection between nodes by drawing a line between them. However, the issue is that the node data will continually be changing, so it doesn't make sense to me to try to hold onto a large vertex buffer containing all the lines to be drawn. Instead of using a new buffer from scratch every single run, which could be a performance hit when I run a large number of nodes, I attempted to have each node hold onto its own vertex buffer and update that small buffer whenever the node was modified. But this has been driving me crazy. The node is contained in a struct, which has a vertex buffer pointer as a member, i.e: struct node { ... IDirect3DVertexBuffer9* vb; ... void RecreateVB(IDirect3DDevice9* d3dDevice); }; I pass the d3dDevice to RecreateVB because it is needed for VB creation. However, whenever I attempt: d3dDevice->CreateVertexBuffer(2*cNeighbors*sizeof(VertexPos),D3DUSAGE_DYNAMIC,0,D3DPOOL_DEFAULT,&vb,0); I get an access violation. On the other hand, I have been able to run the same code above in other parts of my program without trouble. This leads me to believe that I am running into issues trying to create a buffer within the structure. On the other hand, since I am creating only a pointer, I'm not sure if this is an issue. Can somebody give me any suggestions on what I'm doing incorrectly?

Share this post


Link to post
Share on other sites
Advertisement
Well I'm not sure what's causing the problem, but I think you might want to reconsider your design. Having each node have its own VB will cause performance problems because you'll have to switch between them during rendering and each one will be one Draw call.

I would suggest having a list of vertices and a list of indices, so you can draw only the ones on screen, plus then everything you want can be drawn with a single DrawUserIndexedPrimatives(whatever it is in C++) call. You'll have to build up the index list each frame, which might be expensive depending on the amount of nodes. Perhaps add in some form of spacial partitioning.

Share this post


Link to post
Share on other sites
Scet is right. You'll want to manage all of the nodes to write to a single vertex buffer. You'll want to specify dynamic and write only to speed things up. Here's a method I use in one of my classes:


int maxw = this.initializer.Device.DeviceCaps.MaxTextureWidth;
int maxh = this.initializer.Device.DeviceCaps.MaxTextureHeight;

this.width = width + this.growthSurplusSize;
this.height = height + this.growthSurplusSize;
if (this.width > maxw) this.width = maxw;
if (this.height > maxh) this.height = maxh;

this.masterTexture = new Texture(
this.initializer.Device,
this.width,
this.height,
1,
Usage.RenderTarget,
Format.A8R8G8B8,
this.initializer.Device.PresentationParameters.BackBufferFormat,
Pool.Default);





You'll notice I gave it some extra room to grow by adding the growthSurplusSize to the Texture's dimensions.

HTH,

Devin

Share this post


Link to post
Share on other sites
Actually, after thinking about this for a while, I decided to "cheat" and use simple cylinders rather than lines to denote the connections. I did this because this way I do not need to create vertex or index buffers to get the geometry on the screen. I would not have to do the many operations to keep the buffers updated.

I have organized the nodes in my data structure such that it contains pointers to its neighbors. And because all of my nodes lie on the z=0 plane, to connect them using a cylinder, I simply need to find the relevant angle of rotation for the connection.

This raises another question though. How does the drawing of a mesh compare in general performance-wise with drawing objects from a buffer? I would imagine it would be more intensive (for a complicated mesh... which I'm not sure if the cylinder counts as). However, in this case, I think the ability to remove all the vertex generation workload (for the computer and me!) may tip it in the direction of the cylinders.

Share this post


Link to post
Share on other sites
Quote:
Original post by kimt
How does the drawing of a mesh compare in general performance-wise with drawing objects from a buffer?

Sounds to me like you're making a distinction that doesn't really exist. They are basically the same thing, except the mesh has probably encapsulated a lot of the nitty gritty that you were having trouble with, including a vertex buffer per mesh. Every primitive that D3D draws ultimately comes from some type of vertex buffer, whether you have created it explicitly or not. By only using meshes you lose the ability to optimize the vertex code for your purposes.

The posters above suggesting a single large dynamic vertex buffer have identified the fastest way to do what you're trying to do, but perhaps the 'slow' way is more than adequate for your needs and might make your code simpler. If that makes any sense. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by kimt
I have organized the nodes in my data structure such that it contains pointers to its neighbors. And because all of my nodes lie on the z=0 plane, to connect them using a cylinder, I simply need to find the relevant angle of rotation for the connection.

Just another quick comment: you don't have to use 3D coordinates if they aren't relevent to your application. Direct3D just draws triangles; it doesn't really care what they represent in a traditional 2D/3D sense. If you prefer to give D3D transformed coordinates (which is very common in 2D applications) you are more than welcome to do so; simply specify your coordinates in screen space and update your FVF declaration. This is very common for sprite engines but has other uses as well.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!