mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 15:45:38 +00:00
Added reflections support to CarouselComponent.
This commit is contained in:
parent
79c61b2d8a
commit
1798b96cf8
|
@ -207,8 +207,13 @@ public:
|
|||
mColorShift = color;
|
||||
mColorShiftEnd = color;
|
||||
}
|
||||
virtual void setColorShiftEnd(unsigned int color) { mColorShiftEnd = color; }
|
||||
virtual void setOriginalColor(unsigned int color) { mColorOriginalValue = color; }
|
||||
virtual void setChangedColor(unsigned int color) { mColorChangedValue = color; }
|
||||
virtual void setColorGradientHorizontal(bool horizontal) {}
|
||||
virtual void setReflectionsFalloff(float falloff) {}
|
||||
virtual void setFlipX(bool flip) {}
|
||||
virtual void setFlipY(bool flip) {}
|
||||
|
||||
virtual void setImage(const std::string& path, bool tile = false) {}
|
||||
|
||||
|
|
|
@ -262,6 +262,11 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
|||
{"itemRotationOrigin", NORMALIZED_PAIR},
|
||||
{"itemHorizontalAlignment", STRING},
|
||||
{"itemVerticalAlignment", STRING},
|
||||
{"horizontalOffset", FLOAT},
|
||||
{"verticalOffset", FLOAT},
|
||||
{"reflections", BOOLEAN},
|
||||
{"reflectionsOpacity", FLOAT},
|
||||
{"reflectionsFalloff", FLOAT},
|
||||
{"unfocusedItemOpacity", FLOAT},
|
||||
{"maxItemCount", FLOAT},
|
||||
{"defaultLogo", PATH}, // For backward compatibility with legacy themes.
|
||||
|
|
|
@ -40,6 +40,7 @@ ImageComponent::ImageComponent(bool forceLoad, bool dynamic)
|
|||
, mColorShiftEnd {0xFFFFFFFF}
|
||||
, mColorGradientHorizontal {true}
|
||||
, mFadeOpacity {0.0f}
|
||||
, mReflectionsFalloff {0.0f}
|
||||
, mFading {false}
|
||||
, mForceLoad {forceLoad}
|
||||
, mDynamic {dynamic}
|
||||
|
@ -248,7 +249,7 @@ void ImageComponent::cropTransparentPadding(const float maxSizeX, const float ma
|
|||
glm::ivec2 imageSize {mTexture.get()->getSize()};
|
||||
cimg_library::CImg<unsigned char> imageCImg(imageSize.x, imageSize.y, 1, 4, 0);
|
||||
|
||||
int paddingCoords[4] {};
|
||||
int paddingCoords[4] {0, 0, 0, 0};
|
||||
|
||||
// We need to convert our RGBA data to the CImg internal format as CImg does not interleave
|
||||
// the pixels (as in RGBARGBARGBA).
|
||||
|
@ -377,7 +378,7 @@ void ImageComponent::updateVertices()
|
|||
|
||||
void ImageComponent::updateColors()
|
||||
{
|
||||
const float opacity = (mOpacity * (mFading ? mFadeOpacity : 1.0f));
|
||||
const float opacity {mOpacity * (mFading ? mFadeOpacity : 1.0f)};
|
||||
const unsigned int color {(mColorShift & 0xFFFFFF00) |
|
||||
static_cast<unsigned char>((mColorShift & 0xFF) * opacity)};
|
||||
const unsigned int colorEnd {(mColorShiftEnd & 0xFFFFFF00) |
|
||||
|
@ -421,6 +422,7 @@ void ImageComponent::render(const glm::mat4& parentTrans)
|
|||
mVertices->saturation = mSaturation * mThemeSaturation;
|
||||
mVertices->opacity = mThemeOpacity;
|
||||
mVertices->dimming = mDimming;
|
||||
mVertices->reflectionsFalloff = mReflectionsFalloff;
|
||||
|
||||
mRenderer->drawTriangleStrips(&mVertices[0], 4);
|
||||
}
|
||||
|
|
|
@ -66,8 +66,8 @@ public:
|
|||
|
||||
// Multiply all pixels in the image by this color when rendering.
|
||||
void setColorShift(unsigned int color) override;
|
||||
void setColorShiftEnd(unsigned int color);
|
||||
void setColorGradientHorizontal(bool horizontal);
|
||||
void setColorShiftEnd(unsigned int color) override;
|
||||
void setColorGradientHorizontal(bool horizontal) override;
|
||||
|
||||
unsigned int getColorShift() const override { return mColorShift; }
|
||||
|
||||
|
@ -75,8 +75,9 @@ public:
|
|||
void setSaturation(float saturation) override;
|
||||
void setDimming(float dimming) override;
|
||||
|
||||
void setFlipX(bool flip); // Mirror on the X axis.
|
||||
void setFlipY(bool flip); // Mirror on the Y axis.
|
||||
void setReflectionsFalloff(float falloff) override { mReflectionsFalloff = falloff; }
|
||||
void setFlipX(bool flip) override; // Mirror on the X axis.
|
||||
void setFlipY(bool flip) override; // Mirror on the Y axis.
|
||||
|
||||
// Flag indicating if rotation should be based on target size vs. actual size.
|
||||
void setRotateByTargetSize(bool rotate) { mRotateByTargetSize = rotate; }
|
||||
|
@ -129,6 +130,7 @@ private:
|
|||
|
||||
std::shared_ptr<TextureResource> mTexture;
|
||||
float mFadeOpacity;
|
||||
float mReflectionsFalloff;
|
||||
bool mFading;
|
||||
bool mForceLoad;
|
||||
bool mDynamic;
|
||||
|
|
|
@ -117,6 +117,7 @@ private:
|
|||
CarouselType mType;
|
||||
std::string mItemType;
|
||||
std::string mDefaultItem;
|
||||
bool mLegacyMode;
|
||||
std::shared_ptr<Font> mFont;
|
||||
unsigned int mTextColor;
|
||||
unsigned int mTextBackgroundColor;
|
||||
|
@ -133,6 +134,11 @@ private:
|
|||
unsigned int mCarouselColor;
|
||||
unsigned int mCarouselColorEnd;
|
||||
bool mColorGradientHorizontal;
|
||||
bool mReflections;
|
||||
float mReflectionsOpacity;
|
||||
float mReflectionsFalloff;
|
||||
float mHorizontalOffset;
|
||||
float mVerticalOffset;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
|
@ -146,6 +152,7 @@ CarouselComponent<T>::CarouselComponent()
|
|||
, mPreviousScrollVelocity {0}
|
||||
, mTriggerJump {false}
|
||||
, mType {CarouselType::HORIZONTAL}
|
||||
, mLegacyMode {false}
|
||||
, mFont {Font::get(FONT_SIZE_LARGE)}
|
||||
, mTextColor {0x000000FF}
|
||||
, mTextBackgroundColor {0xFFFFFF00}
|
||||
|
@ -161,6 +168,11 @@ CarouselComponent<T>::CarouselComponent()
|
|||
, mCarouselColor {0}
|
||||
, mCarouselColorEnd {0}
|
||||
, mColorGradientHorizontal {true}
|
||||
, mReflections {false}
|
||||
, mReflectionsOpacity {0.5f}
|
||||
, mReflectionsFalloff {1.0f}
|
||||
, mHorizontalOffset {0.0f}
|
||||
, mVerticalOffset {0.0f}
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -183,7 +195,7 @@ void CarouselComponent<T>::addEntry(Entry& entry, const std::shared_ptr<ThemeDat
|
|||
(!defaultPath.empty() && ResourceManager::getInstance().fileExists(defaultPath))) {
|
||||
auto item = std::make_shared<ImageComponent>(false, false);
|
||||
item->setLinearInterpolation(true);
|
||||
item->setMaxSize(glm::round(mItemSize * mItemScale));
|
||||
item->setMaxSize(mItemSize * mItemScale);
|
||||
item->applyTheme(theme, "system", "image_logo",
|
||||
ThemeFlags::PATH | ThemeFlags::COLOR);
|
||||
item->setRotateByTargetSize(true);
|
||||
|
@ -197,7 +209,7 @@ void CarouselComponent<T>::addEntry(Entry& entry, const std::shared_ptr<ThemeDat
|
|||
auto item = std::make_shared<ImageComponent>(false, false);
|
||||
item->setLinearInterpolation(true);
|
||||
item->setImage(entry.data.itemPath);
|
||||
item->setMaxSize(glm::round(mItemSize * mItemScale));
|
||||
item->setMaxSize(mItemSize * mItemScale);
|
||||
item->applyTheme(theme, "system", "", ThemeFlags::ALL);
|
||||
item->setRotateByTargetSize(true);
|
||||
entry.data.item = item;
|
||||
|
@ -207,7 +219,7 @@ void CarouselComponent<T>::addEntry(Entry& entry, const std::shared_ptr<ThemeDat
|
|||
auto defaultItem = std::make_shared<ImageComponent>(false, false);
|
||||
defaultItem->setLinearInterpolation(true);
|
||||
defaultItem->setImage(entry.data.defaultItemPath);
|
||||
defaultItem->setMaxSize(glm::round(mItemSize * mItemScale));
|
||||
defaultItem->setMaxSize(mItemSize * mItemScale);
|
||||
defaultItem->applyTheme(theme, "system", "", ThemeFlags::ALL);
|
||||
defaultItem->setRotateByTargetSize(true);
|
||||
entry.data.item = defaultItem;
|
||||
|
@ -403,37 +415,60 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
|||
float xOff {0.0f};
|
||||
float yOff {0.0f};
|
||||
|
||||
switch (mType) {
|
||||
case CarouselType::HORIZONTAL_WHEEL:
|
||||
case CarouselType::VERTICAL_WHEEL:
|
||||
xOff = std::round((mSize.x - mItemSize.x) / 2.0f - (mEntryCamOffset * itemSpacing.y));
|
||||
yOff = (mSize.y - mItemSize.y) / 2.0f;
|
||||
break;
|
||||
case CarouselType::VERTICAL:
|
||||
itemSpacing.y =
|
||||
((mSize.y - (mItemSize.y * mMaxItemCount)) / (mMaxItemCount)) + mItemSize.y;
|
||||
yOff = (mSize.y - mItemSize.y) / 2.0f - (mEntryCamOffset * itemSpacing.y);
|
||||
if (mItemHorizontalAlignment == ALIGN_LEFT)
|
||||
if (mType == CarouselType::HORIZONTAL_WHEEL || mType == CarouselType::VERTICAL_WHEEL) {
|
||||
xOff = (mSize.x - mItemSize.x) / 2.0f - (mEntryCamOffset * itemSpacing.y);
|
||||
yOff = (mSize.y - mItemSize.y) / 2.0f;
|
||||
}
|
||||
else if (mType == CarouselType::VERTICAL) {
|
||||
itemSpacing.y = ((mSize.y - (mItemSize.y * mMaxItemCount)) / (mMaxItemCount)) + mItemSize.y;
|
||||
yOff = (mSize.y - mItemSize.y) / 2.0f - (mEntryCamOffset * itemSpacing.y);
|
||||
if (mItemHorizontalAlignment == ALIGN_LEFT) {
|
||||
if (mLegacyMode)
|
||||
xOff = mItemSize.x / 10.0f;
|
||||
else if (mItemHorizontalAlignment == ALIGN_RIGHT)
|
||||
xOff = mSize.x - (mItemSize.x * 1.1f);
|
||||
else
|
||||
xOff = (mSize.x - mItemSize.x) / 2.0f;
|
||||
break;
|
||||
case CarouselType::HORIZONTAL:
|
||||
default:
|
||||
itemSpacing.x =
|
||||
((mSize.x - (mItemSize.x * mMaxItemCount)) / (mMaxItemCount)) + mItemSize.x;
|
||||
xOff = std::round((mSize.x - mItemSize.x) / 2.0f - (mEntryCamOffset * itemSpacing.x));
|
||||
if (mItemVerticalAlignment == ALIGN_TOP)
|
||||
xOff = 0.0f;
|
||||
}
|
||||
else if (mItemHorizontalAlignment == ALIGN_RIGHT) {
|
||||
if (mLegacyMode)
|
||||
xOff = mSize.x - mItemSize.x * 1.1f;
|
||||
else
|
||||
xOff = mSize.x - mItemSize.x;
|
||||
}
|
||||
else {
|
||||
xOff = (mSize.x - mItemSize.x) / 2.0f;
|
||||
}
|
||||
}
|
||||
else { // HORIZONTAL.
|
||||
itemSpacing.x = ((mSize.x - (mItemSize.x * mMaxItemCount)) / (mMaxItemCount)) + mItemSize.x;
|
||||
xOff = (mSize.x - mItemSize.x) / 2.0f - (mEntryCamOffset * itemSpacing.x);
|
||||
if (mItemVerticalAlignment == ALIGN_TOP) {
|
||||
if (mLegacyMode)
|
||||
yOff = mItemSize.y / 10.0f;
|
||||
else if (mItemVerticalAlignment == ALIGN_BOTTOM)
|
||||
else
|
||||
yOff = 0.0f;
|
||||
}
|
||||
else if (mItemVerticalAlignment == ALIGN_BOTTOM) {
|
||||
if (mLegacyMode)
|
||||
yOff = mSize.y - (mItemSize.y * 1.1f);
|
||||
else
|
||||
yOff = mSize.y - mItemSize.y - (mReflections ? ((mItemSize.y * mItemScale)) : 0.0f);
|
||||
}
|
||||
else {
|
||||
if (mLegacyMode)
|
||||
yOff = (mSize.y - mItemSize.y) / 2.0f;
|
||||
break;
|
||||
else
|
||||
yOff = (mSize.y - (mItemSize.y * (mReflections ? 2.0f : 1.0f))) / 2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mLegacyMode) {
|
||||
xOff += mSize.x * mHorizontalOffset;
|
||||
yOff += mSize.y * mVerticalOffset;
|
||||
}
|
||||
|
||||
xOff = std::round(xOff);
|
||||
yOff = std::round(yOff);
|
||||
|
||||
int center {static_cast<int>(mEntryCamOffset)};
|
||||
int itemInclusion {static_cast<int>(std::ceil(mMaxItemCount / 2.0f))};
|
||||
bool singleEntry {mEntries.size() == 1};
|
||||
|
@ -441,28 +476,27 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
|||
for (int i = center - itemInclusion; i < center + itemInclusion + 2; ++i) {
|
||||
int index {i};
|
||||
|
||||
// If there is only a single entry, then only render the item once (in the center).
|
||||
if (singleEntry) {
|
||||
mEntries.at(0).data.item->render(
|
||||
glm::translate(carouselTrans, glm::vec3 {0 + xOff, 0 + yOff, 0.0f}));
|
||||
break;
|
||||
}
|
||||
|
||||
while (index < 0)
|
||||
index += static_cast<int>(mEntries.size());
|
||||
while (index >= static_cast<int>(mEntries.size()))
|
||||
index -= static_cast<int>(mEntries.size());
|
||||
|
||||
glm::mat4 itemTrans {carouselTrans};
|
||||
itemTrans = glm::translate(
|
||||
itemTrans, glm::vec3 {i * itemSpacing.x + xOff, i * itemSpacing.y + yOff, 0.0f});
|
||||
|
||||
float distance {i - mEntryCamOffset};
|
||||
|
||||
if (singleEntry)
|
||||
distance = 0.0f;
|
||||
|
||||
float scale {1.0f + ((mItemScale - 1.0f) * (1.0f - fabsf(distance)))};
|
||||
scale = std::min(mItemScale, std::max(1.0f, scale));
|
||||
scale /= mItemScale;
|
||||
|
||||
glm::mat4 itemTrans {carouselTrans};
|
||||
if (singleEntry)
|
||||
itemTrans = glm::translate(carouselTrans, glm::vec3 {xOff, yOff, 0.0f});
|
||||
else
|
||||
itemTrans = glm::translate(
|
||||
itemTrans, glm::vec3 {i * itemSpacing.x + xOff, i * itemSpacing.y + yOff, 0.0f});
|
||||
|
||||
float opacity {0.0f};
|
||||
|
||||
if (distance == 0.0f || mUnfocusedItemOpacity == 1.0f) {
|
||||
|
@ -486,17 +520,33 @@ template <typename T> void CarouselComponent<T>::render(const glm::mat4& parentT
|
|||
comp->setRotationOrigin(mItemRotationOrigin);
|
||||
}
|
||||
|
||||
// When running at lower resolutions, prevent the scale-down to go all the way to
|
||||
// the minimum value. This avoids potential single-pixel alignment issues when the
|
||||
// item can't be vertically placed exactly in the middle of the carousel. Although
|
||||
// the problem theoretically exists at all resolutions, it's not visble at around
|
||||
// 1080p and above.
|
||||
if (std::min(Renderer::getScreenWidth(), Renderer::getScreenHeight()) < 1080.0f)
|
||||
scale = glm::clamp(scale, 1.0f / mItemScale + 0.01f, 1.0f);
|
||||
|
||||
comp->setScale(scale);
|
||||
comp->setOpacity(opacity);
|
||||
comp->render(itemTrans);
|
||||
|
||||
// Don't attempt to add reflections for text entries.
|
||||
if (mReflections && (mEntries.at(index).data.itemPath != "" ||
|
||||
mEntries.at(index).data.defaultItemPath != "")) {
|
||||
itemTrans =
|
||||
glm::translate(itemTrans, glm::vec3 {0.0f, comp->getSize().y * 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)};
|
||||
falloff = mReflectionsOpacity * (1.0f - falloff);
|
||||
comp->setColorShiftEnd(0xFFFFFF00 | static_cast<int>(falloff * 255.0f));
|
||||
// "Extra" falloff as a value of 1.0 already fades the image completely.
|
||||
if (mReflectionsFalloff > 1.0f)
|
||||
comp->setReflectionsFalloff(mReflectionsFalloff - 1.0f);
|
||||
comp->setFlipY(true);
|
||||
comp->render(itemTrans);
|
||||
comp->setFlipY(false);
|
||||
comp->setColorShift(colorShift);
|
||||
comp->setReflectionsFalloff(0.0f);
|
||||
}
|
||||
|
||||
if (singleEntry)
|
||||
break;
|
||||
}
|
||||
mRenderer->popClipRect();
|
||||
}
|
||||
|
@ -522,6 +572,8 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
if (!elem)
|
||||
return;
|
||||
|
||||
mLegacyMode = theme->isLegacyTheme();
|
||||
|
||||
if (elem->has("type")) {
|
||||
const std::string type {elem->get<std::string>("type")};
|
||||
if (type == "horizontal") {
|
||||
|
@ -567,7 +619,7 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
}
|
||||
}
|
||||
|
||||
if (!theme->isLegacyTheme()) {
|
||||
if (!mLegacyMode) {
|
||||
if (elem->has("itemScale"))
|
||||
mItemScale = glm::clamp(elem->get<float>("itemScale"), 0.5f, 3.0f);
|
||||
if (elem->has("itemSize")) {
|
||||
|
@ -633,76 +685,99 @@ void CarouselComponent<T>::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
|||
}
|
||||
}
|
||||
|
||||
if (elem->has("horizontalOffset"))
|
||||
mHorizontalOffset = glm::clamp(elem->get<float>("horizontalOffset"), -1.0f, 1.0f);
|
||||
|
||||
if (elem->has("verticalOffset"))
|
||||
mVerticalOffset = glm::clamp(elem->get<float>("verticalOffset"), -1.0f, 1.0f);
|
||||
|
||||
if (elem->has("reflections") && elem->get<bool>("reflections")) {
|
||||
if (mType == CarouselType::HORIZONTAL) {
|
||||
mReflections = elem->get<bool>("reflections");
|
||||
}
|
||||
else {
|
||||
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
|
||||
"<reflections> only supported for horizontal carousel type";
|
||||
}
|
||||
}
|
||||
|
||||
if (elem->has("reflectionsOpacity"))
|
||||
mReflectionsOpacity = glm::clamp(elem->get<float>("reflectionsOpacity"), 0.1f, 1.0f);
|
||||
|
||||
if (elem->has("reflectionsFalloff"))
|
||||
mReflectionsFalloff = glm::clamp(elem->get<float>("reflectionsFalloff"), 0.0f, 5.0f);
|
||||
|
||||
if (elem->has("unfocusedItemOpacity"))
|
||||
mUnfocusedItemOpacity =
|
||||
glm::clamp(elem->get<float>("unfocusedItemOpacity"), 0.1f, 1.0f);
|
||||
}
|
||||
|
||||
// Start of legacy themes only section.
|
||||
// Legacy themes.
|
||||
if (mLegacyMode) {
|
||||
if (elem->has("logoScale"))
|
||||
mItemScale = glm::clamp(elem->get<float>("logoScale"), 0.5f, 3.0f);
|
||||
if (elem->has("logoSize")) {
|
||||
// Keep size within a 0.05 and 1.0 multiple of the screen size.
|
||||
glm::vec2 itemSize {elem->get<glm::vec2>("logoSize")};
|
||||
if (std::max(itemSize.x, itemSize.y) > 1.0f) {
|
||||
itemSize /= std::max(itemSize.x, itemSize.y);
|
||||
}
|
||||
else if (std::min(itemSize.x, itemSize.y) < 0.005f) {
|
||||
float ratio {std::min(itemSize.x, itemSize.y) / 0.005f};
|
||||
itemSize /= ratio;
|
||||
// Just an extra precaution if a crazy ratio was used.
|
||||
itemSize.x = glm::clamp(itemSize.x, 0.005f, 1.0f);
|
||||
itemSize.y = glm::clamp(itemSize.y, 0.005f, 1.0f);
|
||||
}
|
||||
mItemSize =
|
||||
itemSize * glm::vec2(Renderer::getScreenWidth(), Renderer::getScreenHeight());
|
||||
}
|
||||
|
||||
if (elem->has("logoScale"))
|
||||
mItemScale = glm::clamp(elem->get<float>("logoScale"), 0.5f, 3.0f);
|
||||
if (elem->has("logoSize")) {
|
||||
// Keep size within a 0.05 and 1.0 multiple of the screen size.
|
||||
glm::vec2 itemSize {elem->get<glm::vec2>("logoSize")};
|
||||
if (std::max(itemSize.x, itemSize.y) > 1.0f) {
|
||||
itemSize /= std::max(itemSize.x, itemSize.y);
|
||||
if (elem->has("maxLogoCount")) {
|
||||
if (theme->isLegacyTheme())
|
||||
mMaxItemCount =
|
||||
std::ceil(glm::clamp(elem->get<float>("maxLogoCount"), 0.5f, 30.0f));
|
||||
else
|
||||
mMaxItemCount = glm::clamp(elem->get<float>("maxLogoCount"), 0.5f, 30.0f);
|
||||
}
|
||||
else if (std::min(itemSize.x, itemSize.y) < 0.005f) {
|
||||
float ratio {std::min(itemSize.x, itemSize.y) / 0.005f};
|
||||
itemSize /= ratio;
|
||||
// Just an extra precaution if a crazy ratio was used.
|
||||
itemSize.x = glm::clamp(itemSize.x, 0.005f, 1.0f);
|
||||
itemSize.y = glm::clamp(itemSize.y, 0.005f, 1.0f);
|
||||
}
|
||||
mItemSize = itemSize * glm::vec2(Renderer::getScreenWidth(), Renderer::getScreenHeight());
|
||||
}
|
||||
|
||||
if (elem->has("maxLogoCount")) {
|
||||
if (theme->isLegacyTheme())
|
||||
mMaxItemCount = std::ceil(glm::clamp(elem->get<float>("maxLogoCount"), 0.5f, 30.0f));
|
||||
else
|
||||
mMaxItemCount = glm::clamp(elem->get<float>("maxLogoCount"), 0.5f, 30.0f);
|
||||
}
|
||||
if (elem->has("logoRotation"))
|
||||
mItemRotation = elem->get<float>("logoRotation");
|
||||
if (elem->has("logoRotationOrigin"))
|
||||
mItemRotationOrigin = elem->get<glm::vec2>("logoRotationOrigin");
|
||||
|
||||
if (elem->has("logoRotation"))
|
||||
mItemRotation = elem->get<float>("logoRotation");
|
||||
if (elem->has("logoRotationOrigin"))
|
||||
mItemRotationOrigin = elem->get<glm::vec2>("logoRotationOrigin");
|
||||
|
||||
if (elem->has("logoAlignment")) {
|
||||
const std::string alignment {elem->get<std::string>("logoAlignment")};
|
||||
if (alignment == "left" && mType != CarouselType::HORIZONTAL) {
|
||||
mItemHorizontalAlignment = ALIGN_LEFT;
|
||||
mItemVerticalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else if (alignment == "right" && mType != CarouselType::HORIZONTAL) {
|
||||
mItemHorizontalAlignment = ALIGN_RIGHT;
|
||||
mItemVerticalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else if (alignment == "top" && mType != CarouselType::VERTICAL) {
|
||||
mItemVerticalAlignment = ALIGN_TOP;
|
||||
mItemHorizontalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else if (alignment == "bottom" && mType != CarouselType::VERTICAL) {
|
||||
mItemVerticalAlignment = ALIGN_BOTTOM;
|
||||
mItemHorizontalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else if (alignment == "center") {
|
||||
mItemHorizontalAlignment = ALIGN_CENTER;
|
||||
mItemVerticalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else {
|
||||
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
|
||||
"<logoAlignment> defined as \""
|
||||
<< alignment << "\"";
|
||||
mItemHorizontalAlignment = ALIGN_CENTER;
|
||||
mItemVerticalAlignment = ALIGN_CENTER;
|
||||
if (elem->has("logoAlignment")) {
|
||||
const std::string alignment {elem->get<std::string>("logoAlignment")};
|
||||
if (alignment == "left" && mType != CarouselType::HORIZONTAL) {
|
||||
mItemHorizontalAlignment = ALIGN_LEFT;
|
||||
mItemVerticalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else if (alignment == "right" && mType != CarouselType::HORIZONTAL) {
|
||||
mItemHorizontalAlignment = ALIGN_RIGHT;
|
||||
mItemVerticalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else if (alignment == "top" && mType != CarouselType::VERTICAL) {
|
||||
mItemVerticalAlignment = ALIGN_TOP;
|
||||
mItemHorizontalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else if (alignment == "bottom" && mType != CarouselType::VERTICAL) {
|
||||
mItemVerticalAlignment = ALIGN_BOTTOM;
|
||||
mItemHorizontalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else if (alignment == "center") {
|
||||
mItemHorizontalAlignment = ALIGN_CENTER;
|
||||
mItemVerticalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
else {
|
||||
LOG(LogWarning) << "CarouselComponent: Invalid theme configuration, property "
|
||||
"<logoAlignment> defined as \""
|
||||
<< alignment << "\"";
|
||||
mItemHorizontalAlignment = ALIGN_CENTER;
|
||||
mItemVerticalAlignment = ALIGN_CENTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End of legacy theme section.
|
||||
|
||||
mFont = Font::getFromTheme(elem, properties, mFont);
|
||||
|
||||
if (elem->has("textColor"))
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
float opacity;
|
||||
float saturation;
|
||||
float dimming;
|
||||
float reflectionsFalloff;
|
||||
unsigned int shaders;
|
||||
unsigned int shaderFlags;
|
||||
|
||||
|
@ -69,6 +70,7 @@ public:
|
|||
: opacity {1.0f}
|
||||
, saturation {1.0f}
|
||||
, dimming {1.0f}
|
||||
, reflectionsFalloff {0.0f}
|
||||
, shaders {0}
|
||||
, shaderFlags {0}
|
||||
{
|
||||
|
@ -81,6 +83,7 @@ public:
|
|||
, opacity {1.0f}
|
||||
, saturation {1.0f}
|
||||
, dimming {1.0f}
|
||||
, reflectionsFalloff {0.0f}
|
||||
, shaders {0}
|
||||
, shaderFlags {0}
|
||||
{
|
||||
|
|
|
@ -277,8 +277,8 @@ void RendererOpenGL::destroyContext()
|
|||
|
||||
void RendererOpenGL::setMatrix(const glm::mat4& matrix)
|
||||
{
|
||||
mTrans = matrix;
|
||||
mTrans = getProjectionMatrix() * mTrans;
|
||||
// Set matrix for use with shader.
|
||||
mTrans = getProjectionMatrix() * matrix;
|
||||
}
|
||||
|
||||
void RendererOpenGL::setScissor(const Rect& scissor)
|
||||
|
@ -421,6 +421,7 @@ void RendererOpenGL::drawTriangleStrips(const Vertex* vertices,
|
|||
mCoreShader->setOpacity(vertices->opacity);
|
||||
mCoreShader->setSaturation(vertices->saturation);
|
||||
mCoreShader->setDimming(vertices->dimming);
|
||||
mCoreShader->setReflectionsFalloff(vertices->reflectionsFalloff);
|
||||
mCoreShader->setFlags(vertices->shaderFlags);
|
||||
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices));
|
||||
mLastShader = mCoreShader;
|
||||
|
|
|
@ -22,6 +22,7 @@ ShaderOpenGL::ShaderOpenGL()
|
|||
, mShaderOpacity {0}
|
||||
, mShaderSaturation {0}
|
||||
, mShaderDimming {0}
|
||||
, mShaderReflectionsFalloff {0}
|
||||
, mShaderFlags {0}
|
||||
{
|
||||
}
|
||||
|
@ -123,6 +124,7 @@ void ShaderOpenGL::getVariableLocations(GLuint programID)
|
|||
mShaderOpacity = glGetUniformLocation(mProgramID, "opacity");
|
||||
mShaderSaturation = glGetUniformLocation(mProgramID, "saturation");
|
||||
mShaderDimming = glGetUniformLocation(mProgramID, "dimming");
|
||||
mShaderReflectionsFalloff = glGetUniformLocation(mProgramID, "reflectionsFalloff");
|
||||
mShaderFlags = glGetUniformLocation(mProgramID, "shaderFlags");
|
||||
}
|
||||
|
||||
|
@ -174,6 +176,12 @@ void ShaderOpenGL::setDimming(GLfloat dimming)
|
|||
GL_CHECK_ERROR(glUniform1f(mShaderDimming, dimming));
|
||||
}
|
||||
|
||||
void ShaderOpenGL::setReflectionsFalloff(GLfloat falloff)
|
||||
{
|
||||
if (mShaderReflectionsFalloff != -1)
|
||||
GL_CHECK_ERROR(glUniform1f(mShaderReflectionsFalloff, falloff));
|
||||
}
|
||||
|
||||
void ShaderOpenGL::setFlags(GLuint flags)
|
||||
{
|
||||
if (mShaderFlags != -1)
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
void setOpacity(GLfloat opacity);
|
||||
void setSaturation(GLfloat saturation);
|
||||
void setDimming(GLfloat dimming);
|
||||
void setReflectionsFalloff(GLfloat falloff);
|
||||
void setFlags(GLuint flags);
|
||||
// Sets the shader program to use the loaded shaders.
|
||||
void activateShaders();
|
||||
|
@ -95,6 +96,7 @@ private:
|
|||
GLint mShaderOpacity;
|
||||
GLint mShaderSaturation;
|
||||
GLint mShaderDimming;
|
||||
GLint mShaderReflectionsFalloff;
|
||||
GLint mShaderFlags;
|
||||
};
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ in vec2 texCoord;
|
|||
uniform float opacity;
|
||||
uniform float saturation;
|
||||
uniform float dimming;
|
||||
uniform float reflectionsFalloff;
|
||||
uniform uint shaderFlags;
|
||||
|
||||
uniform sampler2D textureSampler;
|
||||
|
@ -83,6 +84,10 @@ void main()
|
|||
if (0u != (shaderFlags & 1u))
|
||||
sampledColor = sampledColor.bgra;
|
||||
|
||||
// Reflections falloff.
|
||||
if (reflectionsFalloff > 0.0)
|
||||
sampledColor.a = mix(sampledColor.a, sampledColor.a - reflectionsFalloff, texCoord.y);
|
||||
|
||||
FragColor = sampledColor;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue