void CCompChoppyThrower::ReceiveMessage(SMessage &msg) { if (msg.m_type == EMT_SHOOT && m_lastShot >= GetCooldown()) { SShootMsg &shootMsg = static_cast<SShootMsg &>(msg); if (shootMsg.GetWeaponId() == GetId()) { SGetWorldMsg worldMsg; m_owner->ReceiveMessage(worldMsg); CWorld * world = worldMsg.GetWorld(); SGetRotMsg rotMsg; m_owner->ReceiveMessage(rotMsg); SGetPosMsg posMsg; m_owner->ReceiveMessage(posMsg); SGetEnergyMsg getEnergyMsg; m_owner->ReceiveMessage(getEnergyMsg); if (rotMsg.Modified() && getEnergyMsg.Modified() && getEnergyMsg.GetEnergy() - GetEnergyConsumed() > 0) { world->AddEntity(world->GetEntitiesFactory().SpawnEntity( new SBotParams(m_owner->GetSide(), GetImg(), posMsg.GetX(), posMsg.GetY(), m_botLifeTime, GetDamage(), m_speed))); SUpdateEnergyMsg updateEnergyMsg(-GetEnergyConsumed()); m_owner->ReceiveMessage(updateEnergyMsg); m_lastShot = 0; AudioBuffer * buffer = new AudioBuffer("data/sounds/fusion_blaster_shoot.wav"); AudioSource * shootAudio = new AudioSource(buffer); shootAudio->Play(); } } } }
int lua_AudioSource_setPitch(lua_State* state) { // Get the number of parameters. int paramCount = lua_gettop(state); // Attempt to match the parameters to a valid binding. switch (paramCount) { case 2: { if ((lua_type(state, 1) == LUA_TUSERDATA) && lua_type(state, 2) == LUA_TNUMBER) { // Get parameter 1 off the stack. float param1 = (float)luaL_checknumber(state, 2); AudioSource* instance = getInstance(state); instance->setPitch(param1); return 0; } lua_pushstring(state, "lua_AudioSource_setPitch - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } default: { lua_pushstring(state, "Invalid number of parameters (expected 2)."); lua_error(state); break; } } return 0; }
void alSourceUnqueueBuffers(ALuint source, ALsizei n, ALuint* buffers) { DEBUGLOGCALL(LCF_OPENAL); AudioSource* as = audiocontext.getSource(source); if (as == nullptr) return; /* Check if we can unqueue that number of buffers */ int processedBuffers; if (as->state == SOURCE_STOPPED) processedBuffers = as->nbQueue(); else processedBuffers = as->nbQueueProcessed(); if (processedBuffers < n) { ALSETERROR(AL_INVALID_VALUE); return; } debuglog(LCF_OPENAL, "Unqueueing ", n, " buffers out of ", as->nbQueue()); std::lock_guard<std::mutex> lock(audiocontext.mutex); /* Save the id of the unqueued buffers */ for (int i=0; i<n; i++) { buffers[i] = as->buffer_queue[i]->id; } /* Remove the buffers from the queue. * TODO: This is slow on a vector, maybe use forward_list? */ as->buffer_queue.erase(as->buffer_queue.begin(), as->buffer_queue.begin()+n); if (as->state != SOURCE_STOPPED) as->queue_index -= n; }
int lua_AudioSource_isStreamed(lua_State* state) { // Get the number of parameters. int paramCount = lua_gettop(state); // Attempt to match the parameters to a valid binding. switch (paramCount) { case 1: { if ((lua_type(state, 1) == LUA_TUSERDATA)) { AudioSource* instance = getInstance(state); bool result = instance->isStreamed(); // Push the return value onto the stack. lua_pushboolean(state, result); return 1; } lua_pushstring(state, "lua_AudioSource_isStreamed - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } default: { lua_pushstring(state, "Invalid number of parameters (expected 1)."); lua_error(state); break; } } return 0; }
int lua_AudioSource_setLooped(lua_State* state) { // Get the number of parameters. int paramCount = lua_gettop(state); // Attempt to match the parameters to a valid binding. switch (paramCount) { case 2: { if ((lua_type(state, 1) == LUA_TUSERDATA) && lua_type(state, 2) == LUA_TBOOLEAN) { // Get parameter 1 off the stack. bool param1 = gameplay::ScriptUtil::luaCheckBool(state, 2); AudioSource* instance = getInstance(state); instance->setLooped(param1); return 0; } lua_pushstring(state, "lua_AudioSource_setLooped - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } default: { lua_pushstring(state, "Invalid number of parameters (expected 2)."); lua_error(state); break; } } return 0; }
void AudioManager::play_sample_playlist(SamplePlaylist *playlist, float volume) { AudioSource *src; if (!playlist->started){ src = request_source(&playlist->source_idx); if (src){ playlist->it = playlist->samples.begin(); src->set_sample((*playlist->it)); src->set_volume(volume); src->set_playback_volume(volume); src->play(); playlist->it++; playlist->started = true; } } else{ src = get_audio_source(playlist->source_idx); if (src && !src->is_playing()){ if (!(playlist->it == playlist->samples.end())){ src->set_sample((*playlist->it)); src->set_volume(volume); src->set_playback_volume(volume); src->play(); playlist->it++; } } } if (playlist->loop && playlist->it == playlist->samples.end()) playlist->it = playlist->samples.begin(); }
int lua_AudioSource_stop(lua_State* state) { // Get the number of parameters. int paramCount = lua_gettop(state); // Attempt to match the parameters to a valid binding. switch (paramCount) { case 1: { if ((lua_type(state, 1) == LUA_TUSERDATA)) { AudioSource* instance = getInstance(state); instance->stop(); return 0; } else { lua_pushstring(state, "lua_AudioSource_stop - Failed to match the given parameters to a valid function signature."); lua_error(state); } break; } default: { lua_pushstring(state, "Invalid number of parameters (expected 1)."); lua_error(state); break; } } return 0; }
SdlAudioSink::SdlAudioSink(const AudioSource &source, int device_id) : bytes_per_sample(source.BytesPerSample()), ring_buf(RINGBUF_POWER, source.BytesPerSample()), position_sample_count(0), source_out(false), state(Audio::State::STOPPED) { const char *name = SDL_GetAudioDeviceName(device_id, 0); if (name == nullptr) { throw ConfigError(std::string("invalid device id: ") + std::to_string(device_id)); } SDL_AudioSpec want; SDL_zero(want); want.freq = source.SampleRate(); want.format = FORMATS[static_cast<int>(source.OutputSampleFormat())]; want.channels = source.ChannelCount(); want.callback = &SDLCallback; want.userdata = (void *)this; SDL_AudioSpec have; SDL_zero(have); this->device = SDL_OpenAudioDevice(name, 0, &want, &have, 0); if (this->device == 0) { throw ConfigError(std::string("couldn't open device: ") + SDL_GetError()); } }
void AudioManager::stop_source(int source_idx) { if (source_idx < 0) return; AudioSource *src = get_audio_source(source_idx); if (src && src->is_playing()) src->stop(); }
void AudioStereoOutput::connect(AudioSource &source) { if(source.getAudioOutputCount() == 1) { portLeft->connect(source.getAudioConnection(0)); portRight->connect(source.getAudioConnection(0)); } else { portLeft->connect(source.getAudioConnection(0)); portRight->connect(source.getAudioConnection(1)); } }
void alSourcef(ALuint source, ALenum param, ALfloat value) { DEBUGLOGCALL(LCF_OPENAL); AudioSource* as = audiocontext.getSource(source); if (as == nullptr) { ALSETERROR(AL_INVALID_NAME); return; } AudioBuffer* ab; switch(param) { case AL_GAIN: as->volume = value; debuglog(LCF_OPENAL, " Set gain of ", value); break; case AL_PITCH: case AL_MIN_GAIN: case AL_MAX_GAIN: case AL_MAX_DISTANCE: case AL_ROLLOFF_FACTOR: case AL_CONE_OUTER_GAIN: case AL_CONE_INNER_ANGLE: case AL_CONE_OUTER_ANGLE: case AL_REFERENCE_DISTANCE: debuglog(LCF_OPENAL, "Operation not supported"); break; case AL_SEC_OFFSET: /* We fetch the buffer format of the source. * Normally, all buffers from a queue share the exact same format. */ if (! as->buffer_queue.empty()) { ab = as->buffer_queue[0]; debuglog(LCF_OPENAL, " Set position of ", value, " seconds"); value *= (ALfloat) ab->frequency; as->setPosition((int)value); } break; case AL_SAMPLE_OFFSET: /* We fetch the buffer format of the source. * Normally, all buffers from a queue share the exact same format. */ debuglog(LCF_OPENAL, " Set position of ", value, " samples"); as->setPosition((int)value); break; case AL_BYTE_OFFSET: if (! as->buffer_queue.empty()) { ab = as->buffer_queue[0]; value /= (ALfloat) ab->alignSize; debuglog(LCF_OPENAL, " Set position of ", value, " bytes"); as->setPosition((int)value); } break; default: ALSETERROR(AL_INVALID_OPERATION); return; } }
void AudioTransportSourceMod::setSource (PositionableAudioSource* const newSource, int numberOfChannels, int readAheadBufferSize_) { if (source == newSource) { if (source == 0) return; setSource (0, 0, 0); // deselect and reselect to avoid releasing resources wrongly } readAheadBufferSize = readAheadBufferSize_; BufferingAudioSourceMod* newBufferingSource = 0; PositionableAudioSource* newPositionableSource = 0; AudioSource* newMasterSource = 0; ScopedPointer <BufferingAudioSourceMod> oldBufferingSource (bufferingSource); // Deletes the object when this section of code is left. AudioSource* oldMasterSource = masterSource; if (newSource != 0) { newPositionableSource = newSource; if (readAheadBufferSize_ > 0) newPositionableSource = newBufferingSource = new BufferingAudioSourceMod (newPositionableSource, false, numberOfChannels, readAheadBufferSize_); newPositionableSource->setNextReadPosition (0); newMasterSource = newPositionableSource; if (isPrepared) { newMasterSource->prepareToPlay (blockSize, sampleRate); } } { const ScopedLock sl (callbackLock); source = newSource; bufferingSource = newBufferingSource; masterSource = newMasterSource; positionableSource = newPositionableSource; playing = false; } if (oldMasterSource != 0) oldMasterSource->releaseResources(); }
void SceneManager::pop() { if (m_activeList.empty()) { throw std::runtime_error("Attempted to pop from an empty game state stack"); } bool poppingExclusive = false; if (m_activeList.back().second == Modality::Exclusive) { poppingExclusive = true; } delete m_activeList.back().first; m_activeList.pop_back(); if (!m_activeList.empty()) { updateExclusiveScene(); if (!poppingExclusive) { m_activeList.back().first->notifyUncoveredObjects(); } auto go = m_activeList.back().first->getAllGameObjects(); for (size_t i = 0; i < go.size(); i++) { //go[i]->activate(); if (poppingExclusive) { go[i]->setEnabled(go[i]->wasEnabled(), false); } } if (poppingExclusive) { go = m_activeList[m_exclusiveScene].first->getAllGameObjects(); for (size_t i = 0; i < go.size(); i++) { AudioSource * audio = go[i]->getGameComponent<AudioSource>(); if (audio != nullptr) { if (audio->getType() == AudioType::STREAM && audio->wasPlaying()) { audio->play(); } } } } } }
void alSourcePlay(ALuint source) { DEBUGLOGCALL(LCF_OPENAL); AudioSource* as = audiocontext.getSource(source); if (as == nullptr) return; if (as->state == SOURCE_PLAYING) { /* Restart the play from the beginning */ as->setPosition(0); } as->state = SOURCE_PLAYING; }
void alSourceStop(ALuint source) { DEBUGLOGCALL(LCF_OPENAL); AudioSource* as = audiocontext.getSource(source); if (as == nullptr) return; if ((as->state == SOURCE_INITIAL) || (as->state == SOURCE_STOPPED)) { /* Illegal operation. */ return; } as->init(); as->state = SOURCE_STOPPED; }
void alSourceRewind(ALuint source) { DEBUGLOGCALL(LCF_OPENAL); AudioSource* as = audiocontext.getSource(source); if (as == nullptr) return; if (as->state == SOURCE_INITIAL) { /* Illegal operation. */ return; } as->setPosition(0); as->state = SOURCE_INITIAL; }
void SceneManager::push(Scene* scene, Modality modality /*= Modality::Exclusive*/) { if (!m_activeList.empty()) { auto go = m_activeList.back().first->getAllGameObjects(); for (size_t i = 0; i < go.size(); i++) { //go[i]->deactivate(); if (modality == Modality::Exclusive) { go[i]->setWasEnabled(go[i]->isEnabled()); go[i]->setEnabled(false, false); AudioSource * audio = go[i]->getGameComponent<AudioSource>(); if (audio != nullptr) { if (audio->getType() == AudioType::STREAM) { audio->setWasPlaying(audio->isPlaying()); // pause music audio->stop(); } } } } } if (modality == Modality::Popup) { m_activeList.back().first->notifyCoveredObjects(); } m_activeList.push_back(std::make_pair(scene, modality)); scene->init(*m_viewport); scene->setEngine(m_coreEngine); auto attachedToRoot = scene->getRoot()->getAllAttached(); for (size_t i = attachedToRoot.size() - 1; i > 0; i--) { auto gameComponents = attachedToRoot[i]->getAllGameComponents(); for (size_t j = 0; j < gameComponents.size(); j++) { gameComponents[j]->onStart(); } } updateExclusiveScene(); }
void SourceObject::SetCurrentSource (const AudioSource& source) { IsSeeking_ = false; CurrentSource_ = source; Metadata_.clear (); if (source.ToUrl ().scheme ().startsWith ("http")) PrevSoupRank_ = SetSoupRank (G_MAXINT / 2); auto path = source.ToUrl ().toEncoded (); g_object_set (G_OBJECT (Dec_), "uri", path.constData (), nullptr); NextSource_.Clear (); }
int Soloud::play(AudioSource &aSound, float aVolume, float aPan, int aPaused, int aBus) { if (aSound.mFlags & AudioSource::SINGLE_INSTANCE) { // Only one instance allowed, stop others stopSound(aSound); } if (mLockMutexFunc) mLockMutexFunc(mMutex); int ch = findFreeVoice(); if (ch < 0) { if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex); return -1; } if (!aSound.mAudioSourceID) { aSound.mAudioSourceID = mAudioSourceID; mAudioSourceID++; aSound.mSoloud = this; } mVoice[ch] = aSound.createInstance(); mVoice[ch]->mAudioSourceID = aSound.mAudioSourceID; mVoice[ch]->mBusHandle = aBus; mVoice[ch]->init(mPlayIndex, aSound.mBaseSamplerate, aSound.mChannels, aSound.mFlags); mPlayIndex++; if (aPaused) { mVoice[ch]->mFlags |= AudioSourceInstance::PAUSED; } setVoicePan(ch, aPan); setVoiceVolume(ch, aVolume); setVoiceRelativePlaySpeed(ch, 1); int i; for (i = 0; i < FILTERS_PER_STREAM; i++) { if (aSound.mFilter[i]) { mVoice[ch]->mFilter[i] = aSound.mFilter[i]->createInstance(); } } int scratchneeded = SAMPLE_GRANULARITY * mVoice[ch]->mChannels; mVoice[ch]->mResampleData[0]->mBuffer = new float[scratchneeded]; mVoice[ch]->mResampleData[1]->mBuffer = new float[scratchneeded]; // First buffer will be overwritten anyway; the second may be referenced by resampler memset(mVoice[ch]->mResampleData[0]->mBuffer, 0, sizeof(float) * scratchneeded); memset(mVoice[ch]->mResampleData[1]->mBuffer, 0, sizeof(float) * scratchneeded); if (mUnlockMutexFunc) mUnlockMutexFunc(mMutex); int handle = getHandleFromVoice(ch); return handle; }
void AudioController::pause() { std::set<AudioSource*>::iterator itr = _playingSources.begin(); // For each source that is playing, pause it. AudioSource* source = NULL; while (itr != _playingSources.end()) { GP_ASSERT(*itr); source = *itr; _pausingSource = source; source->pause(); _pausingSource = NULL; itr++; } }
void AudioController::resume() { alcMakeContextCurrent(_alcContext); std::set<AudioSource*>::iterator itr = _playingSources.begin(); // For each source that is playing, resume it. AudioSource* source = NULL; while (itr != _playingSources.end()) { GP_ASSERT(*itr); source = *itr; source->resume(); itr++; } }
void AudioController::pause() { std::list<AudioSource*>::iterator itr = _playingSources.begin(); // For each source that is playing, pause it. AudioSource* source = NULL; while (itr != _playingSources.end()) { source = *itr; if (source->getState() == AudioSource::PLAYING) { source->pause(); } itr++; } }
AudioSource* AudioSource::create(Properties* properties) { // Check if the properties is valid and has a valid namespace. assert(properties); if (!properties || !(strcmp(properties->getNamespace(), "audio") == 0)) { WARN("Failed to load audio source from properties object: must be non-null object and have namespace equal to \'audio\'."); return NULL; } const char* path = properties->getString("path"); if (path == NULL) { WARN("Audio file failed to load; the file path was not specified."); return NULL; } // Create the audio source. AudioSource* audio = AudioSource::create(path); if (audio == NULL) { WARN_VARG("Audio file '%s' failed to load properly.", path); return NULL; } // Set any properties that the user specified in the .audio file. if (properties->getString("looped") != NULL) { audio->setLooped(properties->getBool("looped")); } if (properties->getString("gain") != NULL) { audio->setGain(properties->getFloat("gain")); } if (properties->getString("pitch") != NULL) { audio->setPitch(properties->getFloat("pitch")); } Vector3 v; if (properties->getVector3("velocity", &v)) { audio->setVelocity(v); } return audio; }
AudioSource* AudioSource::create(Properties* properties) { // Check if the properties is valid and has a valid namespace. GP_ASSERT(properties); if (!properties || !(strcmp(properties->getNamespace(), "audio") == 0)) { GP_ERROR("Failed to load audio source from properties object: must be non-null object and have namespace equal to 'audio'."); return NULL; } std::string path; if (!properties->getPath("path", &path)) { GP_ERROR("Audio file failed to load; the file path was not specified."); return NULL; } // Create the audio source. AudioSource* audio = AudioSource::create(path.c_str()); if (audio == NULL) { GP_ERROR("Audio file '%s' failed to load properly.", path.c_str()); return NULL; } // Set any properties that the user specified in the .audio file. if (properties->exists("looped")) { audio->setLooped(properties->getBool("looped")); } if (properties->exists("gain")) { audio->setGain(properties->getFloat("gain")); } if (properties->exists("pitch")) { audio->setPitch(properties->getFloat("pitch")); } Vector3 v; if (properties->getVector3("velocity", &v)) { audio->setVelocity(v); } return audio; }
void Execute( void ) { ogst::unique_lock<ogst::mutex> lock(emitter->mutex); if ( emitter->IsValidChannel( channel ) ) { AudioSource *source = emitter->sndChannels[channel]; if ( source == OG_NULL ) source = audioSystemObject.audioThread->FindFreeAudioSource(); if ( source ) { if ( source->Play( emitter, channel, sound, allowLoop ) ) { emitter->sndChannels[channel] = source; emitter->sndChannels[channel]->OnUpdate( &emitter->details ); } return; } User::Warning("No more free sound Sources!"); } }
bool AudioFormatWriter::writeFromAudioSource (AudioSource& source, int numSamplesToRead, const int samplesPerBlock) { const int maxChans = 128; AudioSampleBuffer tempBuffer (getNumChannels(), samplesPerBlock); int* buffers [maxChans]; while (numSamplesToRead > 0) { const int numToDo = jmin (numSamplesToRead, samplesPerBlock); AudioSourceChannelInfo info; info.buffer = &tempBuffer; info.startSample = 0; info.numSamples = numToDo; info.clearActiveBufferRegion(); source.getNextAudioBlock (info); int i; for (i = maxChans; --i >= 0;) buffers[i] = 0; for (i = tempBuffer.getNumChannels(); --i >= 0;) buffers[i] = (int*) tempBuffer.getSampleData (i, 0); if (! isFloatingPoint()) { int** bufferChan = buffers; while (*bufferChan != 0) { int* b = *bufferChan++; // float -> int for (int j = numToDo; --j >= 0;) { const double samp = *(const float*) b; if (samp <= -1.0) *b++ = INT_MIN; else if (samp >= 1.0) *b++ = INT_MAX; else *b++ = roundToInt (INT_MAX * samp); } } } if (! write ((const int**) buffers, numToDo)) return false; numSamplesToRead -= numToDo; } return true; }
int lua_AudioSource_getVelocity(lua_State* state) { // Get the number of parameters. int paramCount = lua_gettop(state); // Attempt to match the parameters to a valid binding. switch (paramCount) { case 1: { if ((lua_type(state, 1) == LUA_TUSERDATA)) { AudioSource* instance = getInstance(state); void* returnPtr = (void*)&(instance->getVelocity()); if (returnPtr) { ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject)); object->instance = returnPtr; object->owns = false; luaL_getmetatable(state, "Vector3"); lua_setmetatable(state, -2); } else { lua_pushnil(state); } return 1; } else { lua_pushstring(state, "lua_AudioSource_getVelocity - Failed to match the given parameters to a valid function signature."); lua_error(state); } break; } default: { lua_pushstring(state, "Invalid number of parameters (expected 1)."); lua_error(state); break; } } return 0; }
void Lv2Plugin::connect(AudioSource &source) { if(audioInputCount == 0) { throw std::logic_error("cannot connect: this plugin has no audio inputs"); } if(audioInputCount == 2 && source.getAudioOutputCount() == 1) { // mono to stereo audioInput[0].setConnection(source.getAudioConnection(0), this); audioInput[1].setConnection(source.getAudioConnection(0), this); } else if(audioInputCount == source.getAudioOutputCount()) { for(uint32_t i = 0; i < audioInputCount; i++) { audioInput[i].setConnection(source.getAudioConnection(i), this); } } else { throw std::logic_error("cannot connect: different number of input/output connections"); } }
// Decode bool Sound::decode(const RString& path, SoundInfo& info, float** data) { bool decoded = false; AudioSource* source = 0; if (path.find(OGG_FILE_EXT) != RString::npos) { #if MOAI_WITH_VORBIS OggAudioSource* as = new OggAudioSource(); source = as; if(as->init(path, true)) decoded = true; #endif } else { #if defined(__APPLE__) ExtAudioFileAudioSource *as = new ExtAudioFileAudioSource(); source = as; if(as->init(path, true)) decoded = true; #elif defined(__ANDROID__) | defined(__linux__) | defined(__OPENAL__) | defined ( __QNX__ ) WaveFileAudioSource *as = new WaveFileAudioSource(); source = as; if(as->init(path, true)) decoded = true; #else DShowAudioSource* as = new DShowAudioSource(); source = as; if(as->init(path, true)) decoded = true; #endif } // Couldn't decode the file if(!decoded) { if(source) delete source; return false; } RAudioBuffer* buffer = source->getBuffer(); UInt32 size = buffer->getDataSize(); // Allocate space and copy the buffer *data = (float*)new char[size]; buffer->copyInto(*data); info.mChannels = source->getNumChannels(); info.mBitsPerSample = 32; info.mSampleRate = source->getSampleRate(); info.mTotalFrames = size / 4 / source->getNumChannels(); info.mLength = (double)size / 4.0 / source->getNumChannels() / source->getSampleRate(); if(source) delete source; return true; }
void SlingshotSmokeApp::setup() { mVolumeMult = 5.0; mLastTime = 0; getWindowIndex(0)->getSignalDraw().connect([=]() { drawRender(); }); mAudioSource = AudioSource(); mAudioSource.setup(); vec2 fluidResolution = vec2(512); vec2 smokeResolution = app::getWindowSize(); mFluid = Fluid(fluidResolution); mSmokers.reserve(2); mSmokers.push_back(shared_ptr<FakeSmoker>(new FakeSmoker(fluidResolution, smokeResolution))); mSmokers.push_back(shared_ptr<PositionSmoker>(new PositionSmoker(fluidResolution, smokeResolution))); mSmokers.push_back(shared_ptr<TransitionSmoker>(new TransitionSmoker(fluidResolution, smokeResolution))); mSmokers.push_back(shared_ptr<BottomSmoker>(new BottomSmoker(fluidResolution, smokeResolution))); mCurrentSmoker = 0; mSmokers[mCurrentSmoker]->light(vec2(0.5, 0.2), mParams); gl::GlslProg::Format renderFormat; renderFormat.vertex(app::loadAsset("passthru.vert")); renderFormat.fragment(app::loadAsset("Smokers/smoke_draw.frag")); mRenderProg = gl::GlslProg::create(renderFormat); mRenderProg->uniform("i_resolution", smokeResolution); gl::Texture2d::Format texFmt; texFmt.setInternalFormat(GL_RGBA32F); texFmt.setDataType(GL_FLOAT); texFmt.setTarget(GL_TEXTURE_2D); texFmt.setWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); gl::Fbo::Format fmt; fmt.disableDepth() .setColorTextureFormat(texFmt); mSmokeField = PingPongFBO(fmt, smokeResolution, 4); // Do params last so that all the FBOs are in the right context vec2 paramsSize = vec2(255, 512); auto format = Window::Format(); format.setSize(paramsSize + vec2(40, 20)); format.setPos(ivec2(100)); WindowRef paramsWindow = createWindow(format); paramsWindow->getSignalDraw().connect([=]() { drawParams(); }); mParams = params::InterfaceGl::create(paramsWindow, "Options", paramsSize); mParams->addParam("Volume", &mVolumeMult) .max(10.0) .min(0.0) .step(0.1); }