MYST3: Use YUVToRGBMan to convert jpeg YUV planes

And assorted clean ups.
Yields an overall 10% gain when loading cube nodes
This commit is contained in:
Bastien Bouclet 2012-12-03 14:27:56 +01:00
parent 2d38944f47
commit 80612ef6c9
4 changed files with 46 additions and 63 deletions

View File

@ -83,9 +83,6 @@ OpenGLTexture::OpenGLTexture(const Graphics::Surface *surface) {
if (format.bytesPerPixel == 4) {
internalFormat = GL_RGBA;
sourceFormat = GL_UNSIGNED_BYTE;
} else if (format.bytesPerPixel == 3) {
internalFormat = GL_RGB;
sourceFormat = GL_UNSIGNED_BYTE;
} else if (format.bytesPerPixel == 2) {
internalFormat = GL_RGB;
sourceFormat = GL_UNSIGNED_SHORT_5_6_5;
@ -409,9 +406,9 @@ void Renderer::drawTexturedRect3D(const Math::Vector3d &topLeft, const Math::Vec
Graphics::Surface *Renderer::getScreenshot() {
Graphics::Surface *s = new Graphics::Surface();
s->create(kOriginalWidth, kOriginalHeight, Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0));
s->create(kOriginalWidth, kOriginalHeight, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
glReadPixels(0, 0, kOriginalWidth, kOriginalHeight, GL_RGB, GL_UNSIGNED_BYTE, s->pixels);
glReadPixels(0, 0, kOriginalWidth, kOriginalHeight, GL_RGBA, GL_UNSIGNED_BYTE, s->pixels);
return s;
}

View File

@ -40,7 +40,7 @@ Menu::Menu(Myst3Engine *vm) :
_saveDrawCaret(false),
_saveCaretCounter(0) {
_saveThumb = new Graphics::Surface();
_saveThumb->create(240, 135, Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0));
_saveThumb->create(240, 135, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
}
Menu::~Menu() {
@ -345,7 +345,7 @@ void Menu::saveMenuOpen() {
// Update the thumbnail to display
if (_saveLoadSpotItem && _saveThumb)
_saveLoadSpotItem->updateData((uint8 *)_saveThumb->pixels);
_saveLoadSpotItem->updateData(_saveThumb);
}
void Menu::saveMenuSelect(uint16 item) {
@ -539,37 +539,35 @@ void Menu::saveGameReadThumbnail(Common::InSaveFile *save) {
// Start of thumbnail data
save->seek(8580);
uint8 *thumbnail = new uint8[kMiniatureSize * 3];
Graphics::Surface *thumbnail = new Graphics::Surface();
thumbnail->create(240, 135, Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24));
// The spot item expects RGB data instead of RGBA
uint8 *ptr = thumbnail;
for (uint i = 0; i < kMiniatureSize; i++) {
uint32 rgba = save->readUint32LE();
uint8 a, r, g, b;
Graphics::colorToARGB< Graphics::ColorMasks<8888> >(rgba, a, r, g, b);
*ptr++ = r;
*ptr++ = g;
*ptr++ = b;
}
// Read BGRA
save->read(thumbnail->pixels, kMiniatureSize * 4);
// Convert to RGBA
thumbnail->convertToInPlace(Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
if (_saveLoadSpotItem)
_saveLoadSpotItem->updateData(thumbnail);
delete[] thumbnail;
thumbnail->free();
delete thumbnail;
}
void Menu::saveGameWriteThumbnail(Common::OutSaveFile *save) {
// The file expects ARGB data instead of RGB
// The file expects BGRA data instead of RGBA
uint8 *src = (uint8 *)_saveThumb->pixels;
for (uint i = 0; i < kMiniatureSize; i++) {
uint8 r, g, b;
uint8 r, g, b, a;
r = *src++;
g = *src++;
b = *src++;
a = *src++;
save->writeByte(b);
save->writeByte(g);
save->writeByte(r);
save->writeByte(0xFF); // Alpha
save->writeByte(a);
}
}
@ -590,22 +588,20 @@ Common::String Menu::prepareSaveNameForDisplay(const Common::String &name) {
}
void Menu::createThumbnail(Graphics::Surface *big, Graphics::Surface *small) {
assert(big->format.bytesPerPixel == 3
&& small->format.bytesPerPixel == 3);
assert(big->format.bytesPerPixel == 4
&& small->format.bytesPerPixel == 4);
uint bigHeight = big->h - Renderer::kTopBorderHeight - Renderer::kBottomBorderHeight;
uint bigYOffset = Renderer::kBottomBorderHeight;
uint8 *dst = (uint8 *)small->pixels;
uint32 *dst = (uint32 *)small->pixels;
for (uint i = 0; i < small->h; i++) {
for (uint j = 0; j < small->w; j++) {
uint32 srcX = big->w * j / small->w;
uint32 srcY = bigYOffset + bigHeight - bigHeight * i / small->h;
uint8 *src = (uint8 *)big->getBasePtr(srcX, srcY - 1);
uint32 *src = (uint32 *)big->getBasePtr(srcX, srcY - 1);
// Copy RGB bytes
*dst++ = *src++;
*dst++ = *src++;
// Copy RGBA pixel
*dst++ = *src++;
}
}

View File

@ -29,26 +29,20 @@
#include "common/debug.h"
#include "common/rect.h"
#include "graphics/conversion.h"
#include "graphics/yuv_to_rgb.h"
namespace Myst3 {
void Face::setTextureFromJPEG(Graphics::JPEGDecoder *jpeg) {
_bitmap = new Graphics::Surface();
_bitmap->create(jpeg->getComponent(1)->w, jpeg->getComponent(1)->h, Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0));
_bitmap->create(jpeg->getComponent(1)->w, jpeg->getComponent(1)->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
const byte *y = (const byte *)jpeg->getComponent(1)->getBasePtr(0, 0);
const byte *u = (const byte *)jpeg->getComponent(2)->getBasePtr(0, 0);
const byte *v = (const byte *)jpeg->getComponent(3)->getBasePtr(0, 0);
byte *ptr = (byte *)_bitmap->getBasePtr(0, 0);
for (int i = 0; i < _bitmap->w * _bitmap->h; i++) {
byte r, g, b;
Graphics::YUV2RGB(*y++, *u++, *v++, r, g, b);
*ptr++ = r;
*ptr++ = g;
*ptr++ = b;
}
YUVToRGBMan.convert444(_bitmap, Graphics::YUVToRGBManager::kScaleFull, y, u, v,
_bitmap->w, _bitmap->h, jpeg->getComponent(1)->pitch, jpeg->getComponent(2)->pitch);
_texture = _vm->_gfx->createTexture(_bitmap);
}
@ -296,7 +290,7 @@ SpotItemFace::~SpotItemFace() {
void SpotItemFace::initBlack(uint16 width, uint16 height) {
_bitmap = new Graphics::Surface();
_bitmap->create(width, height, Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0));
_bitmap->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
initNotDrawn(width, height);
}
@ -304,30 +298,23 @@ void SpotItemFace::initBlack(uint16 width, uint16 height) {
void SpotItemFace::loadData(Graphics::JPEGDecoder *jpeg) {
// Convert active SpotItem image to raw data
_bitmap = new Graphics::Surface();
_bitmap->create(jpeg->getComponent(1)->w, jpeg->getComponent(1)->h, Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0));
_bitmap->create(jpeg->getComponent(1)->w, jpeg->getComponent(1)->h, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
for (int i = 0; i < _bitmap->h; i++) {
const byte *y = (const byte *)jpeg->getComponent(1)->getBasePtr(0, i);
const byte *u = (const byte *)jpeg->getComponent(2)->getBasePtr(0, i);
const byte *v = (const byte *)jpeg->getComponent(3)->getBasePtr(0, i);
const byte *y = (const byte *)jpeg->getComponent(1)->getBasePtr(0, 0);
const byte *u = (const byte *)jpeg->getComponent(2)->getBasePtr(0, 0);
const byte *v = (const byte *)jpeg->getComponent(3)->getBasePtr(0, 0);
byte *ptr = (byte *)_bitmap->getBasePtr(0, i);
for (int j = 0; j < _bitmap->w; j++) {
byte r, g, b;
Graphics::YUV2RGB(*y++, *u++, *v++, r, g, b);
*ptr++ = r;
*ptr++ = g;
*ptr++ = b;
}
}
YUVToRGBMan.convert444(_bitmap, Graphics::YUVToRGBManager::kScaleFull, y, u, v,
_bitmap->w, _bitmap->h, jpeg->getComponent(1)->pitch, jpeg->getComponent(2)->pitch);
initNotDrawn(_bitmap->w, _bitmap->h);
}
void SpotItemFace::updateData(const uint8 *data) {
assert(_bitmap && data);
memcpy(_bitmap->pixels, data, _bitmap->pitch * _bitmap->h);
void SpotItemFace::updateData(const Graphics::Surface *surface) {
assert(_bitmap && surface);
_bitmap->free();
_bitmap->copyFrom(*surface);
_drawn = false;
}
@ -341,11 +328,11 @@ void SpotItemFace::clear() {
void SpotItemFace::initNotDrawn(uint16 width, uint16 height) {
// Copy not drawn SpotItem image from face
_notDrawnBitmap = new Graphics::Surface();
_notDrawnBitmap->create(width, height, Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0));
_notDrawnBitmap->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
for (uint i = 0; i < height; i++) {
memcpy(_notDrawnBitmap->getBasePtr(0, i),
_face->_bitmap->getBasePtr(_posX, _posY + i), width * 3);
_face->_bitmap->getBasePtr(_posX, _posY + i), width * 4);
}
}
@ -353,7 +340,7 @@ void SpotItemFace::draw() {
for (uint i = 0; i < _bitmap->h; i++) {
memcpy(_face->_bitmap->getBasePtr(_posX, _posY + i),
_bitmap->getBasePtr(0, i),
_bitmap->w * 3);
_bitmap->w * 4);
}
_drawn = true;
@ -364,7 +351,7 @@ void SpotItemFace::undraw() {
for (uint i = 0; i < _notDrawnBitmap->h; i++) {
memcpy(_face->_bitmap->getBasePtr(_posX, _posY + i),
_notDrawnBitmap->getBasePtr(0, i),
_notDrawnBitmap->w * 3);
_notDrawnBitmap->w * 4);
}
_drawn = false;
@ -381,14 +368,17 @@ void SpotItemFace::fadeDraw() {
byte rND = *ptrND++;
byte gND = *ptrND++;
byte bND = *ptrND++;
ptrND++; // Alpha
byte rD = *ptrD++;
byte gD = *ptrD++;
byte bD = *ptrD++;
ptrD++; // Alpha
// TODO: optimize ?
*ptrDest++ = rND * (100 - _fadeValue) / 100 + rD * _fadeValue / 100;
*ptrDest++ = gND * (100 - _fadeValue) / 100 + gD * _fadeValue / 100;
*ptrDest++ = bND * (100 - _fadeValue) / 100 + bD * _fadeValue / 100;
ptrDest++; // Alpha
}
}

View File

@ -62,7 +62,7 @@ class SpotItemFace {
void initBlack(uint16 width, uint16 height);
void loadData(Graphics::JPEGDecoder *jpeg);
void updateData(const uint8 *data);
void updateData(const Graphics::Surface *surface);
void clear();
void draw();