draw scale-aware text onto RenderTextures

This commit is contained in:
2025-02-04 21:39:05 -06:00
parent 6fa63307b1
commit 78d10987fe
7 changed files with 68 additions and 15 deletions

View File

@@ -14,6 +14,7 @@
#include "fileio/fileio.hpp"
#include "gfx/render_shapes.hpp"
#include "winutil.hpp"
sf::Shader maskShader;
extern fs::path progDir;
@@ -121,6 +122,32 @@ void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const
rect_draw_some_item(src.getTexture(), dest_rect, targ_gworld, targ_rect, &maskShader);
}
std::map<sf::RenderTexture*,std::vector<sf::Text>> store_scale_aware_text;
static void draw_stored_scale_aware_text(sf::RenderTexture& texture, sf::RenderTarget& dest_window, rectangle targ_rect) {
// Temporarily switch target window to its unscaled view to draw scale-aware text
sf::View view = dest_window.getView();
dest_window.setView(dest_window.getDefaultView());
std::vector<sf::Text> stored_text = store_scale_aware_text[&texture];
for(sf::Text str_to_draw : stored_text){
sf::Vector2f position = str_to_draw.getPosition();
position = position + sf::Vector2f {0.0f+targ_rect.left, 0.0f+targ_rect.top};
str_to_draw.setPosition(position * (float)get_ui_scale());
dest_window.draw(str_to_draw);
}
dest_window.setView(view);
}
void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode) {
rect_draw_some_item(src_render_gworld.getTexture(), src_rect, targ_gworld, targ_rect, mode);
draw_stored_scale_aware_text(src_render_gworld, targ_gworld, targ_rect);
}
void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect) {
rect_draw_some_item(src_render_gworld.getTexture(), src_rect, mask_gworld, targ_gworld, targ_rect);
draw_stored_scale_aware_text(src_render_gworld, targ_gworld, targ_rect);
}
void setActiveRenderTarget(sf::RenderTarget& where) {
const std::type_info& type = typeid(where);
if(type == typeid(sf::RenderWindow&))

View File

@@ -22,7 +22,9 @@ void init_shaders();
void rect_draw_some_item(sf::RenderTarget& targ_gworld,rectangle targ_rect);
void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode = sf::BlendNone);
void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,rectangle in_frame,sf::BlendMode mode = sf::BlendNone);
void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,sf::RenderTarget& targ_gworld,rectangle targ_rect,sf::BlendMode mode = sf::BlendNone);
void rect_draw_some_item(const sf::Texture& src_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect);
void rect_draw_some_item(sf::RenderTexture& src_render_gworld,rectangle src_rect,const sf::Texture& mask_gworld,sf::RenderTarget& targ_gworld,rectangle targ_rect);
void draw_splash(const sf::Texture& splash, sf::RenderWindow& targ, rectangle dest_rect);
void setActiveRenderTarget(sf::RenderTarget& where);

View File

@@ -135,7 +135,14 @@ break_info_t calculate_line_wrapping(rectangle dest_rect, std::string str, TextS
return break_info;
}
void draw_scale_aware(sf::RenderTarget& dest_window, sf::Text str_to_draw) {
// I don't know of a better way to do this than using pointers as keys.
extern std::map<sf::RenderTexture*,std::vector<sf::Text>> store_scale_aware_text;
void clear_scale_aware_text(sf::RenderTexture& texture) {
store_scale_aware_text.erase(&texture);
}
void draw_scale_aware_text(sf::RenderTarget& dest_window, sf::Text str_to_draw) {
str_to_draw.setCharacterSize(str_to_draw.getCharacterSize() * get_ui_scale());
if(dynamic_cast<sf::RenderWindow*>(&dest_window) != nullptr){
@@ -145,8 +152,14 @@ void draw_scale_aware(sf::RenderTarget& dest_window, sf::Text str_to_draw) {
dest_window.setView(dest_window.getDefaultView());
dest_window.draw(str_to_draw);
dest_window.setView(view);
}else if(dynamic_cast<sf::RenderTexture*>(&dest_window) != nullptr){
// TODO Onto a RenderTexture is trickier because the texture is locked at the smaller size.
}else if(sf::RenderTexture* p = dynamic_cast<sf::RenderTexture*>(&dest_window); p != nullptr){
// Onto a RenderTexture is trickier because the texture is locked at the smaller size.
// What we can do is save the sf::Text with its relative position and render
// it onto the RenderWindow that eventually draws the RenderTexture.
if(store_scale_aware_text.find(p) == store_scale_aware_text.end()){
store_scale_aware_text[p] = std::vector<sf::Text> {};
}
store_scale_aware_text[p].push_back(str_to_draw);
}
}
@@ -243,7 +256,7 @@ static void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,st
bounds.inset(0,-4);
fill_rect(dest_window, bounds, options.hilite_bg);
} else str_to_draw.setColor(options.style.colour);
draw_scale_aware(dest_window, str_to_draw);
draw_scale_aware_text(dest_window, str_to_draw);
}
}

View File

@@ -57,7 +57,8 @@ enum class eTextMode {
std::vector<rectangle> draw_string_hilite(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector<hilite_t> hilites,sf::Color hiliteClr);
std::vector<snippet_t> draw_string_sel(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,TextStyle style,std::vector<hilite_t> hilites,sf::Color hiliteClr);
void draw_scale_aware(sf::RenderTarget& dest_window,sf::Text text);
void draw_scale_aware_text(sf::RenderTarget& dest_window, sf::Text str_to_draw);
void clear_scale_aware_text(sf::RenderTexture& texture);
void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style,bool right_align = false);
void win_draw_string(sf::RenderTarget& dest_window,rectangle dest_rect,std::string str,eTextMode mode,TextStyle style, break_info_t break_info,bool right_align = false);
break_info_t calculate_line_wrapping(rectangle dest_rect, std::string str, TextStyle style);