Support sub-image updating in Ui::GL::Image.

This commit is contained in:
John Preston 2021-06-03 11:07:21 +04:00
parent 8b7aa44226
commit 0df1579d4a
2 changed files with 40 additions and 18 deletions

View file

@ -63,30 +63,52 @@ void Image::invalidate() {
_storage = base::take(_image); _storage = base::take(_image);
} }
void Image::bind(QOpenGLFunctions &f) { void Image::bind(QOpenGLFunctions &f, QSize subimage) {
Expects(!_image.isNull()); Expects(!_image.isNull());
Expects(subimage.width() <= _image.width()
&& subimage.height() <= _image.height());
_textures.ensureCreated(f); _textures.ensureCreated(f);
if (subimage.isNull()) {
subimage = _image.size();
}
if (subimage.isEmpty()) {
_textureSize = subimage;
return;
}
const auto cacheKey = _image.cacheKey(); const auto cacheKey = _image.cacheKey();
const auto upload = (_cacheKey != cacheKey); const auto upload = (_cacheKey != cacheKey);
if (upload) { if (upload) {
_cacheKey = cacheKey; _cacheKey = cacheKey;
_index = 1 - _index;
} }
_textures.bind(f, _index); _textures.bind(f, 0);
const auto error = f.glGetError();
if (upload) { if (upload) {
f.glPixelStorei(GL_UNPACK_ROW_LENGTH, _image.bytesPerLine() / 4); f.glPixelStorei(GL_UNPACK_ROW_LENGTH, _image.bytesPerLine() / 4);
f.glTexImage2D( if (_textureSize.width() < subimage.width()
GL_TEXTURE_2D, || _textureSize.height() < subimage.height()) {
0, _textureSize = subimage;
GL_RGBA, f.glTexImage2D(
_image.width(), GL_TEXTURE_2D,
_image.height(), 0,
0, GL_RGBA,
GL_RGBA, subimage.width(),
GL_UNSIGNED_BYTE, subimage.height(),
_image.constBits()); 0,
GL_RGBA,
GL_UNSIGNED_BYTE,
_image.constBits());
} else {
f.glTexSubImage2D(
GL_TEXTURE_2D,
0,
0,
0,
subimage.width(),
subimage.height(),
GL_RGBA,
GL_UNSIGNED_BYTE,
_image.constBits());
}
f.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); f.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} }
} }
@ -112,7 +134,7 @@ TexturedRect Image::texturedRect(
texture.y() + (visible.y() - geometry.y()) * yFactor, texture.y() + (visible.y() - geometry.y()) * yFactor,
visible.width() * xFactor, visible.width() * xFactor,
visible.height() * yFactor); visible.height() * yFactor);
const auto dimensions = QSizeF(_image.size()); const auto dimensions = QSizeF(_textureSize);
return { return {
.geometry = Rect(visible), .geometry = Rect(visible),
.texture = Rect(QRectF( .texture = Rect(QRectF(

View file

@ -101,7 +101,7 @@ public:
[[nodiscard]] QImage takeImage(); [[nodiscard]] QImage takeImage();
void invalidate(); void invalidate();
void bind(QOpenGLFunctions &f); void bind(QOpenGLFunctions &f, QSize subimage = QSize());
void destroy(QOpenGLFunctions &f); void destroy(QOpenGLFunctions &f);
[[nodiscard]] TexturedRect texturedRect( [[nodiscard]] TexturedRect texturedRect(
@ -116,9 +116,9 @@ public:
private: private:
QImage _image; QImage _image;
QImage _storage; QImage _storage;
Textures<2> _textures; Textures<1> _textures;
qint64 _cacheKey = 0; qint64 _cacheKey = 0;
int _index = 0; QSize _textureSize;
}; };