blob: 5821bd745b8c3eb7159f9f24613fc814e7d4065c [file] [log] [blame]
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick3D 1.15
Window {
visible: true
width: 800
height: 480
title: qsTr("Stereoscopic Rendering Example")
color: "#404040"
//visibility: Window.FullScreen
Item {
focus: true
Keys.onPressed: {
if (event.key === Qt.Key_0) {
stereoCamera.stereoMode = 0;
}
if (event.key === Qt.Key_1) {
stereoCamera.stereoMode = 1;
}
if (event.key === Qt.Key_2) {
stereoCamera.stereoMode = 2;
}
if (event.key === Qt.Key_3) {
stereoCamera.stereoMode = 3;
}
if (event.key === Qt.Key_4) {
stereoCamera.stereoMode = 4;
}
if (event.key === Qt.Key_Plus) {
stereoCamera.eyeSeparation += 1;
}
if (event.key === Qt.Key_Minus) {
stereoCamera.eyeSeparation -= 1;
}
}
}
// Scene
SceneNode {
id: sceneRoot
Node {
id: stereoCamera
property real convergence: 600.0
property real eyeSeparation: 35.0
property real fieldOfView: 60.0
property real nearPlane: 10.0
property real farPlane: 2000.0
property real aspectRatio: leftEyeView.width / leftEyeView.height
property real _fov2: Math.tan(fieldOfView * Math.PI / 180 * 0.5)
property real top: nearPlane * _fov2
property real a: aspectRatio * _fov2 * convergence
// 0 = Mono, 1 = TopBottom, 2 = LeftRight, 3 = Anaglyp (red-cyan), 4 = Anaglyph (green-magenta)
property int stereoMode: 1
// True when views are separate, false when they need to be combined with shader
readonly property bool separateViews: (stereoMode == 1 || stereoMode == 2)
readonly property bool isStereo: (stereoMode != 0)
readonly property alias monoCamera: sceneRoot.mainCamera
FrustumCamera {
id: leftEyeCamera
x: stereoCamera.monoCamera.x - stereoCamera.eyeSeparation * 0.5
y: stereoCamera.monoCamera.y
z: stereoCamera.monoCamera.z
clipNear: stereoCamera.nearPlane
clipFar: stereoCamera.farPlane
left: -(stereoCamera.a - stereoCamera.eyeSeparation * 0.5) * stereoCamera.nearPlane / stereoCamera.convergence
right: (stereoCamera.a + stereoCamera.eyeSeparation * 0.5) * stereoCamera.nearPlane / stereoCamera.convergence
top: stereoCamera.top
bottom: -stereoCamera.top
}
FrustumCamera {
id: rightEyeCamera
x: stereoCamera.monoCamera.x + stereoCamera.eyeSeparation * 0.5
y: stereoCamera.monoCamera.y
z: stereoCamera.monoCamera.z
clipNear: stereoCamera.nearPlane
clipFar: stereoCamera.farPlane
left: -(stereoCamera.a + stereoCamera.eyeSeparation * 0.5) * stereoCamera.nearPlane / stereoCamera.convergence
right: (stereoCamera.a - stereoCamera.eyeSeparation * 0.5) * stereoCamera.nearPlane / stereoCamera.convergence
top: stereoCamera.top
bottom: -stereoCamera.top
}
}
}
View3D {
id: monoView
width: parent.width
height: parent.height
importScene: sceneRoot
camera: stereoCamera.monoCamera
visible: !stereoCamera.isStereo
environment: SceneEnvironment {
antialiasingMode: SceneEnvironment.MSAA
}
}
View3D {
id: leftEyeView
width: parent.width
height: parent.height
importScene: sceneRoot
camera: leftEyeCamera
layer.enabled: true
layer.smooth: true
layer.format: ShaderEffectSource.RGBA
visible: stereoCamera.isStereo && stereoCamera.separateViews
transform: Scale {
xScale: (stereoCamera.stereoMode == 2) ? 0.5 : 1.0
yScale: (stereoCamera.stereoMode == 1) ? 0.5 : 1.0
}
environment: SceneEnvironment {
antialiasingMode: SceneEnvironment.MSAA
}
}
View3D {
id: rightEyeView
width: parent.width
height: parent.height
x: (stereoCamera.stereoMode == 2) ? parent.width/2 : 0
y: (stereoCamera.stereoMode == 1) ? parent.height/2 : 0
importScene: sceneRoot
camera: rightEyeCamera
layer.enabled: true
layer.smooth: true
layer.format: ShaderEffectSource.RGBA
visible: stereoCamera.isStereo && stereoCamera.separateViews
transform: Scale {
xScale: (stereoCamera.stereoMode == 2) ? 0.5 : 1.0
yScale: (stereoCamera.stereoMode == 1) ? 0.5 : 1.0
}
environment: SceneEnvironment {
antialiasingMode: SceneEnvironment.MSAA
}
}
ShaderEffect {
id: outputView
anchors.fill: parent
property variant leftEye: leftEyeView
property variant rightEye: rightEyeView
property alias stereoMode: stereoCamera.stereoMode
blending: true
visible: stereoCamera.isStereo && !stereoCamera.separateViews
fragmentShader: "
varying highp vec2 qt_TexCoord0;
uniform sampler2D leftEye;
uniform sampler2D rightEye;
uniform lowp int stereoMode;
uniform lowp float qt_Opacity;
void main() {
lowp vec4 tex1 = texture2D(leftEye, qt_TexCoord0);
lowp vec4 tex2 = texture2D(rightEye, qt_TexCoord0);
if (stereoMode == 3)
gl_FragColor = vec4(tex1.r, tex2.gb, 0.0) * qt_Opacity;
else
gl_FragColor = vec4(tex2.r, tex1.g, tex2.b, 0.0) * qt_Opacity;
}"
}
}