You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-14 13:41:12 +00:00
Add font LCD sub-pixel anti-aliasing support.
This commit is contained in:
@@ -1183,6 +1183,38 @@ void RendererCanvasCull::canvas_item_add_msdf_texture_rect_region(RID p_item, co
|
||||
rect->px_range = p_px_range;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_add_lcd_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate) {
|
||||
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
Item::CommandRect *rect = canvas_item->alloc_command<Item::CommandRect>();
|
||||
ERR_FAIL_COND(!rect);
|
||||
rect->modulate = p_modulate;
|
||||
rect->rect = p_rect;
|
||||
|
||||
rect->texture = p_texture;
|
||||
|
||||
rect->source = p_src_rect;
|
||||
rect->flags = RendererCanvasRender::CANVAS_RECT_REGION | RendererCanvasRender::CANVAS_RECT_LCD;
|
||||
|
||||
if (p_rect.size.x < 0) {
|
||||
rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_H;
|
||||
rect->rect.size.x = -rect->rect.size.x;
|
||||
}
|
||||
if (p_src_rect.size.x < 0) {
|
||||
rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_H;
|
||||
rect->source.size.x = -rect->source.size.x;
|
||||
}
|
||||
if (p_rect.size.y < 0) {
|
||||
rect->flags |= RendererCanvasRender::CANVAS_RECT_FLIP_V;
|
||||
rect->rect.size.y = -rect->rect.size.y;
|
||||
}
|
||||
if (p_src_rect.size.y < 0) {
|
||||
rect->flags ^= RendererCanvasRender::CANVAS_RECT_FLIP_V;
|
||||
rect->source.size.y = -rect->source.size.y;
|
||||
}
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) {
|
||||
Item *canvas_item = canvas_item_owner.get_or_null(p_item);
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
@@ -225,6 +225,7 @@ public:
|
||||
void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
|
||||
void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = false);
|
||||
void canvas_item_add_msdf_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), int p_outline_size = 0, float p_px_range = 1.0);
|
||||
void canvas_item_add_lcd_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1));
|
||||
void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode = RS::NINE_PATCH_STRETCH, RS::NinePatchAxisMode p_y_axis_mode = RS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1));
|
||||
void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0);
|
||||
void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID());
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
CANVAS_RECT_CLIP_UV = 32,
|
||||
CANVAS_RECT_IS_GROUP = 64,
|
||||
CANVAS_RECT_MSDF = 128,
|
||||
CANVAS_RECT_LCD = 256,
|
||||
};
|
||||
|
||||
struct Light {
|
||||
@@ -193,7 +194,7 @@ public:
|
||||
Rect2 rect;
|
||||
Color modulate;
|
||||
Rect2 source;
|
||||
uint8_t flags;
|
||||
uint16_t flags;
|
||||
float outline;
|
||||
float px_range;
|
||||
|
||||
|
||||
@@ -494,7 +494,11 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
}
|
||||
|
||||
//bind pipeline
|
||||
{
|
||||
if (rect->flags & CANVAS_RECT_LCD) {
|
||||
RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_QUAD_LCD_BLEND].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
|
||||
RD::get_singleton()->draw_list_set_blend_constants(p_draw_list, rect->modulate);
|
||||
} else {
|
||||
RID pipeline = pipeline_variants->variants[light_mode][PIPELINE_VARIANT_QUAD].get_render_pipeline(RD::INVALID_ID, p_framebuffer_format);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, pipeline);
|
||||
}
|
||||
@@ -556,6 +560,8 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
push_constant.msdf[1] = rect->outline; // Outline size.
|
||||
push_constant.msdf[2] = 0.f; // Reserved.
|
||||
push_constant.msdf[3] = 0.f; // Reserved.
|
||||
} else if (rect->flags & CANVAS_RECT_LCD) {
|
||||
push_constant.flags |= FLAGS_USE_LCD;
|
||||
}
|
||||
|
||||
push_constant.modulation[0] = rect->modulate.r * base_color.r;
|
||||
@@ -2113,6 +2119,18 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
|
||||
RD::PipelineColorBlendState blend_state;
|
||||
blend_state.attachments.push_back(attachment);
|
||||
|
||||
RD::PipelineColorBlendState::Attachment attachment_lcd;
|
||||
attachment_lcd.enable_blend = true;
|
||||
attachment_lcd.alpha_blend_op = RD::BLEND_OP_ADD;
|
||||
attachment_lcd.color_blend_op = RD::BLEND_OP_ADD;
|
||||
attachment_lcd.src_color_blend_factor = RD::BLEND_FACTOR_CONSTANT_COLOR;
|
||||
attachment_lcd.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
|
||||
attachment_lcd.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
attachment_lcd.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
|
||||
RD::PipelineColorBlendState blend_state_lcd;
|
||||
blend_state_lcd.attachments.push_back(attachment_lcd);
|
||||
|
||||
//update pipelines
|
||||
|
||||
for (int i = 0; i < PIPELINE_LIGHT_MODE_MAX; i++) {
|
||||
@@ -2128,10 +2146,12 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
|
||||
RD::RENDER_PRIMITIVE_LINES,
|
||||
RD::RENDER_PRIMITIVE_LINESTRIPS,
|
||||
RD::RENDER_PRIMITIVE_POINTS,
|
||||
RD::RENDER_PRIMITIVE_TRIANGLES,
|
||||
};
|
||||
|
||||
ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = {
|
||||
{ //non lit
|
||||
{
|
||||
//non lit
|
||||
SHADER_VARIANT_QUAD,
|
||||
SHADER_VARIANT_NINEPATCH,
|
||||
SHADER_VARIANT_PRIMITIVE,
|
||||
@@ -2141,8 +2161,11 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS },
|
||||
{ //lit
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS,
|
||||
SHADER_VARIANT_QUAD,
|
||||
},
|
||||
{
|
||||
//lit
|
||||
SHADER_VARIANT_QUAD_LIGHT,
|
||||
SHADER_VARIANT_NINEPATCH_LIGHT,
|
||||
SHADER_VARIANT_PRIMITIVE_LIGHT,
|
||||
@@ -2152,11 +2175,17 @@ void RendererCanvasRenderRD::CanvasShaderData::set_code(const String &p_code) {
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT },
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT,
|
||||
SHADER_VARIANT_QUAD_LIGHT,
|
||||
},
|
||||
};
|
||||
|
||||
RID shader_variant = canvas_singleton->shader.canvas_shader.version_get_shader(version, shader_variants[i][j]);
|
||||
pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
|
||||
if (j == PIPELINE_VARIANT_QUAD_LCD_BLEND) {
|
||||
pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state_lcd, RD::DYNAMIC_STATE_BLEND_CONSTANTS);
|
||||
} else {
|
||||
pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2363,6 +2392,18 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
|
||||
|
||||
blend_state.attachments.push_back(blend_attachment);
|
||||
|
||||
RD::PipelineColorBlendState::Attachment attachment_lcd;
|
||||
attachment_lcd.enable_blend = true;
|
||||
attachment_lcd.alpha_blend_op = RD::BLEND_OP_ADD;
|
||||
attachment_lcd.color_blend_op = RD::BLEND_OP_ADD;
|
||||
attachment_lcd.src_color_blend_factor = RD::BLEND_FACTOR_CONSTANT_COLOR;
|
||||
attachment_lcd.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
|
||||
attachment_lcd.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
|
||||
attachment_lcd.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
|
||||
RD::PipelineColorBlendState blend_state_lcd;
|
||||
blend_state_lcd.attachments.push_back(attachment_lcd);
|
||||
|
||||
for (int i = 0; i < PIPELINE_LIGHT_MODE_MAX; i++) {
|
||||
for (int j = 0; j < PIPELINE_VARIANT_MAX; j++) {
|
||||
RD::RenderPrimitive primitive[PIPELINE_VARIANT_MAX] = {
|
||||
@@ -2376,10 +2417,12 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
|
||||
RD::RENDER_PRIMITIVE_LINES,
|
||||
RD::RENDER_PRIMITIVE_LINESTRIPS,
|
||||
RD::RENDER_PRIMITIVE_POINTS,
|
||||
RD::RENDER_PRIMITIVE_TRIANGLES,
|
||||
};
|
||||
|
||||
ShaderVariant shader_variants[PIPELINE_LIGHT_MODE_MAX][PIPELINE_VARIANT_MAX] = {
|
||||
{ //non lit
|
||||
{
|
||||
//non lit
|
||||
SHADER_VARIANT_QUAD,
|
||||
SHADER_VARIANT_NINEPATCH,
|
||||
SHADER_VARIANT_PRIMITIVE,
|
||||
@@ -2389,8 +2432,11 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS },
|
||||
{ //lit
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS,
|
||||
SHADER_VARIANT_QUAD,
|
||||
},
|
||||
{
|
||||
//lit
|
||||
SHADER_VARIANT_QUAD_LIGHT,
|
||||
SHADER_VARIANT_NINEPATCH_LIGHT,
|
||||
SHADER_VARIANT_PRIMITIVE_LIGHT,
|
||||
@@ -2400,11 +2446,17 @@ RendererCanvasRenderRD::RendererCanvasRenderRD() {
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_LIGHT,
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT },
|
||||
SHADER_VARIANT_ATTRIBUTES_POINTS_LIGHT,
|
||||
SHADER_VARIANT_QUAD_LIGHT,
|
||||
},
|
||||
};
|
||||
|
||||
RID shader_variant = shader.canvas_shader.version_get_shader(shader.default_version, shader_variants[i][j]);
|
||||
shader.pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
|
||||
if (j == PIPELINE_VARIANT_QUAD_LCD_BLEND) {
|
||||
shader.pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state_lcd, RD::DYNAMIC_STATE_BLEND_CONSTANTS);
|
||||
} else {
|
||||
shader.pipeline_variants.variants[i][j].setup(shader_variant, primitive[j], RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
|
||||
FLAGS_DEFAULT_SPECULAR_MAP_USED = (1 << 27),
|
||||
|
||||
FLAGS_USE_MSDF = (1 << 28),
|
||||
FLAGS_USE_LCD = (1 << 29),
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -122,6 +123,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
|
||||
PIPELINE_VARIANT_ATTRIBUTE_LINES,
|
||||
PIPELINE_VARIANT_ATTRIBUTE_LINES_STRIP,
|
||||
PIPELINE_VARIANT_ATTRIBUTE_POINTS,
|
||||
PIPELINE_VARIANT_QUAD_LCD_BLEND,
|
||||
PIPELINE_VARIANT_MAX
|
||||
};
|
||||
enum PipelineLightMode {
|
||||
|
||||
@@ -509,7 +509,13 @@ void main() {
|
||||
float a = clamp(d * px_size + 0.5, 0.0, 1.0);
|
||||
color.a = a * color.a;
|
||||
}
|
||||
|
||||
} else if (bool(draw_data.flags & FLAGS_USE_LCD)) {
|
||||
vec4 lcd_sample = texture(sampler2D(color_texture, texture_sampler), uv);
|
||||
if (lcd_sample.a == 1.0) {
|
||||
color.rgb = lcd_sample.rgb * color.a;
|
||||
} else {
|
||||
color = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define FLAGS_DEFAULT_SPECULAR_MAP_USED (1 << 27)
|
||||
|
||||
#define FLAGS_USE_MSDF (1 << 28)
|
||||
#define FLAGS_USE_LCD (1 << 29)
|
||||
|
||||
#define SAMPLER_NEAREST_CLAMP 0
|
||||
#define SAMPLER_LINEAR_CLAMP 1
|
||||
|
||||
@@ -429,6 +429,7 @@ void RenderingDevice::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region", "storage_textures"), &RenderingDevice::draw_list_begin, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray<RID>()));
|
||||
ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region", "storage_textures"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2()), DEFVAL(TypedArray<RID>()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("draw_list_set_blend_constants", "draw_list", "color"), &RenderingDevice::draw_list_set_blend_constants);
|
||||
ClassDB::bind_method(D_METHOD("draw_list_bind_render_pipeline", "draw_list", "render_pipeline"), &RenderingDevice::draw_list_bind_render_pipeline);
|
||||
ClassDB::bind_method(D_METHOD("draw_list_bind_uniform_set", "draw_list", "uniform_set", "set_index"), &RenderingDevice::draw_list_bind_uniform_set);
|
||||
ClassDB::bind_method(D_METHOD("draw_list_bind_vertex_array", "draw_list", "vertex_array"), &RenderingDevice::draw_list_bind_vertex_array);
|
||||
|
||||
@@ -1129,6 +1129,7 @@ public:
|
||||
virtual DrawListID draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>()) = 0;
|
||||
virtual Error draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2(), const Vector<RID> &p_storage_textures = Vector<RID>()) = 0;
|
||||
|
||||
virtual void draw_list_set_blend_constants(DrawListID p_list, const Color &p_color) = 0;
|
||||
virtual void draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline) = 0;
|
||||
virtual void draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index) = 0;
|
||||
virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) = 0;
|
||||
|
||||
@@ -831,6 +831,7 @@ public:
|
||||
FUNC6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
|
||||
FUNC7(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, bool)
|
||||
FUNC7(canvas_item_add_msdf_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, int, float)
|
||||
FUNC5(canvas_item_add_lcd_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &)
|
||||
FUNC10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
|
||||
FUNC6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
|
||||
FUNC5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
|
||||
|
||||
Reference in New Issue
Block a user