textures.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. -- Node texture tests
  2. local S = minetest.get_translator("testnodes")
  3. minetest.register_node("testnodes:6sides", {
  4. description = S("Six Textures Test Node").."\n"..
  5. S("Has 1 texture per face"),
  6. tiles = {
  7. "testnodes_normal1.png",
  8. "testnodes_normal2.png",
  9. "testnodes_normal3.png",
  10. "testnodes_normal4.png",
  11. "testnodes_normal5.png",
  12. "testnodes_normal6.png",
  13. },
  14. groups = { dig_immediate = 2 },
  15. })
  16. minetest.register_node("testnodes:anim", {
  17. description = S("Animated Test Node").."\n"..
  18. S("Tiles animate from A to D in 4s cycle"),
  19. tiles = {
  20. { name = "testnodes_anim.png",
  21. animation = {
  22. type = "vertical_frames",
  23. aspect_w = 16,
  24. aspect_h = 16,
  25. length = 4.0,
  26. }, },
  27. },
  28. groups = { dig_immediate = 2 },
  29. })
  30. minetest.register_node("testnodes:fill_positioning", {
  31. description = S("Fill Modifier Test Node") .. "\n" ..
  32. S("The node should have the same look as " ..
  33. "testnodes:fill_positioning_reference."),
  34. drawtype = "glasslike",
  35. paramtype = "light",
  36. tiles = {"[fill:16x16:#ffffff^[fill:6x6:1,1:#00ffdc" ..
  37. "^[fill:6x6:1,9:#00ffdc^[fill:6x6:9,1:#00ffdc^[fill:6x6:9,9:#00ffdc"},
  38. groups = {dig_immediate = 3},
  39. })
  40. minetest.register_node("testnodes:fill_positioning_reference", {
  41. description = S("Fill Modifier Test Node Reference"),
  42. drawtype = "glasslike",
  43. paramtype = "light",
  44. tiles = {"testnodes_fill_positioning_reference.png"},
  45. groups = {dig_immediate = 3},
  46. })
  47. -- Node texture transparency test
  48. local alphas = { 64, 128, 191 }
  49. for a=1,#alphas do
  50. local alpha = alphas[a]
  51. -- Transparency taken from texture
  52. minetest.register_node("testnodes:alpha_texture_"..alpha, {
  53. description = S("Texture Alpha Test Node (@1)", alpha).."\n"..
  54. S("Semi-transparent"),
  55. drawtype = "glasslike",
  56. paramtype = "light",
  57. tiles = {
  58. "testnodes_alpha"..alpha..".png",
  59. },
  60. use_texture_alpha = "blend",
  61. groups = { dig_immediate = 3 },
  62. })
  63. -- Transparency set via texture modifier
  64. minetest.register_node("testnodes:alpha_"..alpha, {
  65. description = S("Alpha Test Node (@1)", alpha).."\n"..
  66. S("Semi-transparent"),
  67. drawtype = "glasslike",
  68. paramtype = "light",
  69. tiles = {
  70. "testnodes_alpha.png^[opacity:" .. alpha,
  71. },
  72. use_texture_alpha = "blend",
  73. groups = { dig_immediate = 3 },
  74. })
  75. end
  76. minetest.register_node("testnodes:alpha_compositing", {
  77. description = S("Alpha Compositing Test Node") .. "\n" ..
  78. S("A regular grid should be visible where each cell contains two " ..
  79. "texels with the same colour.") .. "\n" ..
  80. S("Alpha compositing is gamma-incorrect for backwards compatibility."),
  81. drawtype = "glasslike",
  82. paramtype = "light",
  83. tiles = {"testnodes_alpha_compositing_bottom.png^" ..
  84. "testnodes_alpha_compositing_top.png"},
  85. use_texture_alpha = "blend",
  86. groups = {dig_immediate = 3},
  87. })
  88. -- Generate PNG textures
  89. local function mandelbrot(w, h, iterations)
  90. local r = {}
  91. for y=0, h-1 do
  92. for x=0, w-1 do
  93. local re = (x - w/2) * 4/w
  94. local im = (y - h/2) * 4/h
  95. -- zoom in on a nice view
  96. re = re / 128 - 0.23
  97. im = im / 128 - 0.82
  98. local px, py = 0, 0
  99. local i = 0
  100. while px*px + py*py <= 4 and i < iterations do
  101. px, py = px*px - py*py + re, 2 * px * py + im
  102. i = i + 1
  103. end
  104. r[w*y+x+1] = i / iterations
  105. end
  106. end
  107. return r
  108. end
  109. local function gen_checkers(w, h, tile)
  110. local r = {}
  111. for y=0, h-1 do
  112. for x=0, w-1 do
  113. local hori = math.floor(x / tile) % 2 == 0
  114. local vert = math.floor(y / tile) % 2 == 0
  115. r[w*y+x+1] = hori ~= vert and 1 or 0
  116. end
  117. end
  118. return r
  119. end
  120. -- The engine should perform color reduction of the generated PNG in certain
  121. -- cases, so we have this helper to check the result
  122. local function encode_and_check(w, h, ctype, data)
  123. local ret = core.encode_png(w, h, data)
  124. assert(ret:sub(1, 8) == "\137PNG\r\n\026\n", "missing png signature")
  125. assert(ret:sub(9, 16) == "\000\000\000\rIHDR", "didn't find ihdr chunk")
  126. local ctype_actual = ret:byte(26) -- Color Type (1 byte)
  127. ctype = ({rgba=6, rgb=2, gray=0})[ctype]
  128. assert(ctype_actual == ctype, "png should have color type " .. ctype ..
  129. " but actually has " .. ctype_actual)
  130. return ret
  131. end
  132. local fractal = mandelbrot(512, 512, 128)
  133. local frac_emb = mandelbrot(64, 64, 64)
  134. local checker = gen_checkers(512, 512, 32)
  135. local floor = math.floor
  136. local abs = math.abs
  137. local data_emb = {}
  138. local data_mb = {}
  139. local data_ck = {}
  140. for i=1, #frac_emb do
  141. data_emb[i] = {
  142. r = floor(abs(frac_emb[i] * 2 - 1) * 255),
  143. g = floor(abs(1 - frac_emb[i]) * 255),
  144. b = floor(frac_emb[i] * 255),
  145. a = frac_emb[i] < 0.95 and 255 or 0,
  146. }
  147. end
  148. for i=1, #fractal do
  149. data_mb[i] = {
  150. r = floor(fractal[i] * 255),
  151. g = floor(abs(fractal[i] * 2 - 1) * 255),
  152. b = floor(abs(1 - fractal[i]) * 255),
  153. a = 255,
  154. }
  155. data_ck[i] = checker[i] > 0 and "#888" or "#000"
  156. end
  157. fractal = nil
  158. frac_emb = nil
  159. checker = nil
  160. do
  161. -- we used to write the textures to our mod folder. in order to avoid
  162. -- duplication errors delete them if they still exist.
  163. local path = core.get_modpath(core.get_current_modname()) .. "/textures/"
  164. os.remove(path .. "testnodes_generated_mb.png")
  165. os.remove(path .. "testnodes_generated_ck.png")
  166. end
  167. local textures_path = core.get_worldpath() .. "/"
  168. core.safe_file_write(
  169. textures_path .. "testnodes1.png",
  170. encode_and_check(512, 512, "rgb", data_mb)
  171. )
  172. local png_ck = encode_and_check(512, 512, "gray", data_ck)
  173. core.dynamic_add_media({
  174. filename = "testnodes_generated_mb.png",
  175. filepath = textures_path .. "testnodes1.png"
  176. })
  177. core.dynamic_add_media({
  178. filename = "testnodes_generated_ck.png",
  179. filedata = png_ck,
  180. })
  181. minetest.register_node("testnodes:generated_png_mb", {
  182. description = S("Generated Mandelbrot PNG Test Node"),
  183. tiles = { "testnodes_generated_mb.png" },
  184. groups = { dig_immediate = 2 },
  185. })
  186. minetest.register_node("testnodes:generated_png_ck", {
  187. description = S("Generated Checker PNG Test Node"),
  188. tiles = { "testnodes_generated_ck.png" },
  189. groups = { dig_immediate = 2 },
  190. })
  191. local png_emb = "[png:" .. minetest.encode_base64(
  192. encode_and_check(64, 64, "rgba", data_emb))
  193. minetest.register_node("testnodes:generated_png_emb", {
  194. description = S("Generated In-Band Mandelbrot PNG Test Node"),
  195. tiles = { png_emb },
  196. drawtype = "allfaces", -- required because of transparent pixels
  197. use_texture_alpha = "clip",
  198. paramtype = "light",
  199. groups = { dig_immediate = 2 },
  200. })
  201. minetest.register_node("testnodes:generated_png_src_emb", {
  202. description = S("Generated In-Band Source Blit Mandelbrot PNG Test Node"),
  203. tiles = { png_emb .. "^testnodes_damage_neg.png" },
  204. drawtype = "allfaces", -- required because of transparent pixels
  205. use_texture_alpha = "clip",
  206. paramtype = "light",
  207. groups = { dig_immediate = 2 },
  208. })
  209. minetest.register_node("testnodes:generated_png_dst_emb", {
  210. description = S("Generated In-Band Dest Blit Mandelbrot PNG Test Node"),
  211. tiles = { "testnodes_generated_ck.png^" .. png_emb },
  212. groups = { dig_immediate = 2 },
  213. })
  214. png_ck = nil
  215. png_emb = nil
  216. data_emb = nil
  217. data_mb = nil
  218. data_ck = nil
  219. --[[
  220. The following nodes can be used to demonstrate the TGA format support.
  221. Minetest supports TGA types 1, 2, 3 & 10. While adding the support for
  222. TGA type 9 (RLE-compressed, color-mapped) is easy, it is not advisable
  223. to do so, as it is not backwards compatible with any Minetest pre-5.5;
  224. content creators should therefore either use TGA type 1 or 10, or PNG.
  225. TODO: Types 1, 2 & 10 should have two test nodes each (i.e. bottom-top
  226. and top-bottom) for 16bpp (A1R5G5B5), 24bpp (B8G8R8), 32bpp (B8G8R8A8)
  227. colors.
  228. Note: Minetest requires the optional TGA footer for a texture to load.
  229. If a TGA image does not load in Minetest, append eight (8) null bytes,
  230. then the string “TRUEVISION-XFILE.”, then another null byte.
  231. ]]--
  232. minetest.register_node("testnodes:tga_type1_24bpp_bt", {
  233. description = S("TGA Type 1 (color-mapped RGB) 24bpp bottom-top Test Node"),
  234. drawtype = "glasslike",
  235. paramtype = "light",
  236. sunlight_propagates = true,
  237. tiles = { "testnodes_tga_type1_24bpp_bt.tga" },
  238. groups = { dig_immediate = 2 },
  239. })
  240. minetest.register_node("testnodes:tga_type1_24bpp_tb", {
  241. description = S("TGA Type 1 (color-mapped RGB) 24bpp top-bottom Test Node"),
  242. drawtype = "glasslike",
  243. paramtype = "light",
  244. sunlight_propagates = true,
  245. tiles = { "testnodes_tga_type1_24bpp_tb.tga" },
  246. groups = { dig_immediate = 2 },
  247. })
  248. minetest.register_node("testnodes:tga_type2_16bpp_bt", {
  249. description = S("TGA Type 2 (uncompressed RGB) 16bpp bottom-top Test Node"),
  250. drawtype = "glasslike",
  251. paramtype = "light",
  252. sunlight_propagates = true,
  253. tiles = { "testnodes_tga_type2_16bpp_bt.tga" },
  254. use_texture_alpha = "clip",
  255. groups = { dig_immediate = 2 },
  256. })
  257. minetest.register_node("testnodes:tga_type2_16bpp_tb", {
  258. description = S("TGA Type 2 (uncompressed RGB) 16bpp top-bottom Test Node"),
  259. drawtype = "glasslike",
  260. paramtype = "light",
  261. sunlight_propagates = true,
  262. tiles = { "testnodes_tga_type2_16bpp_tb.tga" },
  263. use_texture_alpha = "clip",
  264. groups = { dig_immediate = 2 },
  265. })
  266. minetest.register_node("testnodes:tga_type2_32bpp_bt", {
  267. description = S("TGA Type 2 (uncompressed RGB) 32bpp bottom-top Test Node"),
  268. drawtype = "glasslike",
  269. paramtype = "light",
  270. sunlight_propagates = true,
  271. tiles = { "testnodes_tga_type2_32bpp_bt.tga" },
  272. use_texture_alpha = "blend",
  273. groups = { dig_immediate = 2 },
  274. })
  275. minetest.register_node("testnodes:tga_type2_32bpp_tb", {
  276. description = S("TGA Type 2 (uncompressed RGB) 32bpp top-bottom Test Node"),
  277. drawtype = "glasslike",
  278. paramtype = "light",
  279. sunlight_propagates = true,
  280. tiles = { "testnodes_tga_type2_32bpp_tb.tga" },
  281. use_texture_alpha = "blend",
  282. groups = { dig_immediate = 2 },
  283. })
  284. minetest.register_node("testnodes:tga_type3_16bpp_bt", {
  285. description = S("TGA Type 3 (uncompressed grayscale) 16bpp bottom-top Test Node"),
  286. drawtype = "glasslike",
  287. paramtype = "light",
  288. sunlight_propagates = true,
  289. tiles = { "testnodes_tga_type3_16bpp_bt.tga" },
  290. use_texture_alpha = "blend",
  291. groups = { dig_immediate = 2 },
  292. })
  293. minetest.register_node("testnodes:tga_type3_16bpp_tb", {
  294. description = S("TGA Type 3 (uncompressed grayscale) 16bpp top-bottom Test Node"),
  295. drawtype = "glasslike",
  296. paramtype = "light",
  297. sunlight_propagates = true,
  298. tiles = { "testnodes_tga_type3_16bpp_tb.tga" },
  299. use_texture_alpha = "blend",
  300. groups = { dig_immediate = 2 },
  301. })
  302. minetest.register_node("testnodes:tga_type10_32bpp_bt", {
  303. description = S("TGA Type 10 (RLE-compressed RGB) 32bpp bottom-top Test Node"),
  304. tiles = { "testnodes_tga_type10_32bpp_bt.tga" },
  305. drawtype = "glasslike",
  306. paramtype = "light",
  307. sunlight_propagates = true,
  308. use_texture_alpha = "blend",
  309. groups = { dig_immediate = 2 },
  310. })
  311. minetest.register_node("testnodes:tga_type10_32bpp_tb", {
  312. description = S("TGA Type 10 (RLE-compressed RGB) 32bpp top-bottom Test Node"),
  313. drawtype = "glasslike",
  314. paramtype = "light",
  315. sunlight_propagates = true,
  316. tiles = { "testnodes_tga_type10_32bpp_tb.tga" },
  317. use_texture_alpha = "blend",
  318. groups = { dig_immediate = 2 },
  319. })