Expand/Shrink

glBufferData

Definition: include pGUI.e
include opengl.e

glBufferData(integer target, size, atom pData, integer usage)
Description: create and initialize a buffer object's data store

target: Specifies the target buffer object. The symbolic constant must be GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER.
size, pData: Specifies the size in bytes of and a pointer the buffer object’s new data store. See glFloat32Array() below.
usage: Specifies the expected usage pattern of the data store. The symbolic constant must be GL_STREAM_DRAW, GL_STATIC_DRAW, or GL_DYNAMIC_DRAW.
pwa/p2js: Supported.
Notes: glBufferData creates a new data store for the buffer object currently bound to target.
Any pre-existing data store is deleted. The new data store is created with the specified size in bytes and usage.
If data is not NULL, the data store is initialized with data from this pointer.

usage is a hint to the GL implementation as to how a buffer object's data store will be accessed.
This enables the GL implementation to make more intelligent decisions that may significantly impact buffer object performance.
It does not, however, constrain the actual usage of the data store.
usage can be broken down into two parts: first, the frequency of access (modification and usage), and second, the nature of that access.
The frequency of access may be one of these:
STREAM The data store contents will be modified once and used at most a few times.
STATIC The data store contents will be modified once and used many times.
DYNAMIC The data store contents will be modified repeatedly and used many times.

The nature of access must be:
DRAW The data store contents are modified by the application, and used as the source for GL drawing and image specification commands.

If pData is NULL, a data store of the specified size is still created, but its contents remain uninitialized and thus undefined.

Clients must align data elements consistent with the requirements of the client platform, with an additional base-level requirement that an offset within a buffer to a datum comprising N bytes be a multiple of N.

Typically the count parameter of glDrawArrays() ultimately determines precisely how many entries OpenGL/WebGL will examine/expect.
Utilities: {integer size, atom pData} = glFloat32Array(sequence data)
While in the C api it is natural to use the (address of) an array, opengl.e must explicitly allocate, poke, and eventually free memory, whereas WebGL specifies that "new Float32Array" should be used, so that’s what opengl.js does.
This Phix-specific routine abstracts away any such differences.
A need for further variations for non-float32 arrays may yet arise.
The possibility of a NULL pData mentioned above does not extend to this routine (and in any case has not been needed or tested).

sequence res = glSimpleA7texcoords(integer faces)
This Phix-specific routine was originally written for demo\pGUI\HelloF.exw and if you have not read the detailed notes in that source I recommend you do so now. As it mentions there are 144 different ways to draw a single rectangle using two triangles, and low-level libraries such as OpenGL and CanvasDraw have a strong tendency to store their data (/pixels) differently and apply different coordinate systems to them, so if you are not careful things come out upside down and/or back-to-front. I therefore invented the "A7" format as {bl,tl,br,tl,tr,br}, ie the six points (aka two triangles) needed to draw it, when looking at it from the texture side and orientated the right way up for that, as a way to simplify things. The following diagram should help.



Drawing the first triangle is a bit like writing a capital A, in reverse italic and without the cross bar, and the second triangle is a bit like drawing a 7. Obviously 2 and 4 are really the same point, as are 3 and 6. As long as you have defined all your (rectangular) faces consistently, then you can appply the same texture mapping to all of them, and at the same time iron out any discrepancies between desktop/Phix and pwa/p2js, which is precisely what glSimpleA7texcoords does.

In practice, demo\pGUI\opengl.e as is used on desktop/Phix repeats {1,0, 1,1, 0,0, 1,1, 0,1, 0,0} whereas pwa\builtins\opengl.js as is used via pwa/p2js repeats {1,1, 1,0, 0,1, 1,0, 0,0, 0,1}, which immediately illustrates the problem glSimpleA7texcoords() solves.
The texture coordinates that OpenGL needs must be a one-to-one mapping between all the 3D points in the model and the corresponding 2D points on the texture, specifying the x and y coordinates as a floating point number between 0 and 1.
Note that internally this routine specifically requests a dword-sequence result from flatten().

Over time I expect further minor variations of this trivial routine to emerge. Note that glSimpleA7texcoords() is exclusively designed for use with GL_TRIANGLES whereas GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN offer more compact representations.
Errors: GL_INVALID_ENUM is generated if target is not GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER.
GL_INVALID_ENUM is generated if usage is not GL_STREAM_DRAW, GL_STATIC_DRAW, or GL_DYNAMIC_DRAW.
GL_INVALID_VALUE is generated if size is negative.
GL_INVALID_OPERATION is generated if the reserved buffer object name 0 is bound to target.
GL_OUT_OF_MEMORY is generated if the GL is unable to create a data store with the specified size.
Associated Gets: glGetBufferParameteriv with argument GL_BUFFER_SIZE or GL_BUFFER_USAGE
See Also: glBindBuffer