Skip to content
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

Closed
wants to merge 3 commits into from

Conversation

Furiiis
Copy link
Contributor

@Furiiis Furiiis commented Mar 18, 2025

Fixes: #7106

@ihhub ihhub added improvement New feature, request or improvement ui UI/GUI related stuff labels Mar 19, 2025
@ihhub ihhub added this to the 1.1.7 milestone Mar 19, 2025
@ihhub ihhub requested review from ihhub and Districh-ru March 19, 2025 09:14
@@ -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 } );
Copy link
Collaborator

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:

// 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?

Copy link
Contributor Author

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

Copy link
Collaborator

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.

@Furiiis Furiiis requested a review from Districh-ru March 19, 2025 20:48
@ihhub ihhub changed the title Add shadow for MeetingDialog Add shadow for Heroes Meeting dialog Mar 21, 2025
@Furiiis Furiiis changed the title Add shadow for Heroes Meeting dialog Draft: Add shadow for Heroes Meeting dialog Mar 21, 2025
@Furiiis Furiiis marked this pull request as draft March 21, 2025 10:51
@Furiiis Furiiis closed this Mar 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
improvement New feature, request or improvement ui UI/GUI related stuff
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Adventure map, shadow is missing for hero meeting window
3 participants