dimanche 1 mars 2015

Efficient drawing of large scene with surfaces + textures


I've been performing STFT using Cinder on 20 minutes of audio data using Cinder and I am in my last step of the project which is drawing the spectrogram. My scene is going to be extremely large (20 * 60 * 44100 pixles wide), however only a subset of the scene needs to be visible at a time (limited by screen width).


I have divided the scene into much smaller pieces (let's say 50 pixels wide each) and concurrently while the audio is being recorded, I update the 50 pixels wide surfaces with new data and as soon as one surface's 50 pixels is finished, it'll be transformed into a texture (in the update call):



int index = 0;
for (auto* surface : mSurfacePool)
{
if (surface)
{
mTexturePool[index] = ci::gl::Texture::create(*surface);
surface.reset(); //clear surface and free the memory
}
index++;
}


As soon as I remove the draw loop, everything runs at 60 fps but when I add the draw loop:



ci::gl::SaveFramebufferBinding _bindings;

//! draw everything to a frame buffer
mFramebuffer.bindFramebuffer();

ci::gl::clear(ci::Color::black());

int index = 0;
for (Surface32f* surface : mSurfacePool)
{
ci::Rectf draw_rect(0, index * mFramesPerSurface, mFftSize, (index + 1) * mFramesPerSurface);
if (draw_rect.getY1() > mViewableFrames)
break;

if (mTexturePool[index])
{
// draw texture
ci::gl::draw(mTexturePool[index], draw_rect);
}
else if (surface)
{
// draw surface
ci::gl::draw(*surface, draw_rect);
}
index++;
}

mFramebuffer.unbindFramebuffer();


Everything lags and fps drops to 5, so I was wondering if there's a technique I can use to draw such large scenes. Thanks!


Actual source code can be found here: http://ift.tt/18Cy6TH




Aucun commentaire:

Enregistrer un commentaire