Jump to content
  • Advertisement
Sign in to follow this  
Opwiz

API-independent vertex buffer

This topic is 4899 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

I got an idea for vertex buffer management in my 3d engine and I would like to know what you think. As I've got little experience actually using vertex buffers this design might be way off. My API-independent vertex buffer class will look something like this:
public class VertexBuffer
{
	private int bufferIndex;
	private int offset;
	private VertexBufferOptions options;
	private bool needUpdate;
	private bool init;
	private object[] vertex;
	... 
}

When e.g. my direct3d renderer is told to use a certain vertex buffer it first checks if it has been initialized (indicated by the init flag) and if not the vertices are stored in hardware (unless the options specifies software usage), the direct3d renderer has a list of direct3d vertex buffers and attempts to put the vertex data in one of them or creates a new one if necessary. The renderer sets the bufferIndex and offset variables that indicates which direct3d vertex buffer and where the vertex data is stored at. The needUpdate flag indicates if the vertices stored in software has been updated and need to be reloaded into hardware. A copy of the vertices is always kept in software which may or may not be inefficient (you'll need a copy of the data anyway if the device is lost right?). If a single vertex is updated all vertices are reloaded into hardware which also might be inefficient (a solution might be to keep track of the indexes of the vertices that has been updated). Any comments?

Share this post


Link to post
Share on other sites
Advertisement
I am in the same dilemma as you are. And I have thought alot on how to solve the platform independent Vertex Buffer.

One way is to keep a copy (like you do) in a structure of your own. However, you will use the double amount of RAM, since it has to be stored in the platform-dependent vertexbuffer too.

At the moment, I do something similar to what you are doing here, but I don't like having two sets of identical data, that have to be syncronized.

DX's vertexbuffer can be opened for read-only, and if you do that, you don't need to lock the gfx-hardware. So isn't it possible to use the API-specific vertexbuffer for final storage? And then just make an interface above it, that is platform-independent?

Something like this:

class Vertexbuffer
{

public:
virtual Vertex* GetVertex(int a_vertexindex) = 0;
virtual void* SetVertex(Vertex* a_vertex, int a_vertexindex) = 0;
...
...
...
}

class DXVertexbuffer : public Vertexbuffer
{
protected:
LPDIRECT3DVERTEXBUFFER9 m_vertexbuffer;


public:
virtual Vertex* GetVertex(int a_vertexindex);
virtual void* SetVertex(Vertex* a_vertex, int a_vertexindex);
...
...
...
}

class GLVertexbuffer : public Vertexbuffer
{
protected:
// whatever the OGL-buffer looks like...

public:
virtual Vertex* GetVertex(int a_vertexindex);
virtual void* SetVertex(Vertex* a_vertex, int a_vertexindex);
...
...
...
}



I suggest a pure interface, that the API-specific classes inherit from. They are forced to support the methods, and thus you have made a platform-independent superclass, that guarantees you uniform access, no matter what platform you are using. That way, the API specific classes can write their methods to get and set data directly in their buffers, and they have the responsibility, that the values are returned in the right format (in my example the format is Vertex).
If you set a vertex in your vertexbuffer, then you have to access the hardware anyway to update it.

If you do this system, you can easily change the API specific class to use another API, without having to change a thing in the classes using it (since the interface is the same).

At least that is some thoughts I had on making vertexbuffers independent, though I haven't implemented it yet. Therefore Im not sure if it is really possible in practice - especially if it is true what you say, that you lose the vertexbuffer if the device is lost...

Share this post


Link to post
Share on other sites
OGRE deals with this in a clean and straightforward matter. It basically involves having a basic HardwareBuffer class that has pure virtual functions for lock, unlock, write data, and read data. It also defines its own flags which are translated internally for each API. Then all you have to do is implement that interface for OpenGL and Direct3D. It's useful that vertex buffers behave almost identically between the two APIs.

Share this post


Link to post
Share on other sites
Quote:
Original post by Promit
OGRE deals with this in a clean and straightforward matter. It basically involves having a basic HardwareBuffer class that has pure virtual functions for lock, unlock, write data, and read data. It also defines its own flags which are translated internally for each API. Then all you have to do is implement that interface for OpenGL and Direct3D. It's useful that vertex buffers behave almost identically between the two APIs.

Yes that is very straight forward and probably the best way to go. I'll let the client programmer worry about batching and minimizing lock/unlock calls for now..

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!