Archived

This topic is now archived and is closed to further replies.

billybob

how to abstract vertex buffers?!

Recommended Posts

i have no idea how to abstract vertex buffers. i guess i could just make a struct with a void* and cast it, but i have no idea how to handle locking and things like that. how do you handle this?

Share this post


Link to post
Share on other sites

  
// Small Vertex Buffer Wrapper

class VertexBuffer {
protected:
Device device;
LPDIRECT3DVERTEXBUFFER9 vb;
public:
VertexBuffer(const Device& device,
UINT length,
DWORD usage,
DWORD fvf,
D3DPOOL pool = D3DPOOL_DEFAULT
) : device(device) {
if(FAILED(device->CreateVertexBuffer(length,usage,fvf,pool,&vb,NULL))) {
throw Exception("Could not Create Vertex Buffer");
}
}
VertexBuffer(const VertexBuffer& other) : device(other.device), vb(other.vb) {
vb->AddRef();
}
~VertexBuffer() {
vb->Release();
}
LPDIRECT3DVERTEXBUFFER9 operator->() {
return vb;
}
LPDIRECT3DVERTEXBUFFER9 getBuffer() {
return vb;
}
};


  
// Typed Vertex Buffer, takes a Fvf compatible Struct

template<typename FvfType> class FvfVertexBuffer : public VertexBuffer {
protected:
bool locked;
public:
FvfVertexBuffer(const Device& device,
UINT length,
DWORD usage,
D3DPOOL pool = D3DPOOL_DEFAULT
) : VertexBuffer(device,length,usage,FvfType::Fvf,pool), locked(false) {
}
FvfVertexBuffer(const FvfVertexBuffer<FvfType>& other) : device(other.device), vb(other.vb), locked(false) {
vb->AddRef();
}
~FvfVertexBuffer() {
vb->Release();
}
FvfType* lockVertexData(DWORD flags=0,unsigned int first=0,unsigned int second=0) {
FvfType* data;
if(FAILED(
vb->Lock(first*sizeof(FvfType),second*sizeof(FvfType),(void**)&data,flags)
)) {
throw Exception("Could not Lock Fvf Vertex Buffer");
}
locked = true;
return data;
}
void unlockVertexData() {
vb->Unlock();
locked = false;
}
LPDIRECT3DVERTEXBUFFER9 getUnlockedBuffer() {
if(locked) {
unlockVertexData();
}
return vb;
}
};


then i can write it like that:


  
struct Vertex {
float x,y,z,rhw;
DWORD color;
enum {
Fvf = D3DFVF_XYZRHW|D3DFVF_DIFFUSE
};
};

Vertex vertices[] = {
{ 120.f, 120.0f, 0.5f, 1.0f, 0xffff0000 },
{ 136.0f, 136.0f, 0.5f, 1.0f, 0xff00ff00 },
{ 120.0f, 136.0f, 0.5f, 1.0f, 0xff00ffff },
};


and where i create the buffer:


  
dx9::FvfVertexBuffer<Vertex> buffer(device,sizeof(vertices),0);
Vertex* target = buffer.lockVertexData();
memcpy(target,vertices,sizeof(vertices));
//actually unneeded, because unlocked before using through .getUnlockedBuffer()

buffer.unlockVertexData();


and somewhere i draw.. that:


  
device->SetStreamSource(0,vertexBuffer.getUnlockedBuffer(),0,sizeof(Vertex));
device->SetFVF(Vertex::Fvf);
device->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);


thats straight from my current playfield..

"take a look around" - limp bizkit
www.google.com

Share this post


Link to post
Share on other sites
while that is really good, it doesn''t let me get away from d3d itself. thats what i need is to make it so the vertex buffer doesn''t know whether its a d3d vertex buffer or another API''s

Share this post


Link to post
Share on other sites
in other words, how would you make a vertex buffer class that could read/write vertices and lock/unlock without knowing whether its a d3d vertex buffer or a opengl one. you would need to be able to pass it to SetStreamSource somehow, without the knowledge that you are sending it to a dx renderer.

like:

class CVertexBuffer
{
//blah blah blah
void * VBData;
//blah blah
};

then when you pass that to a renderer, the renderer internally casts VBData to the format it can read. but if OpenGL and D3D use a different format for vbs, then it won''t work.


void CD3DRenderer::SetVertexSource(CVertexBuffer * ThisCustomBufferThing)
{
Device->SetStreamSource(0, (IDirect3DVertexBuffer8*)ThisCustomBufferThing->GetVB());
}


but you don''t know what API renderer is using

i am using dx8 in C++ btw...

Share this post


Link to post
Share on other sites
I didn''t think OpenGL even used vertex buffers? I thought it was something like ''display lists'' or something like that. (eg. look here.) Even if it does have vertex buffers, the formats are likely to be very different, you may or may not need to lock them, and so on. You probably know more about it than I do, but make sure that you''re familiar with what you''re trying to abstract away before proceeding.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

Share this post


Link to post
Share on other sites
opengl has vertex buffers, they are called vertex arrays there.
the format should be the same, i dont see a problem.

billybob:
you could make an abstacrt base class for your buffers and derive openglvertexbuffer and d3dvertexbuffer from that.
or you could let the rendering device handle your vertex buffers and only it knows if its a d3d or opengl one.(the renderer knows best if its d3d or opengl)

Share this post


Link to post
Share on other sites
quote:
Original post by Kylotan
I didn''t think OpenGL even used vertex buffers? I thought it was something like ''display lists'' or something like that. (eg. look here.) Even if it does have vertex buffers, the formats are likely to be very different, you may or may not need to lock them, and so on. You probably know more about it than I do, but make sure that you''re familiar with what you''re trying to abstract away before proceeding.



thats just it, i have never looked at openGL, so i''m not sure how to abstract d3d vertex buffers.

Share this post


Link to post
Share on other sites