Still, my bad. I foolishly assumed that the OP is on an x86/AMD64 platform where float alignment is the same accross most of the major compilers. One cannot safely make that assumption.
Which OpenGL functions take arguments of array type?
Where did I say that “an array is a pointer”? I said that you “pass a pointer” to a GL function. It’s you who stated something completely bogus:
You cannot pass an argument of structure type to a function expecting an array argument, even if the array parameter is an array of said structure type. Furthermore, array arguments simply decay to a pointer the the first element in C/C++, unless your parameter is a reference to an array in C++ like so:
void f(T (&array)[N]);
Now, what GLM leverages when returning a pointer to the first member of its data types, which are, in C++11 terms, all standard-layout structs, are the following facts:
[ul]
[li]a pointer to an object of structure type which has standard-layout will point to the memory location of its first member, if reinterpreted suitably (i.e. there’s no padding at the beginning of the struct) [/li][li]a standard-layout container has to have only non-static data members with the same access control, i.e. consecutive members will be at higher, consecutive memory locations [/li][li]if the compiler on a specific platform does not enforce a certain alignment, memory occupied by members of a standard-layout struct will be contiguous [/li][/ul]
If all this holds, then you can simply reinterpret a pointer to a an object to a pointer to it’s first member and then apply pointer artihmetic to walk over contigous elements - just like you would for an array of members. Although alignment requirements aren’t standardized, you can still get the needed information for certain compilers and platforms, e.g. on x86/AMD64 platform with G++ and MSVC++, the following type
struct Vector3
{
float x, y, z;
};
is a standard-layout class type which will contain no unnnamed members for alignment reasons, i.e.
sizeof(Vector3) == 3 * sizeof(float)
It therefore holds that for a
Vector3 v;
true == (reinterpret_cast<float*>(&v) == &v.x) == (&v == reinterpret_cast<Vector3*>(&v.x));
and
true == ((&v.x + 1) == &v.y))
If all that’s cool, for any GL function taking a pointer to a block of contiguous memory, like glBufferData(), or glUniform3fv(), pointers returned by GLM can be used without problems.
Hope I got that all right.