mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-07 03:13:49 +00:00
Added floating point support to ColorBufferReader
I consolidated a lot of code that was the same between implementations in the process, so now the code is common.
This commit is contained in:
parent
4a8ae7e1cf
commit
2e1baf433c
|
@ -290,6 +290,7 @@
|
||||||
<ClCompile Include="..\..\src\GBI.cpp" />
|
<ClCompile Include="..\..\src\GBI.cpp" />
|
||||||
<ClCompile Include="..\..\src\gDP.cpp" />
|
<ClCompile Include="..\..\src\gDP.cpp" />
|
||||||
<ClCompile Include="..\..\src\GLideN64.cpp" />
|
<ClCompile Include="..\..\src\GLideN64.cpp" />
|
||||||
|
<ClCompile Include="..\..\src\Graphics\ColorBufferReader.cpp" />
|
||||||
<ClCompile Include="..\..\src\Graphics\CombinerProgram.cpp" />
|
<ClCompile Include="..\..\src\Graphics\CombinerProgram.cpp" />
|
||||||
<ClCompile Include="..\..\src\Graphics\Context.cpp" />
|
<ClCompile Include="..\..\src\Graphics\Context.cpp" />
|
||||||
<ClCompile Include="..\..\src\Graphics\ObjectHandle.cpp" />
|
<ClCompile Include="..\..\src\Graphics\ObjectHandle.cpp" />
|
||||||
|
|
|
@ -296,6 +296,9 @@
|
||||||
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Utils.cpp">
|
<ClCompile Include="..\..\src\Graphics\OpenGLContext\opengl_Utils.cpp">
|
||||||
<Filter>Source Files\Graphics\OpenGL</Filter>
|
<Filter>Source Files\Graphics\OpenGL</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\Graphics\ColorBufferReader.cpp">
|
||||||
|
<Filter>Source Files\Graphics</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\Graphics\CombinerProgram.cpp">
|
<ClCompile Include="..\..\src\Graphics\CombinerProgram.cpp">
|
||||||
<Filter>Source Files\Graphics</Filter>
|
<Filter>Source Files\Graphics</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -65,6 +65,7 @@ set(GLideN64_SOURCES
|
||||||
DepthBufferRender/DepthBufferRender.cpp
|
DepthBufferRender/DepthBufferRender.cpp
|
||||||
common/CommonAPIImpl_common.cpp
|
common/CommonAPIImpl_common.cpp
|
||||||
Graphics/Context.cpp
|
Graphics/Context.cpp
|
||||||
|
Graphics/ColorBufferReader.cpp
|
||||||
Graphics/CombinerProgram.cpp
|
Graphics/CombinerProgram.cpp
|
||||||
Graphics/ObjectHandle.cpp
|
Graphics/ObjectHandle.cpp
|
||||||
Graphics/OpenGLContext/GLFunctions.cpp
|
Graphics/OpenGLContext/GLFunctions.cpp
|
||||||
|
|
89
src/Graphics/ColorBufferReader.cpp
Normal file
89
src/Graphics/ColorBufferReader.cpp
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
|
||||||
|
#include "ColorBufferReader.h"
|
||||||
|
#include "FramebufferTextureFormats.h"
|
||||||
|
#include "Context.h"
|
||||||
|
#include "Parameters.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
std::copy_n(_gpuData, m_tempPixelData.size(), m_tempPixelData.data());
|
||||||
|
u8* pixelDataAlloc = m_pixelData.data();
|
||||||
|
float* pixelData = reinterpret_cast<float*>(m_tempPixelData.data());
|
||||||
|
const u32 colorsPerPixel = 4;
|
||||||
|
const u32 widthPixels = _width * colorsPerPixel;
|
||||||
|
const u32 stridePixels = _stride * colorsPerPixel;
|
||||||
|
|
||||||
|
for (u32 index = 0; index < _height; ++index) {
|
||||||
|
for (u32 widthIndex = 0; widthIndex < widthPixels; ++widthIndex) {
|
||||||
|
u8& dest = *(pixelDataAlloc + index*widthPixels + widthIndex);
|
||||||
|
float& src = *(pixelData + (index+_heightOffset)*stridePixels + widthIndex);
|
||||||
|
dest = static_cast<u8>(src*255.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixelDataAlloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* ColorBufferReader::_convertIntegerTextureBuffer(const u8* _gpuData, u32 _width, u32 _height,
|
||||||
|
u32 _heightOffset, u32 _stride)
|
||||||
|
{
|
||||||
|
const u32 colorsPerPixel = 4;
|
||||||
|
const u32 widthBytes = _width * colorsPerPixel;
|
||||||
|
const u32 strideBytes = _stride * colorsPerPixel;
|
||||||
|
|
||||||
|
u8* pixelDataAlloc = m_pixelData.data();
|
||||||
|
for (u32 lnIndex = 0; lnIndex < _height; ++lnIndex) {
|
||||||
|
memcpy(pixelDataAlloc + lnIndex*widthBytes, _gpuData + ((lnIndex+_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) {
|
||||||
|
return _convertFloatTextureBuffer(pixelData, params.width, params.height, heightOffset, stride);
|
||||||
|
} else {
|
||||||
|
return _convertIntegerTextureBuffer(pixelData, params.width, params.height, heightOffset, stride);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,18 +8,32 @@ namespace graphics {
|
||||||
class ColorBufferReader
|
class ColorBufferReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ColorBufferReader(CachedTexture * _pTexture)
|
ColorBufferReader(CachedTexture * _pTexture);
|
||||||
: m_pTexture(_pTexture) {
|
virtual ~ColorBufferReader() = default;
|
||||||
m_pixelData.resize(m_pTexture->textureBytes);
|
|
||||||
}
|
|
||||||
virtual ~ColorBufferReader() {}
|
|
||||||
|
|
||||||
virtual u8 * readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync) = 0;
|
virtual const u8 * readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync);
|
||||||
virtual void cleanUp() = 0;
|
virtual void cleanUp() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
struct ReadColorBufferParams {
|
||||||
|
s32 x0;
|
||||||
|
s32 y0;
|
||||||
|
u32 width;
|
||||||
|
u32 height;
|
||||||
|
bool sync;
|
||||||
|
ColorFormatParam colorFormat;
|
||||||
|
DatatypeParam colorType;
|
||||||
|
u32 colorFormatBytes;
|
||||||
|
};
|
||||||
|
|
||||||
CachedTexture * m_pTexture;
|
CachedTexture * m_pTexture;
|
||||||
std::vector<u8> m_pixelData;
|
std::vector<u8> m_pixelData;
|
||||||
|
std::vector<u8> m_tempPixelData;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const u8* _convertFloatTextureBuffer(const u8* _gpuData, u32 _width, u32 _height, u32 _heightOffset, u32 _stride);
|
||||||
|
const u8* _convertIntegerTextureBuffer(const u8* _gpuData, u32 _width, u32 _height,u32 _heightOffset, u32 _stride);
|
||||||
|
virtual const u8 * _readPixels(const ReadColorBufferParams& _params, u32& _heightOffset, u32& _stride) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,25 +41,16 @@ void ColorBufferReaderWithBufferStorage::_destroyBuffers()
|
||||||
m_PBO[index] = 0;
|
m_PBO[index] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 * ColorBufferReaderWithBufferStorage::readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync)
|
const u8 * ColorBufferReaderWithBufferStorage::_readPixels(const ReadColorBufferParams& _params, u32& _heightOffset,
|
||||||
|
u32& _stride)
|
||||||
{
|
{
|
||||||
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
|
GLenum format = GLenum(_params.colorFormat);
|
||||||
GLenum colorFormat, colorType, colorFormatBytes;
|
GLenum type = GLenum(_params.colorType);
|
||||||
if (_size > G_IM_SIZ_8b) {
|
|
||||||
colorFormat = GLenum(fbTexFormat.colorFormat);
|
|
||||||
colorType = GLenum(fbTexFormat.colorType);
|
|
||||||
colorFormatBytes = GLenum(fbTexFormat.colorFormatBytes);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
colorFormat = GLenum(fbTexFormat.monochromeFormat);
|
|
||||||
colorType = GLenum(fbTexFormat.monochromeType);
|
|
||||||
colorFormatBytes = GLenum(fbTexFormat.monochromeFormatBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex]));
|
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex]));
|
||||||
glReadPixels(_x0, _y0, m_pTexture->realWidth, _height, colorFormat, colorType, 0);
|
glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, 0);
|
||||||
|
|
||||||
if (!_sync) {
|
if (!_params.sync) {
|
||||||
//Setup a fence sync object so that we know when glReadPixels completes
|
//Setup a fence sync object so that we know when glReadPixels completes
|
||||||
m_fence[m_curIndex] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
m_fence[m_curIndex] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
m_curIndex = (m_curIndex + 1) % _numPBO;
|
m_curIndex = (m_curIndex + 1) % _numPBO;
|
||||||
|
@ -72,19 +63,10 @@ u8 * ColorBufferReaderWithBufferStorage::readPixels(s32 _x0, s32 _y0, u32 _width
|
||||||
glFinish();
|
glFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLubyte* pixelData = reinterpret_cast<GLubyte*>(m_PBOData[m_curIndex]);
|
_heightOffset = 0;
|
||||||
if (pixelData == nullptr)
|
_stride = m_pTexture->realWidth;
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
int widthBytes = _width * colorFormatBytes;
|
return reinterpret_cast<u8*>(m_PBOData[m_curIndex]);
|
||||||
int strideBytes = m_pTexture->realWidth * colorFormatBytes;
|
|
||||||
|
|
||||||
GLubyte* pixelDataAlloc = m_pixelData.data();
|
|
||||||
for (unsigned int lnIndex = 0; lnIndex < _height; ++lnIndex) {
|
|
||||||
memcpy(pixelDataAlloc + lnIndex*widthBytes, pixelData + (lnIndex*strideBytes), widthBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pixelDataAlloc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBufferReaderWithBufferStorage::cleanUp()
|
void ColorBufferReaderWithBufferStorage::cleanUp()
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <Graphics/ColorBufferReader.h>
|
#include <Graphics/ColorBufferReader.h>
|
||||||
#include "opengl_CachedFunctions.h"
|
#include "opengl_CachedFunctions.h"
|
||||||
|
#include <Graphics/Parameter.h>
|
||||||
|
|
||||||
namespace opengl {
|
namespace opengl {
|
||||||
|
|
||||||
|
@ -13,7 +14,8 @@ namespace opengl {
|
||||||
CachedBindBuffer * _bindBuffer);
|
CachedBindBuffer * _bindBuffer);
|
||||||
virtual ~ColorBufferReaderWithBufferStorage();
|
virtual ~ColorBufferReaderWithBufferStorage();
|
||||||
|
|
||||||
u8 * readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync) override;
|
const u8 * _readPixels(const ReadColorBufferParams& _params, u32& _heightOffset, u32& _stride) override;
|
||||||
|
|
||||||
void cleanUp() override;
|
void cleanUp() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -11,6 +11,7 @@ ColorBufferReaderWithEGLImage::ColorBufferReaderWithEGLImage(CachedTexture *_pTe
|
||||||
: graphics::ColorBufferReader(_pTexture)
|
: graphics::ColorBufferReader(_pTexture)
|
||||||
, m_bindTexture(_bindTexture)
|
, m_bindTexture(_bindTexture)
|
||||||
, m_image(0)
|
, m_image(0)
|
||||||
|
, m_bufferLocked(false)
|
||||||
{
|
{
|
||||||
m_glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
m_glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)eglGetProcAddress("glEGLImageTargetTexture2DOES");
|
||||||
_initBuffers();
|
_initBuffers();
|
||||||
|
@ -35,48 +36,43 @@ void ColorBufferReaderWithEGLImage::_initBuffers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 * ColorBufferReaderWithEGLImage::readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync)
|
|
||||||
|
const u8 * ColorBufferReaderWithEGLImage::_readPixels(const ReadColorBufferParams& _params, u32& _heightOffset,
|
||||||
|
u32& _stride)
|
||||||
{
|
{
|
||||||
const graphics::FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
|
GLenum format = GLenum(_params.colorFormat);
|
||||||
GLenum colorFormat, colorType, colorFormatBytes;
|
GLenum type = GLenum(_params.colorType);
|
||||||
if (_size > G_IM_SIZ_8b) {
|
|
||||||
colorFormat = GLenum(fbTexFormat.colorFormat);
|
|
||||||
colorType = GLenum(fbTexFormat.colorType);
|
|
||||||
colorFormatBytes = GLenum(fbTexFormat.colorFormatBytes);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
colorFormat = GLenum(fbTexFormat.monochromeFormat);
|
|
||||||
colorType = GLenum(fbTexFormat.monochromeType);
|
|
||||||
colorFormatBytes = GLenum(fbTexFormat.monochromeFormatBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
u8* pixelData = m_pixelData.data();
|
void* gpuData = nullptr;
|
||||||
|
const u8* returnData = nullptr;
|
||||||
|
|
||||||
if (!_sync) {
|
if (!_params.sync) {
|
||||||
void* ptr;
|
|
||||||
|
|
||||||
m_bindTexture->bind(graphics::Parameter(0), graphics::Parameter(GL_TEXTURE_2D), m_pTexture->name);
|
m_bindTexture->bind(graphics::Parameter(0), graphics::Parameter(GL_TEXTURE_2D), m_pTexture->name);
|
||||||
m_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image);
|
m_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_image);
|
||||||
m_bindTexture->bind(graphics::Parameter(0), graphics::Parameter(GL_TEXTURE_2D), ObjectHandle());
|
m_bindTexture->bind(graphics::Parameter(0), graphics::Parameter(GL_TEXTURE_2D), ObjectHandle());
|
||||||
int widthBytes = _width*colorFormatBytes;
|
|
||||||
int strideBytes = m_pTexture->realWidth * colorFormatBytes;
|
|
||||||
|
|
||||||
m_window.lock(GRALLOC_USAGE_SW_READ_OFTEN, &ptr);
|
m_window.lock(GRALLOC_USAGE_SW_READ_OFTEN, &gpuData);
|
||||||
|
m_bufferLocked = true;
|
||||||
|
_heightOffset = static_cast<u32>(_params.y0);
|
||||||
|
_stride = m_pTexture->realWidth;
|
||||||
|
|
||||||
for (unsigned int lnIndex = 0; lnIndex < _height; ++lnIndex) {
|
|
||||||
memcpy(pixelData + lnIndex*widthBytes, reinterpret_cast<char*>(ptr) + ((lnIndex + _y0)*strideBytes), widthBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_window.unlock();
|
|
||||||
} else {
|
} else {
|
||||||
glReadPixels(_x0, _y0, _width, _height, colorFormat, colorType, pixelData);
|
gpuData = m_pixelData.data();
|
||||||
|
glReadPixels(_params.x0, _params.y0, _params.width, _params.height, format, type, gpuData);
|
||||||
|
_heightOffset = 0;
|
||||||
|
_stride = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pixelData;
|
return reinterpret_cast<u8*>(gpuData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBufferReaderWithEGLImage::cleanUp()
|
void ColorBufferReaderWithEGLImage::cleanUp()
|
||||||
{
|
{
|
||||||
|
if (m_bufferLocked) {
|
||||||
|
m_window.unlock();
|
||||||
|
m_bufferLocked = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EGL
|
#endif // EGL
|
||||||
|
|
|
@ -19,7 +19,8 @@ public:
|
||||||
CachedBindTexture * _bindTexture);
|
CachedBindTexture * _bindTexture);
|
||||||
~ColorBufferReaderWithEGLImage();
|
~ColorBufferReaderWithEGLImage();
|
||||||
|
|
||||||
u8 * readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync) override;
|
const u8 * _readPixels(const ReadColorBufferParams& _params, u32& _heightOffset, u32& _stride) override;
|
||||||
|
|
||||||
void cleanUp() override;
|
void cleanUp() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -29,6 +30,7 @@ private:
|
||||||
GraphicBuffer m_window{};
|
GraphicBuffer m_window{};
|
||||||
EGLImageKHR m_image;
|
EGLImageKHR m_image;
|
||||||
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC m_glEGLImageTargetTexture2DOES;
|
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC m_glEGLImageTargetTexture2DOES;
|
||||||
|
bool m_bufferLocked;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,45 +39,30 @@ void ColorBufferReaderWithPixelBuffer::_initBuffers()
|
||||||
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle::null);
|
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle::null);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 * ColorBufferReaderWithPixelBuffer::readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync)
|
const u8 * ColorBufferReaderWithPixelBuffer::_readPixels(const ReadColorBufferParams& _params, u32& _heightOffset,
|
||||||
|
u32& _stride)
|
||||||
{
|
{
|
||||||
const graphics::FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
|
GLenum format = GLenum(_params.colorFormat);
|
||||||
GLenum colorFormat, colorType, colorFormatBytes;
|
GLenum type = GLenum(_params.colorType);
|
||||||
if (_size > G_IM_SIZ_8b) {
|
|
||||||
colorFormat = GLenum(fbTexFormat.colorFormat);
|
|
||||||
colorType = GLenum(fbTexFormat.colorType);
|
|
||||||
colorFormatBytes = GLenum(fbTexFormat.colorFormatBytes);
|
|
||||||
} else {
|
|
||||||
colorFormat = GLenum(fbTexFormat.monochromeFormat);
|
|
||||||
colorType = GLenum(fbTexFormat.monochromeType);
|
|
||||||
colorFormatBytes = GLenum(fbTexFormat.monochromeFormatBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If Sync, read pixels from the buffer, copy them to RDRAM.
|
// If Sync, read pixels from the buffer, copy them to RDRAM.
|
||||||
// If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM.
|
// If not Sync, read pixels from the buffer, copy pixels from the previous buffer to RDRAM.
|
||||||
if (!_sync) {
|
if (!_params.sync) {
|
||||||
m_curIndex ^= 1;
|
m_curIndex ^= 1;
|
||||||
const u32 nextIndex = m_curIndex ^ 1;
|
const u32 nextIndex = m_curIndex ^ 1;
|
||||||
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex]));
|
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[m_curIndex]));
|
||||||
glReadPixels(_x0, _y0, m_pTexture->realWidth, _height, colorFormat, colorType, 0);
|
glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, 0);
|
||||||
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[nextIndex]));
|
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[nextIndex]));
|
||||||
} else {
|
} else {
|
||||||
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[_numPBO -1]));
|
m_bindBuffer->bind(Parameter(GL_PIXEL_PACK_BUFFER), ObjectHandle(m_PBO[_numPBO -1]));
|
||||||
glReadPixels(_x0, _y0, m_pTexture->realWidth, _height, colorFormat, colorType, 0);
|
glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLubyte* pixelData = (GLubyte*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, m_pTexture->realWidth * _height * colorFormatBytes, GL_MAP_READ_BIT);
|
_heightOffset = 0;
|
||||||
if (pixelData == nullptr)
|
_stride = m_pTexture->realWidth;
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
int widthBytes = _width*colorFormatBytes;
|
return reinterpret_cast<u8*>(glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0,
|
||||||
int strideBytes = m_pTexture->realWidth * colorFormatBytes;
|
m_pTexture->realWidth * _params.height * _params.colorFormatBytes, GL_MAP_READ_BIT));
|
||||||
|
|
||||||
u8 * pixelDataAlloc = m_pixelData.data();
|
|
||||||
for (unsigned int lnIndex = 0; lnIndex < _height; ++lnIndex) {
|
|
||||||
memcpy(pixelDataAlloc + lnIndex*widthBytes, pixelData + (lnIndex*strideBytes), widthBytes);
|
|
||||||
}
|
|
||||||
return pixelDataAlloc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBufferReaderWithPixelBuffer::cleanUp()
|
void ColorBufferReaderWithPixelBuffer::cleanUp()
|
||||||
|
|
|
@ -12,7 +12,7 @@ public:
|
||||||
CachedBindBuffer * _bindBuffer);
|
CachedBindBuffer * _bindBuffer);
|
||||||
~ColorBufferReaderWithPixelBuffer();
|
~ColorBufferReaderWithPixelBuffer();
|
||||||
|
|
||||||
u8 * readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync) override;
|
const u8 * _readPixels(const ReadColorBufferParams& _params, u32& _heightOffset, u32& _stride) override;
|
||||||
void cleanUp() override;
|
void cleanUp() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -11,31 +11,20 @@ ColorBufferReaderWithReadPixels::ColorBufferReaderWithReadPixels(CachedTexture *
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 * ColorBufferReaderWithReadPixels::readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync)
|
const u8 * ColorBufferReaderWithReadPixels::_readPixels(const ReadColorBufferParams& _params, u32& _heightOffset,
|
||||||
|
u32& _stride)
|
||||||
{
|
{
|
||||||
const graphics::FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
|
GLenum format = GLenum(_params.colorFormat);
|
||||||
GLenum colorFormat, colorType, colorFormatBytes;
|
GLenum type = GLenum(_params.colorType);
|
||||||
if (_size > G_IM_SIZ_8b) {
|
|
||||||
colorFormat = GLenum(fbTexFormat.colorFormat);
|
|
||||||
colorType = GLenum(fbTexFormat.colorType);
|
|
||||||
colorFormatBytes = GLenum(fbTexFormat.colorFormatBytes);
|
|
||||||
} else {
|
|
||||||
colorFormat = GLenum(fbTexFormat.monochromeFormat);
|
|
||||||
colorType = GLenum(fbTexFormat.monochromeType);
|
|
||||||
colorFormatBytes = GLenum(fbTexFormat.monochromeFormatBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// No async pixel buffer copies are supported in this class, this is a last resort fallback
|
// No async pixel buffer copies are supported in this class, this is a last resort fallback
|
||||||
auto pixelData = std::unique_ptr<GLubyte[]>(new GLubyte[m_pTexture->realWidth * _height * colorFormatBytes]) ;
|
u8* gpuData = m_pixelData.data();
|
||||||
glReadPixels(_x0, _y0, m_pTexture->realWidth, _height, colorFormat, colorType, pixelData.get());
|
glReadPixels(_params.x0, _params.y0, m_pTexture->realWidth, _params.height, format, type, gpuData);
|
||||||
|
|
||||||
int widthBytes = _width*colorFormatBytes;
|
_heightOffset = 0;
|
||||||
int strideBytes = m_pTexture->realWidth * colorFormatBytes;
|
_stride = m_pTexture->realWidth;
|
||||||
|
|
||||||
for (unsigned int lnIndex = 0; lnIndex < _height; ++lnIndex) {
|
return gpuData;
|
||||||
std::copy_n(pixelData.get() + (lnIndex*strideBytes), widthBytes, m_pixelData.data() + lnIndex*widthBytes);
|
|
||||||
}
|
|
||||||
return m_pixelData.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColorBufferReaderWithReadPixels::cleanUp()
|
void ColorBufferReaderWithReadPixels::cleanUp()
|
||||||
|
|
|
@ -11,7 +11,7 @@ public:
|
||||||
ColorBufferReaderWithReadPixels(CachedTexture * _pTexture);
|
ColorBufferReaderWithReadPixels(CachedTexture * _pTexture);
|
||||||
~ColorBufferReaderWithReadPixels() = default;
|
~ColorBufferReaderWithReadPixels() = default;
|
||||||
|
|
||||||
u8 * readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync) override;
|
const u8 * _readPixels(const ReadColorBufferParams& _params, u32& _heightOffset, u32& _stride) override;
|
||||||
void cleanUp() override;
|
void cleanUp() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ MY_LOCAL_SRC_FILES := \
|
||||||
$(SRCDIR)/BufferCopy/DepthBufferToRDRAM.cpp \
|
$(SRCDIR)/BufferCopy/DepthBufferToRDRAM.cpp \
|
||||||
$(SRCDIR)/BufferCopy/RDRAMtoColorBuffer.cpp \
|
$(SRCDIR)/BufferCopy/RDRAMtoColorBuffer.cpp \
|
||||||
$(SRCDIR)/Graphics/Context.cpp \
|
$(SRCDIR)/Graphics/Context.cpp \
|
||||||
|
$(SRCDIR)/Graphics/ColorBufferReader.cpp \
|
||||||
$(SRCDIR)/Graphics/CombinerProgram.cpp \
|
$(SRCDIR)/Graphics/CombinerProgram.cpp \
|
||||||
$(SRCDIR)/Graphics/ObjectHandle.cpp \
|
$(SRCDIR)/Graphics/ObjectHandle.cpp \
|
||||||
$(SRCDIR)/Graphics/OpenGLContext/GLFunctions.cpp \
|
$(SRCDIR)/Graphics/OpenGLContext/GLFunctions.cpp \
|
||||||
|
|
Loading…
Reference in New Issue
Block a user