0

I have a std::vector<MyVertex> where MyVertex is a struct. I have to push this data to the vertex buffer in Direct3D 9 and the examples I've seen use a memcpy. Unfortunately, memcpy crashes my application so I'm definitely doing something wrong.

std::vector<MyVertex> m_VertsBuff0;

void* vbPtr;
vertexbuffer->Lock (0, 0, &vbPtr, D3DLOCK_DISCARD);
memcpy (vbPtr, &m_VertsBuff0[0], sizeof(m_VertsBuff0)); // also tried sizeof(MyVertex)*m_VertsBuff0.size()
// std::copy(m_VertsBuff0.begin(), m_VertsBuff0.end(), vbPtr); // gives a compiler error void* unknown size
vertexbuffer->Unlock ();
device->SetStreamSource (0, vertexbuffer, 0, sizeof(m_VertsBuff0[0]));

Update:
This was working before when I just used an array instead of a vector. It didn't seem that I had to initialize the void* in the first place, because the example was working just fine. Then I changed it to a vector and it went wrong. Why is it that I have to initialize the void* all of a sudden and doing so still crashes my application.

memcpy (vbPtr, m_VertsBuff0.data(), sizeof(MyVertex) * m_VertsBuff0.size());
Marnix
  • 6,384
  • 4
  • 43
  • 78
  • 2
    `vbPtr` isn't initialized. – Luchian Grigore Aug 27 '13 at 08:03
  • Why did you first tra the (seemingly correct) `sizeof(MyVertex)*m_VertsBuff0.size()` but switched to `sizeof(m_VertsBuff0)` then? Looks like you don't exactly know what arguments to pass to `memcpy`. It looks a lot like headless trying without proper understanding of what should happen there. No good will ever come out of that kind of process. You should read more about what memcpy does, and how that is related to the vertexbuffer. – Arne Mertz Aug 27 '13 at 08:14
  • 1
    For starters, you should check the return value from the `Lock` call so you're sure it succeeded. – molbdnilo Aug 27 '13 at 08:26
  • Question is: how did you create the buffer? is it big enough? An [SSCCE](http://sscce.org) would be great. – Arne Mertz Aug 27 '13 at 08:30
  • how many elements does the vector have? In the code you seem not to fill it. Then the access to the nonexisting first element (`m_VertsBuff0[0]`) is undefined behavior. You **REALLY** should provide that complete example. – Arne Mertz Aug 27 '13 at 08:35
  • @ArneMertz I can't give you a working example, because this is a Unity Native Plugin in C++. But it seems indeed that my `maxVertices` is indeed smaller than the number of vertices I'm reading. – Marnix Aug 27 '13 at 08:36

3 Answers3

1

Use m_VertsBuff0.size() * sizeof(MyVertex) instead of sizeof(m_VertsBuff0) and ensure that 'vbPtr' points to properly allocated memory, e.g.:

void* vbPtr = new char[v.size() * sizeof(int)];
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

You must initialize your vbPtr;

  void* vbPtr = new char[v.size() * sizeof(MyVertex)];
  memcpy (vbPtr, v.data(), v.size() * sizeof(MyVertex));
Alexis
  • 2,149
  • 2
  • 25
  • 39
  • Wrong, the d3d9 Lock API will fill the vbPtr variable with a valid value if the call succeed. You can if you want to keep `std::copy` write this : `MyVertex * vbPtr = nullptr;` and cast the second arguement to `(void**) &vbPtr`. Only do the copy if `vbPtr != nullptr` ofcourse. – galop1n Aug 27 '13 at 08:14
  • My application is still crashing on the memcpy command. So there seems to be something else that is not correct. – Marnix Aug 27 '13 at 08:28
  • @Marnix yes. ant that something is probably outside the code you posted, so we can't help you without that code. See my comment above – Arne Mertz Aug 27 '13 at 08:31
  • @Marnix I don't know your api but if the result of new is != 0 then the only error is maybe from the lock, try to lock `vertexbuffer->Lock (0, 0, &vbPtr, D3DLOCK_DISCARD|D3DLOCK_READONLY);` – Alexis Aug 27 '13 at 08:35
  • I'm accepting this answer, because it helped me a lot. I probably have to set a cap on the number of vertices I can push to the vertex buffer. Still I find it strange that I didn't have to initialize the `void*` in the first place when copying it from an array. – Marnix Aug 27 '13 at 08:37
  • 1
    @Marnix Check also the return value of Lock – Alexis Aug 27 '13 at 08:41
0

Hmm, I think You have to initialize vbPtr to NULL before calling map

Simon Ferquel
  • 366
  • 1
  • 3