mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
![Sergey Lipskiy](/assets/img/avatar_default.png)
- use RiceVideo method for texture size calculation. RiceVideo uses the same method for texture dumping. - rewrite texture mapping. Texture Clamp-Wrap-Mirror implemented in shaders. Problem explanation: https://github.com/gonetz/GLideN64/issues/1885#issuecomment-485136358 Fixed various glitches with HD textures, #1885
97 lines
3.1 KiB
C++
97 lines
3.1 KiB
C++
|
|
#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)
|
|
{
|
|
int bytesToCopy = m_pTexture->width * _height * 16;
|
|
std::copy_n(_gpuData, bytesToCopy, 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;
|
|
|
|
if (_height * widthPixels > m_pixelData.size())
|
|
_height = static_cast<u32>(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<u8>(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<u32>(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);
|
|
}
|
|
}
|
|
} |