GLCOPYPIXELS(3G)
π GLCOPYPIXELS π
okay so welcome to glCopyPixels(3G), straight out of the 3G OpenGL manual pages, and bestie this one is genuinely iconic β it's the "copy-paste but for pixels" function and I need you to be seated for it. π«Ά
β¨ NAME β¨
glCopyPixels β copy pixels in the frame buffer. that's the whole job. no notes. π
πΈ C SPECIFICATION πΈ
void glCopyPixels( GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLenum type )
π PARAMETERS π
x,yβ the window coordinates of the lower left corner of the rectangular region of pixels you're copying. lowercase corner, that's the anchor. π¦width,heightβ the dimensions of that rectangular region of pixels to be copied. both of them have to be nonnegative, no exceptions, no "but bestie I wanted negative width". πtypeβ tells you what kind of values are getting copied: color values, depth values, or stencil values. the symbolic constants it accepts areGL_COLOR,GL_DEPTH, andGL_STENCIL. pick one, queen. π
π« DESCRIPTION π«
glCopyPixels copies a screen-aligned rectangle of pixels from the specified frame buffer location over to a region relative to the current raster position. main character energy, moving pixels around like it's nothing.
ok but real talk: its operation is well defined only if the entire pixel source region is within the exposed portion of the window. results of copies from outside the window, or from regions of the window that are not exposed, are hardware dependent and undefined. so likeβ¦ don't. π
x and y give the window coordinates of the lower left corner of the rectangular region being copied. width and height give the dimensions of that region. and again, both width and height must not be negative. π«
so there's a whole little committee of parameters that control how the pixel data gets processed while it's being copied. those parameters are set with three commands: glPixelTransfer, glPixelMap, and glPixelZoom. this reference page describes the effects on glCopyPixels of most, but not all, of the parameters specified by those three commands. so it's giving "here's the lore, but not all the lore". π
here's the actual pixel math, and it slays: glCopyPixels copies values from each pixel with the lower left-hand corner at (x + i, y + j) for 0 β€ i < width and 0 β€ j < height. this pixel is said to be the ith pixel in the jth row. pixels are copied in row order, from the lowest row to the highest row, and left to right within each row. so it's literally reading order but for rectangles. π
type specifies whether color, depth, or stencil data is being copied. the details of the transfer for each data type are as follows, and I'm giving you ALL of them because I love you:
π GL_COLOR
Indices or RGBA colors are read from the buffer currently specified as the read source buffer (see glReadBuffer).
If the GL is in color index mode, each index that is read from this buffer is converted to a fixed-point with an unspecified number of bits to the right of the binary point. each index is then shifted left by GL_INDEX_SHIFT bits, and added to GL_INDEX_OFFSET. if GL_INDEX_SHIFT is negative, the shift is to the right. in either case, zero bits fill otherwise unspecified bit locations in the result. if GL_MAP_COLOR is true, the index is replaced with the value that it references in lookup table GL_PIXEL_MAP_I_TO_I. whether the lookup replacement of the index is done or not, the integer part of the index is then ANDed with 2bβ1, where b is the number of bits in a color index buffer.
If the GL is in RGBA mode, the red, green, blue, and alpha components of each pixel that is read are converted to an internal floating-point with unspecified precision. the conversion maps the largest representable component value to 1.0, and component value 0 to 0.0. the resulting floating-point color values are then multiplied by GL_c_SCALE and added to GL_c_BIAS, where c is RED, GREEN, BLUE, and ALPHA for the respective color components. the results are clamped to the range [0,1]. if GL_MAP_COLOR is true, each color component is scaled by the size of lookup table GL_PIXEL_MAP_c_TO_c, then replaced by the value that it references in that table. c is R, G, B, or A.
If the GL_ARB_imaging extension is supported, the color values may be additionally processed by color-table lookups, color-matrix transformations, and convolution filters. β¨ fancy.
The GL then converts the resulting indices or RGBA colors to fragments by attaching the current raster position z coordinate and texture coordinates to each pixel, then assigning window coordinates (xr+i,yr+j), where (xr,yr) is the current raster position, and the pixel was the ith pixel in the jth row. these pixel fragments are then treated just like the fragments generated by rasterizing points, lines, or polygons. texture mapping, fog, and all the fragment operations are applied before the fragments are written to the frame buffer. the full pipeline said "hold my boba". π§
π GL_DEPTH
Depth values are read from the depth buffer and converted directly to an internal floating-point with unspecified precision. the resulting floating-point depth value is then multiplied by GL_DEPTH_SCALE and added to GL_DEPTH_BIAS. the result is clamped to the range [0,1].
The GL then converts the resulting depth components to fragments by attaching the current raster position color or color index and texture coordinates to each pixel, then assigning window coordinates (xr+i,yr+j), where (xr,yr) is the current raster position, and the pixel was the ith pixel in the jth row. these pixel fragments are then treated just like the fragments generated by rasterizing points, lines, or polygons. texture mapping, fog, and all the fragment operations are applied before the fragments are written to the frame buffer.
π¦ GL_STENCIL
Stencil indices are read from the stencil buffer and converted to an internal fixed-point with an unspecified number of bits to the right of the binary point. each fixed-point index is then shifted left by GL_INDEX_SHIFT bits, and added to GL_INDEX_OFFSET. if GL_INDEX_SHIFT is negative, the shift is to the right. in either case, zero bits fill otherwise unspecified bit locations in the result. if GL_MAP_STENCIL is true, the index is replaced with the value that it references in lookup table GL_PIXEL_MAP_S_TO_S. whether the lookup replacement of the index is done or not, the integer part of the index is then ANDed with 2bβ1, where b is the number of bits in the stencil buffer. the resulting stencil indices are then written to the stencil buffer such that the index read from the ith location of the jth row is written to location (xr+i,yr+j), where (xr,yr) is the current raster position. only the pixel ownership test, the scissor test, and the stencil writemask affect these write operations. that's it, that's the whole guest list. ποΈ
π the zoom part (do not skip, I'm serious)
The rasterization described thus far assumes pixel zoom factors of 1.0. if glPixelZoom is used to change the x and y pixel zoom factors, pixels are converted to fragments as follows. if (xr, yr) is the current raster position, and a given pixel is in the ith location in the jth row of the source pixel rectangle, then fragments are generated for pixels whose centers are in the rectangle with corners at
(xr+zoomxi, yr+zoomyj)
and
(xr+zoomx(i+1), yr+zoomy(j+1))
where zoomx is the value of GL_ZOOM_X and zoomy is the value of GL_ZOOM_Y. geometry girlies, this one's for you. π
π EXAMPLES π
To copy the color pixel in the lower left corner of the window to the current raster position, use:
glCopyPixels(0, 0, 1, 1, GL_COLOR);
one pixel. corner of the window. raster position. done and dusted. π
π NOTES π
Modes specified by glPixelStore have no effect on the operation of glCopyPixels. so if you were about to set a pack or unpack mode and expect it to matter hereβ¦ it does not, bestie. π
π¨ ERRORS π¨
GL_INVALID_ENUMis generated iftypeis not an accepted value.GL_INVALID_VALUEis generated if eitherwidthorheightis negative.GL_INVALID_OPERATIONis generated iftypeisGL_DEPTHand there is no depth buffer.GL_INVALID_OPERATIONis generated iftypeisGL_STENCILand there is no stencil buffer.GL_INVALID_OPERATIONis generated ifglCopyPixelsis executed between the execution ofglBeginand the corresponding execution ofglEnd.
so basically: valid type, nonnegative dimensions, have the buffer you're asking for, and stay out ofglBegin/glEnd. break any of those and the GL will be like "not today". π
π ASSOCIATED GETS π
glGetwith argumentGL_CURRENT_RASTER_POSITIONglGetwith argumentGL_CURRENT_RASTER_POSITION_VALID
π SEE ALSO π
glColorTable(3G)glConvolutionFilter1D(3G)glConvolutionFilter2D(3G)glDepthFunc(3G)glDrawBuffer(3G)glDrawPixels(3G)glMatrixMode(3G)glPixelMap(3G)glPixelTransfer(3G)glPixelZoom(3G)glRasterPos(3G)glReadBuffer(3G)glReadPixels(3G)glSeparableFilter2D(3G)glStencilFunc(3G)
and that's the page!! this whole thing was GLCOPYPIXELS(3G) from the 3G OpenGL manual pages, so if you ever forget the vibe, just flip back to the 3G section and it'll be right there waiting for you like the loyal bestie it is. go forth and copy pixels responsibly, angel. πβ¨ππ¦πΈπ
π«Ά
π¦ where this page comes from
- opensuse-leap 16.0: Mesa-libGL-devel 24.1.7-160000.3.1 Β· MIT
- opensuse-leap 16.0: Mesa-libGL-devel 24.3.3-160000.3.1 Β· MIT
- opensuse-leap 16.0: Mesa-libGL-devel 24.3.3-160000.3.1 Β· MIT
- opensuse-leap 16.0: Mesa-libGL-devel 24.3.3-160000.3.1 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms