I'm delving into C++ and exploring graphics programming, following a tutorial. However, I've encountered an unexpected issue for which I couldn't find any solutions online.
Here's the code snippet:
struct CustomVertex { float x, y, z; unsigned int color; };
void writeToVRAM(CustomVertex *vertices)
{
...
memcpy(pVoid, vertices, size);
...
return;
}
void createShapes()
{
// Define vertices for a triangle
CustomVertex vertices[] =
{
{ -3.0f, 3.0f, 0.0f, 0xFF0000 }, // Red
{ 3.0f, 3.0f, 0.0f, 0x00FF00 }, // Green
{ 0.0f, -3.0f, 0.0f, 0x0000FF } // Blue
};
writeToVRAM(vertices);
}
I'm attempting to pass the entire array of CustomVertex structs as a pointer to the writeToVRAM function. However, I've noticed that if I don't use pointers, the data isn't transferred properly.
I've tried various function signatures:
void writeToVRAM(CustomVertex *vertices)
void writeToVRAM(CustomVertex vertices)
void writeToVRAM(CustomVertex &vertices)
void writeToVRAM(CustomVertex *vertices[])
void writeToVRAM(CustomVertex vertices[])
And calling methods:
writeToVRAM(&vertices);
writeToVRAM(*vertices);
writeToVRAM(vertices);
Edit: Interestingly, when I refactor the code like this:
void writeToVRAM()
{
CustomVertex vertices[] =
{
{ -3.0f, 3.0f, 0.0f, 0xFF0000 }, // Red
{ 3.0f, 3.0f, 0.0f, 0x00FF00 }, // Green
{ 0.0f, -3.0f, 0.0f, 0x0000FF } // Blue
};
...
memcpy(pVoid, vertices, size);
...
return;
}
Suddenly, it works as expected.
I've exhausted all combinations of pointers and syntax that I could think of, but none have worked. Can anyone provide insight into this peculiar issue?
I've scoured online resources but haven't found anyone else encountering this problem.
Inside of writetovram()
, sizeof(verticies)
doesn't return what you think it does. You can't get the size of an array from just a pointer. There are TONS of questions on StackOverflow on this issue.
Your simplest option is to just pass the array size as another parameter, eg:
struct CUSTOMVERTEX { FLOAT X, Y, Z; DWORD COLOR; };
void writetovram(CUSTOMVERTEX *verticies, int num_verticies)
{
...
memcpy(pVoid, verticies, sizeof(*verticies) * num_verticies);
...
}
void createshapes()
{
//simple square
CUSTOMVERTEX verticies[] =
{
{ -3.0f, 3.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255), },
{ 3.0f, 3.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), },
{ -3.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), },
{ 3.0f, -3.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 255), },
};
writetovram(verticies, 4);
// or:
// writetovram(verticies, sizeof(verticies)/sizeof(verticies[0]));
// or:
// writetovram(verticies, std::size(verticies));
}
Other options include:
pass the array by reference, but only if the size is known at compile-time. But if multiple different-sized arrays need to be used, then writetovram()
would have to be made into a template function so the array size can be deduced at compile-time for each call site.
changing the array to use std::array
or std:vector
instead, passed to the function by reference, and then it can use their size()
methods.