revamped glCopyTexSubImage1/2/3D() to be more like glCopyTexImage1/2/3D()
This commit is contained in:
@@ -2270,6 +2270,8 @@ read_color_image( GLcontext *ctx, GLint x, GLint y,
|
|||||||
(*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
|
(*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
|
||||||
ctx->Pixel.DriverReadBuffer );
|
ctx->Pixel.DriverReadBuffer );
|
||||||
|
|
||||||
|
/* XXX TODO we have to apply pixel transfer ops here! */
|
||||||
|
|
||||||
dst = image;
|
dst = image;
|
||||||
stride = width * 4 * sizeof(GLubyte);
|
stride = width * 4 * sizeof(GLubyte);
|
||||||
for (i = 0; i < height; i++) {
|
for (i = 0; i < height; i++) {
|
||||||
@@ -2305,13 +2307,22 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
|
|||||||
|| !(*ctx->Driver.CopyTexImage1D)(ctx, target, level,
|
|| !(*ctx->Driver.CopyTexImage1D)(ctx, target, level,
|
||||||
internalFormat, x, y, width, border))
|
internalFormat, x, y, width, border))
|
||||||
{
|
{
|
||||||
|
struct gl_pixelstore_attrib unpackSave;
|
||||||
|
|
||||||
|
/* get image from framebuffer */
|
||||||
GLubyte *image = read_color_image( ctx, x, y, width, 1 );
|
GLubyte *image = read_color_image( ctx, x, y, width, 1 );
|
||||||
if (!image) {
|
if (!image) {
|
||||||
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
|
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* call glTexImage1D to redefine the texture */
|
||||||
|
unpackSave = ctx->Unpack;
|
||||||
|
ctx->Unpack = _mesa_native_packing;
|
||||||
(*ctx->Exec->TexImage1D)( target, level, internalFormat, width,
|
(*ctx->Exec->TexImage1D)( target, level, internalFormat, width,
|
||||||
border, GL_RGBA, GL_UNSIGNED_BYTE, image );
|
border, GL_RGBA, GL_UNSIGNED_BYTE, image );
|
||||||
|
ctx->Unpack = unpackSave;
|
||||||
|
|
||||||
FREE(image);
|
FREE(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2335,65 +2346,28 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
|
|||||||
|| !(*ctx->Driver.CopyTexImage2D)(ctx, target, level,
|
|| !(*ctx->Driver.CopyTexImage2D)(ctx, target, level,
|
||||||
internalFormat, x, y, width, height, border))
|
internalFormat, x, y, width, height, border))
|
||||||
{
|
{
|
||||||
|
struct gl_pixelstore_attrib unpackSave;
|
||||||
|
|
||||||
|
/* get image from framebuffer */
|
||||||
GLubyte *image = read_color_image( ctx, x, y, width, height );
|
GLubyte *image = read_color_image( ctx, x, y, width, height );
|
||||||
if (!image) {
|
if (!image) {
|
||||||
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" );
|
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* call glTexImage2D to redefine the texture */
|
||||||
|
unpackSave = ctx->Unpack;
|
||||||
|
ctx->Unpack = _mesa_native_packing;
|
||||||
(ctx->Exec->TexImage2D)( target, level, internalFormat, width,
|
(ctx->Exec->TexImage2D)( target, level, internalFormat, width,
|
||||||
height, border, GL_RGBA, GL_UNSIGNED_BYTE, image );
|
height, border, GL_RGBA, GL_UNSIGNED_BYTE, image );
|
||||||
|
ctx->Unpack = unpackSave;
|
||||||
|
|
||||||
FREE(image);
|
FREE(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do the work of glCopyTexSubImage[123]D.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
copy_tex_sub_image( GLcontext *ctx, struct gl_texture_image *dest,
|
|
||||||
GLint width, GLint height,
|
|
||||||
GLint srcx, GLint srcy,
|
|
||||||
GLint dstx, GLint dsty, GLint dstz )
|
|
||||||
{
|
|
||||||
GLint i;
|
|
||||||
GLint format, components, rectarea;
|
|
||||||
GLint texwidth, texheight, zoffset;
|
|
||||||
|
|
||||||
/* dst[xyz] may be negative if we have a texture border! */
|
|
||||||
dstx += dest->Border;
|
|
||||||
dsty += dest->Border;
|
|
||||||
dstz += dest->Border;
|
|
||||||
texwidth = dest->Width;
|
|
||||||
texheight = dest->Height;
|
|
||||||
rectarea = texwidth * texheight;
|
|
||||||
zoffset = dstz * rectarea;
|
|
||||||
format = dest->Format;
|
|
||||||
components = components_in_intformat( format );
|
|
||||||
|
|
||||||
/* Select buffer to read from */
|
|
||||||
(*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer,
|
|
||||||
ctx->Pixel.DriverReadBuffer );
|
|
||||||
|
|
||||||
for (i = 0;i < height; i++) {
|
|
||||||
GLubyte rgba[MAX_WIDTH][4];
|
|
||||||
GLubyte *dst;
|
|
||||||
gl_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, srcy + i, rgba );
|
|
||||||
dst = dest->Data + ( zoffset + (dsty+i) * texwidth + dstx) * components;
|
|
||||||
_mesa_unpack_ubyte_color_span(ctx, width, format, dst,
|
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, rgba,
|
|
||||||
&_mesa_native_packing, GL_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read from draw buffer (the default) */
|
|
||||||
(*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer,
|
|
||||||
ctx->Color.DriverDrawBuffer );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_mesa_CopyTexSubImage1D( GLenum target, GLint level,
|
_mesa_CopyTexSubImage1D( GLenum target, GLint level,
|
||||||
GLint xoffset, GLint x, GLint y, GLsizei width )
|
GLint xoffset, GLint x, GLint y, GLsizei width )
|
||||||
@@ -2411,19 +2385,28 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
|
|||||||
xoffset, x, y, width)) {
|
xoffset, x, y, width)) {
|
||||||
struct gl_texture_unit *texUnit;
|
struct gl_texture_unit *texUnit;
|
||||||
struct gl_texture_image *teximage;
|
struct gl_texture_image *teximage;
|
||||||
|
struct gl_pixelstore_attrib unpackSave;
|
||||||
|
GLubyte *image;
|
||||||
|
|
||||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
teximage = texUnit->CurrentD[1]->Image[level];
|
teximage = texUnit->CurrentD[1]->Image[level];
|
||||||
assert(teximage);
|
assert(teximage);
|
||||||
if (teximage->Data) {
|
|
||||||
copy_tex_sub_image(ctx, teximage, width, 1, x, y, xoffset, 0, 0);
|
/* get image from frame buffer */
|
||||||
/* tell driver about the change */
|
image = read_color_image(ctx, x, y, width, 1);
|
||||||
/* XXX this is obsolete */
|
if (!image) {
|
||||||
if (ctx->Driver.TexImage) {
|
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
|
||||||
(*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
|
return;
|
||||||
texUnit->CurrentD[1],
|
|
||||||
level, teximage->IntFormat, teximage );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* now call glTexSubImage1D to do the real work */
|
||||||
|
unpackSave = ctx->Unpack;
|
||||||
|
ctx->Unpack = _mesa_native_packing;
|
||||||
|
_mesa_TexSubImage1D(target, level, xoffset, width,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||||
|
ctx->Unpack = unpackSave;
|
||||||
|
|
||||||
|
FREE(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2447,20 +2430,28 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
|
|||||||
xoffset, yoffset, x, y, width, height )) {
|
xoffset, yoffset, x, y, width, height )) {
|
||||||
struct gl_texture_unit *texUnit;
|
struct gl_texture_unit *texUnit;
|
||||||
struct gl_texture_image *teximage;
|
struct gl_texture_image *teximage;
|
||||||
|
struct gl_pixelstore_attrib unpackSave;
|
||||||
|
GLubyte *image;
|
||||||
|
|
||||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
teximage = texUnit->CurrentD[2]->Image[level];
|
teximage = texUnit->CurrentD[2]->Image[level];
|
||||||
assert(teximage);
|
assert(teximage);
|
||||||
if (teximage->Data) {
|
|
||||||
copy_tex_sub_image(ctx, teximage, width, height,
|
/* get image from frame buffer */
|
||||||
x, y, xoffset, yoffset, 0);
|
image = read_color_image(ctx, x, y, width, height);
|
||||||
/* tell driver about the change */
|
if (!image) {
|
||||||
/* XXX this is obsolete */
|
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
|
||||||
if (ctx->Driver.TexImage) {
|
return;
|
||||||
(*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
|
|
||||||
texUnit->CurrentD[2],
|
|
||||||
level, teximage->IntFormat, teximage );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* now call glTexSubImage2D to do the real work */
|
||||||
|
unpackSave = ctx->Unpack;
|
||||||
|
ctx->Unpack = _mesa_native_packing;
|
||||||
|
_mesa_TexSubImage2D(target, level, xoffset, yoffset, width, height,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||||
|
ctx->Unpack = unpackSave;
|
||||||
|
|
||||||
|
FREE(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2484,20 +2475,28 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
|
|||||||
xoffset, yoffset, zoffset, x, y, width, height )) {
|
xoffset, yoffset, zoffset, x, y, width, height )) {
|
||||||
struct gl_texture_unit *texUnit;
|
struct gl_texture_unit *texUnit;
|
||||||
struct gl_texture_image *teximage;
|
struct gl_texture_image *teximage;
|
||||||
|
struct gl_pixelstore_attrib unpackSave;
|
||||||
|
GLubyte *image;
|
||||||
|
|
||||||
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
teximage = texUnit->CurrentD[3]->Image[level];
|
teximage = texUnit->CurrentD[3]->Image[level];
|
||||||
assert(teximage);
|
assert(teximage);
|
||||||
if (teximage->Data) {
|
|
||||||
copy_tex_sub_image(ctx, teximage, width, height,
|
/* get image from frame buffer */
|
||||||
x, y, xoffset, yoffset, zoffset);
|
image = read_color_image(ctx, x, y, width, height);
|
||||||
/* tell driver about the change */
|
if (!image) {
|
||||||
/* XXX this is obsolete */
|
gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
|
||||||
if (ctx->Driver.TexImage) {
|
return;
|
||||||
(*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D,
|
|
||||||
texUnit->CurrentD[3],
|
|
||||||
level, teximage->IntFormat, teximage );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* now call glTexSubImage2D to do the real work */
|
||||||
|
unpackSave = ctx->Unpack;
|
||||||
|
ctx->Unpack = _mesa_native_packing;
|
||||||
|
_mesa_TexSubImage3D(target, level, xoffset, yoffset, zoffset,
|
||||||
|
width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||||
|
ctx->Unpack = unpackSave;
|
||||||
|
|
||||||
|
FREE(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user