I'm trying to use build OpenGL textures in python using numpy, but I'm running into problems because I can't predict how numpy arrays will be organized in memory. The example program below (which should run as-is) illustrates my confusion:
from pylab import *
array_by_hand = array(
[[[1, 2, 3, 4], [1, 2, 3, 4]],
[[1, 2, 3, 4], [1, 2, 3, 4]]], dtype='uint8')
layers = 1 * ones((2, 2)), 2 * ones((2, 2)), 3 * ones((2, 2)), 4 * ones((2, 2))
array_from_layers = dstack(layers)
array_from_layers = array_from_layers.astype('uint8')
print array_by_hand; print
print array_from_layers; print
print ' '.join(x.encode('hex') for x in array_by_hand.data)
print ' '.join(x.encode('hex') for x in array_from_layers.data)
print
print all(array_by_hand == array_from_layers) # True
print str(array_by_hand.data) == str(array_from_layers.data) # False
Although the two arrays are equivalent as far as python is concerned, the are laid out differently in memory and therefore displayed differently by OpenGL. Can someone explain why this is happening and how I might coerce both arrays to the same format?
If you call the tostring method instead, it converts the array to C-contiguous layout:
>>> array_by_hand.tostring() == array_from_layers.tostring()
True
The reason the string is different in your case is because of the dstack
call. It tries to be smart about stacking arrays together by simply combining the underlying data of the source arrays and then changing numpy's stride information. This results in the array not being in C-contiguous layout.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With