| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // This file is part of Desktop App Toolkit,
- // a set of libraries for developing nice desktop applications.
- //
- // For license and copyright information please follow this link:
- // https://github.com/desktop-app/legal/blob/master/LEGAL
- //
- #include "ui/gl/gl_image.h"
- #include <QtGui/QOpenGLFunctions>
- namespace Ui::GL {
- namespace details {
- void GenerateTextures(
- QOpenGLFunctions &f,
- gsl::span<GLuint> values,
- GLint filter,
- GLint clamp) {
- Expects(!values.empty());
- f.glGenTextures(values.size(), values.data());
- for (const auto texture : values) {
- f.glBindTexture(GL_TEXTURE_2D, texture);
- f.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
- f.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
- f.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- f.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- }
- }
- void DestroyTextures(QOpenGLFunctions *f, gsl::span<GLuint> values) {
- Expects(!values.empty());
- if (f) {
- f->glDeleteTextures(values.size(), values.data());
- }
- ranges::fill(values, 0);
- }
- void GenerateFramebuffers(QOpenGLFunctions &f, gsl::span<GLuint> values) {
- Expects(!values.empty());
- f.glGenFramebuffers(values.size(), values.data());
- }
- void DestroyFramebuffers(QOpenGLFunctions *f, gsl::span<GLuint> values) {
- Expects(!values.empty());
- if (f) {
- f->glDeleteTextures(values.size(), values.data());
- }
- ranges::fill(values, 0);
- }
- } // namespace details
- void Image::setImage(QImage image, QSize subimage) {
- Expects(subimage.width() <= image.width()
- && subimage.height() <= image.height());
- _image = std::move(image);
- _subimage = subimage.isValid() ? subimage : _image.size();
- }
- const QImage &Image::image() const {
- return _image;
- }
- QImage Image::takeImage() {
- return _image.isNull() ? base::take(_storage) : base::take(_image);
- }
- void Image::invalidate() {
- _storage = base::take(_image);
- _subimage = QSize();
- }
- void Image::bind(QOpenGLFunctions &f) {
- _textures.ensureCreated(f, GL_NEAREST);
- if (_subimage.isEmpty()) {
- _textureSize = _subimage;
- return;
- }
- const auto cacheKey = _image.cacheKey();
- const auto upload = (_cacheKey != cacheKey);
- if (upload) {
- _cacheKey = cacheKey;
- }
- _textures.bind(f, 0);
- if (upload) {
- f.glPixelStorei(GL_UNPACK_ROW_LENGTH, _image.bytesPerLine() / 4);
- if (_textureSize.width() < _subimage.width()
- || _textureSize.height() < _subimage.height()) {
- _textureSize = _subimage;
- f.glTexImage2D(
- GL_TEXTURE_2D,
- 0,
- kFormatRGBA,
- _subimage.width(),
- _subimage.height(),
- 0,
- kFormatRGBA,
- GL_UNSIGNED_BYTE,
- _image.constBits());
- } else {
- f.glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- 0,
- 0,
- _subimage.width(),
- _subimage.height(),
- kFormatRGBA,
- GL_UNSIGNED_BYTE,
- _image.constBits());
- }
- f.glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- }
- }
- void Image::destroy(QOpenGLFunctions *f) {
- invalidate();
- _textures.destroy(f);
- _cacheKey = 0;
- _textureSize = QSize();
- }
- TexturedRect Image::texturedRect(
- const QRect &geometry,
- const QRect &texture,
- const QRect &clip) {
- Expects(!_image.isNull());
- const auto visible = clip.isNull()
- ? geometry
- : clip.intersected(geometry);
- if (visible.isEmpty()) {
- return TexturedRect{
- .geometry = Rect(visible),
- .texture = Rect(0., 0., 0., 0.),
- };
- }
- const auto xFactor = texture.width() / geometry.width();
- const auto yFactor = texture.height() / geometry.height();
- const auto usedTexture = QRect(
- texture.x() + (visible.x() - geometry.x()) * xFactor,
- texture.y() + (visible.y() - geometry.y()) * yFactor,
- visible.width() * xFactor,
- visible.height() * yFactor);
- const auto dimensions = QSizeF((_textureSize.width() < _subimage.width()
- || _textureSize.height() < _subimage.height())
- ? _subimage
- : _textureSize);
- return {
- .geometry = Rect(visible),
- .texture = Rect(QRectF(
- usedTexture.x() / dimensions.width(),
- usedTexture.y() / dimensions.height(),
- usedTexture.width() / dimensions.width(),
- usedTexture.height() / dimensions.height())),
- };
- }
- } // namespace Ui::GL
|