Commit 697ad3ed by Geoff Lang Committed by Shannon Woods

Replaced switches in Renderer::readPixels with calls to color reading and writing functions.

TRAC #23256 Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods Author: Geoff Lang
parent fe28ca06
...@@ -3483,249 +3483,6 @@ TextureStorage *Renderer11::createTextureStorage2DArray(int levels, GLenum inter ...@@ -3483,249 +3483,6 @@ TextureStorage *Renderer11::createTextureStorage2DArray(int levels, GLenum inter
return new TextureStorage11_2DArray(this, levels, internalformat, usage, width, height, depth); return new TextureStorage11_2DArray(this, levels, internalformat, usage, width, height, depth);
} }
static inline unsigned int getFastPixelCopySize(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType, GLuint clientVersion)
{
GLint sourceInternalFormat = d3d11_gl::GetInternalFormat(sourceFormat);
GLenum sourceGLFormat = gl::GetFormat(sourceInternalFormat, clientVersion);
GLenum sourceGLType = gl::GetType(sourceInternalFormat, clientVersion);
if (sourceGLFormat == destFormat && sourceGLType == destType)
{
return gl::GetPixelBytes(sourceInternalFormat, clientVersion);
}
else
{
return 0;
}
}
static inline void readPixelColor(const unsigned char *data, DXGI_FORMAT format, unsigned int x,
unsigned int y, int inputPitch, gl::ColorF *outColor)
{
switch (format)
{
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
{
unsigned int rgba = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch);
outColor->red = (rgba & 0x000000FF) * (1.0f / 0x000000FF);
outColor->green = (rgba & 0x0000FF00) * (1.0f / 0x0000FF00);
outColor->blue = (rgba & 0x00FF0000) * (1.0f / 0x00FF0000);
outColor->alpha = (rgba & 0xFF000000) * (1.0f / 0xFF000000);
}
break;
case DXGI_FORMAT_A8_UNORM:
{
outColor->red = 0.0f;
outColor->green = 0.0f;
outColor->blue = 0.0f;
outColor->alpha = *(data + x + y * inputPitch) / 255.0f;
}
break;
case DXGI_FORMAT_R32G32B32A32_FLOAT:
{
outColor->red = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 0);
outColor->green = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 1);
outColor->blue = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 2);
outColor->alpha = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 3);
}
break;
case DXGI_FORMAT_R32G32B32_FLOAT:
{
outColor->red = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 0);
outColor->green = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 1);
outColor->blue = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 2);
outColor->alpha = 1.0f;
}
break;
case DXGI_FORMAT_R16G16B16A16_FLOAT:
{
outColor->red = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 0));
outColor->green = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 1));
outColor->blue = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 2));
outColor->alpha = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 3));
}
break;
case DXGI_FORMAT_B8G8R8A8_UNORM:
{
unsigned int bgra = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch);
outColor->red = (bgra & 0x00FF0000) * (1.0f / 0x00FF0000);
outColor->blue = (bgra & 0x000000FF) * (1.0f / 0x000000FF);
outColor->green = (bgra & 0x0000FF00) * (1.0f / 0x0000FF00);
outColor->alpha = (bgra & 0xFF000000) * (1.0f / 0xFF000000);
}
break;
case DXGI_FORMAT_R8_UNORM:
{
outColor->red = *(data + x + y * inputPitch) / 255.0f;
outColor->green = 0.0f;
outColor->blue = 0.0f;
outColor->alpha = 1.0f;
}
break;
case DXGI_FORMAT_R8G8_UNORM:
{
unsigned short rg = *reinterpret_cast<const unsigned short*>(data + 2 * x + y * inputPitch);
outColor->red = (rg & 0xFF00) * (1.0f / 0xFF00);
outColor->green = (rg & 0x00FF) * (1.0f / 0x00FF);
outColor->blue = 0.0f;
outColor->alpha = 1.0f;
}
break;
case DXGI_FORMAT_R16_FLOAT:
{
outColor->red = gl::float16ToFloat32(*reinterpret_cast<const unsigned short*>(data + 2 * x + y * inputPitch));
outColor->green = 0.0f;
outColor->blue = 0.0f;
outColor->alpha = 1.0f;
}
break;
case DXGI_FORMAT_R16G16_FLOAT:
{
outColor->red = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 4 * x + y * inputPitch) + 0));
outColor->green = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 4 * x + y * inputPitch) + 1));
outColor->blue = 0.0f;
outColor->alpha = 1.0f;
}
break;
case DXGI_FORMAT_R10G10B10A2_UNORM:
{
unsigned int rgba = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch);
outColor->red = (rgba & 0x000003FF) * (1.0f / 0x000003FF);
outColor->green = (rgba & 0x000FFC00) * (1.0f / 0x000FFC00);
outColor->blue = (rgba & 0x3FF00000) * (1.0f / 0x3FF00000);
outColor->alpha = (rgba & 0xC0000000) * (1.0f / 0xC0000000);
}
break;
default:
ERR("ReadPixelColor not implemented for DXGI format %u.", format);
UNIMPLEMENTED();
break;
}
}
static inline void writePixelColor(const gl::ColorF &color, GLenum format, GLenum type, unsigned int x,
unsigned int y, int outputPitch, void *outData)
{
unsigned char* byteData = reinterpret_cast<unsigned char*>(outData);
unsigned short* shortData = reinterpret_cast<unsigned short*>(outData);
unsigned int* intData = reinterpret_cast<unsigned int*>(outData);
switch (format)
{
case GL_RGBA:
switch (type)
{
case GL_UNSIGNED_BYTE:
byteData[4 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.red + 0.5f);
byteData[4 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
byteData[4 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.blue + 0.5f);
byteData[4 * x + y * outputPitch + 3] = static_cast<unsigned char>(255 * color.alpha + 0.5f);
break;
case GL_UNSIGNED_INT_2_10_10_10_REV:
intData[x + y * outputPitch / sizeof(unsigned int)] = (static_cast<unsigned int>( 3 * color.alpha) << 30) |
(static_cast<unsigned int>(1023 * color.red ) << 20) |
(static_cast<unsigned int>(1023 * color.green) << 10) |
(static_cast<unsigned int>(1023 * color.blue ) << 0);
break;
default:
ERR("WritePixelColor not implemented for format GL_RGBA and type 0x%X.", type);
UNIMPLEMENTED();
break;
}
break;
case GL_BGRA_EXT:
switch (type)
{
case GL_UNSIGNED_BYTE:
byteData[4 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.blue + 0.5f);
byteData[4 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
byteData[4 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.red + 0.5f);
byteData[4 * x + y * outputPitch + 3] = static_cast<unsigned char>(255 * color.alpha + 0.5f);
break;
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
// this type is packed as follows:
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// --------------------------------------------------------------------------------
// | 4th | 3rd | 2nd | 1st component |
// --------------------------------------------------------------------------------
// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
shortData[x + y * outputPitch / sizeof(unsigned short)] =
(static_cast<unsigned short>(15 * color.alpha + 0.5f) << 12) |
(static_cast<unsigned short>(15 * color.red + 0.5f) << 8) |
(static_cast<unsigned short>(15 * color.green + 0.5f) << 4) |
(static_cast<unsigned short>(15 * color.blue + 0.5f) << 0);
break;
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
// this type is packed as follows:
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// --------------------------------------------------------------------------------
// | 4th | 3rd | 2nd | 1st component |
// --------------------------------------------------------------------------------
// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
shortData[x + y * outputPitch / sizeof(unsigned short)] =
(static_cast<unsigned short>( color.alpha + 0.5f) << 15) |
(static_cast<unsigned short>(31 * color.red + 0.5f) << 10) |
(static_cast<unsigned short>(31 * color.green + 0.5f) << 5) |
(static_cast<unsigned short>(31 * color.blue + 0.5f) << 0);
break;
default:
ERR("WritePixelColor not implemented for format GL_BGRA_EXT and type 0x%X.", type);
UNIMPLEMENTED();
break;
}
break;
case GL_RGB:
switch (type)
{
case GL_UNSIGNED_SHORT_5_6_5:
shortData[x + y * outputPitch / sizeof(unsigned short)] =
(static_cast<unsigned short>(31 * color.blue + 0.5f) << 0) |
(static_cast<unsigned short>(63 * color.green + 0.5f) << 5) |
(static_cast<unsigned short>(31 * color.red + 0.5f) << 11);
break;
case GL_UNSIGNED_BYTE:
byteData[3 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.red + 0.5f);
byteData[3 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
byteData[3 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.blue + 0.5f);
break;
default:
ERR("WritePixelColor not implemented for format GL_RGB and type 0x%X.", type);
UNIMPLEMENTED();
break;
}
break;
default:
ERR("WritePixelColor not implemented for format 0x%X.", format);
UNIMPLEMENTED();
break;
}
}
void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area,
GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder, GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder,
GLint packAlignment, void *pixels) GLint packAlignment, void *pixels)
...@@ -3816,43 +3573,65 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou ...@@ -3816,43 +3573,65 @@ void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResou
inputPitch = static_cast<int>(mapping.RowPitch); inputPitch = static_cast<int>(mapping.RowPitch);
} }
unsigned int fastPixelSize = getFastPixelCopySize(textureDesc.Format, format, type, getCurrentClientVersion()); GLuint clientVersion = getCurrentClientVersion();
if (fastPixelSize != 0)
GLint sourceInternalFormat = d3d11_gl::GetInternalFormat(textureDesc.Format);
GLenum sourceFormat = gl::GetFormat(sourceInternalFormat, clientVersion);
GLenum sourceType = gl::GetType(sourceInternalFormat, clientVersion);
GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
if (sourceFormat == format && sourceType == type)
{ {
// Direct copy possible
unsigned char *dest = static_cast<unsigned char*>(pixels); unsigned char *dest = static_cast<unsigned char*>(pixels);
for (int j = 0; j < area.height; j++) for (int y = 0; y < area.height; y++)
{ {
memcpy(dest + j * outputPitch, source + j * inputPitch, area.width * fastPixelSize); memcpy(dest + y * outputPitch, source + y * inputPitch, area.width * sourcePixelSize);
} }
} }
else if (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM && else
format == GL_RGBA &&
type == GL_UNSIGNED_BYTE)
{ {
// Fast path for swapping red with blue GLint destInternalFormat = gl::GetSizedInternalFormat(format, type, clientVersion);
unsigned char *dest = static_cast<unsigned char*>(pixels); GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion);
for (int j = 0; j < area.height; j++) ColorCopyFunction fastCopyFunc = d3d11::GetFastCopyFunction(textureDesc.Format, format, type, getCurrentClientVersion());
if (fastCopyFunc)
{
// Fast copy is possible through some special function
for (int y = 0; y < area.height; y++)
{ {
for (int i = 0; i < area.width; i++) for (int x = 0; x < area.width; x++)
{ {
unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize;
*(unsigned int*)(dest + 4 * i + j * outputPitch) = void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
(argb & 0xFF00FF00) | // Keep alpha and green
(argb & 0x00FF0000) >> 16 | // Move red to blue fastCopyFunc(src, dest);
(argb & 0x000000FF) << 16; // Move blue to red
} }
} }
} }
else else
{ {
gl::ColorF pixelColor; ColorReadFunction readFunc = d3d11::GetColorReadFunction(textureDesc.Format);
for (int j = 0; j < area.height; j++) ColorWriteFunction writeFunc = gl::GetColorWriteFunction(format, type, clientVersion);
unsigned char temp[16]; // Maximum size of any Color<T> type used.
META_ASSERT(sizeof(temp) >= sizeof(gl::ColorF) &&
sizeof(temp) >= sizeof(gl::ColorUI) &&
sizeof(temp) >= sizeof(gl::ColorI));
for (int y = 0; y < area.height; y++)
{ {
for (int i = 0; i < area.width; i++) for (int x = 0; x < area.width; x++)
{ {
readPixelColor(source, textureDesc.Format, i, j, inputPitch, &pixelColor); void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize;
writePixelColor(pixelColor, format, type, i, j, outputPitch, pixels); void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
// readFunc and writeFunc will be using the same type of color, CopyTexImage
// will not allow the copy otherwise.
readFunc(src, temp);
writeFunc(temp, dest);
}
} }
} }
} }
......
...@@ -2880,9 +2880,6 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz ...@@ -2880,9 +2880,6 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
return; // No sensible error to generate return; // No sensible error to generate
} }
unsigned char *dest = (unsigned char*)pixels;
unsigned short *dest16 = (unsigned short*)pixels;
unsigned char *source; unsigned char *source;
int inputPitch; int inputPitch;
if (packReverseRowOrder) if (packReverseRowOrder)
...@@ -2896,224 +2893,63 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz ...@@ -2896,224 +2893,63 @@ void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsiz
inputPitch = lock.Pitch; inputPitch = lock.Pitch;
} }
unsigned int fastPixelSize = 0; GLuint clientVersion = getCurrentClientVersion();
if (desc.Format == D3DFMT_A8R8G8B8 && GLint sourceInternalFormat = d3d9_gl::GetInternalFormat(desc.Format);
format == GL_BGRA_EXT && GLenum sourceFormat = gl::GetFormat(sourceInternalFormat, clientVersion);
type == GL_UNSIGNED_BYTE) GLenum sourceType = gl::GetType(sourceInternalFormat, clientVersion);
{
fastPixelSize = 4;
}
else if ((desc.Format == D3DFMT_A4R4G4B4 &&
format == GL_BGRA_EXT &&
type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) ||
(desc.Format == D3DFMT_A1R5G5B5 &&
format == GL_BGRA_EXT &&
type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT))
{
fastPixelSize = 2;
}
else if (desc.Format == D3DFMT_A16B16G16R16F &&
format == GL_RGBA &&
type == GL_HALF_FLOAT_OES)
{
fastPixelSize = 8;
}
else if (desc.Format == D3DFMT_A32B32G32R32F &&
format == GL_RGBA &&
type == GL_FLOAT)
{
fastPixelSize = 16;
}
for (int j = 0; j < rect.bottom - rect.top; j++) GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
{
if (fastPixelSize != 0) if (sourceFormat == format && sourceType == type)
{
// Fast path for formats which require no translation:
// D3DFMT_A8R8G8B8 to BGRA/UNSIGNED_BYTE
// D3DFMT_A4R4G4B4 to BGRA/UNSIGNED_SHORT_4_4_4_4_REV_EXT
// D3DFMT_A1R5G5B5 to BGRA/UNSIGNED_SHORT_1_5_5_5_REV_EXT
// D3DFMT_A16B16G16R16F to RGBA/HALF_FLOAT_OES
// D3DFMT_A32B32G32R32F to RGBA/FLOAT
//
// Note that buffers with no alpha go through the slow path below.
memcpy(dest + j * outputPitch,
source + j * inputPitch,
(rect.right - rect.left) * fastPixelSize);
continue;
}
else if (desc.Format == D3DFMT_A8R8G8B8 &&
format == GL_RGBA &&
type == GL_UNSIGNED_BYTE)
{ {
// Fast path for swapping red with blue // Direct copy possible
for (int i = 0; i < rect.right - rect.left; i++) unsigned char *dest = static_cast<unsigned char*>(pixels);
for (int y = 0; y < rect.bottom - rect.top; y++)
{ {
unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); memcpy(dest + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourcePixelSize);
*(unsigned int*)(dest + 4 * i + j * outputPitch) =
(argb & 0xFF00FF00) | // Keep alpha and green
(argb & 0x00FF0000) >> 16 | // Move red to blue
(argb & 0x000000FF) << 16; // Move blue to red
} }
continue;
} }
else
for (int i = 0; i < rect.right - rect.left; i++)
{ {
float r; GLint destInternalFormat = gl::GetSizedInternalFormat(format, type, clientVersion);
float g; GLuint destPixelSize = gl::GetPixelBytes(destInternalFormat, clientVersion);
float b; GLuint sourcePixelSize = gl::GetPixelBytes(sourceInternalFormat, clientVersion);
float a;
switch (desc.Format) ColorCopyFunction fastCopyFunc = d3d9::GetFastCopyFunction(desc.Format, format, type, getCurrentClientVersion());
if (fastCopyFunc)
{ {
case D3DFMT_R5G6B5: // Fast copy is possible through some special function
for (int y = 0; y < rect.bottom - rect.top; y++)
{ {
unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); for (int x = 0; x < rect.right - rect.left; x++)
a = 1.0f;
b = (rgb & 0x001F) * (1.0f / 0x001F);
g = (rgb & 0x07E0) * (1.0f / 0x07E0);
r = (rgb & 0xF800) * (1.0f / 0xF800);
}
break;
case D3DFMT_A1R5G5B5:
{ {
unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); void *dest = static_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize;
void *src = static_cast<unsigned char*>(source) + y * inputPitch + x * sourcePixelSize;
a = (argb & 0x8000) ? 1.0f : 0.0f; fastCopyFunc(src, dest);
b = (argb & 0x001F) * (1.0f / 0x001F);
g = (argb & 0x03E0) * (1.0f / 0x03E0);
r = (argb & 0x7C00) * (1.0f / 0x7C00);
} }
break;
case D3DFMT_A8R8G8B8:
{
unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
} }
break;
case D3DFMT_X8R8G8B8:
{
unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
a = 1.0f;
b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
} }
break; else
case D3DFMT_A2R10G10B10:
{ {
unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); ColorReadFunction readFunc = d3d9::GetColorReadFunction(desc.Format);
ColorWriteFunction writeFunc = gl::GetColorWriteFunction(format, type, clientVersion);
a = (argb & 0xC0000000) * (1.0f / 0xC0000000); gl::ColorF temp;
b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
}
break;
case D3DFMT_A32B32G32R32F:
{
// float formats in D3D are stored rgba, rather than the other way round
r = *((float*)(source + 16 * i + j * inputPitch) + 0);
g = *((float*)(source + 16 * i + j * inputPitch) + 1);
b = *((float*)(source + 16 * i + j * inputPitch) + 2);
a = *((float*)(source + 16 * i + j * inputPitch) + 3);
}
break;
case D3DFMT_A16B16G16R16F:
{
// float formats in D3D are stored rgba, rather than the other way round
r = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 0));
g = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 1));
b = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 2));
a = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 3));
}
break;
default:
UNIMPLEMENTED(); // FIXME
UNREACHABLE();
return;
}
switch (format) for (int y = 0; y < rect.bottom - rect.top; y++)
{
case GL_RGBA:
switch (type)
{ {
case GL_UNSIGNED_BYTE: for (int x = 0; x < rect.right - rect.left; x++)
dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
break;
default: UNREACHABLE();
}
break;
case GL_BGRA_EXT:
switch (type)
{ {
case GL_UNSIGNED_BYTE: void *dest = reinterpret_cast<unsigned char*>(pixels) + y * outputPitch + x * destPixelSize;
dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f); void *src = source + y * inputPitch + x * sourcePixelSize;
dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f); // readFunc and writeFunc will be using the same type of color, CopyTexImage
dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); // will not allow the copy otherwise.
break; readFunc(src, &temp);
case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: writeFunc(&temp, dest);
// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
// this type is packed as follows:
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// --------------------------------------------------------------------------------
// | 4th | 3rd | 2nd | 1st component |
// --------------------------------------------------------------------------------
// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)(15 * a + 0.5f) << 12)|
((unsigned short)(15 * r + 0.5f) << 8) |
((unsigned short)(15 * g + 0.5f) << 4) |
((unsigned short)(15 * b + 0.5f) << 0);
break;
case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
// this type is packed as follows:
// 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
// --------------------------------------------------------------------------------
// | 4th | 3rd | 2nd | 1st component |
// --------------------------------------------------------------------------------
// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)( a + 0.5f) << 15) |
((unsigned short)(31 * r + 0.5f) << 10) |
((unsigned short)(31 * g + 0.5f) << 5) |
((unsigned short)(31 * b + 0.5f) << 0);
break;
default: UNREACHABLE();
}
break;
case GL_RGB:
switch (type)
{
case GL_UNSIGNED_SHORT_5_6_5:
dest16[i + j * outputPitch / sizeof(unsigned short)] =
((unsigned short)(31 * b + 0.5f) << 0) |
((unsigned short)(63 * g + 0.5f) << 5) |
((unsigned short)(31 * r + 0.5f) << 11);
break;
case GL_UNSIGNED_BYTE:
dest[3 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
dest[3 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
dest[3 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
break;
default: UNREACHABLE();
} }
break;
default: UNREACHABLE();
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment