コード例 #1
0
ファイル: samplebuffer.cpp プロジェクト: skyrpex/pathtracer
  void write_image(const string& file, const SampleBuffer& buffer)
  {
    const float samples = static_cast<float>(buffer.samples());
    FIBITMAP* dib = FreeImage_Allocate(buffer.width(), buffer.height(),
        32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);

    const unsigned int BYTESPP =
      FreeImage_GetLine(dib) / FreeImage_GetWidth(dib);
    for (unsigned int y = 0; y < FreeImage_GetHeight(dib); ++y) {
      BYTE* bits = FreeImage_GetScanLine(dib, y);

      for (unsigned int x = 0; x < FreeImage_GetWidth(dib); ++x) {
        vec3 c = gamma_correct(buffer.get(x, y) / samples) * 255.0f;
        bits[FI_RGBA_RED]   = static_cast<BYTE>(c.r);
        bits[FI_RGBA_GREEN] = static_cast<BYTE>(c.g);
        bits[FI_RGBA_BLUE]  = static_cast<BYTE>(c.b);
        bits[FI_RGBA_ALPHA] = 255;

        bits += BYTESPP;
      }
    }

    if (!FreeImage_Save(FIF_PNG, dib, file.c_str(), 0)) {
      string err = "Failed to save screenshot to file '";
      err += file;
      err += '\'';
      throw err;
    }

    FreeImage_Unload(dib);
  }
コード例 #2
0
void LfoControllerDialog::askUserDefWave()
{
	SampleBuffer * sampleBuffer = dynamic_cast<LfoController*>(this->model())->
									m_userDefSampleBuffer;
	QString fileName = sampleBuffer->openAndSetWaveformFile();
	if( fileName.isEmpty() == false )
	{
		// TODO:
		ToolTip::add( m_userWaveBtn, sampleBuffer->audioFile() );
	}
}
コード例 #3
0
ファイル: samplebuffer.cpp プロジェクト: skyrpex/pathtracer
  void SampleBuffer::append(const SampleBuffer& other)
  {
    assert(width() == other.width() && height() == other.height());
    auto it = _buffer.begin();
    auto io = other._buffer.cbegin();
    while (it < _buffer.cend()) {
      *it += *io;
      ++it;
      ++io;
    }

    _samples += other.samples();
  }
コード例 #4
0
void SampleFrontEnd<sample_base_t>::Clear(  )
{
   
   //temporary pointer
   SampleBuffer<sample_base_t>* pSampleBuff;

   for(std::map<std::string,std::pair<SampleSink*,SampleStreamInfo*>>::iterator mit = this->mSampleSinks.begin(); mit != this->mSampleSinks.end(); mit++)
   {
      pSampleBuff = dynamic_cast<SampleBuffer<sample_base_t>*>( mit->second.first );
      if( pSampleBuff )
         pSampleBuff->Flush();
   }
 
};
コード例 #5
0
/// Write the summary to disk, using the derived ReadData() to get the data
/// Here, the decoder ODTask associated with this file must fetch the samples with
/// the ODDecodeTask::Decode() method.
int ODDecodeBlockFile::WriteODDecodeBlockFile()
{

   // To build the summary data, call ReadData (implemented by the
   // derived classes) to get the sample data
   SampleBuffer sampleData;// = NewSamples(mLen, floatSample);
   int ret;
   //use the decoder here.
   mDecoderMutex.Lock();

   if(!mDecoder)
   {
      mDecoderMutex.Unlock();
      return -1;
   }


   //sampleData and mFormat are set by the decoder.
   ret = mDecoder->Decode(sampleData, mFormat, mAliasStart, mLen, mAliasChannel);

   mDecoderMutex.Unlock();
   if(ret < 0) {
      printf("ODDecodeBlockFile Decode failure\n");
      return ret; //failure
   }

   //the summary is also calculated here.
   mFileNameMutex.Lock();
   //TODO: we may need to write a version of WriteSimpleBlockFile that uses threadsafe FILE vs wxFile
   bool bSuccess =
      WriteSimpleBlockFile(
         sampleData.ptr(),
         mLen,
         mFormat,
         NULL);//summaryData);
   wxASSERT(bSuccess); // TODO: Handle failure here by alert to user and undo partial op.
   wxUnusedVar(bSuccess);

   mFileNameMutex.Unlock();

//   delete [] (char *) summaryData;


   mDataAvailableMutex.Lock();
   mDataAvailable=true;
   mDataAvailableMutex.Unlock();

   return ret;
}
コード例 #6
0
ファイル: BitmapWriter.cpp プロジェクト: bracket/handsome
void write_bitmap(char const * path, SampleBuffer const & buffer) {
	FILE * fd = fopen(path, "wb");

	BitmapHeader header;
	BitmapInfo info = make_info(buffer.get_width(), buffer.get_height());

	header.size() = sizeof(header) + sizeof(info) + buffer.get_size() * sizeof(uint32);
	header.offset() = sizeof(header) + sizeof(info);

	fwrite(&header, sizeof(header), 1, fd);
	fwrite(&info, sizeof(info), 1, fd);
	buffer.write_bitmap(fd);

	fclose(fd);
}
コード例 #7
0
ファイル: Gain.cpp プロジェクト: xushoucai/ESP32_BTAudio
void DSP::Filter::Gain::processSamples(SampleBuffer& samples) {
  for(int i = 0; i < samples.size(); ++i) {
    auto scaled = static_cast<int64_t>(samples[i]) * m_gain;

    samples[i] = saturate<int16_t>(scaled >> 16);
  }
}
コード例 #8
0
ファイル: nativefilm.cpp プロジェクト: rbrtribeiro/smalllux3
SampleBuffer *NativeFilm::GetFreeSampleBuffer() {
	// Look for a free buffer
	if (freeSampleBuffers.size() > 0) {
		SampleBuffer *sb = freeSampleBuffers.front();
		freeSampleBuffers.pop_front();

		sb->Reset();
		return sb;
	} else {
		// Need to allocate a new buffer
		SampleBuffer *sb = new SampleBuffer(SampleBufferSize);

		sampleBuffers.push_back(sb);

		return sb;
	}
}
コード例 #9
0
ファイル: graph.cpp プロジェクト: Cubiicle/lmms
QString graphModel::setWaveToUser()
{
	SampleBuffer * sampleBuffer = new SampleBuffer;
	QString fileName = sampleBuffer->openAndSetWaveformFile();
	if( fileName.isEmpty() == false )
	{
		for( int i = 0; i < length(); i++ )
		{
			m_samples[i] = sampleBuffer->userWaveSample(
					i / static_cast<float>( length() ) );
		}
	}

	sharedObject::unref( sampleBuffer );

	emit samplesChanged( 0, length() - 1 );
	return fileName;
};
コード例 #10
0
void SingularSampleBuffer::swapBuffers(SampleBuffer& secondaryBuffer) {
    DEBUG_ASSERT_CLASS_INVARIANT_SingularSampleBuffer;
    DEBUG_ASSERT(m_primaryBuffer.size() == secondaryBuffer.size());

    // SampleUtil::copy() requires that the source and destination
    // memory regions are disjunct. Double-buffering is necessary
    // to satisfy this precondition.
    SampleUtil::copy(
            secondaryBuffer.data(),
            m_primaryBuffer.data(m_headOffset),
            getSize());
    m_primaryBuffer.swap(secondaryBuffer);
    // shift offsets
    m_tailOffset -= m_headOffset;
    m_headOffset = 0;

    DEBUG_ASSERT_CLASS_INVARIANT_SingularSampleBuffer;
}
コード例 #11
0
void SoundEngine::MusicHook(void* userdata, Uint8* stream, int len)
{
    bool* musicFinishedPtr = reinterpret_cast<bool*>(userdata);
    if (!*musicFinishedPtr)
    {
        SampleBuffer buffer;
        Uint32 ret = musicDecoder.Decode(buffer, len);
        if (ret == SOUND_DECODE_COMPLETED) {
            musicDecoder.Close();
            *musicFinishedPtr = true;
        } else if (ret == SOUND_DECODE_ERROR) {
            logger->error("Sound: Error during music decoding, stopping playback of current track.\n");
            *musicFinishedPtr = true;
            return;
        }
        memcpy(stream, &buffer[0], buffer.size());
    }
}
コード例 #12
0
ファイル: ODDecodeFlacTask.cpp プロジェクト: henricj/audacity
//--Decoder stuff:
   ///Decodes the samples for this blockfile from the real file into a float buffer.
   ///This is file specific, so subclasses must implement this only.
   ///the buffer was defined like
   ///samplePtr sampleData = NewSamples(mLen, floatSample);
   ///this->ReadData(sampleData, floatSample, 0, mLen);
   ///This class should call ReadHeader() first, so it knows the length, and can prepare
   ///the file object if it needs to.
int ODFlacDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCount start, size_t len, unsigned int channel)
{

   //we need to lock this so the target stays fixed over the seek/write callback.
   mFlacFileLock.Lock();

   bool usingCache=mLastDecodeStartSample==start;
   if(usingCache)
   {
      //we've just decoded this, so lets use a cache.  (often so for
   }


   mDecodeBufferWritePosition=0;
   mDecodeBufferLen = len;

   data.Allocate(len, mFormat);
   mDecodeBuffer = data.ptr();
   format = mFormat;

   mTargetChannel=channel;

   // Third party library has its own type alias, check it
   static_assert(sizeof(sampleCount::type) <=
                 sizeof(FLAC__int64),
                 "Type FLAC__int64 is too narrow to hold a sampleCount");
   if(!mFile->seek_absolute(static_cast<FLAC__int64>( start.as_long_long() )))
   {
      mFlacFileLock.Unlock();
      return -1;
   }

   while(mDecodeBufferWritePosition<mDecodeBufferLen)
      mFile->process_single();

   mFlacFileLock.Unlock();
   if(!usingCache)
   {
      mLastDecodeStartSample=start;
   }
   //insert into blockfile and
   //calculate summary happen in ODDecodeBlockFile::WriteODDecodeBlockFile, where this method is also called.
   return 1;
}
コード例 #13
0
SampleBuffer *NativePixelDevice::GetFreeSampleBuffer() {
	boost::mutex::scoped_lock lock(splatMutex);

	// Look for a free buffer
	if (freeSampleBuffers.size() > 0) {
		SampleBuffer *sb = freeSampleBuffers.front();
		freeSampleBuffers.pop_front();

		sb->Reset();
		return sb;
	} else {
		// Need to allocate a new buffer
		SampleBuffer *sb = new SampleBuffer(SampleBufferSize);

		sampleBuffers.push_back(sb);

		return sb;
	}
}
void UniformSampleGenerator2DCL::generateNextSamples(SampleBuffer& positionSamplesOut, const VECTOR_CLASS<cl::Event>* waitForEvents /*= nullptr*/, cl::Event* event /*= nullptr*/) {
    if (kernel_ == NULL) {
        return throw Exception("Invalid kernel: Kernel not found or failed to compile");
    }
    size2_t nSamples{static_cast<size_t>(std::sqrt(static_cast<double>(positionSamplesOut.getSize())))};
    if (getUseGLSharing()) {
        SyncCLGL glSync;
        BufferCLGL* samples = positionSamplesOut.getEditableRepresentation<BufferCLGL>();

        // Acquire shared representations before using them in OpenGL
        // The SyncCLGL object will take care of synchronization between OpenGL and OpenCL
        glSync.addToAquireGLObjectList(samples);
        glSync.aquireAllObjects();
        generateSamples(nSamples, positionSamplesOut.getSize(), samples, waitForEvents, event);
    } else {
        BufferCL* samples = positionSamplesOut.getEditableRepresentation<BufferCL>();
        generateSamples(nSamples, positionSamplesOut.getSize(), samples, waitForEvents, event);
    }
}
コード例 #15
0
ファイル: ODDecodeBlockFile.cpp プロジェクト: MindFy/audacity
/// Write the summary to disk, using the derived ReadData() to get the data
/// Here, the decoder ODTask associated with this file must fetch the samples with
/// the ODDecodeTask::Decode() method.
int ODDecodeBlockFile::WriteODDecodeBlockFile()
{

   // To build the summary data, call ReadData (implemented by the
   // derived classes) to get the sample data
   SampleBuffer sampleData;// = NewSamples(mLen, floatSample);
   int ret;

   {
      //use the decoder here.
      ODLocker locker{ &mDecoderMutex };

      if(!mDecoder)
         return -1;

      //sampleData and mFormat are set by the decoder.
      ret = mDecoder->Decode(sampleData, mFormat, mAliasStart, mLen, mAliasChannel);

      if(ret < 0) {
         wxPrintf("ODDecodeBlockFile Decode failure\n");
         return ret; //failure
      }
   }

   {
      //the summary is also calculated here.
      ODLocker locker{ &mFileNameMutex };
      //TODO: we may need to write a version of WriteSimpleBlockFile that uses threadsafe FILE vs wxFile
      bool bSuccess =
         WriteSimpleBlockFile(
                              sampleData.ptr(),
                              mLen,
                              mFormat,
                              NULL);
      if ( !bSuccess )
         return -1;
   }

   wxAtomicInc( mDataAvailable );

   return ret;
}
コード例 #16
0
ファイル: SampleBuffer.cpp プロジェクト: floft/lmms
void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr,
							bool _keep_settings )
{
	// do samplerate-conversion to our default-samplerate
	if( _src_sr != engine::mixer()->baseSampleRate() )
	{
		SampleBuffer * resampled = resample( this, _src_sr,
					engine::mixer()->baseSampleRate() );
		MM_FREE( m_data );
		m_frames = resampled->frames();
		m_data = MM_ALLOC( sampleFrame, m_frames );
		memcpy( m_data, resampled->data(), m_frames *
							sizeof( sampleFrame ) );
		delete resampled;
	}

	if( _keep_settings == false )
	{
		// update frame-variables
		m_loopStartFrame = m_startFrame = 0;
		m_loopEndFrame = m_endFrame = m_frames;
	}
}
コード例 #17
0
ファイル: MultiProgram.cpp プロジェクト: olilarkin/OwlProgram
void processBlock(){
  buffer.split(getProgramVector()->audio_input, getProgramVector()->audio_blocksize);
  patches.process(buffer);
  buffer.comb(getProgramVector()->audio_output);
}
コード例 #18
0
Uint32 SoundFile::Decode(SampleBuffer& buffer, Uint32 length)
{
    if (!initconv || !fileOpened)
    {
        return SOUND_DECODE_ERROR;
    }

    assert(buffer.empty());


    Uint32 max_size = length == 0 ? uncomp_size * conv->len_mult : length;
    buffer.resize(max_size);

    Uint16 comp_sample_size, uncomp_sample_size;
    Uint32 ID;

    //if (offset < 12)
    //    offset = 12;
    //file->seekSet(offset);


    Uint32 written = 0;
    while ((file->tell()+8) < file->fileSize()) {
        // Each sample has a header
        file->readWord(&comp_sample_size, 1);
        file->readWord(&uncomp_sample_size, 1);
        file->readDWord(&ID, 1);

        if (comp_sample_size > (SOUND_MAX_CHUNK_SIZE)) {
            logger->warning("Size data for current sample too large\n");
            return SOUND_DECODE_ERROR;
        }

        // abort if id was wrong */
        if (ID != 0xDEAF) {
            logger->warning("Sample had wrong ID: %x\n", ID);
            return SOUND_DECODE_ERROR;
        }

        if (written + uncomp_sample_size*conv->len_mult > max_size) {
            file->seekCur(-8); // rewind stream back to headers
            buffer.resize(written); // Truncate buffer.
            return SOUND_DECODE_STREAMING;
        }

        // compressed data follows header
        file->readByte(chunk, comp_sample_size);

        if (type == 1) {
            SoundUtils::WSADPCM_Decode(tmpbuff, chunk, comp_sample_size, uncomp_sample_size);
        } else {
            SoundUtils::IMADecode(tmpbuff, chunk, comp_sample_size, imaSample, imaIndex);
        }
        conv->buf = tmpbuff;
        conv->len = uncomp_sample_size;
        if (SDL_ConvertAudio(conv) < 0) {
            logger->warning("Could not run conversion filter: %s\n", SDL_GetError());
            return SOUND_DECODE_ERROR;
        }
        memcpy(&buffer[written], tmpbuff, uncomp_sample_size*conv->len_mult);
        //offset += 8 + comp_sample_size;
        written += uncomp_sample_size*conv->len_mult;
    }

    // Truncate if final sample was too small.
    if (written < max_size)
        buffer.resize(written);

    return SOUND_DECODE_COMPLETED;
}
コード例 #19
0
int ODFFmpegDecoder::Decode(SampleBuffer & data, sampleFormat & format, sampleCount start, sampleCount len, unsigned int channel)
{
   format = mScs[mStreamIndex]->m_osamplefmt;

   data.Allocate(len, format);
   samplePtr bufStart = data.ptr();
   streamContext* sc = NULL;

   // printf("start %llu len %llu\n", start, len);
   //TODO update this to work with seek - this only works linearly now.
   if(mCurrentPos > start && mCurrentPos  <= start+len + kDecodeSampleAllowance)
   {
      //this next call takes data, start and len as reference variables and updates them to reflect the NEW area that is needed.
      FillDataFromCache(bufStart, format, start,len,channel);
   }

   bool seeking = false;
   //look at the decoding timestamp and see if the next sample that will be decoded is not the next sample we need.
   if(len && (mCurrentPos > start + len  || mCurrentPos + kDecodeSampleAllowance < start ) && SeekingAllowed()) {
      sc = mScs[mStreamIndex];
      AVStream* st = sc->m_stream;
      int stindex = -1;
      uint64_t targetts;

      //printf("attempting seek to %llu\n", start);
      //we have to find the index for this stream.
      for (unsigned int i = 0; i < mFormatContext->nb_streams; i++) {
         if (mFormatContext->streams[i] == sc->m_stream )
            stindex =i;
      }

      if(stindex >=0) {
         int numAttempts = 0;
         //reset mCurrentPos to a bogus value
         mCurrentPos = start+len +1;
         while(numAttempts++ < kMaxSeekRewindAttempts && mCurrentPos > start) {
            //we want to move slightly before the start of the block file, but not too far ahead
            targetts = (start-kDecodeSampleAllowance*numAttempts/kMaxSeekRewindAttempts)  * ((double)st->time_base.den/(st->time_base.num * st->codec->sample_rate ));
            if(targetts<0)
               targetts=0;

            //printf("attempting seek to %llu, attempts %d\n", targetts, numAttempts);
            if(av_seek_frame(mFormatContext,stindex,targetts,0) >= 0){
               //find out the dts we've seekd to.
               sampleCount actualDecodeStart = 0.5 + st->codec->sample_rate * st->cur_dts  * ((double)st->time_base.num/st->time_base.den);      //this is mostly safe because den is usually 1 or low number but check for high values.

               mCurrentPos = actualDecodeStart;
               seeking = true;

               //if the seek was past our desired position, rewind a bit.
               //printf("seek ok to %llu samps, float: %f\n",actualDecodeStart,actualDecodeStartDouble);
            } else {
               printf("seek failed");
               break;
            }
         }
         if(mCurrentPos>start){
            mSeekingAllowedStatus = (bool)ODFFMPEG_SEEKING_TEST_FAILED;
            //               url_fseek(mFormatContext->pb,sc->m_pkt.pos,SEEK_SET);
            printf("seek fail, reverting to previous pos\n");
            return -1;
         }
      }
   }
   bool firstpass = true;

   //we decode up to the end of the blockfile
   while (len>0 && (mCurrentPos < start+len) && (sc = ReadNextFrame()) != NULL)
   {
      // ReadNextFrame returns 1 if stream is not to be imported
      if (sc != (streamContext*)1)
      {
         //find out the dts we've seekd to.  can't use the stream->cur_dts because it is faulty.  also note that until we do the first seek, pkt.dts can be false and will change for the same samples after the initial seek.
         sampleCount actualDecodeStart = mCurrentPos;

         // we need adjacent samples, so don't use dts most of the time which will leave gaps between frames
         // for some formats
         // The only other case for inserting silence is for initial offset and ImportFFmpeg.cpp does this for us
         if (seeking) {
            actualDecodeStart = 0.52 + (sc->m_stream->codec->sample_rate * sc->m_pkt.dts
                                        * ((double)sc->m_stream->time_base.num / sc->m_stream->time_base.den));
            //this is mostly safe because den is usually 1 or low number but check for high values.

            //hack to get rounding to work to neareset frame size since dts isn't exact
            if (sc->m_stream->codec->frame_size) {
               actualDecodeStart = ((actualDecodeStart + sc->m_stream->codec->frame_size/2) / sc->m_stream->codec->frame_size) * sc->m_stream->codec->frame_size;
            }
            // reset for the next one
            seeking = false;
         }
         if(actualDecodeStart != mCurrentPos)
            printf("ts not matching - now:%llu , last:%llu, lastlen:%llu, start %llu, len %llu\n",actualDecodeStart, mCurrentPos, mCurrentLen, start, len);
            //if we've skipped over some samples, fill the gap with silence.  This could happen often in the beginning of the file.
         if(actualDecodeStart>start && firstpass) {
            // find the number of samples for the leading silence
            int amt = actualDecodeStart - start;
            FFMpegDecodeCache* cache = new FFMpegDecodeCache;

            //printf("skipping/zeroing %i samples. - now:%llu (%f), last:%llu, lastlen:%llu, start %llu, len %llu\n",amt,actualDecodeStart, actualDecodeStartdouble, mCurrentPos, mCurrentLen, start, len);

            //put it in the cache so the other channels can use it.
            cache->numChannels = sc->m_stream->codec->channels;
            cache->len = amt;
            cache->start=start;
            // 8 bit and 16 bit audio output from ffmpeg means
            // 16 bit int out.
            // 32 bit int, float, double mean float out.
            if (format == int16Sample)
               cache->samplefmt = SAMPLE_FMT_S16;
            else
               cache->samplefmt = SAMPLE_FMT_FLT;

            cache->samplePtr = (uint8_t*) malloc(amt * cache->numChannels * SAMPLE_SIZE(format));

            memset(cache->samplePtr, 0, amt * cache->numChannels * SAMPLE_SIZE(format));

            InsertCache(cache);
         }
         firstpass=false;
         mCurrentPos = actualDecodeStart;
         //decode the entire packet (unused bits get saved in cache, so as long as cache size limit is bigger than the
         //largest packet size, we're ok.
         while (sc->m_pktRemainingSiz > 0)
            //Fill the cache with decoded samples
               if (DecodeFrame(sc,false) < 0)
                  break;

         // Cleanup after frame decoding
         if (sc->m_pktValid)
         {
            av_free_packet(&sc->m_pkt);
            sc->m_pktValid = 0;
         }
      }
   }

   // Flush the decoders if we're done.
   if((!sc || sc == (streamContext*) 1)&& len>0)
   {
      for (int i = 0; i < mNumStreams; i++)
      {
         if (DecodeFrame(mScs[i], true) == 0)
         {
            if (mScs[i]->m_pktValid)
            {
               av_free_packet(&mScs[i]->m_pkt);
               mScs[i]->m_pktValid = 0;
            }
         }
      }
   }

   //this next call takes data, start and len as reference variables and updates them to reflect the NEW area that is needed.
   FillDataFromCache(bufStart, format, start, len, channel);

   // CHECK: not sure if we need this.  In any case it has to be updated for the NEW float case (not just int16)
   //if for some reason we couldn't get the samples, fill them with silence
   /*
   int16_t* outBuf = (int16_t*) bufStart;
   for(int i=0;i<len;i++)
      outBuf[i]=0;
   */
   return 1;
}
コード例 #20
0
ファイル: Main.cpp プロジェクト: 222464/GLLight2D
int main()
{
	sf::RenderWindow window(sf::VideoMode(900, 600), "Path Tracing 2D");
	window.setVerticalSyncEnabled(true);

	glewInit();

	glMatrixMode(GL_PROJECTION);
	Matrix4x4f::OrthoMatrix(0.0f, 900.0f, 0.0f, 600.0f, -1.0f, 1.0f).GL_Load();

	SampleBuffer buffer;

	const float sampleScalar = 1.0f;

	const int downsampledWidth = window.getSize().x * sampleScalar;
	const int downsampledHeight = window.getSize().y * sampleScalar;

	if(!buffer.Create(downsampledWidth, downsampledHeight, "NONE NONE tracerShader.frag"))
		abort();

	buffer.Clear(AABB2D(Vec2f(-downsampledWidth, -downsampledHeight), Vec2f(downsampledWidth, downsampledHeight)));

	Light light;
	light.m_position = Vec3f(0.0f, 0.0f, 32.0f);
	light.m_color = Vec3f(10.0f, 10.0f, 10.0f);

	buffer.m_scene.m_lights.push_back(light);

	Polygon2D basePoly;
	basePoly.m_points.resize(4);
	basePoly.m_points[0] = Vec2f(-50.0f, -50.0f) * sampleScalar;
	basePoly.m_points[1] = Vec2f(50.0f, -50.0f) * sampleScalar;
	basePoly.m_points[2] = Vec2f(50.0f, 50.0f) * sampleScalar;
	basePoly.m_points[3] = Vec2f(-50.0f, 50.0f) * sampleScalar;

	buffer.Add(basePoly);

	Polygon2D basePoly2;
	basePoly2.m_points.resize(4);
	basePoly2.m_points[0] = Vec2f(-50.0f, 100.0f) * sampleScalar;
	basePoly2.m_points[1] = Vec2f(50.0f, 100.0f) * sampleScalar;
	basePoly2.m_points[2] = Vec2f(50.0f, 200.0f) * sampleScalar;
	basePoly2.m_points[3] = Vec2f(-50.0f, 200.0f) * sampleScalar;

	buffer.Add(basePoly2);

	buffer.Compile();
	buffer.Refresh();

	bool close = false;

	while(!close)
	{
		sf::Event event;

		while(window.pollEvent(event))
		{
			if(event.type == sf::Event::Closed)
				close = true;

			if(event.type == sf::Event::MouseMoved)
			{
				buffer.Refresh();

				buffer.m_scene.m_lights.back().m_position = Vec3f((event.mouseMove.x - 450) * sampleScalar, (300 - event.mouseMove.y) * sampleScalar, 32.0f);
			}
		}

		if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
			close = true;

		for(size_t i = 0; i < 1; i++)
			buffer.Accumulate(Vec2f(0.0f, 0.0f), Vec2f(downsampledWidth, downsampledHeight), 0.0f);
		
		glFlush();

		glViewport(0, 0, window.getSize().x, window.getSize().y);
		buffer.RenderBuffer(Vec2f(0.0f, 0.0f), Vec2f(900.0f, 600.0f), 0.0f);

		window.display();
	}

	return 0;
}