mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-30 12:05:39 +00:00
Changed the renderer pixel format from RGBA to BGRA.
Also implemented premultiplied alpha for all images, animations and videos and improved the carousel reflection falloff logic.
This commit is contained in:
parent
ab11f36ece
commit
3c82bb4dfb
|
@ -39,6 +39,8 @@ std::vector<unsigned char> ImageIO::loadFromMemoryRGBA32(const unsigned char* da
|
||||||
fiBitmap = fiConverted;
|
fiBitmap = fiConverted;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FreeImage_PreMultiplyWithAlpha(fiBitmap);
|
||||||
|
|
||||||
if (fiBitmap != nullptr) {
|
if (fiBitmap != nullptr) {
|
||||||
width = FreeImage_GetWidth(fiBitmap);
|
width = FreeImage_GetWidth(fiBitmap);
|
||||||
height = FreeImage_GetHeight(fiBitmap);
|
height = FreeImage_GetHeight(fiBitmap);
|
||||||
|
@ -49,16 +51,7 @@ std::vector<unsigned char> ImageIO::loadFromMemoryRGBA32(const unsigned char* da
|
||||||
const BYTE* scanLine {FreeImage_GetScanLine(fiBitmap, static_cast<int>(i))};
|
const BYTE* scanLine {FreeImage_GetScanLine(fiBitmap, static_cast<int>(i))};
|
||||||
memcpy(tempData + (i * width * 4), scanLine, width * 4);
|
memcpy(tempData + (i * width * 4), scanLine, width * 4);
|
||||||
}
|
}
|
||||||
// Convert from BGRA to RGBA.
|
|
||||||
for (size_t i = 0; i < width * height; ++i) {
|
|
||||||
RGBQUAD bgra {reinterpret_cast<RGBQUAD*>(tempData)[i]};
|
|
||||||
RGBQUAD rgba;
|
|
||||||
rgba.rgbBlue = bgra.rgbRed;
|
|
||||||
rgba.rgbGreen = bgra.rgbGreen;
|
|
||||||
rgba.rgbRed = bgra.rgbBlue;
|
|
||||||
rgba.rgbReserved = bgra.rgbReserved;
|
|
||||||
reinterpret_cast<RGBQUAD*>(tempData)[i] = rgba;
|
|
||||||
}
|
|
||||||
rawData = std::vector<unsigned char> {tempData, tempData + width * height * 4};
|
rawData = std::vector<unsigned char> {tempData, tempData + width * height * 4};
|
||||||
// Free bitmap data.
|
// Free bitmap data.
|
||||||
FreeImage_Unload(fiBitmap);
|
FreeImage_Unload(fiBitmap);
|
||||||
|
|
|
@ -138,7 +138,7 @@ bool Window::init()
|
||||||
mBackgroundOverlay->setImage(":/graphics/frame.png");
|
mBackgroundOverlay->setImage(":/graphics/frame.png");
|
||||||
mBackgroundOverlay->setResize(mRenderer->getScreenWidth(), mRenderer->getScreenHeight());
|
mBackgroundOverlay->setResize(mRenderer->getScreenWidth(), mRenderer->getScreenHeight());
|
||||||
|
|
||||||
mPostprocessedBackground = TextureResource::get("");
|
mPostprocessedBackground = TextureResource::get("", false, false, false, false, false);
|
||||||
|
|
||||||
mListScrollFont = Font::get(FONT_SIZE_LARGE);
|
mListScrollFont = Font::get(FONT_SIZE_LARGE);
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ public:
|
||||||
void setAllowTextScrolling(bool value) { mAllowTextScrolling = value; }
|
void setAllowTextScrolling(bool value) { mAllowTextScrolling = value; }
|
||||||
bool getAllowTextScrolling() { return mAllowTextScrolling; }
|
bool getAllowTextScrolling() { return mAllowTextScrolling; }
|
||||||
|
|
||||||
// For Lottie animations.
|
// For GIF and Lottie animations.
|
||||||
void setAllowFileAnimation(bool value) { mAllowFileAnimation = value; }
|
void setAllowFileAnimation(bool value) { mAllowFileAnimation = value; }
|
||||||
bool getAllowFileAnimation() { return mAllowFileAnimation; }
|
bool getAllowFileAnimation() { return mAllowFileAnimation; }
|
||||||
|
|
||||||
|
|
|
@ -190,10 +190,11 @@ void GIFAnimComponent::setAnimation(const std::string& path)
|
||||||
mSize.x = static_cast<float>(width);
|
mSize.x = static_cast<float>(width);
|
||||||
mSize.y = static_cast<float>(height);
|
mSize.y = static_cast<float>(height);
|
||||||
|
|
||||||
|
FreeImage_PreMultiplyWithAlpha(mFrame);
|
||||||
mPictureRGBA.resize(mFileWidth * mFileHeight * 4);
|
mPictureRGBA.resize(mFileWidth * mFileHeight * 4);
|
||||||
|
|
||||||
FreeImage_ConvertToRawBits(reinterpret_cast<BYTE*>(&mPictureRGBA.at(0)), mFrame, filePitch, 32,
|
FreeImage_ConvertToRawBits(reinterpret_cast<BYTE*>(&mPictureRGBA.at(0)), mFrame, filePitch, 32,
|
||||||
FI_RGBA_RED, FI_RGBA_GREEN, FI_RGBA_BLUE, 1);
|
FI_RGBA_BLUE, FI_RGBA_GREEN, FI_RGBA_RED, 1);
|
||||||
|
|
||||||
mTexture->initFromPixels(&mPictureRGBA.at(0), mFileWidth, mFileHeight);
|
mTexture->initFromPixels(&mPictureRGBA.at(0), mFileWidth, mFileHeight);
|
||||||
|
|
||||||
|
@ -453,6 +454,7 @@ void GIFAnimComponent::render(const glm::mat4& parentTrans)
|
||||||
FIF_GIF, &mAnimIO, static_cast<fi_handle>(mAnimFile), GIF_PLAYBACK);
|
FIF_GIF, &mAnimIO, static_cast<fi_handle>(mAnimFile), GIF_PLAYBACK);
|
||||||
|
|
||||||
mFrame = FreeImage_LockPage(mAnimation, mFrameNum);
|
mFrame = FreeImage_LockPage(mAnimation, mFrameNum);
|
||||||
|
FreeImage_PreMultiplyWithAlpha(mFrame);
|
||||||
mPictureRGBA.clear();
|
mPictureRGBA.clear();
|
||||||
mPictureRGBA.resize(mFrameSize);
|
mPictureRGBA.resize(mFrameSize);
|
||||||
|
|
||||||
|
@ -496,7 +498,7 @@ void GIFAnimComponent::render(const glm::mat4& parentTrans)
|
||||||
vertices->saturation = mSaturation * mThemeSaturation;
|
vertices->saturation = mSaturation * mThemeSaturation;
|
||||||
vertices->opacity = mOpacity * mThemeOpacity;
|
vertices->opacity = mOpacity * mThemeOpacity;
|
||||||
vertices->dimming = mDimming;
|
vertices->dimming = mDimming;
|
||||||
vertices->shaderFlags = Renderer::ShaderFlags::BGRA_TO_RGBA;
|
vertices->shaderFlags = Renderer::ShaderFlags::PREMULTIPLIED;
|
||||||
|
|
||||||
// Render it.
|
// Render it.
|
||||||
mRenderer->drawTriangleStrips(&vertices[0], 4);
|
mRenderer->drawTriangleStrips(&vertices[0], 4);
|
||||||
|
|
|
@ -350,7 +350,7 @@ void ImageComponent::render(const glm::mat4& parentTrans)
|
||||||
mClipRegion.w - mClipRegion.y, 0xFF000033, 0xFF000033);
|
mClipRegion.w - mClipRegion.y, 0xFF000033, 0xFF000033);
|
||||||
}
|
}
|
||||||
// An image with zero size would normally indicate a corrupt image file.
|
// An image with zero size would normally indicate a corrupt image file.
|
||||||
if (mTexture->getSize() != glm::ivec2 {}) {
|
if (mTexture->getSize() != glm::ivec2 {0, 0}) {
|
||||||
// Actually draw the image.
|
// Actually draw the image.
|
||||||
// The bind() function returns false if the texture is not currently loaded. A blank
|
// The bind() function returns false if the texture is not currently loaded. A blank
|
||||||
// texture is bound in this case but we want to handle a fade so it doesn't just
|
// texture is bound in this case but we want to handle a fade so it doesn't just
|
||||||
|
@ -367,6 +367,7 @@ void ImageComponent::render(const glm::mat4& parentTrans)
|
||||||
mVertices->dimming = mDimming;
|
mVertices->dimming = mDimming;
|
||||||
mVertices->reflectionsFalloff = mReflectionsFalloff;
|
mVertices->reflectionsFalloff = mReflectionsFalloff;
|
||||||
|
|
||||||
|
mVertices->shaderFlags = mVertices->shaderFlags | Renderer::ShaderFlags::PREMULTIPLIED;
|
||||||
mRenderer->drawTriangleStrips(&mVertices[0], 4);
|
mRenderer->drawTriangleStrips(&mVertices[0], 4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -487,7 +487,7 @@ void LottieAnimComponent::render(const glm::mat4& parentTrans)
|
||||||
vertices->saturation = mSaturation * mThemeSaturation;
|
vertices->saturation = mSaturation * mThemeSaturation;
|
||||||
vertices->opacity = mOpacity * mThemeOpacity;
|
vertices->opacity = mOpacity * mThemeOpacity;
|
||||||
vertices->dimming = mDimming;
|
vertices->dimming = mDimming;
|
||||||
vertices->shaderFlags = Renderer::ShaderFlags::BGRA_TO_RGBA;
|
vertices->shaderFlags = Renderer::ShaderFlags::PREMULTIPLIED;
|
||||||
|
|
||||||
// Render it.
|
// Render it.
|
||||||
mRenderer->drawTriangleStrips(&vertices[0], 4);
|
mRenderer->drawTriangleStrips(&vertices[0], 4);
|
||||||
|
|
|
@ -134,6 +134,7 @@ void NinePatchComponent::render(const glm::mat4& parentTrans)
|
||||||
if (mTexture && mVertices != nullptr) {
|
if (mTexture && mVertices != nullptr) {
|
||||||
mRenderer->setMatrix(trans);
|
mRenderer->setMatrix(trans);
|
||||||
mVertices->opacity = mOpacity;
|
mVertices->opacity = mOpacity;
|
||||||
|
mVertices->shaderFlags = Renderer::ShaderFlags::PREMULTIPLIED;
|
||||||
mTexture->bind();
|
mTexture->bind();
|
||||||
mRenderer->drawTriangleStrips(&mVertices[0], 6 * 9);
|
mRenderer->drawTriangleStrips(&mVertices[0], 6 * 9);
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,8 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mRenderer->drawTriangleStrips(&vertices[0], 4);
|
mRenderer->drawTriangleStrips(&vertices[0], 4, Renderer::BlendFactor::SRC_ALPHA,
|
||||||
|
Renderer::BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (mVisible)
|
if (mVisible)
|
||||||
|
@ -435,7 +436,7 @@ bool VideoFFmpegComponent::setupVideoFilters()
|
||||||
}
|
}
|
||||||
|
|
||||||
filterDescription.append("format=pix_fmts=")
|
filterDescription.append("format=pix_fmts=")
|
||||||
.append(std::string(av_get_pix_fmt_name(AV_PIX_FMT_RGBA)));
|
.append(std::string(av_get_pix_fmt_name(AV_PIX_FMT_BGRA)));
|
||||||
|
|
||||||
returnValue = avfilter_graph_parse_ptr(mVFilterGraph, filterDescription.c_str(),
|
returnValue = avfilter_graph_parse_ptr(mVFilterGraph, filterDescription.c_str(),
|
||||||
&mVFilterInputs, &mVFilterOutputs, nullptr);
|
&mVFilterInputs, &mVFilterOutputs, nullptr);
|
||||||
|
|
|
@ -898,19 +898,14 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
||||||
mEntries.at(renderItem.index).data.defaultItemPath != "")) {
|
mEntries.at(renderItem.index).data.defaultItemPath != "")) {
|
||||||
glm::mat4 reflectionTrans {glm::translate(
|
glm::mat4 reflectionTrans {glm::translate(
|
||||||
renderItem.trans, glm::vec3 {0.0f, comp->getSize().y * renderItem.scale, 0.0f})};
|
renderItem.trans, glm::vec3 {0.0f, comp->getSize().y * renderItem.scale, 0.0f})};
|
||||||
const unsigned int colorShift {comp->getColorShift()};
|
|
||||||
comp->setColorGradientHorizontal(false);
|
|
||||||
comp->setColorShift(0xFFFFFF00 | static_cast<int>(mReflectionsOpacity * 255.0f));
|
|
||||||
float falloff {glm::clamp(mReflectionsFalloff, 0.0f, 1.0f)};
|
float falloff {glm::clamp(mReflectionsFalloff, 0.0f, 1.0f)};
|
||||||
falloff = mReflectionsOpacity * (1.0f - falloff);
|
falloff = mReflectionsOpacity * (1.0f - falloff);
|
||||||
comp->setColorShiftEnd(0xFFFFFF00 | static_cast<int>(falloff * 255.0f));
|
comp->setOpacity(comp->getOpacity() * mReflectionsOpacity);
|
||||||
// "Extra" falloff as a value of 1.0 already fades the image completely.
|
if (mReflectionsFalloff > 0.0f)
|
||||||
if (mReflectionsFalloff > 1.0f)
|
comp->setReflectionsFalloff(comp->getSize().y / mReflectionsFalloff);
|
||||||
comp->setReflectionsFalloff(mReflectionsFalloff - 1.0f);
|
|
||||||
comp->setFlipY(true);
|
comp->setFlipY(true);
|
||||||
comp->render(reflectionTrans);
|
comp->render(reflectionTrans);
|
||||||
comp->setFlipY(false);
|
comp->setFlipY(false);
|
||||||
comp->setColorShift(colorShift);
|
|
||||||
comp->setReflectionsFalloff(0.0f);
|
comp->setReflectionsFalloff(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,7 +1141,7 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
mReflectionsOpacity = glm::clamp(elem->get<float>("reflectionsOpacity"), 0.1f, 1.0f);
|
mReflectionsOpacity = glm::clamp(elem->get<float>("reflectionsOpacity"), 0.1f, 1.0f);
|
||||||
|
|
||||||
if (elem->has("reflectionsFalloff"))
|
if (elem->has("reflectionsFalloff"))
|
||||||
mReflectionsFalloff = glm::clamp(elem->get<float>("reflectionsFalloff"), 0.0f, 5.0f);
|
mReflectionsFalloff = glm::clamp(elem->get<float>("reflectionsFalloff"), 0.0f, 10.0f);
|
||||||
|
|
||||||
if (elem->has("unfocusedItemOpacity"))
|
if (elem->has("unfocusedItemOpacity"))
|
||||||
mUnfocusedItemOpacity =
|
mUnfocusedItemOpacity =
|
||||||
|
|
|
@ -37,22 +37,15 @@ void Renderer::setIcon()
|
||||||
if (!rawData.empty()) {
|
if (!rawData.empty()) {
|
||||||
ImageIO::flipPixelsVert(rawData.data(), width, height);
|
ImageIO::flipPixelsVert(rawData.data(), width, height);
|
||||||
|
|
||||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
constexpr unsigned int bmask {0x00FF0000};
|
||||||
unsigned int rmask {0xFF000000};
|
constexpr unsigned int gmask {0x0000FF00};
|
||||||
unsigned int gmask {0x00FF0000};
|
constexpr unsigned int rmask {0x000000FF};
|
||||||
unsigned int bmask {0x0000FF00};
|
constexpr unsigned int amask {0xFF000000};
|
||||||
unsigned int amask {0x000000FF};
|
|
||||||
#else
|
|
||||||
unsigned int rmask {0x000000FF};
|
|
||||||
unsigned int gmask {0x0000FF00};
|
|
||||||
unsigned int bmask {0x00FF0000};
|
|
||||||
unsigned int amask {0xFF000000};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Try creating SDL surface from logo data.
|
// Try creating SDL surface from logo data.
|
||||||
SDL_Surface* logoSurface {SDL_CreateRGBSurfaceFrom(
|
SDL_Surface* logoSurface {SDL_CreateRGBSurfaceFrom(
|
||||||
static_cast<void*>(rawData.data()), static_cast<int>(width), static_cast<int>(height),
|
static_cast<void*>(rawData.data()), static_cast<int>(width), static_cast<int>(height),
|
||||||
32, static_cast<int>(width * 4), rmask, gmask, bmask, amask)};
|
32, static_cast<int>(width * 4), bmask, gmask, rmask, amask)};
|
||||||
|
|
||||||
if (logoSurface != nullptr) {
|
if (logoSurface != nullptr) {
|
||||||
SDL_SetWindowIcon(mSDLWindow, logoSurface);
|
SDL_SetWindowIcon(mSDLWindow, logoSurface);
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ShaderFlags {
|
enum ShaderFlags {
|
||||||
BGRA_TO_RGBA = 0x00000001,
|
PREMULTIPLIED = 0x00000001,
|
||||||
FONT_TEXTURE = 0x00000002,
|
FONT_TEXTURE = 0x00000002,
|
||||||
POST_PROCESSING = 0x00000004,
|
POST_PROCESSING = 0x00000004,
|
||||||
CLIPPING = 0x00000008
|
CLIPPING = 0x00000008
|
||||||
|
@ -201,7 +201,7 @@ public:
|
||||||
virtual void drawTriangleStrips(
|
virtual void drawTriangleStrips(
|
||||||
const Vertex* vertices,
|
const Vertex* vertices,
|
||||||
const unsigned int numVertices,
|
const unsigned int numVertices,
|
||||||
const BlendFactor srcBlendFactor = BlendFactor::SRC_ALPHA,
|
const BlendFactor srcBlendFactor = BlendFactor::ONE,
|
||||||
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) = 0;
|
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) = 0;
|
||||||
virtual void setMatrix(const glm::mat4& matrix) = 0;
|
virtual void setMatrix(const glm::mat4& matrix) = 0;
|
||||||
virtual void setScissor(const Rect& scissor) = 0;
|
virtual void setScissor(const Rect& scissor) = 0;
|
||||||
|
|
|
@ -248,13 +248,13 @@ bool RendererOpenGL::createContext()
|
||||||
GL_CHECK_ERROR(glBindVertexArray(mVertexBuffer2));
|
GL_CHECK_ERROR(glBindVertexArray(mVertexBuffer2));
|
||||||
|
|
||||||
uint8_t data[4] {255, 255, 255, 255};
|
uint8_t data[4] {255, 255, 255, 255};
|
||||||
mWhiteTexture = createTexture(TextureType::RGBA, false, false, false, true, 1, 1, data);
|
mWhiteTexture = createTexture(TextureType::BGRA, false, false, false, true, 1, 1, data);
|
||||||
|
|
||||||
mPostProcTexture1 = createTexture(TextureType::RGBA, false, false, false, false,
|
mPostProcTexture1 = createTexture(TextureType::BGRA, false, false, false, false,
|
||||||
static_cast<unsigned int>(getScreenWidth()),
|
static_cast<unsigned int>(getScreenWidth()),
|
||||||
static_cast<unsigned int>(getScreenHeight()), nullptr);
|
static_cast<unsigned int>(getScreenHeight()), nullptr);
|
||||||
|
|
||||||
mPostProcTexture2 = createTexture(TextureType::RGBA, false, false, false, false,
|
mPostProcTexture2 = createTexture(TextureType::BGRA, false, false, false, false,
|
||||||
static_cast<unsigned int>(getScreenWidth()),
|
static_cast<unsigned int>(getScreenWidth()),
|
||||||
static_cast<unsigned int>(getScreenHeight()), nullptr);
|
static_cast<unsigned int>(getScreenHeight()), nullptr);
|
||||||
|
|
||||||
|
@ -376,8 +376,13 @@ unsigned int RendererOpenGL::createTexture(const TextureType type,
|
||||||
linearMagnify ? static_cast<GLfloat>(GL_LINEAR) :
|
linearMagnify ? static_cast<GLfloat>(GL_LINEAR) :
|
||||||
static_cast<GLfloat>(GL_NEAREST)));
|
static_cast<GLfloat>(GL_NEAREST)));
|
||||||
|
|
||||||
|
#if defined(USE_OPENGLES)
|
||||||
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType,
|
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType,
|
||||||
GL_UNSIGNED_BYTE, data));
|
GL_UNSIGNED_BYTE, data));
|
||||||
|
#else
|
||||||
|
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, textureType,
|
||||||
|
GL_UNSIGNED_BYTE, data));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mipmapping)
|
if (mipmapping)
|
||||||
GL_CHECK_ERROR(glGenerateMipmap(GL_TEXTURE_2D));
|
GL_CHECK_ERROR(glGenerateMipmap(GL_TEXTURE_2D));
|
||||||
|
@ -626,7 +631,12 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
|
||||||
else
|
else
|
||||||
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mShaderFBO2));
|
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mShaderFBO2));
|
||||||
|
|
||||||
GL_CHECK_ERROR(glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, textureRGBA));
|
#if defined(USE_OPENGLES)
|
||||||
|
GL_CHECK_ERROR(
|
||||||
|
glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, textureRGBA));
|
||||||
|
#else
|
||||||
|
GL_CHECK_ERROR(glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, textureRGBA));
|
||||||
|
#endif
|
||||||
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
void drawTriangleStrips(
|
void drawTriangleStrips(
|
||||||
const Vertex* vertices,
|
const Vertex* vertices,
|
||||||
const unsigned int numVertices,
|
const unsigned int numVertices,
|
||||||
const BlendFactor srcBlendFactor = BlendFactor::SRC_ALPHA,
|
const BlendFactor srcBlendFactor = BlendFactor::ONE,
|
||||||
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) override;
|
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) override;
|
||||||
|
|
||||||
void shaderPostprocessing(
|
void shaderPostprocessing(
|
||||||
|
|
|
@ -248,8 +248,9 @@ void Font::renderTextCache(TextCache* cache)
|
||||||
it->verts[0].shaderFlags = Renderer::ShaderFlags::FONT_TEXTURE;
|
it->verts[0].shaderFlags = Renderer::ShaderFlags::FONT_TEXTURE;
|
||||||
|
|
||||||
mRenderer->bindTexture(*it->textureIdPtr);
|
mRenderer->bindTexture(*it->textureIdPtr);
|
||||||
mRenderer->drawTriangleStrips(&it->verts[0],
|
mRenderer->drawTriangleStrips(
|
||||||
static_cast<const unsigned int>(it->verts.size()));
|
&it->verts[0], static_cast<const unsigned int>(it->verts.size()),
|
||||||
|
Renderer::BlendFactor::SRC_ALPHA, Renderer::BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
|
||||||
auto svgImage = lunasvg::Document::loadFromData(fileData);
|
auto svgImage = lunasvg::Document::loadFromData(fileData);
|
||||||
|
|
||||||
if (svgImage == nullptr) {
|
if (svgImage == nullptr) {
|
||||||
LOG(LogDebug) << "TextureData::initSVGFromMemory(): Couldn't parse SVG image \"" << mPath
|
LOG(LogError) << "TextureData::initSVGFromMemory(): Couldn't parse SVG image \"" << mPath
|
||||||
<< "\"";
|
<< "\"";
|
||||||
mInvalidSVGFile = true;
|
mInvalidSVGFile = true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -107,7 +107,6 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
|
||||||
|
|
||||||
if (rasterize) {
|
if (rasterize) {
|
||||||
auto bitmap = svgImage->renderToBitmap(mWidth, mHeight);
|
auto bitmap = svgImage->renderToBitmap(mWidth, mHeight);
|
||||||
bitmap.convertToRGBA();
|
|
||||||
mDataRGBA.insert(mDataRGBA.begin(), std::move(bitmap.data()),
|
mDataRGBA.insert(mDataRGBA.begin(), std::move(bitmap.data()),
|
||||||
std::move(bitmap.data() + mWidth * mHeight * 4));
|
std::move(bitmap.data() + mWidth * mHeight * 4));
|
||||||
|
|
||||||
|
@ -221,7 +220,7 @@ bool TextureData::uploadAndBind()
|
||||||
|
|
||||||
// Upload texture.
|
// Upload texture.
|
||||||
mTextureID =
|
mTextureID =
|
||||||
mRenderer->createTexture(Renderer::TextureType::RGBA, true, mLinearMagnify, mMipmapping,
|
mRenderer->createTexture(Renderer::TextureType::BGRA, true, mLinearMagnify, mMipmapping,
|
||||||
mTile, static_cast<const unsigned int>(mWidth),
|
mTile, static_cast<const unsigned int>(mWidth),
|
||||||
static_cast<const unsigned int>(mHeight), mDataRGBA.data());
|
static_cast<const unsigned int>(mHeight), mDataRGBA.data());
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// core.glsl
|
// core.glsl
|
||||||
//
|
//
|
||||||
// Core shader functionality:
|
// Core shader functionality:
|
||||||
// clipping, opacity, saturation, dimming and BGRA to RGBA conversion.
|
// Clipping, opacity, saturation, dimming and reflections falloff.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Vertex section of code:
|
// Vertex section of code:
|
||||||
|
@ -24,7 +24,7 @@ void main(void)
|
||||||
gl_Position = MVPMatrix * vec4(positionVertex.xy, 0.0, 1.0);
|
gl_Position = MVPMatrix * vec4(positionVertex.xy, 0.0, 1.0);
|
||||||
position = positionVertex;
|
position = positionVertex;
|
||||||
texCoord = texCoordVertex;
|
texCoord = texCoordVertex;
|
||||||
color.rgba = colorVertex.abgr;
|
color.abgr = colorVertex.rgba;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fragment section of code:
|
// Fragment section of code:
|
||||||
|
@ -49,7 +49,7 @@ uniform sampler2D textureSampler;
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
// shaderFlags:
|
// shaderFlags:
|
||||||
// 0x00000001 - BGRA to RGBA conversion
|
// 0x00000001 - Premultiplied alpha (BGRA)
|
||||||
// 0x00000002 - Font texture
|
// 0x00000002 - Font texture
|
||||||
// 0x00000004 - Post processing
|
// 0x00000004 - Post processing
|
||||||
// 0x00000008 - Clipping
|
// 0x00000008 - Clipping
|
||||||
|
@ -57,7 +57,7 @@ out vec4 FragColor;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// Discard any pixels outside the clipping region.
|
// Discard any pixels outside the clipping region.
|
||||||
if (0u != (shaderFlags & 8u)) {
|
if (0x0u != (shaderFlags & 0x8u)) {
|
||||||
if (position.x < clipRegion.x)
|
if (position.x < clipRegion.x)
|
||||||
discard;
|
discard;
|
||||||
else if (position.y < clipRegion.y)
|
else if (position.y < clipRegion.y)
|
||||||
|
@ -71,19 +71,31 @@ void main()
|
||||||
vec4 sampledColor = texture(textureSampler, texCoord);
|
vec4 sampledColor = texture(textureSampler, texCoord);
|
||||||
|
|
||||||
// For fonts the alpha information is stored in the red channel.
|
// For fonts the alpha information is stored in the red channel.
|
||||||
if (0u != (shaderFlags & 2u))
|
if (0x0u != (shaderFlags & 0x2u))
|
||||||
sampledColor = vec4(1.0, 1.0, 1.0, sampledColor.r);
|
sampledColor = vec4(1.0, 1.0, 1.0, sampledColor.r);
|
||||||
|
|
||||||
sampledColor *= color;
|
// Different color calculations depending on whether the texture contains premultiplied
|
||||||
|
// alpha or straight alpha values.
|
||||||
|
if (0x0u != (shaderFlags & 0x01u)) {
|
||||||
|
sampledColor.rgb *= color.rgb;
|
||||||
|
sampledColor *= color.a;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sampledColor *= color;
|
||||||
|
}
|
||||||
|
|
||||||
// When post-processing we drop the alpha channel to avoid strange issues
|
// When post-processing we drop the alpha channel to avoid strange issues with some
|
||||||
// with some graphics drivers.
|
// graphics drivers.
|
||||||
if (0u != (shaderFlags & 4u))
|
if (0x0u != (shaderFlags & 0x4u))
|
||||||
sampledColor.a = 1.0;
|
sampledColor.a = 1.0;
|
||||||
|
|
||||||
// Opacity.
|
// Opacity.
|
||||||
if (opacity != 1.0)
|
if (opacity != 1.0) {
|
||||||
sampledColor.a = sampledColor.a * opacity;
|
if (0x0u == (shaderFlags & 0x01u))
|
||||||
|
sampledColor.a *= opacity;
|
||||||
|
else
|
||||||
|
sampledColor *= opacity;
|
||||||
|
}
|
||||||
|
|
||||||
// Saturation.
|
// Saturation.
|
||||||
if (saturation != 1.0) {
|
if (saturation != 1.0) {
|
||||||
|
@ -98,13 +110,9 @@ void main()
|
||||||
sampledColor *= dimColor;
|
sampledColor *= dimColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BGRA to RGBA conversion.
|
|
||||||
if (0u != (shaderFlags & 1u))
|
|
||||||
sampledColor = sampledColor.bgra;
|
|
||||||
|
|
||||||
// Reflections falloff.
|
// Reflections falloff.
|
||||||
if (reflectionsFalloff > 0.0)
|
if (reflectionsFalloff > 0.0)
|
||||||
sampledColor.a = mix(sampledColor.a, sampledColor.a - reflectionsFalloff, texCoord.y);
|
sampledColor.argb *= mix(0.0, 1.0, reflectionsFalloff - position.y) / reflectionsFalloff;
|
||||||
|
|
||||||
FragColor = sampledColor;
|
FragColor = sampledColor;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue