开发者

Help me evaluate this casting

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]]);


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]]


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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜