texture.cpp 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318
  1. /*************************************************************************/
  2. /* texture.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "texture.h"
  31. #include "core/core_string_names.h"
  32. #include "core/io/image_loader.h"
  33. #include "core/method_bind_ext.gen.inc"
  34. #include "core/os/os.h"
  35. #include "mesh.h"
  36. #include "scene/resources/bit_map.h"
  37. #include "servers/camera/camera_feed.h"
  38. Size2 Texture2D::get_size() const {
  39. return Size2(get_width(), get_height());
  40. }
  41. bool Texture2D::is_pixel_opaque(int p_x, int p_y) const {
  42. return true;
  43. }
  44. void Texture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  45. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  46. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  47. VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  48. }
  49. void Texture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  50. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  51. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  52. VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  53. }
  54. void Texture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
  55. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  56. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  57. VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
  58. }
  59. bool Texture2D::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
  60. r_rect = p_rect;
  61. r_src_rect = p_src_rect;
  62. return true;
  63. }
  64. void Texture2D::_bind_methods() {
  65. ClassDB::bind_method(D_METHOD("get_width"), &Texture2D::get_width);
  66. ClassDB::bind_method(D_METHOD("get_height"), &Texture2D::get_height);
  67. ClassDB::bind_method(D_METHOD("get_size"), &Texture2D::get_size);
  68. ClassDB::bind_method(D_METHOD("has_alpha"), &Texture2D::has_alpha);
  69. ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat"), &Texture2D::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT));
  70. ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT));
  71. ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map", "specular_map", "specular_color_shininess", "texture_filter", "texture_repeat", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(Color(1, 1, 1, 1)), DEFVAL(VS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT), DEFVAL(VS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT), DEFVAL(true));
  72. ClassDB::bind_method(D_METHOD("get_data"), &Texture2D::get_data);
  73. ADD_GROUP("", "");
  74. }
  75. Texture2D::Texture2D() {
  76. }
  77. /////////////////////
  78. void ImageTexture::reload_from_file() {
  79. String path = ResourceLoader::path_remap(get_path());
  80. if (!path.is_resource_file())
  81. return;
  82. Ref<Image> img;
  83. img.instance();
  84. if (ImageLoader::load_image(path, img) == OK) {
  85. create_from_image(img);
  86. } else {
  87. Resource::reload_from_file();
  88. _change_notify();
  89. emit_changed();
  90. }
  91. }
  92. bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
  93. if (p_name == "image")
  94. create_from_image(p_value);
  95. else if (p_name == "size") {
  96. Size2 s = p_value;
  97. w = s.width;
  98. h = s.height;
  99. VisualServer::get_singleton()->texture_set_size_override(texture, w, h);
  100. } else
  101. return false;
  102. return true;
  103. }
  104. bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
  105. if (p_name == "image")
  106. r_ret = get_data();
  107. else if (p_name == "size")
  108. r_ret = Size2(w, h);
  109. else
  110. return false;
  111. return true;
  112. }
  113. void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
  114. p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
  115. p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
  116. }
  117. void ImageTexture::_reload_hook(const RID &p_hook) {
  118. String path = get_path();
  119. if (!path.is_resource_file())
  120. return;
  121. Ref<Image> img;
  122. img.instance();
  123. Error err = ImageLoader::load_image(path, img);
  124. ERR_FAIL_COND_MSG(err != OK, "Cannot load image from path '" + path + "'.");
  125. RID new_texture = VisualServer::get_singleton()->texture_2d_create(img);
  126. VisualServer::get_singleton()->texture_replace(texture, new_texture);
  127. _change_notify();
  128. emit_changed();
  129. }
  130. void ImageTexture::create_from_image(const Ref<Image> &p_image) {
  131. ERR_FAIL_COND(p_image.is_null());
  132. w = p_image->get_width();
  133. h = p_image->get_height();
  134. format = p_image->get_format();
  135. mipmaps = p_image->has_mipmaps();
  136. if (texture.is_null()) {
  137. texture = VisualServer::get_singleton()->texture_2d_create(p_image);
  138. } else {
  139. RID new_texture = VisualServer::get_singleton()->texture_2d_create(p_image);
  140. VisualServer::get_singleton()->texture_replace(texture, new_texture);
  141. }
  142. _change_notify();
  143. emit_changed();
  144. image_stored = true;
  145. }
  146. Image::Format ImageTexture::get_format() const {
  147. return format;
  148. }
  149. void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) {
  150. ERR_FAIL_COND(p_image.is_null());
  151. ERR_FAIL_COND(texture.is_null());
  152. ERR_FAIL_COND(p_image->get_width() != w || p_image->get_height() != h);
  153. ERR_FAIL_COND(p_image->get_format() != format);
  154. ERR_FAIL_COND(mipmaps != p_image->has_mipmaps());
  155. if (p_immediate) {
  156. VisualServer::get_singleton()->texture_2d_update_immediate(texture, p_image);
  157. } else {
  158. VisualServer::get_singleton()->texture_2d_update(texture, p_image);
  159. }
  160. _change_notify();
  161. emit_changed();
  162. alpha_cache.unref();
  163. image_stored = true;
  164. }
  165. void ImageTexture::_resource_path_changed() {
  166. String path = get_path();
  167. }
  168. Ref<Image> ImageTexture::get_data() const {
  169. if (image_stored) {
  170. return VisualServer::get_singleton()->texture_2d_get(texture);
  171. } else {
  172. return Ref<Image>();
  173. }
  174. }
  175. int ImageTexture::get_width() const {
  176. return w;
  177. }
  178. int ImageTexture::get_height() const {
  179. return h;
  180. }
  181. RID ImageTexture::get_rid() const {
  182. if (texture.is_null()) {
  183. //we are in trouble, create something temporary
  184. texture = VisualServer::get_singleton()->texture_2d_placeholder_create();
  185. }
  186. return texture;
  187. }
  188. bool ImageTexture::has_alpha() const {
  189. return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8);
  190. }
  191. void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  192. if ((w | h) == 0)
  193. return;
  194. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  195. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  196. VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  197. }
  198. void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  199. if ((w | h) == 0)
  200. return;
  201. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  202. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  203. VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  204. }
  205. void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
  206. if ((w | h) == 0)
  207. return;
  208. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  209. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  210. VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
  211. }
  212. bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
  213. if (!alpha_cache.is_valid()) {
  214. Ref<Image> img = get_data();
  215. if (img.is_valid()) {
  216. if (img->is_compressed()) { //must decompress, if compressed
  217. Ref<Image> decom = img->duplicate();
  218. decom->decompress();
  219. img = decom;
  220. }
  221. alpha_cache.instance();
  222. alpha_cache->create_from_image_alpha(img);
  223. }
  224. }
  225. if (alpha_cache.is_valid()) {
  226. int aw = int(alpha_cache->get_size().width);
  227. int ah = int(alpha_cache->get_size().height);
  228. if (aw == 0 || ah == 0) {
  229. return true;
  230. }
  231. int x = p_x * aw / w;
  232. int y = p_y * ah / h;
  233. x = CLAMP(x, 0, aw);
  234. y = CLAMP(y, 0, ah);
  235. return alpha_cache->get_bit(Point2(x, y));
  236. }
  237. return true;
  238. }
  239. void ImageTexture::set_size_override(const Size2 &p_size) {
  240. Size2 s = p_size;
  241. if (s.x != 0)
  242. w = s.x;
  243. if (s.y != 0)
  244. h = s.y;
  245. VisualServer::get_singleton()->texture_set_size_override(texture, w, h);
  246. }
  247. void ImageTexture::set_path(const String &p_path, bool p_take_over) {
  248. if (texture.is_valid()) {
  249. VisualServer::get_singleton()->texture_set_path(texture, p_path);
  250. }
  251. Resource::set_path(p_path, p_take_over);
  252. }
  253. void ImageTexture::_bind_methods() {
  254. ClassDB::bind_method(D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
  255. ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
  256. ClassDB::bind_method(D_METHOD("update", "image", "immediate"), &ImageTexture::update, DEFVAL(false));
  257. ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
  258. ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook);
  259. }
  260. ImageTexture::ImageTexture() {
  261. w = h = 0;
  262. image_stored = false;
  263. mipmaps = false;
  264. format = Image::FORMAT_L8;
  265. }
  266. ImageTexture::~ImageTexture() {
  267. if (texture.is_valid()) {
  268. VisualServer::get_singleton()->free(texture);
  269. }
  270. }
  271. //////////////////////////////////////////
  272. Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit) {
  273. uint32_t data_format = f->get_32();
  274. uint32_t w = f->get_16();
  275. uint32_t h = f->get_16();
  276. uint32_t mipmaps = f->get_32();
  277. Image::Format format = Image::Format(f->get_32());
  278. print_line("format: " + itos(data_format) + " size " + Size2i(w, h) + " mipmaps: " + itos(mipmaps));
  279. if (data_format == DATA_FORMAT_LOSSLESS || data_format == DATA_FORMAT_LOSSY || data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
  280. //look for a PNG or WEBP file inside
  281. int sw = w;
  282. int sh = h;
  283. //mipmaps need to be read independently, they will be later combined
  284. Vector<Ref<Image> > mipmap_images;
  285. int total_size = 0;
  286. bool first = true;
  287. for (uint32_t i = 0; i < mipmaps + 1; i++) {
  288. uint32_t size = f->get_32();
  289. if (p_size_limit > 0 && i < (mipmaps - 1) && (sw > p_size_limit || sh > p_size_limit)) {
  290. //can't load this due to size limit
  291. sw = MAX(sw >> 1, 1);
  292. sh = MAX(sh >> 1, 1);
  293. f->seek(f->get_position() + size);
  294. continue;
  295. }
  296. Vector<uint8_t> pv;
  297. pv.resize(size);
  298. {
  299. uint8_t *wr = pv.ptrw();
  300. f->get_buffer(wr, size);
  301. }
  302. Ref<Image> img;
  303. if (data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
  304. img = Image::basis_universal_unpacker(pv);
  305. } else if (data_format == DATA_FORMAT_LOSSLESS) {
  306. img = Image::lossless_unpacker(pv);
  307. } else {
  308. img = Image::lossy_unpacker(pv);
  309. }
  310. if (img.is_null() || img->empty()) {
  311. ERR_FAIL_COND_V(img.is_null() || img->empty(), Ref<Image>());
  312. }
  313. if (first) {
  314. //format will actually be the format of the first image,
  315. //as it may have changed on compression
  316. format = img->get_format();
  317. first = false;
  318. } else if (img->get_format() != format) {
  319. img->convert(format); //all needs to be the same format
  320. }
  321. total_size += img->get_data().size();
  322. mipmap_images.push_back(img);
  323. sw = MAX(sw >> 1, 1);
  324. sh = MAX(sh >> 1, 1);
  325. }
  326. //print_line("mipmap read total: " + itos(mipmap_images.size()));
  327. Ref<Image> image;
  328. image.instance();
  329. if (mipmap_images.size() == 1) {
  330. //only one image (which will most likely be the case anyway for this format)
  331. image = mipmap_images[0];
  332. return image;
  333. } else {
  334. //rarer use case, but needs to be supported
  335. Vector<uint8_t> img_data;
  336. img_data.resize(total_size);
  337. {
  338. uint8_t *wr = img_data.ptrw();
  339. int ofs = 0;
  340. for (int i = 0; i < mipmap_images.size(); i++) {
  341. Vector<uint8_t> id = mipmap_images[i]->get_data();
  342. int len = id.size();
  343. const uint8_t *r = id.ptr();
  344. copymem(&wr[ofs], r, len);
  345. ofs += len;
  346. }
  347. }
  348. image->create(w, h, true, mipmap_images[0]->get_format(), img_data);
  349. return image;
  350. }
  351. } else if (data_format == DATA_FORMAT_IMAGE) {
  352. int size = Image::get_image_data_size(w, h, format, mipmaps ? true : false);
  353. for (uint32_t i = 0; i < mipmaps + 1; i++) {
  354. int tw, th;
  355. int ofs = Image::get_image_mipmap_offset_and_dimensions(w, h, format, i, tw, th);
  356. if (p_size_limit > 0 && i < mipmaps && (p_size_limit > tw || p_size_limit > th)) {
  357. if (ofs) {
  358. f->seek(f->get_position() + ofs);
  359. }
  360. continue; //oops, size limit enforced, go to next
  361. }
  362. Vector<uint8_t> data;
  363. data.resize(size - ofs);
  364. {
  365. uint8_t *wr = data.ptrw();
  366. f->get_buffer(wr, data.size());
  367. }
  368. Ref<Image> image;
  369. image.instance();
  370. image->create(tw, th, mipmaps - i ? true : false, format, data);
  371. return image;
  372. }
  373. }
  374. return Ref<Image>();
  375. }
  376. void StreamTexture::set_path(const String &p_path, bool p_take_over) {
  377. if (texture.is_valid()) {
  378. VisualServer::get_singleton()->texture_set_path(texture, p_path);
  379. }
  380. Resource::set_path(p_path, p_take_over);
  381. }
  382. void StreamTexture::_requested_3d(void *p_ud) {
  383. StreamTexture *st = (StreamTexture *)p_ud;
  384. Ref<StreamTexture> stex(st);
  385. ERR_FAIL_COND(!request_3d_callback);
  386. request_3d_callback(stex);
  387. }
  388. void StreamTexture::_requested_roughness(void *p_ud, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_roughness_channel) {
  389. StreamTexture *st = (StreamTexture *)p_ud;
  390. Ref<StreamTexture> stex(st);
  391. ERR_FAIL_COND(!request_roughness_callback);
  392. request_roughness_callback(stex, p_normal_path, p_roughness_channel);
  393. }
  394. void StreamTexture::_requested_normal(void *p_ud) {
  395. StreamTexture *st = (StreamTexture *)p_ud;
  396. Ref<StreamTexture> stex(st);
  397. ERR_FAIL_COND(!request_normal_callback);
  398. request_normal_callback(stex);
  399. }
  400. StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL;
  401. StreamTexture::TextureFormatRoughnessRequestCallback StreamTexture::request_roughness_callback = NULL;
  402. StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL;
  403. Image::Format StreamTexture::get_format() const {
  404. return format;
  405. }
  406. Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) {
  407. alpha_cache.unref();
  408. ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
  409. FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
  410. ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
  411. uint8_t header[4];
  412. f->get_buffer(header, 4);
  413. if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != '2') {
  414. memdelete(f);
  415. ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is corrupt (Bad header).");
  416. }
  417. uint32_t version = f->get_32();
  418. if (version > FORMAT_VERSION) {
  419. memdelete(f);
  420. ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
  421. }
  422. tw_custom = f->get_32();
  423. th_custom = f->get_32();
  424. uint32_t df = f->get_32(); //data format
  425. //skip reserved
  426. mipmap_limit = int(f->get_32());
  427. //reserved
  428. f->get_32();
  429. f->get_32();
  430. f->get_32();
  431. #ifdef TOOLS_ENABLED
  432. r_request_3d = request_3d_callback && df & FORMAT_BIT_DETECT_3D;
  433. r_request_roughness = request_roughness_callback && df & FORMAT_BIT_DETECT_ROUGNESS;
  434. r_request_normal = request_normal_callback && df & FORMAT_BIT_DETECT_NORMAL;
  435. #else
  436. r_request_3d = false;
  437. r_request_roughness = false;
  438. r_request_normal = false;
  439. #endif
  440. if (!(df & FORMAT_BIT_STREAM)) {
  441. p_size_limit = 0;
  442. }
  443. image = load_image_from_file(f, p_size_limit);
  444. memdelete(f);
  445. if (image.is_null() || image->empty()) {
  446. return ERR_CANT_OPEN;
  447. }
  448. return OK;
  449. }
  450. Error StreamTexture::load(const String &p_path) {
  451. int lw, lh, lwc, lhc;
  452. Ref<Image> image;
  453. image.instance();
  454. bool request_3d;
  455. bool request_normal;
  456. bool request_roughness;
  457. int mipmap_limit;
  458. Error err = _load_data(p_path, lw, lh, lwc, lhc, image, request_3d, request_normal, request_roughness, mipmap_limit);
  459. if (err)
  460. return err;
  461. if (texture.is_valid()) {
  462. RID new_texture = VS::get_singleton()->texture_2d_create(image);
  463. VS::get_singleton()->texture_replace(texture, new_texture);
  464. } else {
  465. texture = VS::get_singleton()->texture_2d_create(image);
  466. }
  467. if (lwc || lhc) {
  468. VS::get_singleton()->texture_set_size_override(texture, lwc, lhc);
  469. }
  470. w = lwc ? lwc : lw;
  471. h = lhc ? lhc : lh;
  472. path_to_file = p_path;
  473. format = image->get_format();
  474. if (get_path() == String()) {
  475. //temporarily set path if no path set for resource, helps find errors
  476. VisualServer::get_singleton()->texture_set_path(texture, p_path);
  477. }
  478. #ifdef TOOLS_ENABLED
  479. if (request_3d) {
  480. //print_line("request detect 3D at " + p_path);
  481. VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this);
  482. } else {
  483. //print_line("not requesting detect 3D at " + p_path);
  484. VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL);
  485. }
  486. if (request_roughness) {
  487. //print_line("request detect srgb at " + p_path);
  488. VS::get_singleton()->texture_set_detect_roughness_callback(texture, _requested_roughness, this);
  489. } else {
  490. //print_line("not requesting detect srgb at " + p_path);
  491. VS::get_singleton()->texture_set_detect_roughness_callback(texture, NULL, NULL);
  492. }
  493. if (request_normal) {
  494. //print_line("request detect srgb at " + p_path);
  495. VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
  496. } else {
  497. //print_line("not requesting detect normal at " + p_path);
  498. VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL);
  499. }
  500. #endif
  501. _change_notify();
  502. emit_changed();
  503. return OK;
  504. }
  505. String StreamTexture::get_load_path() const {
  506. return path_to_file;
  507. }
  508. int StreamTexture::get_width() const {
  509. return w;
  510. }
  511. int StreamTexture::get_height() const {
  512. return h;
  513. }
  514. RID StreamTexture::get_rid() const {
  515. if (!texture.is_valid()) {
  516. texture = VS::get_singleton()->texture_2d_placeholder_create();
  517. }
  518. return texture;
  519. }
  520. void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  521. if ((w | h) == 0)
  522. return;
  523. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  524. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  525. VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  526. }
  527. void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  528. if ((w | h) == 0)
  529. return;
  530. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  531. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  532. VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  533. }
  534. void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
  535. if ((w | h) == 0)
  536. return;
  537. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  538. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  539. VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
  540. }
  541. bool StreamTexture::has_alpha() const {
  542. return false;
  543. }
  544. Ref<Image> StreamTexture::get_data() const {
  545. if (texture.is_valid()) {
  546. return VS::get_singleton()->texture_2d_get(texture);
  547. } else {
  548. return Ref<Image>();
  549. }
  550. }
  551. bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
  552. if (!alpha_cache.is_valid()) {
  553. Ref<Image> img = get_data();
  554. if (img.is_valid()) {
  555. if (img->is_compressed()) { //must decompress, if compressed
  556. Ref<Image> decom = img->duplicate();
  557. decom->decompress();
  558. img = decom;
  559. }
  560. alpha_cache.instance();
  561. alpha_cache->create_from_image_alpha(img);
  562. }
  563. }
  564. if (alpha_cache.is_valid()) {
  565. int aw = int(alpha_cache->get_size().width);
  566. int ah = int(alpha_cache->get_size().height);
  567. if (aw == 0 || ah == 0) {
  568. return true;
  569. }
  570. int x = p_x * aw / w;
  571. int y = p_y * ah / h;
  572. x = CLAMP(x, 0, aw);
  573. y = CLAMP(y, 0, ah);
  574. return alpha_cache->get_bit(Point2(x, y));
  575. }
  576. return true;
  577. }
  578. void StreamTexture::reload_from_file() {
  579. String path = get_path();
  580. if (!path.is_resource_file())
  581. return;
  582. path = ResourceLoader::path_remap(path); //remap for translation
  583. path = ResourceLoader::import_remap(path); //remap for import
  584. if (!path.is_resource_file())
  585. return;
  586. load(path);
  587. }
  588. void StreamTexture::_validate_property(PropertyInfo &property) const {
  589. }
  590. void StreamTexture::_bind_methods() {
  591. ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture::load);
  592. ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture::get_load_path);
  593. ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
  594. }
  595. StreamTexture::StreamTexture() {
  596. format = Image::FORMAT_MAX;
  597. w = 0;
  598. h = 0;
  599. }
  600. StreamTexture::~StreamTexture() {
  601. if (texture.is_valid()) {
  602. VS::get_singleton()->free(texture);
  603. }
  604. }
  605. RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error) {
  606. Ref<StreamTexture> st;
  607. st.instance();
  608. Error err = st->load(p_path);
  609. if (r_error)
  610. *r_error = err;
  611. if (err != OK)
  612. return RES();
  613. return st;
  614. }
  615. void ResourceFormatLoaderStreamTexture::get_recognized_extensions(List<String> *p_extensions) const {
  616. p_extensions->push_back("stex");
  617. }
  618. bool ResourceFormatLoaderStreamTexture::handles_type(const String &p_type) const {
  619. return p_type == "StreamTexture";
  620. }
  621. String ResourceFormatLoaderStreamTexture::get_resource_type(const String &p_path) const {
  622. if (p_path.get_extension().to_lower() == "stex")
  623. return "StreamTexture";
  624. return "";
  625. }
  626. //////////////////////////////////////////
  627. int AtlasTexture::get_width() const {
  628. if (region.size.width == 0) {
  629. if (atlas.is_valid())
  630. return atlas->get_width();
  631. return 1;
  632. } else {
  633. return region.size.width + margin.size.width;
  634. }
  635. }
  636. int AtlasTexture::get_height() const {
  637. if (region.size.height == 0) {
  638. if (atlas.is_valid())
  639. return atlas->get_height();
  640. return 1;
  641. } else {
  642. return region.size.height + margin.size.height;
  643. }
  644. }
  645. RID AtlasTexture::get_rid() const {
  646. if (atlas.is_valid())
  647. return atlas->get_rid();
  648. return RID();
  649. }
  650. bool AtlasTexture::has_alpha() const {
  651. if (atlas.is_valid())
  652. return atlas->has_alpha();
  653. return false;
  654. }
  655. void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) {
  656. ERR_FAIL_COND(p_atlas == this);
  657. if (atlas == p_atlas)
  658. return;
  659. atlas = p_atlas;
  660. emit_changed();
  661. _change_notify("atlas");
  662. }
  663. Ref<Texture2D> AtlasTexture::get_atlas() const {
  664. return atlas;
  665. }
  666. void AtlasTexture::set_region(const Rect2 &p_region) {
  667. if (region == p_region)
  668. return;
  669. region = p_region;
  670. emit_changed();
  671. _change_notify("region");
  672. }
  673. Rect2 AtlasTexture::get_region() const {
  674. return region;
  675. }
  676. void AtlasTexture::set_margin(const Rect2 &p_margin) {
  677. if (margin == p_margin)
  678. return;
  679. margin = p_margin;
  680. emit_changed();
  681. _change_notify("margin");
  682. }
  683. Rect2 AtlasTexture::get_margin() const {
  684. return margin;
  685. }
  686. void AtlasTexture::set_filter_clip(const bool p_enable) {
  687. filter_clip = p_enable;
  688. emit_changed();
  689. _change_notify("filter_clip");
  690. }
  691. bool AtlasTexture::has_filter_clip() const {
  692. return filter_clip;
  693. }
  694. void AtlasTexture::_bind_methods() {
  695. ClassDB::bind_method(D_METHOD("set_atlas", "atlas"), &AtlasTexture::set_atlas);
  696. ClassDB::bind_method(D_METHOD("get_atlas"), &AtlasTexture::get_atlas);
  697. ClassDB::bind_method(D_METHOD("set_region", "region"), &AtlasTexture::set_region);
  698. ClassDB::bind_method(D_METHOD("get_region"), &AtlasTexture::get_region);
  699. ClassDB::bind_method(D_METHOD("set_margin", "margin"), &AtlasTexture::set_margin);
  700. ClassDB::bind_method(D_METHOD("get_margin"), &AtlasTexture::get_margin);
  701. ClassDB::bind_method(D_METHOD("set_filter_clip", "enable"), &AtlasTexture::set_filter_clip);
  702. ClassDB::bind_method(D_METHOD("has_filter_clip"), &AtlasTexture::has_filter_clip);
  703. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_atlas", "get_atlas");
  704. ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region"), "set_region", "get_region");
  705. ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin");
  706. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_clip"), "set_filter_clip", "has_filter_clip");
  707. }
  708. void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  709. if (!atlas.is_valid())
  710. return;
  711. Rect2 rc = region;
  712. if (rc.size.width == 0) {
  713. rc.size.width = atlas->get_width();
  714. }
  715. if (rc.size.height == 0) {
  716. rc.size.height = atlas->get_height();
  717. }
  718. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  719. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  720. VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
  721. }
  722. void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  723. if (!atlas.is_valid())
  724. return;
  725. Rect2 rc = region;
  726. if (rc.size.width == 0) {
  727. rc.size.width = atlas->get_width();
  728. }
  729. if (rc.size.height == 0) {
  730. rc.size.height = atlas->get_height();
  731. }
  732. Vector2 scale = p_rect.size / (region.size + margin.size);
  733. Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale);
  734. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  735. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  736. VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
  737. }
  738. void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
  739. //this might not necessarily work well if using a rect, needs to be fixed properly
  740. if (!atlas.is_valid())
  741. return;
  742. Rect2 dr;
  743. Rect2 src_c;
  744. get_rect_region(p_rect, p_src_rect, dr, src_c);
  745. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  746. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  747. VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
  748. }
  749. bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
  750. if (!atlas.is_valid())
  751. return false;
  752. Rect2 rc = region;
  753. Rect2 src = p_src_rect;
  754. if (src.size == Size2()) {
  755. src.size = rc.size;
  756. }
  757. Vector2 scale = p_rect.size / src.size;
  758. src.position += (rc.position - margin.position);
  759. Rect2 src_c = rc.clip(src);
  760. if (src_c.size == Size2())
  761. return false;
  762. Vector2 ofs = (src_c.position - src.position);
  763. if (scale.x < 0) {
  764. float mx = (margin.size.width - margin.position.x);
  765. mx -= margin.position.x;
  766. ofs.x = -(ofs.x + mx);
  767. }
  768. if (scale.y < 0) {
  769. float my = margin.size.height - margin.position.y;
  770. my -= margin.position.y;
  771. ofs.y = -(ofs.y + my);
  772. }
  773. Rect2 dr(p_rect.position + ofs * scale, src_c.size * scale);
  774. r_rect = dr;
  775. r_src_rect = src_c;
  776. return true;
  777. }
  778. bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
  779. if (!atlas.is_valid())
  780. return true;
  781. int x = p_x + region.position.x - margin.position.x;
  782. int y = p_y + region.position.y - margin.position.y;
  783. // margin edge may outside of atlas
  784. if (x < 0 || x >= atlas->get_width()) return false;
  785. if (y < 0 || y >= atlas->get_height()) return false;
  786. return atlas->is_pixel_opaque(x, y);
  787. }
  788. AtlasTexture::AtlasTexture() {
  789. filter_clip = false;
  790. }
  791. /////////////////////////////////////////
  792. int MeshTexture::get_width() const {
  793. return size.width;
  794. }
  795. int MeshTexture::get_height() const {
  796. return size.height;
  797. }
  798. RID MeshTexture::get_rid() const {
  799. return RID();
  800. }
  801. bool MeshTexture::has_alpha() const {
  802. return false;
  803. }
  804. void MeshTexture::set_mesh(const Ref<Mesh> &p_mesh) {
  805. mesh = p_mesh;
  806. }
  807. Ref<Mesh> MeshTexture::get_mesh() const {
  808. return mesh;
  809. }
  810. void MeshTexture::set_image_size(const Size2 &p_size) {
  811. size = p_size;
  812. }
  813. Size2 MeshTexture::get_image_size() const {
  814. return size;
  815. }
  816. void MeshTexture::set_base_texture(const Ref<Texture2D> &p_texture) {
  817. base_texture = p_texture;
  818. }
  819. Ref<Texture2D> MeshTexture::get_base_texture() const {
  820. return base_texture;
  821. }
  822. void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  823. if (mesh.is_null() || base_texture.is_null()) {
  824. return;
  825. }
  826. Transform2D xform;
  827. xform.set_origin(p_pos);
  828. if (p_transpose) {
  829. SWAP(xform.elements[0][1], xform.elements[1][0]);
  830. SWAP(xform.elements[0][0], xform.elements[1][1]);
  831. }
  832. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  833. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  834. VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  835. }
  836. void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  837. if (mesh.is_null() || base_texture.is_null()) {
  838. return;
  839. }
  840. Transform2D xform;
  841. Vector2 origin = p_rect.position;
  842. if (p_rect.size.x < 0) {
  843. origin.x += size.x;
  844. }
  845. if (p_rect.size.y < 0) {
  846. origin.y += size.y;
  847. }
  848. xform.set_origin(origin);
  849. xform.set_scale(p_rect.size / size);
  850. if (p_transpose) {
  851. SWAP(xform.elements[0][1], xform.elements[1][0]);
  852. SWAP(xform.elements[0][0], xform.elements[1][1]);
  853. }
  854. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  855. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  856. VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  857. }
  858. void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
  859. if (mesh.is_null() || base_texture.is_null()) {
  860. return;
  861. }
  862. Transform2D xform;
  863. Vector2 origin = p_rect.position;
  864. if (p_rect.size.x < 0) {
  865. origin.x += size.x;
  866. }
  867. if (p_rect.size.y < 0) {
  868. origin.y += size.y;
  869. }
  870. xform.set_origin(origin);
  871. xform.set_scale(p_rect.size / size);
  872. if (p_transpose) {
  873. SWAP(xform.elements[0][1], xform.elements[1][0]);
  874. SWAP(xform.elements[0][0], xform.elements[1][1]);
  875. }
  876. RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
  877. RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
  878. VisualServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  879. }
  880. bool MeshTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
  881. r_rect = p_rect;
  882. r_src_rect = p_src_rect;
  883. return true;
  884. }
  885. bool MeshTexture::is_pixel_opaque(int p_x, int p_y) const {
  886. return true;
  887. }
  888. void MeshTexture::_bind_methods() {
  889. ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshTexture::set_mesh);
  890. ClassDB::bind_method(D_METHOD("get_mesh"), &MeshTexture::get_mesh);
  891. ClassDB::bind_method(D_METHOD("set_image_size", "size"), &MeshTexture::set_image_size);
  892. ClassDB::bind_method(D_METHOD("get_image_size"), &MeshTexture::get_image_size);
  893. ClassDB::bind_method(D_METHOD("set_base_texture", "texture"), &MeshTexture::set_base_texture);
  894. ClassDB::bind_method(D_METHOD("get_base_texture"), &MeshTexture::get_base_texture);
  895. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
  896. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base_texture", "get_base_texture");
  897. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "image_size", PROPERTY_HINT_RANGE, "0,16384,1"), "set_image_size", "get_image_size");
  898. }
  899. MeshTexture::MeshTexture() {
  900. }
  901. //////////////////////////////////////////
  902. int LargeTexture::get_width() const {
  903. return size.width;
  904. }
  905. int LargeTexture::get_height() const {
  906. return size.height;
  907. }
  908. RID LargeTexture::get_rid() const {
  909. return RID();
  910. }
  911. bool LargeTexture::has_alpha() const {
  912. for (int i = 0; i < pieces.size(); i++) {
  913. if (pieces[i].texture->has_alpha())
  914. return true;
  915. }
  916. return false;
  917. }
  918. int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_texture) {
  919. ERR_FAIL_COND_V(p_texture.is_null(), -1);
  920. Piece p;
  921. p.offset = p_offset;
  922. p.texture = p_texture;
  923. pieces.push_back(p);
  924. return pieces.size() - 1;
  925. }
  926. void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) {
  927. ERR_FAIL_INDEX(p_idx, pieces.size());
  928. pieces.write[p_idx].offset = p_offset;
  929. };
  930. void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture) {
  931. ERR_FAIL_COND(p_texture == this);
  932. ERR_FAIL_COND(p_texture.is_null());
  933. ERR_FAIL_INDEX(p_idx, pieces.size());
  934. pieces.write[p_idx].texture = p_texture;
  935. };
  936. void LargeTexture::set_size(const Size2 &p_size) {
  937. size = p_size;
  938. }
  939. void LargeTexture::clear() {
  940. pieces.clear();
  941. size = Size2i();
  942. }
  943. Array LargeTexture::_get_data() const {
  944. Array arr;
  945. for (int i = 0; i < pieces.size(); i++) {
  946. arr.push_back(pieces[i].offset);
  947. arr.push_back(pieces[i].texture);
  948. }
  949. arr.push_back(Size2(size));
  950. return arr;
  951. }
  952. void LargeTexture::_set_data(const Array &p_array) {
  953. ERR_FAIL_COND(p_array.size() < 1);
  954. ERR_FAIL_COND(!(p_array.size() & 1));
  955. clear();
  956. for (int i = 0; i < p_array.size() - 1; i += 2) {
  957. add_piece(p_array[i], p_array[i + 1]);
  958. }
  959. size = Size2(p_array[p_array.size() - 1]);
  960. }
  961. int LargeTexture::get_piece_count() const {
  962. return pieces.size();
  963. }
  964. Vector2 LargeTexture::get_piece_offset(int p_idx) const {
  965. ERR_FAIL_INDEX_V(p_idx, pieces.size(), Vector2());
  966. return pieces[p_idx].offset;
  967. }
  968. Ref<Texture2D> LargeTexture::get_piece_texture(int p_idx) const {
  969. ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture2D>());
  970. return pieces[p_idx].texture;
  971. }
  972. Ref<Image> LargeTexture::to_image() const {
  973. Ref<Image> img = memnew(Image(this->get_width(), this->get_height(), false, Image::FORMAT_RGBA8));
  974. for (int i = 0; i < pieces.size(); i++) {
  975. Ref<Image> src_img = pieces[i].texture->get_data();
  976. img->blit_rect(src_img, Rect2(0, 0, src_img->get_width(), src_img->get_height()), pieces[i].offset);
  977. }
  978. return img;
  979. }
  980. void LargeTexture::_bind_methods() {
  981. ClassDB::bind_method(D_METHOD("add_piece", "ofs", "texture"), &LargeTexture::add_piece);
  982. ClassDB::bind_method(D_METHOD("set_piece_offset", "idx", "ofs"), &LargeTexture::set_piece_offset);
  983. ClassDB::bind_method(D_METHOD("set_piece_texture", "idx", "texture"), &LargeTexture::set_piece_texture);
  984. ClassDB::bind_method(D_METHOD("set_size", "size"), &LargeTexture::set_size);
  985. ClassDB::bind_method(D_METHOD("clear"), &LargeTexture::clear);
  986. ClassDB::bind_method(D_METHOD("get_piece_count"), &LargeTexture::get_piece_count);
  987. ClassDB::bind_method(D_METHOD("get_piece_offset", "idx"), &LargeTexture::get_piece_offset);
  988. ClassDB::bind_method(D_METHOD("get_piece_texture", "idx"), &LargeTexture::get_piece_texture);
  989. ClassDB::bind_method(D_METHOD("_set_data", "data"), &LargeTexture::_set_data);
  990. ClassDB::bind_method(D_METHOD("_get_data"), &LargeTexture::_get_data);
  991. ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data");
  992. }
  993. void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  994. for (int i = 0; i < pieces.size(); i++) {
  995. // TODO
  996. pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  997. }
  998. }
  999. void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat) const {
  1000. //tiling not supported for this
  1001. if (size.x == 0 || size.y == 0)
  1002. return;
  1003. Size2 scale = p_rect.size / size;
  1004. for (int i = 0; i < pieces.size(); i++) {
  1005. // TODO
  1006. pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
  1007. }
  1008. }
  1009. void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, VS::CanvasItemTextureFilter p_texture_filter, VS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
  1010. //tiling not supported for this
  1011. if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0)
  1012. return;
  1013. Size2 scale = p_rect.size / p_src_rect.size;
  1014. for (int i = 0; i < pieces.size(); i++) {
  1015. // TODO
  1016. Rect2 rect(pieces[i].offset, pieces[i].texture->get_size());
  1017. if (!p_src_rect.intersects(rect))
  1018. continue;
  1019. Rect2 local = p_src_rect.clip(rect);
  1020. Rect2 target = local;
  1021. target.size *= scale;
  1022. target.position = p_rect.position + (p_src_rect.position + rect.position) * scale;
  1023. local.position -= rect.position;
  1024. pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat, false);
  1025. }
  1026. }
  1027. bool LargeTexture::is_pixel_opaque(int p_x, int p_y) const {
  1028. for (int i = 0; i < pieces.size(); i++) {
  1029. // TODO
  1030. if (!pieces[i].texture.is_valid())
  1031. continue;
  1032. Rect2 rect(pieces[i].offset, pieces[i].texture->get_size());
  1033. if (rect.has_point(Point2(p_x, p_y))) {
  1034. return pieces[i].texture->is_pixel_opaque(p_x - rect.position.x, p_y - rect.position.y);
  1035. }
  1036. }
  1037. return true;
  1038. }
  1039. LargeTexture::LargeTexture() {
  1040. }
  1041. ///////////////////
  1042. void CurveTexture::_bind_methods() {
  1043. ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width);
  1044. ClassDB::bind_method(D_METHOD("set_curve", "curve"), &CurveTexture::set_curve);
  1045. ClassDB::bind_method(D_METHOD("get_curve"), &CurveTexture::get_curve);
  1046. ClassDB::bind_method(D_METHOD("_update"), &CurveTexture::_update);
  1047. ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "32,4096"), "set_width", "get_width");
  1048. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
  1049. }
  1050. void CurveTexture::set_width(int p_width) {
  1051. ERR_FAIL_COND(p_width < 32 || p_width > 4096);
  1052. _width = p_width;
  1053. _update();
  1054. }
  1055. int CurveTexture::get_width() const {
  1056. return _width;
  1057. }
  1058. void CurveTexture::ensure_default_setup(float p_min, float p_max) {
  1059. if (_curve.is_null()) {
  1060. Ref<Curve> curve = Ref<Curve>(memnew(Curve));
  1061. curve->add_point(Vector2(0, 1));
  1062. curve->add_point(Vector2(1, 1));
  1063. curve->set_min_value(p_min);
  1064. curve->set_max_value(p_max);
  1065. set_curve(curve);
  1066. // Min and max is 0..1 by default
  1067. }
  1068. }
  1069. void CurveTexture::set_curve(Ref<Curve> p_curve) {
  1070. if (_curve != p_curve) {
  1071. if (_curve.is_valid()) {
  1072. _curve->disconnect(CoreStringNames::get_singleton()->changed, this, "_update");
  1073. }
  1074. _curve = p_curve;
  1075. if (_curve.is_valid()) {
  1076. _curve->connect(CoreStringNames::get_singleton()->changed, this, "_update");
  1077. }
  1078. _update();
  1079. }
  1080. }
  1081. void CurveTexture::_update() {
  1082. Vector<uint8_t> data;
  1083. data.resize(_width * sizeof(float));
  1084. // The array is locked in that scope
  1085. {
  1086. uint8_t *wd8 = data.ptrw();
  1087. float *wd = (float *)wd8;
  1088. if (_curve.is_valid()) {
  1089. Curve &curve = **_curve;
  1090. for (int i = 0; i < _width; ++i) {
  1091. float t = i / static_cast<float>(_width);
  1092. wd[i] = curve.interpolate_baked(t);
  1093. }
  1094. } else {
  1095. for (int i = 0; i < _width; ++i) {
  1096. wd[i] = 0;
  1097. }
  1098. }
  1099. }
  1100. Ref<Image> image = memnew(Image(_width, 1, false, Image::FORMAT_RF, data));
  1101. if (_texture.is_valid()) {
  1102. RID new_texture = VS::get_singleton()->texture_2d_create(image);
  1103. VS::get_singleton()->texture_replace(_texture, new_texture);
  1104. } else {
  1105. _texture = VS::get_singleton()->texture_2d_create(image);
  1106. }
  1107. emit_changed();
  1108. }
  1109. Ref<Curve> CurveTexture::get_curve() const {
  1110. return _curve;
  1111. }
  1112. RID CurveTexture::get_rid() const {
  1113. if (!_texture.is_valid()) {
  1114. _texture = VS::get_singleton()->texture_2d_placeholder_create();
  1115. }
  1116. return _texture;
  1117. }
  1118. CurveTexture::CurveTexture() {
  1119. _width = 2048;
  1120. }
  1121. CurveTexture::~CurveTexture() {
  1122. if (_texture.is_valid()) {
  1123. VS::get_singleton()->free(_texture);
  1124. }
  1125. }
  1126. //////////////////
  1127. //setter and getter names for property serialization
  1128. #define COLOR_RAMP_GET_OFFSETS "get_offsets"
  1129. #define COLOR_RAMP_GET_COLORS "get_colors"
  1130. #define COLOR_RAMP_SET_OFFSETS "set_offsets"
  1131. #define COLOR_RAMP_SET_COLORS "set_colors"
  1132. GradientTexture::GradientTexture() {
  1133. update_pending = false;
  1134. width = 2048;
  1135. _queue_update();
  1136. }
  1137. GradientTexture::~GradientTexture() {
  1138. if (texture.is_valid()) {
  1139. VS::get_singleton()->free(texture);
  1140. }
  1141. }
  1142. void GradientTexture::_bind_methods() {
  1143. ClassDB::bind_method(D_METHOD("set_gradient", "gradient"), &GradientTexture::set_gradient);
  1144. ClassDB::bind_method(D_METHOD("get_gradient"), &GradientTexture::get_gradient);
  1145. ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture::set_width);
  1146. ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update);
  1147. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
  1148. ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
  1149. }
  1150. void GradientTexture::set_gradient(Ref<Gradient> p_gradient) {
  1151. if (p_gradient == gradient)
  1152. return;
  1153. if (gradient.is_valid()) {
  1154. gradient->disconnect(CoreStringNames::get_singleton()->changed, this, "_update");
  1155. }
  1156. gradient = p_gradient;
  1157. if (gradient.is_valid()) {
  1158. gradient->connect(CoreStringNames::get_singleton()->changed, this, "_update");
  1159. }
  1160. _update();
  1161. emit_changed();
  1162. }
  1163. Ref<Gradient> GradientTexture::get_gradient() const {
  1164. return gradient;
  1165. }
  1166. void GradientTexture::_queue_update() {
  1167. if (update_pending)
  1168. return;
  1169. update_pending = true;
  1170. call_deferred("_update");
  1171. }
  1172. void GradientTexture::_update() {
  1173. update_pending = false;
  1174. if (gradient.is_null())
  1175. return;
  1176. Vector<uint8_t> data;
  1177. data.resize(width * 4);
  1178. {
  1179. uint8_t *wd8 = data.ptrw();
  1180. Gradient &g = **gradient;
  1181. for (int i = 0; i < width; i++) {
  1182. float ofs = float(i) / (width - 1);
  1183. Color color = g.get_color_at_offset(ofs);
  1184. wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255));
  1185. wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255));
  1186. wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255));
  1187. wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255));
  1188. }
  1189. }
  1190. Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
  1191. if (texture.is_valid()) {
  1192. RID new_texture = VS::get_singleton()->texture_2d_create(image);
  1193. VS::get_singleton()->texture_replace(texture, new_texture);
  1194. } else {
  1195. texture = VS::get_singleton()->texture_2d_create(image);
  1196. }
  1197. emit_changed();
  1198. }
  1199. void GradientTexture::set_width(int p_width) {
  1200. width = p_width;
  1201. _queue_update();
  1202. }
  1203. int GradientTexture::get_width() const {
  1204. return width;
  1205. }
  1206. Ref<Image> GradientTexture::get_data() const {
  1207. if (!texture.is_valid()) {
  1208. return Ref<Image>();
  1209. }
  1210. return VisualServer::get_singleton()->texture_2d_get(texture);
  1211. }
  1212. //////////////////////////////////////
  1213. void ProxyTexture::_bind_methods() {
  1214. ClassDB::bind_method(D_METHOD("set_base", "base"), &ProxyTexture::set_base);
  1215. ClassDB::bind_method(D_METHOD("get_base"), &ProxyTexture::get_base);
  1216. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base", "get_base");
  1217. }
  1218. void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) {
  1219. ERR_FAIL_COND(p_texture == this);
  1220. base = p_texture;
  1221. if (base.is_valid()) {
  1222. if (proxy_ph.is_valid()) {
  1223. VS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
  1224. VS::get_singleton()->free(proxy_ph);
  1225. proxy_ph = RID();
  1226. } else if (proxy.is_valid()) {
  1227. VS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
  1228. } else {
  1229. proxy = VS::get_singleton()->texture_proxy_create(base->get_rid());
  1230. }
  1231. }
  1232. }
  1233. Ref<Texture2D> ProxyTexture::get_base() const {
  1234. return base;
  1235. }
  1236. int ProxyTexture::get_width() const {
  1237. if (base.is_valid())
  1238. return base->get_width();
  1239. return 1;
  1240. }
  1241. int ProxyTexture::get_height() const {
  1242. if (base.is_valid())
  1243. return base->get_height();
  1244. return 1;
  1245. }
  1246. RID ProxyTexture::get_rid() const {
  1247. if (proxy.is_null()) {
  1248. proxy_ph = VS::get_singleton()->texture_2d_placeholder_create();
  1249. proxy = VS::get_singleton()->texture_proxy_create(proxy_ph);
  1250. }
  1251. return proxy;
  1252. }
  1253. bool ProxyTexture::has_alpha() const {
  1254. if (base.is_valid())
  1255. return base->has_alpha();
  1256. return false;
  1257. }
  1258. ProxyTexture::ProxyTexture() {
  1259. //proxy = VS::get_singleton()->texture_create();
  1260. }
  1261. ProxyTexture::~ProxyTexture() {
  1262. if (proxy_ph.is_valid()) {
  1263. VS::get_singleton()->free(proxy_ph);
  1264. }
  1265. if (proxy.is_valid()) {
  1266. VS::get_singleton()->free(proxy);
  1267. }
  1268. }
  1269. //////////////////////////////////////////////
  1270. void AnimatedTexture::_update_proxy() {
  1271. RWLockRead r(rw_lock);
  1272. float delta;
  1273. if (prev_ticks == 0) {
  1274. delta = 0;
  1275. prev_ticks = OS::get_singleton()->get_ticks_usec();
  1276. } else {
  1277. uint64_t ticks = OS::get_singleton()->get_ticks_usec();
  1278. delta = float(double(ticks - prev_ticks) / 1000000.0);
  1279. prev_ticks = ticks;
  1280. }
  1281. time += delta;
  1282. float limit;
  1283. if (fps == 0) {
  1284. limit = 0;
  1285. } else {
  1286. limit = 1.0 / fps;
  1287. }
  1288. int iter_max = frame_count;
  1289. while (iter_max) {
  1290. float frame_limit = limit + frames[current_frame].delay_sec;
  1291. if (time > frame_limit) {
  1292. current_frame++;
  1293. if (current_frame >= frame_count) {
  1294. current_frame = 0;
  1295. }
  1296. time -= frame_limit;
  1297. } else {
  1298. break;
  1299. }
  1300. iter_max--;
  1301. }
  1302. if (frames[current_frame].texture.is_valid()) {
  1303. VisualServer::get_singleton()->texture_proxy_update(proxy, frames[current_frame].texture->get_rid());
  1304. }
  1305. }
  1306. void AnimatedTexture::set_frames(int p_frames) {
  1307. ERR_FAIL_COND(p_frames < 1 || p_frames > MAX_FRAMES);
  1308. RWLockWrite r(rw_lock);
  1309. frame_count = p_frames;
  1310. }
  1311. int AnimatedTexture::get_frames() const {
  1312. return frame_count;
  1313. }
  1314. void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) {
  1315. ERR_FAIL_COND(p_texture == this);
  1316. ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
  1317. RWLockWrite w(rw_lock);
  1318. frames[p_frame].texture = p_texture;
  1319. }
  1320. Ref<Texture2D> AnimatedTexture::get_frame_texture(int p_frame) const {
  1321. ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture2D>());
  1322. RWLockRead r(rw_lock);
  1323. return frames[p_frame].texture;
  1324. }
  1325. void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) {
  1326. ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
  1327. RWLockRead r(rw_lock);
  1328. frames[p_frame].delay_sec = p_delay_sec;
  1329. }
  1330. float AnimatedTexture::get_frame_delay(int p_frame) const {
  1331. ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0);
  1332. RWLockRead r(rw_lock);
  1333. return frames[p_frame].delay_sec;
  1334. }
  1335. void AnimatedTexture::set_fps(float p_fps) {
  1336. ERR_FAIL_COND(p_fps < 0 || p_fps >= 1000);
  1337. fps = p_fps;
  1338. }
  1339. float AnimatedTexture::get_fps() const {
  1340. return fps;
  1341. }
  1342. int AnimatedTexture::get_width() const {
  1343. RWLockRead r(rw_lock);
  1344. if (!frames[current_frame].texture.is_valid()) {
  1345. return 1;
  1346. }
  1347. return frames[current_frame].texture->get_width();
  1348. }
  1349. int AnimatedTexture::get_height() const {
  1350. RWLockRead r(rw_lock);
  1351. if (!frames[current_frame].texture.is_valid()) {
  1352. return 1;
  1353. }
  1354. return frames[current_frame].texture->get_height();
  1355. }
  1356. RID AnimatedTexture::get_rid() const {
  1357. return proxy;
  1358. }
  1359. bool AnimatedTexture::has_alpha() const {
  1360. RWLockRead r(rw_lock);
  1361. if (!frames[current_frame].texture.is_valid()) {
  1362. return false;
  1363. }
  1364. return frames[current_frame].texture->has_alpha();
  1365. }
  1366. Ref<Image> AnimatedTexture::get_data() const {
  1367. RWLockRead r(rw_lock);
  1368. if (!frames[current_frame].texture.is_valid()) {
  1369. return Ref<Image>();
  1370. }
  1371. return frames[current_frame].texture->get_data();
  1372. }
  1373. bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
  1374. RWLockRead r(rw_lock);
  1375. if (frames[current_frame].texture.is_valid()) {
  1376. return frames[current_frame].texture->is_pixel_opaque(p_x, p_y);
  1377. }
  1378. return true;
  1379. }
  1380. void AnimatedTexture::_validate_property(PropertyInfo &property) const {
  1381. String prop = property.name;
  1382. if (prop.begins_with("frame_")) {
  1383. int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int();
  1384. if (frame >= frame_count) {
  1385. property.usage = 0;
  1386. }
  1387. }
  1388. }
  1389. void AnimatedTexture::_bind_methods() {
  1390. ClassDB::bind_method(D_METHOD("set_frames", "frames"), &AnimatedTexture::set_frames);
  1391. ClassDB::bind_method(D_METHOD("get_frames"), &AnimatedTexture::get_frames);
  1392. ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps);
  1393. ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps);
  1394. ClassDB::bind_method(D_METHOD("set_frame_texture", "frame", "texture"), &AnimatedTexture::set_frame_texture);
  1395. ClassDB::bind_method(D_METHOD("get_frame_texture", "frame"), &AnimatedTexture::get_frame_texture);
  1396. ClassDB::bind_method(D_METHOD("set_frame_delay", "frame", "delay"), &AnimatedTexture::set_frame_delay);
  1397. ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay);
  1398. ClassDB::bind_method(D_METHOD("_update_proxy"), &AnimatedTexture::_update_proxy);
  1399. ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames");
  1400. ADD_PROPERTY(PropertyInfo(Variant::REAL, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps");
  1401. for (int i = 0; i < MAX_FRAMES; i++) {
  1402. ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i);
  1403. ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i);
  1404. }
  1405. BIND_CONSTANT(MAX_FRAMES);
  1406. }
  1407. AnimatedTexture::AnimatedTexture() {
  1408. //proxy = VS::get_singleton()->texture_create();
  1409. proxy_ph = VS::get_singleton()->texture_2d_placeholder_create();
  1410. proxy = VS::get_singleton()->texture_proxy_create(proxy_ph);
  1411. VisualServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
  1412. time = 0;
  1413. frame_count = 1;
  1414. fps = 4;
  1415. prev_ticks = 0;
  1416. current_frame = 0;
  1417. VisualServer::get_singleton()->connect("frame_pre_draw", this, "_update_proxy");
  1418. #ifndef NO_THREADS
  1419. rw_lock = RWLock::create();
  1420. #else
  1421. rw_lock = NULL;
  1422. #endif
  1423. }
  1424. AnimatedTexture::~AnimatedTexture() {
  1425. VS::get_singleton()->free(proxy);
  1426. VS::get_singleton()->free(proxy_ph);
  1427. if (rw_lock) {
  1428. memdelete(rw_lock);
  1429. }
  1430. }
  1431. ///////////////////////////////
  1432. Image::Format TextureLayered::get_format() const {
  1433. return format;
  1434. }
  1435. uint32_t TextureLayered::get_width() const {
  1436. return width;
  1437. }
  1438. uint32_t TextureLayered::get_height() const {
  1439. return height;
  1440. }
  1441. uint32_t TextureLayered::get_layers() const {
  1442. return layers;
  1443. }
  1444. Error TextureLayered::_create_from_images(const Array &p_images) {
  1445. Vector<Ref<Image> > images;
  1446. for (int i = 0; i < p_images.size(); i++) {
  1447. Ref<Image> img = p_images[i];
  1448. ERR_FAIL_COND_V(img.is_null(), ERR_INVALID_PARAMETER);
  1449. images.push_back(img);
  1450. }
  1451. return create_from_images(images);
  1452. }
  1453. Array TextureLayered::_get_images() const {
  1454. Array images;
  1455. for (int i = 0; i < layers; i++) {
  1456. images.push_back(get_layer_data(i));
  1457. }
  1458. return images;
  1459. }
  1460. Error TextureLayered::create_from_images(Vector<Ref<Image> > p_images) {
  1461. int new_layers = p_images.size();
  1462. ERR_FAIL_COND_V(new_layers == 0, ERR_INVALID_PARAMETER);
  1463. if (layered_type == VS::TEXTURE_LAYERED_CUBEMAP) {
  1464. ERR_FAIL_COND_V_MSG(new_layers != 6, ERR_INVALID_PARAMETER,
  1465. "Cubemaps require exactly 6 layers");
  1466. } else if (layered_type == VS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {
  1467. ERR_FAIL_COND_V_MSG((new_layers % 6) != 0, ERR_INVALID_PARAMETER,
  1468. "Cubemap array layers must be a multiple of 6");
  1469. }
  1470. ERR_FAIL_COND_V(p_images[0].is_null() || p_images[0]->empty(), ERR_INVALID_PARAMETER);
  1471. Image::Format new_format = p_images[0]->get_format();
  1472. int new_width = p_images[0]->get_width();
  1473. int new_height = p_images[0]->get_height();
  1474. bool new_mipmaps = p_images[0]->has_mipmaps();
  1475. for (int i = 1; i < p_images.size(); i++) {
  1476. ERR_FAIL_COND_V_MSG(p_images[i]->get_format() != new_format, ERR_INVALID_PARAMETER,
  1477. "All images must share the same format");
  1478. ERR_FAIL_COND_V_MSG(p_images[i]->get_width() != new_width || p_images[i]->get_height() != new_height, ERR_INVALID_PARAMETER,
  1479. "All images must share the same dimensions");
  1480. ERR_FAIL_COND_V_MSG(p_images[i]->has_mipmaps() != new_mipmaps, ERR_INVALID_PARAMETER,
  1481. "All images must share the usage of mipmaps");
  1482. }
  1483. if (texture.is_valid()) {
  1484. RID new_texture = VS::get_singleton()->texture_2d_layered_create(p_images, layered_type);
  1485. ERR_FAIL_COND_V(!new_texture.is_valid(), ERR_CANT_CREATE);
  1486. VS::get_singleton()->texture_replace(texture, new_texture);
  1487. } else {
  1488. texture = VS::get_singleton()->texture_2d_layered_create(p_images, layered_type);
  1489. ERR_FAIL_COND_V(!texture.is_valid(), ERR_CANT_CREATE);
  1490. }
  1491. format = new_format;
  1492. width = new_width;
  1493. height = new_height;
  1494. layers = new_layers;
  1495. mipmaps = new_mipmaps;
  1496. return OK;
  1497. }
  1498. void TextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
  1499. ERR_FAIL_COND(texture.is_valid());
  1500. ERR_FAIL_COND(p_image.is_null());
  1501. ERR_FAIL_COND(p_image->get_format() != format);
  1502. ERR_FAIL_COND(p_image->get_width() != width || p_image->get_height() != height);
  1503. ERR_FAIL_INDEX(p_layer, layers);
  1504. ERR_FAIL_COND(p_image->has_mipmaps() != mipmaps);
  1505. VS::get_singleton()->texture_2d_update(texture, p_image, p_layer);
  1506. }
  1507. Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
  1508. ERR_FAIL_INDEX_V(p_layer, layers, Ref<Image>());
  1509. return VS::get_singleton()->texture_2d_layer_get(texture, p_layer);
  1510. }
  1511. RID TextureLayered::get_rid() const {
  1512. if (texture.is_null()) {
  1513. texture = VS::get_singleton()->texture_2d_layered_placeholder_create();
  1514. }
  1515. return texture;
  1516. }
  1517. void TextureLayered::set_path(const String &p_path, bool p_take_over) {
  1518. if (texture.is_valid()) {
  1519. VS::get_singleton()->texture_set_path(texture, p_path);
  1520. }
  1521. Resource::set_path(p_path, p_take_over);
  1522. }
  1523. void TextureLayered::_bind_methods() {
  1524. ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
  1525. ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width);
  1526. ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height);
  1527. ClassDB::bind_method(D_METHOD("get_layers"), &TextureLayered::get_layers);
  1528. ClassDB::bind_method(D_METHOD("create_from_images", "images"), &TextureLayered::_create_from_images);
  1529. ClassDB::bind_method(D_METHOD("update_layer", "image", "layer"), &TextureLayered::update_layer);
  1530. ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data);
  1531. ClassDB::bind_method(D_METHOD("_get_images"), &TextureLayered::_get_images);
  1532. ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images");
  1533. }
  1534. TextureLayered::TextureLayered(VisualServer::TextureLayeredType p_layered_type) {
  1535. layered_type = p_layered_type;
  1536. format = Image::FORMAT_MAX;
  1537. width = 0;
  1538. height = 0;
  1539. layers = 0;
  1540. }
  1541. TextureLayered::~TextureLayered() {
  1542. if (texture.is_valid()) {
  1543. VS::get_singleton()->free(texture);
  1544. }
  1545. }
  1546. RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error) {
  1547. if (r_error) {
  1548. *r_error = ERR_CANT_OPEN;
  1549. }
  1550. Ref<TextureLayered> lt;
  1551. if (p_path.ends_with("cube")) {
  1552. Ref<Cubemap> cube;
  1553. cube.instance();
  1554. lt = cube;
  1555. } else if (p_path.ends_with("cubearr")) {
  1556. Ref<CubemapArray> cubearr;
  1557. cubearr.instance();
  1558. lt = cubearr;
  1559. } else if (p_path.ends_with("tex2darr")) {
  1560. Ref<Texture2DArray> t2darr;
  1561. t2darr.instance();
  1562. lt = t2darr;
  1563. } else {
  1564. ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture extension.");
  1565. }
  1566. FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
  1567. ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");
  1568. char header[5] = { 0, 0, 0, 0, 0 };
  1569. f->get_buffer((uint8_t *)header, 4);
  1570. if (String(header) != "GDLT") {
  1571. f->close();
  1572. memdelete(f);
  1573. if (r_error) {
  1574. *r_error = ERR_FILE_CORRUPT;
  1575. }
  1576. // FIXME: It's bogus that we fail in both branches. Seen while rebasing
  1577. // vulkan branch on master branch.
  1578. ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture.");
  1579. } else {
  1580. f->close();
  1581. memdelete(f);
  1582. ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture file format '" + String((const char *)header) + "'.");
  1583. }
  1584. int tw = f->get_32();
  1585. int th = f->get_32();
  1586. int td = f->get_32();
  1587. bool use_mipmaps = f->get_32() != 0; //texture flags (deprecated)
  1588. Image::Format format = Image::Format(f->get_32());
  1589. uint32_t compression = f->get_32(); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
  1590. Vector<Ref<Image> > images;
  1591. for (int layer = 0; layer < td; layer++) {
  1592. Ref<Image> image;
  1593. image.instance();
  1594. if (compression == COMPRESSION_LOSSLESS) {
  1595. //look for a PNG file inside
  1596. int mipmaps = f->get_32();
  1597. Vector<Ref<Image> > mipmap_images;
  1598. for (int i = 0; i < mipmaps; i++) {
  1599. uint32_t size = f->get_32();
  1600. Vector<uint8_t> pv;
  1601. pv.resize(size);
  1602. {
  1603. uint8_t *w = pv.ptrw();
  1604. f->get_buffer(w, size);
  1605. }
  1606. Ref<Image> img = Image::lossless_unpacker(pv);
  1607. if (img.is_null() || img->empty() || format != img->get_format()) {
  1608. if (r_error) {
  1609. *r_error = ERR_FILE_CORRUPT;
  1610. }
  1611. f->close();
  1612. memdelete(f);
  1613. ERR_FAIL_V(RES());
  1614. }
  1615. mipmap_images.push_back(img);
  1616. }
  1617. if (mipmap_images.size() == 1) {
  1618. image = mipmap_images[0];
  1619. } else {
  1620. int total_size = Image::get_image_data_size(tw, th, format, true);
  1621. Vector<uint8_t> img_data;
  1622. img_data.resize(total_size);
  1623. {
  1624. uint8_t *w = img_data.ptrw();
  1625. int ofs = 0;
  1626. for (int i = 0; i < mipmap_images.size(); i++) {
  1627. Vector<uint8_t> id = mipmap_images[i]->get_data();
  1628. int len = id.size();
  1629. const uint8_t *r = id.ptr();
  1630. copymem(&w[ofs], r, len);
  1631. ofs += len;
  1632. }
  1633. }
  1634. image->create(tw, th, true, format, img_data);
  1635. if (image->empty()) {
  1636. if (r_error) {
  1637. *r_error = ERR_FILE_CORRUPT;
  1638. }
  1639. f->close();
  1640. memdelete(f);
  1641. ERR_FAIL_V(RES());
  1642. }
  1643. }
  1644. } else {
  1645. //look for regular format
  1646. int total_size = Image::get_image_data_size(tw, th, format, use_mipmaps);
  1647. Vector<uint8_t> img_data;
  1648. img_data.resize(total_size);
  1649. {
  1650. uint8_t *w = img_data.ptrw();
  1651. int bytes = f->get_buffer(w, total_size);
  1652. if (bytes != total_size) {
  1653. if (r_error) {
  1654. *r_error = ERR_FILE_CORRUPT;
  1655. }
  1656. f->close();
  1657. memdelete(f);
  1658. ERR_FAIL_V(RES());
  1659. }
  1660. }
  1661. image->create(tw, th, use_mipmaps, format, img_data);
  1662. }
  1663. images.push_back(image);
  1664. }
  1665. Error err = lt->create_from_images(images);
  1666. if (err != OK) {
  1667. *r_error = err;
  1668. return RES();
  1669. } else {
  1670. if (r_error)
  1671. *r_error = OK;
  1672. }
  1673. return lt;
  1674. }
  1675. void ResourceFormatLoaderTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
  1676. p_extensions->push_back("cube");
  1677. p_extensions->push_back("cubearr");
  1678. p_extensions->push_back("tex2darr");
  1679. }
  1680. bool ResourceFormatLoaderTextureLayered::handles_type(const String &p_type) const {
  1681. return p_type == "Texture2DArray" || p_type == "Cubemap" || p_type == "CubemapArray";
  1682. }
  1683. String ResourceFormatLoaderTextureLayered::get_resource_type(const String &p_path) const {
  1684. if (p_path.get_extension().to_lower() == "cube")
  1685. return "Cubemap";
  1686. if (p_path.get_extension().to_lower() == "cubearr")
  1687. return "CubemapArray";
  1688. if (p_path.get_extension().to_lower() == "tex2darr")
  1689. return "Texture2DArray";
  1690. return "";
  1691. }
  1692. ///////////////////////////////
  1693. void CameraTexture::_bind_methods() {
  1694. ClassDB::bind_method(D_METHOD("set_camera_feed_id", "feed_id"), &CameraTexture::set_camera_feed_id);
  1695. ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &CameraTexture::get_camera_feed_id);
  1696. ClassDB::bind_method(D_METHOD("set_which_feed", "which_feed"), &CameraTexture::set_which_feed);
  1697. ClassDB::bind_method(D_METHOD("get_which_feed"), &CameraTexture::get_which_feed);
  1698. ClassDB::bind_method(D_METHOD("set_camera_active", "active"), &CameraTexture::set_camera_active);
  1699. ClassDB::bind_method(D_METHOD("get_camera_active"), &CameraTexture::get_camera_active);
  1700. ADD_PROPERTY(PropertyInfo(Variant::INT, "camera_feed_id"), "set_camera_feed_id", "get_camera_feed_id");
  1701. ADD_PROPERTY(PropertyInfo(Variant::INT, "which_feed"), "set_which_feed", "get_which_feed");
  1702. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "camera_is_active"), "set_camera_active", "get_camera_active");
  1703. }
  1704. int CameraTexture::get_width() const {
  1705. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  1706. if (feed.is_valid()) {
  1707. return feed->get_base_width();
  1708. } else {
  1709. return 0;
  1710. }
  1711. }
  1712. int CameraTexture::get_height() const {
  1713. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  1714. if (feed.is_valid()) {
  1715. return feed->get_base_height();
  1716. } else {
  1717. return 0;
  1718. }
  1719. }
  1720. bool CameraTexture::has_alpha() const {
  1721. return false;
  1722. }
  1723. RID CameraTexture::get_rid() const {
  1724. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  1725. if (feed.is_valid()) {
  1726. return feed->get_texture(which_feed);
  1727. } else {
  1728. return RID();
  1729. }
  1730. }
  1731. void CameraTexture::set_flags(uint32_t p_flags) {
  1732. // not supported
  1733. }
  1734. uint32_t CameraTexture::get_flags() const {
  1735. // not supported
  1736. return 0;
  1737. }
  1738. Ref<Image> CameraTexture::get_data() const {
  1739. // not (yet) supported
  1740. return Ref<Image>();
  1741. }
  1742. void CameraTexture::set_camera_feed_id(int p_new_id) {
  1743. camera_feed_id = p_new_id;
  1744. _change_notify();
  1745. }
  1746. int CameraTexture::get_camera_feed_id() const {
  1747. return camera_feed_id;
  1748. }
  1749. void CameraTexture::set_which_feed(CameraServer::FeedImage p_which) {
  1750. which_feed = p_which;
  1751. _change_notify();
  1752. }
  1753. CameraServer::FeedImage CameraTexture::get_which_feed() const {
  1754. return which_feed;
  1755. }
  1756. void CameraTexture::set_camera_active(bool p_active) {
  1757. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  1758. if (feed.is_valid()) {
  1759. feed->set_active(p_active);
  1760. _change_notify();
  1761. }
  1762. }
  1763. bool CameraTexture::get_camera_active() const {
  1764. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  1765. if (feed.is_valid()) {
  1766. return feed->is_active();
  1767. } else {
  1768. return false;
  1769. }
  1770. }
  1771. CameraTexture::CameraTexture() {
  1772. camera_feed_id = 0;
  1773. which_feed = CameraServer::FEED_RGBA_IMAGE;
  1774. }
  1775. CameraTexture::~CameraTexture() {
  1776. // nothing to do here yet
  1777. }