ff4ff35918
Red Bear OS is a full fork. All sources must be available from git clone with zero network access. Removed gitignore rules that excluded fetched source trees under recipes/*/source/, local/recipes/kde/*/source/, local/recipes/qt/*/source/, and vendor source trees. Build artifacts (target/, build/, source.tar, *.o, *.so) remain excluded. 127291 files added — kernel, relibc, base, bootloader, pkgar, all KDE/Qt frameworks, mesa, wayland, DRM drivers, and every other recipe source.
274 lines
7.7 KiB
QML
274 lines
7.7 KiB
QML
// Copyright (C) 2025 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
import QtQuick
|
|
import QtQuick3D
|
|
import QtQuick3D.Helpers
|
|
import QtQuick3D.AssetUtils
|
|
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
import QtQml.Models
|
|
|
|
ApplicationWindow {
|
|
width: 1480
|
|
height: 900
|
|
visible: true
|
|
title: qsTr("QtQuick3D SSGI Lightmap Demo")
|
|
|
|
View3D {
|
|
id: view
|
|
anchors.fill: parent
|
|
|
|
property Loader3D currentLoader: loaderCornell
|
|
property url currentSource: "assets/CornellBox/CornellBox.qml"
|
|
onCurrentSourceChanged: {
|
|
updateLoadedScene()
|
|
}
|
|
|
|
environment: ExtendedSceneEnvironment {
|
|
id: env
|
|
clearColor: "black"
|
|
backgroundMode: SceneEnvironment.Color
|
|
}
|
|
|
|
function updateLoadedScene() {
|
|
posAnim.stop()
|
|
rotAnim.stop()
|
|
let loaders = [loaderCornell, loaderBedroom, loaderSponza]
|
|
for (var i = 0; i < loaders.length; i++) {
|
|
let loader = loaders[i]
|
|
let item = loader.item
|
|
if (item === null) {
|
|
continue
|
|
}
|
|
|
|
if (loader.source === view.currentSource) {
|
|
env.lightmapper = item.lightmapper
|
|
env.backgroundMode = item.backgroundMode
|
|
env.lightProbe = item.lightProbe
|
|
env.ssgiEnabled = buttonSSGI.checked
|
|
cameraNode.position = item.cameraPositions[item.cameraIndex]
|
|
cameraNode.eulerRotation = item.cameraRotations[item.cameraIndex]
|
|
item.enableLightmaps = buttonBaked.checked
|
|
env.ssgiIndirectLightBoost = item.ssgiIndirectLightBoost
|
|
env.probeExposure = item.probeExposure
|
|
item.visible = true
|
|
view.currentLoader = loader
|
|
} else {
|
|
item.enableLightmaps = false
|
|
item.visible = false
|
|
}
|
|
}
|
|
}
|
|
|
|
Loader3D {
|
|
id: loaderCornell
|
|
asynchronous: true
|
|
source: "assets/CornellBox/CornellBox.qml"
|
|
onStatusChanged: () => {
|
|
if (status === Loader3D.Ready)
|
|
view.updateLoadedScene()
|
|
}
|
|
}
|
|
|
|
Loader3D {
|
|
id: loaderBedroom
|
|
asynchronous: true
|
|
source: "assets/Bedroom/Bedroom.qml"
|
|
onStatusChanged: () => {
|
|
if (status === Loader3D.Ready)
|
|
view.updateLoadedScene()
|
|
}
|
|
}
|
|
|
|
Loader3D {
|
|
id: loaderSponza
|
|
asynchronous: true
|
|
source: "assets/Sponza/Sponza.qml"
|
|
onStatusChanged: () => {
|
|
if (status === Loader3D.Ready)
|
|
view.updateLoadedScene()
|
|
}
|
|
}
|
|
|
|
WasdController {
|
|
controlledObject: cameraNode
|
|
}
|
|
|
|
PerspectiveCamera {
|
|
id: cameraNode
|
|
z: 300
|
|
y: 100
|
|
}
|
|
}
|
|
|
|
RowLayout {
|
|
id: buttonRow
|
|
spacing: 12
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
anchors.bottom: parent.bottom
|
|
anchors.bottomMargin: 20
|
|
|
|
IconButton {
|
|
id: buttonSSGI
|
|
text: "SSGI"
|
|
conflictingButtons: [buttonOff, buttonBaked]
|
|
iconSource: "qrc:/assets/icons/ssgi.svg"
|
|
onCheckedChanged: {
|
|
if (checked) {
|
|
env.ssgiEnabled = true
|
|
if (view.currentLoader.item) {
|
|
view.currentLoader.item.enableLightmaps = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IconButton {
|
|
id: buttonBaked
|
|
checked: true
|
|
text: "Baked"
|
|
conflictingButtons: [buttonOff, buttonSSGI]
|
|
iconSource: "qrc:/assets/icons/baked.svg"
|
|
onCheckedChanged: {
|
|
if (checked) {
|
|
env.ssgiEnabled = false
|
|
if (view.currentLoader.item) {
|
|
view.currentLoader.item.enableLightmaps = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
IconButton {
|
|
id: buttonOff
|
|
text: "Off"
|
|
iconSource: "qrc:/assets/icons/off.svg"
|
|
conflictingButtons: [buttonBaked, buttonSSGI]
|
|
onCheckedChanged: {
|
|
if (checked) {
|
|
env.ssgiEnabled = false
|
|
if (view.currentLoader.item) {
|
|
view.currentLoader.item.enableLightmaps = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: 1
|
|
height: 60
|
|
color: "#aaa"
|
|
opacity: 0.4
|
|
} // separator
|
|
|
|
IconButton {
|
|
id: demoButton
|
|
text: "Demo"
|
|
iconSource: "qrc:/assets/icons/reset-camera.svg"
|
|
toggable: true
|
|
onClicked: {
|
|
if (demoButton.checked) {
|
|
nextCamera()
|
|
}
|
|
}
|
|
}
|
|
|
|
IconButton {
|
|
text: "Next View"
|
|
iconSource: "qrc:/assets/icons/right-arrow.svg"
|
|
checkable: false
|
|
onClicked: {
|
|
nextCamera()
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
width: 1
|
|
height: 60
|
|
color: "#aaa"
|
|
opacity: 0.4
|
|
} // separator
|
|
|
|
IconButton {
|
|
id: buttonBedroom
|
|
text: "Bedroom"
|
|
iconSource: "qrc:/assets/icons/bedroom.svg"
|
|
conflictingButtons: [buttonCornell, buttonSponza]
|
|
onCheckedChanged: {
|
|
if (checked)
|
|
view.currentSource = "assets/Bedroom/Bedroom.qml"
|
|
}
|
|
}
|
|
|
|
IconButton {
|
|
id: buttonCornell
|
|
text: "Cornell"
|
|
iconSource: "qrc:/assets/icons/cornell.svg"
|
|
checked: true
|
|
conflictingButtons: [buttonBedroom, buttonSponza]
|
|
onCheckedChanged: {
|
|
if (checked)
|
|
view.currentSource = "assets/CornellBox/CornellBox.qml"
|
|
}
|
|
}
|
|
|
|
IconButton {
|
|
id: buttonSponza
|
|
text: "Sponza"
|
|
iconSource: "qrc:/assets/icons/sponza.svg"
|
|
conflictingButtons: [buttonCornell, buttonBedroom]
|
|
onCheckedChanged: {
|
|
if (checked)
|
|
view.currentSource = "assets/Sponza/Sponza.qml"
|
|
}
|
|
}
|
|
}
|
|
|
|
function nextCamera() {
|
|
let loader = view.currentLoader
|
|
let item = loader.item
|
|
if (item === null) {
|
|
return
|
|
}
|
|
|
|
posAnim.stop()
|
|
rotAnim.stop()
|
|
|
|
item.cameraIndex = (item.cameraIndex + 1) % item.cameraPositions.length
|
|
posAnim.to = item.cameraPositions[item.cameraIndex]
|
|
rotAnim.to = item.cameraRotations[item.cameraIndex]
|
|
|
|
posAnim.start()
|
|
rotAnim.start()
|
|
}
|
|
|
|
Timer {
|
|
id: demoTimer
|
|
interval: 7500
|
|
repeat: true
|
|
running: demoButton.checked
|
|
onTriggered: {
|
|
nextCamera()
|
|
}
|
|
}
|
|
|
|
// Animations
|
|
Vector3dAnimation {
|
|
id: posAnim
|
|
target: cameraNode
|
|
property: "position"
|
|
duration: demoButton.checked ? 2000 : 1000
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
|
|
Vector3dAnimation {
|
|
id: rotAnim
|
|
target: cameraNode
|
|
property: "eulerRotation"
|
|
duration: demoButton.checked ? 2000 : 1000
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|