__BulbRendererDefineAccumulateHardNoStencil.gml 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Feather disable all
  2. function __BulbRendererDefineAccumulateHardNoStencil()
  3. {
  4. __AccumulateHardLights = function(_boundaryL, _boundaryT, _boundaryR, _boundaryB, _cameraCX, _cameraCY, _cameraW, _cameraH, _cameraCos, _cameraSin, _normalCoeff)
  5. {
  6. static _shdBulbHardShadows_u_vLight = shader_get_uniform(__shdBulbHardShadows, "u_vLight" );
  7. static _shdBulbHardShadows_u_fNormalCoeff = shader_get_uniform(__shdBulbHardShadows, "u_fNormalCoeff");
  8. static _shdBulbHardShadowsSunlight_u_vLightVector = shader_get_uniform(__shdBulbHardShadowsSunlight, "u_vLightVector");
  9. static _shdBulbHardShadowsSunlight_u_fNormalCoeff = shader_get_uniform(__shdBulbHardShadowsSunlight, "u_fNormalCoeff");
  10. static _shdBulbLightWithNormalMap_u_vInfo = shader_get_uniform(__shdBulbLightWithNormalMap, "u_vInfo" );
  11. static _shdBulbLightWithoutNormalMap_u_fIntensity = shader_get_uniform(__shdBulbLightWithoutNormalMap, "u_fIntensity" );
  12. static _shdBulbSunlightWithNormalMap_u_vSunInfo = shader_get_uniform(__shdBulbSunlightWithNormalMap, "u_vInfo" );
  13. static _sshdBulbSunlightWithoutNormalMap_u_fIntensity = shader_get_uniform(__shdBulbSunlightWithoutNormalMap, "u_fIntensity" );
  14. var _staticVBuffer = __staticVBuffer;
  15. var _dynamicVBuffer = __dynamicVBuffer;
  16. var _rendererNormalMap = normalMap;
  17. if (_rendererNormalMap)
  18. {
  19. shader_set(__shdBulbLightWithNormalMap);
  20. texture_set_stage(shader_get_sampler_index(__shdBulbLightWithNormalMap, "u_sNormalMap"), surface_get_texture(GetNormalMapSurface()));
  21. shader_set_uniform_f(shader_get_uniform(__shdBulbLightWithNormalMap, "u_vCamera"), _cameraCX, _cameraCY, _cameraW/2, _cameraH/2);
  22. shader_set_uniform_f(shader_get_uniform(__shdBulbLightWithNormalMap, "u_vCameraVector"), _cameraCos, _cameraSin);
  23. shader_set_uniform_f(shader_get_uniform(__shdBulbLightWithNormalMap, "u_fSpecularIntensity"), hdr? BULB_SPECULAR_MAP_INTENSITY : 0);
  24. shader_set(__shdBulbSunlightWithNormalMap);
  25. shader_set_uniform_f(shader_get_uniform(__shdBulbSunlightWithNormalMap, "u_fSpecularIntensity"), hdr? BULB_SPECULAR_MAP_INTENSITY : 0);
  26. }
  27. //bm_max requires some trickery with alpha to get good-looking results
  28. //Determine the blend mode and "default" shader accordingly
  29. gpu_set_blendmode(bm_add);
  30. //Set up the coefficient to flip normals
  31. //We use this to control self-renderer
  32. shader_set(__shdBulbHardShadows);
  33. shader_set_uniform_f(_shdBulbHardShadows_u_fNormalCoeff, _normalCoeff);
  34. //Also do the same for our sunlight shader, provided we have any sunlight sources
  35. if (array_length(__sunlightArray) > 0)
  36. {
  37. shader_set(__shdBulbHardShadowsSunlight);
  38. shader_set_uniform_f(_shdBulbHardShadowsSunlight_u_fNormalCoeff, _normalCoeff);
  39. }
  40. //Set our default shader
  41. shader_reset();
  42. gpu_set_colorwriteenable(true, true, true, false);
  43. //And switch on z-testing. We'll use z-testing for stenciling
  44. gpu_set_ztestenable(true);
  45. gpu_set_zwriteenable(true);
  46. gpu_set_zfunc(cmpfunc_lessequal);
  47. var _i = 0;
  48. repeat(array_length(__lightsArray))
  49. {
  50. var _weak = __lightsArray[_i];
  51. if (!weak_ref_alive(_weak) || _weak.ref.__destroyed)
  52. {
  53. array_delete(__lightsArray, _i, 1);
  54. }
  55. else
  56. {
  57. with(_weak.ref)
  58. {
  59. if (visible)
  60. {
  61. __CheckSpriteDimensions();
  62. //If this light is active, do some drawing
  63. if (__IsOnScreen(_boundaryL, _boundaryT, _boundaryR, _boundaryB))
  64. {
  65. if (castShadows)
  66. {
  67. //Turn off all RGBA writing, leaving only z-writing
  68. gpu_set_colorwriteenable(false, false, false, false);
  69. //Guarantee that we're going to write to the z-buffer with the next operations
  70. gpu_set_zfunc(cmpfunc_always);
  71. //Reset z-buffer
  72. draw_sprite_ext(sprite, image,
  73. x, y,
  74. xscale, yscale, angle,
  75. c_black, 1);
  76. //Stencil out shadow areas
  77. shader_set(__shdBulbHardShadows);
  78. shader_set_uniform_f(_shdBulbHardShadows_u_vLight, x, y);
  79. vertex_submit(_staticVBuffer, pr_trianglelist, -1);
  80. vertex_submit(_dynamicVBuffer, pr_trianglelist, -1);
  81. //Swap to drawing RGB data (no alpha to make the output surface tidier)
  82. gpu_set_colorwriteenable(true, true, true, false);
  83. gpu_set_zfunc(cmpfunc_lessequal);
  84. //Reset shader and draw the light itself, but "behind" the shadows
  85. if (_rendererNormalMap && normalMap)
  86. {
  87. shader_set(__shdBulbLightWithNormalMap);
  88. shader_set_uniform_f(_shdBulbLightWithNormalMap_u_vInfo, x, y, normalMapZ, intensity);
  89. }
  90. else
  91. {
  92. shader_set(__shdBulbLightWithoutNormalMap);
  93. shader_set_uniform_f(_shdBulbLightWithoutNormalMap_u_fIntensity, intensity);
  94. }
  95. draw_sprite_ext(sprite, image, x, y, xscale, yscale, angle, blend, 1);
  96. }
  97. else
  98. {
  99. //Just draw the sprite, no fancy stuff here
  100. if (_rendererNormalMap && normalMap)
  101. {
  102. shader_set(__shdBulbLightWithNormalMap);
  103. shader_set_uniform_f(_shdBulbLightWithNormalMap_u_vInfo, x, y, normalMapZ, intensity);
  104. }
  105. else
  106. {
  107. shader_set(__shdBulbLightWithoutNormalMap);
  108. shader_set_uniform_f(_shdBulbLightWithoutNormalMap_u_fIntensity, intensity);
  109. }
  110. draw_sprite_ext(sprite, image, x, y, xscale, yscale, angle, blend, 1);
  111. }
  112. }
  113. }
  114. }
  115. ++_i;
  116. }
  117. }
  118. var _i = 0;
  119. repeat(array_length(__sunlightArray))
  120. {
  121. var _weak = __sunlightArray[_i];
  122. if (!weak_ref_alive(_weak) || _weak.ref.__destroyed)
  123. {
  124. array_delete(__sunlightArray, _i, 1);
  125. }
  126. else
  127. {
  128. with(_weak.ref)
  129. {
  130. if (visible)
  131. {
  132. //Turn off all RGBA writing, leaving only z-writing
  133. gpu_set_colorwriteenable(false, false, false, false);
  134. //Guarantee that we're going to write to the z-buffer with the next operations
  135. gpu_set_zfunc(cmpfunc_always);
  136. //Full surface clear of the z-buffer
  137. draw_sprite_ext(__sprBulbPixel, 0, _boundaryL, _boundaryT, _boundaryR - _boundaryL, _boundaryB - _boundaryT, 0, c_black, 0);
  138. //Stencil out shadow areas
  139. shader_set(__shdBulbHardShadowsSunlight);
  140. shader_set_uniform_f(_shdBulbHardShadowsSunlight_u_vLightVector, dcos(angle), -dsin(angle));
  141. vertex_submit(_staticVBuffer, pr_trianglelist, -1);
  142. vertex_submit(_dynamicVBuffer, pr_trianglelist, -1);
  143. //Swap to drawing RGB data (no alpha to make the output surface tidier)
  144. gpu_set_colorwriteenable(true, true, true, false);
  145. gpu_set_zfunc(cmpfunc_lessequal);
  146. //Reset shader and draw the light itself, but "behind" the shado
  147. if (_rendererNormalMap && normalMap)
  148. {
  149. shader_set(__shdBulbSunlightWithNormalMap);
  150. shader_set_uniform_f(_shdBulbSunlightWithNormalMap_u_vSunInfo, dcos(angle), -dsin(angle), normalMapZ, intensity);
  151. }
  152. else
  153. {
  154. shader_set(__shdBulbLightWithoutNormalMap);
  155. shader_set_uniform_f(_shdBulbLightWithoutNormalMap_u_fIntensity, intensity);
  156. }
  157. draw_sprite_ext(__sprBulbPixel, 0, _boundaryL, _boundaryT, _boundaryR - _boundaryL, _boundaryB - _boundaryT, 0, blend, 1);
  158. }
  159. }
  160. ++_i;
  161. }
  162. }
  163. shader_reset();
  164. gpu_set_colorwriteenable(true, true, true, true);
  165. gpu_set_blendmode(bm_normal);
  166. gpu_set_zfunc(cmpfunc_lessequal);
  167. gpu_set_ztestenable(false);
  168. gpu_set_zwriteenable(false);
  169. }
  170. }