Fix Image::texturedRect() before Image::bind().

This commit is contained in:
John Preston 2021-06-15 16:47:06 +04:00
parent 27e9e349bf
commit 4837b47623
2 changed files with 22 additions and 21 deletions

View file

@ -51,8 +51,12 @@ void DestroyFramebuffers(QOpenGLFunctions &f, gsl::span<GLuint> values) {
} // namespace details } // namespace details
void Image::setImage(QImage image) { void Image::setImage(QImage image, QSize subimage) {
Expects(subimage.width() <= image.width()
&& subimage.height() <= image.height());
_image = std::move(image); _image = std::move(image);
_subimage = subimage.isValid() ? subimage : _image.size();
} }
const QImage &Image::image() const { const QImage &Image::image() const {
@ -67,17 +71,10 @@ void Image::invalidate() {
_storage = base::take(_image); _storage = base::take(_image);
} }
void Image::bind(QOpenGLFunctions &f, QSize subimage) { void Image::bind(QOpenGLFunctions &f) {
Expects(!_image.isNull());
Expects(subimage.width() <= _image.width()
&& subimage.height() <= _image.height());
_textures.ensureCreated(f, GL_NEAREST); _textures.ensureCreated(f, GL_NEAREST);
if (!subimage.isValid()) { if (_subimage.isEmpty()) {
subimage = _image.size(); _textureSize = _subimage;
}
if (subimage.isEmpty()) {
_textureSize = subimage;
return; return;
} }
const auto cacheKey = _image.cacheKey(); const auto cacheKey = _image.cacheKey();
@ -88,15 +85,15 @@ void Image::bind(QOpenGLFunctions &f, QSize subimage) {
_textures.bind(f, 0); _textures.bind(f, 0);
if (upload) { if (upload) {
f.glPixelStorei(GL_UNPACK_ROW_LENGTH, _image.bytesPerLine() / 4); f.glPixelStorei(GL_UNPACK_ROW_LENGTH, _image.bytesPerLine() / 4);
if (_textureSize.width() < subimage.width() if (_textureSize.width() < _subimage.width()
|| _textureSize.height() < subimage.height()) { || _textureSize.height() < _subimage.height()) {
_textureSize = subimage; _textureSize = _subimage;
f.glTexImage2D( f.glTexImage2D(
GL_TEXTURE_2D, GL_TEXTURE_2D,
0, 0,
GL_RGBA, GL_RGBA,
subimage.width(), _subimage.width(),
subimage.height(), _subimage.height(),
0, 0,
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
@ -107,8 +104,8 @@ void Image::bind(QOpenGLFunctions &f, QSize subimage) {
0, 0,
0, 0,
0, 0,
subimage.width(), _subimage.width(),
subimage.height(), _subimage.height(),
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
_image.constBits()); _image.constBits());
@ -144,7 +141,10 @@ 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(_textureSize); const auto dimensions = QSizeF((_textureSize.width() < _subimage.width()
|| _textureSize.height() < _subimage.height())
? _subimage
: _textureSize);
return { return {
.geometry = Rect(visible), .geometry = Rect(visible),
.texture = Rect(QRectF( .texture = Rect(QRectF(

View file

@ -107,12 +107,12 @@ struct TexturedRect {
class Image final { class Image final {
public: public:
void setImage(QImage image); void setImage(QImage image, QSize subimage = QSize());
[[nodiscard]] const QImage &image() const; [[nodiscard]] const QImage &image() const;
[[nodiscard]] QImage takeImage(); [[nodiscard]] QImage takeImage();
void invalidate(); void invalidate();
void bind(QOpenGLFunctions &f, QSize subimage = QSize()); void bind(QOpenGLFunctions &f);
void destroy(QOpenGLFunctions &f); void destroy(QOpenGLFunctions &f);
[[nodiscard]] TexturedRect texturedRect( [[nodiscard]] TexturedRect texturedRect(
@ -129,6 +129,7 @@ private:
QImage _storage; QImage _storage;
Textures<1> _textures; Textures<1> _textures;
qint64 _cacheKey = 0; qint64 _cacheKey = 0;
QSize _subimage;
QSize _textureSize; QSize _textureSize;
}; };