mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Manual rounding support in OpenGL media viewer.
This commit is contained in:
parent
b9e0c60adf
commit
24a1208b9a
7 changed files with 117 additions and 2 deletions
|
@ -46,6 +46,31 @@ uniform float transparentSize;
|
|||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] ShaderPart FragmentRoundedCorners() {
|
||||
return {
|
||||
.header = R"(
|
||||
uniform vec4 roundRect;
|
||||
uniform float roundRadius;
|
||||
|
||||
float roundedCorner() {
|
||||
vec2 rectHalf = roundRect.zw / 2.;
|
||||
vec2 rectCenter = roundRect.xy + rectHalf;
|
||||
vec2 fromRectCenter = abs(gl_FragCoord.xy - rectCenter);
|
||||
vec2 vectorRadius = vec2(roundRadius + 0.5, roundRadius + 0.5);
|
||||
vec2 fromCenterWithRadius = fromRectCenter + vectorRadius;
|
||||
vec2 fromRoundingCenter = max(fromCenterWithRadius, rectHalf)
|
||||
- rectHalf;
|
||||
float rounded = length(fromRoundingCenter) - roundRadius;
|
||||
|
||||
return 1. - smoothstep(0., 1., rounded);
|
||||
}
|
||||
)",
|
||||
.body = R"(
|
||||
result = vec4(roundedCorner());
|
||||
)",
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
OverlayWidget::RendererGL::RendererGL(not_null<OverlayWidget*> owner)
|
||||
|
@ -69,7 +94,10 @@ void OverlayWidget::RendererGL::init(
|
|||
constexpr auto kQuadVertices = kQuads * 4;
|
||||
constexpr auto kQuadValues = kQuadVertices * 4;
|
||||
constexpr auto kControlsValues = kControlsCount * kControlValues;
|
||||
constexpr auto kValues = kQuadValues + kControlsValues;
|
||||
constexpr auto kRoundingQuads = 4;
|
||||
constexpr auto kRoundingVertices = kRoundingQuads * 6;
|
||||
constexpr auto kRoundingValues = kRoundingVertices * 2;
|
||||
constexpr auto kValues = kQuadValues + kControlsValues + kRoundingValues;
|
||||
|
||||
_contentBuffer.emplace();
|
||||
_contentBuffer->setUsagePattern(QOpenGLBuffer::DynamicDraw);
|
||||
|
@ -130,6 +158,12 @@ void OverlayWidget::RendererGL::init(
|
|||
FragmentGlobalOpacity(),
|
||||
}));
|
||||
|
||||
_roundedCornersProgram.emplace();
|
||||
LinkProgram(
|
||||
&*_roundedCornersProgram,
|
||||
VertexShader({ VertexViewportTransform() }),
|
||||
FragmentShader({ FragmentRoundedCorners() }));
|
||||
|
||||
const auto renderer = reinterpret_cast<const char*>(
|
||||
f.glGetString(GL_RENDERER));
|
||||
CrashReports::SetAnnotation(
|
||||
|
@ -598,6 +632,76 @@ void OverlayWidget::RendererGL::paintGroupThumbs(
|
|||
}, kGroupThumbsOffset, true);
|
||||
}
|
||||
|
||||
void OverlayWidget::RendererGL::paintRoundedCorners(int radius) {
|
||||
const auto topLeft = transformRect(QRect(0, 0, radius, radius));
|
||||
const auto topRight = transformRect(
|
||||
QRect(_viewport.width() - radius, 0, radius, radius));
|
||||
const auto bottomRight = transformRect(QRect(
|
||||
_viewport.width() - radius,
|
||||
_viewport.height() - radius,
|
||||
radius,
|
||||
radius));
|
||||
const auto bottomLeft = transformRect(
|
||||
QRect(0, _viewport.height() - radius, radius, radius));
|
||||
const GLfloat coords[] = {
|
||||
topLeft.left(), topLeft.top(),
|
||||
topLeft.right(), topLeft.top(),
|
||||
topLeft.right(), topLeft.bottom(),
|
||||
topLeft.right(), topLeft.bottom(),
|
||||
topLeft.left(), topLeft.bottom(),
|
||||
topLeft.left(), topLeft.top(),
|
||||
|
||||
topRight.left(), topRight.top(),
|
||||
topRight.right(), topRight.top(),
|
||||
topRight.right(), topRight.bottom(),
|
||||
topRight.right(), topRight.bottom(),
|
||||
topRight.left(), topRight.bottom(),
|
||||
topRight.left(), topRight.top(),
|
||||
|
||||
bottomRight.left(), bottomRight.top(),
|
||||
bottomRight.right(), bottomRight.top(),
|
||||
bottomRight.right(), bottomRight.bottom(),
|
||||
bottomRight.right(), bottomRight.bottom(),
|
||||
bottomRight.left(), bottomRight.bottom(),
|
||||
bottomRight.left(), bottomRight.top(),
|
||||
|
||||
bottomLeft.left(), bottomLeft.top(),
|
||||
bottomLeft.right(), bottomLeft.top(),
|
||||
bottomLeft.right(), bottomLeft.bottom(),
|
||||
bottomLeft.right(), bottomLeft.bottom(),
|
||||
bottomLeft.left(), bottomLeft.bottom(),
|
||||
bottomLeft.left(), bottomLeft.top(),
|
||||
};
|
||||
const auto offset = kControlsOffset
|
||||
+ (kControlsCount * kControlValues) / 4;
|
||||
const auto byteOffset = offset * 4 * sizeof(GLfloat);
|
||||
_contentBuffer->write(byteOffset, coords, sizeof(coords));
|
||||
_roundedCornersProgram->bind();
|
||||
_roundedCornersProgram->setUniformValue("viewport", _uniformViewport);
|
||||
const auto roundRect = transformRect(QRect(QPoint(), _viewport));
|
||||
_roundedCornersProgram->setUniformValue("roundRect", Uniform(roundRect));
|
||||
_roundedCornersProgram->setUniformValue(
|
||||
"roundRadius",
|
||||
GLfloat(radius * _factor));
|
||||
|
||||
_f->glEnable(GL_BLEND);
|
||||
_f->glBlendFunc(GL_ZERO, GL_SRC_ALPHA);
|
||||
|
||||
GLint position = _roundedCornersProgram->attributeLocation("position");
|
||||
_f->glVertexAttribPointer(
|
||||
position,
|
||||
2,
|
||||
GL_FLOAT,
|
||||
GL_FALSE,
|
||||
2 * sizeof(GLfloat),
|
||||
reinterpret_cast<const void*>(byteOffset));
|
||||
_f->glEnableVertexAttribArray(position);
|
||||
|
||||
_f->glDrawArrays(GL_TRIANGLES, 0, base::array_size(coords) / 2);
|
||||
|
||||
_f->glDisableVertexAttribArray(position);
|
||||
}
|
||||
|
||||
void OverlayWidget::RendererGL::invalidate() {
|
||||
_trackFrameIndex = -1;
|
||||
_streamedIndex = -1;
|
||||
|
|
|
@ -68,6 +68,7 @@ private:
|
|||
void paintFooter(QRect outer, float64 opacity) override;
|
||||
void paintCaption(QRect outer, float64 opacity) override;
|
||||
void paintGroupThumbs(QRect outer, float64 opacity) override;
|
||||
void paintRoundedCorners(int radius) override;
|
||||
|
||||
void invalidate();
|
||||
|
||||
|
@ -110,6 +111,7 @@ private:
|
|||
std::optional<QOpenGLShaderProgram> _nv12Program;
|
||||
std::optional<QOpenGLShaderProgram> _fillProgram;
|
||||
std::optional<QOpenGLShaderProgram> _controlsProgram;
|
||||
std::optional<QOpenGLShaderProgram> _roundedCornersProgram;
|
||||
Ui::GL::Textures<4> _textures;
|
||||
QSize _rgbaSize;
|
||||
QSize _lumaSize;
|
||||
|
|
|
@ -190,4 +190,8 @@ void OverlayWidget::RendererSW::paintGroupThumbs(
|
|||
}
|
||||
}
|
||||
|
||||
void OverlayWidget::RendererSW::paintRoundedCorners(int radius) {
|
||||
// The RpWindow rounding overlay will do the job.
|
||||
}
|
||||
|
||||
} // namespace Media::View
|
||||
|
|
|
@ -50,6 +50,7 @@ private:
|
|||
void paintFooter(QRect outer, float64 opacity) override;
|
||||
void paintCaption(QRect outer, float64 opacity) override;
|
||||
void paintGroupThumbs(QRect outer, float64 opacity) override;
|
||||
void paintRoundedCorners(int radius) override;
|
||||
|
||||
[[nodiscard]] static QRect TransformRect(QRectF geometry, int rotation);
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
virtual void paintFooter(QRect outer, float64 opacity) = 0;
|
||||
virtual void paintCaption(QRect outer, float64 opacity) = 0;
|
||||
virtual void paintGroupThumbs(QRect outer, float64 opacity) = 0;
|
||||
virtual void paintRoundedCorners(int radius) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -3692,6 +3692,9 @@ void OverlayWidget::paint(not_null<Renderer*> renderer) {
|
|||
}
|
||||
}
|
||||
checkGroupThumbsAnimation();
|
||||
if (const auto radius = _window->manualRoundingRadius()) {
|
||||
renderer->paintRoundedCorners(radius);
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayWidget::checkGroupThumbsAnimation() {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit eb4d44ecd37815dc9465ec46b86f94191531b0c7
|
||||
Subproject commit 3b69ec499ccc7f4208a6413fbeb6f5ebe84f3f55
|
Loading…
Add table
Reference in a new issue