Active speaker + Round corners (OpenGL)

This commit is contained in:
Julien Wadel 2024-03-28 10:38:21 +01:00
parent d70b08c36e
commit 2b1a1525e5
10 changed files with 82 additions and 32 deletions

View file

@ -46,6 +46,7 @@ ParticipantDeviceCore::ParticipantDeviceCore(const std::shared_ptr<linphone::Par
mAddress = Utils::coreStringToAppString(device->getAddress()->asStringUriOnly());
mIsMuted = device->getIsMuted();
mIsMe = isMe;
mIsSpeaking = device->getIsSpeaking();
mParticipantDeviceModel = Utils::makeQObject_ptr<ParticipantDeviceModel>(device);
mParticipantDeviceModel->setSelf(mParticipantDeviceModel);
mState = LinphoneEnums::fromLinphone(device->getState());

View file

@ -1,7 +1,7 @@
list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc
data/assistant/create-app-sip-account.rc
data/assistant/use-other-sip-account.rc
data/shaders/roundEffect.vert.qsb
data/shaders/opacityMask.frag.qsb
data/shaders/roundEffect.frag.qsb
)

View file

@ -0,0 +1,16 @@
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
};
layout(binding = 1) uniform sampler2D source;
layout(binding = 2) uniform sampler2D maskSource;
void main() {
fragColor = texture(source, qt_TexCoord0.st) * (texture(maskSource, qt_TexCoord0.st).a) * qt_Opacity;
}

Binary file not shown.

View file

@ -1,18 +1,43 @@
#version 440
layout(location = 0) in vec2 coord;
//qsb --glsl "100 es,120,150" --hlsl 50 --msl 12 -o roundEffect.frag.qsb roundEffect.frag
// qt_TexCoord0 E [0.0 , 1.0]
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
float edge;
};
// How soft the edges should be (in pixels). Higher values could be used to simulate a drop shadow. = 1.0
float edgeSoftness;
// The radius of the corners (in pixels).
float radius;
// Apply a drop shadow effect. = 0.5
float shadowSoftness;
// Drop shadow offset. = 0.5
float shadowOffset;
float width;
float height;
} ubuf;
layout(binding = 1) uniform sampler2D src;
void main() {
float dist = distance(coord, vec2( 0.5 ));
float delta = fwidth(dist);
float alpha = smoothstep( mix(clamp(edge, 0.0, 1.0), 0.0, 0.5) - delta, 0.5, dist );
vec4 tex = texture(src, coord);
fragColor = mix( tex, vec4(0.0), alpha) * qt_Opacity;
float roundedBoxSDF(vec2 position, vec2 offset, float radius) {
return length(max(abs(position)-offset+radius,0.0))-radius;
}
void main(){
vec2 size = vec2(ubuf.width, ubuf.height);
vec2 center = vec2(0.5);
// Calculate distance to edge.
float dist = roundedBoxSDF( (qt_TexCoord0.xy - center) * size, size/2.0 - 1.0, ubuf.radius);
float smoothedAlpha = max(1.0 - smoothstep(-ubuf.edgeSoftness, ubuf.edgeSoftness * 2.0, dist), 0);
// Return the resultant shape.
vec4 tex = texture(src, qt_TexCoord0.st);
vec4 quadColor = mix(vec4(0.0, 0.0, 0.0, 0.0), vec4(tex.rgb, smoothedAlpha), smoothedAlpha);
// Apply a drop shadow effect.
vec2 shadowOffset = vec2(0.0, ubuf.shadowOffset);
float shadowDistance = roundedBoxSDF((qt_TexCoord0.xy - center) * size, size/2.0, ubuf.radius);
float shadowAlpha = 1.0 - smoothstep(-1.0, ubuf.shadowSoftness, shadowDistance);
vec4 shadowColor = vec4(0.4, 0.4, 0.4, 1.0);
fragColor = mix(quadColor, shadowColor, shadowAlpha - smoothedAlpha) * ubuf.qt_Opacity;
}

View file

@ -1,13 +0,0 @@
#version 440
layout(location = 0) in vec4 qt_Vertex;
layout(location = 1) in vec2 qt_MultiTextCoord0;
layout(location = 0) out vec2 coord;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
};
void main() {
coord = qt_MultiTextCoord0;
gl_Position = qt_Matrix * qt_Vertex;
}

View file

@ -124,7 +124,6 @@ StackView {
id: avatarItem
height: mainItem.height
width: height
Image {
id: image
visible: false
@ -135,16 +134,20 @@ StackView {
fillMode: Image.PreserveAspectCrop
anchors.centerIn: parent
source: mainItem.account && mainItem.account.core.pictureUri
|| mainItem.contact && mainItem.contact.core.pictureUri
|| computedAvatarUri
|| mainItem.contact && mainItem.contact.core.pictureUri
|| computedAvatarUri
mipmap: true
layer.enabled: true
}
ShaderEffect {
id: roundEffect
property variant src: image
property double edge: 0.9
property real edge: 0.9
property real edgeSoftness: 0.9
property real radius: width / 2.0
property real shadowSoftness: 0.5
property real shadowOffset: 0.01
anchors.fill: parent
vertexShader: 'qrc:/data/shaders/roundEffect.vert.qsb'
fragmentShader: 'qrc:/data/shaders/roundEffect.frag.qsb'
}
}

View file

@ -18,6 +18,7 @@ Item {
property AccountGui account: null
property ParticipantDeviceGui participantDevice: null
property bool previewEnabled: false
property bool displayBorder : participantDevice && participantDevice.core.isSpeaking || false
property color color: DefaultStyle.grey_600
property int radius: 15 * DefaultStyle.dp
property var peerAddressObj: participantDevice && participantDevice.core
@ -32,10 +33,13 @@ Item {
Rectangle {
id: background
color: mainItem.color
color: noCameraLayout.visible ? mainItem.color : 'transparent'
radius: mainItem.radius
anchors.fill: parent
border.color: DefaultStyle.main2_200
border.width: mainItem.displayBorder ? 3 * DefaultStyle.dp : 0
ColumnLayout {
id: noCameraLayout
anchors.centerIn: parent
visible: !cameraLoader.active || cameraLoader.status != Loader.Ready || !cameraLoader.item.isReady
Avatar{
@ -85,11 +89,11 @@ Item {
Item {
height: cameraLoader.height
width: cameraLoader.width
property bool isReady: cameraItem.visible
property alias isReady: cameraItem.isReady
CameraGui{
id: cameraItem
anchors.fill: parent
visible: isReady
visible: false
call: mainItem.call
participantDevice: mainItem.participantDevice
isPreview: mainItem.previewEnabled
@ -98,6 +102,20 @@ Item {
console.log("Request new renderer")
resetTimer.restart()
}
layer.enabled: true
}
ShaderEffect {
id: roundEffect
property variant src: cameraItem
property real edge: 0.9
property real edgeSoftness: 0.9
property real radius: mainItem.radius
property real shadowSoftness: 0.5
property real shadowOffset: 0.01
anchors.fill: parent
visible: cameraItem.isReady
fragmentShader: 'qrc:/data/shaders/roundEffect.frag.qsb'
}
}
}