regl
regl copied to clipboard
[Feature Suggestion] Texture data format: 'C' or 'F'
In numerical libraries like numpy, there is a distinction between C-style and Fortran-style (row-major, column-major) memory order.
Currently, as far as I can tell, default and only way to upload texture data through regl.texture
is Fortran-style (column-major) since in texture.js
at line 771 transposeData
function is applied.
Proposal: Add a flag to texture constructor to choose C-style and skip this transposition step. Possible flags could be:
{
memoryOrder: 'row' | 'column' | 'C' | 'F',
transpose: boolean
}
I can also give this a go if you agree with the suggestion.
Thanks for the suggestion, @deluksic!
For the sake of argument, I made an example of how this may be accomplished with the current API: Reorganizing Input Data for regl Using the ndarray Format
To make a long story short, you may use data
, shape
, stride
, and offset
to pass any ndarray-like object as the data
property of a texture. The shape/stride/offset combination allows you to perform any reordering/flipping/transposing/striding/etc, and regl performs the copy internally, as needed to correctly pass data along to WebGL.
As for what those strides are, you can perform the stride computation yourself, which is not exactly user-friendly, nor is it the worst, or you can use the ndarray library (it's small!) and pass an actual ndarray object for the texture data.
In short, the shape/stride computation is:
value(i, j, k) = data[offset + stride[0] * i + stride[1] * j + stride[2] * k...]
which gives you quite a few possibilities.
Unless I'm mistaken, I do find the combination of memoryOrder
, transpose
, and the existing flipY
flag a bit confusing since it seems like those operations depend on the order in which they're applied to the input, as opposed to passing an ndarray which clearly indicates that massaging the input is your concern, and the only thing regl can do is flipY.
I am already pre-transposing the ndarray like this, to get the correct format:
array.transpose(1, 0, 2);
However, I felt its a little weird that a transpose needs to be done at all. Hence my suggestion to introduce transpose
OR memoryOrder
(not both, sorry!). I would lean towards memoryOrder
.
I see your point about flipY
and operation order. But memory order in my mind has nothing to do with what is a Y direction. In any case, memoryOrder
would be done first as it is just a format specification, and then you can have a potential flipY
act on it later. Does it make sense? :relaxed:
On the other hand, what would be very confusing is: this flag makes no sense if you don't pass in an ArrayLike object for data, since that code path does not seem to transpose anything?