From c3934d9e8653f293ee96e0ccba3c371cfffccc2d Mon Sep 17 00:00:00 2001 From: matsukaze Date: Tue, 1 Apr 2014 15:49:08 -0700 Subject: [PATCH 1/5] Fix heap corruption. --- interface/src/Audio.cpp | 119 +++++++++++++++++++++++----------------- interface/src/Audio.h | 8 +++ 2 files changed, 78 insertions(+), 49 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 67f2e2caec..5e2524a54c 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -95,6 +95,7 @@ void Audio::reset() { QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { QAudioDeviceInfo result; foreach(QAudioDeviceInfo audioDevice, QAudioDeviceInfo::availableDevices(mode)) { + qDebug() << audioDevice.deviceName() << " " << deviceName; if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { result = audioDevice; } @@ -162,6 +163,8 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { qDebug() << "output device:" << woc.szPname; deviceName = woc.szPname; } + qDebug() << "DEBUG [" << deviceName << "] [" << getNamedAudioDeviceForMode(mode, deviceName).deviceName() << "]"; + return getNamedAudioDeviceForMode(mode, deviceName); #endif @@ -321,10 +324,12 @@ QVector Audio::getDeviceNames(QAudio::Mode mode) { } bool Audio::switchInputToAudioDevice(const QString& inputDeviceName) { + qDebug() << "DEBUG [" << inputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName).deviceName() << "]"; return switchInputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName)); } bool Audio::switchOutputToAudioDevice(const QString& outputDeviceName) { + qDebug() << "DEBUG [" << outputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName).deviceName() << "]"; return switchOutputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName)); } @@ -343,7 +348,7 @@ void Audio::handleAudioInput() { QByteArray inputByteArray = _inputDevice->readAll(); - if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio) && !_muted) { + if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio) && !_muted && _audioOutput) { // if this person wants local loopback add that to the locally injected audio if (!_loopbackOutputDevice && _loopbackAudioOutput) { @@ -356,7 +361,7 @@ void Audio::handleAudioInput() { _loopbackOutputDevice->write(inputByteArray); } } else { - static float loopbackOutputToInputRatio = (_outputFormat.sampleRate() / (float) _inputFormat.sampleRate()) + float loopbackOutputToInputRatio = (_outputFormat.sampleRate() / (float) _inputFormat.sampleRate()) * (_outputFormat.channelCount() / _inputFormat.channelCount()); QByteArray loopBackByteArray(inputByteArray.size() * loopbackOutputToInputRatio, 0); @@ -381,9 +386,6 @@ void Audio::handleAudioInput() { // zero out the monoAudioSamples array and the locally injected audio memset(monoAudioSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL); - // zero out the locally injected audio in preparation for audio procedural sounds - memset(_localProceduralSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL); - if (!_muted) { // we aren't muted, downsample the input audio linearResampling((int16_t*) inputAudioSamples, @@ -492,28 +494,8 @@ void Audio::handleAudioInput() { _lastInputLoudness = 0; } - // add procedural effects to the appropriate input samples - addProceduralSounds(monoAudioSamples, - NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); - - if (!_proceduralOutputDevice && _proceduralAudioOutput) { - _proceduralOutputDevice = _proceduralAudioOutput->start(); - } - - // send whatever procedural sounds we want to locally loop back to the _proceduralOutputDevice - QByteArray proceduralOutput; - proceduralOutput.resize(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * _outputFormat.sampleRate() * - _outputFormat.channelCount() * sizeof(int16_t) / (_desiredInputFormat.sampleRate() * - _desiredInputFormat.channelCount())); - - linearResampling(_localProceduralSamples, - reinterpret_cast(proceduralOutput.data()), - NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL, - proceduralOutput.size() / sizeof(int16_t), - _desiredInputFormat, _outputFormat); - - if (_proceduralOutputDevice) { - _proceduralOutputDevice->write(proceduralOutput); + if (_proceduralAudioOutput) { + processProceduralAudio(monoAudioSamples, NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); } NodeList* nodeList = NodeList::getInstance(); @@ -593,9 +575,43 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) { } } + if (_audioOutput) { + // Audio output must exist and be correctly set up if we're going to process received audio + processReceivedAudio(audioByteArray); + } + + Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AUDIO).updateValue(audioByteArray.size()); + + _lastReceiveTime = currentReceiveTime; +} + +bool Audio::mousePressEvent(int x, int y) { + if (_iconBounds.contains(x, y)) { + toggleMute(); + return true; + } + return false; +} + +void Audio::toggleMute() { + _muted = !_muted; + muteToggled(); +} + +void Audio::toggleAudioNoiseReduction() { + _noiseGateEnabled = !_noiseGateEnabled; +} + +void Audio::processReceivedAudio(const QByteArray& audioByteArray) +{ _ringBuffer.parseData(audioByteArray); - static float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float) _outputFormat.sampleRate()) + float outSampleRate = _outputFormat.sampleRate(); + float desSampleRate = _desiredOutputFormat.sampleRate(); + int outChannelCount = _outputFormat.channelCount(); + int desChannelCount = _desiredOutputFormat.channelCount(); + float myOutputRatio = desSampleRate / outSampleRate * (desChannelCount / outChannelCount); + float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float) _outputFormat.sampleRate()) * (_desiredOutputFormat.channelCount() / (float) _outputFormat.channelCount()); if (!_ringBuffer.isStarved() && _audioOutput && _audioOutput->bytesFree() == _audioOutput->bufferSize()) { @@ -650,33 +666,38 @@ void Audio::addReceivedAudioToBuffer(const QByteArray& audioByteArray) { } delete[] ringBufferSamples; } - } - - Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::AUDIO).updateValue(audioByteArray.size()); - - _lastReceiveTime = currentReceiveTime; } -bool Audio::mousePressEvent(int x, int y) { - if (_iconBounds.contains(x, y)) { - toggleMute(); - return true; +void Audio::processProceduralAudio(int16_t* monoInput, int numSamples) { + + // zero out the locally injected audio in preparation for audio procedural sounds + // This is correlated to numSamples, so it really needs to be numSamples * sizeof(sample) + memset(_localProceduralSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL); + // add procedural effects to the appropriate input samples + addProceduralSounds(monoInput, NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + + if (!_proceduralOutputDevice) { + _proceduralOutputDevice = _proceduralAudioOutput->start(); + } + + // send whatever procedural sounds we want to locally loop back to the _proceduralOutputDevice + QByteArray proceduralOutput; + proceduralOutput.resize(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * _outputFormat.sampleRate() * + _outputFormat.channelCount() * sizeof(int16_t) / (_desiredInputFormat.sampleRate() * + _desiredInputFormat.channelCount())); + + linearResampling(_localProceduralSamples, + reinterpret_cast(proceduralOutput.data()), + NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL, + proceduralOutput.size() / sizeof(int16_t), + _desiredInputFormat, _outputFormat); + + if (_proceduralOutputDevice) { + _proceduralOutputDevice->write(proceduralOutput); } - return false; } -void Audio::toggleMute() { - _muted = !_muted; - muteToggled(); -} - -void Audio::toggleAudioNoiseReduction() { - _noiseGateEnabled = !_noiseGateEnabled; -} - - - // Take a pointer to the acquired microphone input samples and add procedural sounds void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) { float sample; diff --git a/interface/src/Audio.h b/interface/src/Audio.h index e1f2762ece..1e54fd22eb 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -165,9 +165,17 @@ private: // Audio callback in class context. inline void performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* outputRight); + // Process procedural audio by + // 1. Echo to the local procedural output device + // 2. Mix with the audio input + void processProceduralAudio(int16_t* monoInput, int numSamples); + // Add sounds that we want the user to not hear themselves, by adding on top of mic input signal void addProceduralSounds(int16_t* monoInput, int numSamples); + // Process received audio + void processReceivedAudio(const QByteArray& audioByteArray); + bool switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo); bool switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo); }; From 952ca928f195d0535e602d8407f2174f1d1383ca Mon Sep 17 00:00:00 2001 From: matsukaze Date: Wed, 2 Apr 2014 12:28:22 -0700 Subject: [PATCH 2/5] More audio fixes. Fix audio buffer size on Win. --- interface/src/Audio.cpp | 67 +++++++++++++++++++++++++++++++---------- interface/src/Audio.h | 7 +++++ 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 5e2524a54c..8cb4ecfecd 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -282,8 +282,6 @@ void linearResampling(int16_t* sourceSamples, int16_t* destinationSamples, } } -const int CALLBACK_ACCELERATOR_RATIO = 2; - void Audio::start() { // set up the desired audio format @@ -305,8 +303,11 @@ void Audio::start() { qDebug() << "The default audio output device is" << outputDeviceInfo.deviceName(); bool outputFormatSupported = switchOutputToAudioDevice(outputDeviceInfo); - if (!inputFormatSupported || !outputFormatSupported) { - qDebug() << "Unable to set up audio I/O because of a problem with input or output formats."; + if (!inputFormatSupported) { + qDebug() << "Unable to set up audio input because of a problem with input format."; + } + if (!outputFormatSupported) { + qDebug() << "Unable to set up audio output because of a problem with output format."; } } @@ -341,10 +342,9 @@ void Audio::handleAudioInput() { static int16_t* monoAudioSamples = (int16_t*) (monoAudioDataPacket + leadingBytes); - static float inputToNetworkInputRatio = _numInputCallbackBytes * CALLBACK_ACCELERATOR_RATIO - / NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL; + float inputToNetworkInputRatio = calculateDeviceToNetworkInputRatio(_numInputCallbackBytes); - static unsigned int inputSamplesRequired = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * inputToNetworkInputRatio; + unsigned int inputSamplesRequired = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * inputToNetworkInputRatio; QByteArray inputByteArray = _inputDevice->readAll(); @@ -606,11 +606,6 @@ void Audio::processReceivedAudio(const QByteArray& audioByteArray) { _ringBuffer.parseData(audioByteArray); - float outSampleRate = _outputFormat.sampleRate(); - float desSampleRate = _desiredOutputFormat.sampleRate(); - int outChannelCount = _outputFormat.channelCount(); - int desChannelCount = _desiredOutputFormat.channelCount(); - float myOutputRatio = desSampleRate / outSampleRate * (desChannelCount / outChannelCount); float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float) _outputFormat.sampleRate()) * (_desiredOutputFormat.channelCount() / (float) _outputFormat.channelCount()); @@ -861,13 +856,12 @@ bool Audio::switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo) { qDebug() << "The format to be used for audio input is" << _inputFormat; _audioInput = new QAudioInput(inputDeviceInfo, _inputFormat, this); - _numInputCallbackBytes = NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL * _inputFormat.channelCount() - * (_inputFormat.sampleRate() / SAMPLE_RATE) - / CALLBACK_ACCELERATOR_RATIO; + _numInputCallbackBytes = calculateNumberOfInputCallbackBytes(_inputFormat); _audioInput->setBufferSize(_numInputCallbackBytes); // how do we want to handle input working, but output not working? - _inputRingBuffer.resizeForFrameSize(_numInputCallbackBytes * CALLBACK_ACCELERATOR_RATIO / sizeof(int16_t)); + int numFrameSamples = calculateNumberOfFrameSamples(_numInputCallbackBytes); + _inputRingBuffer.resizeForFrameSize(numFrameSamples); _inputDevice = _audioInput->start(); connect(_inputDevice, SIGNAL(readyRead()), this, SLOT(handleAudioInput())); @@ -924,3 +918,44 @@ bool Audio::switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo) } return supportedFormat; } + +// The following constant is operating system dependent due to differences in +// the way input audio is handled. The audio input buffer size is inversely +// proportional to the accelerator ratio. + +#ifdef Q_OS_WIN +const float Audio::CALLBACK_ACCELERATOR_RATIO = 0.4f; +#endif + +#ifdef Q_OS_MAC +const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f; +#endif + +#ifdef Q_OS_LINUX +const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f; +#endif + +int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) +{ + int numInputCallbackBytes = (int)(((NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + * format.channelCount() + * (format.sampleRate() / SAMPLE_RATE)) + / CALLBACK_ACCELERATOR_RATIO) + 0.5f); + + return numInputCallbackBytes; +} + +float Audio::calculateDeviceToNetworkInputRatio(int numBytes) +{ + float inputToNetworkInputRatio = (int)((_numInputCallbackBytes + * CALLBACK_ACCELERATOR_RATIO + / NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL) + 0.5f); + + return inputToNetworkInputRatio; +} + +int Audio::calculateNumberOfFrameSamples(int numBytes) +{ + int frameSamples = (int)(numBytes * CALLBACK_ACCELERATOR_RATIO + 0.5f) / sizeof(int16_t); + return frameSamples; +} diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 1e54fd22eb..896ab3c3fb 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -178,6 +178,13 @@ private: bool switchInputToAudioDevice(const QAudioDeviceInfo& inputDeviceInfo); bool switchOutputToAudioDevice(const QAudioDeviceInfo& outputDeviceInfo); + + // Callback acceleration dependent calculations + static const float CALLBACK_ACCELERATOR_RATIO; + int calculateNumberOfInputCallbackBytes(const QAudioFormat& format); + int calculateNumberOfFrameSamples(int numBytes); + float calculateDeviceToNetworkInputRatio(int numBytes); + }; From 94a23b7ffccd062ce9093ddd6c361f1517f54590 Mon Sep 17 00:00:00 2001 From: matsukaze Date: Wed, 2 Apr 2014 14:15:20 -0700 Subject: [PATCH 3/5] Fix brace location and replace tab with space. --- interface/src/Audio.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 8cb4ecfecd..4b6cec2e50 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -95,7 +95,7 @@ void Audio::reset() { QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { QAudioDeviceInfo result; foreach(QAudioDeviceInfo audioDevice, QAudioDeviceInfo::availableDevices(mode)) { - qDebug() << audioDevice.deviceName() << " " << deviceName; + qDebug() << audioDevice.deviceName() << " " << deviceName; if (audioDevice.deviceName().trimmed() == deviceName.trimmed()) { result = audioDevice; } @@ -602,8 +602,7 @@ void Audio::toggleAudioNoiseReduction() { _noiseGateEnabled = !_noiseGateEnabled; } -void Audio::processReceivedAudio(const QByteArray& audioByteArray) -{ +void Audio::processReceivedAudio(const QByteArray& audioByteArray) { _ringBuffer.parseData(audioByteArray); float networkOutputToOutputRatio = (_desiredOutputFormat.sampleRate() / (float) _outputFormat.sampleRate()) @@ -935,8 +934,7 @@ const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f; const float Audio::CALLBACK_ACCELERATOR_RATIO = 2.0f; #endif -int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) -{ +int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) { int numInputCallbackBytes = (int)(((NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL * format.channelCount() * (format.sampleRate() / SAMPLE_RATE)) @@ -945,8 +943,7 @@ int Audio::calculateNumberOfInputCallbackBytes(const QAudioFormat& format) return numInputCallbackBytes; } -float Audio::calculateDeviceToNetworkInputRatio(int numBytes) -{ +float Audio::calculateDeviceToNetworkInputRatio(int numBytes) { float inputToNetworkInputRatio = (int)((_numInputCallbackBytes * CALLBACK_ACCELERATOR_RATIO / NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL) + 0.5f); @@ -954,8 +951,7 @@ float Audio::calculateDeviceToNetworkInputRatio(int numBytes) return inputToNetworkInputRatio; } -int Audio::calculateNumberOfFrameSamples(int numBytes) -{ +int Audio::calculateNumberOfFrameSamples(int numBytes) { int frameSamples = (int)(numBytes * CALLBACK_ACCELERATOR_RATIO + 0.5f) / sizeof(int16_t); return frameSamples; } From 75429179223a579c2e8afb9f3a6b036b1361af4f Mon Sep 17 00:00:00 2001 From: matsukaze Date: Wed, 2 Apr 2014 14:22:17 -0700 Subject: [PATCH 4/5] Fix tab with space. --- interface/src/Audio.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 4b6cec2e50..c7e11b74d2 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -325,12 +325,12 @@ QVector Audio::getDeviceNames(QAudio::Mode mode) { } bool Audio::switchInputToAudioDevice(const QString& inputDeviceName) { - qDebug() << "DEBUG [" << inputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName).deviceName() << "]"; + qDebug() << "DEBUG [" << inputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName).deviceName() << "]"; return switchInputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioInput, inputDeviceName)); } bool Audio::switchOutputToAudioDevice(const QString& outputDeviceName) { - qDebug() << "DEBUG [" << outputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName).deviceName() << "]"; + qDebug() << "DEBUG [" << outputDeviceName << "] [" << getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName).deviceName() << "]"; return switchOutputToAudioDevice(getNamedAudioDeviceForMode(QAudio::AudioOutput, outputDeviceName)); } @@ -682,10 +682,10 @@ void Audio::processProceduralAudio(int16_t* monoInput, int numSamples) { _desiredInputFormat.channelCount())); linearResampling(_localProceduralSamples, - reinterpret_cast(proceduralOutput.data()), - NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL, - proceduralOutput.size() / sizeof(int16_t), - _desiredInputFormat, _outputFormat); + reinterpret_cast(proceduralOutput.data()), + NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL, + proceduralOutput.size() / sizeof(int16_t), + _desiredInputFormat, _outputFormat); if (_proceduralOutputDevice) { _proceduralOutputDevice->write(proceduralOutput); From d28d686ceba67511f844eb4afb31d8c0f47e29e0 Mon Sep 17 00:00:00 2001 From: matsukaze Date: Wed, 2 Apr 2014 17:45:22 -0700 Subject: [PATCH 5/5] Fix for missing voxel system on domain change. Fix for assertion failure thrown by Qt on exit. --- interface/src/ui/overlays/ImageOverlay.cpp | 9 +++++---- interface/src/ui/overlays/ImageOverlay.h | 2 ++ interface/src/voxels/VoxelSystem.cpp | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/overlays/ImageOverlay.cpp b/interface/src/ui/overlays/ImageOverlay.cpp index 178383749b..ac5c8ecefa 100644 --- a/interface/src/ui/overlays/ImageOverlay.cpp +++ b/interface/src/ui/overlays/ImageOverlay.cpp @@ -16,6 +16,7 @@ #include "ImageOverlay.h" ImageOverlay::ImageOverlay() : + _manager(0), _textureID(0), _renderImage(false), _textureBound(false), @@ -33,9 +34,9 @@ ImageOverlay::~ImageOverlay() { // TODO: handle setting image multiple times, how do we manage releasing the bound texture? void ImageOverlay::setImageURL(const QUrl& url) { // TODO: are we creating too many QNetworkAccessManager() when multiple calls to setImageURL are made? - QNetworkAccessManager* manager = new QNetworkAccessManager(this); - connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); - manager->get(QNetworkRequest(url)); + _manager = new QNetworkAccessManager(); + connect(_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); + _manager->get(QNetworkRequest(url)); } void ImageOverlay::replyFinished(QNetworkReply* reply) { @@ -44,7 +45,7 @@ void ImageOverlay::replyFinished(QNetworkReply* reply) { QByteArray rawData = reply->readAll(); _textureImage.loadFromData(rawData); _renderImage = true; - + _manager->deleteLater(); } void ImageOverlay::render() { diff --git a/interface/src/ui/overlays/ImageOverlay.h b/interface/src/ui/overlays/ImageOverlay.h index 77cac3b3c6..d6165e388d 100644 --- a/interface/src/ui/overlays/ImageOverlay.h +++ b/interface/src/ui/overlays/ImageOverlay.h @@ -49,6 +49,8 @@ private: QUrl _imageURL; QImage _textureImage; + QNetworkAccessManager* _manager; + GLuint _textureID; QRect _fromImage; // where from in the image to sample bool _renderImage; // is there an image associated with this overlay, or is it just a colored rectangle diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index 5c68485436..bb907c8a9a 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -1508,7 +1508,9 @@ void VoxelSystem::killLocalVoxels() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "VoxelSystem::killLocalVoxels()"); _tree->lockForWrite(); + VoxelSystem* voxelSystem = _tree->getRoot()->getVoxelSystem(); _tree->eraseAllOctreeElements(); + _tree->getRoot()->setVoxelSystem(voxelSystem); _tree->unlock(); clearFreeBufferIndexes(); if (_usePrimitiveRenderer) {