TextureShaderClass.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. using System;
  2. using System.Collections.Generic;
  3. using SlimDX;
  4. using SlimDX.D3DCompiler;
  5. using SlimDX.Direct3D11;
  6. using SlimDX.DXGI;
  7. using SlimDX.Windows;
  8. using Device = SlimDX.Direct3D11.Device;
  9. using Resource = SlimDX.Direct3D11.Resource;
  10. using Buffer = SlimDX.Direct3D11.Buffer;
  11. namespace EQ2ModelViewer {
  12. public class TextureShaderClass {
  13. private struct MatrixBufferType {
  14. public Matrix world;
  15. public Matrix view;
  16. public Matrix projection;
  17. }
  18. private VertexShader m_VertexShader;
  19. private PixelShader m_PixelShader;
  20. private InputLayout m_Layout;
  21. private Buffer m_MatrixBuffer;
  22. private SamplerState m_SamplerState;
  23. public bool Initialize(Device device) {
  24. if (!InitializeShader(device, "Texture.vs", "Texture.ps"))
  25. return false;
  26. return true;
  27. }
  28. public void ShutDown() {
  29. if (m_SamplerState != null)
  30. m_SamplerState.Dispose();
  31. if (m_MatrixBuffer != null)
  32. m_MatrixBuffer.Dispose();
  33. if (m_Layout != null)
  34. m_Layout.Dispose();
  35. if (m_PixelShader != null)
  36. m_PixelShader.Dispose();
  37. if (m_VertexShader != null)
  38. m_VertexShader.Dispose();
  39. }
  40. public bool Render(DeviceContext context, int indexCount, Matrix worldMatrix, Matrix viewMatrix, Matrix projectionMatrix, ShaderResourceView texture) {
  41. if (!SetShaderParameters(context, worldMatrix, viewMatrix, projectionMatrix, texture))
  42. return false;
  43. RenderShader(context, indexCount);
  44. return true;
  45. }
  46. private bool InitializeShader(Device device, string vertexShader, string pixelShader) {
  47. ShaderSignature inputSignature;
  48. string error;
  49. // load and compile the vertex shader
  50. using (var bytecode = ShaderBytecode.CompileFromFile(vertexShader, "TextureVertexShader", "vs_5_0", ShaderFlags.EnableStrictness, EffectFlags.None, null, null, out error)) {
  51. inputSignature = ShaderSignature.GetInputSignature(bytecode);
  52. m_VertexShader = new VertexShader(device, bytecode);
  53. }
  54. if (m_VertexShader == null) {
  55. Console.WriteLine("InitializeShader: Error creating vertex shader: " + error);
  56. return false;
  57. }
  58. // load and compile the pixel shader
  59. using (var bytecode = ShaderBytecode.CompileFromFile(pixelShader, "TexturePixelShader", "ps_5_0", ShaderFlags.EnableStrictness, EffectFlags.None, null, null, out error))
  60. m_PixelShader = new PixelShader(device, bytecode);
  61. if (m_PixelShader == null) {
  62. Console.WriteLine("InitializeShader: Error creating pixel shader: " + error);
  63. return false;
  64. }
  65. var elements = new[] {
  66. new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0, InputClassification.PerVertexData, 0),
  67. new InputElement("TEXCOORD", 0, Format.R32G32_Float, -1, 0, InputClassification.PerVertexData, 0) };
  68. m_Layout = new InputLayout(device, inputSignature, elements);
  69. m_MatrixBuffer = new Buffer(device, System.Runtime.InteropServices.Marshal.SizeOf(typeof(MatrixBufferType)), ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0);
  70. if (m_MatrixBuffer == null) {
  71. Console.WriteLine("InitializeShader: Unable to create the matrix buffer.");
  72. return false;
  73. }
  74. SamplerDescription samplerDesc = new SamplerDescription();
  75. samplerDesc.Filter = Filter.MinMagMipLinear;
  76. samplerDesc.AddressU = TextureAddressMode.Wrap;
  77. samplerDesc.AddressV = TextureAddressMode.Wrap;
  78. samplerDesc.AddressW = TextureAddressMode.Wrap;
  79. samplerDesc.MipLodBias = 0.0f;
  80. samplerDesc.MaximumAnisotropy = 1;
  81. samplerDesc.ComparisonFunction = Comparison.Always;
  82. samplerDesc.BorderColor = new Color4(0.0f, 0.0f, 0.0f, 0.0f);
  83. samplerDesc.MinimumLod = 0;
  84. samplerDesc.MaximumLod = 3.402823466e+38f; // from d3d11.h, #define D3D11_FLOAT32_MAX ( 3.402823466e+38f )
  85. m_SamplerState = SamplerState.FromDescription(device, samplerDesc);
  86. if (m_SamplerState == null) {
  87. Console.WriteLine("InitializeShader: Unable to create the sampler state.");
  88. return false;
  89. }
  90. return true;
  91. }
  92. private bool SetShaderParameters(DeviceContext context, Matrix worldMatrix, Matrix viewMatrix, Matrix projectionMatrix, ShaderResourceView texture) {
  93. Matrix.Transpose(ref worldMatrix, out worldMatrix);
  94. Matrix.Transpose(ref viewMatrix, out viewMatrix);
  95. Matrix.Transpose(ref projectionMatrix, out projectionMatrix);
  96. var mappedResource = context.MapSubresource(m_MatrixBuffer, 0, MapMode.WriteDiscard, SlimDX.Direct3D11.MapFlags.None);
  97. MatrixBufferType data = new MatrixBufferType();
  98. data.world = worldMatrix;
  99. data.view = viewMatrix;
  100. data.projection = projectionMatrix;
  101. mappedResource.Data.Write<MatrixBufferType>(data);
  102. context.UnmapSubresource(m_MatrixBuffer, 0);
  103. context.VertexShader.SetConstantBuffer(m_MatrixBuffer, 0);
  104. context.PixelShader.SetShaderResource(texture, 0);
  105. return true;
  106. }
  107. private void RenderShader(DeviceContext context, int indexCount) {
  108. context.InputAssembler.InputLayout = m_Layout;
  109. context.VertexShader.Set(m_VertexShader);
  110. context.PixelShader.Set(m_PixelShader);
  111. context.PixelShader.SetSampler(m_SamplerState, 0);
  112. context.DrawIndexed(indexCount, 0, 0);
  113. }
  114. }
  115. }