问题
I often use a struct to encapsulate a piece of graphics data, like colors/pixels. Provided they use the expected data type, can I pass arrays of these to OpenGL, or does this violate strict aliasing rules? For example:
typedef struct Color {
uint8_t v[4];
} Color;
Color colors[200];
for (int i = 0; i < 200; i++) {
/* populate color data */
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors);
Versus the less abstracted version:
uint8_t colors[200 * 4];
for (int i = 0; i < 200 * 4; i++) {
/* populate color data */
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors);
回答1:
You can make it work, as long as there is no padding. Double-check that 4 == sizeof (Color)
.
In some cases you might also need to use glPixelStorei
with GL_UNPACK_ALIGNMENT
to let OpenGL know that array elements in sequential rows are close-packed, without extra padding at the end of a row.
The actual read operations in OpenGL and other library functions aren't visible to the C++ compiler, so strict aliasing doesn't apply to them. The rule does apply to your code, but since you are passing a const void*
, the compiler has to assume it can alias anything, and not perform reordering across the library call.
来源:https://stackoverflow.com/questions/23983404/passing-arrays-of-structs-to-opengl