bool GFileList::GetFullEffectName(gtuint uiIndex, gstring& outString) { const gchar* name = GetEffectName( uiIndex ); if( name == NULL ) return false; gchar fullPath[GN_MAX_PATH] = { 0, }; const char* workDir = GnSystem::GetWorkDirectory(); GnSprintf( fullPath, sizeof(fullPath), "%sEffect/%s/%s.gm", workDir, name, name ); outString = fullPath; return true; }
bool Effect::TotalProgress(double frac) { if (!mProgress && wxGetElapsedTime(false) > 500) { mProgress = new wxProgressDialog(GetEffectName(), GetEffectAction(), 1000, mParent, wxPD_CAN_ABORT | wxPD_REMAINING_TIME | wxPD_AUTO_HIDE); } bool cancelling = false; if (mProgress) { cancelling = !mProgress->Update((int)(frac*1000 + 0.5)); } return cancelling; }
bool Effect::DoEffect(wxWindow *parent, int flags, double projectRate, TrackList *list, TrackFactory *factory, double *t0, double *t1, wxString params) { wxASSERT(*t0 <= *t1); if (mOutputTracks) { delete mOutputTracks; mOutputTracks = NULL; } mFactory = factory; mProjectRate = projectRate; mParent = parent; mTracks = list; mT0 = *t0; mT1 = *t1; CountWaveTracks(); // Note: Init may read parameters from preferences if (!Init()) return false; // If a parameter string was provided, it overrides any remembered settings // (but if the user is to be prompted, that takes priority) if (!params.IsEmpty()) { ShuttleCli shuttle; shuttle.mParams = params; shuttle.mbStoreInClient=true; if( !TransferParameters( shuttle )) { wxMessageBox( wxString::Format( _("Could not set parameters of effect %s\n to %s."), GetEffectName().c_str(), params.c_str() ) ); return false; } } // Don't prompt user if we are dealing with a // effect that is already configured, e.g. repeating // the last effect on a different selection. if( (flags & CONFIGURED_EFFECT) == 0) { if (!PromptUser()) return false; } bool returnVal = true; bool skipFlag = CheckWhetherSkipEffect(); if (skipFlag == false) { mProgress = new ProgressDialog(StripAmpersand(GetEffectName()), GetEffectAction(), pdlgHideStopButton); returnVal = Process(); delete mProgress; } End(); if (mOutputTracks) { delete mOutputTracks; mOutputTracks = NULL; } if (returnVal) { *t0 = mT0; *t1 = mT1; } return returnVal; }
void Effect::Preview() { wxWindow* FocusDialog = wxWindow::FindFocus(); if (gAudioIO->IsBusy()) return; // Mix a few seconds of audio from all of the tracks double previewLen = 6.0; gPrefs->Read(wxT("/AudioIO/EffectsPreviewLen"), &previewLen); WaveTrack *mixLeft = NULL; WaveTrack *mixRight = NULL; double rate = mProjectRate; double t0 = mT0; double t1 = t0 + previewLen; if (t1 > mT1) t1 = mT1; if (t1 <= t0) return; bool success = ::MixAndRender(mTracks, mFactory, rate, floatSample, t0, t1, &mixLeft, &mixRight); if (!success) { return; } // Save the original track list TrackList *saveTracks = mTracks; // Build new tracklist from rendering tracks mTracks = new TrackList(); mixLeft->SetSelected(true); mTracks->Add(mixLeft); if (mixRight) { mixRight->SetSelected(true); mTracks->Add(mixRight); } // Update track/group counts CountWaveTracks(); // Reset times t0 = mixLeft->GetStartTime(); t1 = mixLeft->GetEndTime(); double t0save = mT0; double t1save = mT1; mT0 = t0; mT1 = t1; // Apply effect // Effect is already inited; we call Process, End, and then Init // again, so the state is exactly the way it was before Preview // was called. mProgress = new ProgressDialog(StripAmpersand(GetEffectName()), _("Preparing preview"), pdlgHideCancelButton); // Have only "Stop" button. bool bSuccess = Process(); delete mProgress; End(); Init(); if (bSuccess) { mT0 = t0save; mT1 = t1save; WaveTrackArray playbackTracks; WaveTrackArray recordingTracks; // Probably not the same tracks post-processing, so can't rely on previous values of mixLeft & mixRight. TrackListOfKindIterator iter(Track::Wave, mTracks); mixLeft = (WaveTrack*)(iter.First()); mixRight = (WaveTrack*)(iter.Next()); playbackTracks.Add(mixLeft); if (mixRight) playbackTracks.Add(mixRight); #ifdef EXPERIMENTAL_MIDI_OUT NoteTrackArray empty; #endif // Start audio playing int token = gAudioIO->StartStream(playbackTracks, recordingTracks, #ifdef EXPERIMENTAL_MIDI_OUT empty, #endif NULL, rate, t0, t1, NULL); if (token) { int previewing = eProgressSuccess; mProgress = new ProgressDialog(StripAmpersand(GetEffectName()), _("Previewing"), pdlgHideCancelButton); while (gAudioIO->IsStreamActive(token) && previewing == eProgressSuccess) { ::wxMilliSleep(100); previewing = mProgress->Update(gAudioIO->GetStreamTime() - t0, t1 - t0); } gAudioIO->StopStream(); while (gAudioIO->IsBusy()) { ::wxMilliSleep(100); } delete mProgress; } else { wxMessageBox(_("Error while opening sound device. Please check the output device settings and the project sample rate."), _("Error"), wxOK | wxICON_EXCLAMATION, FocusDialog); } } if (FocusDialog) { FocusDialog->SetFocus(); } delete mOutputTracks; mOutputTracks = NULL; mTracks->Clear(true); // true => delete the tracks delete mTracks; mTracks = saveTracks; }
wxString VampEffect::GetEffectAction() { return wxString::Format(_("Extracting features: %s"), GetEffectName().c_str()); }
bool VampEffect::Process() { if (!mPlugin) return false; TrackListIterator iter(mWaveTracks); int count = 0; WaveTrack *left = (WaveTrack *)iter.First(); bool multiple = false; int prevTrackChannels = 0; TrackListIterator scooter(iter); if (left->GetLinked()) scooter.Next(); if (scooter.Next()) { // if there is another track beyond this one and any linked one, // then we're processing more than one track. That means we // should use the originating track name in each new label // track's name, to make clear which is which multiple = true; } while (left) { sampleCount lstart, rstart; sampleCount len; GetSamples(left, &lstart, &len); WaveTrack *right = NULL; int channels = 1; if (left->GetLinked()) { right = (WaveTrack *)iter.Next(); channels = 2; GetSamples(right, &rstart, &len); } size_t step = mPlugin->getPreferredStepSize(); size_t block = mPlugin->getPreferredBlockSize(); bool initialiseRequired = true; if (block == 0) { if (step != 0) block = step; else block = 1024; } if (step == 0) { step = block; } if (prevTrackChannels > 0) { // Plugin has already been initialised, so if the number of // channels remains the same, we only need to do a reset. // Otherwise we need to re-construct the whole plugin, // because a Vamp plugin can't be re-initialised. if (prevTrackChannels == channels) { mPlugin->reset(); initialiseRequired = false; } else { //!!! todo: retain parameters previously set Init(); } } if (initialiseRequired) { if (!mPlugin->initialise(channels, step, block)) { wxMessageBox(_("Sorry, Vamp Plug-in failed to initialize.")); return false; } } LabelTrack *ltrack = mFactory->NewLabelTrack(); if (!multiple) { ltrack->SetName(GetEffectName()); } else { ltrack->SetName(wxString::Format(wxT("%s: %s"), left->GetName().c_str(), GetEffectName().c_str())); } mTracks->Add(ltrack); float **data = new float*[channels]; for (int c = 0; c < channels; ++c) data[c] = new float[block]; sampleCount originalLen = len; sampleCount ls = lstart; sampleCount rs = rstart; while (len) { int request = block; if (request > len) request = len; if (left) left->Get((samplePtr)data[0], floatSample, ls, request); if (right) right->Get((samplePtr)data[1], floatSample, rs, request); if (request < (int)block) { for (int c = 0; c < channels; ++c) { for (int i = request; i < (int)block; ++i) { data[c][i] = 0.f; } } } Vamp::RealTime timestamp = Vamp::RealTime::frame2RealTime (ls, (int)(mRate + 0.5)); Vamp::Plugin::FeatureSet features = mPlugin->process(data, timestamp); AddFeatures(ltrack, features); if (len > (int)step) len -= step; else len = 0; ls += step; rs += step; if (channels > 1) { if (TrackGroupProgress(count, (ls - lstart) / double(originalLen))) return false; } else { if (TrackProgress(count, (ls - lstart) / double(originalLen))) return false; } } Vamp::Plugin::FeatureSet features = mPlugin->getRemainingFeatures(); AddFeatures(ltrack, features); prevTrackChannels = channels; left = (WaveTrack *)iter.Next(); } return true; }
void CNewParticleEffect::DebugDrawBbox ( bool bCulled ) { int nParticlesShowBboxCost = g_cl_particle_show_bbox_cost; bool bShowCheapSystems = false; if ( nParticlesShowBboxCost < 0 ) { nParticlesShowBboxCost = -nParticlesShowBboxCost; bShowCheapSystems = true; } Vector center = GetRenderOrigin(); Vector mins = m_MinBounds - center; Vector maxs = m_MaxBounds - center; int r, g, b; bool bDraw = true; if ( bCulled ) { r = 64; g = 64; b = 64; } else if ( nParticlesShowBboxCost > 0 ) { float fAmount = (float)m_nActiveParticles / (float)nParticlesShowBboxCost; if ( fAmount < 0.5f ) { if ( bShowCheapSystems ) { r = 0; g = 255; b = 0; } else { // Prevent the screen getting spammed with low-count particles which aren't that expensive. bDraw = false; r = 0; g = 0; b = 0; } } else if ( fAmount < 1.0f ) { // green 0.5-1.0 blue int nBlend = (int)( 512.0f * ( fAmount - 0.5f ) ); nBlend = MIN ( 255, MAX ( 0, nBlend ) ); r = 0; g = 255 - nBlend; b = nBlend; } else if ( fAmount < 2.0f ) { // blue 1.0-2.0 red int nBlend = (int)( 256.0f * ( fAmount - 1.0f ) ); nBlend = MIN ( 255, MAX ( 0, nBlend ) ); r = nBlend; g = 0; b = 255 - nBlend; } else { r = 255; g = 0; b = 0; } } else { if ( GetAutoUpdateBBox() ) { // red is bad, the bbox update is costly r = 255; g = 0; b = 0; } else { // green, this effect presents less cpu load r = 0; g = 255; b = 0; } } if ( bDraw ) { debugoverlay->AddBoxOverlay( center, mins, maxs, QAngle( 0, 0, 0 ), r, g, b, 16, 0 ); debugoverlay->AddTextOverlayRGB( center, 0, 0, r, g, b, 64, "%s:(%d)", GetEffectName(), m_nActiveParticles ); } }
//----------------------------------------------------------------------------- // Rendering //----------------------------------------------------------------------------- int CNewParticleEffect::DrawModel( int flags, const RenderableInstance_t &instance ) { VPROF_BUDGET( "CNewParticleEffect::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); if ( r_DrawParticles.GetBool() == false ) return 0; if ( !GetClientMode()->ShouldDrawParticles() || !ParticleMgr()->ShouldRenderParticleSystems() ) return 0; if( flags & STUDIO_SHADOWDEPTHTEXTURE ) return 0; if ( m_hOwner && m_hOwner->IsDormant() ) return 0; // do distance cull check here. We do it here instead of in particles so we can easily only do // it for root objects, not bothering to cull children individually CMatRenderContextPtr pRenderContext( materials ); if ( !m_pDef->IsScreenSpaceEffect() && !m_pDef->IsViewModelEffect() ) { Vector vecCamera; pRenderContext->GetWorldSpaceCameraPosition( &vecCamera ); if ( ( CalcSqrDistanceToAABB( m_MinBounds, m_MaxBounds, vecCamera ) > ( m_pDef->m_flMaxDrawDistance * m_pDef->m_flMaxDrawDistance ) ) ) return 0; } if ( ( flags & STUDIO_TRANSPARENCY ) || !IsBatchable() || !m_pDef->IsDrawnThroughLeafSystem() ) { int viewentity = render->GetViewEntity(); C_BaseEntity *pCameraObject = cl_entitylist->GetEnt( viewentity ); // apply logic that lets you skip rendering a system if the camera is attached to its entity if ( ( ( pCameraObject && ( m_pDef->m_nSkipRenderControlPoint != -1 ) && ( m_pDef->m_nSkipRenderControlPoint <= m_nHighestCP ) && ( GetControlPointEntity( m_pDef->m_nSkipRenderControlPoint ) == pCameraObject ) ) ) || ( ( pCameraObject && ( m_pDef->m_nAllowRenderControlPoint != -1 ) && ( m_pDef->m_nAllowRenderControlPoint <= m_nHighestCP ) && ( GetControlPointEntity( m_pDef->m_nAllowRenderControlPoint ) != pCameraObject ) ) ) ) return 0; Vector4D vecDiffuseModulation( 1.0f, 1.0f, 1.0f, 1.0f ); //instance.m_nAlpha / 255.0f ); pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PushMatrix(); pRenderContext->LoadIdentity(); Render( pRenderContext, vecDiffuseModulation, ( flags & STUDIO_TRANSPARENCY ) ? IsTwoPass() : false, pCameraObject ); pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PopMatrix(); } else { g_pParticleSystemMgr->AddToRenderCache( this ); } if ( cl_particles_show_bbox.GetBool() ) { Vector center = GetRenderOrigin(); Vector mins = m_MinBounds - center; Vector maxs = m_MaxBounds - center; int r, g; if ( GetAutoUpdateBBox() ) { // red is bad, the bbox update is costly r = 255; g = 0; } else { // green, this effect presents less cpu load r = 0; g = 255; } Vector vecCurCPPos = GetControlPointAtCurrentTime( 0 ); debugoverlay->AddBoxOverlay( center, mins, maxs, QAngle( 0, 0, 0 ), r, g, 0, 16, 0 ); debugoverlay->AddTextOverlayRGB( center, 0, 0, r, g, 0, 64, "%s:(%d)", GetEffectName(), m_nActiveParticles ); } return 1; }
//----------------------------------------------------------------------------- // Rendering //----------------------------------------------------------------------------- int CNewParticleEffect::DrawModel( int flags ) { VPROF_BUDGET( "CNewParticleEffect::DrawModel", VPROF_BUDGETGROUP_PARTICLE_RENDERING ); if ( r_DrawParticles.GetBool() == false ) return 0; // City17: DX7? Don't draw. if( engine->GetDXSupportLevel() < 80 ) return 0; if ( !g_pClientMode->ShouldDrawParticles() || !ParticleMgr()->ShouldRenderParticleSystems() ) return 0; if( flags & STUDIO_SHADOWDEPTHTEXTURE ) return 0; // do distance cull check here. We do it here instead of in particles so we can easily only do // it for root objects, not bothering to cull children individually CMatRenderContextPtr pRenderContext( materials ); Vector vecCamera; pRenderContext->GetWorldSpaceCameraPosition( &vecCamera ); if ( CalcSqrDistanceToAABB( m_MinBounds, m_MaxBounds, vecCamera ) > ( m_pDef->m_flMaxDrawDistance * m_pDef->m_flMaxDrawDistance ) ) return 0; if ( flags & STUDIO_TRANSPARENCY ) { int viewentity = render->GetViewEntity(); C_BaseEntity *pCameraObject = cl_entitylist->GetEnt( viewentity ); // apply logic that lets you skip rendering a system if the camera is attached to its entity if ( pCameraObject && ( m_pDef->m_nSkipRenderControlPoint != -1 ) && ( m_pDef->m_nSkipRenderControlPoint <= m_nHighestCP ) && ( GetControlPointEntity( m_pDef->m_nSkipRenderControlPoint ) == pCameraObject ) ) return 0; pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PushMatrix(); pRenderContext->LoadIdentity(); Render( pRenderContext, IsTwoPass(), pCameraObject ); pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PopMatrix(); } else { g_pParticleSystemMgr->AddToRenderCache( this ); } if ( !IsRetail() && cl_particles_show_bbox.GetBool() ) { Vector center = GetRenderOrigin(); Vector mins = m_MinBounds - center; Vector maxs = m_MaxBounds - center; int r, g; if ( GetAutoUpdateBBox() ) { // red is bad, the bbox update is costly r = 255; g = 0; } else { // green, this effect presents less cpu load r = 0; g = 255; } debugoverlay->AddBoxOverlay( center, mins, maxs, QAngle( 0, 0, 0 ), r, g, 0, 16, 0 ); debugoverlay->AddTextOverlayRGB( center, 0, 0, r, g, 0, 64, "%s:(%d)", GetEffectName(), m_nActiveParticles ); } return 1; }