diff --git a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.cpp index 40063652c8..3de3e590b9 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.cpp @@ -26,6 +26,8 @@ bool DebugHmdDisplayPlugin::isSupported() const { void DebugHmdDisplayPlugin::resetSensors() { _currentRenderFrameInfo.renderPose = glm::mat4(); // identity + _currentRenderFrameInfo.renderPose = glm::translate(glm::mat4(), glm::vec3(0.0f, 1.76f, 0.0f)); + } bool DebugHmdDisplayPlugin::beginFrameRender(uint32_t frameIndex) { @@ -35,6 +37,8 @@ bool DebugHmdDisplayPlugin::beginFrameRender(uint32_t frameIndex) { // FIXME simulate head movement //_currentRenderFrameInfo.renderPose = ; //_currentRenderFrameInfo.presentPose = _currentRenderFrameInfo.renderPose; + _currentRenderFrameInfo.renderPose = glm::translate(glm::mat4(), glm::vec3(0.0f, 1.76f, 0.0f)); + _currentRenderFrameInfo.presentPose = _currentRenderFrameInfo.renderPose; withNonPresentThreadLock([&] { _frameInfos[frameIndex] = _currentRenderFrameInfo; @@ -71,6 +75,7 @@ bool DebugHmdDisplayPlugin::internalActivate() { _eyeOffsets[1][3] = vec4{ 0.0327499993, 0.0, -0.0149999997, 1.0 }; _renderTargetSize = { 3024, 1680 }; _cullingProjection = _eyeProjections[0]; + // This must come after the initialization, so that the values calculated // above are available during the customizeContext call (when not running // in threaded present mode) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index c1ce05c18b..00373eb196 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -410,20 +410,24 @@ void GLBackend::render(const Batch& batch) { renderPassTransfer(batch); } -#ifdef GPU_STEREO_DRAWCALL_INSTANCED +//#ifdef GPU_STEREO_DRAWCALL_INSTANCED +#ifdef GPU_STEREO_VIEWPORT_CLIPPED if (_stereo.isStereo()) { glEnable(GL_CLIP_DISTANCE0); } #endif +//#endif { PROFILE_RANGE(render_gpu_gl_detail, _stereo.isStereo() ? "Render Stereo" : "Render"); renderPassDraw(batch); } -#ifdef GPU_STEREO_DRAWCALL_INSTANCED +//#ifdef GPU_STEREO_DRAWCALL_INSTANCED +#ifdef GPU_STEREO_VIEWPORT_CLIPPED if (_stereo.isStereo()) { glDisable(GL_CLIP_DISTANCE0); } #endif +//#endif // Restore the saved stereo state for the next batch _stereo._enable = savedStereo; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 37dde5b08e..8a459c86ca 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -36,7 +36,8 @@ #define GPU_STEREO_TECHNIQUE_DOUBLED_SIMPLE #else //#define GPU_STEREO_TECHNIQUE_DOUBLED_SMARTER -#define GPU_STEREO_TECHNIQUE_INSTANCED +//#define GPU_STEREO_TECHNIQUE_INSTANCED +#define GPU_STEREO_TECHNIQUE_INSTANCED_MULTIVIEWPORT #endif // Let these be configured by the one define picked above @@ -51,6 +52,13 @@ #ifdef GPU_STEREO_TECHNIQUE_INSTANCED #define GPU_STEREO_DRAWCALL_INSTANCED +#define GPU_STEREO_VIEWPORT_CLIPPED +#define GPU_STEREO_CAMERA_BUFFER +#endif + +#ifdef GPU_STEREO_TECHNIQUE_INSTANCED_MULTIVIEWPORT +#define GPU_STEREO_DRAWCALL_INSTANCED +#define GPU_STEREO_MULTI_VIEWPORT #define GPU_STEREO_CAMERA_BUFFER #endif diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendTransform.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendTransform.cpp index 2c2a4e254c..caa194764d 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendTransform.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendTransform.cpp @@ -39,6 +39,45 @@ void GLBackend::do_setViewportTransform(const Batch& batch, size_t paramOffset) #ifdef GPU_STEREO_DRAWCALL_INSTANCED { + #ifdef GPU_STEREO_MULTI_VIEWPORT + ivec4& vp = _transform._viewport; + auto sideWidth = vp.z / 2; + + vec4 leftRight[3]; + + // Mono + leftRight[0] = vp; + + // Left side + leftRight[1] = vp; + leftRight[1].x = 0; + leftRight[1].z = sideWidth; + + // right side + leftRight[2] = vp; + leftRight[2].x = sideWidth; + leftRight[2].z = sideWidth; + + glViewportArrayv(0, 3, (float*)leftRight); + + // Where we assign the GL viewport + if (_stereo.isStereo()) { + + // ivec4 leftRight[3]; + // leftRight[0] = vp; + vp.z /= 2; + /* leftRight[1] = vp; // left side + leftRight[2] = vp; // right side + leftRight[2].x += vp.z; + glViewportArrayv(0, 3, (float*) leftRight); +*/ + if (_stereo._pass) { + vp.x += vp.z; + } + } else { + // glViewport(vp.x, vp.y, vp.z, vp.w); + } + #else ivec4& vp = _transform._viewport; glViewport(vp.x, vp.y, vp.z, vp.w); @@ -49,6 +88,7 @@ void GLBackend::do_setViewportTransform(const Batch& batch, size_t paramOffset) vp.x += vp.z; } } + #endif } #else if (!_inRenderTransferPass && !isStereo()) { @@ -123,7 +163,7 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo if (_invalidView || _invalidProj || _invalidViewport) { size_t offset = _cameraUboSize * _cameras.size(); - Vec2 finalJitter = _projectionJitter / Vec2(framebufferSize); + Vec2 finalJitter = _projectionJitter / Vec2(framebufferSize); _cameraOffsets.push_back(TransformStageState::Pair(commandIndex, offset)); if (stereo.isStereo()) { diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 43205ba4c2..998204ce92 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -168,10 +168,15 @@ TransformObject getTransformObject() { vec2 eyeOffsetScale = vec2(-0.5, +0.5); uint eyeIndex = uint(_stereoSide); #ifndef GPU_GLES +#ifdef GPU_GL450 + gl_ViewportIndex = _stereoSide + 1; + // gl_ViewportIndex = 2 - _stereoSide; +#else gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]); #endif - float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w; - <$clipPos$>.x = newClipPosX; +#endif + // float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w; + // <$clipPos$>.x = newClipPosX; #endif #else diff --git a/libraries/shaders/headers/450/header.glsl b/libraries/shaders/headers/450/header.glsl index 6ce61b4378..a33b7634b1 100644 --- a/libraries/shaders/headers/450/header.glsl +++ b/libraries/shaders/headers/450/header.glsl @@ -1,4 +1,5 @@ #version 450 core +#extension GL_ARB_shader_viewport_layer_array : require #define GPU_GL450 #define GPU_SSBO_TRANSFORM_OBJECT #define BITFIELD int diff --git a/tools/shadergen.py b/tools/shadergen.py index ffbe1662ec..120fcc6bb7 100644 --- a/tools/shadergen.py +++ b/tools/shadergen.py @@ -190,6 +190,10 @@ def processCommand(line): if (dialect == '310es'): spirvCrossDialect = '320es' spirvCrossArgs = [spirvCrossExec, '--output', glslFile, spirvFile, '--version', spirvCrossDialect] if (dialect == '410'): spirvCrossArgs.append('--no-420pack-extension') + if (dialect == '450'): + spirvCrossArgs.append('--extension') + spirvCrossArgs.append('GL_ARB_shader_viewport_layer_array') + executeSubprocess(spirvCrossArgs) else: # This logic is necessary because cmake will agressively keep re-executing the shadergen