Path: blob/master/scene/resources/drawable_texture_2d.cpp
20934 views
/**************************************************************************/1/* drawable_texture_2d.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "drawable_texture_2d.h"3132DrawableTexture2D::DrawableTexture2D() {33default_material = RS::get_singleton()->texture_drawable_get_default_material();34}3536DrawableTexture2D::~DrawableTexture2D() {37if (texture.is_valid()) {38ERR_FAIL_NULL(RenderingServer::get_singleton());39RenderingServer::get_singleton()->free_rid(texture);40}41}4243// Initialize Texture Resource with a call to rendering server. Overwrite existing.44void DrawableTexture2D::_initialize() {45if (texture.is_valid()) {46RID new_texture = RS::get_singleton()->texture_drawable_create(width, height, (RS::TextureDrawableFormat)format, base_color, mipmaps);47RS::get_singleton()->texture_replace(texture, new_texture);48} else {49texture = RS::get_singleton()->texture_drawable_create(width, height, (RS::TextureDrawableFormat)format, base_color, mipmaps);50}51}5253// Setup basic parameters on the Drawable Texture54void DrawableTexture2D::setup(int p_width, int p_height, DrawableFormat p_format, const Color &p_color, bool p_use_mipmaps) {55ERR_FAIL_COND_MSG(p_width <= 0 || p_width > 16384, "Texture dimensions have to be in the 1 to 16384 range.");56ERR_FAIL_COND_MSG(p_height <= 0 || p_height > 16384, "Texture dimensions have to be in the 1 to 16384 range.");57width = p_width;58height = p_height;59format = p_format;60mipmaps = p_use_mipmaps;61base_color = p_color;62_initialize();63notify_property_list_changed();64emit_changed();65}6667void DrawableTexture2D::set_width(int p_width) {68ERR_FAIL_COND_MSG(p_width <= 0 || p_width > 16384, "Texture dimensions have to be in the 1 to 16384 range.");69if (width == p_width) {70return;71}72width = p_width;73notify_property_list_changed();74emit_changed();75}7677int DrawableTexture2D::get_width() const {78return width;79}8081void DrawableTexture2D::set_height(int p_height) {82ERR_FAIL_COND_MSG(p_height <= 0 || p_height > 16384, "Texture dimensions have to be in the 1 to 16384 range.");83if (height == p_height) {84return;85}86height = p_height;87notify_property_list_changed();88emit_changed();89}9091int DrawableTexture2D::get_height() const {92return height;93}9495void DrawableTexture2D::set_format(DrawableFormat p_format) {96if (format == p_format) {97return;98}99format = p_format;100notify_property_list_changed();101emit_changed();102}103104DrawableTexture2D::DrawableFormat DrawableTexture2D::get_format() const {105return format;106}107108void DrawableTexture2D::set_use_mipmaps(bool p_mipmaps) {109if (mipmaps == p_mipmaps) {110return;111}112mipmaps = p_mipmaps;113notify_property_list_changed();114emit_changed();115}116117bool DrawableTexture2D::get_use_mipmaps() const {118return mipmaps;119}120121RID DrawableTexture2D::get_rid() const {122if (texture.is_null()) {123// We are in trouble, create something temporary.124// 4, 4, false, Image::FORMAT_RGBA8125texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();126}127return texture;128}129130void DrawableTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {131if ((width | height) == 0) {132return;133}134RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(width, height)), texture, false, p_modulate, p_transpose);135}136137void DrawableTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {138if ((width | height) == 0) {139return;140}141RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose);142}143144void DrawableTexture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const {145if ((width | height) == 0) {146return;147}148RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, p_clip_uv);149}150151// Perform a blit operation from the given source to the given rect on self.152void DrawableTexture2D::blit_rect(const Rect2i p_rect, const Ref<Texture2D> &p_source, const Color &p_modulate, int p_mipmap, const Ref<Material> &p_material) {153// Use user Shader if exists.154RID material = default_material;155if (p_material.is_valid()) {156material = p_material->get_rid();157if (p_material->get_shader_mode() != Shader::MODE_TEXTURE_BLIT) {158WARN_PRINT("ShaderMaterial passed to blit_rect() is not a texture_blit shader. Using default instead.");159}160}161162// Rendering server expects textureParameters as a TypedArray[RID]163Array textures;164textures.push_back(texture);165166if (p_source.is_valid()) {167ERR_FAIL_COND_MSG(texture == p_source->get_rid(), "Cannot use self as a source.");168}169Array src_textures;170if (Ref<AtlasTexture>(p_source).is_valid()) {171WARN_PRINT("AtlasTexture not supported as a source for blit_rect. Using default White.");172src_textures.push_back(RID());173} else {174src_textures.push_back(p_source);175}176177RS::get_singleton()->texture_drawable_blit_rect(textures, p_rect, material, p_modulate, src_textures, p_mipmap);178notify_property_list_changed();179}180181// Perform a blit operation from the given sources to the given rect on self and extra targets182void DrawableTexture2D::blit_rect_multi(const Rect2i p_rect, const TypedArray<Texture2D> &p_sources, const TypedArray<DrawableTexture2D> &p_extra_targets, const Color &p_modulate, int p_mipmap, const Ref<Material> &p_material) {183RID material = default_material;184if (p_material.is_valid()) {185material = p_material->get_rid();186if (p_material->get_shader_mode() != Shader::MODE_TEXTURE_BLIT) {187WARN_PRINT("ShaderMaterial passed to blit_rect_multi() is not a texture_blit shader. Using default instead.");188}189}190191// Rendering server expects textureParameters as a TypedArray[RID]192Array textures;193textures.push_back(texture);194int i = 0;195while (i < p_extra_targets.size()) {196textures.push_back(RID(p_extra_targets[i]));197i += 1;198}199i = 0;200Array src_textures;201while (i < p_sources.size()) {202if (Ref<AtlasTexture>(p_sources[i]).is_valid()) {203WARN_PRINT("AtlasTexture not supported as a source for blit_rect. Using default White.");204src_textures.push_back(RID());205} else {206src_textures.push_back(RID(p_sources[i]));207}208ERR_FAIL_COND_MSG(textures.has(RID(src_textures[i])), "Cannot use self as a source.");209i += 1;210}211212RS::get_singleton()->texture_drawable_blit_rect(textures, p_rect, material, p_modulate, src_textures, p_mipmap);213notify_property_list_changed();214}215216Ref<Image> DrawableTexture2D::get_image() const {217if (texture.is_valid()) {218return RS::get_singleton()->texture_2d_get(texture);219} else {220return Ref<Image>();221}222}223224void DrawableTexture2D::generate_mipmaps() {225if (texture.is_valid()) {226RS::get_singleton()->texture_drawable_generate_mipmaps(texture);227}228}229230void DrawableTexture2D::_bind_methods() {231ClassDB::bind_method(D_METHOD("setup", "width", "height", "format", "color", "use_mipmaps"), &DrawableTexture2D::setup, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(false));232ClassDB::bind_method(D_METHOD("blit_rect", "rect", "source", "modulate", "mipmap", "material"), &DrawableTexture2D::blit_rect, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(0), DEFVAL(Ref<Material>()));233ClassDB::bind_method(D_METHOD("blit_rect_multi", "rect", "sources", "extra_targets", "modulate", "mipmap", "material"), &DrawableTexture2D::blit_rect_multi, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(0), DEFVAL(Ref<Material>()));234ClassDB::bind_method(D_METHOD("generate_mipmaps"), &DrawableTexture2D::generate_mipmaps);235236BIND_ENUM_CONSTANT(DRAWABLE_FORMAT_RGBA8);237BIND_ENUM_CONSTANT(DRAWABLE_FORMAT_RGBA8_SRGB);238BIND_ENUM_CONSTANT(DRAWABLE_FORMAT_RGBAH);239BIND_ENUM_CONSTANT(DRAWABLE_FORMAT_RGBAF);240}241242243