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