15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci    EXT_pixel_buffer_object
45bd8deadSopenharmony_ci
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci    GL_EXT_pixel_buffer_object
85bd8deadSopenharmony_ci
95bd8deadSopenharmony_ciStatus
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci    Implemented by NVIDIA drivers (Release 55).
125bd8deadSopenharmony_ci
135bd8deadSopenharmony_ciContributors
145bd8deadSopenharmony_ci
155bd8deadSopenharmony_ci    Ralf Biermann
165bd8deadSopenharmony_ci    Derek Cornish
175bd8deadSopenharmony_ci    Matt Craighead
185bd8deadSopenharmony_ci    Bill Licea-Kane
195bd8deadSopenharmony_ci    Brian Paul
205bd8deadSopenharmony_ci
215bd8deadSopenharmony_ciContact
225bd8deadSopenharmony_ci
235bd8deadSopenharmony_ci    Ralf Biermann, NVIDIA Corporation (rbiermann 'at' nvidia.com)
245bd8deadSopenharmony_ci    Derek Cornish, NVIDIA Corporation (dcornish 'at' nvidia.com)
255bd8deadSopenharmony_ci
265bd8deadSopenharmony_ciIP Status
275bd8deadSopenharmony_ci
285bd8deadSopenharmony_ci    Unknown.
295bd8deadSopenharmony_ci
305bd8deadSopenharmony_ciVersion
315bd8deadSopenharmony_ci
325bd8deadSopenharmony_ci    NVIDIA Date: March 29, 2004 (version 1.0)
335bd8deadSopenharmony_ci
345bd8deadSopenharmony_ciNumber
355bd8deadSopenharmony_ci
365bd8deadSopenharmony_ci    302
375bd8deadSopenharmony_ci
385bd8deadSopenharmony_ciStatus
395bd8deadSopenharmony_ci
405bd8deadSopenharmony_ci    NVIDIA Release 55 (early 2004) drivers support this extension.
415bd8deadSopenharmony_ci
425bd8deadSopenharmony_ciDependencies
435bd8deadSopenharmony_ci
445bd8deadSopenharmony_ci    Written based on the wording of the OpenGL 1.5 specification.
455bd8deadSopenharmony_ci
465bd8deadSopenharmony_ci    GL_NV_pixel_data_range affects the definition of this extension.
475bd8deadSopenharmony_ci
485bd8deadSopenharmony_ciOverview
495bd8deadSopenharmony_ci
505bd8deadSopenharmony_ci    This extension expands on the interface provided by buffer objects.
515bd8deadSopenharmony_ci    It is intended to permit buffer objects to be used not only with 
525bd8deadSopenharmony_ci    vertex array data, but also with pixel data.
535bd8deadSopenharmony_ci    Buffer objects were promoted from the ARB_vertex_buffer_object
545bd8deadSopenharmony_ci    extension in OpenGL 1.5.
555bd8deadSopenharmony_ci
565bd8deadSopenharmony_ci    Recall that buffer objects conceptually are nothing more than arrays
575bd8deadSopenharmony_ci    of bytes, just like any chunk of memory. Buffer objects allow GL
585bd8deadSopenharmony_ci    commands to source data from a buffer object by binding the buffer
595bd8deadSopenharmony_ci    object to a given target and then overloading a certain set of GL
605bd8deadSopenharmony_ci    commands' pointer arguments to refer to offsets inside the buffer,
615bd8deadSopenharmony_ci    rather than pointers to user memory.  An offset is encoded in a
625bd8deadSopenharmony_ci    pointer by adding the offset to a null pointer.
635bd8deadSopenharmony_ci
645bd8deadSopenharmony_ci    This extension does not add any new functionality to buffer
655bd8deadSopenharmony_ci    objects themselves.  It simply adds two new targets to which buffer
665bd8deadSopenharmony_ci    objects can be bound: PIXEL_PACK_BUFFER and PIXEL_UNPACK_BUFFER.
675bd8deadSopenharmony_ci    When a buffer object is bound to the PIXEL_PACK_BUFFER target,
685bd8deadSopenharmony_ci    commands such as ReadPixels write their data into a buffer object.
695bd8deadSopenharmony_ci    When a buffer object is bound to the PIXEL_UNPACK_BUFFER target,
705bd8deadSopenharmony_ci    commands such as DrawPixels read their data from a buffer object.
715bd8deadSopenharmony_ci
725bd8deadSopenharmony_ci    There are a wide variety of applications for such functionality.
735bd8deadSopenharmony_ci    Some of the most interesting ones are:
745bd8deadSopenharmony_ci
755bd8deadSopenharmony_ci    - "Render to vertex array."  The application can use a fragment
765bd8deadSopenharmony_ci      program to render some image into one of its buffers, then read
775bd8deadSopenharmony_ci      this image out into a buffer object via ReadPixels.  Then, it can
785bd8deadSopenharmony_ci      use this buffer object as a source of vertex data.
795bd8deadSopenharmony_ci
805bd8deadSopenharmony_ci    - Streaming textures.  If the application uses MapBuffer/UnmapBuffer
815bd8deadSopenharmony_ci      to write its data for TexSubImage into a buffer object, at least
825bd8deadSopenharmony_ci      one of the data copies usually required to download a texture can
835bd8deadSopenharmony_ci      be eliminated, significantly increasing texture download
845bd8deadSopenharmony_ci      performance.
855bd8deadSopenharmony_ci
865bd8deadSopenharmony_ci    - Asynchronous ReadPixels.  If an application needs to read back a
875bd8deadSopenharmony_ci      number of images and process them with the CPU, the existing GL
885bd8deadSopenharmony_ci      interface makes it nearly impossible to pipeline this operation.
895bd8deadSopenharmony_ci      The driver will typically send the hardware a readback command
905bd8deadSopenharmony_ci      when ReadPixels is called, and then wait for all of the data to
915bd8deadSopenharmony_ci      be available before returning control to the application.  Then,
925bd8deadSopenharmony_ci      the application can either process the data immediately or call
935bd8deadSopenharmony_ci      ReadPixels again; in neither case will the readback overlap with
945bd8deadSopenharmony_ci      the processing.  If the application issues several readbacks into
955bd8deadSopenharmony_ci      several buffer objects, however, and then maps each one to process
965bd8deadSopenharmony_ci      its data, then the readbacks can proceed in parallel with the data
975bd8deadSopenharmony_ci      processing.
985bd8deadSopenharmony_ci
995bd8deadSopenharmony_ciIssues
1005bd8deadSopenharmony_ci
1015bd8deadSopenharmony_ci    How does this extension relate to ARB_vertex_buffer_object?
1025bd8deadSopenharmony_ci
1035bd8deadSopenharmony_ci        It builds on the ARB_vertex_buffer_object framework by adding
1045bd8deadSopenharmony_ci        two new targets that buffers can be bound to.
1055bd8deadSopenharmony_ci
1065bd8deadSopenharmony_ci    How does this extension relate to NV_pixel_data_range?
1075bd8deadSopenharmony_ci
1085bd8deadSopenharmony_ci        This extension relates to NV_pixel_data_range in the same way that
1095bd8deadSopenharmony_ci        ARB_vertex_buffer_object relates to NV_vertex_array_range. To
1105bd8deadSopenharmony_ci        paraphrase the ARB_vertex_buffer_object spec, here are the main
1115bd8deadSopenharmony_ci        differences:
1125bd8deadSopenharmony_ci
1135bd8deadSopenharmony_ci        - Applications are no longer responsible for memory management
1145bd8deadSopenharmony_ci          and synchronization.
1155bd8deadSopenharmony_ci
1165bd8deadSopenharmony_ci        - Applications may still access high-performance memory directly,
1175bd8deadSopenharmony_ci          but this is optional, and such access is more restricted.
1185bd8deadSopenharmony_ci
1195bd8deadSopenharmony_ci        - Buffer changes (BindBuffer) are generally expected to
1205bd8deadSopenharmony_ci          be very lightweight, rather than extremely heavyweight
1215bd8deadSopenharmony_ci          (PixelDataRangeNV).
1225bd8deadSopenharmony_ci
1235bd8deadSopenharmony_ci        - A platform-specific allocator such as wgl/glXAllocateMemoryNV
1245bd8deadSopenharmony_ci          is no longer required.
1255bd8deadSopenharmony_ci
1265bd8deadSopenharmony_ci    Can a given buffer be used for both vertex and pixel data?
1275bd8deadSopenharmony_ci
1285bd8deadSopenharmony_ci        RESOLVED: YES.  All buffers can be used with all buffer bindings,
1295bd8deadSopenharmony_ci        in whatever combinations the application finds useful.  Consider
1305bd8deadSopenharmony_ci        yourself warned, however, by the following issue.
1315bd8deadSopenharmony_ci
1325bd8deadSopenharmony_ci    May implementations make use of the target as a hint to select an
1335bd8deadSopenharmony_ci    appropriate memory space for the buffer?
1345bd8deadSopenharmony_ci
1355bd8deadSopenharmony_ci        RESOLVED: YES, as long as such behavior is transparent to the
1365bd8deadSopenharmony_ci        application. Some implementations may choose, for example,
1375bd8deadSopenharmony_ci        that they would rather stream vertex data from write-combined
1385bd8deadSopenharmony_ci        system memory, element (or index) data from video memory, and
1395bd8deadSopenharmony_ci        pixel data from video memory.
1405bd8deadSopenharmony_ci
1415bd8deadSopenharmony_ci        In fact, one can imagine arbitrarily complicated heuristics for
1425bd8deadSopenharmony_ci        selecting the memory space, based on factors such as the target,
1435bd8deadSopenharmony_ci        the "usage" argument, and the application's observed behavior.
1445bd8deadSopenharmony_ci
1455bd8deadSopenharmony_ci        While it is entirely legal to create a buffer object by binding
1465bd8deadSopenharmony_ci        it to ARRAY_BUFFER and loading it with data, then using it with
1475bd8deadSopenharmony_ci        the PIXEL_UNPACK_BUFFER_EXT or PIXEL_PACK_BUFFER_EXT binding, such
1485bd8deadSopenharmony_ci        behavior is liable to confuse the driver and may hurt performance.
1495bd8deadSopenharmony_ci        If the driver implemented the hypothetical heuristic described
1505bd8deadSopenharmony_ci        earlier, such a buffer might have already been located in
1515bd8deadSopenharmony_ci        write-combined system memory, and so the driver would have to
1525bd8deadSopenharmony_ci        choose between two bad options: relocate the buffer into video
1535bd8deadSopenharmony_ci        memory, or accept lower performance caused by streaming pixel
1545bd8deadSopenharmony_ci        data from slower system memory.
1555bd8deadSopenharmony_ci
1565bd8deadSopenharmony_ci    Should all pixel path commands be supported, or just a subset of
1575bd8deadSopenharmony_ci    them?
1585bd8deadSopenharmony_ci
1595bd8deadSopenharmony_ci        RESOLVED: ALL.  While there is little reason to believe that,
1605bd8deadSopenharmony_ci        say, ConvolutionFilter2D would benefit from this extension, there
1615bd8deadSopenharmony_ci        is no reason _not_ to support it.  The full list of commands
1625bd8deadSopenharmony_ci        affected by this extension is listed in the spec.
1635bd8deadSopenharmony_ci
1645bd8deadSopenharmony_ci    Should PixelMap and GetPixelMap be supported?
1655bd8deadSopenharmony_ci
1665bd8deadSopenharmony_ci        RESOLVED: YES.  They're not really pixel path operations, but,
1675bd8deadSopenharmony_ci        again, there is no good reason to omit operations, and they _are_
1685bd8deadSopenharmony_ci        operations that pass around big chunks of pixel-related data.
1695bd8deadSopenharmony_ci        If we support PolygonStipple, surely we should support this.
1705bd8deadSopenharmony_ci
1715bd8deadSopenharmony_ci    How does the buffer binding state push/pop?
1725bd8deadSopenharmony_ci
1735bd8deadSopenharmony_ci        RESOLVED: As part of the pixel store client state.  This is
1745bd8deadSopenharmony_ci        analogous to how the vertex buffer object bindings pushed/popped
1755bd8deadSopenharmony_ci        as part of the vertex array client state.
1765bd8deadSopenharmony_ci
1775bd8deadSopenharmony_ci    Should NV_pixel_data_range (PDR) be used concurrently with pixel
1785bd8deadSopenharmony_ci    buffer objects ?
1795bd8deadSopenharmony_ci
1805bd8deadSopenharmony_ci        RESOLVED: NO. While it would be possible to allocate a memory
1815bd8deadSopenharmony_ci        range for PDR, using a pointer into this memory range with one
1825bd8deadSopenharmony_ci        of the commands affected by EXT_pixel_buffer_object will not
1835bd8deadSopenharmony_ci        work if a pixel buffer object other than zero is bound to the
1845bd8deadSopenharmony_ci        buffer binding point affecting the command. Pixel buffer objects
1855bd8deadSopenharmony_ci        always have higher precedence than PDR.
1865bd8deadSopenharmony_ci
1875bd8deadSopenharmony_ci    Do the null pointer rules for glTexImage1D, glTexImage2D
1885bd8deadSopenharmony_ci    and glTexImage3D for allocating textures with undefined
1895bd8deadSopenharmony_ci    content also apply when a non-zero buffer object is bound to
1905bd8deadSopenharmony_ci    PIXEL_UNPACK_BUFFER_BINDING_EXT ?
1915bd8deadSopenharmony_ci        
1925bd8deadSopenharmony_ci        RESOLVED: NO. The null pointer is interpreted as a non-zero
1935bd8deadSopenharmony_ci        pointer to the data storage whose contents may be still
1945bd8deadSopenharmony_ci        undefined. This data will be used to create the texture array.
1955bd8deadSopenharmony_ci        If the null pointer rule is required, no non-zero buffer object
1965bd8deadSopenharmony_ci        should be bound to PIXEL_UNPACK_BUFFER_BINDING_EXT.
1975bd8deadSopenharmony_ci
1985bd8deadSopenharmony_ciNew Procedures and Functions
1995bd8deadSopenharmony_ci
2005bd8deadSopenharmony_ci    None.
2015bd8deadSopenharmony_ci
2025bd8deadSopenharmony_ciNew Tokens
2035bd8deadSopenharmony_ci
2045bd8deadSopenharmony_ci    Accepted by the <target> parameters of BindBuffer, BufferData, 
2055bd8deadSopenharmony_ci    BufferSubData, MapBuffer, UnmapBuffer, GetBufferSubData, 
2065bd8deadSopenharmony_ci    GetBufferParameteriv, and GetBufferPointerv:
2075bd8deadSopenharmony_ci
2085bd8deadSopenharmony_ci        PIXEL_PACK_BUFFER_EXT                        0x88EB
2095bd8deadSopenharmony_ci        PIXEL_UNPACK_BUFFER_EXT                      0x88EC
2105bd8deadSopenharmony_ci
2115bd8deadSopenharmony_ci    Accepted by the <pname> parameter of GetBooleanv, GetIntegerv,
2125bd8deadSopenharmony_ci    GetFloatv, and GetDoublev:
2135bd8deadSopenharmony_ci
2145bd8deadSopenharmony_ci        PIXEL_PACK_BUFFER_BINDING_EXT                0x88ED
2155bd8deadSopenharmony_ci        PIXEL_UNPACK_BUFFER_BINDING_EXT              0x88EF
2165bd8deadSopenharmony_ci
2175bd8deadSopenharmony_ci
2185bd8deadSopenharmony_ciAdditions to Chapter 2 of the GL Specification (OpenGL Operation)
2195bd8deadSopenharmony_ci
2205bd8deadSopenharmony_ci    None
2215bd8deadSopenharmony_ci
2225bd8deadSopenharmony_ciAdditions to Chapter 3 of the 1.2.1 Specification (Rasterization)
2235bd8deadSopenharmony_ci
2245bd8deadSopenharmony_ci    Additions to subsection 3.8.1 of the 1.2.1 Specification (Texture
2255bd8deadSopenharmony_ci    Image Specification)
2265bd8deadSopenharmony_ci
2275bd8deadSopenharmony_ci    The extension EXT_pixel_buffer_object makes an exception to this
2285bd8deadSopenharmony_ci    rule of passing a null pointer to glTexImage1D, glTexImage2D and
2295bd8deadSopenharmony_ci    glTexImage3D. If PIXEL_UNPACK_BUFFER_BINDING_EXT is non-zero
2305bd8deadSopenharmony_ci    and a null pointer is passed to these functions, the texture
2315bd8deadSopenharmony_ci    array is created and the image contents are sourced from the
2325bd8deadSopenharmony_ci    data store of the bound buffer object.
2335bd8deadSopenharmony_ci
2345bd8deadSopenharmony_ciAdditions to Chapter 4 of the 1.2.1 Specification (Per-Fragment
2355bd8deadSopenharmony_ciOperations and the Frame Buffer)
2365bd8deadSopenharmony_ci
2375bd8deadSopenharmony_ci    Added a subsection 4.3.5 (Pixel Buffer Object unpack operation)
2385bd8deadSopenharmony_ci    in section 4.3 (Drawing, Reading and copying Pixels)
2395bd8deadSopenharmony_ci
2405bd8deadSopenharmony_ci    The extension EXT_pixel_buffer_object affects the operation of
2415bd8deadSopenharmony_ci    several OpenGL commands described in section 3.6 (Pixel Rectangles),
2425bd8deadSopenharmony_ci    section 3.7 (Bitmaps), and section 3.8 (Texturing).
2435bd8deadSopenharmony_ci
2445bd8deadSopenharmony_ci    In unextended OpenGL 1.3 with ARB_imaging support, the commands
2455bd8deadSopenharmony_ci    glBitmap, glColorSubTable, glColorTable, glCompressedTexImage1D,
2465bd8deadSopenharmony_ci    glCompressedTexImage2D, glCompressedTexImage3D,
2475bd8deadSopenharmony_ci    glCompressedTexSubImage1D, glCompressedTexSubImage2D,
2485bd8deadSopenharmony_ci    glCompressedTexSubImage3D, glConvolutionFilter1D,
2495bd8deadSopenharmony_ci    glConvolutionFilter2D, glDrawPixels, glPixelMapfv, glPixelMapuiv,
2505bd8deadSopenharmony_ci    glPixelMapusv, glPolygonStipple, glSeparableFilter2D, glTexImage1D,
2515bd8deadSopenharmony_ci    glTexImage2D, glTexImage3D, glTexSubImage1D, glTexSubImage2D
2525bd8deadSopenharmony_ci    and glTexSubImage3D operate as previously defined, except
2535bd8deadSopenharmony_ci    that pixel data is sourced from a buffer object's data store if
2545bd8deadSopenharmony_ci    PIXEL_UNPACK_BUFFER_BINDING_EXT is non-zero. When the data is sourced
2555bd8deadSopenharmony_ci    from a buffer object, the pointer value passed in as an argument to
2565bd8deadSopenharmony_ci    the command is used to compute an offset, in basic machine units,
2575bd8deadSopenharmony_ci    into the data store of the buffer object. This offset is computed
2585bd8deadSopenharmony_ci    by subtracting a null pointer from the pointer value, where both
2595bd8deadSopenharmony_ci    pointers are treated as pointers to basic machine units.
2605bd8deadSopenharmony_ci
2615bd8deadSopenharmony_ciAdditions to Chapter 5 of the 1.2.1 Specification (Special Functions)
2625bd8deadSopenharmony_ci
2635bd8deadSopenharmony_ci    None
2645bd8deadSopenharmony_ci
2655bd8deadSopenharmony_ciAdditions to Chapter 6 of the 1.2.1 Specification (State and State
2665bd8deadSopenharmony_ciRequests)
2675bd8deadSopenharmony_ci
2685bd8deadSopenharmony_ci    Additions to subsection 6.1.13 (Buffer Object Queries) in chapter 6
2695bd8deadSopenharmony_ci    
2705bd8deadSopenharmony_ci    In unextended OpenGL 1.5 with ARB_imaging support, the commands
2715bd8deadSopenharmony_ci    glGetColorTable, glGetCompressedTexImage, glGetConvolutionFilter,
2725bd8deadSopenharmony_ci    glGetHistogram, glGetMinmax, glGetPixelMapfv, glGetPixelMapuiv,
2735bd8deadSopenharmony_ci    glGetPixelMapusv, glGetPolygonStipple, glGetSeparableFilter,
2745bd8deadSopenharmony_ci    glGetTexImage and glReadPixels operate as previously defined,
2755bd8deadSopenharmony_ci    except that pixel data is stored in a buffer object's data store if
2765bd8deadSopenharmony_ci    PIXEL_PACK_BUFFER_BINDING_EXT is non-zero. When a buffer object is
2775bd8deadSopenharmony_ci    the target of the pixel data, the target pointer value passed in as
2785bd8deadSopenharmony_ci    an argument to the command is used to compute an offset, in basic
2795bd8deadSopenharmony_ci    machine units, into the data store of the buffer object. This offset
2805bd8deadSopenharmony_ci    is computed by subtracting a null pointer from the pointer value,
2815bd8deadSopenharmony_ci    where both pointers are treated as pointers to basic machine units.
2825bd8deadSopenharmony_ci
2835bd8deadSopenharmony_ciErrors
2845bd8deadSopenharmony_ci
2855bd8deadSopenharmony_ci    None
2865bd8deadSopenharmony_ci
2875bd8deadSopenharmony_ciNew State
2885bd8deadSopenharmony_ci
2895bd8deadSopenharmony_ci(table 6.20, Pixels, p. 235)
2905bd8deadSopenharmony_ci
2915bd8deadSopenharmony_ci    Get Value                        Type  Get Command  Initial Value  Sec     Attribute
2925bd8deadSopenharmony_ci    ---------                        ----  -----------  -------------  ---     ---------
2935bd8deadSopenharmony_ci    PIXEL_PACK_BUFFER_BINDING_EXT    Z+    GetIntegerv  0              4.3.5   pixel-store
2945bd8deadSopenharmony_ci    PIXEL_UNPACK_BUFFER_BINDING_EXT  Z+    GetIntegerv  0              6.1.13  pixel-store
2955bd8deadSopenharmony_ci
2965bd8deadSopenharmony_ciNew Implementation Dependent State
2975bd8deadSopenharmony_ci
2985bd8deadSopenharmony_ci    (none)
2995bd8deadSopenharmony_ci
3005bd8deadSopenharmony_ci
3015bd8deadSopenharmony_ciUsage Examples
3025bd8deadSopenharmony_ci
3035bd8deadSopenharmony_ci    Convenient macro definition for specifying buffer offsets:
3045bd8deadSopenharmony_ci
3055bd8deadSopenharmony_ci        #define BUFFER_OFFSET(i) ((char *)NULL + (i))
3065bd8deadSopenharmony_ci
3075bd8deadSopenharmony_ci    Example 1: Render to vertex array
3085bd8deadSopenharmony_ci
3095bd8deadSopenharmony_ci        // create a buffer object for a number of vertices consisting of 
3105bd8deadSopenharmony_ci        // 4 float values per vertex
3115bd8deadSopenharmony_ci        GenBuffers(1, vertexBuffer);
3125bd8deadSopenharmony_ci        BindBuffer(PIXEL_PACK_BUFFER_EXT, vertexBuffer);
3135bd8deadSopenharmony_ci        BufferData(PIXEL_PACK_BUFFER_EXT, numberVertices*4, NULL, DYNAMIC_DRAW);
3145bd8deadSopenharmony_ci
3155bd8deadSopenharmony_ci        // render vertex data into framebuffer using a fragment program
3165bd8deadSopenharmony_ci        BindProgramARB(FRAGMENT_PROGRAM_ARB, fragmentProgram);
3175bd8deadSopenharmony_ci        DrawBuffer(GL_BACK);
3185bd8deadSopenharmony_ci        renderVertexData();
3195bd8deadSopenharmony_ci        BindProgramARB(FRAGMENT_PROGRAM_ARB, 0);
3205bd8deadSopenharmony_ci
3215bd8deadSopenharmony_ci        // read the vertex data back from framebuffer
3225bd8deadSopenharmony_ci        ReadBuffer(GL_BACK);
3235bd8deadSopenharmony_ci        ReadPixels(0, 0, numberVertices*4, height/2,
3245bd8deadSopenharmony_ci            GL_BGRA, GL_FLOAT, BUFFER_OFFSET(0));
3255bd8deadSopenharmony_ci
3265bd8deadSopenharmony_ci        // change the binding point of the buffer object to
3275bd8deadSopenharmony_ci        // the vertex array binding point
3285bd8deadSopenharmony_ci        BindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
3295bd8deadSopenharmony_ci
3305bd8deadSopenharmony_ci        EnableClientState(VERTEX_ARRAY);
3315bd8deadSopenharmony_ci        VertexPointer(4, FLOAT, 0, BUFFER_OFFSET(0));
3325bd8deadSopenharmony_ci        DrawArrays(TRIANGLE_STRIP, 0, numberVertices);
3335bd8deadSopenharmony_ci
3345bd8deadSopenharmony_ci    Example 2: Streaming textures
3355bd8deadSopenharmony_ci
3365bd8deadSopenharmony_ci    streaming textures using NV_pixel_data_range 
3375bd8deadSopenharmony_ci
3385bd8deadSopenharmony_ci        void *pdrMemory, *texData;
3395bd8deadSopenharmony_ci
3405bd8deadSopenharmony_ci        pdrMemory = AllocateMemoryNV(texsize, 0.0, 1.0, 1.0);
3415bd8deadSopenharmony_ci
3425bd8deadSopenharmony_ci        PixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV, texsize, pdrMemory);
3435bd8deadSopenharmony_ci
3445bd8deadSopenharmony_ci        EnableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV);
3455bd8deadSopenharmony_ci
3465bd8deadSopenharmony_ci        // setup texture environment
3475bd8deadSopenharmony_ci        ...     
3485bd8deadSopenharmony_ci
3495bd8deadSopenharmony_ci        texData = getNextImage();
3505bd8deadSopenharmony_ci
3515bd8deadSopenharmony_ci        while (texData) {
3525bd8deadSopenharmony_ci
3535bd8deadSopenharmony_ci            memcpy(pdrMemory, texData, texsize);
3545bd8deadSopenharmony_ci
3555bd8deadSopenharmony_ci            FlushPixelDataRangeNV(GL_WRITE_PIXEL_DATA_RANGE_NV);
3565bd8deadSopenharmony_ci
3575bd8deadSopenharmony_ci            TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
3585bd8deadSopenharmony_ci                texWidth, texHeight, GL_BGRA, GL_UNSIGNED_BYTE, pdrMemory);
3595bd8deadSopenharmony_ci
3605bd8deadSopenharmony_ci            // draw textured geometry
3615bd8deadSopenharmony_ci            Begin(GL_QUADS);
3625bd8deadSopenharmony_ci            ...
3635bd8deadSopenharmony_ci            End();
3645bd8deadSopenharmony_ci
3655bd8deadSopenharmony_ci            texData = getNextImage();
3665bd8deadSopenharmony_ci        }
3675bd8deadSopenharmony_ci
3685bd8deadSopenharmony_ci        DisableClientState(GL_WRITE_PIXEL_DATA_RANGE_NV);
3695bd8deadSopenharmony_ci
3705bd8deadSopenharmony_ci        FreeMemoryNV(pdrMemory);
3715bd8deadSopenharmony_ci    
3725bd8deadSopenharmony_ci    streaming textures using EXT_pixel_buffer_object:
3735bd8deadSopenharmony_ci
3745bd8deadSopenharmony_ci        void *pboMemory, *texData;
3755bd8deadSopenharmony_ci
3765bd8deadSopenharmony_ci        // create and bind texture image buffer object
3775bd8deadSopenharmony_ci        GenBuffers(1, &texBuffer);
3785bd8deadSopenharmony_ci        BindBuffer(PIXEL_UNPACK_BUFFER_EXT, texBuffer);
3795bd8deadSopenharmony_ci        BufferData(PIXEL_UNPACK_BUFFER_EXT, texSize, NULL, STREAM_DRAW);
3805bd8deadSopenharmony_ci
3815bd8deadSopenharmony_ci        texData = getNextImage();
3825bd8deadSopenharmony_ci
3835bd8deadSopenharmony_ci        while (texData) {
3845bd8deadSopenharmony_ci
3855bd8deadSopenharmony_ci            // map the texture image buffer
3865bd8deadSopenharmony_ci            pboMemory = MapBuffer(PIXEL_UNPACK_BUFFER_EXT, WRITE_ONLY);
3875bd8deadSopenharmony_ci            
3885bd8deadSopenharmony_ci            // modify (sub-)buffer data
3895bd8deadSopenharmony_ci            memcpy(pboMemory, texData, texsize);
3905bd8deadSopenharmony_ci
3915bd8deadSopenharmony_ci            // unmap the texture image buffer
3925bd8deadSopenharmony_ci            if (!UnmapBuffer(PIXEL_UNPACK_BUFFER_EXT)) {
3935bd8deadSopenharmony_ci                // Handle error case
3945bd8deadSopenharmony_ci            }
3955bd8deadSopenharmony_ci
3965bd8deadSopenharmony_ci            // update (sub-)teximage from texture image buffer
3975bd8deadSopenharmony_ci            TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, 
3985bd8deadSopenharmony_ci                          GL_BGRA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
3995bd8deadSopenharmony_ci
4005bd8deadSopenharmony_ci            // draw textured geometry
4015bd8deadSopenharmony_ci            Begin(GL_QUADS);
4025bd8deadSopenharmony_ci            ...
4035bd8deadSopenharmony_ci            End();
4045bd8deadSopenharmony_ci
4055bd8deadSopenharmony_ci            texData = getNextImage();
4065bd8deadSopenharmony_ci        }
4075bd8deadSopenharmony_ci
4085bd8deadSopenharmony_ci        BindBuffer(PIXEL_UNPACK_BUFFER_EXT, 0);
4095bd8deadSopenharmony_ci
4105bd8deadSopenharmony_ci    Example 3: Asynchronous ReadPixels
4115bd8deadSopenharmony_ci
4125bd8deadSopenharmony_ci    traditional ReadPixels
4135bd8deadSopenharmony_ci
4145bd8deadSopenharmony_ci        unsigned int readBuffer[imagewidth*imageheight*4];
4155bd8deadSopenharmony_ci
4165bd8deadSopenharmony_ci        // render to framebuffer
4175bd8deadSopenharmony_ci        DrawBuffer(GL_BACK);
4185bd8deadSopenharmony_ci        renderScene()
4195bd8deadSopenharmony_ci        
4205bd8deadSopenharmony_ci        // read image from framebuffer
4215bd8deadSopenharmony_ci        ReadBuffer(GL_BACK); 
4225bd8deadSopenharmony_ci        ReadPixels();
4235bd8deadSopenharmony_ci
4245bd8deadSopenharmony_ci        // process image when ReadPixels returns after reading the whole buffer
4255bd8deadSopenharmony_ci        processImage(readBuffer);
4265bd8deadSopenharmony_ci
4275bd8deadSopenharmony_ci    asynchronous ReadPixels
4285bd8deadSopenharmony_ci
4295bd8deadSopenharmony_ci        GenBuffers(2, imageBuffers);
4305bd8deadSopenharmony_ci
4315bd8deadSopenharmony_ci        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);
4325bd8deadSopenharmony_ci        BufferData(PIXEL_PACK_BUFFER_EXT, imageSize / 2, NULL, STATIC_READ);
4335bd8deadSopenharmony_ci
4345bd8deadSopenharmony_ci        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);
4355bd8deadSopenharmony_ci        BufferData(PIXEL_PACK_BUFFER_EXT, imageSize / 2, NULL, STATIC_READ);
4365bd8deadSopenharmony_ci
4375bd8deadSopenharmony_ci        // render to framebuffer
4385bd8deadSopenharmony_ci        DrawBuffer(GL_BACK);
4395bd8deadSopenharmony_ci        renderScene();
4405bd8deadSopenharmony_ci
4415bd8deadSopenharmony_ci        // Bind two different buffer objects and start the ReadPixels 
4425bd8deadSopenharmony_ci        // asynchronously. Each call will return directly after starting the 
4435bd8deadSopenharmony_ci        // DMA transfer.
4445bd8deadSopenharmony_ci        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);
4455bd8deadSopenharmony_ci        ReadPixels(0, 0, width, height/2,
4465bd8deadSopenharmony_ci            GL_BGRA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
4475bd8deadSopenharmony_ci
4485bd8deadSopenharmony_ci        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);
4495bd8deadSopenharmony_ci        ReadPixels(0, height/2, width, height/2, GL_BGRA, GL_UNSIGNED_BYTE, 
4505bd8deadSopenharmony_ci                   BUFFER_OFFSET(0));
4515bd8deadSopenharmony_ci        
4525bd8deadSopenharmony_ci        // process partial images 
4535bd8deadSopenharmony_ci        pboMemory1 = MapBuffer(PIXEL_PACK_BUFFER_EXT, READ_ONLY);
4545bd8deadSopenharmony_ci        processImage(pboMemory1);
4555bd8deadSopenharmony_ci        pboMemory2 = MapBuffer(PIXEL_PACK_BUFFER_EXT, READ_ONLY);
4565bd8deadSopenharmony_ci        processImage(pboMemory2);
4575bd8deadSopenharmony_ci
4585bd8deadSopenharmony_ci        // unmap the image buffers
4595bd8deadSopenharmony_ci        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[0]);
4605bd8deadSopenharmony_ci        if (!UnmapBuffer(PIXEL_PACK_BUFFER_EXT)) {
4615bd8deadSopenharmony_ci            // Handle error case
4625bd8deadSopenharmony_ci        }
4635bd8deadSopenharmony_ci        BindBuffer(PIXEL_PACK_BUFFER_EXT, imageBuffers[1]);
4645bd8deadSopenharmony_ci        if (!UnmapBuffer(PIXEL_PACK_BUFFER_EXT)) {
4655bd8deadSopenharmony_ci            // Handle error case
4665bd8deadSopenharmony_ci        }
467