Skip to content
Snippets Groups Projects
Commit b2dc6b0d authored by samuel's avatar samuel
Browse files

use ShaderEffect

parent dd82b734
No related branches found
No related tags found
No related merge requests found
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.5)
project(plasma-luna3)
......@@ -7,4 +7,6 @@ set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR})
find_package(KF6Plasma REQUIRED)
add_custom_command(OUTPUT shadow.gsb COMMAND "/usr/lib/qt6/bin/qsb package/contents/ui/shadow.frag --qt6 -o shadow.gsb")
plasma_install_package(package org.kde.userbase.plasma.luna3)
......@@ -21,8 +21,8 @@
*/
import Qt5Compat.GraphicalEffects
import QtQuick 2.1
import QtQuick 2.14
import QtQuick.Shapes
import org.kde.ksvg as KSvg
import org.kde.plasma.core as PlasmaCore
import org.kde.plasma.plasmoid
......@@ -45,177 +45,241 @@ Item {
Item {
id: lunaBackground
visible: false
anchors.centerIn: parent
width: Math.min(parent.width, parent.height)
height: Math.min(parent.width, parent.height)
visible: false
}
KSvg.SvgItem {
id: lunaSvgItem
Item {
id: lunaTexture
imagePath: lunarImage === '' ? '' : Qt.resolvedUrl("../data/" + lunarImage)
visible: false
anchors.centerIn: parent
width: lunaBackground.width
height: lunaBackground.height
// Rotation to compensate the moon's image basic position to a north pole view
transformOrigin: Item.Center
rotation: -lunarImageTweak
}
Canvas {
id: lunaCanvas
visible: false
layer.enabled: true
layer.smooth: true
property string lunarImage: lunaIcon.lunarImage
property string diskColor: lunaIcon.diskColor
KSvg.SvgItem {
id: lunaSvgItem
width: lunaBackground.width
height: lunaBackground.height
visible: false
anchors.centerIn: parent
contextType: "2d"
onLunarImageChanged: requestPaint()
onDiskColorChanged: requestPaint()
onPaint: {
var radius = Math.floor(height / 2);
context.reset();
context.globalAlpha = (lunarImage === '') ? 1 : 0;
context.fillStyle = diskColor;
context.translate(radius, radius);
context.beginPath();
context.arc(0, 0, radius, 0, 2 * Math.PI);
context.closePath();
context.fill();
imagePath: lunarImage === '' ? '' : Qt.resolvedUrl("../data/" + lunarImage)
visible: true
anchors.centerIn: parent
width: lunaBackground.width
height: lunaBackground.height
// Rotation to compensate the moon's image basic position to a north pole view
transformOrigin: Item.Center
rotation: latitude - 90 - lunarImageTweak
}
}
Canvas {
id: shadow
Shape {
id: lunaCanvas
property int latitude: lunaIcon.latitude
property int theta: lunaIcon.theta
property bool showShadow: lunaIcon.showShadow
property bool showGrid: lunaIcon.showGrid
property bool showTycho: lunaIcon.showTycho
property bool showCopernicus: lunaIcon.showCopernicus
property string lunarImage: lunaIcon.lunarImage
property string diskColor: lunaIcon.diskColor
function radians(deg) {
return deg / 180 * Math.PI;
}
opacity: (lunarImage === '') ? 1 : 0
width: lunaBackground.width
height: lunaBackground.height
visible: true
anchors.centerIn: parent
preferredRendererType: Shape.CurveRenderer
function marker(radius, latitude, longitude) {
var dy = radius * Math.sin(radians(latitude));
var dx = radius * Math.cos(radians(latitude)) * Math.sin(radians(longitude));
// console.log("dx: " + dx.toString());
// console.log("dy: " + dy.toString());
context.beginPath();
context.strokeStyle = "#FF0000";
context.arc(dx, -dy, 5, 0, 2 * Math.PI);
context.moveTo(dx - 5, -dy - 5);
context.lineTo(dx + 5, -dy + 5);
context.moveTo(dx - 5, -dy + 5);
context.lineTo(dx + 5, -dy - 5);
context.stroke();
}
ShapePath {
fillColor: diskColor
strokeWidth: -1 //no stroke
PathAngleArc {
property int radius: Math.floor(height / 2)
centerX: radius
centerY: radius
radiusY: radius
radiusX: radius
startAngle: 0
sweepAngle: 360
}
function grid(radius) {
context.beginPath();
context.strokeStyle = "#FF4040";
context.moveTo(0, -radius);
context.lineTo(0, radius);
context.moveTo(-radius, 0);
context.lineTo(radius, 0);
context.stroke();
context.beginPath();
context.strokeStyle = "#40FF40";
for (var ll = 10; ll < 65; ll += 10) {
var dy = radius * Math.sin(radians(ll));
context.moveTo(-radius, dy);
context.lineTo(radius, dy);
context.moveTo(-radius, -dy);
context.lineTo(radius, -dy);
}
context.stroke();
}
width: lunaBackground.width
height: lunaBackground.height
visible: false
anchors.centerIn: parent
contextType: "2d"
onLatitudeChanged: requestPaint()
onThetaChanged: requestPaint()
onShowGridChanged: requestPaint()
onShowTychoChanged: requestPaint()
onShowCopernicusChanged: requestPaint()
onShowShadowChanged: requestPaint()
onPaint: {
var radius = Math.floor(height / 2);
var cosTheta = Math.cos(theta / 180 * Math.PI);
var counterclockwisep = (theta < 180);
context.reset();
context.globalAlpha = 0.9;
context.translate(radius, radius);
if (showShadow) {
if (theta != 180) {
context.beginPath();
context.fillStyle = '#000000';
context.strokeStyle = '#000000';
context.arc(0, 0, radius, -0.5 * Math.PI, 0.5 * Math.PI, counterclockwisep);
if ((theta % 180) != 90) {
context.scale(cosTheta, 1);
context.arc(0, 0, radius, 0.5 * Math.PI, -0.5 * Math.PI, counterclockwisep);
Canvas {
id: shadow
property int latitude: lunaIcon.latitude
property int theta: lunaIcon.theta
property bool showShadow: lunaIcon.showShadow
width: lunaBackground.width
height: lunaBackground.height
visible: true
anchors.centerIn: parent
contextType: "2d"
onLatitudeChanged: requestPaint()
onThetaChanged: requestPaint()
onShowShadowChanged: requestPaint()
onPaint: {
context.reset();
if (showShadow) {
var radius = Math.floor(height / 2);
var cosTheta = Math.cos(theta / 180 * Math.PI);
var counterclockwisep = (theta < 180);
context.globalAlpha = 0.9;
context.translate(radius, radius);
context.rotate((latitude - 90) / 180 * Math.PI);
if (theta != 180) {
context.beginPath();
context.fillStyle = '#000000';
context.strokeStyle = '#000000';
context.arc(0, 0, radius, -0.5 * Math.PI, 0.5 * Math.PI, counterclockwisep);
if ((theta % 180) != 90) {
context.scale(cosTheta, 1);
context.arc(0, 0, radius, 0.5 * Math.PI, -0.5 * Math.PI, counterclockwisep);
}
context.closePath();
context.fill();
context.stroke();
}
context.closePath();
context.fill();
context.stroke();
}
} else {
// Calibration markers
if (showGrid)
grid(radius);
}
}
Canvas {
id: markers
property int latitude: lunaIcon.latitude
property int theta: lunaIcon.theta
property bool showShadow: lunaIcon.showShadow
property bool showGrid: lunaIcon.showGrid
property bool showTycho: lunaIcon.showTycho
property bool showCopernicus: lunaIcon.showCopernicus
function radians(deg) {
return deg / 180 * Math.PI;
}
function marker(radius, latitude, longitude) {
var dy = radius * Math.sin(radians(latitude));
var dx = radius * Math.cos(radians(latitude)) * Math.sin(radians(longitude));
// console.log("dx: " + dx.toString());
// console.log("dy: " + dy.toString());
context.beginPath();
context.strokeStyle = "#FF0000";
context.arc(dx, -dy, 5, 0, 2 * Math.PI);
context.moveTo(dx - 5, -dy - 5);
context.lineTo(dx + 5, -dy + 5);
context.moveTo(dx - 5, -dy + 5);
context.lineTo(dx + 5, -dy - 5);
context.stroke();
}
function grid(radius) {
context.beginPath();
context.strokeStyle = "#FF4040";
context.moveTo(0, -radius);
context.lineTo(0, radius);
context.moveTo(-radius, 0);
context.lineTo(radius, 0);
context.stroke();
context.beginPath();
context.strokeStyle = "#40FF40";
for (var ll = 10; ll < 65; ll += 10) {
var dy = radius * Math.sin(radians(ll));
context.moveTo(-radius, dy);
context.lineTo(radius, dy);
context.moveTo(-radius, -dy);
context.lineTo(radius, -dy);
}
context.stroke();
}
width: lunaBackground.width
height: lunaBackground.height
visible: true
anchors.centerIn: parent
contextType: "2d"
onLatitudeChanged: requestPaint()
onThetaChanged: requestPaint()
onShowGridChanged: requestPaint()
onShowTychoChanged: requestPaint()
onShowCopernicusChanged: requestPaint()
onShowShadowChanged: requestPaint()
onPaint: {
context.reset();
if (!showShadow) {
var radius = Math.floor(height / 2);
var cosTheta = Math.cos(theta / 180 * Math.PI);
var counterclockwisep = (theta < 180);
context.globalAlpha = 0.9;
context.translate(radius, radius);
context.rotate((latitude - 90) / 180 * Math.PI);
// Calibration markers
if (showGrid)
grid(radius);
// Tycho
if (showTycho)
marker(radius, -43, -11.5);
// Tycho
if (showTycho)
marker(radius, -43, -11.5);
// Copernicus
if (showCopernicus)
marker(radius, 9.6, -20);
// Copernicus
if (showCopernicus)
marker(radius, 9.6, -20);
}
}
}
}
Blend {
id: lunaSource
ShaderEffectSource {
id: lunaMask
anchors.fill: lunaBackground
source: lunaSvgItem
foregroundSource: lunaCanvas
mode: "normal"
anchors.centerIn: parent
width: lunaBackground.width
height: lunaBackground.height
visible: false
}
// Shadow acts as a transparency mask
OpacityMask {
anchors.fill: lunaBackground
source: lunaSource
maskSource: shadow
invert: true
rotation: latitude - 90
visible: transparentShadow
sourceItem: Shape {
opacity: 1
width: lunaBackground.width
height: lunaBackground.height
visible: true
anchors.centerIn: parent
preferredRendererType: Shape.CurveRenderer
ShapePath {
fillColor: '#000000'
strokeWidth: -1 //no stroke
PathAngleArc {
property int radius: Math.floor(height / 2)
centerX: radius
centerY: radius
radiusY: radius
radiusX: radius
startAngle: 0
sweepAngle: 360
}
}
}
}
// Shadow is printed on top of the moon image
Blend {
ShaderEffect {
property variant source: lunaTexture
property variant shadow: shadow
property variant mask: lunaMask
property int transparent: transparentShadow
visible: true
anchors.fill: lunaBackground
source: lunaSource
foregroundSource: shadow
rotation: latitude - 90
mode: "normal"
visible: !transparentShadow
fragmentShader: "shadow.gsb"
}
}
#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;
int transparent;
};
layout(binding = 1) uniform sampler2D source;
layout(binding = 2) uniform sampler2D shadow;
layout(binding = 3) uniform sampler2D mask;
void main() { fragColor = texture(source, qt_TexCoord0)
* texture(mask, qt_TexCoord0).a
* (1 - texture(shadow, qt_TexCoord0).a * transparent)
* qt_Opacity ;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment