Merge pull request #83489 from groud/implement_tile_map_normals
Allow normal maps on TileMaps that use texture padding
This commit is contained in:
commit
65e7ddadd7
|
@ -1496,6 +1496,9 @@ CanvasItem::~CanvasItem() {
|
|||
|
||||
void CanvasTexture::set_diffuse_texture(const Ref<Texture2D> &p_diffuse) {
|
||||
ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_diffuse.ptr()) != nullptr, "Can't self-assign a CanvasTexture");
|
||||
if (diffuse_texture == p_diffuse) {
|
||||
return;
|
||||
}
|
||||
diffuse_texture = p_diffuse;
|
||||
|
||||
RID tex_rid = diffuse_texture.is_valid() ? diffuse_texture->get_rid() : RID();
|
||||
|
@ -1508,9 +1511,13 @@ Ref<Texture2D> CanvasTexture::get_diffuse_texture() const {
|
|||
|
||||
void CanvasTexture::set_normal_texture(const Ref<Texture2D> &p_normal) {
|
||||
ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_normal.ptr()) != nullptr, "Can't self-assign a CanvasTexture");
|
||||
if (normal_texture == p_normal) {
|
||||
return;
|
||||
}
|
||||
normal_texture = p_normal;
|
||||
RID tex_rid = normal_texture.is_valid() ? normal_texture->get_rid() : RID();
|
||||
RS::get_singleton()->canvas_texture_set_channel(canvas_texture, RS::CANVAS_TEXTURE_CHANNEL_NORMAL, tex_rid);
|
||||
emit_changed();
|
||||
}
|
||||
Ref<Texture2D> CanvasTexture::get_normal_texture() const {
|
||||
return normal_texture;
|
||||
|
@ -1518,9 +1525,13 @@ Ref<Texture2D> CanvasTexture::get_normal_texture() const {
|
|||
|
||||
void CanvasTexture::set_specular_texture(const Ref<Texture2D> &p_specular) {
|
||||
ERR_FAIL_COND_MSG(Object::cast_to<CanvasTexture>(p_specular.ptr()) != nullptr, "Can't self-assign a CanvasTexture");
|
||||
if (specular_texture == p_specular) {
|
||||
return;
|
||||
}
|
||||
specular_texture = p_specular;
|
||||
RID tex_rid = specular_texture.is_valid() ? specular_texture->get_rid() : RID();
|
||||
RS::get_singleton()->canvas_texture_set_channel(canvas_texture, RS::CANVAS_TEXTURE_CHANNEL_SPECULAR, tex_rid);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
Ref<Texture2D> CanvasTexture::get_specular_texture() const {
|
||||
|
@ -1528,8 +1539,12 @@ Ref<Texture2D> CanvasTexture::get_specular_texture() const {
|
|||
}
|
||||
|
||||
void CanvasTexture::set_specular_color(const Color &p_color) {
|
||||
if (specular == p_color) {
|
||||
return;
|
||||
}
|
||||
specular = p_color;
|
||||
RS::get_singleton()->canvas_texture_set_shading_parameters(canvas_texture, specular, shininess);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
Color CanvasTexture::get_specular_color() const {
|
||||
|
@ -1537,8 +1552,12 @@ Color CanvasTexture::get_specular_color() const {
|
|||
}
|
||||
|
||||
void CanvasTexture::set_specular_shininess(real_t p_shininess) {
|
||||
if (shininess == p_shininess) {
|
||||
return;
|
||||
}
|
||||
shininess = p_shininess;
|
||||
RS::get_singleton()->canvas_texture_set_shading_parameters(canvas_texture, specular, shininess);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
real_t CanvasTexture::get_specular_shininess() const {
|
||||
|
@ -1546,16 +1565,24 @@ real_t CanvasTexture::get_specular_shininess() const {
|
|||
}
|
||||
|
||||
void CanvasTexture::set_texture_filter(CanvasItem::TextureFilter p_filter) {
|
||||
if (texture_filter == p_filter) {
|
||||
return;
|
||||
}
|
||||
texture_filter = p_filter;
|
||||
RS::get_singleton()->canvas_texture_set_texture_filter(canvas_texture, RS::CanvasItemTextureFilter(p_filter));
|
||||
emit_changed();
|
||||
}
|
||||
CanvasItem::TextureFilter CanvasTexture::get_texture_filter() const {
|
||||
return texture_filter;
|
||||
}
|
||||
|
||||
void CanvasTexture::set_texture_repeat(CanvasItem::TextureRepeat p_repeat) {
|
||||
if (texture_repeat == p_repeat) {
|
||||
return;
|
||||
}
|
||||
texture_repeat = p_repeat;
|
||||
RS::get_singleton()->canvas_texture_set_texture_repeat(canvas_texture, RS::CanvasItemTextureRepeat(p_repeat));
|
||||
emit_changed();
|
||||
}
|
||||
CanvasItem::TextureRepeat CanvasTexture::get_texture_repeat() const {
|
||||
return texture_repeat;
|
||||
|
|
|
@ -4758,30 +4758,18 @@ void TileSetAtlasSource::_queue_update_padded_texture() {
|
|||
call_deferred(SNAME("_update_padded_texture"));
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::_update_padded_texture() {
|
||||
if (!padded_texture_needs_update) {
|
||||
return;
|
||||
}
|
||||
padded_texture_needs_update = false;
|
||||
padded_texture = Ref<ImageTexture>();
|
||||
Ref<ImageTexture> TileSetAtlasSource::_create_padded_image_texture(const Ref<Texture2D> &p_source) {
|
||||
ERR_FAIL_COND_V(p_source.is_null(), Ref<ImageTexture>());
|
||||
|
||||
if (!texture.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!use_texture_padding) {
|
||||
return;
|
||||
Ref<Image> src_image = p_source->get_image();
|
||||
if (src_image.is_null()) {
|
||||
Ref<ImageTexture> ret;
|
||||
ret.instantiate();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Size2 size = get_atlas_grid_size() * (texture_region_size + Vector2i(2, 2));
|
||||
|
||||
Ref<Image> src = texture->get_image();
|
||||
|
||||
if (!src.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<Image> image = Image::create_empty(size.x, size.y, false, src->get_format());
|
||||
Ref<Image> image = Image::create_empty(size.x, size.y, false, src_image->get_format());
|
||||
|
||||
for (KeyValue<Vector2i, TileAlternativesData> kv : tiles) {
|
||||
for (int frame = 0; frame < (int)kv.value.animation_frames_durations.size(); frame++) {
|
||||
|
@ -4797,24 +4785,89 @@ void TileSetAtlasSource::_update_padded_texture() {
|
|||
Vector2i frame_coords = kv.key + (kv.value.size_in_atlas + kv.value.animation_separation) * ((kv.value.animation_columns > 0) ? Vector2i(frame % kv.value.animation_columns, frame / kv.value.animation_columns) : Vector2i(frame, 0));
|
||||
Vector2i base_pos = frame_coords * (texture_region_size + Vector2i(2, 2)) + Vector2i(1, 1);
|
||||
|
||||
image->blit_rect(*src, src_rect, base_pos);
|
||||
image->blit_rect(*src_image, src_rect, base_pos);
|
||||
|
||||
image->blit_rect(*src, top_src_rect, base_pos + Vector2i(0, -1));
|
||||
image->blit_rect(*src, bottom_src_rect, base_pos + Vector2i(0, src_rect.size.y));
|
||||
image->blit_rect(*src, left_src_rect, base_pos + Vector2i(-1, 0));
|
||||
image->blit_rect(*src, right_src_rect, base_pos + Vector2i(src_rect.size.x, 0));
|
||||
image->blit_rect(*src_image, top_src_rect, base_pos + Vector2i(0, -1));
|
||||
image->blit_rect(*src_image, bottom_src_rect, base_pos + Vector2i(0, src_rect.size.y));
|
||||
image->blit_rect(*src_image, left_src_rect, base_pos + Vector2i(-1, 0));
|
||||
image->blit_rect(*src_image, right_src_rect, base_pos + Vector2i(src_rect.size.x, 0));
|
||||
|
||||
image->set_pixelv(base_pos + Vector2i(-1, -1), src->get_pixelv(src_rect.position));
|
||||
image->set_pixelv(base_pos + Vector2i(src_rect.size.x, -1), src->get_pixelv(src_rect.position + Vector2i(src_rect.size.x - 1, 0)));
|
||||
image->set_pixelv(base_pos + Vector2i(-1, src_rect.size.y), src->get_pixelv(src_rect.position + Vector2i(0, src_rect.size.y - 1)));
|
||||
image->set_pixelv(base_pos + Vector2i(src_rect.size.x, src_rect.size.y), src->get_pixelv(src_rect.position + Vector2i(src_rect.size.x - 1, src_rect.size.y - 1)));
|
||||
image->set_pixelv(base_pos + Vector2i(-1, -1), src_image->get_pixelv(src_rect.position));
|
||||
image->set_pixelv(base_pos + Vector2i(src_rect.size.x, -1), src_image->get_pixelv(src_rect.position + Vector2i(src_rect.size.x - 1, 0)));
|
||||
image->set_pixelv(base_pos + Vector2i(-1, src_rect.size.y), src_image->get_pixelv(src_rect.position + Vector2i(0, src_rect.size.y - 1)));
|
||||
image->set_pixelv(base_pos + Vector2i(src_rect.size.x, src_rect.size.y), src_image->get_pixelv(src_rect.position + Vector2i(src_rect.size.x - 1, src_rect.size.y - 1)));
|
||||
}
|
||||
}
|
||||
|
||||
if (!padded_texture.is_valid()) {
|
||||
padded_texture.instantiate();
|
||||
return ImageTexture::create_from_image(image);
|
||||
}
|
||||
|
||||
void TileSetAtlasSource::_update_padded_texture() {
|
||||
if (!padded_texture_needs_update) {
|
||||
return;
|
||||
}
|
||||
padded_texture->set_image(image);
|
||||
padded_texture_needs_update = false;
|
||||
|
||||
if (padded_texture.is_valid()) {
|
||||
padded_texture->disconnect_changed(callable_mp(this, &TileSetAtlasSource::_queue_update_padded_texture));
|
||||
}
|
||||
|
||||
padded_texture = Ref<CanvasTexture>();
|
||||
|
||||
if (texture.is_null()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!use_texture_padding) {
|
||||
return;
|
||||
}
|
||||
|
||||
padded_texture.instantiate();
|
||||
|
||||
Ref<CanvasTexture> src_canvas_texture = texture;
|
||||
if (src_canvas_texture.is_valid()) {
|
||||
// Use all textures.
|
||||
// Diffuse
|
||||
Ref<Texture2D> src = src_canvas_texture->get_diffuse_texture();
|
||||
Ref<ImageTexture> image_texture;
|
||||
if (src.is_valid()) {
|
||||
image_texture = _create_padded_image_texture(src);
|
||||
} else {
|
||||
image_texture.instantiate();
|
||||
}
|
||||
padded_texture->set_diffuse_texture(image_texture);
|
||||
|
||||
// Normal
|
||||
src = src_canvas_texture->get_normal_texture();
|
||||
image_texture.instantiate();
|
||||
if (src.is_valid()) {
|
||||
image_texture = _create_padded_image_texture(src);
|
||||
} else {
|
||||
image_texture.instantiate();
|
||||
}
|
||||
padded_texture->set_normal_texture(image_texture);
|
||||
|
||||
// Specular
|
||||
src = src_canvas_texture->get_specular_texture();
|
||||
image_texture.instantiate();
|
||||
if (src.is_valid()) {
|
||||
image_texture = _create_padded_image_texture(src);
|
||||
} else {
|
||||
image_texture.instantiate();
|
||||
}
|
||||
padded_texture->set_specular_texture(image_texture);
|
||||
|
||||
// Other properties.
|
||||
padded_texture->set_specular_color(src_canvas_texture->get_specular_color());
|
||||
padded_texture->set_specular_shininess(src_canvas_texture->get_specular_shininess());
|
||||
padded_texture->set_texture_filter(src_canvas_texture->get_texture_filter());
|
||||
padded_texture->set_texture_repeat(src_canvas_texture->get_texture_repeat());
|
||||
} else {
|
||||
// Use only diffuse.
|
||||
Ref<ImageTexture> image_texture = _create_padded_image_texture(texture);
|
||||
padded_texture->set_diffuse_texture(image_texture);
|
||||
}
|
||||
padded_texture->connect_changed(callable_mp(this, &TileSetAtlasSource::_queue_update_padded_texture));
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
|
|
|
@ -641,9 +641,10 @@ private:
|
|||
void _create_coords_mapping_cache(Vector2i p_atlas_coords);
|
||||
|
||||
bool use_texture_padding = true;
|
||||
Ref<ImageTexture> padded_texture;
|
||||
Ref<CanvasTexture> padded_texture;
|
||||
bool padded_texture_needs_update = false;
|
||||
void _queue_update_padded_texture();
|
||||
Ref<ImageTexture> _create_padded_image_texture(const Ref<Texture2D> &p_source);
|
||||
void _update_padded_texture();
|
||||
|
||||
protected:
|
||||
|
|
Loading…
Reference in New Issue