Using byte arrays and "casting" them to an external structure

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Using byte arrays and "casting" them to an external structure

Jeff M.
I've been trying for a while now to figure out how to do this and I
keep coming up short. /sigh. I'm sure there is a way to do this, it's
just not immediately obvious to me. Let me describe a little of what I
want (and why I want it), what I know Dolphin has (and why it won't
work), and what I've tried (and hasn't worked).

I want to have a large buffer of bytes that I can treat as an array of
vertices. However, the vertices are not a known format (correction,
they could be 1 of many formats) - likewise, they could be of any
arbitrary format. The could be transformed, lit, textured, etc.
Likewise, they could be any of the above with added data. An example of
this would be a "particle":

struct particle { // textured, lit particle
   float x, y, z;
   unsigned int diffuse;
   float u, v;
   float nx, ny, nz;

   // particle data
   float life;
   float vel_x, vel_y, vel_z;
   // ... more data here
};

I don't if many of you have programmed 3D games before, but generally
speaking, I would slam a whole bunch of these through the GPU with a
stride. All the particle data will get skipped and only the vertex data
is used. So, given an arbitrary length byte array, I want to be able to
treat address offsets into the array at 2D, 3D, lit, colored, textured,
whatever vertices. In C, of course, this is super trivial.

Now, I can create the byte array easily enough, and I have some
ExternalStructure subclasses set up for N different variations of
vertices. The problem is that I can't modify the ByteArray in-place.
I've tried various things. Closest to what I want is:

b := ByteArray new: 20.
a := b addressAtOffset: 8.
v := D3DVERTEX_TNL fromAddress: a.
v x: 10.4.

However, this has some problems. First off, #addressAtOffset: is always
returning an ExternalAddress(NULL). Now, obviously this is because
#addressAtOffset: isn't returning the address AT the offset, but rather
the address IN the offset (that took me a while). Ugh.

All other methods I see for getting the information seem to want to
copy the bytes into the structure instead of just pointing to them.
This is unacceptable for performace reasons. So, is there a way to do
what I want? I imagine the answer to this (long) post will be a single
line: it will either be "no" or "use #...:".

Thanks for any replies.

Jeff M.


Reply | Threaded
Open this post in threaded view
|

Re: Using byte arrays and "casting" them to an external structure

Chris Uppal-3
Jeff,

> b := ByteArray new: 20.
> a := b addressAtOffset: 8.
> v := D3DVERTEX_TNL fromAddress: a.
> v x: 10.4.

I think you mean:

    b := ByteArray new: 20.
    a := b yourAddress + 8.
    v := D3DVERTEX_TNL atAddress: a.
    v x: 10.4.

WARNING: access to the fields of the D3DVERTEX_TNL is /NOT/ bounds-checked
against the underlying ByteArray.

(Also, there is a subtle difference between #atAddress: and #fromAddress: which
I have never fully fathomed; the former seems to be preferred although I don't
think it makes any difference in this case).

Alternatively a StructureArray may do what you want in a safer and less ad-hoc
way, but I'm not sure if you are able to overlay such a regular structure over
your raw bytes.  If nothing else, StructureArray and its sibling subclasses of
ExternalArray, may give you some ideas for safer ways of overlaying a structure
on a byte array.

    -- chris