#include "ColorBufferReader.h" #include "FramebufferTextureFormats.h" #include "Context.h" #include "Parameters.h" #include #include namespace graphics { ColorBufferReader::ColorBufferReader(CachedTexture * _pTexture) : m_pTexture(_pTexture) { m_pixelData.resize(m_pTexture->textureBytes); m_tempPixelData.resize(m_pTexture->textureBytes); } const u8* ColorBufferReader::_convertFloatTextureBuffer(const u8* _gpuData, u32 _width, u32 _height, u32 _heightOffset, u32 _stride) { int bytesToCopy = m_pTexture->width * _height * 16; std::copy_n(_gpuData, bytesToCopy, m_tempPixelData.data()); u8* pixelDataAlloc = m_pixelData.data(); float* pixelData = reinterpret_cast(m_tempPixelData.data()); const u32 colorsPerPixel = 4; const u32 widthPixels = _width * colorsPerPixel; const u32 stridePixels = _stride * colorsPerPixel; if (_height * widthPixels > m_pixelData.size()) _height = static_cast(m_pixelData.size()) / widthPixels; for (u32 heightIndex = 0; heightIndex < _height; ++heightIndex) { for (u32 widthIndex = 0; widthIndex < widthPixels; ++widthIndex) { u8& dest = *(pixelDataAlloc + heightIndex*widthPixels + widthIndex); float& src = *(pixelData + (heightIndex+_heightOffset)*stridePixels + widthIndex); dest = static_cast(src*255.0); } } return pixelDataAlloc; } const u8* ColorBufferReader::_convertIntegerTextureBuffer(const u8* _gpuData, u32 _width, u32 _height, u32 _heightOffset, u32 _stride, u32 _colorsPerPixel) { const u32 widthBytes = _width * _colorsPerPixel; const u32 strideBytes = _stride * _colorsPerPixel; u8* pixelDataAlloc = m_pixelData.data(); if (_height * widthBytes > m_pixelData.size()) _height = static_cast(m_pixelData.size()) / widthBytes; for (u32 index = 0; index < _height; ++index) { memcpy(pixelDataAlloc + index * widthBytes, _gpuData + ((index + _heightOffset) * strideBytes), widthBytes); } return pixelDataAlloc; } const u8 * ColorBufferReader::readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync) { const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats(); ReadColorBufferParams params; params.x0 = _x0; params.y0 = _y0; params.width = _width; params.height = _height; params.sync = _sync; if (_size > G_IM_SIZ_8b) { params.colorFormat = fbTexFormat.colorFormat; params.colorType = fbTexFormat.colorType; params.colorFormatBytes = fbTexFormat.colorFormatBytes; } else { params.colorFormat = fbTexFormat.monochromeFormat; params.colorType = fbTexFormat.monochromeType; params.colorFormatBytes = fbTexFormat.monochromeFormatBytes; } u32 heightOffset = 0; u32 stride = 0; const u8* pixelData = _readPixels(params, heightOffset, stride); if (pixelData == nullptr) return nullptr; if(params.colorType == datatype::FLOAT && _size > G_IM_SIZ_8b) { return _convertFloatTextureBuffer(pixelData, params.width, params.height, heightOffset, stride); } else { return _convertIntegerTextureBuffer(pixelData, params.width, params.height, heightOffset, stride, params.colorFormatBytes); } } }