Thread: DirectX: VertexBuffer with Length 0?

  1. #1
    Registered User
    Join Date
    Jun 2003
    Posts
    361

    DirectX: VertexBuffer with Length 0?

    I've got a question about this line:
    D3DDevice->CreateVertexBuffer(NUM_VERTICES * sizeof(MyVertex), D3DUSAGE_WRITEONLY, D3D8T_CUSTOMVERTEX, D3DPOOL_MANAGED, &VBMain);

    The first Parameter passed is the "Length". I'm assuming this is the size (amount of room) that will be set aside for VBMain (my Vertex Buffer). Here's the problem though:
    I start off with no vertices, so, NUM_VERTICES = 0. This is setting aside 0 "Length". I'm wondering if I'll get into some trouble if I try to pass vertices later on that I create during run-time to a Vertex Buffer that was created in this way.

    Thanks for any insight (And if anyone could clear up what exactly that "Length" means it'd also be appreciated)

  2. #2
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Basically you have your vertex structure where certain information is kept such as position, normal, texture coords, etc. The vertex buffer needs to know how much memory to allocate for your object so you pass in the size of a structure * num of verts. That's where that comes from. You should probably just create a big vertex buffer and then you will have room to work with. Creating vertex buffers a lot is expensive! Then when you call DrawPrimitive you pass in how many elements get drawn so there is no garbage being displayed. Hope that clears something up.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  3. #3
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    So I should declare a vertex buffer at the beginning that can hold many (I.e. thousands) of vertices?

    The thing is I don't know how many vertices I'll exactly need because I make them on the fly. So far, unsuccessfully, but I'm writing functions that will:
    Create an array of Temp variables of type MyStruct.
    I'll know the size of this Temp array based on the object I'm creating.
    Fill in the Temp Variable.
    Append its contents over into my AllVertices[] variable of type MyStruct.
    (AllVertices[] is of undefined size).
    Then reinitalise my VertexBuffer with my AllVertices[] variable.

    This was the most efficient method I could think of. But if I create one massive VertexBuffer, then I may or may not reach/exceed my initial guess at vertices. Do you see of any ways around this? (or better ways of creating on the fly?)

    Thanks so far

  4. #4
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Maybe you should tell me exactly what you are trying to do here. For instance, I might have a different answer if we are talking about point sprites vs. regular polys. Usually when you are creating a vertex buffer ( vb ) you know how many verts you will need so its not a problem, however in a case like yours sometimes you don't know. So you don't have an upper limit of the number of verts for this dynamic buffer?

    You know what, before I say anything else just tell me exactly what you're trying to do and then I can probably give you better help.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  5. #5
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    My vertex buffer:
    IDirect3DVertexBuffer8 *VBMain = NULL;

    My structure looks like this:
    Code:
    struct MyVertex
    {
    	FLOAT X, Y, Z;  //Coordinates on screen
    	FLOAT TU, TV;  //Texture Coordinates
    };
    Then, to make my program more efficient, until now I have been declaring my vertices like this:
    Code:
    MyVertex AllVertices[];=
    {
    	//TRIANGLE
    	{-0.5f,  0.5f, 0.0f, 0.75f, 0.750f},
    	{ 0.5f,	 0.0f, 0.0f, 1.00f, 0.875f},
    	{-0.5f, -0.5f, 0.0f, 0.75f, 1.000f},
    	//SQUARE 1
    	{-0.0f,  0.0f, 0.0f, 0.0f, 0.0f},
    	{ 0.0f,  0.0f, 0.0f, 0.5f, 0.0f},
    	{-0.0f, -0.0f, 0.0f, 0.0f, 0.5f},
    	{ 0.0f, -0.0f, 0.0f, 0.5f, 0.5f},
    	//SQUARE 2
    	{-25.0f, -19.00f, 0.0f, 0.0f, 0.50f},
    	{-20.0f, -19.0f, 0.0f, 1.0f, 0.50f},
    	{-25.0f, -20.00f, 0.0f, 0.0f, 0.75f},
    	{-20.0f, -20.00f, 0.0f, 1.0f, 0.75f},
    };
    Keeping all of my vertices for my entire program in one array.
    Then, I passed my AllVertices variable into VBMain with:
    Code:
    HRESULT Attempt;
    unsigned char *VBVertices;
    
    Attempt = VBMain->Lock(0, 0, &VBVertices, 0);
    if (FAILED(Attempt))
    {
    	MessageBox(NULL, "Could Not Lock Vertex Buffer", "Error", MB_OK|MB_TOPMOST);
    	return false;
    }
    memcpy(VBVertices, AllVertices, sizeof(AllVertices));
    VBMain->Unlock();
    So, in essence, I've been hardcoding my vertices into my code and have been working with that.

    Now, what I want to do is get rid of the hardcoding and create functions to add vertices to my AllVertices[] variable. Meaning, I was hoping to declare AllVertices with:
    Code:
    MyVertex AllVertices[];
    Allowing me to add as much data to the array as needed. But, I come across problems.
    One problem comes from this line:
    Code:
    D3DDevice->CreateVertexBuffer(NUM_VERTICES * sizeof(MyVertex), D3DUSAGE_WRITEONLY, D3D8T_CUSTOMVERTEX, D3DPOOL_MANAGED, &VBMain);
    Where NUM_VERTICES is:
    Code:
    #define NUM_VERTICES (sizeof(AllVertices)/sizeof(MyVertex))
    From this, NUM_VERTICES will equal 0. Meaning I'm creating a VertexBuffer with "Length" 0. C++ doesn't like that.

    I'm asking, whether there is a better way around this than declaring:
    MyVertex AllVertices[5000];
    at the beginning because the functions I am creating to append to the array may be called often enough that eventually, that 5000 (or whichever number I choose) might be exceeded.

    (Hope that clears up my question a bit And thanks for sticking with it so far )

  6. #6
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Okay, you are right about sticking all the vertices into the one buffer will be a little more efficient. However, you won't notice anything with that few of vertices. Usually when you talk about batching like that you are talking about 2,000 vertices or so. You may want to consider separate vb's for readability / maintainability. You might try making an Object base class then deriving all your classes from it ( i.e. Square, Triangle, etc ) You know they all need a vertex buffer and the vertex declaration. Then in the constructors of the derived classes you can create the buffers to whatever size is suitable. If you want them in one vertex buffer and you don't know the size initially, I guess one cheap way to do it would be in the init stage of your app. Are you going to be adding objects on the fly or just in the beginning? Because if its in the beginning you can just keep track of how many verts you need when creating the objects then create a buffer big enough to hold them all and fill it in appropriately. I would suggest using separate vb's until you start seeing a performance hit from it. Trust me, until you get into very complex 3D environments you won't see a big boost. Let me know if you have more concerns/issues.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  7. #7
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Awesome thanks for the help there

    I've managed to stick with one VB and took your advice on creating objects during initialisation. I don't know if I'll be needing to create them later on, but for now this is plenty good

    I have a seperate problem now that's gonna keep me outta this post for a while though. I'm in the process of making an asteroids kind of game with full physics (momentum, gravity, etc.) but, so far, I've done it all without one Class. The end result is just over 1000 lines of code to move a triangle around the screen Hehe (it's a tad better than that). But I know I should be using Classes for this, so I'm gonna put in my fifth attempt at them and hope I don't give up this time.

    Thanks for you help MrWizard.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Strange string behavior
    By jcafaro10 in forum C Programming
    Replies: 2
    Last Post: 04-07-2009, 07:38 PM
  3. Need help with a snake game (ncurses)
    By Adam4444 in forum C Programming
    Replies: 11
    Last Post: 01-17-2007, 03:41 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. length of string etc.
    By Peachy in forum C Programming
    Replies: 5
    Last Post: 09-27-2001, 12:04 PM