Reputation: 2236
I found this in the PowerVR mesh drawing code and I don't really know how to read it.
&((unsigned short*)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]
What is going on here? Is this a reference to void cast as an unsigned short pointer and then offset by (3*mesh(etc...) + batchNum)? It's breaking my brain.
It's found in the context of a glDrawElements call:
glDrawElements(GL_TRIANGLES, i32Tris * 3, GL_UNSIGNED_SHORT,
&((unsigned short*)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]);
Upvotes: 3
Views: 268
Reputation: 18015
Really, this kind of hack is due to OpenGL expressing offsets inside Buffer Objects through the pointer argument of glDrawElements.
glDrawElements(mode, count, type, void* indices)
indices
represents either a client-side memory pointer or a server-side memory offset based on the binding of GL_ELEMENT_ARRAY_BUFFER_ARB
It's interesting to dig a bit deeper... From the VBO specification:
Is it legal C to use pointers as offsets?
We haven't come to any definitive conclusion about this. [...]
Varying opinions have been expressed as to whether this is legal, although no one could provide an example of a real system where any problems would occur.
Upvotes: 1
Reputation: 332986
Let's go from the inside out.
(unsigned short*)0
This is casting 0
to an unsigned short pointer. This will be used for computing a memory offset, computed in terms of the size of an unsigned short.
3 * mesh.sBoneBatches.pnBatchOffset[batchNum]
This is, presumably, the offset in memory of some batch of triangles. A triangle is composed of 3 shorts, so it looks like they are storing an offset in terms of numbers of triangles, and then multiplying by 3 to get the number of shorts.
((unsigned short*)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]
This is now using that 0
pointer to find the memory location of the given offset. This would normally return the value of that memory location, but they want a pointer to pass into glDrawElements, so the use the &
operator to get a pointer to that memory location:
&((unsigned short*)0)[3 * mesh.sBoneBatches.pnBatchOffset[batchNum]]
Upvotes: 6
Reputation: 2960
Its an obfuscated way of computing
sizeof(unsigned short) * 3 * mesh.sBoneBatches.pnBatchOffset[batchNum]
but since it doesn't actually save any characters, its not a very good obfuscation
Upvotes: 0
Reputation: 2135
It's computing a byte offset -- 3 * mesh.sBoneBatches.pnBatchOffset[batchNum] is the index. Using 0 as the pointer means that the address will be just the offset value, nothing else.
Upvotes: 2