Archived

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

Funkymunky

Dynamic Buffers

Recommended Posts

Funkymunky    1413
Alright I''m getting desperate with these things. I''ve posted this question before, but noone ever replies with a solution. I need a dynamic Index buffer. Does this mean I need a dynamic vertex buffer too, even if that is going to remain the same? I can''t get this damn thing working. here is my basic code for a dynamix index buffer, which does not work. #define D3DFVF_DROVERTS (D3DFVF_XYZ | D3DFVF_DIFFUSE) struct DROVertex { D3DXVECTOR3 position; D3DCOLOR color; }; DROVertex verts[4]; IDirect3DVertexBuffer8 *vbuffer; WORD *indices; IDirect3DIndexBuffer8 *ibuffer; // fill in verts device->CreateVertexBuffer(4*sizeof(DROVertex), D3DUSAGE_SOFTWAREPROCESSING, D3DFVF_DROVERTS, D3DPOOL_DEFAULT, &vbuffer) DROVertex *pVertices; if(vbuffer->Lock(0, sizeof(verts), (BYTE**)&pVertices, 0)) for(int i=0; i<4; i++) { pVertices.position = verts[i].position; pVertices[i].color = verts[i].color; } vbuffer->Unlock(); indices = new WORD[4]; device->CreateIndexBuffer(4*sizeof(WORD), D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &ibuffer) // from here, every 2 seconds i change from 3-4 indices, and draw a triangle fan so it should switch from a triangle to a quad if you catch my drift WORD *pIndices; ibuffer->Lock(0, 3*sizeof(WORD), (BYTE**)&pIndices, D3DLOCK_NOSYSLOCK | D3DLOCK_DISCARD); for(int i=0; i<3; i++) pIndices[i] = indices[i]; ibuffer->Unlock(); // then come render time, I do a drawindexed primitive call, with D3DPT_TRIANGLEFAN and the # of vertices indexed and the # of triangles to draw. Doesnt work. Help?! Please?!?!

Share this post


Link to post
Share on other sites
Boki    124
Show the DIP code, please. The provided code looks ok so far. BTW: use the debug runtime and watch the debug spew may also help.

Bjørn.

Share this post


Link to post
Share on other sites
Funkymunky    1413
device->BeginScene();
device->Clear(0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);

device->SetStreamSource(0, vbuffer, sizeof(DROVertex));
device->SetVertexShader(D3DFVF_DROVERTS);
device->SetIndices(ibuffer, 0);
if(on)
device->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0, 3, 0, 1);
else
device->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0, 4, 0, 2);


Edited by - Funkymunky on July 28, 2001 3:22:55 PM

Share this post


Link to post
Share on other sites
Boki    124
Hm, looks ok.

Some other thing to check (in no particular order):
- return values of the functions (test at least for D3D_OK in debug build)
- order of vertices (or current cull mode)
- colour of the vertices (not white and alpha set to 0xFF)
- type of device (e.g. software processing vbs wont be usable in hw mode)
- ensure that you know whether the locks succeed or not

Bjørn.

Share this post


Link to post
Share on other sites
S1CA    1418
Perhaps being a little bit more specific than "It doesn''t work" will get you more replies!!! - **how** doesn''t it work ? - do you get a crash ?, do you get corrupt graphics ?, do you get an error code back from any calls ?

0. Make sure you''re running with the DEBUG version of the D3D runtime (you get the option when you install the SDK) and make sure you set the slider in the control panel to maximum when you have problems - It should be your first stop particularly if things "just don''t work"

1. You create the vertex buffer with a software vertex processing flag set indicating that all the t&l of that buffer will be done with the CPU... but you don''t set that for the index buffer!! - specify the same processing type for all buffers used in the same DrawPrim call.

2. You use D3DPOOL_DEFAULT which can imply VIDEO memory on a T&L device (even with software vertex processing) - Change it to system if you''re explicitly specifying software vertex processing.

3. Same goes for the DONOTCLIP flag - D3D and the drivers do extra temporary buffer creation based on that flag, particularly with software VP [The PSGP] (to store outcodes etc):
a. Only specify DONOTCLIP if you''re 100% certain every vertex falls within the screen/guardband - otherwise you''ll get artefacts.

4. You don''t need a dynamic vertex buffer with a dynamic index buffer.

5. You shouldn''t be calling DISCARD for every lock!!! - that''ll just chew up video memory - you need to use the correct combination of DISCARD and NOOVERWRITE - look at the DirectX FAQ on MSDN for the correct usage pattern.

6. Performance Note: Creating 4 vertex/index buffers is going to be pretty wasteful - group all stuff using the same format which is used around the same time into single big buffers!

7. Performance Note: Passing less than 20 polygons to a DrawPrimitive call should be considered extremely bad practice - on T&L cards, passing less than 200 per call is bad!

8. All of that assumes its not something simpler and elsewhere like transformation matrices or texture states (how hard have you checked)

--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
Funkymunky    1413
1) Yes, I''ve been running with DEBUG runtimes. slider to max.
2) I don''t have a T&L device
3) ok. i took out DONOTCLIP
4) cool
5) I know: this is a test program because i can''t get a dynamic index buffer working. How will calling discard every time i update the buffer chew up video memory? It returns a pointer to a new memory area, clearing up the old.
6) i know, test prog
7) yes
8) i''ve checked harder than a bull on viagra

all that said, i did find a returned error. My DrawIndexedPrimitive call returns D3DERR_INVALIDCALL, which is about generic as it gets. Everything else is fine, locks, rendercalls...except me. I''m still angry as hell at Microsoft for making this such a pain in the ass. Any more suggestions?

Share this post


Link to post
Share on other sites
DrunkenHyena    805
quote:
Original post by Funkymunky
all that said, i did find a returned error. My DrawIndexedPrimitive call returns D3DERR_INVALIDCALL, which is about generic as it gets. Everything else is fine, locks, rendercalls...except me. I''m still angry as hell at Microsoft for making this such a pain in the ass. Any more suggestions?


G''day!

I don''t see anything in the code that should make it fail. It could be as simple as bad test data, or your ''on'' flag could be set wrong.

I can honestly say that I''ve never seen an INVALIDCALL without something being dumped to the debug spew.



Stay Casual,

Ken
Drunken Hyena

Share this post


Link to post
Share on other sites
Funkymunky    1413
hhmmm...what does "Stream 0 stride should match the stride, implied by the current vertex shader"

friends don''t let friends code while under the influence of prescription drugs. Damn i wrote this crap like a crackhead....not..that...crack....is.....prescribed......

Share this post


Link to post
Share on other sites
Boki    124
"Stream 0 stride should match the stride, implied by the current vertex shader" means that the size of your vertex structure is not the same as the one d2d expected - even thought it seems to be...

Try to align DROVertex to 4 bytes (via pragma pack( push, 4 ) and an accompaning pragma pack( pop ) after the struct).

Bjørn.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Hmmm,

Maybe I do it differently but it doesn''t look like your copying the data into your vertex buffer and index buffer properly.

instead of pVertices = verts[i].somevariable etc.

use:-
int iOffset = 0;
for (int i = 0; i < 4; i++) {
memcpy(pVertices + iOffset, Verts[i], sizeof(DROVertex));
iOffset += sizeof(DROVertex);
}

If the Verts[i] bit doesn''t work create a pointer to your vertex
structure and use the new operator
i.e.
DROVertex *pVert;
pVert = new DROVertex[4];
Then fill the structure with data and pass this pointer to the memcpy function instead of Verts[i]. i.e. as pVert[i].

Do similar for the index buffers.

Something else I noticed.
You put:-
pVertices.position = verts[i].position;
pVertices[i].color = verts[i].color;

Should it be:-
pVertices[i].position = verts[i].position;
pVertices[i].color = verts[i].color;

???

Hope some of this helps.

Share this post


Link to post
Share on other sites
EvilDecl81    360
OK, there is some pretty bad form here in many places so bare with me, this post might be long.

First, DYNAMIC index buffers are a waste of time right now. They are their to provide orthaganlity in the event that hardware vendors actually DO have a notion of index buffers at some point in the future.
They don''t right now (I''m not sure about the GF4, but I doubt it does), its all in system memory and gets copied into command stream. The bandwidth required for the index buffer just isn''t high enough for the Hardware vendors to justify implenting in the hardware.

Second, this usage scenario is silly. You are drawing like 4 triangles. If the buffer does manage to be a real dynamic buffer, then getting a new peice of memory from the lock can take as much 5000-10000 CPU cycles. Hardly optimal unless you are really throwing alot of vertices around.

Third, you are locking with NO_SYSLOCK. This is silly to call with so a short copy. NOSYSLOCK should only be used when you are going to party on the buffer for a while and don''t want events such as the mouse cursor not to get updated. There is overhead when using this flag.

Finally, with the tiny amount of drawing you are doing, you are probally going to get better perf with DrawPrimitiveUP, (Before I get flamed, note that DrawPrimitiveUP has the same effective performance as Dynamic vertex buffers that you stuff data into yourself.)






EvilDecl81

Share this post


Link to post
Share on other sites
I''m sure his simple example is just that: An example. If you''re trying to learn how to use vertex buffers, you don''t start by trying to render an entire level.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites