-
-
Notifications
You must be signed in to change notification settings - Fork 391
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft: Add shadow for Heroes Meeting dialog #9654
Conversation
@@ -316,6 +316,11 @@ void Heroes::MeetingDialog( Heroes & otherHero ) | |||
fheroes2::Point dst_pt( cur_pt ); | |||
fheroes2::Blit( backSprite, src_rt.x, src_rt.y, display, dst_pt.x, dst_pt.y, src_rt.width, src_rt.height ); | |||
|
|||
// shadow | |||
if ( !isDefaultScreenSize ) { | |||
fheroes2::addGradientShadow( backSprite, display, { dst_pt.x, dst_pt.y }, { -15, 15 } ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Furiiis, your implementation is OK but there is one thing I've noticed.
The fheroes2::addGradientShadow()
makes a shadow that is dropped from a solid object of some height (in example, buttons):
while all dialogs in the original game are considered as flat rectangles that are floating in some height over the game image:
So to be more consistent with the other in-game dialogs we can use the logic from:
fheroes2/src/fheroes2/gui/ui_window.cpp
Lines 348 to 370 in dbd923c
// Render shadow at the left side of the window. | |
int32_t offsetY = _windowArea.y + borderSize; | |
ApplyTransform( _output, _totalArea.x, offsetY, borderSize, 1, 5 ); | |
++offsetY; | |
ApplyTransform( _output, _totalArea.x, offsetY, 1, _windowArea.height - 2, 5 ); | |
ApplyTransform( _output, _totalArea.x + 1, offsetY, borderSize - 1, 1, 4 ); | |
++offsetY; | |
ApplyTransform( _output, _totalArea.x + 1, offsetY, 1, _windowArea.height - 4, 4 ); | |
ApplyTransform( _output, _totalArea.x + 2, offsetY, borderSize - 2, 1, 3 ); | |
++offsetY; | |
ApplyTransform( _output, _totalArea.x + 2, offsetY, 1, _windowArea.height - 6, 3 ); | |
ApplyTransform( _output, _totalArea.x + 3, offsetY, borderSize - 3, _windowArea.height - borderSize - 3, 2 ); | |
// Render shadow at the bottom side of the window. | |
offsetY = _windowArea.y + _windowArea.height; | |
const int32_t shadowBottomEdge = _windowArea.y + _totalArea.height; | |
ApplyTransform( _output, _totalArea.x + 3, offsetY, _windowArea.width - 6, borderSize - 3, 2 ); | |
ApplyTransform( _output, _totalArea.x + 2, shadowBottomEdge - 3, _windowArea.width - 4, 1, 3 ); | |
ApplyTransform( _output, _totalArea.x + _windowArea.width - 3, offsetY, 1, borderSize - 3, 3 ); | |
ApplyTransform( _output, _totalArea.x + 1, shadowBottomEdge - 2, _windowArea.width - 2, 1, 4 ); | |
ApplyTransform( _output, _totalArea.x + _windowArea.width - 2, offsetY, 1, borderSize - 2, 4 ); | |
ApplyTransform( _output, _totalArea.x, shadowBottomEdge - 1, _windowArea.width, 1, 5 ); | |
ApplyTransform( _output, _totalArea.x + _windowArea.width - 1, offsetY, 1, borderSize - 1, 5 ); |
And put it to a new function in
image.cpp
(in example, we can name it addShadowForRectangularDialog()
), use this new function here and in ui_window.cpp
.
We could also make a new function more flexible to set the shadow offset like it is done for fheroes2::addGradientShadow()
. And then we could also use the new function also to update the shadow for Battle::PopupDamageInfo
and for the other such dialogs and pop-ups.
What do you think about such change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Districh-ru,
I added a new parameter slopeEffect
to fheroes2::addGradientShadow()
:
void addGradientShadow( const Sprite & in, Image & out, const Point & outPos, const Point & shadowOffset, const bool slopeEffect = true );
Now it can generate straight shadows, and we can replace this code:
// Render shadow at the left side of the window.
int32_t offsetY = _windowArea.y + borderSize;
ApplyTransform( _output, _totalArea.x, offsetY, borderSize, 1, 5 );
++offsetY;
ApplyTransform( _output, _totalArea.x, offsetY, 1, _windowArea.height - 2, 5 );
ApplyTransform( _output, _totalArea.x + 1, offsetY, borderSize - 1, 1, 4 );
++offsetY;
ApplyTransform( _output, _totalArea.x + 1, offsetY, 1, _windowArea.height - 4, 4 );
ApplyTransform( _output, _totalArea.x + 2, offsetY, borderSize - 2, 1, 3 );
++offsetY;
...
with a simple call to fheroes2::addGradientShadow()
.
I didn't tested how it generates different shadow positions (left and top, top and right, right and bottom shadow lines). Of course such positions will never be used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Furiiis, unfortunately the updated code makes a sharp shadow:
while the original game dialog shadow is soft.
The fheroes2 engine (like the original game) has 4 values for shadow strength in the transform layer: from 5 (light) to 2 (strong).
The addGradientShadow()
function increases the shadow strength in opposite direction relative to the shadowOffset
parameter and also takes into account the "thickness" of the image in this direction for clamping the maximum shadow strength.
Sadly but this function cannot be easily updated to generate soft shadows for the "flat" objects.
That's why the code in ui_window.cpp
was made.
The fast solution is to reuse it and make it a bit more flexible to generate such shadows for rectangular dialogs.
Later we can improve this solution to generate soft shadows for "flat" objects of any shape.
Fixes: #7106