Provide some simple OpenGL primitives.
This commit is contained in:
parent
e6b736e718
commit
8b7aa44226
7 changed files with 228 additions and 9 deletions
|
|
@ -63,6 +63,8 @@ PRIVATE
|
||||||
ui/gl/gl_image.h
|
ui/gl/gl_image.h
|
||||||
ui/gl/gl_math.cpp
|
ui/gl/gl_math.cpp
|
||||||
ui/gl/gl_math.h
|
ui/gl/gl_math.h
|
||||||
|
ui/gl/gl_primitives.cpp
|
||||||
|
ui/gl/gl_primitives.h
|
||||||
ui/gl/gl_shader.cpp
|
ui/gl/gl_shader.cpp
|
||||||
ui/gl/gl_shader.h
|
ui/gl/gl_shader.h
|
||||||
ui/gl/gl_surface.cpp
|
ui/gl/gl_surface.cpp
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,13 @@ QSizeF Uniform(QSize size) {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect TransformRect(const Rect &raster, QSize viewport, float factor) {
|
||||||
|
return {
|
||||||
|
raster.left() * factor,
|
||||||
|
float(viewport.height() - raster.bottom()) * factor,
|
||||||
|
raster.width() * factor,
|
||||||
|
raster.height() * factor,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Ui::GL
|
} // namespace Ui::GL
|
||||||
|
|
|
||||||
|
|
@ -76,4 +76,9 @@ private:
|
||||||
[[nodiscard]] QVector4D Uniform(const QColor &color);
|
[[nodiscard]] QVector4D Uniform(const QColor &color);
|
||||||
[[nodiscard]] QSizeF Uniform(QSize size);
|
[[nodiscard]] QSizeF Uniform(QSize size);
|
||||||
|
|
||||||
|
[[nodiscard]] Rect TransformRect(
|
||||||
|
const Rect &raster,
|
||||||
|
QSize viewport,
|
||||||
|
float factor);
|
||||||
|
|
||||||
} // namespace Ui::GL
|
} // namespace Ui::GL
|
||||||
|
|
|
||||||
148
ui/gl/gl_primitives.cpp
Normal file
148
ui/gl/gl_primitives.cpp
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
// 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_primitives.h"
|
||||||
|
|
||||||
|
#include "ui/gl/gl_shader.h"
|
||||||
|
#include "ui/style/style_core.h"
|
||||||
|
|
||||||
|
#include <QtGui/QOpenGLFunctions>
|
||||||
|
|
||||||
|
namespace Ui::GL {
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<float, GLfloat>);
|
||||||
|
|
||||||
|
void FillRectVertices(float *coords, Rect rect) {
|
||||||
|
coords[0] = coords[10] = rect.left();
|
||||||
|
coords[1] = coords[11] = rect.top();
|
||||||
|
coords[2] = rect.right();
|
||||||
|
coords[3] = rect.top();
|
||||||
|
coords[4] = coords[6] = rect.right();
|
||||||
|
coords[5] = coords[7] = rect.bottom();
|
||||||
|
coords[8] = rect.left();
|
||||||
|
coords[9] = rect.bottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillTriangles(
|
||||||
|
QOpenGLFunctions &f,
|
||||||
|
gsl::span<const float> coords,
|
||||||
|
not_null<QOpenGLBuffer*> buffer,
|
||||||
|
not_null<QOpenGLShaderProgram*> program,
|
||||||
|
QSize viewportWithFactor,
|
||||||
|
const QColor &color,
|
||||||
|
Fn<void()> additional) {
|
||||||
|
Expects(coords.size() % 6 == 0);
|
||||||
|
|
||||||
|
if (coords.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buffer->bind();
|
||||||
|
buffer->allocate(coords.data(), coords.size() * sizeof(GLfloat));
|
||||||
|
|
||||||
|
f.glUseProgram(program->programId());
|
||||||
|
program->setUniformValue("viewport", QSizeF(viewportWithFactor));
|
||||||
|
program->setUniformValue("s_color", Uniform(color));
|
||||||
|
|
||||||
|
GLint position = program->attributeLocation("position");
|
||||||
|
f.glVertexAttribPointer(
|
||||||
|
position,
|
||||||
|
2,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
2 * sizeof(GLfloat),
|
||||||
|
nullptr);
|
||||||
|
f.glEnableVertexAttribArray(position);
|
||||||
|
|
||||||
|
if (additional) {
|
||||||
|
additional();
|
||||||
|
}
|
||||||
|
|
||||||
|
f.glDrawArrays(GL_TRIANGLES, 0, coords.size() / 2);
|
||||||
|
|
||||||
|
f.glDisableVertexAttribArray(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillTexturedRectangle(
|
||||||
|
QOpenGLFunctions &f,
|
||||||
|
not_null<QOpenGLShaderProgram*> program,
|
||||||
|
int skipVertices) {
|
||||||
|
const auto shift = [&](int elements) {
|
||||||
|
return reinterpret_cast<const void*>(
|
||||||
|
(skipVertices * 4 + elements) * sizeof(GLfloat));
|
||||||
|
};
|
||||||
|
GLint position = program->attributeLocation("position");
|
||||||
|
f.glVertexAttribPointer(
|
||||||
|
position,
|
||||||
|
2,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
4 * sizeof(GLfloat),
|
||||||
|
shift(0));
|
||||||
|
f.glEnableVertexAttribArray(position);
|
||||||
|
|
||||||
|
GLint texcoord = program->attributeLocation("v_texcoordIn");
|
||||||
|
f.glVertexAttribPointer(
|
||||||
|
texcoord,
|
||||||
|
2,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
4 * sizeof(GLfloat),
|
||||||
|
shift(2));
|
||||||
|
f.glEnableVertexAttribArray(texcoord);
|
||||||
|
|
||||||
|
f.glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
|
||||||
|
f.glDisableVertexAttribArray(position);
|
||||||
|
f.glDisableVertexAttribArray(texcoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundFiller::init(QOpenGLFunctions &f) {
|
||||||
|
_bgBuffer.emplace();
|
||||||
|
_bgBuffer->setUsagePattern(QOpenGLBuffer::DynamicDraw);
|
||||||
|
_bgBuffer->create();
|
||||||
|
_bgProgram.emplace();
|
||||||
|
LinkProgram(
|
||||||
|
&*_bgProgram,
|
||||||
|
VertexShader({ VertexViewportTransform() }),
|
||||||
|
FragmentShader({ FragmentStaticColor() }));
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundFiller::deinit(QOpenGLFunctions &f) {
|
||||||
|
_bgProgram.reset();
|
||||||
|
_bgBuffer.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BackgroundFiller::fill(
|
||||||
|
QOpenGLFunctions &f,
|
||||||
|
const QRegion ®ion,
|
||||||
|
QSize viewport,
|
||||||
|
float factor,
|
||||||
|
const style::color &color) {
|
||||||
|
const auto &rgb = color->c.toRgb();
|
||||||
|
if (region.isEmpty()) {
|
||||||
|
return;
|
||||||
|
} else if (region.end() - region.begin() == 1
|
||||||
|
&& (*region.begin()).size() == viewport) {
|
||||||
|
f.glClearColor(rgb.redF(), rgb.greenF(), rgb.blueF(), rgb.alphaF());
|
||||||
|
f.glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_bgTriangles.resize((region.end() - region.begin()) * 12);
|
||||||
|
auto coords = _bgTriangles.data();
|
||||||
|
for (const auto rect : region) {
|
||||||
|
FillRectVertices(coords, TransformRect(rect, viewport, factor));
|
||||||
|
coords += 12;
|
||||||
|
}
|
||||||
|
FillTriangles(
|
||||||
|
f,
|
||||||
|
_bgTriangles,
|
||||||
|
&*_bgBuffer,
|
||||||
|
&*_bgProgram,
|
||||||
|
viewport * factor,
|
||||||
|
rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Ui::GL
|
||||||
54
ui/gl/gl_primitives.h
Normal file
54
ui/gl/gl_primitives.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/gl/gl_math.h"
|
||||||
|
#include "ui/style/style_core.h"
|
||||||
|
|
||||||
|
#include <QtGui/QOpenGLBuffer>
|
||||||
|
#include <QtGui/QOpenGLShaderProgram>
|
||||||
|
|
||||||
|
class QOpenGLFunctions;
|
||||||
|
|
||||||
|
namespace Ui::GL {
|
||||||
|
|
||||||
|
void FillRectVertices(float *coords, Rect rect);
|
||||||
|
|
||||||
|
void FillTriangles(
|
||||||
|
QOpenGLFunctions &f,
|
||||||
|
gsl::span<const float> coords,
|
||||||
|
not_null<QOpenGLBuffer*> buffer,
|
||||||
|
not_null<QOpenGLShaderProgram*> program,
|
||||||
|
QSize viewportWithFactor,
|
||||||
|
const QColor &color,
|
||||||
|
Fn<void()> additional = nullptr);
|
||||||
|
|
||||||
|
void FillTexturedRectangle(
|
||||||
|
QOpenGLFunctions &f,
|
||||||
|
not_null<QOpenGLShaderProgram*> program,
|
||||||
|
int skipVertices = 0);
|
||||||
|
|
||||||
|
class BackgroundFiller final {
|
||||||
|
public:
|
||||||
|
void init(QOpenGLFunctions &f);
|
||||||
|
void deinit(QOpenGLFunctions &);
|
||||||
|
|
||||||
|
void fill(
|
||||||
|
QOpenGLFunctions &f,
|
||||||
|
const QRegion ®ion,
|
||||||
|
QSize viewport,
|
||||||
|
float factor,
|
||||||
|
const style::color &color);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<QOpenGLBuffer> _bgBuffer;
|
||||||
|
std::optional<QOpenGLShaderProgram> _bgProgram;
|
||||||
|
std::vector<float> _bgTriangles;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Ui::GL
|
||||||
|
|
@ -126,18 +126,19 @@ void colorizeImage(const QImage &src, QColor c, QImage *outResult, QRect srcRect
|
||||||
outResult->setDevicePixelRatio(src.devicePixelRatio());
|
outResult->setDevicePixelRatio(src.devicePixelRatio());
|
||||||
}
|
}
|
||||||
|
|
||||||
QBrush transparentPlaceholderBrush() {
|
QImage TransparentPlaceholder() {
|
||||||
auto size = st::transparentPlaceholderSize * DevicePixelRatio();
|
const auto size = st::transparentPlaceholderSize * DevicePixelRatio();
|
||||||
auto transparent = QImage(2 * size, 2 * size, QImage::Format_ARGB32_Premultiplied);
|
auto result = QImage(
|
||||||
transparent.fill(st::mediaviewTransparentBg->c);
|
2 * size, 2 * size,
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
result.fill(st::mediaviewTransparentBg->c);
|
||||||
{
|
{
|
||||||
QPainter p(&transparent);
|
QPainter p(&result);
|
||||||
p.fillRect(0, size, size, size, st::mediaviewTransparentFg);
|
p.fillRect(0, size, size, size, st::mediaviewTransparentFg);
|
||||||
p.fillRect(size, 0, size, size, st::mediaviewTransparentFg);
|
p.fillRect(size, 0, size, size, st::mediaviewTransparentFg);
|
||||||
}
|
}
|
||||||
transparent.setDevicePixelRatio(DevicePixelRatio());
|
result.setDevicePixelRatio(DevicePixelRatio());
|
||||||
return QBrush(transparent);
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ inline QImage colorizeImage(const QImage &src, const color &c, QRect srcRect = Q
|
||||||
return colorizeImage(src, c->c, srcRect);
|
return colorizeImage(src, c->c, srcRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
QBrush transparentPlaceholderBrush();
|
[[nodiscard]] QImage TransparentPlaceholder();
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue