Jump to content
  • Advertisement

Archived

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

Lohrno

How do I copy a VertexBuffer, and then read the contents?

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

Okay, what I am trying to do is duplicate a vertexbuffer so that I can copy it, process the vertices, and then do poly by poly collision detection. Here''s the code I have so far to copy a vertex buffer. void Model::GetCopyOfVB(LPDIRECT3DVERTEXBUFFER9 BufCopy, DWORD *NumVertices) { LPDIRECT3DVERTEXBUFFER9 ModelVB = 0; D3DVERTEXBUFFER_DESC VBDesc; pMesh->GetVertexBuffer(&ModelVB); if (NumVertices != NULL) *NumVertices = pMesh->GetNumVertices(); else { OutputDebugString("Nope, the number of vertices pointer is null...try again...\n"); return; } ModelVB->GetDesc(&VBDesc); g_pd3dDevice->CreateVertexBuffer(VBDesc.Size,D3DUSAGE_SOFTWAREPROCESSING, VBDesc.FVF,D3DPOOL_SYSTEMMEM, &BufCopy,NULL); } The problem I''m having is that I am not sure how I should go about locking the first one (ModelVB) and copying it into the second one. How do I know what FVF, and what size it is? And where do I get a pointer to the vertices themselves. Then, once I have copied it, and processed it using ProcessVertices, I would like to read the x,y, and z coordinates of the vertices. How would I go aobut doing that? -=Lohrno

Share this post


Link to post
Share on other sites
Advertisement
quote:
And where do I get a pointer to the vertices themselves.


In the beginner forum?

The buffer would need to be created without WRITEONLY. It will be dreadfully slow to read from a buffer if it''s in videocard memory. We can see you''re making the new buffer in system memory, and not write-only, but you''ll have to make sure the buffer passed in was created the same way.

Use Lock to get the pointer, just like you do when writing to the buffer. You''ll need to store the FVF and/or stride values somewhere for yourself.

To read the vertices after they have been processed, again, Lock the buffer and read the values. Using process vertices will run things through a projection matrix, resulting in XYZRHW coordinates which you''ll likely have trouble comparing to the originals.

Also, process vertices writes to a second buffer (ie: Does a copy and process for you in one step), so you don''t need to copy the buffer yourself anyway.

Share this post


Link to post
Share on other sites
quote:
Original post by Namethatnobodyelsetook
In the beginner forum?


cute...


quote:
Also, process vertices writes to a second buffer (ie: Does a copy and process for you in one step), so you don''t need to copy the buffer yourself anyway.


Okay cool.. so I don''t need to do this whole copying thing.

The hitch here is that I''m using LPD3DXMESH to load my .X files. How would I figure out the size of the given FVF structure so I know how far I should increment my pointer...? (Yes I put it in SYSTEMMEM, and did not specify WRITEONLY.)

I load x files like so:


  
if( FAILED( D3DXLoadMeshFromX( filename, D3DXMESH_SYSTEMMEM,
g_pd3dDevice, NULL,
&pD3DXMtrlBuffer, NULL, &dwNumMaterials,
&pMesh ) ) )


(at least I hope it doesnt specify writeonly for me...)

-=Lohrno

Share this post


Link to post
Share on other sites
I''ve never used a .X file, but pressing F12 on your D3DX define I can see you can specify additional options. You''re not specifying write only, so you probably won''t get that. You should include D3DXMESH_SOFTWAREPROCESSING though.

The format for an FVF buffer is well defined. Here''s a (badly written in terms of XYZ format types) conversion routine.


  
unsigned long ConvertD3DFVFToStride(unsigned long nFVF)
{
unsigned long nStride = 0;

if (nFVF & D3DFVF_XYZ)
nStride += 12;
if (nFVF & D3DFVF_XYZRHW)
nStride += 16;
if (nFVF & D3DFVF_NORMAL)
nStride += 12;
if (nFVF & D3DFVF_PSIZE)
nStride += 4;
if (nFVF & D3DFVF_DIFFUSE)
nStride += 4;
if (nFVF & D3DFVF_SPECULAR)
nStride += 4;
nStride += ( (nFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT ) * 8;

return nStride;
}

Share this post


Link to post
Share on other sites
Hmmm that''s what I was afraid of having to do...

Oh well, better get started, thanks a lot for the help!

-=Lohrno

Share this post


Link to post
Share on other sites
I was just going to post the same question.

I am just doing a simple D3DXCreateBox. It looks like it doesn''t have a color section in the FVF by default which is what I want to access. How can you specify the vertex format to use in my case? Or, once I know the stride of the buffer, how do I know what the offset is to each member of the vertex?

Share this post


Link to post
Share on other sites
quote:
Original post by UnknownPlayer
Just a note - D3DX has a function which does this for you, can''t remember the name though.

##UnknownPlayer##


Uhm a function which tests for collision, or which find the FVF size?

-=Lohrno

Share this post


Link to post
Share on other sites
quote:
Original post by beoch
How can you specify the vertex format to use in my case? Or, once I know the stride of the buffer, how do I know what the offset is to each member of the vertex?


I''ve never used the CreateBox function, so how to add color I couldn''t tell you. Perhaps make your own buffer with color and copy the data. I''m sure you can coax the function into creating colors (DX team tends to be good about things like that), but I don''t know how.

As for the offset of each element, it''s covered in the help files. Specifically, the page that looks exactly like this one:

[url]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dx8_c/directx_cpp/Graphics/ProgrammersGuide/UsingDirect3D/VertexData/FixedFunction/VertexFormats/vformats.asp[/url]

The data comes in RAM in the exact order shown here. Skip any items that aren''t in your FVF, such as blending weights, or point sizes.

ie: D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE

xyz @ 0
normal @ 12
diffuse @ 24
xyz @ 28
...

ie: D3DFVF_XYZRHW | D3DFVF_TEX1

xyzrhw @ 0
uv @ 16
xyzrhw @ 24
...

Share this post


Link to post
Share on other sites
Reading a VB is always bad...
mostly because you have to lock it.

To copy/duplicate a mesh, clone it.

For 3d collisions, compute a dot product, then refine with the bounding spheres, then refine again with the bounding box. In 99% of cases, this works, very fast and just fine...

My $0.02...

Laurent - http://jeux-direct.com/

Share this post


Link to post
Share on other sites

  • 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!