texture.cpp 101 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535
  1. /*************************************************************************/
  2. /* texture.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2022 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/io/marshalls.h"
  34. #include "core/math/geometry_2d.h"
  35. #include "core/os/os.h"
  36. #include "scene/resources/bit_map.h"
  37. #include "scene/resources/mesh.h"
  38. #include "servers/camera/camera_feed.h"
  39. int Texture2D::get_width() const {
  40. int ret;
  41. if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) {
  42. return ret;
  43. }
  44. return 0;
  45. }
  46. int Texture2D::get_height() const {
  47. int ret;
  48. if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) {
  49. return ret;
  50. }
  51. return 0;
  52. }
  53. Size2 Texture2D::get_size() const {
  54. return Size2(get_width(), get_height());
  55. }
  56. bool Texture2D::is_pixel_opaque(int p_x, int p_y) const {
  57. bool ret;
  58. if (GDVIRTUAL_CALL(_is_pixel_opaque, p_x, p_y, ret)) {
  59. return ret;
  60. }
  61. return true;
  62. }
  63. bool Texture2D::has_alpha() const {
  64. bool ret;
  65. if (GDVIRTUAL_CALL(_has_alpha, ret)) {
  66. return ret;
  67. }
  68. return true;
  69. }
  70. void Texture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
  71. if (GDVIRTUAL_CALL(_draw, p_canvas_item, p_pos, p_modulate, p_transpose)) {
  72. return;
  73. }
  74. RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose);
  75. }
  76. void Texture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
  77. if (GDVIRTUAL_CALL(_draw_rect, p_canvas_item, p_rect, p_tile, p_modulate, p_transpose)) {
  78. return;
  79. }
  80. RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose);
  81. }
  82. 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, bool p_clip_uv) const {
  83. if (GDVIRTUAL_CALL(_draw_rect_region, p_canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_clip_uv)) {
  84. return;
  85. }
  86. RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, p_clip_uv);
  87. }
  88. bool Texture2D::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
  89. r_rect = p_rect;
  90. r_src_rect = p_src_rect;
  91. return true;
  92. }
  93. void Texture2D::_bind_methods() {
  94. ClassDB::bind_method(D_METHOD("get_width"), &Texture2D::get_width);
  95. ClassDB::bind_method(D_METHOD("get_height"), &Texture2D::get_height);
  96. ClassDB::bind_method(D_METHOD("get_size"), &Texture2D::get_size);
  97. ClassDB::bind_method(D_METHOD("has_alpha"), &Texture2D::has_alpha);
  98. ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose"), &Texture2D::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
  99. ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
  100. ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(true));
  101. ClassDB::bind_method(D_METHOD("get_image"), &Texture2D::get_image);
  102. ADD_GROUP("", "");
  103. GDVIRTUAL_BIND(_get_width);
  104. GDVIRTUAL_BIND(_get_height);
  105. GDVIRTUAL_BIND(_is_pixel_opaque, "x", "y");
  106. GDVIRTUAL_BIND(_has_alpha);
  107. GDVIRTUAL_BIND(_draw, "to_canvas_item", "pos", "modulate", "transpose")
  108. GDVIRTUAL_BIND(_draw_rect, "to_canvas_item", "rect", "tile", "modulate", "transpose")
  109. GDVIRTUAL_BIND(_draw_rect_region, "tp_canvas_item", "rect", "src_rect", "modulate", "transpose", "clip_uv");
  110. }
  111. Texture2D::Texture2D() {
  112. }
  113. /////////////////////
  114. void ImageTexture::reload_from_file() {
  115. String path = ResourceLoader::path_remap(get_path());
  116. if (!path.is_resource_file()) {
  117. return;
  118. }
  119. Ref<Image> img;
  120. img.instantiate();
  121. if (ImageLoader::load_image(path, img) == OK) {
  122. set_image(img);
  123. } else {
  124. Resource::reload_from_file();
  125. notify_property_list_changed();
  126. emit_changed();
  127. }
  128. }
  129. bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
  130. if (p_name == "image") {
  131. set_image(p_value);
  132. return true;
  133. }
  134. return false;
  135. }
  136. bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
  137. if (p_name == "image") {
  138. r_ret = get_image();
  139. return true;
  140. }
  141. return false;
  142. }
  143. void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
  144. p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("image"), PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
  145. }
  146. Ref<ImageTexture> ImageTexture::create_from_image(const Ref<Image> &p_image) {
  147. ERR_FAIL_COND_V_MSG(p_image.is_null() || p_image->is_empty(), Ref<ImageTexture>(), "Invalid image");
  148. Ref<ImageTexture> image_texture;
  149. image_texture.instantiate();
  150. image_texture->set_image(p_image);
  151. return image_texture;
  152. }
  153. void ImageTexture::set_image(const Ref<Image> &p_image) {
  154. ERR_FAIL_COND_MSG(p_image.is_null() || p_image->is_empty(), "Invalid image");
  155. w = p_image->get_width();
  156. h = p_image->get_height();
  157. format = p_image->get_format();
  158. mipmaps = p_image->has_mipmaps();
  159. if (texture.is_null()) {
  160. texture = RenderingServer::get_singleton()->texture_2d_create(p_image);
  161. } else {
  162. RID new_texture = RenderingServer::get_singleton()->texture_2d_create(p_image);
  163. RenderingServer::get_singleton()->texture_replace(texture, new_texture);
  164. }
  165. notify_property_list_changed();
  166. emit_changed();
  167. image_stored = true;
  168. }
  169. Image::Format ImageTexture::get_format() const {
  170. return format;
  171. }
  172. void ImageTexture::update(const Ref<Image> &p_image) {
  173. ERR_FAIL_COND_MSG(p_image.is_null(), "Invalid image");
  174. ERR_FAIL_COND_MSG(texture.is_null(), "Texture is not initialized.");
  175. ERR_FAIL_COND_MSG(p_image->get_width() != w || p_image->get_height() != h,
  176. "The new image dimensions must match the texture size.");
  177. ERR_FAIL_COND_MSG(p_image->get_format() != format,
  178. "The new image format must match the texture's image format.");
  179. ERR_FAIL_COND_MSG(mipmaps != p_image->has_mipmaps(),
  180. "The new image mipmaps configuration must match the texture's image mipmaps configuration");
  181. RS::get_singleton()->texture_2d_update(texture, p_image);
  182. notify_property_list_changed();
  183. emit_changed();
  184. alpha_cache.unref();
  185. image_stored = true;
  186. }
  187. Ref<Image> ImageTexture::get_image() const {
  188. if (image_stored) {
  189. return RenderingServer::get_singleton()->texture_2d_get(texture);
  190. } else {
  191. return Ref<Image>();
  192. }
  193. }
  194. int ImageTexture::get_width() const {
  195. return w;
  196. }
  197. int ImageTexture::get_height() const {
  198. return h;
  199. }
  200. RID ImageTexture::get_rid() const {
  201. if (texture.is_null()) {
  202. //we are in trouble, create something temporary
  203. texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();
  204. }
  205. return texture;
  206. }
  207. bool ImageTexture::has_alpha() const {
  208. return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8);
  209. }
  210. void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
  211. if ((w | h) == 0) {
  212. return;
  213. }
  214. RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose);
  215. }
  216. void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
  217. if ((w | h) == 0) {
  218. return;
  219. }
  220. RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose);
  221. }
  222. 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, bool p_clip_uv) const {
  223. if ((w | h) == 0) {
  224. return;
  225. }
  226. RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, p_clip_uv);
  227. }
  228. bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
  229. if (!alpha_cache.is_valid()) {
  230. Ref<Image> img = get_image();
  231. if (img.is_valid()) {
  232. if (img->is_compressed()) { //must decompress, if compressed
  233. Ref<Image> decom = img->duplicate();
  234. decom->decompress();
  235. img = decom;
  236. }
  237. alpha_cache.instantiate();
  238. alpha_cache->create_from_image_alpha(img);
  239. }
  240. }
  241. if (alpha_cache.is_valid()) {
  242. int aw = int(alpha_cache->get_size().width);
  243. int ah = int(alpha_cache->get_size().height);
  244. if (aw == 0 || ah == 0) {
  245. return true;
  246. }
  247. int x = p_x * aw / w;
  248. int y = p_y * ah / h;
  249. x = CLAMP(x, 0, aw);
  250. y = CLAMP(y, 0, ah);
  251. return alpha_cache->get_bit(Point2(x, y));
  252. }
  253. return true;
  254. }
  255. void ImageTexture::set_size_override(const Size2i &p_size) {
  256. Size2i s = p_size;
  257. if (s.x != 0) {
  258. w = s.x;
  259. }
  260. if (s.y != 0) {
  261. h = s.y;
  262. }
  263. RenderingServer::get_singleton()->texture_set_size_override(texture, w, h);
  264. }
  265. void ImageTexture::set_path(const String &p_path, bool p_take_over) {
  266. if (texture.is_valid()) {
  267. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  268. }
  269. Resource::set_path(p_path, p_take_over);
  270. }
  271. void ImageTexture::_bind_methods() {
  272. ClassDB::bind_static_method("ImageTexture", D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
  273. ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
  274. ClassDB::bind_method(D_METHOD("set_image", "image"), &ImageTexture::set_image);
  275. ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update);
  276. ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
  277. }
  278. ImageTexture::ImageTexture() {}
  279. ImageTexture::~ImageTexture() {
  280. if (texture.is_valid()) {
  281. RenderingServer::get_singleton()->free(texture);
  282. }
  283. }
  284. /////////////////////
  285. void PortableCompressedTexture2D::_set_data(const Vector<uint8_t> &p_data) {
  286. if (p_data.size() == 0) {
  287. return; //nothing to do
  288. }
  289. const uint8_t *data = p_data.ptr();
  290. uint32_t data_size = p_data.size();
  291. ERR_FAIL_COND(data_size < 20);
  292. compression_mode = CompressionMode(decode_uint32(data + 0));
  293. format = Image::Format(decode_uint32(data + 4));
  294. uint32_t mipmap_count = decode_uint32(data + 8);
  295. size.width = decode_uint32(data + 12);
  296. size.height = decode_uint32(data + 16);
  297. mipmaps = mipmap_count > 1;
  298. data += 20;
  299. data_size -= 20;
  300. Ref<Image> image;
  301. switch (compression_mode) {
  302. case COMPRESSION_MODE_LOSSLESS:
  303. case COMPRESSION_MODE_LOSSY: {
  304. Vector<uint8_t> image_data;
  305. ERR_FAIL_COND(data_size < 4);
  306. for (uint32_t i = 0; i < mipmap_count; i++) {
  307. uint32_t mipsize = decode_uint32(data);
  308. data += 4;
  309. data_size -= 4;
  310. ERR_FAIL_COND(mipsize < data_size);
  311. Ref<Image> img = memnew(Image(data, data_size));
  312. ERR_FAIL_COND(img->is_empty());
  313. if (img->get_format() != format) { // May happen due to webp/png in the tiny mipmaps.
  314. img->convert(format);
  315. }
  316. image_data.append_array(img->get_data());
  317. data += mipsize;
  318. data_size -= mipsize;
  319. }
  320. image = Ref<Image>(memnew(Image(size.width, size.height, mipmap_count > 1, format, image_data)));
  321. } break;
  322. case COMPRESSION_MODE_BASIS_UNIVERSAL: {
  323. ERR_FAIL_COND(!Image::basis_universal_unpacker_ptr);
  324. image = Image::basis_universal_unpacker_ptr(data, data_size);
  325. } break;
  326. case COMPRESSION_MODE_S3TC:
  327. case COMPRESSION_MODE_ETC2:
  328. case COMPRESSION_MODE_BPTC: {
  329. image = Ref<Image>(memnew(Image(size.width, size.height, mipmap_count > 1, format, p_data.slice(20))));
  330. } break;
  331. }
  332. ERR_FAIL_COND(image.is_null());
  333. if (texture.is_null()) {
  334. texture = RenderingServer::get_singleton()->texture_2d_create(image);
  335. } else {
  336. RID new_texture = RenderingServer::get_singleton()->texture_2d_create(image);
  337. RenderingServer::get_singleton()->texture_replace(texture, new_texture);
  338. }
  339. image_stored = true;
  340. RenderingServer::get_singleton()->texture_set_size_override(texture, size_override.width, size_override.height);
  341. alpha_cache.unref();
  342. if (keep_all_compressed_buffers || keep_compressed_buffer) {
  343. compressed_buffer = p_data;
  344. } else {
  345. compressed_buffer.clear();
  346. }
  347. }
  348. PortableCompressedTexture2D::CompressionMode PortableCompressedTexture2D::get_compression_mode() const {
  349. return compression_mode;
  350. }
  351. Vector<uint8_t> PortableCompressedTexture2D::_get_data() const {
  352. return compressed_buffer;
  353. }
  354. void PortableCompressedTexture2D::create_from_image(const Ref<Image> &p_image, CompressionMode p_compression_mode, bool p_normal_map, float p_lossy_quality) {
  355. ERR_FAIL_COND(p_image.is_null() || p_image->is_empty());
  356. Vector<uint8_t> buffer;
  357. buffer.resize(20);
  358. encode_uint32(p_compression_mode, buffer.ptrw());
  359. encode_uint32(p_image->get_format(), buffer.ptrw() + 4);
  360. encode_uint32(p_image->get_mipmap_count() + 1, buffer.ptrw() + 8);
  361. encode_uint32(p_image->get_width(), buffer.ptrw() + 12);
  362. encode_uint32(p_image->get_height(), buffer.ptrw() + 16);
  363. switch (p_compression_mode) {
  364. case COMPRESSION_MODE_LOSSLESS:
  365. case COMPRESSION_MODE_LOSSY: {
  366. for (int i = 0; i < p_image->get_mipmap_count() + 1; i++) {
  367. Vector<uint8_t> data;
  368. if (p_compression_mode == COMPRESSION_MODE_LOSSY) {
  369. data = Image::webp_lossy_packer(p_image->get_image_from_mipmap(i), p_lossy_quality);
  370. } else {
  371. data = Image::webp_lossless_packer(p_image->get_image_from_mipmap(i));
  372. }
  373. int data_len = data.size();
  374. buffer.resize(buffer.size() + 4);
  375. encode_uint32(data_len, buffer.ptrw() + buffer.size() - 4);
  376. buffer.append_array(data);
  377. }
  378. } break;
  379. case COMPRESSION_MODE_BASIS_UNIVERSAL: {
  380. Image::UsedChannels uc = p_image->detect_used_channels(p_normal_map ? Image::COMPRESS_SOURCE_NORMAL : Image::COMPRESS_SOURCE_GENERIC);
  381. Vector<uint8_t> budata = Image::basis_universal_packer(p_image, uc);
  382. buffer.append_array(budata);
  383. } break;
  384. case COMPRESSION_MODE_S3TC:
  385. case COMPRESSION_MODE_ETC2:
  386. case COMPRESSION_MODE_BPTC: {
  387. Ref<Image> copy = p_image->duplicate();
  388. switch (p_compression_mode) {
  389. case COMPRESSION_MODE_S3TC:
  390. copy->compress(Image::COMPRESS_S3TC);
  391. break;
  392. case COMPRESSION_MODE_ETC2:
  393. copy->compress(Image::COMPRESS_ETC2);
  394. break;
  395. case COMPRESSION_MODE_BPTC:
  396. copy->compress(Image::COMPRESS_BPTC);
  397. break;
  398. default: {
  399. };
  400. }
  401. buffer.append_array(copy->get_data());
  402. } break;
  403. }
  404. _set_data(buffer);
  405. }
  406. Image::Format PortableCompressedTexture2D::get_format() const {
  407. return format;
  408. }
  409. Ref<Image> PortableCompressedTexture2D::get_image() const {
  410. if (image_stored) {
  411. return RenderingServer::get_singleton()->texture_2d_get(texture);
  412. } else {
  413. return Ref<Image>();
  414. }
  415. }
  416. int PortableCompressedTexture2D::get_width() const {
  417. return size.width;
  418. }
  419. int PortableCompressedTexture2D::get_height() const {
  420. return size.height;
  421. }
  422. RID PortableCompressedTexture2D::get_rid() const {
  423. if (texture.is_null()) {
  424. //we are in trouble, create something temporary
  425. texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();
  426. }
  427. return texture;
  428. }
  429. bool PortableCompressedTexture2D::has_alpha() const {
  430. return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8);
  431. }
  432. void PortableCompressedTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
  433. if (size.width == 0 || size.height == 0) {
  434. return;
  435. }
  436. RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, size), texture, false, p_modulate, p_transpose);
  437. }
  438. void PortableCompressedTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
  439. if (size.width == 0 || size.height == 0) {
  440. return;
  441. }
  442. RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose);
  443. }
  444. void PortableCompressedTexture2D::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 {
  445. if (size.width == 0 || size.height == 0) {
  446. return;
  447. }
  448. RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, p_clip_uv);
  449. }
  450. bool PortableCompressedTexture2D::is_pixel_opaque(int p_x, int p_y) const {
  451. if (!alpha_cache.is_valid()) {
  452. Ref<Image> img = get_image();
  453. if (img.is_valid()) {
  454. if (img->is_compressed()) { //must decompress, if compressed
  455. Ref<Image> decom = img->duplicate();
  456. decom->decompress();
  457. img = decom;
  458. }
  459. alpha_cache.instantiate();
  460. alpha_cache->create_from_image_alpha(img);
  461. }
  462. }
  463. if (alpha_cache.is_valid()) {
  464. int aw = int(alpha_cache->get_size().width);
  465. int ah = int(alpha_cache->get_size().height);
  466. if (aw == 0 || ah == 0) {
  467. return true;
  468. }
  469. int x = p_x * aw / size.width;
  470. int y = p_y * ah / size.height;
  471. x = CLAMP(x, 0, aw);
  472. y = CLAMP(y, 0, ah);
  473. return alpha_cache->get_bit(Point2(x, y));
  474. }
  475. return true;
  476. }
  477. void PortableCompressedTexture2D::set_size_override(const Size2 &p_size) {
  478. size_override = p_size;
  479. RenderingServer::get_singleton()->texture_set_size_override(texture, size_override.width, size_override.height);
  480. }
  481. Size2 PortableCompressedTexture2D::get_size_override() const {
  482. return size_override;
  483. }
  484. void PortableCompressedTexture2D::set_path(const String &p_path, bool p_take_over) {
  485. if (texture.is_valid()) {
  486. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  487. }
  488. Resource::set_path(p_path, p_take_over);
  489. }
  490. bool PortableCompressedTexture2D::keep_all_compressed_buffers = false;
  491. void PortableCompressedTexture2D::set_keep_all_compressed_buffers(bool p_keep) {
  492. keep_all_compressed_buffers = p_keep;
  493. }
  494. bool PortableCompressedTexture2D::is_keeping_all_compressed_buffers() {
  495. return keep_all_compressed_buffers;
  496. }
  497. void PortableCompressedTexture2D::set_keep_compressed_buffer(bool p_keep) {
  498. keep_compressed_buffer = p_keep;
  499. if (!p_keep) {
  500. compressed_buffer.clear();
  501. }
  502. }
  503. bool PortableCompressedTexture2D::is_keeping_compressed_buffer() const {
  504. return keep_compressed_buffer;
  505. }
  506. void PortableCompressedTexture2D::_bind_methods() {
  507. ClassDB::bind_method(D_METHOD("create_from_image", "image", "compression_mode", "normal_map", "lossy_quality"), &PortableCompressedTexture2D::create_from_image, DEFVAL(false), DEFVAL(0.8));
  508. ClassDB::bind_method(D_METHOD("get_format"), &PortableCompressedTexture2D::get_format);
  509. ClassDB::bind_method(D_METHOD("get_compression_mode"), &PortableCompressedTexture2D::get_compression_mode);
  510. ClassDB::bind_method(D_METHOD("set_size_override", "size"), &PortableCompressedTexture2D::set_size_override);
  511. ClassDB::bind_method(D_METHOD("get_size_override"), &PortableCompressedTexture2D::get_size_override);
  512. ClassDB::bind_method(D_METHOD("set_keep_compressed_buffer", "keep"), &PortableCompressedTexture2D::set_keep_compressed_buffer);
  513. ClassDB::bind_method(D_METHOD("is_keeping_compressed_buffer"), &PortableCompressedTexture2D::is_keeping_compressed_buffer);
  514. ClassDB::bind_method(D_METHOD("_set_data", "data"), &PortableCompressedTexture2D::_set_data);
  515. ClassDB::bind_method(D_METHOD("_get_data"), &PortableCompressedTexture2D::_get_data);
  516. ClassDB::bind_static_method("PortableCompressedTexture2D", D_METHOD("set_keep_all_compressed_buffers", "keep"), &PortableCompressedTexture2D::set_keep_all_compressed_buffers);
  517. ClassDB::bind_static_method("PortableCompressedTexture2D", D_METHOD("is_keeping_all_compressed_buffers"), &PortableCompressedTexture2D::is_keeping_all_compressed_buffers);
  518. ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "_set_data", "_get_data");
  519. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size_override", PROPERTY_HINT_NONE, "suffix:px"), "set_size_override", "get_size_override");
  520. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_compressed_buffer"), "set_keep_compressed_buffer", "is_keeping_compressed_buffer");
  521. BIND_ENUM_CONSTANT(COMPRESSION_MODE_LOSSLESS);
  522. BIND_ENUM_CONSTANT(COMPRESSION_MODE_LOSSY);
  523. BIND_ENUM_CONSTANT(COMPRESSION_MODE_BASIS_UNIVERSAL);
  524. BIND_ENUM_CONSTANT(COMPRESSION_MODE_S3TC);
  525. BIND_ENUM_CONSTANT(COMPRESSION_MODE_ETC2);
  526. BIND_ENUM_CONSTANT(COMPRESSION_MODE_BPTC);
  527. }
  528. PortableCompressedTexture2D::PortableCompressedTexture2D() {}
  529. PortableCompressedTexture2D::~PortableCompressedTexture2D() {
  530. if (texture.is_valid()) {
  531. RenderingServer::get_singleton()->free(texture);
  532. }
  533. }
  534. //////////////////////////////////////////
  535. Ref<Image> CompressedTexture2D::load_image_from_file(Ref<FileAccess> f, int p_size_limit) {
  536. uint32_t data_format = f->get_32();
  537. uint32_t w = f->get_16();
  538. uint32_t h = f->get_16();
  539. uint32_t mipmaps = f->get_32();
  540. Image::Format format = Image::Format(f->get_32());
  541. if (data_format == DATA_FORMAT_PNG || data_format == DATA_FORMAT_WEBP || data_format == DATA_FORMAT_BASIS_UNIVERSAL) {
  542. //look for a PNG or WEBP file inside
  543. int sw = w;
  544. int sh = h;
  545. //mipmaps need to be read independently, they will be later combined
  546. Vector<Ref<Image>> mipmap_images;
  547. uint64_t total_size = 0;
  548. bool first = true;
  549. for (uint32_t i = 0; i < mipmaps + 1; i++) {
  550. uint32_t size = f->get_32();
  551. if (p_size_limit > 0 && i < (mipmaps - 1) && (sw > p_size_limit || sh > p_size_limit)) {
  552. //can't load this due to size limit
  553. sw = MAX(sw >> 1, 1);
  554. sh = MAX(sh >> 1, 1);
  555. f->seek(f->get_position() + size);
  556. continue;
  557. }
  558. Vector<uint8_t> pv;
  559. pv.resize(size);
  560. {
  561. uint8_t *wr = pv.ptrw();
  562. f->get_buffer(wr, size);
  563. }
  564. Ref<Image> img;
  565. if (data_format == DATA_FORMAT_BASIS_UNIVERSAL && Image::basis_universal_unpacker) {
  566. img = Image::basis_universal_unpacker(pv);
  567. } else if (data_format == DATA_FORMAT_PNG && Image::png_unpacker) {
  568. img = Image::png_unpacker(pv);
  569. } else if (data_format == DATA_FORMAT_WEBP && Image::webp_unpacker) {
  570. img = Image::webp_unpacker(pv);
  571. }
  572. if (img.is_null() || img->is_empty()) {
  573. ERR_FAIL_COND_V(img.is_null() || img->is_empty(), Ref<Image>());
  574. }
  575. if (first) {
  576. //format will actually be the format of the first image,
  577. //as it may have changed on compression
  578. format = img->get_format();
  579. first = false;
  580. } else if (img->get_format() != format) {
  581. img->convert(format); //all needs to be the same format
  582. }
  583. total_size += img->get_data().size();
  584. mipmap_images.push_back(img);
  585. sw = MAX(sw >> 1, 1);
  586. sh = MAX(sh >> 1, 1);
  587. }
  588. //print_line("mipmap read total: " + itos(mipmap_images.size()));
  589. Ref<Image> image;
  590. image.instantiate();
  591. if (mipmap_images.size() == 1) {
  592. //only one image (which will most likely be the case anyway for this format)
  593. image = mipmap_images[0];
  594. return image;
  595. } else {
  596. //rarer use case, but needs to be supported
  597. Vector<uint8_t> img_data;
  598. img_data.resize(total_size);
  599. {
  600. uint8_t *wr = img_data.ptrw();
  601. int ofs = 0;
  602. for (int i = 0; i < mipmap_images.size(); i++) {
  603. Vector<uint8_t> id = mipmap_images[i]->get_data();
  604. int len = id.size();
  605. const uint8_t *r = id.ptr();
  606. memcpy(&wr[ofs], r, len);
  607. ofs += len;
  608. }
  609. }
  610. image->create(w, h, true, mipmap_images[0]->get_format(), img_data);
  611. return image;
  612. }
  613. } else if (data_format == DATA_FORMAT_IMAGE) {
  614. int size = Image::get_image_data_size(w, h, format, mipmaps ? true : false);
  615. for (uint32_t i = 0; i < mipmaps + 1; i++) {
  616. int tw, th;
  617. int ofs = Image::get_image_mipmap_offset_and_dimensions(w, h, format, i, tw, th);
  618. if (p_size_limit > 0 && i < mipmaps && (p_size_limit > tw || p_size_limit > th)) {
  619. if (ofs) {
  620. f->seek(f->get_position() + ofs);
  621. }
  622. continue; //oops, size limit enforced, go to next
  623. }
  624. Vector<uint8_t> data;
  625. data.resize(size - ofs);
  626. {
  627. uint8_t *wr = data.ptrw();
  628. f->get_buffer(wr, data.size());
  629. }
  630. Ref<Image> image;
  631. image.instantiate();
  632. image->create(tw, th, mipmaps - i ? true : false, format, data);
  633. return image;
  634. }
  635. }
  636. return Ref<Image>();
  637. }
  638. void CompressedTexture2D::set_path(const String &p_path, bool p_take_over) {
  639. if (texture.is_valid()) {
  640. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  641. }
  642. Resource::set_path(p_path, p_take_over);
  643. }
  644. void CompressedTexture2D::_requested_3d(void *p_ud) {
  645. CompressedTexture2D *ct = (CompressedTexture2D *)p_ud;
  646. Ref<CompressedTexture2D> ctex(ct);
  647. ERR_FAIL_COND(!request_3d_callback);
  648. request_3d_callback(ctex);
  649. }
  650. void CompressedTexture2D::_requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel) {
  651. CompressedTexture2D *ct = (CompressedTexture2D *)p_ud;
  652. Ref<CompressedTexture2D> ctex(ct);
  653. ERR_FAIL_COND(!request_roughness_callback);
  654. request_roughness_callback(ctex, p_normal_path, p_roughness_channel);
  655. }
  656. void CompressedTexture2D::_requested_normal(void *p_ud) {
  657. CompressedTexture2D *ct = (CompressedTexture2D *)p_ud;
  658. Ref<CompressedTexture2D> ctex(ct);
  659. ERR_FAIL_COND(!request_normal_callback);
  660. request_normal_callback(ctex);
  661. }
  662. CompressedTexture2D::TextureFormatRequestCallback CompressedTexture2D::request_3d_callback = nullptr;
  663. CompressedTexture2D::TextureFormatRoughnessRequestCallback CompressedTexture2D::request_roughness_callback = nullptr;
  664. CompressedTexture2D::TextureFormatRequestCallback CompressedTexture2D::request_normal_callback = nullptr;
  665. Image::Format CompressedTexture2D::get_format() const {
  666. return format;
  667. }
  668. Error CompressedTexture2D::_load_data(const String &p_path, int &r_width, int &r_height, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) {
  669. alpha_cache.unref();
  670. ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
  671. Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
  672. ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, vformat("Unable to open file: %s.", p_path));
  673. uint8_t header[4];
  674. f->get_buffer(header, 4);
  675. if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != '2') {
  676. ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is corrupt (Bad header).");
  677. }
  678. uint32_t version = f->get_32();
  679. if (version > FORMAT_VERSION) {
  680. ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new.");
  681. }
  682. r_width = f->get_32();
  683. r_height = f->get_32();
  684. uint32_t df = f->get_32(); //data format
  685. //skip reserved
  686. mipmap_limit = int(f->get_32());
  687. //reserved
  688. f->get_32();
  689. f->get_32();
  690. f->get_32();
  691. #ifdef TOOLS_ENABLED
  692. r_request_3d = request_3d_callback && df & FORMAT_BIT_DETECT_3D;
  693. r_request_roughness = request_roughness_callback && df & FORMAT_BIT_DETECT_ROUGNESS;
  694. r_request_normal = request_normal_callback && df & FORMAT_BIT_DETECT_NORMAL;
  695. #else
  696. r_request_3d = false;
  697. r_request_roughness = false;
  698. r_request_normal = false;
  699. #endif
  700. if (!(df & FORMAT_BIT_STREAM)) {
  701. p_size_limit = 0;
  702. }
  703. image = load_image_from_file(f, p_size_limit);
  704. if (image.is_null() || image->is_empty()) {
  705. return ERR_CANT_OPEN;
  706. }
  707. return OK;
  708. }
  709. Error CompressedTexture2D::load(const String &p_path) {
  710. int lw, lh;
  711. Ref<Image> image;
  712. image.instantiate();
  713. bool request_3d;
  714. bool request_normal;
  715. bool request_roughness;
  716. int mipmap_limit;
  717. Error err = _load_data(p_path, lw, lh, image, request_3d, request_normal, request_roughness, mipmap_limit);
  718. if (err) {
  719. return err;
  720. }
  721. if (texture.is_valid()) {
  722. RID new_texture = RS::get_singleton()->texture_2d_create(image);
  723. RS::get_singleton()->texture_replace(texture, new_texture);
  724. } else {
  725. texture = RS::get_singleton()->texture_2d_create(image);
  726. }
  727. if (lw || lh) {
  728. RS::get_singleton()->texture_set_size_override(texture, lw, lh);
  729. }
  730. w = lw;
  731. h = lh;
  732. path_to_file = p_path;
  733. format = image->get_format();
  734. if (get_path().is_empty()) {
  735. //temporarily set path if no path set for resource, helps find errors
  736. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  737. }
  738. #ifdef TOOLS_ENABLED
  739. if (request_3d) {
  740. //print_line("request detect 3D at " + p_path);
  741. RS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this);
  742. } else {
  743. //print_line("not requesting detect 3D at " + p_path);
  744. RS::get_singleton()->texture_set_detect_3d_callback(texture, nullptr, nullptr);
  745. }
  746. if (request_roughness) {
  747. //print_line("request detect srgb at " + p_path);
  748. RS::get_singleton()->texture_set_detect_roughness_callback(texture, _requested_roughness, this);
  749. } else {
  750. //print_line("not requesting detect srgb at " + p_path);
  751. RS::get_singleton()->texture_set_detect_roughness_callback(texture, nullptr, nullptr);
  752. }
  753. if (request_normal) {
  754. //print_line("request detect srgb at " + p_path);
  755. RS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
  756. } else {
  757. //print_line("not requesting detect normal at " + p_path);
  758. RS::get_singleton()->texture_set_detect_normal_callback(texture, nullptr, nullptr);
  759. }
  760. #endif
  761. notify_property_list_changed();
  762. emit_changed();
  763. return OK;
  764. }
  765. String CompressedTexture2D::get_load_path() const {
  766. return path_to_file;
  767. }
  768. int CompressedTexture2D::get_width() const {
  769. return w;
  770. }
  771. int CompressedTexture2D::get_height() const {
  772. return h;
  773. }
  774. RID CompressedTexture2D::get_rid() const {
  775. if (!texture.is_valid()) {
  776. texture = RS::get_singleton()->texture_2d_placeholder_create();
  777. }
  778. return texture;
  779. }
  780. void CompressedTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
  781. if ((w | h) == 0) {
  782. return;
  783. }
  784. RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose);
  785. }
  786. void CompressedTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
  787. if ((w | h) == 0) {
  788. return;
  789. }
  790. RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose);
  791. }
  792. void CompressedTexture2D::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 {
  793. if ((w | h) == 0) {
  794. return;
  795. }
  796. RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, p_clip_uv);
  797. }
  798. bool CompressedTexture2D::has_alpha() const {
  799. return false;
  800. }
  801. Ref<Image> CompressedTexture2D::get_image() const {
  802. if (texture.is_valid()) {
  803. return RS::get_singleton()->texture_2d_get(texture);
  804. } else {
  805. return Ref<Image>();
  806. }
  807. }
  808. bool CompressedTexture2D::is_pixel_opaque(int p_x, int p_y) const {
  809. if (!alpha_cache.is_valid()) {
  810. Ref<Image> img = get_image();
  811. if (img.is_valid()) {
  812. if (img->is_compressed()) { //must decompress, if compressed
  813. Ref<Image> decom = img->duplicate();
  814. decom->decompress();
  815. img = decom;
  816. }
  817. alpha_cache.instantiate();
  818. alpha_cache->create_from_image_alpha(img);
  819. }
  820. }
  821. if (alpha_cache.is_valid()) {
  822. int aw = int(alpha_cache->get_size().width);
  823. int ah = int(alpha_cache->get_size().height);
  824. if (aw == 0 || ah == 0) {
  825. return true;
  826. }
  827. int x = p_x * aw / w;
  828. int y = p_y * ah / h;
  829. x = CLAMP(x, 0, aw);
  830. y = CLAMP(y, 0, ah);
  831. return alpha_cache->get_bit(Point2(x, y));
  832. }
  833. return true;
  834. }
  835. void CompressedTexture2D::reload_from_file() {
  836. String path = get_path();
  837. if (!path.is_resource_file()) {
  838. return;
  839. }
  840. path = ResourceLoader::path_remap(path); //remap for translation
  841. path = ResourceLoader::import_remap(path); //remap for import
  842. if (!path.is_resource_file()) {
  843. return;
  844. }
  845. load(path);
  846. }
  847. void CompressedTexture2D::_validate_property(PropertyInfo &p_property) const {
  848. }
  849. void CompressedTexture2D::_bind_methods() {
  850. ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTexture2D::load);
  851. ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTexture2D::get_load_path);
  852. ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path");
  853. }
  854. CompressedTexture2D::CompressedTexture2D() {}
  855. CompressedTexture2D::~CompressedTexture2D() {
  856. if (texture.is_valid()) {
  857. RS::get_singleton()->free(texture);
  858. }
  859. }
  860. Ref<Resource> ResourceFormatLoaderCompressedTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
  861. Ref<CompressedTexture2D> st;
  862. st.instantiate();
  863. Error err = st->load(p_path);
  864. if (r_error) {
  865. *r_error = err;
  866. }
  867. if (err != OK) {
  868. return Ref<Resource>();
  869. }
  870. return st;
  871. }
  872. void ResourceFormatLoaderCompressedTexture2D::get_recognized_extensions(List<String> *p_extensions) const {
  873. p_extensions->push_back("ctex");
  874. }
  875. bool ResourceFormatLoaderCompressedTexture2D::handles_type(const String &p_type) const {
  876. return p_type == "CompressedTexture2D";
  877. }
  878. String ResourceFormatLoaderCompressedTexture2D::get_resource_type(const String &p_path) const {
  879. if (p_path.get_extension().to_lower() == "ctex") {
  880. return "CompressedTexture2D";
  881. }
  882. return "";
  883. }
  884. ////////////////////////////////////
  885. TypedArray<Image> Texture3D::_get_datai() const {
  886. Vector<Ref<Image>> data = get_data();
  887. TypedArray<Image> ret;
  888. ret.resize(data.size());
  889. for (int i = 0; i < data.size(); i++) {
  890. ret[i] = data[i];
  891. }
  892. return ret;
  893. }
  894. Image::Format Texture3D::get_format() const {
  895. Image::Format ret;
  896. if (GDVIRTUAL_REQUIRED_CALL(_get_format, ret)) {
  897. return ret;
  898. }
  899. return Image::FORMAT_MAX;
  900. }
  901. int Texture3D::get_width() const {
  902. int ret;
  903. if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) {
  904. return ret;
  905. }
  906. return 0;
  907. }
  908. int Texture3D::get_height() const {
  909. int ret;
  910. if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) {
  911. return ret;
  912. }
  913. return 0;
  914. }
  915. int Texture3D::get_depth() const {
  916. int ret;
  917. if (GDVIRTUAL_REQUIRED_CALL(_get_depth, ret)) {
  918. return ret;
  919. }
  920. return 0;
  921. }
  922. bool Texture3D::has_mipmaps() const {
  923. bool ret;
  924. if (GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret)) {
  925. return ret;
  926. }
  927. return false;
  928. }
  929. Vector<Ref<Image>> Texture3D::get_data() const {
  930. TypedArray<Image> ret;
  931. if (GDVIRTUAL_REQUIRED_CALL(_get_data, ret)) {
  932. Vector<Ref<Image>> data;
  933. data.resize(ret.size());
  934. for (int i = 0; i < data.size(); i++) {
  935. data.write[i] = ret[i];
  936. }
  937. return data;
  938. }
  939. return Vector<Ref<Image>>();
  940. }
  941. void Texture3D::_bind_methods() {
  942. ClassDB::bind_method(D_METHOD("get_format"), &Texture3D::get_format);
  943. ClassDB::bind_method(D_METHOD("get_width"), &Texture3D::get_width);
  944. ClassDB::bind_method(D_METHOD("get_height"), &Texture3D::get_height);
  945. ClassDB::bind_method(D_METHOD("get_depth"), &Texture3D::get_depth);
  946. ClassDB::bind_method(D_METHOD("has_mipmaps"), &Texture3D::has_mipmaps);
  947. ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_datai);
  948. GDVIRTUAL_BIND(_get_format);
  949. GDVIRTUAL_BIND(_get_width);
  950. GDVIRTUAL_BIND(_get_height);
  951. GDVIRTUAL_BIND(_get_depth);
  952. GDVIRTUAL_BIND(_has_mipmaps);
  953. GDVIRTUAL_BIND(_get_data);
  954. }
  955. //////////////////////////////////////////
  956. Image::Format ImageTexture3D::get_format() const {
  957. return format;
  958. }
  959. int ImageTexture3D::get_width() const {
  960. return width;
  961. }
  962. int ImageTexture3D::get_height() const {
  963. return height;
  964. }
  965. int ImageTexture3D::get_depth() const {
  966. return depth;
  967. }
  968. bool ImageTexture3D::has_mipmaps() const {
  969. return mipmaps;
  970. }
  971. Error ImageTexture3D::_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data) {
  972. Vector<Ref<Image>> images;
  973. images.resize(p_data.size());
  974. for (int i = 0; i < images.size(); i++) {
  975. images.write[i] = p_data[i];
  976. }
  977. return create(p_format, p_width, p_height, p_depth, p_mipmaps, images);
  978. }
  979. void ImageTexture3D::_update(const TypedArray<Image> &p_data) {
  980. Vector<Ref<Image>> images;
  981. images.resize(p_data.size());
  982. for (int i = 0; i < images.size(); i++) {
  983. images.write[i] = p_data[i];
  984. }
  985. return update(images);
  986. }
  987. Error ImageTexture3D::create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {
  988. RID tex = RenderingServer::get_singleton()->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
  989. ERR_FAIL_COND_V(tex.is_null(), ERR_CANT_CREATE);
  990. if (texture.is_valid()) {
  991. RenderingServer::get_singleton()->texture_replace(texture, tex);
  992. }
  993. return OK;
  994. }
  995. void ImageTexture3D::update(const Vector<Ref<Image>> &p_data) {
  996. ERR_FAIL_COND(!texture.is_valid());
  997. RenderingServer::get_singleton()->texture_3d_update(texture, p_data);
  998. }
  999. Vector<Ref<Image>> ImageTexture3D::get_data() const {
  1000. ERR_FAIL_COND_V(!texture.is_valid(), Vector<Ref<Image>>());
  1001. return RS::get_singleton()->texture_3d_get(texture);
  1002. }
  1003. RID ImageTexture3D::get_rid() const {
  1004. if (!texture.is_valid()) {
  1005. texture = RS::get_singleton()->texture_3d_placeholder_create();
  1006. }
  1007. return texture;
  1008. }
  1009. void ImageTexture3D::set_path(const String &p_path, bool p_take_over) {
  1010. if (texture.is_valid()) {
  1011. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  1012. }
  1013. Resource::set_path(p_path, p_take_over);
  1014. }
  1015. void ImageTexture3D::_bind_methods() {
  1016. ClassDB::bind_method(D_METHOD("create", "format", "width", "height", "depth", "use_mipmaps", "data"), &ImageTexture3D::_create);
  1017. ClassDB::bind_method(D_METHOD("update", "data"), &ImageTexture3D::_update);
  1018. }
  1019. ImageTexture3D::ImageTexture3D() {
  1020. }
  1021. ImageTexture3D::~ImageTexture3D() {
  1022. if (texture.is_valid()) {
  1023. RS::get_singleton()->free(texture);
  1024. }
  1025. }
  1026. ////////////////////////////////////////////
  1027. void CompressedTexture3D::set_path(const String &p_path, bool p_take_over) {
  1028. if (texture.is_valid()) {
  1029. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  1030. }
  1031. Resource::set_path(p_path, p_take_over);
  1032. }
  1033. Image::Format CompressedTexture3D::get_format() const {
  1034. return format;
  1035. }
  1036. Error CompressedTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) {
  1037. Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
  1038. ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, vformat("Unable to open file: %s.", p_path));
  1039. uint8_t header[4];
  1040. f->get_buffer(header, 4);
  1041. ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L', ERR_FILE_UNRECOGNIZED);
  1042. //stored as compressed textures (used for lossless and lossy compression)
  1043. uint32_t version = f->get_32();
  1044. if (version > FORMAT_VERSION) {
  1045. ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new.");
  1046. }
  1047. r_depth = f->get_32(); //depth
  1048. f->get_32(); //ignored (mode)
  1049. f->get_32(); // ignored (data format)
  1050. f->get_32(); //ignored
  1051. int mipmaps = f->get_32();
  1052. f->get_32(); //ignored
  1053. f->get_32(); //ignored
  1054. r_mipmaps = mipmaps != 0;
  1055. r_data.clear();
  1056. for (int i = 0; i < (r_depth + mipmaps); i++) {
  1057. Ref<Image> image = CompressedTexture2D::load_image_from_file(f, 0);
  1058. ERR_FAIL_COND_V(image.is_null() || image->is_empty(), ERR_CANT_OPEN);
  1059. if (i == 0) {
  1060. r_format = image->get_format();
  1061. r_width = image->get_width();
  1062. r_height = image->get_height();
  1063. }
  1064. r_data.push_back(image);
  1065. }
  1066. return OK;
  1067. }
  1068. Error CompressedTexture3D::load(const String &p_path) {
  1069. Vector<Ref<Image>> data;
  1070. int tw, th, td;
  1071. Image::Format tfmt;
  1072. bool tmm;
  1073. Error err = _load_data(p_path, data, tfmt, tw, th, td, tmm);
  1074. if (err) {
  1075. return err;
  1076. }
  1077. if (texture.is_valid()) {
  1078. RID new_texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data);
  1079. RS::get_singleton()->texture_replace(texture, new_texture);
  1080. } else {
  1081. texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data);
  1082. }
  1083. w = tw;
  1084. h = th;
  1085. d = td;
  1086. mipmaps = tmm;
  1087. format = tfmt;
  1088. path_to_file = p_path;
  1089. if (get_path().is_empty()) {
  1090. //temporarily set path if no path set for resource, helps find errors
  1091. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  1092. }
  1093. notify_property_list_changed();
  1094. emit_changed();
  1095. return OK;
  1096. }
  1097. String CompressedTexture3D::get_load_path() const {
  1098. return path_to_file;
  1099. }
  1100. int CompressedTexture3D::get_width() const {
  1101. return w;
  1102. }
  1103. int CompressedTexture3D::get_height() const {
  1104. return h;
  1105. }
  1106. int CompressedTexture3D::get_depth() const {
  1107. return d;
  1108. }
  1109. bool CompressedTexture3D::has_mipmaps() const {
  1110. return mipmaps;
  1111. }
  1112. RID CompressedTexture3D::get_rid() const {
  1113. if (!texture.is_valid()) {
  1114. texture = RS::get_singleton()->texture_3d_placeholder_create();
  1115. }
  1116. return texture;
  1117. }
  1118. Vector<Ref<Image>> CompressedTexture3D::get_data() const {
  1119. if (texture.is_valid()) {
  1120. return RS::get_singleton()->texture_3d_get(texture);
  1121. } else {
  1122. return Vector<Ref<Image>>();
  1123. }
  1124. }
  1125. void CompressedTexture3D::reload_from_file() {
  1126. String path = get_path();
  1127. if (!path.is_resource_file()) {
  1128. return;
  1129. }
  1130. path = ResourceLoader::path_remap(path); //remap for translation
  1131. path = ResourceLoader::import_remap(path); //remap for import
  1132. if (!path.is_resource_file()) {
  1133. return;
  1134. }
  1135. load(path);
  1136. }
  1137. void CompressedTexture3D::_validate_property(PropertyInfo &p_property) const {
  1138. }
  1139. void CompressedTexture3D::_bind_methods() {
  1140. ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTexture3D::load);
  1141. ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTexture3D::get_load_path);
  1142. ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path");
  1143. }
  1144. CompressedTexture3D::CompressedTexture3D() {}
  1145. CompressedTexture3D::~CompressedTexture3D() {
  1146. if (texture.is_valid()) {
  1147. RS::get_singleton()->free(texture);
  1148. }
  1149. }
  1150. /////////////////////////////
  1151. Ref<Resource> ResourceFormatLoaderCompressedTexture3D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
  1152. Ref<CompressedTexture3D> st;
  1153. st.instantiate();
  1154. Error err = st->load(p_path);
  1155. if (r_error) {
  1156. *r_error = err;
  1157. }
  1158. if (err != OK) {
  1159. return Ref<Resource>();
  1160. }
  1161. return st;
  1162. }
  1163. void ResourceFormatLoaderCompressedTexture3D::get_recognized_extensions(List<String> *p_extensions) const {
  1164. p_extensions->push_back("ctex3d");
  1165. }
  1166. bool ResourceFormatLoaderCompressedTexture3D::handles_type(const String &p_type) const {
  1167. return p_type == "CompressedTexture3D";
  1168. }
  1169. String ResourceFormatLoaderCompressedTexture3D::get_resource_type(const String &p_path) const {
  1170. if (p_path.get_extension().to_lower() == "ctex3d") {
  1171. return "CompressedTexture3D";
  1172. }
  1173. return "";
  1174. }
  1175. ////////////////////////////////////////////
  1176. int AtlasTexture::get_width() const {
  1177. if (region.size.width == 0) {
  1178. if (atlas.is_valid()) {
  1179. return atlas->get_width();
  1180. }
  1181. return 1;
  1182. } else {
  1183. return region.size.width + margin.size.width;
  1184. }
  1185. }
  1186. int AtlasTexture::get_height() const {
  1187. if (region.size.height == 0) {
  1188. if (atlas.is_valid()) {
  1189. return atlas->get_height();
  1190. }
  1191. return 1;
  1192. } else {
  1193. return region.size.height + margin.size.height;
  1194. }
  1195. }
  1196. RID AtlasTexture::get_rid() const {
  1197. if (atlas.is_valid()) {
  1198. return atlas->get_rid();
  1199. }
  1200. return RID();
  1201. }
  1202. bool AtlasTexture::has_alpha() const {
  1203. if (atlas.is_valid()) {
  1204. return atlas->has_alpha();
  1205. }
  1206. return false;
  1207. }
  1208. void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) {
  1209. ERR_FAIL_COND(p_atlas == this);
  1210. if (atlas == p_atlas) {
  1211. return;
  1212. }
  1213. atlas = p_atlas;
  1214. emit_changed();
  1215. }
  1216. Ref<Texture2D> AtlasTexture::get_atlas() const {
  1217. return atlas;
  1218. }
  1219. void AtlasTexture::set_region(const Rect2 &p_region) {
  1220. if (region == p_region) {
  1221. return;
  1222. }
  1223. region = p_region;
  1224. emit_changed();
  1225. }
  1226. Rect2 AtlasTexture::get_region() const {
  1227. return region;
  1228. }
  1229. void AtlasTexture::set_margin(const Rect2 &p_margin) {
  1230. if (margin == p_margin) {
  1231. return;
  1232. }
  1233. margin = p_margin;
  1234. emit_changed();
  1235. }
  1236. Rect2 AtlasTexture::get_margin() const {
  1237. return margin;
  1238. }
  1239. void AtlasTexture::set_filter_clip(const bool p_enable) {
  1240. filter_clip = p_enable;
  1241. emit_changed();
  1242. }
  1243. bool AtlasTexture::has_filter_clip() const {
  1244. return filter_clip;
  1245. }
  1246. void AtlasTexture::_bind_methods() {
  1247. ClassDB::bind_method(D_METHOD("set_atlas", "atlas"), &AtlasTexture::set_atlas);
  1248. ClassDB::bind_method(D_METHOD("get_atlas"), &AtlasTexture::get_atlas);
  1249. ClassDB::bind_method(D_METHOD("set_region", "region"), &AtlasTexture::set_region);
  1250. ClassDB::bind_method(D_METHOD("get_region"), &AtlasTexture::get_region);
  1251. ClassDB::bind_method(D_METHOD("set_margin", "margin"), &AtlasTexture::set_margin);
  1252. ClassDB::bind_method(D_METHOD("get_margin"), &AtlasTexture::get_margin);
  1253. ClassDB::bind_method(D_METHOD("set_filter_clip", "enable"), &AtlasTexture::set_filter_clip);
  1254. ClassDB::bind_method(D_METHOD("has_filter_clip"), &AtlasTexture::has_filter_clip);
  1255. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_atlas", "get_atlas");
  1256. ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region", PROPERTY_HINT_NONE, "suffix:px"), "set_region", "get_region");
  1257. ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin", PROPERTY_HINT_NONE, "suffix:px"), "set_margin", "get_margin");
  1258. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_clip"), "set_filter_clip", "has_filter_clip");
  1259. }
  1260. void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
  1261. if (!atlas.is_valid()) {
  1262. return;
  1263. }
  1264. Rect2 rc = region;
  1265. if (rc.size.width == 0) {
  1266. rc.size.width = atlas->get_width();
  1267. }
  1268. if (rc.size.height == 0) {
  1269. rc.size.height = atlas->get_height();
  1270. }
  1271. atlas->draw_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), rc, p_modulate, p_transpose, filter_clip);
  1272. }
  1273. void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
  1274. if (!atlas.is_valid()) {
  1275. return;
  1276. }
  1277. Rect2 rc = region;
  1278. if (rc.size.width == 0) {
  1279. rc.size.width = atlas->get_width();
  1280. }
  1281. if (rc.size.height == 0) {
  1282. rc.size.height = atlas->get_height();
  1283. }
  1284. Vector2 scale = p_rect.size / (region.size + margin.size);
  1285. Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale);
  1286. atlas->draw_rect_region(p_canvas_item, dr, rc, p_modulate, p_transpose, filter_clip);
  1287. }
  1288. 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, bool p_clip_uv) const {
  1289. //this might not necessarily work well if using a rect, needs to be fixed properly
  1290. if (!atlas.is_valid()) {
  1291. return;
  1292. }
  1293. Rect2 dr;
  1294. Rect2 src_c;
  1295. get_rect_region(p_rect, p_src_rect, dr, src_c);
  1296. atlas->draw_rect_region(p_canvas_item, dr, src_c, p_modulate, p_transpose, filter_clip);
  1297. }
  1298. bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
  1299. if (!atlas.is_valid()) {
  1300. return false;
  1301. }
  1302. Rect2 rc = region;
  1303. Rect2 src = p_src_rect;
  1304. if (src.size == Size2()) {
  1305. src.size = rc.size;
  1306. }
  1307. Vector2 scale = p_rect.size / src.size;
  1308. src.position += (rc.position - margin.position);
  1309. Rect2 src_c = rc.intersection(src);
  1310. if (src_c.size == Size2()) {
  1311. return false;
  1312. }
  1313. Vector2 ofs = (src_c.position - src.position);
  1314. if (scale.x < 0) {
  1315. float mx = (margin.size.width - margin.position.x);
  1316. mx -= margin.position.x;
  1317. ofs.x = -(ofs.x + mx);
  1318. }
  1319. if (scale.y < 0) {
  1320. float my = margin.size.height - margin.position.y;
  1321. my -= margin.position.y;
  1322. ofs.y = -(ofs.y + my);
  1323. }
  1324. Rect2 dr(p_rect.position + ofs * scale, src_c.size * scale);
  1325. r_rect = dr;
  1326. r_src_rect = src_c;
  1327. return true;
  1328. }
  1329. bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
  1330. if (!atlas.is_valid()) {
  1331. return true;
  1332. }
  1333. int x = p_x + region.position.x - margin.position.x;
  1334. int y = p_y + region.position.y - margin.position.y;
  1335. // margin edge may outside of atlas
  1336. if (x < 0 || x >= atlas->get_width()) {
  1337. return false;
  1338. }
  1339. if (y < 0 || y >= atlas->get_height()) {
  1340. return false;
  1341. }
  1342. return atlas->is_pixel_opaque(x, y);
  1343. }
  1344. Ref<Image> AtlasTexture::get_image() const {
  1345. if (!atlas.is_valid() || !atlas->get_image().is_valid()) {
  1346. return Ref<Image>();
  1347. }
  1348. return atlas->get_image()->get_rect(region);
  1349. }
  1350. AtlasTexture::AtlasTexture() {}
  1351. /////////////////////////////////////////
  1352. int MeshTexture::get_width() const {
  1353. return size.width;
  1354. }
  1355. int MeshTexture::get_height() const {
  1356. return size.height;
  1357. }
  1358. RID MeshTexture::get_rid() const {
  1359. return RID();
  1360. }
  1361. bool MeshTexture::has_alpha() const {
  1362. return false;
  1363. }
  1364. void MeshTexture::set_mesh(const Ref<Mesh> &p_mesh) {
  1365. mesh = p_mesh;
  1366. }
  1367. Ref<Mesh> MeshTexture::get_mesh() const {
  1368. return mesh;
  1369. }
  1370. void MeshTexture::set_image_size(const Size2 &p_size) {
  1371. size = p_size;
  1372. }
  1373. Size2 MeshTexture::get_image_size() const {
  1374. return size;
  1375. }
  1376. void MeshTexture::set_base_texture(const Ref<Texture2D> &p_texture) {
  1377. base_texture = p_texture;
  1378. }
  1379. Ref<Texture2D> MeshTexture::get_base_texture() const {
  1380. return base_texture;
  1381. }
  1382. void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
  1383. if (mesh.is_null() || base_texture.is_null()) {
  1384. return;
  1385. }
  1386. Transform2D xform;
  1387. xform.set_origin(p_pos);
  1388. if (p_transpose) {
  1389. SWAP(xform.columns[0][1], xform.columns[1][0]);
  1390. SWAP(xform.columns[0][0], xform.columns[1][1]);
  1391. }
  1392. RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid());
  1393. }
  1394. void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
  1395. if (mesh.is_null() || base_texture.is_null()) {
  1396. return;
  1397. }
  1398. Transform2D xform;
  1399. Vector2 origin = p_rect.position;
  1400. if (p_rect.size.x < 0) {
  1401. origin.x += size.x;
  1402. }
  1403. if (p_rect.size.y < 0) {
  1404. origin.y += size.y;
  1405. }
  1406. xform.set_origin(origin);
  1407. xform.set_scale(p_rect.size / size);
  1408. if (p_transpose) {
  1409. SWAP(xform.columns[0][1], xform.columns[1][0]);
  1410. SWAP(xform.columns[0][0], xform.columns[1][1]);
  1411. }
  1412. RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid());
  1413. }
  1414. 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, bool p_clip_uv) const {
  1415. if (mesh.is_null() || base_texture.is_null()) {
  1416. return;
  1417. }
  1418. Transform2D xform;
  1419. Vector2 origin = p_rect.position;
  1420. if (p_rect.size.x < 0) {
  1421. origin.x += size.x;
  1422. }
  1423. if (p_rect.size.y < 0) {
  1424. origin.y += size.y;
  1425. }
  1426. xform.set_origin(origin);
  1427. xform.set_scale(p_rect.size / size);
  1428. if (p_transpose) {
  1429. SWAP(xform.columns[0][1], xform.columns[1][0]);
  1430. SWAP(xform.columns[0][0], xform.columns[1][1]);
  1431. }
  1432. RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid());
  1433. }
  1434. bool MeshTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
  1435. r_rect = p_rect;
  1436. r_src_rect = p_src_rect;
  1437. return true;
  1438. }
  1439. bool MeshTexture::is_pixel_opaque(int p_x, int p_y) const {
  1440. return true;
  1441. }
  1442. void MeshTexture::_bind_methods() {
  1443. ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshTexture::set_mesh);
  1444. ClassDB::bind_method(D_METHOD("get_mesh"), &MeshTexture::get_mesh);
  1445. ClassDB::bind_method(D_METHOD("set_image_size", "size"), &MeshTexture::set_image_size);
  1446. ClassDB::bind_method(D_METHOD("get_image_size"), &MeshTexture::get_image_size);
  1447. ClassDB::bind_method(D_METHOD("set_base_texture", "texture"), &MeshTexture::set_base_texture);
  1448. ClassDB::bind_method(D_METHOD("get_base_texture"), &MeshTexture::get_base_texture);
  1449. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
  1450. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_base_texture", "get_base_texture");
  1451. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "image_size", PROPERTY_HINT_RANGE, "0,16384,1,suffix:px"), "set_image_size", "get_image_size");
  1452. }
  1453. MeshTexture::MeshTexture() {
  1454. }
  1455. //////////////////////////////////////////
  1456. void CurveTexture::_bind_methods() {
  1457. ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width);
  1458. ClassDB::bind_method(D_METHOD("set_curve", "curve"), &CurveTexture::set_curve);
  1459. ClassDB::bind_method(D_METHOD("get_curve"), &CurveTexture::get_curve);
  1460. ClassDB::bind_method(D_METHOD("set_texture_mode", "texture_mode"), &CurveTexture::set_texture_mode);
  1461. ClassDB::bind_method(D_METHOD("get_texture_mode"), &CurveTexture::get_texture_mode);
  1462. ClassDB::bind_method(D_METHOD("_update"), &CurveTexture::_update);
  1463. ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096,suffix:px"), "set_width", "get_width");
  1464. ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "RGB,Red"), "set_texture_mode", "get_texture_mode");
  1465. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve", "get_curve");
  1466. BIND_ENUM_CONSTANT(TEXTURE_MODE_RGB);
  1467. BIND_ENUM_CONSTANT(TEXTURE_MODE_RED);
  1468. }
  1469. void CurveTexture::set_width(int p_width) {
  1470. ERR_FAIL_COND(p_width < 32 || p_width > 4096);
  1471. if (_width == p_width) {
  1472. return;
  1473. }
  1474. _width = p_width;
  1475. _update();
  1476. }
  1477. int CurveTexture::get_width() const {
  1478. return _width;
  1479. }
  1480. void CurveTexture::ensure_default_setup(float p_min, float p_max) {
  1481. if (_curve.is_null()) {
  1482. Ref<Curve> curve = Ref<Curve>(memnew(Curve));
  1483. curve->add_point(Vector2(0, 1));
  1484. curve->add_point(Vector2(1, 1));
  1485. curve->set_min_value(p_min);
  1486. curve->set_max_value(p_max);
  1487. set_curve(curve);
  1488. // Min and max is 0..1 by default
  1489. }
  1490. }
  1491. void CurveTexture::set_curve(Ref<Curve> p_curve) {
  1492. if (_curve != p_curve) {
  1493. if (_curve.is_valid()) {
  1494. _curve->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveTexture::_update));
  1495. }
  1496. _curve = p_curve;
  1497. if (_curve.is_valid()) {
  1498. _curve->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveTexture::_update));
  1499. }
  1500. _update();
  1501. }
  1502. }
  1503. void CurveTexture::_update() {
  1504. Vector<uint8_t> data;
  1505. data.resize(_width * sizeof(float) * (texture_mode == TEXTURE_MODE_RGB ? 3 : 1));
  1506. // The array is locked in that scope
  1507. {
  1508. uint8_t *wd8 = data.ptrw();
  1509. float *wd = (float *)wd8;
  1510. if (_curve.is_valid()) {
  1511. Curve &curve = **_curve;
  1512. for (int i = 0; i < _width; ++i) {
  1513. float t = i / static_cast<float>(_width);
  1514. if (texture_mode == TEXTURE_MODE_RGB) {
  1515. wd[i * 3 + 0] = curve.sample_baked(t);
  1516. wd[i * 3 + 1] = wd[i * 3 + 0];
  1517. wd[i * 3 + 2] = wd[i * 3 + 0];
  1518. } else {
  1519. wd[i] = curve.sample_baked(t);
  1520. }
  1521. }
  1522. } else {
  1523. for (int i = 0; i < _width; ++i) {
  1524. if (texture_mode == TEXTURE_MODE_RGB) {
  1525. wd[i * 3 + 0] = 0;
  1526. wd[i * 3 + 1] = 0;
  1527. wd[i * 3 + 2] = 0;
  1528. } else {
  1529. wd[i] = 0;
  1530. }
  1531. }
  1532. }
  1533. }
  1534. Ref<Image> image = memnew(Image(_width, 1, false, texture_mode == TEXTURE_MODE_RGB ? Image::FORMAT_RGBF : Image::FORMAT_RF, data));
  1535. if (_texture.is_valid()) {
  1536. if (_current_texture_mode != texture_mode || _current_width != _width) {
  1537. RID new_texture = RS::get_singleton()->texture_2d_create(image);
  1538. RS::get_singleton()->texture_replace(_texture, new_texture);
  1539. } else {
  1540. RS::get_singleton()->texture_2d_update(_texture, image);
  1541. }
  1542. } else {
  1543. _texture = RS::get_singleton()->texture_2d_create(image);
  1544. }
  1545. _current_texture_mode = texture_mode;
  1546. _current_width = _width;
  1547. emit_changed();
  1548. }
  1549. Ref<Curve> CurveTexture::get_curve() const {
  1550. return _curve;
  1551. }
  1552. void CurveTexture::set_texture_mode(TextureMode p_mode) {
  1553. ERR_FAIL_COND(p_mode < TEXTURE_MODE_RGB || p_mode > TEXTURE_MODE_RED);
  1554. if (texture_mode == p_mode) {
  1555. return;
  1556. }
  1557. texture_mode = p_mode;
  1558. _update();
  1559. }
  1560. CurveTexture::TextureMode CurveTexture::get_texture_mode() const {
  1561. return texture_mode;
  1562. }
  1563. RID CurveTexture::get_rid() const {
  1564. if (!_texture.is_valid()) {
  1565. _texture = RS::get_singleton()->texture_2d_placeholder_create();
  1566. }
  1567. return _texture;
  1568. }
  1569. CurveTexture::CurveTexture() {}
  1570. CurveTexture::~CurveTexture() {
  1571. if (_texture.is_valid()) {
  1572. RS::get_singleton()->free(_texture);
  1573. }
  1574. }
  1575. //////////////////
  1576. void CurveXYZTexture::_bind_methods() {
  1577. ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveXYZTexture::set_width);
  1578. ClassDB::bind_method(D_METHOD("set_curve_x", "curve"), &CurveXYZTexture::set_curve_x);
  1579. ClassDB::bind_method(D_METHOD("get_curve_x"), &CurveXYZTexture::get_curve_x);
  1580. ClassDB::bind_method(D_METHOD("set_curve_y", "curve"), &CurveXYZTexture::set_curve_y);
  1581. ClassDB::bind_method(D_METHOD("get_curve_y"), &CurveXYZTexture::get_curve_y);
  1582. ClassDB::bind_method(D_METHOD("set_curve_z", "curve"), &CurveXYZTexture::set_curve_z);
  1583. ClassDB::bind_method(D_METHOD("get_curve_z"), &CurveXYZTexture::get_curve_z);
  1584. ClassDB::bind_method(D_METHOD("_update"), &CurveXYZTexture::_update);
  1585. ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096,suffix:px"), "set_width", "get_width");
  1586. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_x", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_x", "get_curve_x");
  1587. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_y", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_y", "get_curve_y");
  1588. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "curve_z", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_curve_z", "get_curve_z");
  1589. }
  1590. void CurveXYZTexture::set_width(int p_width) {
  1591. ERR_FAIL_COND(p_width < 32 || p_width > 4096);
  1592. if (_width == p_width) {
  1593. return;
  1594. }
  1595. _width = p_width;
  1596. _update();
  1597. }
  1598. int CurveXYZTexture::get_width() const {
  1599. return _width;
  1600. }
  1601. void CurveXYZTexture::ensure_default_setup(float p_min, float p_max) {
  1602. if (_curve_x.is_null()) {
  1603. Ref<Curve> curve = Ref<Curve>(memnew(Curve));
  1604. curve->add_point(Vector2(0, 1));
  1605. curve->add_point(Vector2(1, 1));
  1606. curve->set_min_value(p_min);
  1607. curve->set_max_value(p_max);
  1608. set_curve_x(curve);
  1609. }
  1610. if (_curve_y.is_null()) {
  1611. Ref<Curve> curve = Ref<Curve>(memnew(Curve));
  1612. curve->add_point(Vector2(0, 1));
  1613. curve->add_point(Vector2(1, 1));
  1614. curve->set_min_value(p_min);
  1615. curve->set_max_value(p_max);
  1616. set_curve_y(curve);
  1617. }
  1618. if (_curve_z.is_null()) {
  1619. Ref<Curve> curve = Ref<Curve>(memnew(Curve));
  1620. curve->add_point(Vector2(0, 1));
  1621. curve->add_point(Vector2(1, 1));
  1622. curve->set_min_value(p_min);
  1623. curve->set_max_value(p_max);
  1624. set_curve_z(curve);
  1625. }
  1626. }
  1627. void CurveXYZTexture::set_curve_x(Ref<Curve> p_curve) {
  1628. if (_curve_x != p_curve) {
  1629. if (_curve_x.is_valid()) {
  1630. _curve_x->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update));
  1631. }
  1632. _curve_x = p_curve;
  1633. if (_curve_x.is_valid()) {
  1634. _curve_x->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED);
  1635. }
  1636. _update();
  1637. }
  1638. }
  1639. void CurveXYZTexture::set_curve_y(Ref<Curve> p_curve) {
  1640. if (_curve_y != p_curve) {
  1641. if (_curve_y.is_valid()) {
  1642. _curve_y->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update));
  1643. }
  1644. _curve_y = p_curve;
  1645. if (_curve_y.is_valid()) {
  1646. _curve_y->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED);
  1647. }
  1648. _update();
  1649. }
  1650. }
  1651. void CurveXYZTexture::set_curve_z(Ref<Curve> p_curve) {
  1652. if (_curve_z != p_curve) {
  1653. if (_curve_z.is_valid()) {
  1654. _curve_z->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update));
  1655. }
  1656. _curve_z = p_curve;
  1657. if (_curve_z.is_valid()) {
  1658. _curve_z->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveXYZTexture::_update), CONNECT_REFERENCE_COUNTED);
  1659. }
  1660. _update();
  1661. }
  1662. }
  1663. void CurveXYZTexture::_update() {
  1664. Vector<uint8_t> data;
  1665. data.resize(_width * sizeof(float) * 3);
  1666. // The array is locked in that scope
  1667. {
  1668. uint8_t *wd8 = data.ptrw();
  1669. float *wd = (float *)wd8;
  1670. if (_curve_x.is_valid()) {
  1671. Curve &curve_x = **_curve_x;
  1672. for (int i = 0; i < _width; ++i) {
  1673. float t = i / static_cast<float>(_width);
  1674. wd[i * 3 + 0] = curve_x.sample_baked(t);
  1675. }
  1676. } else {
  1677. for (int i = 0; i < _width; ++i) {
  1678. wd[i * 3 + 0] = 0;
  1679. }
  1680. }
  1681. if (_curve_y.is_valid()) {
  1682. Curve &curve_y = **_curve_y;
  1683. for (int i = 0; i < _width; ++i) {
  1684. float t = i / static_cast<float>(_width);
  1685. wd[i * 3 + 1] = curve_y.sample_baked(t);
  1686. }
  1687. } else {
  1688. for (int i = 0; i < _width; ++i) {
  1689. wd[i * 3 + 1] = 0;
  1690. }
  1691. }
  1692. if (_curve_z.is_valid()) {
  1693. Curve &curve_z = **_curve_z;
  1694. for (int i = 0; i < _width; ++i) {
  1695. float t = i / static_cast<float>(_width);
  1696. wd[i * 3 + 2] = curve_z.sample_baked(t);
  1697. }
  1698. } else {
  1699. for (int i = 0; i < _width; ++i) {
  1700. wd[i * 3 + 2] = 0;
  1701. }
  1702. }
  1703. }
  1704. Ref<Image> image = memnew(Image(_width, 1, false, Image::FORMAT_RGBF, data));
  1705. if (_texture.is_valid()) {
  1706. if (_current_width != _width) {
  1707. RID new_texture = RS::get_singleton()->texture_2d_create(image);
  1708. RS::get_singleton()->texture_replace(_texture, new_texture);
  1709. } else {
  1710. RS::get_singleton()->texture_2d_update(_texture, image);
  1711. }
  1712. } else {
  1713. _texture = RS::get_singleton()->texture_2d_create(image);
  1714. }
  1715. _current_width = _width;
  1716. emit_changed();
  1717. }
  1718. Ref<Curve> CurveXYZTexture::get_curve_x() const {
  1719. return _curve_x;
  1720. }
  1721. Ref<Curve> CurveXYZTexture::get_curve_y() const {
  1722. return _curve_y;
  1723. }
  1724. Ref<Curve> CurveXYZTexture::get_curve_z() const {
  1725. return _curve_z;
  1726. }
  1727. RID CurveXYZTexture::get_rid() const {
  1728. if (!_texture.is_valid()) {
  1729. _texture = RS::get_singleton()->texture_2d_placeholder_create();
  1730. }
  1731. return _texture;
  1732. }
  1733. CurveXYZTexture::CurveXYZTexture() {}
  1734. CurveXYZTexture::~CurveXYZTexture() {
  1735. if (_texture.is_valid()) {
  1736. RS::get_singleton()->free(_texture);
  1737. }
  1738. }
  1739. //////////////////
  1740. GradientTexture1D::GradientTexture1D() {
  1741. _queue_update();
  1742. }
  1743. GradientTexture1D::~GradientTexture1D() {
  1744. if (texture.is_valid()) {
  1745. RS::get_singleton()->free(texture);
  1746. }
  1747. }
  1748. void GradientTexture1D::_bind_methods() {
  1749. ClassDB::bind_method(D_METHOD("set_gradient", "gradient"), &GradientTexture1D::set_gradient);
  1750. ClassDB::bind_method(D_METHOD("get_gradient"), &GradientTexture1D::get_gradient);
  1751. ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture1D::set_width);
  1752. // The `get_width()` method is already exposed by the parent class Texture2D.
  1753. ClassDB::bind_method(D_METHOD("set_use_hdr", "enabled"), &GradientTexture1D::set_use_hdr);
  1754. ClassDB::bind_method(D_METHOD("is_using_hdr"), &GradientTexture1D::is_using_hdr);
  1755. ClassDB::bind_method(D_METHOD("_update"), &GradientTexture1D::_update);
  1756. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_gradient", "get_gradient");
  1757. ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,16384,suffix:px"), "set_width", "get_width");
  1758. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
  1759. }
  1760. void GradientTexture1D::set_gradient(Ref<Gradient> p_gradient) {
  1761. if (p_gradient == gradient) {
  1762. return;
  1763. }
  1764. if (gradient.is_valid()) {
  1765. gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture1D::_update));
  1766. }
  1767. gradient = p_gradient;
  1768. if (gradient.is_valid()) {
  1769. gradient->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture1D::_update));
  1770. }
  1771. _update();
  1772. emit_changed();
  1773. }
  1774. Ref<Gradient> GradientTexture1D::get_gradient() const {
  1775. return gradient;
  1776. }
  1777. void GradientTexture1D::_queue_update() {
  1778. if (update_pending) {
  1779. return;
  1780. }
  1781. update_pending = true;
  1782. call_deferred(SNAME("_update"));
  1783. }
  1784. void GradientTexture1D::_update() {
  1785. update_pending = false;
  1786. if (gradient.is_null()) {
  1787. return;
  1788. }
  1789. if (use_hdr) {
  1790. // High dynamic range.
  1791. Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBAF));
  1792. Gradient &g = **gradient;
  1793. // `create()` isn't available for non-uint8_t data, so fill in the data manually.
  1794. for (int i = 0; i < width; i++) {
  1795. float ofs = float(i) / (width - 1);
  1796. image->set_pixel(i, 0, g.get_color_at_offset(ofs));
  1797. }
  1798. if (texture.is_valid()) {
  1799. RID new_texture = RS::get_singleton()->texture_2d_create(image);
  1800. RS::get_singleton()->texture_replace(texture, new_texture);
  1801. } else {
  1802. texture = RS::get_singleton()->texture_2d_create(image);
  1803. }
  1804. } else {
  1805. // Low dynamic range. "Overbright" colors will be clamped.
  1806. Vector<uint8_t> data;
  1807. data.resize(width * 4);
  1808. {
  1809. uint8_t *wd8 = data.ptrw();
  1810. Gradient &g = **gradient;
  1811. for (int i = 0; i < width; i++) {
  1812. float ofs = float(i) / (width - 1);
  1813. Color color = g.get_color_at_offset(ofs);
  1814. wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255));
  1815. wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255));
  1816. wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255));
  1817. wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255));
  1818. }
  1819. }
  1820. Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
  1821. if (texture.is_valid()) {
  1822. RID new_texture = RS::get_singleton()->texture_2d_create(image);
  1823. RS::get_singleton()->texture_replace(texture, new_texture);
  1824. } else {
  1825. texture = RS::get_singleton()->texture_2d_create(image);
  1826. }
  1827. }
  1828. emit_changed();
  1829. }
  1830. void GradientTexture1D::set_width(int p_width) {
  1831. ERR_FAIL_COND_MSG(p_width <= 0 || p_width > 16384, "Texture dimensions have to be within 1 to 16384 range.");
  1832. width = p_width;
  1833. _queue_update();
  1834. }
  1835. int GradientTexture1D::get_width() const {
  1836. return width;
  1837. }
  1838. void GradientTexture1D::set_use_hdr(bool p_enabled) {
  1839. if (p_enabled == use_hdr) {
  1840. return;
  1841. }
  1842. use_hdr = p_enabled;
  1843. _queue_update();
  1844. }
  1845. bool GradientTexture1D::is_using_hdr() const {
  1846. return use_hdr;
  1847. }
  1848. Ref<Image> GradientTexture1D::get_image() const {
  1849. if (!texture.is_valid()) {
  1850. return Ref<Image>();
  1851. }
  1852. return RenderingServer::get_singleton()->texture_2d_get(texture);
  1853. }
  1854. //////////////////
  1855. GradientTexture2D::GradientTexture2D() {
  1856. _queue_update();
  1857. }
  1858. GradientTexture2D::~GradientTexture2D() {
  1859. if (texture.is_valid()) {
  1860. RS::get_singleton()->free(texture);
  1861. }
  1862. }
  1863. void GradientTexture2D::set_gradient(Ref<Gradient> p_gradient) {
  1864. if (gradient == p_gradient) {
  1865. return;
  1866. }
  1867. if (gradient.is_valid()) {
  1868. gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture2D::_queue_update));
  1869. }
  1870. gradient = p_gradient;
  1871. if (gradient.is_valid()) {
  1872. gradient->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture2D::_queue_update));
  1873. }
  1874. _update();
  1875. emit_changed();
  1876. }
  1877. Ref<Gradient> GradientTexture2D::get_gradient() const {
  1878. return gradient;
  1879. }
  1880. void GradientTexture2D::_queue_update() {
  1881. if (update_pending) {
  1882. return;
  1883. }
  1884. update_pending = true;
  1885. call_deferred(SNAME("_update"));
  1886. }
  1887. void GradientTexture2D::_update() {
  1888. update_pending = false;
  1889. if (gradient.is_null()) {
  1890. return;
  1891. }
  1892. Ref<Image> image;
  1893. image.instantiate();
  1894. if (gradient->get_points_count() <= 1) { // No need to interpolate.
  1895. image->create(width, height, false, (use_hdr) ? Image::FORMAT_RGBAF : Image::FORMAT_RGBA8);
  1896. image->fill((gradient->get_points_count() == 1) ? gradient->get_color(0) : Color(0, 0, 0, 1));
  1897. } else {
  1898. if (use_hdr) {
  1899. image->create(width, height, false, Image::FORMAT_RGBAF);
  1900. Gradient &g = **gradient;
  1901. // `create()` isn't available for non-uint8_t data, so fill in the data manually.
  1902. for (int y = 0; y < height; y++) {
  1903. for (int x = 0; x < width; x++) {
  1904. float ofs = _get_gradient_offset_at(x, y);
  1905. image->set_pixel(x, y, g.get_color_at_offset(ofs));
  1906. }
  1907. }
  1908. } else {
  1909. Vector<uint8_t> data;
  1910. data.resize(width * height * 4);
  1911. {
  1912. uint8_t *wd8 = data.ptrw();
  1913. Gradient &g = **gradient;
  1914. for (int y = 0; y < height; y++) {
  1915. for (int x = 0; x < width; x++) {
  1916. float ofs = _get_gradient_offset_at(x, y);
  1917. const Color &c = g.get_color_at_offset(ofs);
  1918. wd8[(x + (y * width)) * 4 + 0] = uint8_t(CLAMP(c.r * 255.0, 0, 255));
  1919. wd8[(x + (y * width)) * 4 + 1] = uint8_t(CLAMP(c.g * 255.0, 0, 255));
  1920. wd8[(x + (y * width)) * 4 + 2] = uint8_t(CLAMP(c.b * 255.0, 0, 255));
  1921. wd8[(x + (y * width)) * 4 + 3] = uint8_t(CLAMP(c.a * 255.0, 0, 255));
  1922. }
  1923. }
  1924. }
  1925. image->create(width, height, false, Image::FORMAT_RGBA8, data);
  1926. }
  1927. }
  1928. if (texture.is_valid()) {
  1929. RID new_texture = RS::get_singleton()->texture_2d_create(image);
  1930. RS::get_singleton()->texture_replace(texture, new_texture);
  1931. } else {
  1932. texture = RS::get_singleton()->texture_2d_create(image);
  1933. }
  1934. emit_changed();
  1935. }
  1936. float GradientTexture2D::_get_gradient_offset_at(int x, int y) const {
  1937. if (fill_to == fill_from) {
  1938. return 0;
  1939. }
  1940. float ofs = 0;
  1941. Vector2 pos;
  1942. if (width > 1) {
  1943. pos.x = static_cast<float>(x) / (width - 1);
  1944. }
  1945. if (height > 1) {
  1946. pos.y = static_cast<float>(y) / (height - 1);
  1947. }
  1948. if (fill == Fill::FILL_LINEAR) {
  1949. Vector2 segment[2];
  1950. segment[0] = fill_from;
  1951. segment[1] = fill_to;
  1952. Vector2 closest = Geometry2D::get_closest_point_to_segment_uncapped(pos, &segment[0]);
  1953. ofs = (closest - fill_from).length() / (fill_to - fill_from).length();
  1954. if ((closest - fill_from).dot(fill_to - fill_from) < 0) {
  1955. ofs *= -1;
  1956. }
  1957. } else if (fill == Fill::FILL_RADIAL) {
  1958. ofs = (pos - fill_from).length() / (fill_to - fill_from).length();
  1959. }
  1960. if (repeat == Repeat::REPEAT_NONE) {
  1961. ofs = CLAMP(ofs, 0.0, 1.0);
  1962. } else if (repeat == Repeat::REPEAT) {
  1963. ofs = Math::fmod(ofs, 1.0f);
  1964. if (ofs < 0) {
  1965. ofs = 1 + ofs;
  1966. }
  1967. } else if (repeat == Repeat::REPEAT_MIRROR) {
  1968. ofs = Math::abs(ofs);
  1969. ofs = Math::fmod(ofs, 2.0f);
  1970. if (ofs > 1.0) {
  1971. ofs = 2.0 - ofs;
  1972. }
  1973. }
  1974. return ofs;
  1975. }
  1976. void GradientTexture2D::set_width(int p_width) {
  1977. ERR_FAIL_COND_MSG(p_width <= 0 || p_width > 16384, "Texture dimensions have to be within 1 to 16384 range.");
  1978. width = p_width;
  1979. _queue_update();
  1980. }
  1981. int GradientTexture2D::get_width() const {
  1982. return width;
  1983. }
  1984. void GradientTexture2D::set_height(int p_height) {
  1985. ERR_FAIL_COND_MSG(p_height <= 0 || p_height > 16384, "Texture dimensions have to be within 1 to 16384 range.");
  1986. height = p_height;
  1987. _queue_update();
  1988. }
  1989. int GradientTexture2D::get_height() const {
  1990. return height;
  1991. }
  1992. void GradientTexture2D::set_use_hdr(bool p_enabled) {
  1993. if (p_enabled == use_hdr) {
  1994. return;
  1995. }
  1996. use_hdr = p_enabled;
  1997. _queue_update();
  1998. }
  1999. bool GradientTexture2D::is_using_hdr() const {
  2000. return use_hdr;
  2001. }
  2002. void GradientTexture2D::set_fill_from(Vector2 p_fill_from) {
  2003. fill_from = p_fill_from;
  2004. _queue_update();
  2005. }
  2006. Vector2 GradientTexture2D::get_fill_from() const {
  2007. return fill_from;
  2008. }
  2009. void GradientTexture2D::set_fill_to(Vector2 p_fill_to) {
  2010. fill_to = p_fill_to;
  2011. _queue_update();
  2012. }
  2013. Vector2 GradientTexture2D::get_fill_to() const {
  2014. return fill_to;
  2015. }
  2016. void GradientTexture2D::set_fill(Fill p_fill) {
  2017. fill = p_fill;
  2018. _queue_update();
  2019. }
  2020. GradientTexture2D::Fill GradientTexture2D::get_fill() const {
  2021. return fill;
  2022. }
  2023. void GradientTexture2D::set_repeat(Repeat p_repeat) {
  2024. repeat = p_repeat;
  2025. _queue_update();
  2026. }
  2027. GradientTexture2D::Repeat GradientTexture2D::get_repeat() const {
  2028. return repeat;
  2029. }
  2030. RID GradientTexture2D::get_rid() const {
  2031. if (!texture.is_valid()) {
  2032. texture = RS::get_singleton()->texture_2d_placeholder_create();
  2033. }
  2034. return texture;
  2035. }
  2036. Ref<Image> GradientTexture2D::get_image() const {
  2037. if (!texture.is_valid()) {
  2038. return Ref<Image>();
  2039. }
  2040. return RenderingServer::get_singleton()->texture_2d_get(texture);
  2041. }
  2042. void GradientTexture2D::_bind_methods() {
  2043. ClassDB::bind_method(D_METHOD("set_gradient", "gradient"), &GradientTexture2D::set_gradient);
  2044. ClassDB::bind_method(D_METHOD("get_gradient"), &GradientTexture2D::get_gradient);
  2045. ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture2D::set_width);
  2046. ClassDB::bind_method(D_METHOD("set_height", "height"), &GradientTexture2D::set_height);
  2047. ClassDB::bind_method(D_METHOD("set_use_hdr", "enabled"), &GradientTexture2D::set_use_hdr);
  2048. ClassDB::bind_method(D_METHOD("is_using_hdr"), &GradientTexture2D::is_using_hdr);
  2049. ClassDB::bind_method(D_METHOD("set_fill", "fill"), &GradientTexture2D::set_fill);
  2050. ClassDB::bind_method(D_METHOD("get_fill"), &GradientTexture2D::get_fill);
  2051. ClassDB::bind_method(D_METHOD("set_fill_from", "fill_from"), &GradientTexture2D::set_fill_from);
  2052. ClassDB::bind_method(D_METHOD("get_fill_from"), &GradientTexture2D::get_fill_from);
  2053. ClassDB::bind_method(D_METHOD("set_fill_to", "fill_to"), &GradientTexture2D::set_fill_to);
  2054. ClassDB::bind_method(D_METHOD("get_fill_to"), &GradientTexture2D::get_fill_to);
  2055. ClassDB::bind_method(D_METHOD("set_repeat", "repeat"), &GradientTexture2D::set_repeat);
  2056. ClassDB::bind_method(D_METHOD("get_repeat"), &GradientTexture2D::get_repeat);
  2057. ClassDB::bind_method(D_METHOD("_update"), &GradientTexture2D::_update);
  2058. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT), "set_gradient", "get_gradient");
  2059. ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,or_greater,suffix:px"), "set_width", "get_width");
  2060. ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,or_greater,suffix:px"), "set_height", "get_height");
  2061. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
  2062. ADD_GROUP("Fill", "fill_");
  2063. ADD_PROPERTY(PropertyInfo(Variant::INT, "fill", PROPERTY_HINT_ENUM, "Linear,Radial"), "set_fill", "get_fill");
  2064. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "fill_from"), "set_fill_from", "get_fill_from");
  2065. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "fill_to"), "set_fill_to", "get_fill_to");
  2066. ADD_GROUP("Repeat", "repeat_");
  2067. ADD_PROPERTY(PropertyInfo(Variant::INT, "repeat", PROPERTY_HINT_ENUM, "No Repeat,Repeat,Mirror Repeat"), "set_repeat", "get_repeat");
  2068. BIND_ENUM_CONSTANT(FILL_LINEAR);
  2069. BIND_ENUM_CONSTANT(FILL_RADIAL);
  2070. BIND_ENUM_CONSTANT(REPEAT_NONE);
  2071. BIND_ENUM_CONSTANT(REPEAT);
  2072. BIND_ENUM_CONSTANT(REPEAT_MIRROR);
  2073. }
  2074. //////////////////////////////////////
  2075. void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) {
  2076. ERR_FAIL_COND(p_texture == this);
  2077. base = p_texture;
  2078. if (base.is_valid()) {
  2079. if (proxy_ph.is_valid()) {
  2080. RS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
  2081. RS::get_singleton()->free(proxy_ph);
  2082. proxy_ph = RID();
  2083. } else if (proxy.is_valid()) {
  2084. RS::get_singleton()->texture_proxy_update(proxy, base->get_rid());
  2085. } else {
  2086. proxy = RS::get_singleton()->texture_proxy_create(base->get_rid());
  2087. }
  2088. }
  2089. }
  2090. Ref<Texture2D> ProxyTexture::get_base() const {
  2091. return base;
  2092. }
  2093. int ProxyTexture::get_width() const {
  2094. if (base.is_valid()) {
  2095. return base->get_width();
  2096. }
  2097. return 1;
  2098. }
  2099. int ProxyTexture::get_height() const {
  2100. if (base.is_valid()) {
  2101. return base->get_height();
  2102. }
  2103. return 1;
  2104. }
  2105. RID ProxyTexture::get_rid() const {
  2106. if (proxy.is_null()) {
  2107. proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
  2108. proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
  2109. }
  2110. return proxy;
  2111. }
  2112. bool ProxyTexture::has_alpha() const {
  2113. if (base.is_valid()) {
  2114. return base->has_alpha();
  2115. }
  2116. return false;
  2117. }
  2118. ProxyTexture::ProxyTexture() {
  2119. //proxy = RS::get_singleton()->texture_create();
  2120. }
  2121. ProxyTexture::~ProxyTexture() {
  2122. if (proxy_ph.is_valid()) {
  2123. RS::get_singleton()->free(proxy_ph);
  2124. }
  2125. if (proxy.is_valid()) {
  2126. RS::get_singleton()->free(proxy);
  2127. }
  2128. }
  2129. //////////////////////////////////////////////
  2130. void AnimatedTexture::_update_proxy() {
  2131. RWLockRead r(rw_lock);
  2132. float delta;
  2133. if (prev_ticks == 0) {
  2134. delta = 0;
  2135. prev_ticks = OS::get_singleton()->get_ticks_usec();
  2136. } else {
  2137. uint64_t ticks = OS::get_singleton()->get_ticks_usec();
  2138. delta = float(double(ticks - prev_ticks) / 1000000.0);
  2139. prev_ticks = ticks;
  2140. }
  2141. time += delta;
  2142. float limit;
  2143. if (fps == 0) {
  2144. limit = 0;
  2145. } else {
  2146. limit = 1.0 / fps;
  2147. }
  2148. int iter_max = frame_count;
  2149. while (iter_max && !pause) {
  2150. float frame_limit = limit + frames[current_frame].delay_sec;
  2151. if (time > frame_limit) {
  2152. current_frame++;
  2153. if (current_frame >= frame_count) {
  2154. if (oneshot) {
  2155. current_frame = frame_count - 1;
  2156. } else {
  2157. current_frame = 0;
  2158. }
  2159. }
  2160. time -= frame_limit;
  2161. } else {
  2162. break;
  2163. }
  2164. iter_max--;
  2165. }
  2166. if (frames[current_frame].texture.is_valid()) {
  2167. RenderingServer::get_singleton()->texture_proxy_update(proxy, frames[current_frame].texture->get_rid());
  2168. }
  2169. }
  2170. void AnimatedTexture::set_frames(int p_frames) {
  2171. ERR_FAIL_COND(p_frames < 1 || p_frames > MAX_FRAMES);
  2172. RWLockWrite r(rw_lock);
  2173. frame_count = p_frames;
  2174. }
  2175. int AnimatedTexture::get_frames() const {
  2176. return frame_count;
  2177. }
  2178. void AnimatedTexture::set_current_frame(int p_frame) {
  2179. ERR_FAIL_COND(p_frame < 0 || p_frame >= frame_count);
  2180. RWLockWrite r(rw_lock);
  2181. current_frame = p_frame;
  2182. }
  2183. int AnimatedTexture::get_current_frame() const {
  2184. return current_frame;
  2185. }
  2186. void AnimatedTexture::set_pause(bool p_pause) {
  2187. RWLockWrite r(rw_lock);
  2188. pause = p_pause;
  2189. }
  2190. bool AnimatedTexture::get_pause() const {
  2191. return pause;
  2192. }
  2193. void AnimatedTexture::set_oneshot(bool p_oneshot) {
  2194. RWLockWrite r(rw_lock);
  2195. oneshot = p_oneshot;
  2196. }
  2197. bool AnimatedTexture::get_oneshot() const {
  2198. return oneshot;
  2199. }
  2200. void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) {
  2201. ERR_FAIL_COND(p_texture == this);
  2202. ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
  2203. RWLockWrite w(rw_lock);
  2204. frames[p_frame].texture = p_texture;
  2205. }
  2206. Ref<Texture2D> AnimatedTexture::get_frame_texture(int p_frame) const {
  2207. ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture2D>());
  2208. RWLockRead r(rw_lock);
  2209. return frames[p_frame].texture;
  2210. }
  2211. void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) {
  2212. ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
  2213. RWLockRead r(rw_lock);
  2214. frames[p_frame].delay_sec = p_delay_sec;
  2215. }
  2216. float AnimatedTexture::get_frame_delay(int p_frame) const {
  2217. ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0);
  2218. RWLockRead r(rw_lock);
  2219. return frames[p_frame].delay_sec;
  2220. }
  2221. void AnimatedTexture::set_fps(float p_fps) {
  2222. ERR_FAIL_COND(p_fps < 0 || p_fps >= 1000);
  2223. fps = p_fps;
  2224. }
  2225. float AnimatedTexture::get_fps() const {
  2226. return fps;
  2227. }
  2228. int AnimatedTexture::get_width() const {
  2229. RWLockRead r(rw_lock);
  2230. if (!frames[current_frame].texture.is_valid()) {
  2231. return 1;
  2232. }
  2233. return frames[current_frame].texture->get_width();
  2234. }
  2235. int AnimatedTexture::get_height() const {
  2236. RWLockRead r(rw_lock);
  2237. if (!frames[current_frame].texture.is_valid()) {
  2238. return 1;
  2239. }
  2240. return frames[current_frame].texture->get_height();
  2241. }
  2242. RID AnimatedTexture::get_rid() const {
  2243. return proxy;
  2244. }
  2245. bool AnimatedTexture::has_alpha() const {
  2246. RWLockRead r(rw_lock);
  2247. if (!frames[current_frame].texture.is_valid()) {
  2248. return false;
  2249. }
  2250. return frames[current_frame].texture->has_alpha();
  2251. }
  2252. Ref<Image> AnimatedTexture::get_image() const {
  2253. RWLockRead r(rw_lock);
  2254. if (!frames[current_frame].texture.is_valid()) {
  2255. return Ref<Image>();
  2256. }
  2257. return frames[current_frame].texture->get_image();
  2258. }
  2259. bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
  2260. RWLockRead r(rw_lock);
  2261. if (frames[current_frame].texture.is_valid()) {
  2262. return frames[current_frame].texture->is_pixel_opaque(p_x, p_y);
  2263. }
  2264. return true;
  2265. }
  2266. void AnimatedTexture::_validate_property(PropertyInfo &p_property) const {
  2267. String prop = p_property.name;
  2268. if (prop.begins_with("frame_")) {
  2269. int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int();
  2270. if (frame >= frame_count) {
  2271. p_property.usage = PROPERTY_USAGE_NONE;
  2272. }
  2273. }
  2274. }
  2275. void AnimatedTexture::_bind_methods() {
  2276. ClassDB::bind_method(D_METHOD("set_frames", "frames"), &AnimatedTexture::set_frames);
  2277. ClassDB::bind_method(D_METHOD("get_frames"), &AnimatedTexture::get_frames);
  2278. ClassDB::bind_method(D_METHOD("set_current_frame", "frame"), &AnimatedTexture::set_current_frame);
  2279. ClassDB::bind_method(D_METHOD("get_current_frame"), &AnimatedTexture::get_current_frame);
  2280. ClassDB::bind_method(D_METHOD("set_pause", "pause"), &AnimatedTexture::set_pause);
  2281. ClassDB::bind_method(D_METHOD("get_pause"), &AnimatedTexture::get_pause);
  2282. ClassDB::bind_method(D_METHOD("set_oneshot", "oneshot"), &AnimatedTexture::set_oneshot);
  2283. ClassDB::bind_method(D_METHOD("get_oneshot"), &AnimatedTexture::get_oneshot);
  2284. ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps);
  2285. ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps);
  2286. ClassDB::bind_method(D_METHOD("set_frame_texture", "frame", "texture"), &AnimatedTexture::set_frame_texture);
  2287. ClassDB::bind_method(D_METHOD("get_frame_texture", "frame"), &AnimatedTexture::get_frame_texture);
  2288. ClassDB::bind_method(D_METHOD("set_frame_delay", "frame", "delay"), &AnimatedTexture::set_frame_delay);
  2289. ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay);
  2290. 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");
  2291. ADD_PROPERTY(PropertyInfo(Variant::INT, "current_frame", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_current_frame", "get_current_frame");
  2292. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pause"), "set_pause", "get_pause");
  2293. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "oneshot"), "set_oneshot", "get_oneshot");
  2294. ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps");
  2295. for (int i = 0; i < MAX_FRAMES; i++) {
  2296. 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);
  2297. ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01,suffix:s", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i);
  2298. }
  2299. BIND_CONSTANT(MAX_FRAMES);
  2300. }
  2301. AnimatedTexture::AnimatedTexture() {
  2302. //proxy = RS::get_singleton()->texture_create();
  2303. proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
  2304. proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
  2305. RenderingServer::get_singleton()->texture_set_force_redraw_if_visible(proxy, true);
  2306. RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy));
  2307. }
  2308. AnimatedTexture::~AnimatedTexture() {
  2309. RS::get_singleton()->free(proxy);
  2310. RS::get_singleton()->free(proxy_ph);
  2311. }
  2312. ///////////////////////////////
  2313. Image::Format TextureLayered::get_format() const {
  2314. Image::Format ret;
  2315. if (GDVIRTUAL_REQUIRED_CALL(_get_format, ret)) {
  2316. return ret;
  2317. }
  2318. return Image::FORMAT_MAX;
  2319. }
  2320. TextureLayered::LayeredType TextureLayered::get_layered_type() const {
  2321. uint32_t ret;
  2322. if (GDVIRTUAL_REQUIRED_CALL(_get_layered_type, ret)) {
  2323. return (LayeredType)ret;
  2324. }
  2325. return LAYERED_TYPE_2D_ARRAY;
  2326. }
  2327. int TextureLayered::get_width() const {
  2328. int ret;
  2329. if (GDVIRTUAL_REQUIRED_CALL(_get_width, ret)) {
  2330. return ret;
  2331. }
  2332. return 0;
  2333. }
  2334. int TextureLayered::get_height() const {
  2335. int ret;
  2336. if (GDVIRTUAL_REQUIRED_CALL(_get_height, ret)) {
  2337. return ret;
  2338. }
  2339. return 0;
  2340. }
  2341. int TextureLayered::get_layers() const {
  2342. int ret;
  2343. if (GDVIRTUAL_REQUIRED_CALL(_get_layers, ret)) {
  2344. return ret;
  2345. }
  2346. return 0;
  2347. }
  2348. bool TextureLayered::has_mipmaps() const {
  2349. bool ret;
  2350. if (GDVIRTUAL_REQUIRED_CALL(_has_mipmaps, ret)) {
  2351. return ret;
  2352. }
  2353. return false;
  2354. }
  2355. Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
  2356. Ref<Image> ret;
  2357. if (GDVIRTUAL_REQUIRED_CALL(_get_layer_data, p_layer, ret)) {
  2358. return ret;
  2359. }
  2360. return Ref<Image>();
  2361. }
  2362. void TextureLayered::_bind_methods() {
  2363. ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
  2364. ClassDB::bind_method(D_METHOD("get_layered_type"), &TextureLayered::get_layered_type);
  2365. ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width);
  2366. ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height);
  2367. ClassDB::bind_method(D_METHOD("get_layers"), &TextureLayered::get_layers);
  2368. ClassDB::bind_method(D_METHOD("has_mipmaps"), &TextureLayered::has_mipmaps);
  2369. ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data);
  2370. BIND_ENUM_CONSTANT(LAYERED_TYPE_2D_ARRAY);
  2371. BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP);
  2372. BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP_ARRAY);
  2373. GDVIRTUAL_BIND(_get_format);
  2374. GDVIRTUAL_BIND(_get_layered_type);
  2375. GDVIRTUAL_BIND(_get_width);
  2376. GDVIRTUAL_BIND(_get_height);
  2377. GDVIRTUAL_BIND(_get_layers);
  2378. GDVIRTUAL_BIND(_has_mipmaps);
  2379. GDVIRTUAL_BIND(_get_layer_data, "layer_index");
  2380. }
  2381. ///////////////////////////////
  2382. Image::Format ImageTextureLayered::get_format() const {
  2383. return format;
  2384. }
  2385. int ImageTextureLayered::get_width() const {
  2386. return width;
  2387. }
  2388. int ImageTextureLayered::get_height() const {
  2389. return height;
  2390. }
  2391. int ImageTextureLayered::get_layers() const {
  2392. return layers;
  2393. }
  2394. bool ImageTextureLayered::has_mipmaps() const {
  2395. return mipmaps;
  2396. }
  2397. ImageTextureLayered::LayeredType ImageTextureLayered::get_layered_type() const {
  2398. return layered_type;
  2399. }
  2400. Error ImageTextureLayered::_create_from_images(const Array &p_images) {
  2401. Vector<Ref<Image>> images;
  2402. for (int i = 0; i < p_images.size(); i++) {
  2403. Ref<Image> img = p_images[i];
  2404. ERR_FAIL_COND_V(img.is_null(), ERR_INVALID_PARAMETER);
  2405. images.push_back(img);
  2406. }
  2407. return create_from_images(images);
  2408. }
  2409. Array ImageTextureLayered::_get_images() const {
  2410. Array images;
  2411. for (int i = 0; i < layers; i++) {
  2412. images.push_back(get_layer_data(i));
  2413. }
  2414. return images;
  2415. }
  2416. Error ImageTextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
  2417. int new_layers = p_images.size();
  2418. ERR_FAIL_COND_V(new_layers == 0, ERR_INVALID_PARAMETER);
  2419. if (layered_type == LAYERED_TYPE_CUBEMAP) {
  2420. ERR_FAIL_COND_V_MSG(new_layers != 6, ERR_INVALID_PARAMETER,
  2421. "Cubemaps require exactly 6 layers");
  2422. } else if (layered_type == LAYERED_TYPE_CUBEMAP_ARRAY) {
  2423. ERR_FAIL_COND_V_MSG((new_layers % 6) != 0, ERR_INVALID_PARAMETER,
  2424. "Cubemap array layers must be a multiple of 6");
  2425. }
  2426. ERR_FAIL_COND_V(p_images[0].is_null() || p_images[0]->is_empty(), ERR_INVALID_PARAMETER);
  2427. Image::Format new_format = p_images[0]->get_format();
  2428. int new_width = p_images[0]->get_width();
  2429. int new_height = p_images[0]->get_height();
  2430. bool new_mipmaps = p_images[0]->has_mipmaps();
  2431. for (int i = 1; i < p_images.size(); i++) {
  2432. ERR_FAIL_COND_V_MSG(p_images[i]->get_format() != new_format, ERR_INVALID_PARAMETER,
  2433. "All images must share the same format");
  2434. ERR_FAIL_COND_V_MSG(p_images[i]->get_width() != new_width || p_images[i]->get_height() != new_height, ERR_INVALID_PARAMETER,
  2435. "All images must share the same dimensions");
  2436. ERR_FAIL_COND_V_MSG(p_images[i]->has_mipmaps() != new_mipmaps, ERR_INVALID_PARAMETER,
  2437. "All images must share the usage of mipmaps");
  2438. }
  2439. if (texture.is_valid()) {
  2440. RID new_texture = RS::get_singleton()->texture_2d_layered_create(p_images, RS::TextureLayeredType(layered_type));
  2441. ERR_FAIL_COND_V(!new_texture.is_valid(), ERR_CANT_CREATE);
  2442. RS::get_singleton()->texture_replace(texture, new_texture);
  2443. } else {
  2444. texture = RS::get_singleton()->texture_2d_layered_create(p_images, RS::TextureLayeredType(layered_type));
  2445. ERR_FAIL_COND_V(!texture.is_valid(), ERR_CANT_CREATE);
  2446. }
  2447. format = new_format;
  2448. width = new_width;
  2449. height = new_height;
  2450. layers = new_layers;
  2451. mipmaps = new_mipmaps;
  2452. return OK;
  2453. }
  2454. void ImageTextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
  2455. ERR_FAIL_COND_MSG(texture.is_null(), "Texture is not initialized.");
  2456. ERR_FAIL_COND_MSG(p_image.is_null(), "Invalid image.");
  2457. ERR_FAIL_COND_MSG(p_image->get_format() != format, "Image format must match texture's image format.");
  2458. ERR_FAIL_COND_MSG(p_image->get_width() != width || p_image->get_height() != height, "Image size must match texture's image size.");
  2459. ERR_FAIL_COND_MSG(p_image->has_mipmaps() != mipmaps, "Image mipmap configuration must match texture's image mipmap configuration.");
  2460. ERR_FAIL_INDEX_MSG(p_layer, layers, "Layer index is out of bounds.");
  2461. RS::get_singleton()->texture_2d_update(texture, p_image, p_layer);
  2462. }
  2463. Ref<Image> ImageTextureLayered::get_layer_data(int p_layer) const {
  2464. ERR_FAIL_INDEX_V(p_layer, layers, Ref<Image>());
  2465. return RS::get_singleton()->texture_2d_layer_get(texture, p_layer);
  2466. }
  2467. RID ImageTextureLayered::get_rid() const {
  2468. if (texture.is_null()) {
  2469. texture = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type));
  2470. }
  2471. return texture;
  2472. }
  2473. void ImageTextureLayered::set_path(const String &p_path, bool p_take_over) {
  2474. if (texture.is_valid()) {
  2475. RS::get_singleton()->texture_set_path(texture, p_path);
  2476. }
  2477. Resource::set_path(p_path, p_take_over);
  2478. }
  2479. void ImageTextureLayered::_bind_methods() {
  2480. ClassDB::bind_method(D_METHOD("create_from_images", "images"), &ImageTextureLayered::_create_from_images);
  2481. ClassDB::bind_method(D_METHOD("update_layer", "image", "layer"), &ImageTextureLayered::update_layer);
  2482. ClassDB::bind_method(D_METHOD("_get_images"), &ImageTextureLayered::_get_images);
  2483. ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images");
  2484. }
  2485. ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) {
  2486. layered_type = p_layered_type;
  2487. }
  2488. ImageTextureLayered::~ImageTextureLayered() {
  2489. if (texture.is_valid()) {
  2490. RS::get_singleton()->free(texture);
  2491. }
  2492. }
  2493. ///////////////////////////////////////////
  2494. void CompressedTextureLayered::set_path(const String &p_path, bool p_take_over) {
  2495. if (texture.is_valid()) {
  2496. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  2497. }
  2498. Resource::set_path(p_path, p_take_over);
  2499. }
  2500. Image::Format CompressedTextureLayered::get_format() const {
  2501. return format;
  2502. }
  2503. Error CompressedTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit) {
  2504. ERR_FAIL_COND_V(images.size() != 0, ERR_INVALID_PARAMETER);
  2505. Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
  2506. ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, vformat("Unable to open file: %s.", p_path));
  2507. uint8_t header[4];
  2508. f->get_buffer(header, 4);
  2509. if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L') {
  2510. ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture layered file is corrupt (Bad header).");
  2511. }
  2512. uint32_t version = f->get_32();
  2513. if (version > FORMAT_VERSION) {
  2514. ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Compressed texture file is too new.");
  2515. }
  2516. uint32_t layer_count = f->get_32(); //layer count
  2517. uint32_t type = f->get_32(); //layer count
  2518. ERR_FAIL_COND_V(type != layered_type, ERR_INVALID_DATA);
  2519. uint32_t df = f->get_32(); //data format
  2520. mipmap_limit = int(f->get_32());
  2521. //reserved
  2522. f->get_32();
  2523. f->get_32();
  2524. f->get_32();
  2525. if (!(df & FORMAT_BIT_STREAM)) {
  2526. p_size_limit = 0;
  2527. }
  2528. images.resize(layer_count);
  2529. for (uint32_t i = 0; i < layer_count; i++) {
  2530. Ref<Image> image = CompressedTexture2D::load_image_from_file(f, p_size_limit);
  2531. ERR_FAIL_COND_V(image.is_null() || image->is_empty(), ERR_CANT_OPEN);
  2532. images.write[i] = image;
  2533. }
  2534. return OK;
  2535. }
  2536. Error CompressedTextureLayered::load(const String &p_path) {
  2537. Vector<Ref<Image>> images;
  2538. int mipmap_limit;
  2539. Error err = _load_data(p_path, images, mipmap_limit);
  2540. if (err) {
  2541. return err;
  2542. }
  2543. if (texture.is_valid()) {
  2544. RID new_texture = RS::get_singleton()->texture_2d_layered_create(images, RS::TextureLayeredType(layered_type));
  2545. RS::get_singleton()->texture_replace(texture, new_texture);
  2546. } else {
  2547. texture = RS::get_singleton()->texture_2d_layered_create(images, RS::TextureLayeredType(layered_type));
  2548. }
  2549. w = images[0]->get_width();
  2550. h = images[0]->get_height();
  2551. mipmaps = images[0]->has_mipmaps();
  2552. format = images[0]->get_format();
  2553. layers = images.size();
  2554. path_to_file = p_path;
  2555. if (get_path().is_empty()) {
  2556. //temporarily set path if no path set for resource, helps find errors
  2557. RenderingServer::get_singleton()->texture_set_path(texture, p_path);
  2558. }
  2559. notify_property_list_changed();
  2560. emit_changed();
  2561. return OK;
  2562. }
  2563. String CompressedTextureLayered::get_load_path() const {
  2564. return path_to_file;
  2565. }
  2566. int CompressedTextureLayered::get_width() const {
  2567. return w;
  2568. }
  2569. int CompressedTextureLayered::get_height() const {
  2570. return h;
  2571. }
  2572. int CompressedTextureLayered::get_layers() const {
  2573. return layers;
  2574. }
  2575. bool CompressedTextureLayered::has_mipmaps() const {
  2576. return mipmaps;
  2577. }
  2578. TextureLayered::LayeredType CompressedTextureLayered::get_layered_type() const {
  2579. return layered_type;
  2580. }
  2581. RID CompressedTextureLayered::get_rid() const {
  2582. if (!texture.is_valid()) {
  2583. texture = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type));
  2584. }
  2585. return texture;
  2586. }
  2587. Ref<Image> CompressedTextureLayered::get_layer_data(int p_layer) const {
  2588. if (texture.is_valid()) {
  2589. return RS::get_singleton()->texture_2d_layer_get(texture, p_layer);
  2590. } else {
  2591. return Ref<Image>();
  2592. }
  2593. }
  2594. void CompressedTextureLayered::reload_from_file() {
  2595. String path = get_path();
  2596. if (!path.is_resource_file()) {
  2597. return;
  2598. }
  2599. path = ResourceLoader::path_remap(path); //remap for translation
  2600. path = ResourceLoader::import_remap(path); //remap for import
  2601. if (!path.is_resource_file()) {
  2602. return;
  2603. }
  2604. load(path);
  2605. }
  2606. void CompressedTextureLayered::_validate_property(PropertyInfo &p_property) const {
  2607. }
  2608. void CompressedTextureLayered::_bind_methods() {
  2609. ClassDB::bind_method(D_METHOD("load", "path"), &CompressedTextureLayered::load);
  2610. ClassDB::bind_method(D_METHOD("get_load_path"), &CompressedTextureLayered::get_load_path);
  2611. ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.ctex"), "load", "get_load_path");
  2612. }
  2613. CompressedTextureLayered::CompressedTextureLayered(LayeredType p_type) {
  2614. layered_type = p_type;
  2615. }
  2616. CompressedTextureLayered::~CompressedTextureLayered() {
  2617. if (texture.is_valid()) {
  2618. RS::get_singleton()->free(texture);
  2619. }
  2620. }
  2621. /////////////////////////////////////////////////
  2622. Ref<Resource> ResourceFormatLoaderCompressedTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
  2623. Ref<CompressedTextureLayered> ct;
  2624. if (p_path.get_extension().to_lower() == "ctexarray") {
  2625. Ref<CompressedTexture2DArray> c;
  2626. c.instantiate();
  2627. ct = c;
  2628. } else if (p_path.get_extension().to_lower() == "ccube") {
  2629. Ref<CompressedCubemap> c;
  2630. c.instantiate();
  2631. ct = c;
  2632. } else if (p_path.get_extension().to_lower() == "ccubearray") {
  2633. Ref<CompressedCubemapArray> c;
  2634. c.instantiate();
  2635. ct = c;
  2636. } else {
  2637. if (r_error) {
  2638. *r_error = ERR_FILE_UNRECOGNIZED;
  2639. }
  2640. return Ref<Resource>();
  2641. }
  2642. Error err = ct->load(p_path);
  2643. if (r_error) {
  2644. *r_error = err;
  2645. }
  2646. if (err != OK) {
  2647. return Ref<Resource>();
  2648. }
  2649. return ct;
  2650. }
  2651. void ResourceFormatLoaderCompressedTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
  2652. p_extensions->push_back("ctexarray");
  2653. p_extensions->push_back("ccube");
  2654. p_extensions->push_back("ccubearray");
  2655. }
  2656. bool ResourceFormatLoaderCompressedTextureLayered::handles_type(const String &p_type) const {
  2657. return p_type == "CompressedTexture2DArray" || p_type == "CompressedCubemap" || p_type == "CompressedCubemapArray";
  2658. }
  2659. String ResourceFormatLoaderCompressedTextureLayered::get_resource_type(const String &p_path) const {
  2660. if (p_path.get_extension().to_lower() == "ctexarray") {
  2661. return "CompressedTexture2DArray";
  2662. }
  2663. if (p_path.get_extension().to_lower() == "ccube") {
  2664. return "CompressedCubemap";
  2665. }
  2666. if (p_path.get_extension().to_lower() == "ccubearray") {
  2667. return "CompressedCubemapArray";
  2668. }
  2669. return "";
  2670. }
  2671. ///////////////////////////////
  2672. void CameraTexture::_bind_methods() {
  2673. ClassDB::bind_method(D_METHOD("set_camera_feed_id", "feed_id"), &CameraTexture::set_camera_feed_id);
  2674. ClassDB::bind_method(D_METHOD("get_camera_feed_id"), &CameraTexture::get_camera_feed_id);
  2675. ClassDB::bind_method(D_METHOD("set_which_feed", "which_feed"), &CameraTexture::set_which_feed);
  2676. ClassDB::bind_method(D_METHOD("get_which_feed"), &CameraTexture::get_which_feed);
  2677. ClassDB::bind_method(D_METHOD("set_camera_active", "active"), &CameraTexture::set_camera_active);
  2678. ClassDB::bind_method(D_METHOD("get_camera_active"), &CameraTexture::get_camera_active);
  2679. ADD_PROPERTY(PropertyInfo(Variant::INT, "camera_feed_id"), "set_camera_feed_id", "get_camera_feed_id");
  2680. ADD_PROPERTY(PropertyInfo(Variant::INT, "which_feed"), "set_which_feed", "get_which_feed");
  2681. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "camera_is_active"), "set_camera_active", "get_camera_active");
  2682. }
  2683. int CameraTexture::get_width() const {
  2684. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  2685. if (feed.is_valid()) {
  2686. return feed->get_base_width();
  2687. } else {
  2688. return 0;
  2689. }
  2690. }
  2691. int CameraTexture::get_height() const {
  2692. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  2693. if (feed.is_valid()) {
  2694. return feed->get_base_height();
  2695. } else {
  2696. return 0;
  2697. }
  2698. }
  2699. bool CameraTexture::has_alpha() const {
  2700. return false;
  2701. }
  2702. RID CameraTexture::get_rid() const {
  2703. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  2704. if (feed.is_valid()) {
  2705. return feed->get_texture(which_feed);
  2706. } else {
  2707. if (_texture.is_null()) {
  2708. _texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();
  2709. }
  2710. return _texture;
  2711. }
  2712. }
  2713. Ref<Image> CameraTexture::get_image() const {
  2714. // not (yet) supported
  2715. return Ref<Image>();
  2716. }
  2717. void CameraTexture::set_camera_feed_id(int p_new_id) {
  2718. camera_feed_id = p_new_id;
  2719. notify_property_list_changed();
  2720. }
  2721. int CameraTexture::get_camera_feed_id() const {
  2722. return camera_feed_id;
  2723. }
  2724. void CameraTexture::set_which_feed(CameraServer::FeedImage p_which) {
  2725. which_feed = p_which;
  2726. notify_property_list_changed();
  2727. }
  2728. CameraServer::FeedImage CameraTexture::get_which_feed() const {
  2729. return which_feed;
  2730. }
  2731. void CameraTexture::set_camera_active(bool p_active) {
  2732. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  2733. if (feed.is_valid()) {
  2734. feed->set_active(p_active);
  2735. notify_property_list_changed();
  2736. }
  2737. }
  2738. bool CameraTexture::get_camera_active() const {
  2739. Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
  2740. if (feed.is_valid()) {
  2741. return feed->is_active();
  2742. } else {
  2743. return false;
  2744. }
  2745. }
  2746. CameraTexture::CameraTexture() {}
  2747. CameraTexture::~CameraTexture() {
  2748. if (_texture.is_valid()) {
  2749. RenderingServer::get_singleton()->free(_texture);
  2750. }
  2751. }
  2752. ///////////////////////////
  2753. void PlaceholderTexture2D::set_size(Size2 p_size) {
  2754. size = p_size;
  2755. }
  2756. int PlaceholderTexture2D::get_width() const {
  2757. return size.width;
  2758. }
  2759. int PlaceholderTexture2D::get_height() const {
  2760. return size.height;
  2761. }
  2762. bool PlaceholderTexture2D::has_alpha() const {
  2763. return false;
  2764. }
  2765. Ref<Image> PlaceholderTexture2D::get_image() const {
  2766. return Ref<Image>();
  2767. }
  2768. RID PlaceholderTexture2D::get_rid() const {
  2769. return rid;
  2770. }
  2771. void PlaceholderTexture2D::_bind_methods() {
  2772. ClassDB::bind_method(D_METHOD("set_size", "size"), &PlaceholderTexture2D::set_size);
  2773. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size", PROPERTY_HINT_NONE, "suffix:px"), "set_size", "get_size");
  2774. }
  2775. PlaceholderTexture2D::PlaceholderTexture2D() {
  2776. rid = RS::get_singleton()->texture_2d_placeholder_create();
  2777. }
  2778. PlaceholderTexture2D::~PlaceholderTexture2D() {
  2779. RS::get_singleton()->free(rid);
  2780. }
  2781. ///////////////////////////////////////////////
  2782. void PlaceholderTexture3D::set_size(const Vector3i &p_size) {
  2783. size = p_size;
  2784. }
  2785. Vector3i PlaceholderTexture3D::get_size() const {
  2786. return size;
  2787. }
  2788. Image::Format PlaceholderTexture3D::get_format() const {
  2789. return Image::FORMAT_RGB8;
  2790. }
  2791. int PlaceholderTexture3D::get_width() const {
  2792. return size.x;
  2793. }
  2794. int PlaceholderTexture3D::get_height() const {
  2795. return size.y;
  2796. }
  2797. int PlaceholderTexture3D::get_depth() const {
  2798. return size.z;
  2799. }
  2800. bool PlaceholderTexture3D::has_mipmaps() const {
  2801. return false;
  2802. }
  2803. Vector<Ref<Image>> PlaceholderTexture3D::get_data() const {
  2804. return Vector<Ref<Image>>();
  2805. }
  2806. void PlaceholderTexture3D::_bind_methods() {
  2807. ClassDB::bind_method(D_METHOD("set_size", "size"), &PlaceholderTexture3D::set_size);
  2808. ClassDB::bind_method(D_METHOD("get_size"), &PlaceholderTexture3D::get_size);
  2809. ADD_PROPERTY(PropertyInfo(Variant::VECTOR3I, "size", PROPERTY_HINT_NONE, "suffix:px"), "set_size", "get_size");
  2810. }
  2811. PlaceholderTexture3D::PlaceholderTexture3D() {
  2812. rid = RS::get_singleton()->texture_3d_placeholder_create();
  2813. }
  2814. PlaceholderTexture3D::~PlaceholderTexture3D() {
  2815. RS::get_singleton()->free(rid);
  2816. }
  2817. /////////////////////////////////////////////////
  2818. void PlaceholderTextureLayered::set_size(const Size2i &p_size) {
  2819. size = p_size;
  2820. }
  2821. Size2i PlaceholderTextureLayered::get_size() const {
  2822. return size;
  2823. }
  2824. void PlaceholderTextureLayered::set_layers(int p_layers) {
  2825. layers = p_layers;
  2826. }
  2827. Image::Format PlaceholderTextureLayered::get_format() const {
  2828. return Image::FORMAT_RGB8;
  2829. }
  2830. TextureLayered::LayeredType PlaceholderTextureLayered::get_layered_type() const {
  2831. return layered_type;
  2832. }
  2833. int PlaceholderTextureLayered::get_width() const {
  2834. return size.x;
  2835. }
  2836. int PlaceholderTextureLayered::get_height() const {
  2837. return size.y;
  2838. }
  2839. int PlaceholderTextureLayered::get_layers() const {
  2840. return layers;
  2841. }
  2842. bool PlaceholderTextureLayered::has_mipmaps() const {
  2843. return false;
  2844. }
  2845. Ref<Image> PlaceholderTextureLayered::get_layer_data(int p_layer) const {
  2846. return Ref<Image>();
  2847. }
  2848. void PlaceholderTextureLayered::_bind_methods() {
  2849. ClassDB::bind_method(D_METHOD("set_size", "size"), &PlaceholderTextureLayered::set_size);
  2850. ClassDB::bind_method(D_METHOD("get_size"), &PlaceholderTextureLayered::get_size);
  2851. ClassDB::bind_method(D_METHOD("set_layers", "layers"), &PlaceholderTextureLayered::set_layers);
  2852. ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size", PROPERTY_HINT_NONE, "suffix:px"), "set_size", "get_size");
  2853. ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_RANGE, "1,4096"), "set_layers", "get_layers");
  2854. }
  2855. PlaceholderTextureLayered::PlaceholderTextureLayered(LayeredType p_type) {
  2856. layered_type = p_type;
  2857. rid = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type));
  2858. }
  2859. PlaceholderTextureLayered::~PlaceholderTextureLayered() {
  2860. RS::get_singleton()->free(rid);
  2861. }