test_glsl_shader.py 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453
  1. from panda3d import core
  2. import os
  3. import struct
  4. import pytest
  5. from _pytest.outcomes import Failed
  6. SHADERS_DIR = core.Filename.from_os_specific(os.path.dirname(__file__))
  7. def test_glsl_test(env):
  8. "Test to make sure that the GLSL tests work correctly."
  9. env.run_glsl("assert(true);")
  10. def test_glsl_test_fail(env):
  11. "Same as above, but making sure that the failure case works correctly."
  12. with pytest.raises(Failed):
  13. env.run_glsl("assert(false);")
  14. def test_glsl_sampler(env):
  15. tex1 = core.Texture("tex1-ubyte-rgba8")
  16. tex1.setup_1d_texture(1, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  17. tex1.set_clear_color((0, 2 / 255.0, 1, 1))
  18. tex2 = core.Texture("tex2-float-rgba32")
  19. tex2.setup_2d_texture(1, 1, core.Texture.T_float, core.Texture.F_rgba32)
  20. tex2.set_clear_color((1.0, 2.0, -3.14, 0.0))
  21. tex3 = core.Texture("tex3-float-r32")
  22. tex3.setup_3d_texture(1, 1, 1, core.Texture.T_float, core.Texture.F_r32)
  23. tex3.set_clear_color((0.5, 0.0, 0.0, 1.0))
  24. preamble = """
  25. uniform sampler1D tex1;
  26. uniform sampler2D tex2;
  27. uniform sampler3D tex3;
  28. """
  29. code = """
  30. assert(texture(tex1, 0) == vec4(0, 2 / 255.0, 1, 1));
  31. assert(texture(tex2, vec2(0, 0)) == vec4(1.0, 2.0, -3.14, 0.0));
  32. assert(texture(tex3, vec3(0, 0, 0)).r == 0.5);
  33. """
  34. env.run_glsl(code, preamble, {'tex1': tex1, 'tex2': tex2, 'tex3': tex3})
  35. def test_glsl_texture_size(env):
  36. tex1_0 = core.Texture("tex1-0-1d")
  37. tex1_0.setup_1d_texture(128, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  38. tex1_1 = core.Texture("tex1-1-1d")
  39. tex1_1.setup_1d_texture(256, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  40. tex2 = core.Texture("tex2-2d")
  41. tex2.setup_2d_texture(64, 32, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  42. tex3 = core.Texture("tex3-cube")
  43. tex3.setup_cube_map(16, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  44. tex4 = core.Texture("tex4-3d")
  45. tex4.setup_3d_texture(8, 4, 2, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  46. preamble = """
  47. uniform sampler1D tex1[2];
  48. uniform sampler2D tex2;
  49. uniform samplerCube tex3;
  50. uniform sampler3D tex4;
  51. """
  52. code = """
  53. assert(textureSize(tex1[0], 0) == 128);
  54. assert(textureSize(tex1[1], 0) == 256);
  55. assert(textureSize(tex2, 0) == ivec2(64, 32));
  56. assert(textureSize(tex3, 0) == ivec2(16, 16));
  57. assert(textureSize(tex4, 0) == ivec3(8, 4, 2));
  58. // dummy sample this texture so it doesn't get optimized out
  59. assert(texture(tex1[0], 0) != vec4(2, 2, 2, 2));
  60. """
  61. env.run_glsl(code, preamble, {'tex1[0]': tex1_0, 'tex1[1]': tex1_1, 'tex2': tex2, 'tex3': tex3, 'tex4': tex4})
  62. def test_glsl_texture_query_levels(env):
  63. tex1_0 = core.Texture("tex1-0-1d")
  64. tex1_0.setup_1d_texture(128, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  65. tex1_0.set_minfilter(core.SamplerState.FT_linear_mipmap_linear)
  66. tex1_1 = core.Texture("tex1-1-1d")
  67. tex1_1.setup_1d_texture(256, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  68. tex1_1.set_minfilter(core.SamplerState.FT_nearest)
  69. tex2 = core.Texture("tex2-2d")
  70. tex2.setup_2d_texture(64, 32, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  71. tex2.set_minfilter(core.SamplerState.FT_linear_mipmap_linear)
  72. tex3 = core.Texture("tex3-cube")
  73. tex3.setup_cube_map(16, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  74. tex3.set_minfilter(core.SamplerState.FT_linear_mipmap_linear)
  75. tex4 = core.Texture("tex4-3d")
  76. tex4.setup_3d_texture(8, 4, 2, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  77. tex4.set_minfilter(core.SamplerState.FT_linear_mipmap_linear)
  78. preamble = """
  79. uniform sampler1D tex1[2];
  80. uniform sampler2D tex2;
  81. uniform samplerCube tex3;
  82. uniform sampler3D tex4;
  83. """
  84. code = """
  85. assert(textureQueryLevels(tex1[1]) == 1);
  86. assert(textureQueryLevels(tex1[0]) == 8);
  87. assert(textureQueryLevels(tex2) == 7);
  88. assert(textureQueryLevels(tex3) == 5);
  89. assert(textureQueryLevels(tex4) == 4);
  90. """
  91. env.run_glsl(code, preamble, {'tex1[0]': tex1_0, 'tex1[1]': tex1_1, 'tex2': tex2, 'tex3': tex3, 'tex4': tex4}, version=430)
  92. def test_glsl_isampler(env):
  93. from struct import pack
  94. tex1 = core.Texture("")
  95. tex1.setup_1d_texture(1, core.Texture.T_byte, core.Texture.F_rgba8i)
  96. tex1.set_ram_image(pack('bbbb', 0, 1, 2, 3))
  97. tex2 = core.Texture("")
  98. tex2.setup_2d_texture(1, 1, core.Texture.T_short, core.Texture.F_r16i)
  99. tex2.set_ram_image(pack('h', 4))
  100. tex3 = core.Texture("")
  101. tex3.setup_3d_texture(1, 1, 1, core.Texture.T_int, core.Texture.F_r32i)
  102. tex3.set_ram_image(pack('i', 5))
  103. preamble = """
  104. uniform isampler1D tex1;
  105. uniform isampler2D tex2;
  106. uniform isampler3D tex3;
  107. """
  108. code = """
  109. assert(texelFetch(tex1, 0, 0) == ivec4(0, 1, 2, 3));
  110. assert(texelFetch(tex2, ivec2(0, 0), 0) == ivec4(4, 0, 0, 1));
  111. assert(texelFetch(tex3, ivec3(0, 0, 0), 0) == ivec4(5, 0, 0, 1));
  112. """
  113. env.run_glsl(code, preamble, {'tex1': tex1, 'tex2': tex2, 'tex3': tex3})
  114. def test_glsl_usampler(env):
  115. from struct import pack
  116. tex1 = core.Texture("")
  117. tex1.setup_1d_texture(1, core.Texture.T_unsigned_byte, core.Texture.F_rgba8i)
  118. tex1.set_ram_image(pack('BBBB', 0, 1, 2, 3))
  119. tex2 = core.Texture("")
  120. tex2.setup_2d_texture(1, 1, core.Texture.T_unsigned_short, core.Texture.F_r16i)
  121. tex2.set_ram_image(pack('H', 4))
  122. tex3 = core.Texture("")
  123. tex3.setup_3d_texture(1, 1, 1, core.Texture.T_unsigned_int, core.Texture.F_r32i)
  124. tex3.set_ram_image(pack('I', 5))
  125. preamble = """
  126. uniform usampler1D tex1;
  127. uniform usampler2D tex2;
  128. uniform usampler3D tex3;
  129. """
  130. code = """
  131. assert(texelFetch(tex1, 0, 0) == uvec4(0, 1, 2, 3));
  132. assert(texelFetch(tex2, ivec2(0, 0), 0) == uvec4(4, 0, 0, 1));
  133. assert(texelFetch(tex3, ivec3(0, 0, 0), 0) == uvec4(5, 0, 0, 1));
  134. """
  135. env.run_glsl(code, preamble, {'tex1': tex1, 'tex2': tex2, 'tex3': tex3})
  136. def test_glsl_image(env):
  137. tex1 = core.Texture("")
  138. tex1.setup_1d_texture(1, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  139. tex1.set_clear_color((0, 2 / 255.0, 1, 1))
  140. tex2 = core.Texture("")
  141. tex2.setup_2d_texture(1, 1, core.Texture.T_float, core.Texture.F_rgba32)
  142. tex2.set_clear_color((1.0, 2.0, -3.14, 0.0))
  143. preamble = """
  144. layout(rgba8) uniform image1D tex1;
  145. layout(rgba32f) uniform image2D tex2;
  146. """
  147. code = """
  148. assert(imageLoad(tex1, 0) == vec4(0, 2 / 255.0, 1, 1));
  149. assert(imageLoad(tex2, ivec2(0, 0)) == vec4(1.0, 2.0, -3.14, 0.0));
  150. """
  151. env.run_glsl(code, preamble, {'tex1': tex1, 'tex2': tex2})
  152. def test_glsl_iimage(env):
  153. from struct import pack
  154. tex1 = core.Texture("")
  155. tex1.setup_1d_texture(1, core.Texture.T_byte, core.Texture.F_rgba8i)
  156. tex1.set_ram_image(pack('bbbb', 0, 1, 2, 3))
  157. tex2 = core.Texture("")
  158. tex2.setup_2d_texture(1, 1, core.Texture.T_short, core.Texture.F_r16i)
  159. tex2.set_ram_image(pack('h', 4))
  160. tex3 = core.Texture("")
  161. tex3.setup_3d_texture(1, 1, 1, core.Texture.T_int, core.Texture.F_r32i)
  162. tex3.set_ram_image(pack('i', 5))
  163. preamble = """
  164. layout(rgba8i) uniform iimage1D tex1;
  165. layout(r16i) uniform iimage2D tex2;
  166. layout(r32i) uniform iimage3D tex3;
  167. """
  168. code = """
  169. assert(imageLoad(tex1, 0) == ivec4(0, 1, 2, 3));
  170. assert(imageLoad(tex2, ivec2(0, 0)) == ivec4(4, 0, 0, 1));
  171. assert(imageLoad(tex3, ivec3(0, 0, 0)) == ivec4(5, 0, 0, 1));
  172. """
  173. env.run_glsl(code, preamble, {'tex1': tex1, 'tex2': tex2, 'tex3': tex3})
  174. def test_glsl_uimage(env):
  175. from struct import pack
  176. tex1 = core.Texture("")
  177. tex1.setup_1d_texture(1, core.Texture.T_unsigned_byte, core.Texture.F_rgba8i)
  178. tex1.set_ram_image(pack('BBBB', 0, 1, 2, 3))
  179. tex2 = core.Texture("")
  180. tex2.setup_2d_texture(1, 1, core.Texture.T_unsigned_short, core.Texture.F_r16i)
  181. tex2.set_ram_image(pack('H', 4))
  182. tex3 = core.Texture("")
  183. tex3.setup_3d_texture(1, 1, 1, core.Texture.T_unsigned_int, core.Texture.F_r32i)
  184. tex3.set_ram_image(pack('I', 5))
  185. preamble = """
  186. layout(rgba8ui) uniform uimage1D tex1;
  187. layout(r16ui) uniform uimage2D tex2;
  188. layout(r32ui) uniform uimage3D tex3;
  189. """
  190. code = """
  191. assert(imageLoad(tex1, 0) == uvec4(0, 1, 2, 3));
  192. assert(imageLoad(tex2, ivec2(0, 0)) == uvec4(4, 0, 0, 1));
  193. assert(imageLoad(tex3, ivec3(0, 0, 0)) == uvec4(5, 0, 0, 1));
  194. """
  195. env.run_glsl(code, preamble, {'tex1': tex1, 'tex2': tex2, 'tex3': tex3})
  196. def test_glsl_image_size(env):
  197. tex1_0 = core.Texture("tex1-0-1d")
  198. tex1_0.setup_1d_texture(128, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  199. tex1_1 = core.Texture("tex1-1-1d")
  200. tex1_1.setup_1d_texture(256, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  201. tex2 = core.Texture("tex2-2d")
  202. tex2.setup_2d_texture(64, 32, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  203. tex3 = core.Texture("tex3-cube")
  204. tex3.setup_cube_map(16, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  205. tex4 = core.Texture("tex4-3d")
  206. tex4.setup_3d_texture(8, 4, 2, core.Texture.T_unsigned_byte, core.Texture.F_rgba8)
  207. preamble = """
  208. uniform writeonly image1D tex1[2];
  209. uniform writeonly image2D tex2;
  210. uniform writeonly imageCube tex3;
  211. uniform writeonly image3D tex4;
  212. """
  213. code = """
  214. assert(imageSize(tex1[0]) == 128);
  215. assert(imageSize(tex1[1]) == 256);
  216. assert(imageSize(tex2) == ivec2(64, 32));
  217. assert(imageSize(tex3) == ivec2(16, 16));
  218. assert(imageSize(tex4) == ivec3(8, 4, 2));
  219. """
  220. env.run_glsl(code, preamble, {'tex1[0]': tex1_0, 'tex1[1]': tex1_1, 'tex2': tex2, 'tex3': tex3, 'tex4': tex4}, version=430)
  221. def test_glsl_ssbo(env):
  222. from struct import pack, unpack
  223. num1 = pack('<i', 1234567)
  224. num2 = pack('<ii', -1234567, 0)
  225. buffer1 = core.ShaderBuffer("buffer1", num1, core.GeomEnums.UH_static)
  226. buffer2 = core.ShaderBuffer("buffer2", num2, core.GeomEnums.UH_static)
  227. buffer3 = core.ShaderBuffer("buffer3", 8, core.GeomEnums.UH_static)
  228. preamble = """
  229. layout(std430, binding=0) readonly buffer buffer1 {
  230. int value1;
  231. };
  232. layout(std430, binding=1) buffer buffer2 {
  233. readonly int value2;
  234. int value3;
  235. };
  236. layout(std430, binding=3) buffer buffer3 {
  237. writeonly int value4;
  238. int value5;
  239. };
  240. """
  241. # Assigning value3 to 999 first proves buffers aren't accidentally aliased
  242. code = """
  243. assert(value1 == 1234567);
  244. assert(value2 == -1234567);
  245. value3 = 98765;
  246. value4 = 5343525;
  247. value5 = 999;
  248. """
  249. env.run_glsl(code, preamble,
  250. {'buffer1': buffer1, 'buffer2': buffer2, 'buffer3': buffer3},
  251. version=430)
  252. data1 = env.engine.extract_shader_buffer_data(buffer2, env.gsg)
  253. assert unpack('<ii', data1[:8]) == (-1234567, 98765)
  254. data2 = env.engine.extract_shader_buffer_data(buffer3, env.gsg)
  255. assert unpack('<ii', data2[:8]) == (5343525, 999)
  256. def test_glsl_ssbo_array(env):
  257. from struct import pack
  258. dummy = pack('<i', 999999)
  259. num1 = pack('<i', 1234567)
  260. num2 = pack('<i', -1234567)
  261. unused = core.ShaderBuffer("unused", dummy, core.GeomEnums.UH_static)
  262. buffer1 = core.ShaderBuffer("buffer1", num1, core.GeomEnums.UH_static)
  263. buffer2 = core.ShaderBuffer("buffer2", num2, core.GeomEnums.UH_static)
  264. preamble = """
  265. struct InsideStruct {
  266. int value;
  267. };
  268. layout(std430, binding=0) buffer test {
  269. readonly InsideStruct inside[1];
  270. } test_ns[3][1];
  271. """
  272. code = """
  273. assert(test_ns[1][0].inside[0].value == 1234567);
  274. assert(test_ns[2][0].inside[0].value == -1234567);
  275. """
  276. env.run_glsl(code, preamble,
  277. {'test[0][0]': unused, 'test[1][0]': buffer1, 'test[2][0]': buffer2},
  278. version=430)
  279. def test_glsl_ssbo_runtime_length(env):
  280. from struct import pack
  281. nums = pack('<ii', 1234, 5678)
  282. ssbo = core.ShaderBuffer("ssbo", nums, core.GeomEnums.UH_static)
  283. preamble = """
  284. layout(std430, binding=0) buffer ssbo {
  285. int values[];
  286. };
  287. """
  288. code = """
  289. assert(values.length() == 2);
  290. assert(values[0] == 1234);
  291. assert(values[1] == 5678);
  292. """
  293. env.run_glsl(code, preamble, {'ssbo': ssbo}, version=430)
  294. def test_glsl_float(env):
  295. inputs = dict(
  296. zero=0,
  297. a=1.23,
  298. b=-829.123,
  299. array=(1, 2, 3, 4),
  300. )
  301. preamble = """
  302. uniform float zero;
  303. uniform float a;
  304. uniform float b;
  305. uniform float array[4];
  306. """
  307. code = """
  308. assert(zero == 0);
  309. assert(abs(a - 1.23) < 0.001);
  310. assert(abs(b - -829.123) < 0.001);
  311. assert(array[0] == 1.0);
  312. assert(array[1] == 2.0);
  313. assert(array[2] == 3.0);
  314. assert(array[3] == 4.0);
  315. """
  316. env.run_glsl(code, preamble, inputs)
  317. def test_glsl_int(env):
  318. inputs = dict(
  319. zero=0,
  320. intmax=0x7fffffff,
  321. intmin=-0x7fffffff,
  322. )
  323. preamble = """
  324. uniform int zero;
  325. uniform int intmax;
  326. uniform int intmin;
  327. """
  328. code = """
  329. assert(zero == 0);
  330. assert(intmax == 0x7fffffff);
  331. assert(intmin == -0x7fffffff);
  332. """
  333. env.run_glsl(code, preamble, inputs)
  334. def test_glsl_uint(env):
  335. #TODO: fix passing uints greater than intmax
  336. inputs = dict(
  337. zero=0,
  338. intmax=0x7fffffff,
  339. )
  340. preamble = """
  341. uniform uint zero;
  342. uniform uint intmax;
  343. """
  344. code = """
  345. assert(zero == 0u);
  346. assert(intmax == 0x7fffffffu);
  347. """
  348. env.run_glsl(code, preamble, inputs)
  349. #@pytest.mark.xfail(reason="https://github.com/KhronosGroup/SPIRV-Tools/issues/3387")
  350. def test_glsl_bool(env):
  351. flags = dict(
  352. flag1=False,
  353. flag2=0,
  354. flag3=0.0,
  355. flag4=True,
  356. flag5=1,
  357. flag6=3,
  358. )
  359. preamble = """
  360. uniform bool flag1;
  361. uniform bool flag2;
  362. uniform bool flag3;
  363. uniform bool flag4;
  364. uniform bool flag5;
  365. uniform bool flag6;
  366. """
  367. code = """
  368. assert(!flag1);
  369. assert(!flag2);
  370. assert(!flag3);
  371. assert(flag4);
  372. assert(flag5);
  373. assert(flag6);
  374. """
  375. env.run_glsl(code, preamble, flags)
  376. def test_glsl_mat3(env):
  377. param1 = core.LMatrix4f(core.LMatrix3f(1, 2, 3, 4, 5, 6, 7, 8, 9))
  378. param2 = core.LMatrix4d(core.LMatrix3d(10, 11, 12, 13, 14, 15, 16, 17, 18))
  379. param3 = core.NodePath("param3")
  380. param3.set_mat(core.LMatrix3(19, 20, 21, 22, 23, 24, 25, 26, 27))
  381. preamble = """
  382. uniform mat3 param1;
  383. uniform mat3 param2;
  384. uniform mat3 param3;
  385. """
  386. code = """
  387. assert(param1[0] == vec3(1, 2, 3));
  388. assert(param1[1] == vec3(4, 5, 6));
  389. assert(param1[2] == vec3(7, 8, 9));
  390. assert(param2[0] == vec3(10, 11, 12));
  391. assert(param2[1] == vec3(13, 14, 15));
  392. assert(param2[2] == vec3(16, 17, 18));
  393. assert(param3[0] == vec3(19, 20, 21));
  394. assert(param3[1] == vec3(22, 23, 24));
  395. assert(param3[2] == vec3(25, 26, 27));
  396. """
  397. env.run_glsl(code, preamble,
  398. {'param1': param1, 'param2': param2, 'param3': param3})
  399. def test_glsl_mat4(env):
  400. param1 = core.LMatrix4f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
  401. param2 = core.LMatrix4d(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32)
  402. param3 = core.NodePath("param3")
  403. param3.set_mat(core.LMatrix4(
  404. 33, 34, 35, 36,
  405. 37, 38, 39, 40,
  406. 41, 42, 43, 44,
  407. 45, 46, 47, 48))
  408. preamble = """
  409. uniform mat4 param1;
  410. uniform mat4 param2;
  411. uniform mat4 param3;
  412. """
  413. code = """
  414. assert(param1[0] == vec4(1, 2, 3, 4));
  415. assert(param1[1] == vec4(5, 6, 7, 8));
  416. assert(param1[2] == vec4(9, 10, 11, 12));
  417. assert(param1[3] == vec4(13, 14, 15, 16));
  418. assert(param2[0] == vec4(17, 18, 19, 20));
  419. assert(param2[1] == vec4(21, 22, 23, 24));
  420. assert(param2[2] == vec4(25, 26, 27, 28));
  421. assert(param2[3] == vec4(29, 30, 31, 32));
  422. assert(param3[0] == vec4(33, 34, 35, 36));
  423. assert(param3[1] == vec4(37, 38, 39, 40));
  424. assert(param3[2] == vec4(41, 42, 43, 44));
  425. assert(param3[3] == vec4(45, 46, 47, 48));
  426. """
  427. env.run_glsl(code, preamble,
  428. {'param1': param1, 'param2': param2, 'param3': param3})
  429. def test_glsl_mat3x4(env):
  430. param1 = core.LMatrix4f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
  431. param2 = core.LMatrix4d(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32)
  432. preamble = """
  433. uniform mat3x4 param1;
  434. uniform mat3x4 param2;
  435. """
  436. code = """
  437. assert(param1[0] == vec4(1, 2, 3, 4));
  438. assert(param1[1] == vec4(5, 6, 7, 8));
  439. assert(param1[2] == vec4(9, 10, 11, 12));
  440. assert(param2[0] == vec4(17, 18, 19, 20));
  441. assert(param2[1] == vec4(21, 22, 23, 24));
  442. assert(param2[2] == vec4(25, 26, 27, 28));
  443. """
  444. env.run_glsl(code, preamble,
  445. {'param1': param1, 'param2': param2})
  446. def test_glsl_mat4x3(env):
  447. param1 = core.LMatrix4f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
  448. param2 = core.LMatrix4d(17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32)
  449. preamble = """
  450. uniform mat4x3 param1;
  451. uniform mat4x3 param2;
  452. uniform mat4x3 param3;
  453. """
  454. code = """
  455. assert(param1[0] == vec3(1, 2, 3));
  456. assert(param1[1] == vec3(5, 6, 7));
  457. assert(param1[2] == vec3(9, 10, 11));
  458. assert(param1[3] == vec3(13, 14, 15));
  459. assert(param2[0] == vec3(17, 18, 19));
  460. assert(param2[1] == vec3(21, 22, 23));
  461. assert(param2[2] == vec3(25, 26, 27));
  462. assert(param2[3] == vec3(29, 30, 31));
  463. """
  464. env.run_glsl(code, preamble,
  465. {'param1': param1, 'param2': param2})
  466. def test_glsl_pta_int(env):
  467. pta = core.PTA_int((0, 1, 2, 3))
  468. preamble = """
  469. uniform int pta[4];
  470. """
  471. code = """
  472. assert(pta[0] == 0);
  473. assert(pta[1] == 1);
  474. assert(pta[2] == 2);
  475. assert(pta[3] == 3);
  476. """
  477. env.run_glsl(code, preamble, {'pta': pta})
  478. def test_glsl_pta_ivec4(env):
  479. pta = core.PTA_LVecBase4i(((0, 1, 2, 3), (4, 5, 6, 7)))
  480. preamble = """
  481. uniform ivec4 pta[2];
  482. """
  483. code = """
  484. assert(pta[0] == ivec4(0, 1, 2, 3));
  485. assert(pta[1] == ivec4(4, 5, 6, 7));
  486. """
  487. env.run_glsl(code, preamble, {'pta': pta})
  488. @pytest.mark.parametrize("type", (core.PTA_LVecBase3f, core.PTA_LVecBase3d, core.PTA_LVecBase3i))
  489. def test_glsl_pta_vec3(env, type):
  490. pta = type((
  491. (0, 1, 2),
  492. (3, 4, 5),
  493. (6, 7, 8),
  494. ))
  495. preamble = """
  496. uniform vec3 pta[3];
  497. """
  498. code = """
  499. assert(pta[0] == vec3(0, 1, 2));
  500. assert(pta[1] == vec3(3, 4, 5));
  501. assert(pta[2] == vec3(6, 7, 8));
  502. """
  503. env.run_glsl(code, preamble, {'pta': pta})
  504. @pytest.mark.parametrize("type", (core.PTA_LVecBase3f, core.PTA_LVecBase3d, core.PTA_LVecBase3i))
  505. def test_glsl_pta_dvec3(env, type):
  506. pta = type((
  507. (0, 1, 2),
  508. (3, 4, 5),
  509. (6, 7, 8),
  510. ))
  511. preamble = """
  512. uniform dvec3 pta[3];
  513. """
  514. code = """
  515. assert(pta[0] == vec3(0, 1, 2));
  516. assert(pta[1] == vec3(3, 4, 5));
  517. assert(pta[2] == vec3(6, 7, 8));
  518. """
  519. env.run_glsl(code, preamble, {'pta': pta})
  520. @pytest.mark.parametrize("type", (core.PTA_LVecBase4f, core.PTA_LVecBase4d, core.PTA_LVecBase4i))
  521. def test_glsl_pta_vec4(env, type):
  522. pta = type((
  523. (0, 1, 2, 3),
  524. (4, 5, 6, 7),
  525. (8, 9, 10, 11),
  526. ))
  527. preamble = """
  528. uniform vec4 pta[4];
  529. """
  530. code = """
  531. assert(pta[0] == vec4(0, 1, 2, 3));
  532. assert(pta[1] == vec4(4, 5, 6, 7));
  533. assert(pta[2] == vec4(8, 9, 10, 11));
  534. """
  535. env.run_glsl(code, preamble, {'pta': pta})
  536. @pytest.mark.parametrize("type", (core.PTA_LVecBase4f, core.PTA_LVecBase4d, core.PTA_LVecBase4i))
  537. def test_glsl_pta_dvec4(env, type):
  538. pta = type((
  539. (0, 1, 2, 3),
  540. (4, 5, 6, 7),
  541. (8, 9, 10, 11),
  542. ))
  543. preamble = """
  544. uniform dvec4 pta[4];
  545. """
  546. code = """
  547. assert(pta[0] == dvec4(0, 1, 2, 3));
  548. assert(pta[1] == dvec4(4, 5, 6, 7));
  549. assert(pta[2] == dvec4(8, 9, 10, 11));
  550. """
  551. env.run_glsl(code, preamble, {'pta': pta})
  552. @pytest.mark.parametrize("type", (core.PTA_LMatrix3f, core.PTA_LMatrix3d))
  553. def test_glsl_pta_mat3(env, type):
  554. pta = type((
  555. (0, 1, 2, 3, 4, 5, 6, 7, 8),
  556. (9, 10, 11, 12, 13, 14, 15, 16, 17),
  557. ))
  558. preamble = """
  559. uniform mat3 pta[2];
  560. """
  561. code = """
  562. assert(pta[0][0] == vec3(0, 1, 2));
  563. assert(pta[0][1] == vec3(3, 4, 5));
  564. assert(pta[0][2] == vec3(6, 7, 8));
  565. assert(pta[1][0] == vec3(9, 10, 11));
  566. assert(pta[1][1] == vec3(12, 13, 14));
  567. assert(pta[1][2] == vec3(15, 16, 17));
  568. """
  569. env.run_glsl(code, preamble, {'pta': pta})
  570. @pytest.mark.parametrize("type", (core.PTA_LMatrix4f, core.PTA_LMatrix4d))
  571. def test_glsl_pta_mat4(env, type):
  572. pta = type((
  573. (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
  574. (16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31),
  575. ))
  576. preamble = """
  577. uniform mat4 pta[2];
  578. """
  579. code = """
  580. assert(pta[0][0] == vec4(0, 1, 2, 3));
  581. assert(pta[0][1] == vec4(4, 5, 6, 7));
  582. assert(pta[0][2] == vec4(8, 9, 10, 11));
  583. assert(pta[0][3] == vec4(12, 13, 14, 15));
  584. assert(pta[1][0] == vec4(16, 17, 18, 19));
  585. assert(pta[1][1] == vec4(20, 21, 22, 23));
  586. assert(pta[1][2] == vec4(24, 25, 26, 27));
  587. assert(pta[1][3] == vec4(28, 29, 30, 31));
  588. """
  589. env.run_glsl(code, preamble, {'pta': pta})
  590. def test_glsl_param_vec4(env):
  591. param = core.ParamVecBase4((0, 1, 2, 3))
  592. preamble = """
  593. uniform vec4 param;
  594. """
  595. code = """
  596. assert(param.x == 0.0);
  597. assert(param.y == 1.0);
  598. assert(param.z == 2.0);
  599. assert(param.w == 3.0);
  600. """
  601. env.run_glsl(code, preamble, {'param': param})
  602. def test_glsl_param_ivec4(env):
  603. param = core.ParamVecBase4i((0, 1, 2, 3))
  604. preamble = """
  605. uniform ivec4 param;
  606. """
  607. code = """
  608. assert(param.x == 0);
  609. assert(param.y == 1);
  610. assert(param.z == 2);
  611. assert(param.w == 3);
  612. """
  613. env.run_glsl(code, preamble, {'param': param})
  614. def test_glsl_struct(env):
  615. preamble = """
  616. uniform struct TestStruct {
  617. vec3 a;
  618. float b;
  619. sampler2D c;
  620. float unused;
  621. vec3 d[2];
  622. vec2 e;
  623. sampler2D f;
  624. } test;
  625. """
  626. code = """
  627. assert(test.a == vec3(1, 2, 3));
  628. assert(test.b == 4);
  629. assert(texture(test.c, vec2(0, 0)).r == 5);
  630. assert(test.d[0] == vec3(6, 7, 8));
  631. assert(test.d[1] == vec3(9, 10, 11));
  632. assert(test.e == vec2(12, 13));
  633. assert(texture(test.f, vec2(0, 0)).r == 14);
  634. """
  635. tex_c = core.Texture('c')
  636. tex_c.setup_2d_texture(1, 1, core.Texture.T_float, core.Texture.F_r32)
  637. tex_c.set_clear_color((5, 0, 0, 0))
  638. tex_f = core.Texture('f')
  639. tex_f.setup_2d_texture(1, 1, core.Texture.T_float, core.Texture.F_r32)
  640. tex_f.set_clear_color((14, 0, 0, 0))
  641. env.run_glsl(code, preamble, {
  642. 'test.unused': 0,
  643. 'test.a': (1, 2, 3),
  644. 'test.b': 4,
  645. 'test.c': tex_c,
  646. 'test.d': [(6, 7, 8), (9, 10, 11)],
  647. 'test.e': [12, 13],
  648. 'test.f': tex_f,
  649. })
  650. def test_glsl_struct_nested(env):
  651. preamble = """
  652. struct TestSubStruct1 {
  653. float a;
  654. float b;
  655. };
  656. struct TestSubStruct2 {
  657. float unused;
  658. sampler2D a;
  659. vec2 b;
  660. };
  661. uniform struct TestStruct {
  662. vec3 a;
  663. TestSubStruct1 b;
  664. TestSubStruct2 c;
  665. float d;
  666. } test;
  667. """
  668. code = """
  669. assert(test.a == vec3(1, 2, 3));
  670. assert(test.b.a == 4);
  671. assert(test.b.b == 5);
  672. assert(texture(test.c.a, vec2(0, 0)).r == 6);
  673. assert(test.c.b == vec2(7, 8));
  674. assert(test.d == 9);
  675. """
  676. tex_c_a = core.Texture()
  677. tex_c_a.setup_2d_texture(1, 1, core.Texture.T_float, core.Texture.F_r32)
  678. tex_c_a.set_clear_color((6, 0, 0, 0))
  679. env.run_glsl(code, preamble, {
  680. 'test.unused': 0,
  681. 'test.a': (1, 2, 3),
  682. 'test.b.a': 4,
  683. 'test.b.b': 5,
  684. 'test.c.unused': 0,
  685. 'test.c.a': tex_c_a,
  686. 'test.c.b': (7, 8),
  687. 'test.d': 9,
  688. })
  689. def test_glsl_struct_array(env):
  690. preamble = """
  691. uniform struct TestStruct {
  692. vec3 a;
  693. sampler2D b;
  694. float unused;
  695. float c;
  696. } test[2];
  697. """
  698. code = """
  699. assert(test[0].a == vec3(1, 2, 3));
  700. assert(texture(test[0].b, vec2(0, 0)).r == 4);
  701. assert(test[0].c == 5);
  702. assert(test[1].a == vec3(6, 7, 8));
  703. assert(texture(test[1].b, vec2(0, 0)).r == 9);
  704. assert(test[1].c == 10);
  705. """
  706. tex_0_b = core.Texture()
  707. tex_0_b.setup_2d_texture(1, 1, core.Texture.T_float, core.Texture.F_r32)
  708. tex_0_b.set_clear_color((4, 0, 0, 0))
  709. tex_1_b = core.Texture()
  710. tex_1_b.setup_2d_texture(1, 1, core.Texture.T_float, core.Texture.F_r32)
  711. tex_1_b.set_clear_color((9, 0, 0, 0))
  712. env.run_glsl(code, preamble, {
  713. 'test[0].unused': 0,
  714. 'test[0].a': (1, 2, 3),
  715. 'test[0].b': tex_0_b,
  716. 'test[0].c': 5,
  717. 'test[1].unused': 0,
  718. 'test[1].a': (6, 7, 8),
  719. 'test[1].b': tex_1_b,
  720. 'test[1].c': 10,
  721. })
  722. def test_glsl_struct_pseudo_light(env):
  723. # Something that looks like a named light source, but isn't one at all
  724. preamble = """
  725. struct FakeLightParameters {
  726. vec4 specular;
  727. vec4 position;
  728. vec3 attenuation;
  729. float constantAttenuation;
  730. float radius;
  731. };
  732. uniform FakeLightParameters test;
  733. """
  734. code = """
  735. assert(test.specular == vec4(1, 2, 3, 4));
  736. assert(test.position == vec4(5, 6, 7, 8));
  737. assert(test.attenuation == vec3(9, 10, 11));
  738. assert(test.constantAttenuation == 12);
  739. assert(test.radius == 13);
  740. """
  741. env.run_glsl(code, preamble, {
  742. 'test.specular': (1, 2, 3, 4),
  743. 'test.position': (5, 6, 7, 8),
  744. 'test.attenuation': (9, 10, 11),
  745. 'test.constantAttenuation': 12,
  746. 'test.radius': 13,
  747. })
  748. def test_glsl_light(env):
  749. preamble = """
  750. uniform struct p3d_LightSourceParameters {
  751. vec4 color;
  752. vec3 ambient;
  753. vec4 diffuse;
  754. vec4 specular;
  755. vec3 position;
  756. vec4 halfVector;
  757. vec4 spotDirection;
  758. float spotCutoff;
  759. float spotCosCutoff;
  760. float spotExponent;
  761. vec3 attenuation;
  762. float constantAttenuation;
  763. float linearAttenuation;
  764. float quadraticAttenuation;
  765. } plight;
  766. """
  767. code = """
  768. assert(plight.color == vec4(1, 2, 3, 4));
  769. assert(plight.ambient == vec3(0, 0, 0));
  770. assert(plight.diffuse == vec4(1, 2, 3, 4));
  771. assert(plight.specular == vec4(5, 6, 7, 8));
  772. assert(plight.position == vec3(9, 10, 11));
  773. assert(plight.spotCutoff == 180);
  774. assert(plight.spotCosCutoff == -1);
  775. assert(plight.spotExponent == 0);
  776. assert(plight.attenuation == vec3(12, 13, 14));
  777. assert(plight.constantAttenuation == 12);
  778. assert(plight.linearAttenuation == 13);
  779. assert(plight.quadraticAttenuation == 14);
  780. """
  781. plight = core.PointLight("plight")
  782. plight.color = (1, 2, 3, 4)
  783. plight.specular_color = (5, 6, 7, 8)
  784. plight.transform = core.TransformState.make_pos((9, 10, 11))
  785. plight.attenuation = (12, 13, 14)
  786. env.run_glsl(code, preamble, {
  787. 'plight': core.NodePath(plight),
  788. })
  789. def test_glsl_named_light_source(env):
  790. spot = core.Spotlight("spot")
  791. spot.get_lens().set_fov(90, 90)
  792. spot.set_color((1, 2, 3, 4))
  793. spot.set_specular_color((5, 6, 7, 8))
  794. preamble = """
  795. struct p3d_LightSourceParameters {
  796. vec4 color;
  797. vec4 specular;
  798. };
  799. uniform p3d_LightSourceParameters spot;
  800. """
  801. code = """
  802. assert(spot.color == vec4(1, 2, 3, 4));
  803. assert(spot.specular == vec4(5, 6, 7, 8));
  804. """
  805. env.run_glsl(code, preamble, {'spot': core.NodePath(spot)})
  806. def test_glsl_state_light(env):
  807. preamble = """
  808. uniform struct p3d_LightSourceParameters {
  809. vec4 color;
  810. vec3 ambient;
  811. vec4 diffuse;
  812. vec4 specular;
  813. vec4 position;
  814. vec4 halfVector;
  815. vec4 spotDirection;
  816. float spotCutoff;
  817. float spotCosCutoff;
  818. float spotExponent;
  819. vec3 attenuation;
  820. float constantAttenuation;
  821. float linearAttenuation;
  822. float quadraticAttenuation;
  823. } p3d_LightSource[2];
  824. """
  825. code = """
  826. assert(p3d_LightSource[0].color == vec4(1, 2, 3, 4));
  827. assert(p3d_LightSource[0].ambient == vec3(0, 0, 0));
  828. assert(p3d_LightSource[0].diffuse == vec4(1, 2, 3, 4));
  829. assert(p3d_LightSource[0].specular == vec4(5, 6, 7, 8));
  830. assert(p3d_LightSource[0].position == vec4(9, 10, 11, 1));
  831. assert(p3d_LightSource[0].spotCutoff == 180);
  832. assert(p3d_LightSource[0].spotCosCutoff == -1);
  833. assert(p3d_LightSource[0].spotExponent == 0);
  834. assert(p3d_LightSource[0].attenuation == vec3(12, 13, 14));
  835. assert(p3d_LightSource[0].constantAttenuation == 12);
  836. assert(p3d_LightSource[0].linearAttenuation == 13);
  837. assert(p3d_LightSource[0].quadraticAttenuation == 14);
  838. assert(p3d_LightSource[1].color == vec4(15, 16, 17, 18));
  839. assert(p3d_LightSource[1].ambient == vec3(0, 0, 0));
  840. assert(p3d_LightSource[1].diffuse == vec4(15, 16, 17, 18));
  841. assert(p3d_LightSource[1].specular == vec4(19, 20, 21, 22));
  842. assert(p3d_LightSource[1].position == vec4(0, 1, 0, 0));
  843. assert(p3d_LightSource[1].spotCutoff == 180);
  844. assert(p3d_LightSource[1].spotCosCutoff == -1);
  845. assert(p3d_LightSource[1].spotExponent == 0);
  846. assert(p3d_LightSource[1].attenuation == vec3(1, 0, 0));
  847. assert(p3d_LightSource[1].constantAttenuation == 1);
  848. assert(p3d_LightSource[1].linearAttenuation == 0);
  849. assert(p3d_LightSource[1].quadraticAttenuation == 0);
  850. """
  851. plight = core.PointLight("plight")
  852. plight.priority = 0
  853. plight.color = (1, 2, 3, 4)
  854. plight.specular_color = (5, 6, 7, 8)
  855. plight.transform = core.TransformState.make_pos((9, 10, 11))
  856. plight.attenuation = (12, 13, 14)
  857. plight_path = core.NodePath(plight)
  858. dlight = core.DirectionalLight("dlight")
  859. dlight.priority = -1
  860. dlight.direction = (0, -1, 0)
  861. dlight.color = (15, 16, 17, 18)
  862. dlight.specular_color = (19, 20, 21, 22)
  863. dlight.transform = core.TransformState.make_pos((23, 24, 25))
  864. dlight_path = core.NodePath(dlight)
  865. lattr = core.LightAttrib.make()
  866. lattr = lattr.add_on_light(plight_path)
  867. lattr = lattr.add_on_light(dlight_path)
  868. state = core.RenderState.make(lattr)
  869. env.run_glsl(code, preamble, state=state)
  870. def test_glsl_state_light_source(env):
  871. spot = core.Spotlight("spot")
  872. spot.priority = 3
  873. spot.get_lens().set_fov(120, 120)
  874. spot.set_color((1, 2, 3, 4))
  875. spot.set_specular_color((5, 6, 7, 8))
  876. spot.attenuation = (23, 24, 25)
  877. spot.exponent = 26
  878. dire = core.DirectionalLight("dire")
  879. dire.priority = 2
  880. dire.set_color((9, 10, 11, 12))
  881. dire.set_specular_color((13, 14, 15, 16))
  882. dire.direction = (17, 18, 19)
  883. preamble = """
  884. struct p3d_LightSourceParameters {
  885. vec4 color;
  886. vec4 specular;
  887. vec4 ambient;
  888. vec4 diffuse;
  889. vec4 position;
  890. vec3 attenuation;
  891. float constantAttenuation;
  892. float linearAttenuation;
  893. float quadraticAttenuation;
  894. float spotExponent;
  895. float spotCosCutoff;
  896. float spotCutoff;
  897. mat4 shadowViewMatrix;
  898. };
  899. uniform p3d_LightSourceParameters p3d_LightSource[3];
  900. """
  901. code = """
  902. assert(p3d_LightSource[0].color == vec4(1, 2, 3, 4));
  903. assert(p3d_LightSource[0].specular == vec4(5, 6, 7, 8));
  904. assert(p3d_LightSource[0].ambient == vec4(0, 0, 0, 1));
  905. assert(p3d_LightSource[0].diffuse == vec4(1, 2, 3, 4));
  906. assert(p3d_LightSource[0].position == vec4(20, 21, 22, 1));
  907. assert(p3d_LightSource[0].attenuation == vec3(23, 24, 25));
  908. assert(p3d_LightSource[0].constantAttenuation == 23);
  909. assert(p3d_LightSource[0].linearAttenuation == 24);
  910. assert(p3d_LightSource[0].quadraticAttenuation == 25);
  911. assert(p3d_LightSource[0].spotExponent == 26);
  912. assert(p3d_LightSource[0].spotCosCutoff > 0.499);
  913. assert(p3d_LightSource[0].spotCosCutoff < 0.501);
  914. assert(p3d_LightSource[0].spotCutoff == 60);
  915. assert(p3d_LightSource[0].shadowViewMatrix[0][0] > 0.2886);
  916. assert(p3d_LightSource[0].shadowViewMatrix[0][0] < 0.2887);
  917. assert(p3d_LightSource[0].shadowViewMatrix[0][1] == 0);
  918. assert(p3d_LightSource[0].shadowViewMatrix[0][2] == 0);
  919. assert(p3d_LightSource[0].shadowViewMatrix[0][3] == 0);
  920. assert(p3d_LightSource[0].shadowViewMatrix[1][0] == 0.5);
  921. assert(p3d_LightSource[0].shadowViewMatrix[1][1] == 0.5);
  922. assert(p3d_LightSource[0].shadowViewMatrix[1][2] > 1.0);
  923. assert(p3d_LightSource[0].shadowViewMatrix[1][2] < 1.00002);
  924. assert(p3d_LightSource[0].shadowViewMatrix[1][3] == 1);
  925. assert(p3d_LightSource[0].shadowViewMatrix[2][0] == 0);
  926. assert(p3d_LightSource[0].shadowViewMatrix[2][1] > 0.2886);
  927. assert(p3d_LightSource[0].shadowViewMatrix[2][1] < 0.2887);
  928. assert(p3d_LightSource[0].shadowViewMatrix[2][2] == 0);
  929. assert(p3d_LightSource[0].shadowViewMatrix[2][3] == 0);
  930. assert(p3d_LightSource[0].shadowViewMatrix[3][0] > -16.2736);
  931. assert(p3d_LightSource[0].shadowViewMatrix[3][0] < -16.2734);
  932. assert(p3d_LightSource[0].shadowViewMatrix[3][1] > -16.8510);
  933. assert(p3d_LightSource[0].shadowViewMatrix[3][1] < -16.8508);
  934. assert(p3d_LightSource[0].shadowViewMatrix[3][2] > -22.0003);
  935. assert(p3d_LightSource[0].shadowViewMatrix[3][2] < -22.0001);
  936. assert(p3d_LightSource[0].shadowViewMatrix[3][3] > -21.0001);
  937. assert(p3d_LightSource[0].shadowViewMatrix[3][3] < -20.9999);
  938. assert(p3d_LightSource[1].color == vec4(9, 10, 11, 12));
  939. assert(p3d_LightSource[1].specular == vec4(13, 14, 15, 16));
  940. assert(p3d_LightSource[1].diffuse == vec4(9, 10, 11, 12));
  941. assert(p3d_LightSource[1].ambient == vec4(0, 0, 0, 1));
  942. assert(p3d_LightSource[1].position == vec4(-17, -18, -19, 0));
  943. assert(p3d_LightSource[1].attenuation == vec3(1, 0, 0));
  944. assert(p3d_LightSource[1].constantAttenuation == 1);
  945. assert(p3d_LightSource[1].linearAttenuation == 0);
  946. assert(p3d_LightSource[1].quadraticAttenuation == 0);
  947. assert(p3d_LightSource[1].spotExponent == 0);
  948. assert(p3d_LightSource[1].spotCosCutoff == -1);
  949. assert(p3d_LightSource[2].color == vec4(0, 0, 0, 1));
  950. assert(p3d_LightSource[2].specular == vec4(0, 0, 0, 1));
  951. assert(p3d_LightSource[2].diffuse == vec4(0, 0, 0, 1));
  952. assert(p3d_LightSource[2].ambient == vec4(0, 0, 0, 1));
  953. assert(p3d_LightSource[2].position == vec4(0, 0, 1, 0));
  954. assert(p3d_LightSource[2].attenuation == vec3(1, 0, 0));
  955. assert(p3d_LightSource[2].constantAttenuation == 1);
  956. assert(p3d_LightSource[2].linearAttenuation == 0);
  957. assert(p3d_LightSource[2].quadraticAttenuation == 0);
  958. assert(p3d_LightSource[2].spotExponent == 0);
  959. assert(p3d_LightSource[2].spotCosCutoff == -1);
  960. """
  961. node = core.NodePath("state")
  962. spot_path = node.attach_new_node(spot)
  963. spot_path.set_pos(20, 21, 22)
  964. node.set_light(spot_path)
  965. dire_path = node.attach_new_node(dire)
  966. node.set_light(dire_path)
  967. env.run_glsl(code, preamble, state=node.get_state())
  968. def test_glsl_state_material(env):
  969. mat = core.Material("mat")
  970. mat.ambient = (1, 2, 3, 4)
  971. mat.diffuse = (5, 6, 7, 8)
  972. mat.emission = (9, 10, 11, 12)
  973. mat.specular = (13, 14, 15, 0)
  974. mat.shininess = 16
  975. mat.metallic = 0.5
  976. mat.refractive_index = 21
  977. preamble = """
  978. struct p3d_MaterialParameters {
  979. vec4 ambient;
  980. vec4 diffuse;
  981. vec4 emission;
  982. vec3 specular;
  983. float shininess;
  984. float metallic;
  985. float refractiveIndex;
  986. };
  987. uniform p3d_MaterialParameters p3d_Material;
  988. """
  989. code = """
  990. assert(p3d_Material.ambient == vec4(1, 2, 3, 4));
  991. assert(p3d_Material.diffuse == vec4(5, 6, 7, 8));
  992. assert(p3d_Material.emission == vec4(9, 10, 11, 12));
  993. assert(p3d_Material.specular == vec3(13, 14, 15));
  994. assert(p3d_Material.shininess == 16);
  995. assert(p3d_Material.metallic == 0.5);
  996. assert(p3d_Material.refractiveIndex == 21);
  997. """
  998. node = core.NodePath("state")
  999. node.set_material(mat)
  1000. env.run_glsl(code, preamble, state=node.get_state())
  1001. def test_glsl_state_material_pbr(env):
  1002. mat = core.Material("mat")
  1003. mat.base_color = (1, 2, 3, 4)
  1004. mat.emission = (9, 10, 11, 12)
  1005. mat.roughness = 16
  1006. mat.metallic = 0.5
  1007. mat.refractive_index = 21
  1008. preamble = """
  1009. struct p3d_MaterialParameters {
  1010. vec4 baseColor;
  1011. vec4 emission;
  1012. float metallic;
  1013. float refractiveIndex;
  1014. float roughness;
  1015. };
  1016. uniform p3d_MaterialParameters p3d_Material;
  1017. """
  1018. code = """
  1019. assert(p3d_Material.baseColor == vec4(1, 2, 3, 4));
  1020. assert(p3d_Material.emission == vec4(9, 10, 11, 12));
  1021. assert(p3d_Material.roughness == 16);
  1022. assert(p3d_Material.metallic == 0.5);
  1023. assert(p3d_Material.refractiveIndex == 21);
  1024. """
  1025. node = core.NodePath("state")
  1026. node.set_material(mat)
  1027. env.run_glsl(code, preamble, state=node.get_state())
  1028. def test_glsl_state_fog(env):
  1029. fog = core.Fog("fog")
  1030. fog.color = (1, 2, 3, 4)
  1031. fog.exp_density = 0.5
  1032. fog.set_linear_range(6, 10)
  1033. preamble = """
  1034. struct p3d_FogParameters {
  1035. vec4 color;
  1036. float density;
  1037. float start;
  1038. float end;
  1039. float scale;
  1040. };
  1041. uniform p3d_FogParameters p3d_Fog;
  1042. """
  1043. code = """
  1044. assert(p3d_Fog.color == vec4(1, 2, 3, 4));
  1045. assert(p3d_Fog.density == 0.5);
  1046. assert(p3d_Fog.start == 6);
  1047. assert(p3d_Fog.end == 10);
  1048. assert(p3d_Fog.scale == 0.25);
  1049. """
  1050. node = core.NodePath("state")
  1051. node.set_fog(fog)
  1052. env.run_glsl(code, preamble, state=node.get_state())
  1053. def test_glsl_state_texture(env):
  1054. def gen_texture(v):
  1055. tex = core.Texture(f"tex{v}")
  1056. tex.setup_2d_texture(1, 1, core.Texture.T_unsigned_byte, core.Texture.F_red)
  1057. tex.set_clear_color((v / 255.0, 0, 0, 0))
  1058. return tex
  1059. np = core.NodePath("test")
  1060. ts1 = core.TextureStage("ts1")
  1061. ts1.sort = 10
  1062. ts1.mode = core.TextureStage.M_modulate
  1063. np.set_texture(ts1, gen_texture(1))
  1064. ts2 = core.TextureStage("ts2")
  1065. ts2.sort = 20
  1066. ts2.mode = core.TextureStage.M_add
  1067. np.set_texture(ts2, gen_texture(2))
  1068. ts3 = core.TextureStage("ts3")
  1069. ts3.sort = 30
  1070. ts3.mode = core.TextureStage.M_modulate
  1071. np.set_texture(ts3, gen_texture(3))
  1072. ts4 = core.TextureStage("ts4")
  1073. ts4.sort = 40
  1074. ts4.mode = core.TextureStage.M_normal_height
  1075. np.set_texture(ts4, gen_texture(4))
  1076. ts5 = core.TextureStage("ts5")
  1077. ts5.sort = 50
  1078. ts5.mode = core.TextureStage.M_add
  1079. np.set_texture(ts5, gen_texture(5))
  1080. ts6 = core.TextureStage("ts6")
  1081. ts6.sort = 60
  1082. ts6.mode = core.TextureStage.M_normal
  1083. np.set_texture(ts6, gen_texture(6))
  1084. # Do this in multiple passes to stay under sampler limit of 16
  1085. preamble = """
  1086. uniform sampler2D p3d_Texture2;
  1087. uniform sampler2D p3d_Texture0;
  1088. uniform sampler2D p3d_Texture1;
  1089. uniform sampler2D p3d_Texture3;
  1090. uniform sampler2D p3d_Texture4;
  1091. uniform sampler2D p3d_Texture5;
  1092. uniform sampler2D p3d_Texture6;
  1093. uniform sampler2D p3d_Texture[7];
  1094. """
  1095. code = """
  1096. vec2 coord = vec2(0, 0);
  1097. assert(abs(texture(p3d_Texture2, coord).r - 3.0 / 255.0) < 0.001);
  1098. assert(abs(texture(p3d_Texture0, coord).r - 1.0 / 255.0) < 0.001);
  1099. assert(abs(texture(p3d_Texture1, coord).r - 2.0 / 255.0) < 0.001);
  1100. assert(abs(texture(p3d_Texture3, coord).r - 4.0 / 255.0) < 0.001);
  1101. assert(abs(texture(p3d_Texture4, coord).r - 5.0 / 255.0) < 0.001);
  1102. assert(abs(texture(p3d_Texture5, coord).r - 6.0 / 255.0) < 0.001);
  1103. assert(texture(p3d_Texture6, coord).r == 1.0);
  1104. assert(abs(texture(p3d_Texture[0], coord).r - 1.0 / 255.0) < 0.001);
  1105. assert(abs(texture(p3d_Texture[2], coord).r - 3.0 / 255.0) < 0.001);
  1106. assert(abs(texture(p3d_Texture[3], coord).r - 4.0 / 255.0) < 0.001);
  1107. assert(abs(texture(p3d_Texture[1], coord).r - 2.0 / 255.0) < 0.001);
  1108. assert(abs(texture(p3d_Texture[4], coord).r - 5.0 / 255.0) < 0.001);
  1109. assert(abs(texture(p3d_Texture[5], coord).r - 6.0 / 255.0) < 0.001);
  1110. assert(texture(p3d_Texture[6], coord).r == 1.0);
  1111. """
  1112. env.run_glsl(code, preamble, state=np.get_state())
  1113. preamble = """
  1114. uniform sampler2D p3d_TextureFF[5];
  1115. uniform sampler2D p3d_TextureModulate[3];
  1116. uniform sampler2D p3d_TextureAdd[3];
  1117. uniform sampler2D p3d_TextureNormal[3];
  1118. uniform sampler2D p3d_TextureHeight[2];
  1119. """
  1120. code = """
  1121. vec2 coord = vec2(0, 0);
  1122. assert(abs(texture(p3d_TextureFF[0], coord).r - 1.0 / 255.0) < 0.001);
  1123. assert(abs(texture(p3d_TextureFF[1], coord).r - 2.0 / 255.0) < 0.001);
  1124. assert(abs(texture(p3d_TextureFF[2], coord).r - 3.0 / 255.0) < 0.001);
  1125. assert(abs(texture(p3d_TextureFF[3], coord).r - 5.0 / 255.0) < 0.001);
  1126. assert(texture(p3d_TextureFF[4], coord).r == 1.0);
  1127. assert(abs(texture(p3d_TextureModulate[0], coord).r - 1.0 / 255.0) < 0.001);
  1128. assert(abs(texture(p3d_TextureModulate[1], coord).r - 3.0 / 255.0) < 0.001);
  1129. assert(texture(p3d_TextureModulate[2], coord).r == 1.0);
  1130. assert(abs(texture(p3d_TextureAdd[0], coord).r - 2.0 / 255.0) < 0.001);
  1131. assert(abs(texture(p3d_TextureAdd[1], coord).r - 5.0 / 255.0) < 0.001);
  1132. assert(texture(p3d_TextureAdd[2], coord) == vec4(0.0, 0.0, 0.0, 1.0));
  1133. assert(abs(texture(p3d_TextureNormal[0], coord).r - 4.0 / 255.0) < 0.001);
  1134. assert(abs(texture(p3d_TextureNormal[1], coord).r - 6.0 / 255.0) < 0.001);
  1135. assert(all(lessThan(abs(texture(p3d_TextureNormal[2], coord) - vec4(127 / 255.0, 127 / 255.0, 1.0, 0.0)), vec4(0.004))));
  1136. assert(texture(p3d_TextureHeight[0], coord).r == 4.0 / 255.0);
  1137. assert(all(lessThan(abs(texture(p3d_TextureHeight[1], coord) - vec4(127 / 255.0, 127 / 255.0, 1.0, 0.0)), vec4(0.004))));
  1138. """
  1139. env.run_glsl(code, preamble, state=np.get_state())
  1140. def test_glsl_frame_number(env):
  1141. clock = core.ClockObject.get_global_clock()
  1142. old_frame_count = clock.get_frame_count()
  1143. try:
  1144. clock.set_frame_count(123)
  1145. preamble = """
  1146. uniform int osg_FrameNumber;
  1147. """
  1148. code = """
  1149. assert(osg_FrameNumber == 123);
  1150. """
  1151. env.run_glsl(code, preamble)
  1152. finally:
  1153. clock.set_frame_count(old_frame_count)
  1154. def test_glsl_write_extract_image_buffer(env):
  1155. # Tests that we can write to a buffer texture on the GPU, and then extract
  1156. # the data on the CPU. We test two textures since there was in the past a
  1157. # where it would only work correctly for one texture.
  1158. tex1 = core.Texture("tex1")
  1159. tex1.set_clear_color(0)
  1160. tex1.setup_buffer_texture(1, core.Texture.T_unsigned_int, core.Texture.F_r32i,
  1161. core.GeomEnums.UH_static)
  1162. tex2 = core.Texture("tex2")
  1163. tex2.set_clear_color(0)
  1164. tex2.setup_buffer_texture(1, core.Texture.T_int, core.Texture.F_r32i,
  1165. core.GeomEnums.UH_static)
  1166. preamble = """
  1167. layout(r32ui) uniform uimageBuffer tex1;
  1168. layout(r32i) uniform iimageBuffer tex2;
  1169. """
  1170. code = """
  1171. assert(imageLoad(tex1, 0).r == 0u);
  1172. assert(imageLoad(tex2, 0).r == 0);
  1173. imageStore(tex1, 0, uvec4(123));
  1174. imageStore(tex2, 0, ivec4(-456));
  1175. memoryBarrier();
  1176. assert(imageLoad(tex1, 0).r == 123u);
  1177. assert(imageLoad(tex2, 0).r == -456);
  1178. """
  1179. env.run_glsl(code, preamble, {'tex1': tex1, 'tex2': tex2})
  1180. env.extract_texture_data(tex1)
  1181. env.extract_texture_data(tex2)
  1182. assert struct.unpack('I', tex1.get_ram_image()) == (123,)
  1183. assert struct.unpack('i', tex2.get_ram_image()) == (-456,)
  1184. def test_glsl_compile_error():
  1185. """Test getting compile errors from bad shaders"""
  1186. vert_path = core.Filename(SHADERS_DIR, 'glsl_bad.vert')
  1187. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple.frag')
  1188. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1189. assert shader is None
  1190. def test_glsl_from_file():
  1191. """Test compiling GLSL shaders from files"""
  1192. vert_path = core.Filename(SHADERS_DIR, 'glsl_simple.vert')
  1193. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple.frag')
  1194. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1195. assert shader is not None
  1196. def test_glsl_from_file_legacy():
  1197. """Test compiling GLSL shaders from files"""
  1198. vert_path = core.Filename(SHADERS_DIR, 'glsl_simple_legacy.vert')
  1199. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple_legacy.frag')
  1200. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1201. assert shader is not None
  1202. def test_glsl_includes():
  1203. """Test preprocessing includes in GLSL shaders"""
  1204. vert_path = core.Filename(SHADERS_DIR, 'glsl_include.vert')
  1205. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple.frag')
  1206. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1207. assert shader is not None
  1208. def test_glsl_includes_legacy():
  1209. """Test preprocessing includes in GLSL shaders"""
  1210. vert_path = core.Filename(SHADERS_DIR, 'glsl_include_legacy.vert')
  1211. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple_legacy.frag')
  1212. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1213. assert shader is not None
  1214. def test_glsl_includes_angle_nodir():
  1215. """Test preprocessing includes with angle includes without model-path"""
  1216. vert_path = core.Filename(SHADERS_DIR, 'glsl_include_angle.vert')
  1217. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple.frag')
  1218. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1219. assert shader is None
  1220. def test_glsl_includes_angle_nodir_legacy():
  1221. """Test preprocessing includes with angle includes without model-path"""
  1222. vert_path = core.Filename(SHADERS_DIR, 'glsl_include_angle_legacy.vert')
  1223. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple_legacy.frag')
  1224. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1225. assert shader is None
  1226. @pytest.fixture
  1227. def with_current_dir_on_model_path():
  1228. model_path = core.get_model_path()
  1229. model_path.prepend_directory(core.Filename.from_os_specific(os.path.dirname(__file__)))
  1230. yield
  1231. model_path.clear_local_value()
  1232. def test_glsl_includes_angle_withdir(with_current_dir_on_model_path):
  1233. """Test preprocessing includes with angle includes with model-path"""
  1234. vert_path = core.Filename(SHADERS_DIR, 'glsl_include_angle.vert')
  1235. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple.frag')
  1236. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1237. assert shader is not None
  1238. def test_glsl_includes_angle_withdir_legacy(with_current_dir_on_model_path):
  1239. """Test preprocessing includes with angle includes with model-path"""
  1240. vert_path = core.Filename(SHADERS_DIR, 'glsl_include_angle_legacy.vert')
  1241. frag_path = core.Filename(SHADERS_DIR, 'glsl_simple_legacy.frag')
  1242. shader = core.Shader.load(core.Shader.SL_GLSL, vert_path, frag_path)
  1243. assert shader is not None