Renderer.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /******************************************************************************
  2. Use 'Renderer(func)' to start rendering using custom rendering function.
  3. Use 'Renderer()' to access current rendering phase/mode.
  4. Use 'Renderer.type()' to get/set rendering type.
  5. /******************************************************************************/
  6. enum RENDER_TYPE // Rendering Type, please check documentation for more info
  7. {
  8. RT_DEFERRED, // full bump mapping, multiple lights , full shadows, full special effects, good for complex scenes with many lights, unavailable in OpenGL ES 2
  9. RT_FORWARD , // only flat/normal bump mapping, multiple lights , full shadows, limited special effects, good for simple scenes with low number of lights (ideally 1 directional light only)
  10. RT_SIMPLE , // only flat bump mapping, only 1 light (directional), no shadows , limited special effects, good for editors - fastest rendering
  11. RT_NUM , // number of Rendering Types
  12. };
  13. #if EE_PRIVATE
  14. ASSERT(RT_DEFERRED==0); // keep Deferred as the first value as it's the most important renderer, when being first, it will improve 'switch' performance for this renderer
  15. #endif
  16. enum RENDER_MODE // Rendering Mode, rendering phase of the rendering process
  17. {
  18. RM_SIMPLE , // simple
  19. RM_SOLID , // solid
  20. RM_SOLID_M , // solid in mirrors/reflections
  21. RM_AMBIENT , // ambient
  22. RM_OVERLAY , // overlay mode for rendering semi transparent surfaces onto solid meshes (like bullet holes)
  23. RM_OUTLINE , // here you can optionally draw outlines of meshes using 'Mesh.drawOutline'
  24. RM_BEHIND , // here you can optionally draw meshes which are behind the visible meshes using 'Mesh.drawBehind'
  25. RM_FUR , // fur
  26. RM_BLEND , // alpha blending
  27. RM_SHADOW , // shadow map, render all shadow casting objects here using 'Mesh.drawShadow', objects not rendered in this phase will not cast shadows
  28. RM_EARLY_Z , // early z
  29. RM_CLOUD , // clouds
  30. RM_WATER , // water surfaces
  31. RM_PALETTE , // color palette #0 (rendering is performed using 'D.colorPalette' texture)
  32. RM_PALETTE1, // color palette #1 (rendering is performed using 'D.colorPalette1' texture)
  33. RM_PREPARE , // render all objects here using 'Mesh.draw', and add all lights to the scene using 'Light*.add'
  34. RM_SHADER_NUM=RM_EARLY_Z+SUPPORT_EARLY_Z, // all modes from start RM_SIMPLE to RM_EARLY_Z are included in the 'MeshPart' shader lookup list
  35. };
  36. enum RENDER_STAGE : Byte // Rendering Stage, allows displaying only desired rendering stages
  37. {
  38. RS_DEFAULT , // default, rendering is performed normally (full scene is rendered)
  39. RS_DEPTH , // display Depth
  40. RS_COLOR , // display Unlit Color (available in RT_DEFERRED)
  41. RS_NORMAL , // display Normals (available in RT_DEFERRED)
  42. RS_VEL , // display Velocity (available in RT_DEFERRED)
  43. RS_LIGHT , // display Light (available in RT_DEFERRED)
  44. RS_LIGHT_AO , // display combined Light+AO (available in RT_DEFERRED)
  45. RS_AO , // display Ambient Occlusion (available in RT_DEFERRED and RT_FORWARD)
  46. RS_LIT_COLOR , // display Lit Color
  47. RS_REFLECTION , // display Reflection (available if Water reflection is visible)
  48. RS_WATER_COLOR , // display Water Unlit Color (available in RT_DEFERRED and if 'Water.max1Light' is disabled)
  49. RS_WATER_NORMAL, // display Water Normal (available if RT_DEFERRED and if 'Water.max1Light' is disabled)
  50. RS_WATER_LIGHT , // display Water Light (available if RT_DEFERRED and if 'Water.max1Light' is disabled)
  51. #if EE_PRIVATE
  52. RS_VEL_CONVERT , // display Converted Velocity (available in RT_DEFERRED)
  53. RS_VEL_DILATED , // display Dilated Velocity (available in RT_DEFERRED)
  54. RS_VEL_LEAK , // display Leak Removed Velocity (available in RT_DEFERRED)
  55. RS_SKY_COVERAGE, // display Sky Coverage
  56. #endif
  57. };
  58. #if EE_PRIVATE
  59. enum DEPTH_READ_MODE
  60. {
  61. NO_DEPTH_READ, // default
  62. WANT_DEPTH_READ, // want if possible, but not required
  63. NEED_DEPTH_READ, // need and can't run without it
  64. DEPTH_READ_NUM , // number of depth read modes
  65. };
  66. #endif
  67. /******************************************************************************/
  68. struct RendererClass // handles rendering
  69. {
  70. RENDER_STAGE stage ; // display desired rendering stage, default=RS_DEFAULT
  71. Bool combine , // if enabled this will apply the final rendered image onto the previous background instead of overwriting it, default=false
  72. wire ; // if use wireframe during rendering (not available under OpenGL ES), default=false
  73. Color clear_color ; // screen clearing color, default=BLACK, used only for RT_SIMPLE and RT_FORWARD rendering types
  74. Dbl lowest_visible_point; // Y coordinates of lowest visible point on the scene, by default=-DBL_MAX (which means full visibility), you can optionally set this to a custom value before the shadow rendering stage, the value should be world-space Y coordinate of the lowest visible point on the scene below which you don't expect any objects to be visible, for example if your scene has heightmaps and there won't be anything visible under the heightmaps, then you can set this value to the minimum of all heightmap mesh box Y coordinates, setting the value will improve shadow quality and rendering performance
  75. ImageRC *target ; // render target destination, this can be set to a custom 'ImageRC' of IMAGE_RT mode, in that case the rendering will be performed onto the selected image, this image should have its aspect (proportions) the same as the screen (D.resW, D.resH), if set to null then rendering is performed to the screen, default=null
  76. ImagePtr cel_shade_palette ; // cel shading light palette, you can set this to custom texture in "Init()", if used then this should point to a palette of custom width and 1 pixel height, if set to null then usage of cel shading is disabled, used only in RT_DEFERRED renderer, default=null
  77. ShaderParam *C material_color, // Vec4
  78. *C highlight , // Vec
  79. *C ambient_color ; // Vec
  80. #if EE_PRIVATE
  81. C VecI2& res ()C {return _res ;} // get Current Render Target Size (in pixels)
  82. Int resW()C {return _res.x;} // get Current Render Target Width (in pixels)
  83. Int resH()C {return _res.y;} // get Current Render Target Height (in pixels)
  84. Int fxW()C {return Min(_col->w(), _final->w());} // get width for post process render target (remember that final can be set to VR texture, so we can't use 'D.renderW')
  85. Int fxH()C {return Min(_col->h(), _final->h());} // get height for post process render target (remember that final can be set to VR texture, so we can't use 'D.renderH')
  86. VecI2 fx ()C {return VecI2(fxW(), fxH());}
  87. Bool inside()C {return _render!=null;} // if currently inside rendering process
  88. void requestMirror(C PlaneM &plane, Int priority, Bool shadows, Int resolution); // request engine to render mirror reflection for 'plane'
  89. Bool wantDepth ()C; Bool canReadDepth ()C; Bool safeCanReadDepth()C; Bool canReadDepth1S()C; Bool hasDepthAttached()C; Bool hasStencilAttached()C;
  90. Bool wantEdgeSoften()C; Bool hasEdgeSoften()C;
  91. Bool wantEyeAdapt ()C; Bool hasEyeAdapt ()C;
  92. Bool wantBloom ()C; Bool hasBloom ()C;
  93. Bool wantMotion ()C; Bool hasMotion ()C;
  94. Bool wantDof ()C; Bool hasDof ()C;
  95. Bool hasAO ()C;
  96. Bool fastCombine()C;
  97. Bool slowCombine()C;
  98. Bool hasVolLight()C;
  99. Bool anyDeferred()C;
  100. Bool anyForward ()C;
  101. #endif
  102. // get / set
  103. RendererClass& type (RENDER_TYPE type); RENDER_TYPE type ()C {return _type ;} // set/get Rendering Type, default=RT_DEFERRED (RT_SIMPLE for Mobile), the change is NOT instant, avoid calling real-time
  104. RENDER_MODE operator() ()C {return _mode ;} // get active RENDER_MODE, call this inside custom 'Render' function to obtain current phase of rendering process
  105. Bool mirror ()C {return _mirror ;} // if currently rendering mirrored/reflection side
  106. Bool firstPass ()C {return _first_pass;} // if currently rendering the first pass ( the main one) of the Forward Renderer
  107. Bool secondaryPass ()C {return !_first_pass;} // if currently rendering a secondary pass (not the main one) of the Forward Renderer
  108. RendererClass& simplePrecision(Bool per_pixel); Bool simplePrecision ()C {return _simple_prec;} // set/get precision of the RT_SIMPLE renderer, default=true (false for Mobile), the change is NOT instant, avoid calling real-time
  109. Bool lowDepthPrecision()C; // get if current depth buffer has low precision (16-bits) for which you may want to increase viewport near plane "D.viewFrom" to avoid depth artifacts, such low precision can be encountered on old graphic cards or some mobile devices
  110. // simple vertex fog
  111. RendererClass& simpleVertexFogColor(C Vec &fog_color ); Vec simpleVertexFogColor()C {return _vtx_fog_color;} // set/get simple vertex fog color, default=(0.40, 0.48, 0.64), the change is instant, you can call it real-time
  112. RendererClass& simpleVertexFogRange(Flt start_frac, Flt end_frac); Flt simpleVertexFogStart()C {return _vtx_fog_start;} // set/get simple vertex fog range, default=(start=0.8, end=1.0), vertex fog is available only for RT_SIMPLE renderer with Renderer.simplePrecision set to false (this is the recommended method for applying fog on low-performance GPU's, in other case please use 'Sky' or 'Fog' to control the fog), the change is instant, you can call it real-time
  113. Flt simpleVertexFogEnd ()C {return _vtx_fog_end ;} // set/get simple vertex fog range, default=(start=0.8, end=1.0), vertex fog is available only for RT_SIMPLE renderer with Renderer.simplePrecision set to false (this is the recommended method for applying fog on low-performance GPU's, in other case please use 'Sky' or 'Fog' to control the fog), the change is instant, you can call it real-time
  114. // operations
  115. RendererClass& operator()(void (&render)()); // perform 3D rendering using custom 'render' callback function
  116. ImageRTPtr get (void (&render)()); // perform 3D rendering using custom 'render' callback function and return the result as a render target instead of drawing it to the screen
  117. void setDepthForDebugDrawing(); // call this after rendering (calling the 'Renderer') if you wish to perform 3D debug drawing
  118. void hasGlow (); // call this inside 'render' function if you've manually drawn elements on the screen that have glow to notify the engine that glow is visible on the scene (if engine is not notified about glow being present then it may skip this effect), normally you don't need to call this as for example meshes handle this automatically, however you may want to call this for manually drawn graphics
  119. #if EE_PRIVATE
  120. void finalizeGlow();
  121. #endif
  122. Bool capture (Image &image, Int w=-1, Int h=-1, Int type=IMAGE_R8G8B8A8, Int mode=IMAGE_2D, Int mip_maps=1, Bool alpha=false); // capture screen to 'image', 'w h'=desired size (in pixels, -1=autodetect), 'type'=IMAGE_TYPE, 'mode'=IMAGE_MODE, 'mip_maps'=number of mip-maps (0=autodetect), 'alpha'=if include alpha transparency
  123. Bool screenShot (C Str &name , Bool alpha=false); // capture screen and save as 'name' , sample usage: screenShot ("shot.bmp" ) , 'alpha'=if include alpha transparency
  124. Bool screenShots(C Str &name , C Str &ext, Bool alpha=false); // capture screen and save as 'name' followed by automatically detected number, with 'ext' extension, sample usage: screenShots("shot ","bmp") , 'alpha'=if include alpha transparency, this method allows to store screenshot in a folder where screenshots can already exist, in that situation the method will automatically set the new screenshot filename so it will not overwrite any previous files
  125. // time measurement
  126. void timeMeasure (Bool on); // enable/disable rendering time measurement, default=false (warning: time measurement may decrease rendering performance)
  127. Bool timeMeasure ( )C {return _t_measure ;}
  128. Flt timeReflection ( )C {return _t_reflection [0];}
  129. Flt timePrepare ( )C {return _t_prepare [0];}
  130. Flt timeSolid ( )C {return _t_solid [0];}
  131. Flt timeOverlay ( )C {return _t_overlay [0];}
  132. Flt timeWater ( )C {return _t_water [0];}
  133. Flt timeLight ( )C {return _t_light [0];}
  134. Flt timeSky ( )C {return _t_sky [0];}
  135. Flt timeBlend ( )C {return _t_blend [0];}
  136. Flt timePalette ( )C {return _t_palette [0];}
  137. Flt timeBehind ( )C {return _t_behind [0];}
  138. Flt timeRays ( )C {return _t_rays [0];}
  139. Flt timeRefract ( )C {return _t_refract [0];}
  140. Flt timeVolumetric ( )C {return _t_volumetric [0];}
  141. Flt timePostProcess( )C {return _t_post_process[0];}
  142. Flt timeGpuWait ( )C {return _t_gpu_wait [0];}
  143. #if EE_PRIVATE
  144. void del ();
  145. void create();
  146. ImageRTPtr getBackBuffer(); // this method will copy the current render target data to an internal image, and return reference to the image so it can be used as a texture in custom shaders rendering, if this method is used then it should be called only inside RM_BLEND rendering mode or outside the Render function, the returned image should be used only for setting it as a shader texture, do not use the image afterwards
  147. void getShdRT ();
  148. void getLumRT ();
  149. void getWaterLumRT();
  150. Bool set (C ImageRTPtr &image);
  151. void setOutline(C Color &color);
  152. void mode(RENDER_MODE mode);
  153. void setDS ();
  154. void linearizeDepth(Image &dest, Image &depth); // this reads from depth buffer and stores it to custom render target in linearized mode
  155. void resolveDepth();
  156. void adaptEye (ImageRC &src, Image &dest);
  157. void bloom (Image &src, Image &dest, Bool dither=false);
  158. Bool motionBlur (Image &src, Image &dest, Bool dither=false);
  159. void dof (Image &src, Image &dest, Bool dither=false);
  160. void Combine ();
  161. Bool reflection ();
  162. void prepare ();
  163. void solid ();
  164. void overlay ();
  165. void waterPreLight ();
  166. void light ();
  167. Bool waterPostLight ();
  168. void edgeDetect ();
  169. void sky ();
  170. void blend ();
  171. void palette (Int index);
  172. void behind ();
  173. void edgeSoften ();
  174. void outline ();
  175. void ao ();
  176. void resolveMultiSample();
  177. void downSample ();
  178. void applyOutline ();
  179. void volumetric ();
  180. void refract ();
  181. void postProcess ();
  182. void cleanup ();
  183. // render target methods
  184. #if DX9
  185. void setCube(Image &cube, Image *ds, DIR_ENUM dir); // set cube render target
  186. #endif
  187. #if DX11 // needed on DX11 because it doesn't allow reading and writing to RT's and Depth Buffer at the same time
  188. static void setDSLookup (); // !! needs to be called after 'set' !! this needs to be called if we plan to call methods below
  189. static void setDS (ID3D11DepthStencilView *dsv);
  190. static void needDepthTest(); // !! needs to be called after 'D.depthWrite' !! set only if we need depth writing, or there's no depth buffer attached, otherwise keep current to avoid unnecessary state changes
  191. static void wantDepthRead();
  192. static void needDepthRead();
  193. #elif WEB // needed on WEB because it doesn't allow reading and writing to RT's and Depth Buffer at the same time
  194. static void setDSLookup ();
  195. static void setDS (UInt ds_txtr_id);
  196. static void needDepthTest();
  197. INLINE void wantDepthRead() {needDepthTest();} // works always the same as 'needDepthTest' on WEB
  198. INLINE void needDepthRead() { setDS(0);} // never supported on WEB
  199. #else
  200. INLINE void setDSLookup () {}
  201. INLINE void needDepthTest() {}
  202. INLINE void wantDepthRead() {}
  203. INLINE void needDepthRead() {}
  204. #endif
  205. void set(Image *t0, Image *t1, Image *t2, Image *t3, Image *ds, Bool custom_viewport, DEPTH_READ_MODE depth_read_mode=NO_DEPTH_READ); // set render targets, 'custom_viewport'=if true then custom viewport based on 'D.viewRect' is used and if false then full viewport is used
  206. void set(Image *t0, Image *ds, Bool custom_viewport, DEPTH_READ_MODE depth_read_mode=NO_DEPTH_READ) {set(t0, null, null, null, ds, custom_viewport, depth_read_mode);} // set render targets, 'custom_viewport'=if true then custom viewport based on 'D.viewRect' is used and if false then full viewport is used
  207. Bool swapDS1S(ImageRTPtr &ds_1s);
  208. void setMainViewport(); // set main viewport
  209. void setEyeViewport (); // set viewport current eye
  210. Rect* setEyeParams (); // set params current eye without setting the viewport
  211. void createShadowMap();
  212. void rtClear ();
  213. void rtClean ();
  214. void rtDel ();
  215. Bool rtCreate ();
  216. void setMain ();
  217. void update ();
  218. Bool mapMain();
  219. void unmapMain();
  220. static Rect colClamp (C VecI2 &size );
  221. static Rect screenToPixel (C Rect &screen);
  222. static RectI screenToPixelI (C Rect &screen);
  223. static Vec2 screenToPixelSize (C Vec2 &screen);
  224. static Rect pixelToScreen (C RectI &pixel );
  225. static Vec2 pixelToScreenSize( Flt pixel );
  226. #endif
  227. #if !EE_PRIVATE
  228. private:
  229. #endif
  230. RENDER_TYPE _type, _cur_type;
  231. RENDER_MODE _mode;
  232. ALPHA_MODE _mesh_blend_alpha;
  233. Bool _has_glow, _fur_is, _simple_prec, _mirror, _mirror_want, _mirror_shadows, _first_pass, _palette_mode, _eye_adapt_scale_cur, _t_measure, _set_depth_needed, _get_target, _stereo, _mesh_early_z, _mesh_shader_vel;
  234. Byte _cull_mode[2], _solid_mode_index, _mesh_stencil_value, _mesh_stencil_mode, _outline;
  235. Int _eye, _eye_num, _mirror_priority, _mirror_resolution, _mesh_variation_1;
  236. UInt _frst_light_offset, _blst_light_offset, _mesh_draw_mask;
  237. Color _mesh_highlight;
  238. Flt _shd_range, _vtx_fog_start, _vtx_fog_end;
  239. VecI2 _res;
  240. Vec _vtx_fog_color;
  241. Rect _clip;
  242. PlaneM _mirror_plane;
  243. Shader *_shader_early_z, *_shader_shd_map, *_shader_shd_map_skin;
  244. #if SUPPORT_MLAA
  245. ImagePtr _mlaa_area;
  246. #endif
  247. ImagePtr _smaa_area, _smaa_search;
  248. void (*_render)();
  249. C Memc<ShaderParamChange> *_shader_param_changes;
  250. ImageRC _main, _main_ds,
  251. _shd_map, _cld_map, _shd_map_null,
  252. _eye_adapt_scale[2],
  253. *_cur_main, *_cur_main_ds;
  254. Image *_cur[4], *_cur_ds;
  255. ImageRTPtr _h0, _h1, _q0, _q1, // <- these members are to be used only temporarily
  256. _gui, _gui_ds,
  257. _col, _ds, _ds_1s, _nrm, _vel,
  258. _lum, _lum_1s, _shd_1s, _shd_ms,
  259. _water_col, _water_nrm, _water_ds, _water_lum,
  260. _vol, _ao, _fade, _back, _back_ds, _mirror_rt, _outline_rt, _sky_coverage, _final;
  261. Memx<ImageRC> _rts;
  262. #if EE_PRIVATE
  263. GPU_API(IDirect3DSurface9 *_cur_id[4] , ID3D11RenderTargetView *_cur_id[4] , union{UInt _cur_id[4] ; Ptr _cur_id_ptr[4] ;});
  264. GPU_API(IDirect3DSurface9 *_cur_ds_id , ID3D11DepthStencilView *_cur_ds_id , union{UInt _cur_ds_id ; Ptr _cur_ds_id_ptr ;});
  265. GPU_API(Ptr _cur_ds_ids[3], ID3D11DepthStencilView *_cur_ds_ids[3], union{UInt _cur_ds_ids[3]; Ptr _cur_ds_ids_ptr[3];}); ASSERT(DEPTH_READ_NUM==3); // [DEPTH_READ_NUM]
  266. #else
  267. Ptr _cur_id[4], _cur_ds_id, _cur_ds_ids[3];
  268. #endif
  269. Int _t_measures[2];
  270. Dbl _t_last_measure;
  271. Flt _t_reflection[2], _t_prepare[2], _t_solid[2], _t_overlay[2], _t_water[2], _t_light[2], _t_sky[2], _t_blend[2], _t_palette[2], _t_behind[2], _t_rays[2], _t_refract[2], _t_volumetric[2], _t_post_process[2], _t_gpu_wait[2];
  272. RendererClass();
  273. }extern
  274. Renderer; // Main Renderer
  275. /******************************************************************************/
  276. #if EE_PRIVATE
  277. extern MeshRender MshrBox, MshrBoxR, MshrBall;
  278. Flt DepthError(Dbl from, Dbl range, Dbl z, Bool perspective, Int bits);
  279. #if DX9
  280. void SetVtxNrmMulAdd(Bool compressed);
  281. #else
  282. INLINE void SetVtxNrmMulAdd(Bool compressed) {}
  283. #endif
  284. INLINE Bool ReuseDefaultMaterialForNonSkinnedShadowShader(Shader *shader) {return shader==Renderer._shader_shd_map ;} // this is the most common shadow shader, for which we don't use any material properties (except culling) so we can put all instances to default materials to reduce overhead
  285. INLINE Bool ReuseDefaultMaterialForSkinnedShadowShader (Shader *shader) {return shader==Renderer._shader_shd_map_skin;} // this is the most common shadow shader, for which we don't use any material properties (except culling) so we can put all instances to default materials to reduce overhead
  286. Bool _SetHighlight (C Color &color );
  287. #endif
  288. void SetDrawMask ( UInt draw_mask =0xFFFFFFFF ); // set MeshPart "draw group" bit combination , this can be called before rendering meshes , draw mask is used to control which MeshParts should be rendered, it is a bit combination of all MeshPart draw groups (which are set using 'MeshPart.drawGroup') that should be included in rendering, each bit is responsible for a different group, for example SetDrawMask(0xFFFFFFFF) enables drawing of all groups, SetDrawMask(IndexToFlag(1) | IndexToFlag(3)) enables drawing of only 1 and 3 group, SetDrawMask(0) completely disables rendering
  289. void SetHighlight (C Color &color =TRANSPARENT ); // set highlight of currently rendered meshes , this can be called before rendering meshes in RM_PREPARE mode
  290. void SetVariation ( Int variation =0 ); // set material variation of currently rendered meshes , this can be called before rendering meshes in RM_PREPARE mode, if variation index is out of range, then default #0 variation will be used
  291. void SetStencilValue( Bool terrain =false ); // set stencil value applied when rendering meshes , this can be called before rendering meshes in RM_PREPARE mode
  292. void SetStencilMode ( Bool terrain_only=false ); // set stencil mode applied when rendering meshes , this can be called before rendering blend meshes in RM_PREPARE or RM_BLEND mode
  293. void SetBehindBias ( Flt distance ); // set bias tolerance for behind effect in meters , this can be called before rendering meshes in RM_BEHIND mode
  294. void SetBlendAlpha (ALPHA_MODE alpha =ALPHA_BLEND_FACTOR); // set custom alpha blending of currently rendered meshes, this can be called before rendering meshes in RM_BLEND mode
  295. void SetEarlyZ ( Bool on =false ); // set early Z of currently rendered meshes , this can be called before rendering meshes in RM_PREPARE mode, default=false
  296. /******************************************************************************
  297. Use following functions for setting Shader Parameter Changes for specific instances of meshes
  298. Call in following order: 1. link, 2. draw, 3. unlink, like this:
  299. LinkShaderParamChanges(changes); mesh.draw(..);
  300. UnlinkShaderParamChanges(changes);
  301. /******************************************************************************/
  302. void LinkShaderParamChanges(const_mem_addr C Memc<ShaderParamChange> &changes); // this can be called before drawing mesh, 'changes' must point to object in constant memory address (only pointer is stored through which the object is later accessed), 'changes' must exist until the rendering is finished
  303. void UnlinkShaderParamChanges(const_mem_addr C Memc<ShaderParamChange> &changes); // this must be called after drawing mesh
  304. /******************************************************************************/