Fixed artifacts on toolbar and gizmobar icons showing up when changing screen or toolbar scale factors
This commit is contained in:
parent
bea82a4501
commit
5b2e2fe7b3
@ -68,4 +68,8 @@
|
||||
// Enable using Y axis of 3Dconnexion devices as zoom
|
||||
#define ENABLE_3DCONNEXION_Y_AS_ZOOM (1 && ENABLE_2_2_0_BETA1)
|
||||
|
||||
// Enable a modified version of the toolbar textures where all the icons are separated by 1 pixel
|
||||
#define ENABLE_MODIFIED_TOOLBAR_TEXTURES (1 && ENABLE_2_2_0_BETA1)
|
||||
|
||||
|
||||
#endif // _technologies_h_
|
||||
|
@ -168,12 +168,26 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
||||
if (filenames.empty() || states.empty() || (sprite_size_px == 0))
|
||||
return false;
|
||||
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
// every tile needs to have a 1px border around it to avoid artifacts when linear sampling on its edges
|
||||
unsigned int sprite_size_px_ex = sprite_size_px + 1;
|
||||
|
||||
m_width = 1 + (int)(sprite_size_px_ex * states.size());
|
||||
m_height = 1 + (int)(sprite_size_px_ex * filenames.size());
|
||||
#else
|
||||
m_width = (int)(sprite_size_px * states.size());
|
||||
m_height = (int)(sprite_size_px * filenames.size());
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
|
||||
int n_pixels = m_width * m_height;
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
int sprite_n_pixels = sprite_size_px_ex * sprite_size_px_ex;
|
||||
int sprite_stride = sprite_size_px_ex * 4;
|
||||
#else
|
||||
int sprite_n_pixels = sprite_size_px * sprite_size_px;
|
||||
int sprite_bytes = sprite_n_pixels * 4;
|
||||
int sprite_stride = sprite_size_px * 4;
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
int sprite_bytes = sprite_n_pixels * 4;
|
||||
|
||||
if (n_pixels <= 0)
|
||||
{
|
||||
@ -211,7 +225,12 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
||||
|
||||
float scale = (float)sprite_size_px / std::max(image->width, image->height);
|
||||
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
// offset by 1 to leave the first pixel empty (both in x and y)
|
||||
nsvgRasterize(rast, image, 1, 1, scale, sprite_data.data(), sprite_size_px, sprite_size_px, sprite_stride);
|
||||
#else
|
||||
nsvgRasterize(rast, image, 0, 0, scale, sprite_data.data(), sprite_size_px, sprite_size_px, sprite_stride);
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
|
||||
// makes white only copy of the sprite
|
||||
::memcpy((void*)sprite_white_only_data.data(), (const void*)sprite_data.data(), sprite_bytes);
|
||||
@ -231,7 +250,11 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
||||
::memset((void*)&sprite_gray_only_data.data()[offset], 128, 3);
|
||||
}
|
||||
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
int sprite_offset_px = sprite_id * (int)sprite_size_px_ex * m_width;
|
||||
#else
|
||||
int sprite_offset_px = sprite_id * sprite_size_px * m_width;
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
int state_id = -1;
|
||||
for (const std::pair<int, bool>& state : states)
|
||||
{
|
||||
@ -250,6 +273,23 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
||||
// applies background, if needed
|
||||
if (state.second)
|
||||
{
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
float inv_255 = 1.0f / 255.0f;
|
||||
// offset by 1 to leave the first pixel empty (both in x and y)
|
||||
for (int r = 1; r <= sprite_size_px; ++r)
|
||||
{
|
||||
int offset_r = r * sprite_size_px_ex;
|
||||
for (int c = 1; c <= sprite_size_px; ++c)
|
||||
{
|
||||
int offset = (offset_r + c) * 4;
|
||||
float alpha = (float)output_data.data()[offset + 3] * inv_255;
|
||||
output_data.data()[offset + 0] = (unsigned char)(output_data.data()[offset + 0] * alpha);
|
||||
output_data.data()[offset + 1] = (unsigned char)(output_data.data()[offset + 1] * alpha);
|
||||
output_data.data()[offset + 2] = (unsigned char)(output_data.data()[offset + 2] * alpha);
|
||||
output_data.data()[offset + 3] = (unsigned char)(128 * (1.0f - alpha) + output_data.data()[offset + 3] * alpha);
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (int i = 0; i < sprite_n_pixels; ++i)
|
||||
{
|
||||
int offset = i * 4;
|
||||
@ -259,13 +299,22 @@ bool GLTexture::load_from_svg_files_as_sprites_array(const std::vector<std::stri
|
||||
output_data.data()[offset + 2] = (unsigned char)(output_data.data()[offset + 2] * alpha);
|
||||
output_data.data()[offset + 3] = (unsigned char)(128 * (1.0f - alpha) + output_data.data()[offset + 3] * alpha);
|
||||
}
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
}
|
||||
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
int state_offset_px = sprite_offset_px + state_id * sprite_size_px_ex;
|
||||
for (int j = 0; j < (int)sprite_size_px_ex; ++j)
|
||||
{
|
||||
::memcpy((void*)&data.data()[(state_offset_px + j * m_width) * 4], (const void*)&output_data.data()[j * sprite_stride], sprite_stride);
|
||||
}
|
||||
#else
|
||||
int state_offset_px = sprite_offset_px + state_id * sprite_size_px;
|
||||
for (int j = 0; j < (int)sprite_size_px; ++j)
|
||||
{
|
||||
::memcpy((void*)&data.data()[(state_offset_px + j * m_width) * 4], (const void*)&output_data.data()[j * sprite_stride], sprite_stride);
|
||||
}
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
}
|
||||
|
||||
nsvgDelete(image);
|
||||
|
@ -86,7 +86,35 @@ bool GLToolbarItem::update_enabled_state()
|
||||
|
||||
void GLToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
|
||||
{
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
auto uvs = [this](unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) ->GLTexture::Quad_UVs
|
||||
{
|
||||
assert((tex_width != 0) && (tex_height != 0));
|
||||
GLTexture::Quad_UVs ret;
|
||||
// tiles in the texture are spaced by 1 pixel
|
||||
float icon_size_px = (float)(tex_width - 1) / (float)Num_States;
|
||||
float inv_tex_width = 1.0f / (float)tex_width;
|
||||
float inv_tex_height = 1.0f / (float)tex_height;
|
||||
// tiles in the texture are spaced by 1 pixel
|
||||
float u_offset = 1.0f * inv_tex_width;
|
||||
float v_offset = 1.0f * inv_tex_height;
|
||||
float du = icon_size_px * inv_tex_width;
|
||||
float dv = icon_size_px * inv_tex_height;
|
||||
float left = u_offset + (float)m_state * du;
|
||||
float right = left + du - u_offset;
|
||||
float top = v_offset + (float)m_data.sprite_id * dv;
|
||||
float bottom = top + dv - v_offset;
|
||||
ret.left_top = { left, top };
|
||||
ret.left_bottom = { left, bottom };
|
||||
ret.right_bottom = { right, bottom };
|
||||
ret.right_top = { right, top };
|
||||
return ret;
|
||||
};
|
||||
|
||||
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, uvs(tex_width, tex_height, icon_size));
|
||||
#else
|
||||
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size));
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
|
||||
if (is_pressed())
|
||||
{
|
||||
@ -97,6 +125,7 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b
|
||||
}
|
||||
}
|
||||
|
||||
#if !ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
|
||||
{
|
||||
GLTexture::Quad_UVs uvs;
|
||||
@ -110,14 +139,14 @@ GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int
|
||||
float right = left + scaled_icon_width;
|
||||
float top = (float)m_data.sprite_id * scaled_icon_height;
|
||||
float bottom = top + scaled_icon_height;
|
||||
|
||||
uvs.left_top = { left, top };
|
||||
uvs.left_bottom = { left, bottom };
|
||||
uvs.right_bottom = { right, bottom };
|
||||
uvs.right_top = { right, top };
|
||||
|
||||
|
||||
return uvs;
|
||||
}
|
||||
#endif // !ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
|
||||
BackgroundTexture::Metadata::Metadata()
|
||||
: filename("")
|
||||
|
@ -143,7 +143,9 @@ public:
|
||||
void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const;
|
||||
|
||||
private:
|
||||
#if !ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
GLTexture::Quad_UVs get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const;
|
||||
#endif // !ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
void set_visible(bool visible) { m_data.visible = visible; }
|
||||
|
||||
friend class GLToolbar;
|
||||
|
@ -838,8 +838,14 @@ void GLGizmosManager::render_background(float left, float top, float right, floa
|
||||
|
||||
void GLGizmosManager::do_render_overlay() const
|
||||
{
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
std::vector<size_t> selectable_idxs = get_selectable_idxs();
|
||||
if (selectable_idxs.empty())
|
||||
return;
|
||||
#else
|
||||
if (m_gizmos.empty())
|
||||
return;
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
|
||||
float cnv_w = (float)m_parent.get_canvas_size().get_width();
|
||||
float cnv_h = (float)m_parent.get_canvas_size().get_height();
|
||||
@ -870,13 +876,34 @@ void GLGizmosManager::do_render_overlay() const
|
||||
unsigned int icons_texture_id = m_icons_texture.get_id();
|
||||
int tex_width = m_icons_texture.get_width();
|
||||
int tex_height = m_icons_texture.get_height();
|
||||
float inv_tex_width = (tex_width != 0) ? 1.0f / tex_width : 0.0f;
|
||||
float inv_tex_height = (tex_height != 0) ? 1.0f / tex_height : 0.0f;
|
||||
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
if ((icons_texture_id == 0) || (tex_width <= 1) || (tex_height <= 1))
|
||||
return;
|
||||
|
||||
#if ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
|
||||
float du = (float)(tex_width - 1) / (4.0f * (float)tex_width); // 4 is the number of possible states if the icons
|
||||
#else
|
||||
float du = (float)(tex_width - 1) / (3.0f * (float)tex_width); // 3 is the number of possible states if the icons
|
||||
#endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
|
||||
float dv = (float)(tex_height - 1) / (float)(selectable_idxs.size() * tex_height);
|
||||
|
||||
// tiles in the texture are spaced by 1 pixel
|
||||
float u_offset = 1.0f / (float)tex_width;
|
||||
float v_offset = 1.0f / (float)tex_height;
|
||||
#else
|
||||
if ((icons_texture_id == 0) || (tex_width <= 0) || (tex_height <= 0))
|
||||
return;
|
||||
|
||||
float inv_tex_width = (tex_width != 0) ? 1.0f / tex_width : 0.0f;
|
||||
float inv_tex_height = (tex_height != 0) ? 1.0f / tex_height : 0.0f;
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
for (size_t idx : selectable_idxs)
|
||||
#else
|
||||
for (size_t idx : get_selectable_idxs())
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
{
|
||||
GLGizmoBase* gizmo = m_gizmos[idx].get();
|
||||
|
||||
@ -887,6 +914,12 @@ void GLGizmosManager::do_render_overlay() const
|
||||
int icon_idx = m_current == idx ? 2 : (m_hover == idx ? 1 : 0);
|
||||
#endif // ENABLE_GIZMO_ICONS_NON_ACTIVABLE_STATE
|
||||
|
||||
#if ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
float v_top = v_offset + sprite_id * dv;
|
||||
float u_left = u_offset + icon_idx * du;
|
||||
float v_bottom = v_top + dv - v_offset;
|
||||
float u_right = u_left + du - u_offset;
|
||||
#else
|
||||
float u_icon_size = icons_size * inv_tex_width;
|
||||
float v_icon_size = icons_size * inv_tex_height;
|
||||
|
||||
@ -894,6 +927,7 @@ void GLGizmosManager::do_render_overlay() const
|
||||
float u_left = icon_idx * u_icon_size;
|
||||
float v_bottom = v_top + v_icon_size;
|
||||
float u_right = u_left + u_icon_size;
|
||||
#endif // ENABLE_MODIFIED_TOOLBAR_TEXTURES
|
||||
|
||||
GLTexture::render_sub_texture(icons_texture_id, zoomed_top_x, zoomed_top_x + zoomed_icons_size, zoomed_top_y - zoomed_icons_size, zoomed_top_y, { { u_left, v_bottom }, { u_right, v_bottom }, { u_right, v_top }, { u_left, v_top } });
|
||||
if (idx == m_current) {
|
||||
|
Loading…
Reference in New Issue
Block a user