/RacingGameWindows1/RacingGame/RacingGame/Shaders/ShaderEffect.cs

https://bitbucket.org/ddreaper/racing-game-kit · C# · 863 lines · 543 code · 68 blank · 252 comment · 67 complexity · 1dfb7b24c41c3b63e510a6a1f1cca833 MD5 · raw file

  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // ShaderEffect.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using directives
  10. using Microsoft.Xna.Framework;
  11. using Microsoft.Xna.Framework.Graphics;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.IO;
  15. using System.Text;
  16. using RacingGame.Graphics;
  17. using RacingGame.Helpers;
  18. using Texture = RacingGame.Graphics.Texture;
  19. using XnaTexture = Microsoft.Xna.Framework.Graphics.Texture;
  20. #endregion
  21. namespace RacingGame.Shaders
  22. {
  23. /// <summary>
  24. /// Shader effect class. You can either directly use this class by
  25. /// providing a fx filename in the constructor or derive from this class
  26. /// for special shader functionality (see post screen shaders for a more
  27. /// complex example).
  28. /// </summary>
  29. public class ShaderEffect : IDisposable
  30. {
  31. #region Some shaders
  32. /// <summary>
  33. /// Line rendering shader
  34. /// </summary>
  35. public static ShaderEffect lineRendering =
  36. new ShaderEffect("LineRendering.fx");
  37. /// <summary>
  38. /// Simple shader with just per pixel lighting for testing.
  39. /// </summary>
  40. public static ShaderEffect lighting =
  41. new ShaderEffect("LightingShader.fx");
  42. /// <summary>
  43. /// Normal mapping shader for simple objects and the landscape rendering.
  44. /// </summary>
  45. public static ShaderEffect normalMapping =
  46. new ShaderEffect("NormalMapping.fx");
  47. /// <summary>
  48. /// Landscape normal mapping shader for the landscape rendering with
  49. /// detail texture support, everything else should use normalMapping.
  50. /// </summary>
  51. public static ShaderEffect landscapeNormalMapping =
  52. new ShaderEffect("LandscapeNormalMapping.fx");
  53. /// <summary>
  54. /// Shadow mapping shader
  55. /// </summary>
  56. public static ShadowMapShader shadowMapping =
  57. new ShadowMapShader();
  58. #endregion
  59. #region Variables
  60. /// <summary>
  61. /// Content name for this shader
  62. /// </summary>
  63. private string shaderContentName = "";
  64. /// <summary>
  65. /// Effect
  66. /// </summary>
  67. protected Effect effect = null;
  68. /// <summary>
  69. /// Effect handles for shaders.
  70. /// </summary>
  71. protected EffectParameter worldViewProj,
  72. viewProj,
  73. world,
  74. viewInverse,
  75. projection,
  76. lightDir,
  77. ambientColor,
  78. diffuseColor,
  79. specularColor,
  80. specularPower,
  81. alphaFactor,
  82. scale,
  83. diffuseTexture,
  84. normalTexture,
  85. heightTexture,
  86. reflectionCubeTexture,
  87. detailTexture,
  88. parallaxAmount,
  89. carHueColorChange;
  90. #endregion
  91. #region Properties
  92. /// <summary>
  93. /// Is this shader valid to render? If not we can't perform any rendering.
  94. /// </summary>
  95. /// <returns>Bool</returns>
  96. public bool Valid
  97. {
  98. get
  99. {
  100. return effect != null;
  101. }
  102. }
  103. /// <summary>
  104. /// Effect
  105. /// </summary>
  106. /// <returns>Effect</returns>
  107. public Effect Effect
  108. {
  109. get
  110. {
  111. return effect;
  112. }
  113. }
  114. /// <summary>
  115. /// Number of techniques
  116. /// </summary>
  117. /// <returns>Int</returns>
  118. public int NumberOfTechniques
  119. {
  120. get
  121. {
  122. return effect.Techniques.Count;
  123. }
  124. }
  125. /// <summary>
  126. /// Get technique
  127. /// </summary>
  128. /// <param name="techniqueName">Technique name</param>
  129. /// <returns>Effect technique</returns>
  130. public EffectTechnique GetTechnique(string techniqueName)
  131. {
  132. return effect.Techniques[techniqueName];
  133. }
  134. /// <summary>
  135. /// World parameter
  136. /// </summary>
  137. /// <returns>Effect parameter</returns>
  138. public EffectParameter WorldParameter
  139. {
  140. get
  141. {
  142. return world;
  143. }
  144. }
  145. /// <summary>
  146. /// Set value helper to set an effect parameter.
  147. /// </summary>
  148. /// <param name="param">Param</param>
  149. /// <param name="setMatrix">Set matrix</param>
  150. private static void SetValue(EffectParameter param,
  151. ref Matrix lastUsedMatrix, Matrix newMatrix)
  152. {
  153. // Always update, matrices change every frame anyway!
  154. lastUsedMatrix = newMatrix;
  155. param.SetValue(newMatrix);
  156. }
  157. /// <summary>
  158. /// Set value helper to set an effect parameter.
  159. /// </summary>
  160. /// <param name="param">Param</param>
  161. /// <param name="lastUsedVector">Last used vector</param>
  162. /// <param name="newVector">New vector</param>
  163. private static void SetValue(EffectParameter param,
  164. ref Vector3 lastUsedVector, Vector3 newVector)
  165. {
  166. if (param != null &&
  167. lastUsedVector != newVector)
  168. {
  169. lastUsedVector = newVector;
  170. param.SetValue(newVector);
  171. }
  172. }
  173. /// <summary>
  174. /// Set value helper to set an effect parameter.
  175. /// </summary>
  176. /// <param name="param">Param</param>
  177. /// <param name="lastUsedColor">Last used color</param>
  178. /// <param name="newColor">New color</param>
  179. private static void SetValue(EffectParameter param,
  180. ref Color lastUsedColor, Color newColor)
  181. {
  182. // Note: This check eats few % of the performance, but the color
  183. // often stays the change (around 50%).
  184. if (param != null &&
  185. //slower: lastUsedColor != newColor)
  186. lastUsedColor.PackedValue != newColor.PackedValue)
  187. {
  188. lastUsedColor = newColor;
  189. param.SetValue(newColor.ToVector4());
  190. }
  191. }
  192. /// <summary>
  193. /// Set value helper to set an effect parameter.
  194. /// </summary>
  195. /// <param name="param">Param</param>
  196. /// <param name="lastUsedValue">Last used value</param>
  197. /// <param name="newValue">New value</param>
  198. private static void SetValue(EffectParameter param,
  199. ref float lastUsedValue, float newValue)
  200. {
  201. if (param != null &&
  202. lastUsedValue != newValue)
  203. {
  204. lastUsedValue = newValue;
  205. param.SetValue(newValue);
  206. }
  207. }
  208. /// <summary>
  209. /// Set value helper to set an effect parameter.
  210. /// </summary>
  211. /// <param name="param">Param</param>
  212. /// <param name="lastUsedValue">Last used value</param>
  213. /// <param name="newValue">New value</param>
  214. private static void SetValue(EffectParameter param,
  215. ref XnaTexture lastUsedValue, XnaTexture newValue)
  216. {
  217. if (param != null &&
  218. lastUsedValue != newValue)
  219. {
  220. lastUsedValue = newValue;
  221. param.SetValue(newValue);
  222. }
  223. }
  224. protected Matrix lastUsedWorldViewProjMatrix = Matrix.Identity;
  225. /// <summary>
  226. /// Set world view proj matrix
  227. /// </summary>
  228. protected Matrix WorldViewProjMatrix
  229. {
  230. get
  231. {
  232. // Note: Only implemented for stupid FxCop rule,
  233. // you should never "get" a shader texture this way!
  234. return lastUsedWorldViewProjMatrix;
  235. }
  236. set
  237. {
  238. SetValue(worldViewProj, ref lastUsedWorldViewProjMatrix, value);
  239. }
  240. }
  241. protected Matrix lastUsedViewProjMatrix = Matrix.Identity;
  242. /// <summary>
  243. /// Set view proj matrix
  244. /// </summary>
  245. protected Matrix ViewProjMatrix
  246. {
  247. get
  248. {
  249. // Note: Only implemented for stupid FxCop rule,
  250. // you should never "get" a shader texture this way!
  251. return lastUsedViewProjMatrix;
  252. }
  253. set
  254. {
  255. SetValue(viewProj, ref lastUsedViewProjMatrix, value);
  256. }
  257. }
  258. /// <summary>
  259. /// Set world matrix
  260. /// </summary>
  261. public Matrix WorldMatrix
  262. {
  263. get
  264. {
  265. // Note: Only implemented for stupid FxCop rule,
  266. // you should never "get" a shader texture this way!
  267. return Matrix.Identity;//makes REALLY no sense!
  268. }
  269. set
  270. {
  271. // Faster, we checked world matrix in constructor.
  272. world.SetValue(value);
  273. }
  274. }
  275. protected Matrix lastUsedInverseViewMatrix = Matrix.Identity;
  276. /// <summary>
  277. /// Set view inverse matrix
  278. /// </summary>
  279. protected Matrix InverseViewMatrix
  280. {
  281. get
  282. {
  283. // Note: Only implemented for stupid FxCop rule,
  284. // you should never "get" a shader texture this way!
  285. return lastUsedInverseViewMatrix;
  286. }
  287. set
  288. {
  289. SetValue(viewInverse, ref lastUsedInverseViewMatrix, value);
  290. }
  291. }
  292. protected Matrix lastUsedProjectionMatrix = Matrix.Identity;
  293. /// <summary>
  294. /// Set projection matrix
  295. /// </summary>
  296. protected Matrix ProjectionMatrix
  297. {
  298. get
  299. {
  300. // Note: Only implemented for stupid FxCop rule,
  301. // you should never "get" a shader texture this way!
  302. return lastUsedProjectionMatrix;
  303. }
  304. set
  305. {
  306. SetValue(projection, ref lastUsedProjectionMatrix, value);
  307. }
  308. }
  309. protected Vector3 lastUsedLightDir = Vector3.Zero;
  310. /// <summary>
  311. /// Set light direction
  312. /// </summary>
  313. protected Vector3 LightDir
  314. {
  315. get
  316. {
  317. // Note: Only implemented for stupid FxCop rule,
  318. // you should never "get" a shader texture this way!
  319. return lastUsedLightDir;
  320. }
  321. set
  322. {
  323. // Make sure lightDir is normalized (fx files are optimized
  324. // to work with a normalized lightDir vector)
  325. value.Normalize();
  326. // Set negative value, shader is optimized not to negate dir!
  327. SetValue(lightDir, ref lastUsedLightDir, -value);
  328. }
  329. }
  330. protected Color lastUsedAmbientColor = ColorHelper.Empty;
  331. /// <summary>
  332. /// Ambient color
  333. /// </summary>
  334. public Color AmbientColor
  335. {
  336. get
  337. {
  338. // Note: Only implemented for stupid FxCop rule,
  339. // you should never "get" a shader texture this way!
  340. return lastUsedAmbientColor;
  341. }
  342. set
  343. {
  344. SetValue(ambientColor, ref lastUsedAmbientColor, value);
  345. }
  346. }
  347. protected Color lastUsedDiffuseColor = ColorHelper.Empty;
  348. /// <summary>
  349. /// Diffuse color
  350. /// </summary>
  351. public Color DiffuseColor
  352. {
  353. get
  354. {
  355. // Note: Only implemented for stupid FxCop rule,
  356. // you should never "get" a shader texture this way!
  357. return lastUsedDiffuseColor;
  358. }
  359. set
  360. {
  361. SetValue(diffuseColor, ref lastUsedDiffuseColor, value);
  362. }
  363. }
  364. protected Color lastUsedSpecularColor = ColorHelper.Empty;
  365. /// <summary>
  366. /// Specular color
  367. /// </summary>
  368. public Color SpecularColor
  369. {
  370. get
  371. {
  372. // Note: Only implemented for stupid FxCop rule,
  373. // you should never "get" a shader texture this way!
  374. return lastUsedSpecularColor;
  375. }
  376. set
  377. {
  378. SetValue(specularColor, ref lastUsedSpecularColor, value);
  379. }
  380. }
  381. private float lastUsedSpecularPower = 0;
  382. /// <summary>
  383. /// SpecularPower for specular color
  384. /// </summary>
  385. public float SpecularPower
  386. {
  387. get
  388. {
  389. // Note: Only implemented for stupid FxCop rule,
  390. // you should never "get" a shader texture this way!
  391. return lastUsedSpecularPower;
  392. }
  393. set
  394. {
  395. SetValue(specularPower, ref lastUsedSpecularPower, value);
  396. }
  397. }
  398. private float lastUsedAlphaFactor = 0;
  399. /// <summary>
  400. /// Alpha factor
  401. /// </summary>
  402. /// <returns>Float</returns>
  403. public float AlphaFactor
  404. {
  405. get
  406. {
  407. // Note: Only implemented for stupid FxCop rule,
  408. // you should never "get" a shader texture this way!
  409. return lastUsedAlphaFactor;
  410. }
  411. set
  412. {
  413. SetValue(alphaFactor, ref lastUsedAlphaFactor, value);
  414. }
  415. }
  416. protected XnaTexture lastUsedDiffuseTexture = null;
  417. /// <summary>
  418. /// Set diffuse texture
  419. /// </summary>
  420. public Texture DiffuseTexture
  421. {
  422. get
  423. {
  424. // Note: Only implemented for stupid FxCop rule,
  425. // you should never "get" a shader texture this way!
  426. return null;//makes no sense!
  427. }
  428. set
  429. {
  430. SetValue(diffuseTexture, ref lastUsedDiffuseTexture,
  431. value != null ? value.XnaTexture : null);
  432. }
  433. }
  434. protected XnaTexture lastUsedNormalTexture = null;
  435. /// <summary>
  436. /// Set normal texture for normal mapping
  437. /// </summary>
  438. public Texture NormalTexture
  439. {
  440. get
  441. {
  442. // Note: Only implemented for stupid FxCop rule,
  443. // you should never "get" a shader texture this way!
  444. return null;//makes no sense!
  445. }
  446. set
  447. {
  448. SetValue(normalTexture, ref lastUsedNormalTexture,
  449. value != null ? value.XnaTexture : null);
  450. }
  451. }
  452. protected XnaTexture lastUsedHeightTexture = null;
  453. /// <summary>
  454. /// Set height texture for parallax mapping
  455. /// </summary>
  456. public Texture HeightTexture
  457. {
  458. get
  459. {
  460. // Note: Only implemented for stupid FxCop rule,
  461. // you should never "get" a shader texture this way!
  462. return null;//makes no sense!
  463. }
  464. set
  465. {
  466. SetValue(heightTexture, ref lastUsedHeightTexture,
  467. value != null ? value.XnaTexture : null);
  468. }
  469. }
  470. protected TextureCube lastUsedReflectionCubeTexture = null;
  471. /// <summary>
  472. /// Set reflection cube map texture for reflection stuff.
  473. /// </summary>
  474. public TextureCube ReflectionCubeTexture
  475. {
  476. get
  477. {
  478. return lastUsedReflectionCubeTexture;
  479. }
  480. set
  481. {
  482. if (reflectionCubeTexture != null &&
  483. lastUsedReflectionCubeTexture != value)
  484. {
  485. lastUsedReflectionCubeTexture = value;
  486. reflectionCubeTexture.SetValue(value);
  487. }
  488. }
  489. }
  490. protected XnaTexture lastUsedDetailTexture = null;
  491. /// <summary>
  492. /// Set height texture for parallax mapping
  493. /// </summary>
  494. public Texture DetailTexture
  495. {
  496. get
  497. {
  498. // Note: Only implemented for stupid FxCop rule,
  499. // you should never "get" a shader texture this way!
  500. return null;//makes no sense!
  501. }
  502. set
  503. {
  504. SetValue(detailTexture, ref lastUsedDetailTexture,
  505. value != null ? value.XnaTexture : null);
  506. }
  507. }
  508. protected float lastUsedParallaxAmount = -1.0f;
  509. /// <summary>
  510. /// Parallax amount for parallax and offset shaders.
  511. /// </summary>
  512. public float ParallaxAmount
  513. {
  514. get
  515. {
  516. // Note: Only implemented for stupid FxCop rule,
  517. // you should never "get" a shader texture this way!
  518. return lastUsedParallaxAmount;
  519. }
  520. set
  521. {
  522. SetValue(parallaxAmount, ref lastUsedParallaxAmount, value);
  523. }
  524. }
  525. protected Color lastUsedCarHueColorChange = ColorHelper.Empty;
  526. /// <summary>
  527. /// Shadow car color for the special ShadowCar shader.
  528. /// </summary>
  529. public Color CarHueColorChange
  530. {
  531. get
  532. {
  533. // Note: Only implemented for stupid FxCop rule,
  534. // you should never "get" a shader texture this way!
  535. return lastUsedCarHueColorChange;
  536. }
  537. set
  538. {
  539. SetValue(carHueColorChange, ref lastUsedCarHueColorChange, value);
  540. }
  541. }
  542. #endregion
  543. #region Constructor
  544. [System.Diagnostics.CodeAnalysis.SuppressMessage(
  545. "Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  546. public ShaderEffect(string shaderName)
  547. {
  548. if (BaseGame.Device == null)
  549. throw new InvalidOperationException(
  550. "XNA device is not initialized, can't create ShaderEffect.");
  551. shaderContentName = Path.GetFileNameWithoutExtension(shaderName);
  552. Reload();
  553. }
  554. #endregion
  555. #region Dispose
  556. /// <summary>
  557. /// Dispose
  558. /// </summary>
  559. public void Dispose()
  560. {
  561. Dispose(true);
  562. GC.SuppressFinalize(this);
  563. }
  564. /// <summary>
  565. /// Dispose
  566. /// </summary>
  567. /// <param name="disposing">Disposing</param>
  568. protected virtual void Dispose(bool disposing)
  569. {
  570. if (disposing)
  571. {
  572. // Dispose shader effect
  573. if (effect != null)
  574. effect.Dispose();
  575. }
  576. }
  577. #endregion
  578. #region Reload effect
  579. /// <summary>
  580. /// Reload effect (can be useful if we change the fx file dynamically).
  581. /// </summary>
  582. public void Reload()
  583. {
  584. // Load shader
  585. effect = BaseGame.Content.Load<Effect>(
  586. Path.Combine(Directories.ContentDirectory, "Shaders", shaderContentName));
  587. // Reset and get all avialable parameters.
  588. // This is especially important for derived classes.
  589. ResetParameters();
  590. GetParameters();
  591. }
  592. #endregion
  593. #region Reset parameters
  594. /// <summary>
  595. /// Reset parameters
  596. /// </summary>
  597. protected virtual void ResetParameters()
  598. {
  599. lastUsedInverseViewMatrix = Matrix.Identity;
  600. lastUsedAmbientColor = ColorHelper.Empty;
  601. lastUsedDiffuseTexture = null;
  602. }
  603. #endregion
  604. #region Get parameters
  605. /// <summary>
  606. /// Get parameters, override to support more
  607. /// </summary>
  608. protected virtual void GetParameters()
  609. {
  610. worldViewProj = effect.Parameters["worldViewProj"];
  611. viewProj = effect.Parameters["viewProj"];
  612. world = effect.Parameters["world"];
  613. viewInverse = effect.Parameters["viewInverse"];
  614. projection = effect.Parameters["projection"];
  615. lightDir = effect.Parameters["lightDir"];
  616. ambientColor = effect.Parameters["ambientColor"];
  617. diffuseColor = effect.Parameters["diffuseColor"];
  618. specularColor = effect.Parameters["specularColor"];
  619. specularPower = effect.Parameters["specularPower"];
  620. alphaFactor = effect.Parameters["alphaFactor"];
  621. // Default alpha factor to 1.0f for hotels and stuff
  622. AlphaFactor = 1.0f;
  623. scale = effect.Parameters["scale"];
  624. diffuseTexture = effect.Parameters["diffuseTexture"];
  625. normalTexture = effect.Parameters["normalTexture"];
  626. heightTexture = effect.Parameters["heightTexture"];
  627. reflectionCubeTexture = effect.Parameters["reflectionCubeTexture"];
  628. detailTexture = effect.Parameters["detailTexture"];
  629. parallaxAmount = effect.Parameters["parallaxAmount"];
  630. carHueColorChange = effect.Parameters["carHueColorChange"];
  631. }
  632. #endregion
  633. #region SetParameters
  634. /// <summary>
  635. /// Set parameters, this overload sets all material parameters too.
  636. /// </summary>
  637. public virtual void SetParameters(Material setMat)
  638. {
  639. if (worldViewProj != null)
  640. worldViewProj.SetValue(BaseGame.WorldViewProjectionMatrix);
  641. if (viewProj != null)
  642. viewProj.SetValue(BaseGame.ViewProjectionMatrix);
  643. if (world != null)
  644. world.SetValue(BaseGame.WorldMatrix);
  645. if (viewInverse != null)
  646. viewInverse.SetValue(BaseGame.InverseViewMatrix);
  647. if (lightDir != null)
  648. lightDir.SetValue(BaseGame.LightDirection);
  649. // Set the reflection cube texture only once
  650. if (lastUsedReflectionCubeTexture == null &&
  651. reflectionCubeTexture != null)
  652. {
  653. ReflectionCubeTexture = BaseGame.UI.SkyCubeMapTexture;
  654. }
  655. // Set all material properties
  656. if (setMat != null)
  657. {
  658. AmbientColor = setMat.ambientColor;
  659. DiffuseColor = setMat.diffuseColor;
  660. SpecularColor = setMat.specularColor;
  661. SpecularPower = setMat.specularPower;
  662. DiffuseTexture = setMat.diffuseTexture;
  663. NormalTexture = setMat.normalTexture;
  664. HeightTexture = setMat.heightTexture;
  665. ParallaxAmount = setMat.parallaxAmount;
  666. DetailTexture = setMat.detailTexture;
  667. }
  668. }
  669. /// <summary>
  670. /// Set parameters, override to set more
  671. /// </summary>
  672. public virtual void SetParameters()
  673. {
  674. SetParameters(null);
  675. }
  676. /// <summary>
  677. /// Set parameters, this overload sets all material parameters too.
  678. /// </summary>
  679. public virtual void SetParametersOptimizedGeneral()
  680. {
  681. if (worldViewProj != null)
  682. worldViewProj.SetValue(BaseGame.WorldViewProjectionMatrix);
  683. if (viewProj != null)
  684. viewProj.SetValue(BaseGame.ViewProjectionMatrix);
  685. if (world != null)
  686. world.SetValue(BaseGame.WorldMatrix);
  687. if (viewInverse != null)
  688. viewInverse.SetValue(BaseGame.InverseViewMatrix);
  689. if (lightDir != null)
  690. lightDir.SetValue(BaseGame.LightDirection);
  691. // Set the reflection cube texture only once
  692. if (lastUsedReflectionCubeTexture == null &&
  693. reflectionCubeTexture != null)
  694. {
  695. ReflectionCubeTexture = BaseGame.UI.SkyCubeMapTexture;
  696. }
  697. // lastUsed parameters for colors and textures are not used,
  698. // but we overwrite the values in SetParametersOptimized.
  699. // We fix this by clearing all lastUsed values we will use later.
  700. lastUsedAmbientColor = ColorHelper.Empty;
  701. lastUsedDiffuseColor = ColorHelper.Empty;
  702. lastUsedSpecularColor = ColorHelper.Empty;
  703. lastUsedDiffuseTexture = null;
  704. lastUsedNormalTexture = null;
  705. }
  706. /// <summary>
  707. /// Set parameters, this overload sets all material parameters too.
  708. /// </summary>
  709. public virtual void SetParametersOptimized(Material setMat)
  710. {
  711. if (setMat == null)
  712. throw new ArgumentNullException("setMat");
  713. // No need to set world matrix, will be done later in mesh rendering
  714. // in the MeshRenderManager. All the rest is set with help of the
  715. // SetParametersOptimizedGeneral above.
  716. // Only update ambient, diffuse, specular and the textures, the rest
  717. // will not change for a material change in MeshRenderManager.
  718. ambientColor.SetValue(setMat.ambientColor.ToVector4());
  719. diffuseColor.SetValue(setMat.diffuseColor.ToVector4());
  720. specularColor.SetValue(setMat.specularColor.ToVector4());
  721. if (setMat.diffuseTexture != null)
  722. diffuseTexture.SetValue(setMat.diffuseTexture.XnaTexture);
  723. if (setMat.normalTexture != null)
  724. normalTexture.SetValue(setMat.normalTexture.XnaTexture);
  725. }
  726. #endregion
  727. #region Update
  728. /// <summary>
  729. /// Update
  730. /// </summary>
  731. public void Update()
  732. {
  733. for (int num = 0; num < effect.CurrentTechnique.Passes.Count; num++)
  734. {
  735. effect.CurrentTechnique.Passes[num].Apply();
  736. }
  737. }
  738. #endregion
  739. #region Render
  740. /// <summary>
  741. /// Render
  742. /// </summary>
  743. /// <param name="setMat">Set matrix</param>
  744. /// <param name="passName">Pass name</param>
  745. /// <param name="renderDelegate">Render delegate</param>
  746. public void Render(Material setMat,
  747. string techniqueName,
  748. BaseGame.RenderHandler renderCode)
  749. {
  750. if (techniqueName == null)
  751. throw new ArgumentNullException("techniqueName");
  752. if (renderCode == null)
  753. throw new ArgumentNullException("renderCode");
  754. SetParameters(setMat);
  755. // Start shader
  756. effect.CurrentTechnique = effect.Techniques[techniqueName];
  757. // Render all passes (usually just one)
  758. //foreach (EffectPass pass in effect.CurrentTechnique.Passes)
  759. for (int num = 0; num < effect.CurrentTechnique.Passes.Count; num++)
  760. {
  761. EffectPass pass = effect.CurrentTechnique.Passes[num];
  762. pass.Apply();
  763. renderCode();
  764. }
  765. }
  766. /// <summary>
  767. /// Render
  768. /// </summary>
  769. /// <param name="techniqueName">Technique name</param>
  770. /// <param name="renderDelegate">Render delegate</param>
  771. public void Render(string techniqueName,
  772. BaseGame.RenderHandler renderDelegate)
  773. {
  774. Render(null, techniqueName, renderDelegate);
  775. }
  776. #endregion
  777. #region Render single pass shader
  778. /// <summary>
  779. /// Render single pass shader
  780. /// </summary>
  781. /// <param name="renderDelegate">Render delegate</param>
  782. public void RenderSinglePassShader(
  783. BaseGame.RenderHandler renderCode)
  784. {
  785. if (renderCode == null)
  786. throw new ArgumentNullException("renderCode");
  787. // Start effect (current technique should be set)
  788. // Start first pass
  789. effect.CurrentTechnique.Passes[0].Apply();
  790. // Render
  791. renderCode();
  792. }
  793. #endregion
  794. }
  795. }