Active speaker + Round corners (OpenGL)
This commit is contained in:
parent
d70b08c36e
commit
2b1a1525e5
10 changed files with 82 additions and 32 deletions
|
|
@ -46,6 +46,7 @@ ParticipantDeviceCore::ParticipantDeviceCore(const std::shared_ptr<linphone::Par
|
||||||
mAddress = Utils::coreStringToAppString(device->getAddress()->asStringUriOnly());
|
mAddress = Utils::coreStringToAppString(device->getAddress()->asStringUriOnly());
|
||||||
mIsMuted = device->getIsMuted();
|
mIsMuted = device->getIsMuted();
|
||||||
mIsMe = isMe;
|
mIsMe = isMe;
|
||||||
|
mIsSpeaking = device->getIsSpeaking();
|
||||||
mParticipantDeviceModel = Utils::makeQObject_ptr<ParticipantDeviceModel>(device);
|
mParticipantDeviceModel = Utils::makeQObject_ptr<ParticipantDeviceModel>(device);
|
||||||
mParticipantDeviceModel->setSelf(mParticipantDeviceModel);
|
mParticipantDeviceModel->setSelf(mParticipantDeviceModel);
|
||||||
mState = LinphoneEnums::fromLinphone(device->getState());
|
mState = LinphoneEnums::fromLinphone(device->getState());
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc
|
list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc
|
||||||
data/assistant/create-app-sip-account.rc
|
data/assistant/create-app-sip-account.rc
|
||||||
data/assistant/use-other-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
|
data/shaders/roundEffect.frag.qsb
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
16
Linphone/data/shaders/opacityMask.frag
Normal file
16
Linphone/data/shaders/opacityMask.frag
Normal 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;
|
||||||
|
}
|
||||||
BIN
Linphone/data/shaders/opacityMask.frag.qsb
Normal file
BIN
Linphone/data/shaders/opacityMask.frag.qsb
Normal file
Binary file not shown.
|
|
@ -1,18 +1,43 @@
|
||||||
#version 440
|
#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(location = 0) out vec4 fragColor;
|
||||||
layout(std140, binding = 0) uniform buf {
|
layout(std140, binding = 0) uniform buf {
|
||||||
mat4 qt_Matrix;
|
mat4 qt_Matrix;
|
||||||
float qt_Opacity;
|
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;
|
layout(binding = 1) uniform sampler2D src;
|
||||||
|
|
||||||
void main() {
|
float roundedBoxSDF(vec2 position, vec2 offset, float radius) {
|
||||||
float dist = distance(coord, vec2( 0.5 ));
|
return length(max(abs(position)-offset+radius,0.0))-radius;
|
||||||
float delta = fwidth(dist);
|
}
|
||||||
float alpha = smoothstep( mix(clamp(edge, 0.0, 1.0), 0.0, 0.5) - delta, 0.5, dist );
|
|
||||||
|
void main(){
|
||||||
vec4 tex = texture(src, coord);
|
vec2 size = vec2(ubuf.width, ubuf.height);
|
||||||
fragColor = mix( tex, vec4(0.0), alpha) * qt_Opacity;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -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;
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
|
@ -124,7 +124,6 @@ StackView {
|
||||||
id: avatarItem
|
id: avatarItem
|
||||||
height: mainItem.height
|
height: mainItem.height
|
||||||
width: height
|
width: height
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: image
|
id: image
|
||||||
visible: false
|
visible: false
|
||||||
|
|
@ -135,16 +134,20 @@ StackView {
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
source: mainItem.account && mainItem.account.core.pictureUri
|
source: mainItem.account && mainItem.account.core.pictureUri
|
||||||
|| mainItem.contact && mainItem.contact.core.pictureUri
|
|| mainItem.contact && mainItem.contact.core.pictureUri
|
||||||
|| computedAvatarUri
|
|| computedAvatarUri
|
||||||
mipmap: true
|
mipmap: true
|
||||||
|
layer.enabled: true
|
||||||
}
|
}
|
||||||
ShaderEffect {
|
ShaderEffect {
|
||||||
id: roundEffect
|
id: roundEffect
|
||||||
property variant src: image
|
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
|
anchors.fill: parent
|
||||||
vertexShader: 'qrc:/data/shaders/roundEffect.vert.qsb'
|
|
||||||
fragmentShader: 'qrc:/data/shaders/roundEffect.frag.qsb'
|
fragmentShader: 'qrc:/data/shaders/roundEffect.frag.qsb'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ Item {
|
||||||
property AccountGui account: null
|
property AccountGui account: null
|
||||||
property ParticipantDeviceGui participantDevice: null
|
property ParticipantDeviceGui participantDevice: null
|
||||||
property bool previewEnabled: false
|
property bool previewEnabled: false
|
||||||
|
property bool displayBorder : participantDevice && participantDevice.core.isSpeaking || false
|
||||||
property color color: DefaultStyle.grey_600
|
property color color: DefaultStyle.grey_600
|
||||||
property int radius: 15 * DefaultStyle.dp
|
property int radius: 15 * DefaultStyle.dp
|
||||||
property var peerAddressObj: participantDevice && participantDevice.core
|
property var peerAddressObj: participantDevice && participantDevice.core
|
||||||
|
|
@ -32,10 +33,13 @@ Item {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: background
|
id: background
|
||||||
color: mainItem.color
|
color: noCameraLayout.visible ? mainItem.color : 'transparent'
|
||||||
radius: mainItem.radius
|
radius: mainItem.radius
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
border.color: DefaultStyle.main2_200
|
||||||
|
border.width: mainItem.displayBorder ? 3 * DefaultStyle.dp : 0
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
id: noCameraLayout
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
visible: !cameraLoader.active || cameraLoader.status != Loader.Ready || !cameraLoader.item.isReady
|
visible: !cameraLoader.active || cameraLoader.status != Loader.Ready || !cameraLoader.item.isReady
|
||||||
Avatar{
|
Avatar{
|
||||||
|
|
@ -85,11 +89,11 @@ Item {
|
||||||
Item {
|
Item {
|
||||||
height: cameraLoader.height
|
height: cameraLoader.height
|
||||||
width: cameraLoader.width
|
width: cameraLoader.width
|
||||||
property bool isReady: cameraItem.visible
|
property alias isReady: cameraItem.isReady
|
||||||
CameraGui{
|
CameraGui{
|
||||||
id: cameraItem
|
id: cameraItem
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: isReady
|
visible: false
|
||||||
call: mainItem.call
|
call: mainItem.call
|
||||||
participantDevice: mainItem.participantDevice
|
participantDevice: mainItem.participantDevice
|
||||||
isPreview: mainItem.previewEnabled
|
isPreview: mainItem.previewEnabled
|
||||||
|
|
@ -98,6 +102,20 @@ Item {
|
||||||
console.log("Request new renderer")
|
console.log("Request new renderer")
|
||||||
resetTimer.restart()
|
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'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue