[Public WebGL] WebGLArray iterator proposal

Patrick Baggett [email protected]
Sat Jan 9 23:43:21 PST 2010

I'd like to propose a new method for the WebGLArray that makes it easier to
implement interleaved data structures, and supporting classes.

Using EMCAScript, it is unusually hard to manipulate data on a byte-by-byte
basis as the language does not reveal that fine a level of detail about the
machine. I'm sure other web-based languages equally try to abstract these

In OpenGL using C, it is common to create an interleaved data structure such
as this once

struct vertex {
GLfloat x, y, z; //position
GLubyte color[4];

Notice that is made of 3x floats and 4x ubytes. On most GL implementations,
this is 128 bits in total.

And to write to it, you might do:

GLfloat* pos = &some_vertex.x;
unsigned char* color = &some_vertex.color;
pos[0] = ...;
color[0] = ...;

/* Advance to next vertex */
pos += sizeof(struct vertex) / sizeof(GLfloat);
color += sizeof(struct vertex) / sizeof(GLubyte);

Using C++, you could even wrap the "magic" pointer arithmetic in a nice

In EMCAScript, the WebGLArray buffers can be used to do this as above, but
is a severely painful process because while you can create a WebGLFloatArray
to access the position elements, you can't "skip" the color components nor
write to them properly.

pos = WebGLFloatArray( 3 + 1); //3x floats + 1 color (happens to use same
storage amount)
pos.set(0, x);
pos.set(1, y);
pos.set(2, z);
//Set color? you'd have to encode the RGBA bytes as a float...That means
looking up IEEE 754 spec. and a lot of gross hacks.

The problem is that there is no way to access the bits in 96-127 without
treating it as a float. You might consider using slice() to map those bits,
but the spec clearly states:
"The returned WebGLArray<https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/doc/spec/WebGL-spec.html#WebGLArray>will
be of the same underlying type as the original
It would therefore be impossible to slice() the last 32-bit value and
convert to a WebGLUnsignedByteArray. Even if you could, you'd have to call
slice() and use weird offset math, making it far more annoying than it
should be and very error prone.

In a lot of cases, what is really needed is some kind of custom defined
iterator. The idea of what you would be trying to do (say, loading from a
file), is perhaps load separate chunks of information into a single buffer.
So, if you were loading a model and ran across the position data in the
file, you'd write the first 3 floats for the position, skip the color, write
the next 3 floats, skip the color data and so on. When you came across the
color data in the file, you'd want to do the opposite: skip first 3 floats,
write 4 color bytes, skip 3 float, write 4 color bytes, etc. Obviously, in
C/C++ this would be a trivial operation and be considered basic pointer
In 3D graphics, typically things come in [packed] groups of 3s and 4s, so
simply allowing a variable stride *between individual elements* would not be
sufficient. Elements in the array would need to be treated as groups of 1 or
more primitive types -- like glVertexAttribArray expects them. This would
bring consistency between how data is manipulated and how is expected by the

I propose a new function to WebGLArray called "getIterator()" (not
particularly attached to the name, but is was all I could think of)

WebGLArray::getIterator(offset, type, number, stride)
offset: Offset in bytes from start of WebGLArray
type: What type of element FLOAT, UNSIGNED_BYTE, BYTE, etc.
number: Number of elements in a group, 1, 2, 3, 4
stride: Stride in bytes between groups


hasNext(): boolean, does the iterator have another element. Can be
implemented with simple pointer comparisons
next(): Advance iterator
get(): returns a WebGL[Type]Array containing the group of elements
set( value ) : Sets the element group at the current location
  value : A sequence<type> of elements
set( array, offset ) : Sets the element group at the current location using
an WebGL[Type]Array. The number of elements is implied by the creation.
array : A WebGL[Type]Array
offset : Offset into 'array' from where element-wise copying should begin.

Could add some other functions such as getType(), getNumber(), and
getStride() to get creation parameters.

Thus, it would be possible to do something like this [EMCAScript]:

bufsize = sizeofElements * numberOfElements;
buffer = new WebGLByteArray( bufsize );

pos = buffer.getIterator(0, FLOAT, 3, sizeofElements);

for(i=0; i<numberOfElements; i++)
  vector = file.readNextPosition();

   pos.set( vector );


delete pos;

color = buffer.getIterator(12, UNSIGNED_BYTE, 4, sizeofElements);

//repeat for color


It could be argued that this kind of detail is too burdensome and/or
out-of-scope for the WebGL spec since it has little to do with graphics. The
WebGL spec looks as if it is a straightforward adaptation of the OpenGL ES
spec, which is written for C. While the C implementation shouldn't define
these sorts of details, in the WebGL arena, *there is no other way to
accomplish this without the use of extremely difficult constructs.* Yet, the
WebGL spec. defines operations on  data as if these constructs were

//Step 1: Somehow set up buffers (the actual problem at hand)

//Step 2: Use them -- well that's no problem at all!
VertexAttribPointer( pos_index, 3, FLOAT, false, sizeofElements, 0);
VertexAttribPointer( color_index, 3, UNSIGNED_BYTE, true, sizeofElements,

Arbitrary interpretation of packed binary data is just something that
web-based programming languages were never designed for, and the spec should
account for this. It already has to a limited extent by the inclusion the
WebGLArray classes, but in their current form, the classes cannot be used
for very much.


Possible Issues:

Writing a non-byte type then reading it back as bytes would reveal platform
details (byte-ordering). Similarly, writing 4 bytes to a buffer and using it
as float could possibly give the wrong value depending on how the bytes are
written to the buffer. I can't really think of a good reason an application
would do this, but I do list it here for consideration.


Work Arounds:
In order to make use of interleaved vertex attribute data right now, I have
to convert all of the types in my interleaved structure to be of the same
type, which means the colors would be stored as 4x floating point values --
thus *increasing* the amount of memory required. This clearly should not be
the goal of an adaptation of an *embedded* spec.

The only work around that does not increase memory would be to have separate
array buffers for each attribute, which can hurt performance since multiple
reads would be required (1 per vertex attribute) or multiple DMAs depending
on implementation. In addition, it's just messy and requires more handles to


EMCAScript (and other languages) are fundamentally limited in their handling
of byte-level data structure manipulations, and WebGL expects that sort of
functionality to make appropriate use of some of its functions (e.g.
glVertexAttribPointer). The WebGLArray classes which represent contiguous
memory blocks are a good idea, but their functionality is too limited to be
of use in real-world scenarios.

Patrick Baggett
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://khronos.org/pipermail/public_webgl_khronos.org/attachments/20100110/a0465e03/attachment.html>

More information about the public_webgl mailing list