diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4e40f2d928..51d33c2522 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2622,7 +2622,12 @@ glm::vec3 Application::getSunDirection() { return skyStage->getSunLight()->getDirection(); } +// FIXME, preprocessor guard this check to occur only in DEBUG builds +static QThread * activeRenderingThread = nullptr; + void Application::updateShadowMap() { + activeRenderingThread = QThread::currentThread(); + PerformanceTimer perfTimer("shadowMap"); QOpenGLFramebufferObject* fbo = DependencyManager::get()->getShadowFramebufferObject(); fbo->bind(); @@ -2717,6 +2722,10 @@ void Application::updateShadowMap() { glLoadIdentity(); glOrtho(minima.x, maxima.x, minima.y, maxima.y, -maxima.z, -minima.z); + glm::mat4 projAgain; + glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat*)&projAgain); + + glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); @@ -2772,6 +2781,7 @@ void Application::updateShadowMap() { fbo->release(); glViewport(0, 0, _glWidget->getDeviceWidth(), _glWidget->getDeviceHeight()); + activeRenderingThread = nullptr; } const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f }; @@ -2832,9 +2842,6 @@ QImage Application::renderAvatarBillboard() { return image; } -// FIXME, preprocessor guard this check to occur only in DEBUG builds -static QThread * activeRenderingThread = nullptr; - ViewFrustum* Application::getViewFrustum() { #ifdef DEBUG if (QThread::currentThread() == activeRenderingThread) { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 3ea4723801..13db6d28dd 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -337,8 +337,13 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool // simple frustum check float boundingRadius = getBillboardSize(); - ViewFrustum* frustum = (renderMode == Avatar::SHADOW_RENDER_MODE) ? - Application::getInstance()->getShadowViewFrustum() : Application::getInstance()->getDisplayViewFrustum(); + + ViewFrustum* frustum = nullptr; + if (renderMode == Avatar::SHADOW_RENDER_MODE) { + frustum = Application::getInstance()->getShadowViewFrustum(); + } else { + frustum = Application::getInstance()->getDisplayViewFrustum(); + } if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) { return; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f92523c58f..e4eb6e7869 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1005,22 +1005,25 @@ void MyAvatar::renderBody(ViewFrustum* renderFrustum, RenderMode renderMode, boo Camera *camera = Application::getInstance()->getCamera(); const glm::vec3 cameraPos = camera->getPosition(); - // Set near clip distance according to skeleton model dimensions if first person and there is no separate head model. - if (shouldRenderHead(cameraPos, renderMode) || !getHead()->getFaceModel().getURL().isEmpty()) { - renderFrustum->setNearClip(DEFAULT_NEAR_CLIP); - } else { - float clipDistance = _skeletonModel.getHeadClipDistance(); - if (OculusManager::isConnected()) { - // If avatar is horizontally in front of camera, increase clip distance by the amount it is in front. - glm::vec3 cameraToAvatar = _position - cameraPos; - cameraToAvatar.y = 0.0f; - glm::vec3 cameraLookAt = camera->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f); - float headOffset = glm::dot(cameraLookAt, cameraToAvatar); - if (headOffset > 0) { - clipDistance += headOffset; + // Only tweak the frustum near far if it's not shadow + if (renderMode != SHADOW_RENDER_MODE) { + // Set near clip distance according to skeleton model dimensions if first person and there is no separate head model. + if (shouldRenderHead(cameraPos, renderMode) || !getHead()->getFaceModel().getURL().isEmpty()) { + renderFrustum->setNearClip(DEFAULT_NEAR_CLIP); + } else { + float clipDistance = _skeletonModel.getHeadClipDistance(); + if (OculusManager::isConnected()) { + // If avatar is horizontally in front of camera, increase clip distance by the amount it is in front. + glm::vec3 cameraToAvatar = _position - cameraPos; + cameraToAvatar.y = 0.0f; + glm::vec3 cameraLookAt = camera->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f); + float headOffset = glm::dot(cameraLookAt, cameraToAvatar); + if (headOffset > 0) { + clipDistance += headOffset; + } } + renderFrustum->setNearClip(clipDistance); } - renderFrustum->setNearClip(clipDistance); } // Render the body's voxels and head diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index 6c23776e18..fe2da31231 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -31,6 +31,10 @@ class Text3DOverlay; #define OVR_CLIENT_DISTORTION 1 +// Direct HMD mode is currently only supported on windows and some linux systems will +// misbehave if we try to enable the Oculus SDK at all, so isolate support for Direct +// mode only to windows for now +#ifdef Q_OS_WIN // On Win32 platforms, enabling Direct HMD requires that the SDK be // initialized before the GL context is set up, but this breaks v-sync // for any application that has a Direct mode enable Rift connected @@ -40,6 +44,7 @@ class Text3DOverlay; // caveat that it will break v-sync in NON-VR mode if you have an Oculus // Rift connect and in Direct mode #define OVR_DIRECT_MODE 1 +#endif /// Handles interaction with the Oculus Rift. diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 0dcab2c81b..94470f48e4 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1281,6 +1281,9 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) { } void AudioClient::checkDevices() { +# ifdef Q_OS_LINUX + // on linux, this makes the audio stream hiccup +# else QVector inputDevices = getDeviceNames(QAudio::AudioInput); QVector outputDevices = getDeviceNames(QAudio::AudioOutput); @@ -1290,6 +1293,7 @@ void AudioClient::checkDevices() { emit deviceChanged(); } +# endif } void AudioClient::loadSettings() { diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index bcfdc4f36c..3f794575fe 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -104,7 +104,7 @@ void makeBindings(GLBackend::GLShader* shader) { loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer"); if (loc >= 0) { glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_CAMERA_SLOT); - shader->_transformCameraSlot = gpu::TRANSFORM_OBJECT_SLOT; + shader->_transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT; } #endif } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index d04972ebee..e77b8c4226 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -121,18 +121,20 @@ Model::Locations Model::_normalMapLocations; Model::Locations Model::_specularMapLocations; Model::Locations Model::_normalSpecularMapLocations; Model::Locations Model::_translucentLocations; +Model::Locations Model::_shadowLocations; Model::Locations Model::_lightmapLocations; Model::Locations Model::_lightmapNormalMapLocations; Model::Locations Model::_lightmapSpecularMapLocations; Model::Locations Model::_lightmapNormalSpecularMapLocations; + Model::SkinLocations Model::_skinLocations; Model::SkinLocations Model::_skinNormalMapLocations; Model::SkinLocations Model::_skinSpecularMapLocations; Model::SkinLocations Model::_skinNormalSpecularMapLocations; -Model::SkinLocations Model::_skinShadowLocations; Model::SkinLocations Model::_skinTranslucentLocations; +Model::SkinLocations Model::_skinShadowLocations; AbstractViewStateInterface* Model::_viewState = NULL; @@ -284,8 +286,7 @@ void Model::init() { _shadowProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelShadowVertex, modelShadowPixel)); makeResult = gpu::Shader::makeProgram(*_shadowProgram, slotBindings); - Model::Locations tempShadowLoc; - initProgram(_shadowProgram, tempShadowLoc); + initProgram(_shadowProgram, _shadowLocations); _lightmapProgram = gpu::ShaderPointer(gpu::Shader::createProgram(modelLightmapVertex, modelLightmapPixel)); makeResult = gpu::Shader::makeProgram(*_lightmapProgram, slotBindings); @@ -656,7 +657,7 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) { renderSetup(args); return renderCore(alpha, mode, args); } - + bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { PROFILE_RANGE(__FUNCTION__); if (!_viewState) { @@ -670,7 +671,12 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { // Setup the projection matrix if (args && args->_viewFrustum) { glm::mat4 proj; - args->_viewFrustum->evalProjectionMatrix(proj); + // If for easier debug depending on the pass + if (mode == RenderArgs::SHADOW_RENDER_MODE) { + args->_viewFrustum->evalProjectionMatrix(proj); + } else { + args->_viewFrustum->evalProjectionMatrix(proj); + } batch.setProjectionTransform(proj); } @@ -678,7 +684,9 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { if (_transforms.empty()) { _transforms.push_back(Transform()); } + _transforms[0] = _viewState->getViewTransform(); + // apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space) _transforms[0].preTranslate(-_translation); @@ -699,7 +707,7 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { GLBATCH(glDisable)(GL_BLEND); GLBATCH(glEnable)(GL_ALPHA_TEST); - + if (mode == SHADOW_RENDER_MODE) { GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f); } @@ -1710,14 +1718,19 @@ void Model::startScene(RenderArgs::RenderSide renderSide) { } } -void Model::setupBatchTransform(gpu::Batch& batch) { +void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) { // Capture the view matrix once for the rendering of this model if (_transforms.empty()) { _transforms.push_back(Transform()); } + + // We should be able to use the Frustum viewpoint onstead of the "viewTransform" + // but it s still buggy in some cases, so let's s wait and fix it... _transforms[0] = _viewState->getViewTransform(); + _transforms[0].preTranslate(-_translation); + batch.setViewTransform(_transforms[0]); } @@ -1738,7 +1751,12 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { if (args) { glm::mat4 proj; - args->_viewFrustum->evalProjectionMatrix(proj); + // If for easier debug depending on the pass + if (mode == RenderArgs::SHADOW_RENDER_MODE) { + args->_viewFrustum->evalProjectionMatrix(proj); + } else { + args->_viewFrustum->evalProjectionMatrix(proj); + } gpu::Batch batch; batch.setProjectionTransform(proj); backend.render(batch); @@ -2286,6 +2304,7 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f skinLocations = &_skinLocations; if (mode == SHADOW_RENDER_MODE) { program = _shadowProgram; + locations = &_shadowLocations; skinProgram = _skinShadowProgram; skinLocations = &_skinShadowLocations; } else if (translucent && alphaThreshold == 0.0f) { @@ -2376,7 +2395,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, args, locations, skinLocations); pickProgramsNeeded = false; } - model->setupBatchTransform(batch); + model->setupBatchTransform(batch, args); meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, locations, skinLocations); } } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 5dbd0b03c2..f1bbf151cd 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -357,6 +357,7 @@ private: static Locations _specularMapLocations; static Locations _normalSpecularMapLocations; static Locations _translucentLocations; + static Locations _shadowLocations; static Locations _lightmapLocations; static Locations _lightmapNormalMapLocations; @@ -377,8 +378,9 @@ private: static SkinLocations _skinNormalMapLocations; static SkinLocations _skinSpecularMapLocations; static SkinLocations _skinNormalSpecularMapLocations; - static SkinLocations _skinShadowLocations; static SkinLocations _skinTranslucentLocations; + static SkinLocations _skinShadowLocations; + static void initSkinProgram(ProgramObject& program, SkinLocations& locations); static void initSkinProgram(gpu::ShaderPointer& program, SkinLocations& locations); @@ -463,7 +465,7 @@ private: bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL, bool forceRenderMeshes = false); - void setupBatchTransform(gpu::Batch& batch); + void setupBatchTransform(gpu::Batch& batch, RenderArgs* args); QVector* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned); int renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,