From d15b02ff291e3124d9bb8ac3b06b704c292f52ab Mon Sep 17 00:00:00 2001 From: Paul Lemire Date: Wed, 20 Feb 2019 09:54:07 +0100 Subject: QOpenGLTexture::setData add overloads to allow specifying sub images All current setData implementation only allow to specify a full size sub image for a given mip level. In some cases, we might only want to update a small region on an image, in which cases being able to specify the x, y, z offsets as well as the dimensions is required. Change-Id: I880cfcc67a814733e8ab880aa8766c87b7bc7e45 Reviewed-by: Giuseppe D'Angelo --- src/gui/opengl/qopengltexture.cpp | 234 ++++++++++++++++++++++++++++++++++++++ src/gui/opengl/qopengltexture.h | 26 +++++ src/gui/opengl/qopengltexture_p.h | 4 + 3 files changed, 264 insertions(+) (limited to 'src/gui/opengl') diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp index 5b7956d31e..f25988585e 100644 --- a/src/gui/opengl/qopengltexture.cpp +++ b/src/gui/opengl/qopengltexture.cpp @@ -1467,6 +1467,122 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, int layerCount, QOp } } +void QOpenGLTexturePrivate::setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth, + int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, + QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + switch (target) { + case QOpenGLTexture::Target1D: + Q_UNUSED(layer); + Q_UNUSED(cubeFace); + Q_UNUSED(layerCount); + Q_UNUSED(yOffset); + Q_UNUSED(zOffset); + Q_UNUSED(height); + Q_UNUSED(depth); + texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel, + xOffset, width, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target1DArray: + Q_UNUSED(cubeFace); + Q_UNUSED(yOffset); + Q_UNUSED(zOffset); + Q_UNUSED(height); + Q_UNUSED(depth); + texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel, + xOffset, layer, + width, + layerCount, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target2D: + Q_UNUSED(layer); + Q_UNUSED(cubeFace); + Q_UNUSED(layerCount); + Q_UNUSED(zOffset); + Q_UNUSED(depth); + texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel, + xOffset, yOffset, + width, height, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target2DArray: + Q_UNUSED(cubeFace); + Q_UNUSED(zOffset); + Q_UNUSED(depth); + texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + xOffset, yOffset, layer, + width, height, layerCount, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target3D: + Q_UNUSED(cubeFace); + Q_UNUSED(layerCount); + texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + xOffset, yOffset, zOffset, + width, height, depth, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::TargetCubeMap: + Q_UNUSED(layer); + Q_UNUSED(layerCount); + Q_UNUSED(zOffset); + Q_UNUSED(depth); + texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel, + xOffset, yOffset, + width, height, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::TargetCubeMapArray: { + Q_UNUSED(zOffset); + Q_UNUSED(depth); + int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX; + int layerFace = 6 * layer + faceIndex; + texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel, + xOffset, yOffset, layerFace, + width, height, + layerCount, + sourceFormat, sourceType, data, options); + break; + } + + case QOpenGLTexture::TargetRectangle: + Q_UNUSED(mipLevel); + Q_UNUSED(layer); + Q_UNUSED(cubeFace); + Q_UNUSED(layerCount); + Q_UNUSED(zOffset); + Q_UNUSED(depth); + texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0, + xOffset, yOffset, + width, height, + sourceFormat, sourceType, data, options); + break; + + case QOpenGLTexture::Target2DMultisample: + case QOpenGLTexture::Target2DMultisampleArray: + case QOpenGLTexture::TargetBuffer: + // We don't upload pixel data for these targets + qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload"); + break; + } + + // If requested perform automatic mip map generation + if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) { + Q_Q(QOpenGLTexture); + q->generateMipMaps(); + } +} + + void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, @@ -3380,6 +3496,124 @@ void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType, d->setData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options); } +/*! + \since 5.14 + \overload + + This overload is to be used to update a part of the texture. Parameters \a + xOffset, \a yOffset, \a zOffset specify the texel offsets within the + texture. Parameters \a width, \a height and \a depth specify the dimensions + of the sub image. + + The structure of the pixel data pointed to by \a data is specified by \a + sourceFormat and \a sourceType. The pixel data upload can optionally be + controlled by \a options. +*/ +void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + Q_D(QOpenGLTexture); + Q_ASSERT(d->textureId); + d->setData(xOffset, yOffset, zOffset, + width, height, depth, + 0, 0, 1, + QOpenGLTexture::CubeMapPositiveX, sourceFormat, + sourceType, data, options); +} + +/*! + \since 5.14 + \overload + + This overload is to be used to update a part of the texture. Parameters \a + xOffset, \a yOffset, \a zOffset specify the texel offsets within the + texture. Parameters \a width, \a height and \a depth specify the dimensions + of the sub image. The mip map level and layerof the sub image we want to + update are specified with \a mipLevel and \a layer. + + The structure of the pixel data pointed to by \a data is specified by \a + sourceFormat and \a sourceType. The pixel data upload can optionally be + controlled by \a options. +*/ +void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + Q_D(QOpenGLTexture); + Q_ASSERT(d->textureId); + d->setData(xOffset, yOffset, zOffset, + width, height, depth, + mipLevel, layer, 1, + QOpenGLTexture::CubeMapPositiveX, sourceFormat, + sourceType, data, options); +} + +/*! + \since 5.14 + \overload + + This overload is to be used to update a part of the texture. Parameters \a + xOffset, \a yOffset, \a zOffset specify the texel offsets within the + texture. Parameters \a width, \a height and \a depth specify the dimensions + of the sub image.The mip map level, layer and cube map face of the sub + image we want to update are specified with \a mipLevel, \a layer and \a + face. + + The structure of the pixel data pointed to by \a data is specified by \a + sourceFormat and \a sourceType. The pixel data upload can optionally be + controlled by \a options. +*/ +void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + CubeMapFace face, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + Q_D(QOpenGLTexture); + Q_ASSERT(d->textureId); + d->setData(xOffset, yOffset, zOffset, + width, height, depth, + mipLevel, layer, 1, + face, sourceFormat, + sourceType, data, options); +} + +/*! + \since 5.14 + \overload + + This overload is to be used to update a part of the texture. Parameters \a + xOffset, \a yOffset, \a zOffset specify the texel offsets within the + texture. Parameters \a width, \a height and \a depth specify the dimensions + of the sub image.The mip map level, starting layer, cube map face and + number of layers of the sub image we want to update are specified with \a + mipLevel, \a layer, \a face and \a layerCount. + + The structure of the pixel data pointed to by \a data is specified by \a + sourceFormat and \a sourceType. The pixel data upload can optionally be + controlled by \a options. +*/ +void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + CubeMapFace face, int layerCount, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options) +{ + Q_D(QOpenGLTexture); + Q_ASSERT(d->textureId); + d->setData(xOffset, yOffset, zOffset, + width, height, depth, + mipLevel, layer, layerCount, + face, sourceFormat, + sourceType, data, options); +} + #if QT_DEPRECATED_SINCE(5, 3) /*! \obsolete diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h index c0c5283374..7d984babc8 100644 --- a/src/gui/opengl/qopengltexture.h +++ b/src/gui/opengl/qopengltexture.h @@ -485,6 +485,32 @@ public: void setData(PixelFormat sourceFormat, PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, int mipLevel, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + CubeMapFace cubeFace, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + void setData(int xOffset, int yOffset, int zOffset, + int width, int height, int depth, + int mipLevel, int layer, + CubeMapFace cubeFace, int layerCount, + PixelFormat sourceFormat, PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options = nullptr); + // Compressed data upload // ### Qt 6: remove the non-const void * overloads #if QT_DEPRECATED_SINCE(5, 3) diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h index f7694f77bc..9f3457ad0a 100644 --- a/src/gui/opengl/qopengltexture_p.h +++ b/src/gui/opengl/qopengltexture_p.h @@ -101,6 +101,10 @@ public: void setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, const void *data, const QOpenGLPixelTransferOptions * const options); + void setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth, + int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, + QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType, + const void *data, const QOpenGLPixelTransferOptions * const options); void setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace, int dataSize, const void *data, const QOpenGLPixelTransferOptions * const options); -- cgit v1.2.3