1d access to a 2d type array

BlitzMax Forums/BlitzMax Programming/1d access to a 2d type array

CS_TBL(Posted 2007) [#1]
Ok, here's the idea: I have a type representing a pixel, e.g.
type pixel
  field r:float
  field g:float
  field b:float
  field i1:int
  field i2:int
end type


Then I'll create my 'image':
local myimage:pixel=new pixel[16,16]


(or something, maybe some more initializing, anyway, that's not the point here :P)

Anyway, I can access the pixel fields in a nested y,x FOR loop of course. But next to doing this I also want 1-dimensional access for both reading and writing. E.g. if I know the width and height (16 and 16) then I want to be able to run through the whole shebang in a for 256 loop. Oh.. and superstrict..!

How? :P I didn't find PTRs to be very cooperative, and going out of bounds (e.g. mypixel[255,0]) also wasn't much appreciated.


ziggy(Posted 2007) [#2]
Haven't tested but shouldn't it be something like this?
Function GetLinear:pixel(Value:int)
    return MyImage[value/16,Value mod 16]
End Function



CS_TBL(Posted 2007) [#3]
That's not the solution I meant.. of course I can calculate everything myself: 1d access in a 2d arrary, '2d' access in a 1d array. It's this calculation I want to get rid of (in per-pixel calculations), and thus I want something low-level.

One can step through, say, ints in a 2d int array using a pointer. That's 1d access of a 2d array. But alas, couldn't make a pointer of my pixel object. And I'm not sure whether a pointer is such a nice solution here anyway.


ziggy(Posted 2007) [#4]
I don't think BlitzMax array of type instances are stored in a uniform block or memory. So I don't think accesing to the data directly is possible. Also, pointer for class instances are not valid in BlitzMax, so making something like:
Local X:Pixel Ptr
won't compile. Local X:pixel is a pointer itself... Maybe someone with more experience on arrays on BlitzMax can lend a hand...
Obviously creating a one dimensional array of pointers to the 2 dimensional array items would do the job, but it would be slow on creation time and not consitent on data storage. instance changes on the 2 dimensional array would not be reflected on the other one, and vice-versa.


ImaginaryHuman(Posted 2007) [#5]
If you have a two dimensional array, each element in the first dimension potentially has its own memory space to store all items within it. So if you define your array as [x,y], and if let's say both x and y are 16, then for every x position in the array there is a separate block of memory with 16 y's in it. When you add a dimension to an array it stops being a contiguous block of memory. You could step through each of the elements in the first dimension and read the entire contents of that element's second dimension in sequence, but like at the end of a row you have to jump to a new memory location.

If you want a contiguous memory block I recommend using a bank instead of an array, or just allocate some memory yourself, and then use pointer access, because every time right now that you're doing array[x,y] blitzmax is behind the scenes going array+rowbasepointer+x to find the address. At least then you are in control of when you use it as rows and when you use it as a solid block of pixels. Also pointers to memory may be faster than arrays.


CS_TBL(Posted 2007) [#6]
A bank has its advantages yes.. for instance, you can poke either a float or an int at a specific spot, meaning you actually have choice during the process. The low-level poking is a bit less nice tho, tho one can use CONSTs for offsets like 'r', 'g', 'b', etc.

But uhm, before I make worries about something irrelevant, is a x+width*y for each array entry in a 1-dimensional array slowing down? Or does BMax's 2d array addressing works exactly the same?


Dreamora(Posted 2007) [#7]
Thats how it most likely works, yes.
anything else makes no real sense especially as BMs performance is en par with C# and higher.


CS_TBL(Posted 2007) [#8]
ok, I've chosen wisely: TBank, and 2 arrays which contain bank offsets. One array is a 1d array, the other is 2d. Both contain the same numbers, but I can thus choose my preferred access method. Storing those offsets in those arrays saves quite a few multipliers for each pixel..

Still I wonder whether I'm just making too crappy stuff here or whether BMax seriously lacks some functionality here ... aaaaaaaanyway ...