Making a level editor / Dynamic size vertex buffers

Started by
7 comments, last by ZeroEffect 19 years, 4 months ago
Okay, at the moment I'm making a level editor, and I need to have the ability to add and remove verticies and faces from a dynamic vertex and index buffer, but I seem to remember reading somewhere that actually changing the size of such a buffer after it's been created is not possible, and that's fair enough but now I need to find a way around this so I can allow users total control of the level while keeping everything displaying at a nice and friendly rate. So, there are three possible solutions that I can see: - The first option is not to use vertex buffers at all, and just go with using DrawPrimitiveUP. This would certainly make my life a lot easier, but as a level grows in size and complexity it will slow down my editor to a crawl even when a mesh is not being modified, making it frustrating to traverse and edit (WYSIWYG is kind of useless if WYS takes 2 seconds to render each frame). - The second option is to destroy and re-create the vertex buffer whenever a new vertex/face is added or destroyed. This is naturally not a good idea, although I could probably merge it with the previous technique so that after an object is deselected, it copies the object to a new vertex buffer and when it is modified again, it merely uses internal data to display it using DrawPrimitiveUP. However, this will incur a slighht stall that may be quite long on larger/more detailed objects. - The third option is to make vertex/index buffer 'blocks' of maybe 500 elements or so, and when the number of verticies/faces grows above the 500-vertex range, create a new vertex/index buffer, then during rendering draw both of them in succession, sort of like a linked list in a sense. The main issue I have with this method is it will make it very hard to keep track of specific verticies the more the buffers change, as every time I delete a vertex from the middle of the buffer I will need to update all the face information to make sure that any face using a vertex index after the one that was deleted gets its index shifted down one so that it's pointing to the correct vertex. Even if I manage to get past this problem, as I said in point 3, there's also going to be the problem of managing which verticies a face points to when the indicies will be constantly changing as data is added and removed. As you can see, this is a fairly difficult task which is made all the more by the fact that these sort of things aren't widely discussed so Google hasn't proved incredibly helpful. If anyone has any experience with writing a level editor or a modelling program, I would really appreciate anything you can add that would help me along this path. I think after this experience I might have a look into writing a tutorial on this, as it could be valuable to other people as well. :) Thanks for your time, guys!
Advertisement
I'd make a dynamic buffer at max size, and then completely rebuild it's data every frame. This way, when deleting vertices, you're not left with empty spaces in the middle of the VB.

If you run out of room in the first VB, create another one (this should only be done once, not once per frame) and use that as well. If you still need more, make another one.

The important part is to rebuild the data from scratch every frame/every time something changes. That way, your data is always organized correctly in the VB, without any gaps from stuff being deleted.
Sirob Yes.» - status: Work-O-Rama.
The gaps aren't so much of a problem, keeping all of the index lists pointing to the correct data is where the main problem lies.

Due to the fact that I'm going to be moving around verticies that may be linked to more that one polygon, I've decided to go with a indexed mesh approach so that moving a vertex will alter its connected faces accordingly. However, if I delete a vertex from the mesh and fill the gap with data, the index buffer will start referring to the wrong verticies, and this is what I'm trying to avoid.

I think I will go with the 'VB chain' approach, it's just a matter of how I'm going to deal with synchronisation now. Hell, I may be taking this from completly the wrong approach. :)
Okay, I ran a couple of tests, but I've come across a problem with the VB chain idea.

Namely, what can I do if a triangle in the the index buffer references verticies from two or three different vertex buffers? I cant change vertex buffers mid-triangle, so this is going to pose somewhat of a problem.

Does anyone have a solution for this, or possibly an alternative way of dealing with dynamically-sizing vertex buffers?
Can't you just create a buffer bigger than it needs to be, then when you fill it up create a new buffer even bigger still and copy everything into that.
Just like a Vector.
That wouldn't work, since buffers have a maximum size, and he's assuming he'll pass that size (quite probable too).


Anywho, I guess in those cases you have no choice but to duplicate the vertices.

That brings me back to what I said before, I think you need to use your own structure to hold and manipulate the vertices, and then just transfer that structure into a VB when you need to. It might seem slower, but VBs do have several limitations that would make any other method quite difficult, IMO.
Sirob Yes.» - status: Work-O-Rama.
I thought about this, because I am doing much the same of what you're doing.


I am using a window to get the information from the user as to what size of terrain they want, as well as the resolution they want. From that I will create a global vertex buffer. Also, if you are wanting to incorporate other objects, just create classes for these objects and give them a VB. You can create a linked list of the objects to draw them.

There's just not a good way to do it with VBs. At least from what I can see.
I WISH SOMEONE WOULD FIX THE DAMNED LOGIN!
Create a big VB, if its size is maxed create a new one and so forth until done editing.

Then write an algroythm to nicely compile the VB's created while editing in a nice managable VB(s) for the game process.

That would leave no heaping CPU work till the end.
I would tend to agree with sirob regarding the use of your own structures to manage the vertex data (internally) and then recreate/update the vertex buffer only when a change has been made to that vertex data. Relatively speaking, the time spent by a user adding/removing/modifying verties in a mesh is very small. As such, you should only ever recreate/modify the VB when an actual change has occurred. This may help in the sizing department as well. By recreating the VB you can size it exactly to match the number of vertices in a mesh (unless you reach the maximum limit of the video card).

Try not to focus on how slow creating/updating the VB is. Focus on limiting the number of times you actually have to do it (i.e. every frame == very bad).

Chris Z.
Chris Z. GPU FX

This topic is closed to new replies.

Advertisement