Shader.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "Shader.h"
  2. #include <d3d11.h>
  3. #include <d3d12.h>
  4. #include <iostream>
  5. #include "File.h"
  6. #include "DXBuffer.h"
  7. #include "Text.h"
  8. using namespace Framework;
  9. // Contents of the Shader class
  10. // Constructor
  11. Shader::Shader()
  12. : ReferenceCounter()
  13. {
  14. type = UNBEKANNT;
  15. constBuffers = new RCArray<DXBuffer>();
  16. }
  17. // Destructor
  18. Shader::~Shader()
  19. {
  20. constBuffers->release();
  21. }
  22. // Deletes a constant buffer
  23. // index: the index of the buffer to be deleted. Buffer 0 cannot
  24. // be deleted while buffer 1 still exists, etc.
  25. bool Shader::removeConstBuffer(int index)
  26. {
  27. if (index < 0) return 0;
  28. bool ok = 1;
  29. constBuffers->set(0, index);
  30. return 1;
  31. }
  32. // Copies data into a constant buffer
  33. // zD3d11Context: The context object used for copying
  34. // data: A pointer to a byte array the size of the buffer
  35. // index: The index of the buffer
  36. // laen: The length of the data in bytes (-1 for the maximum size of the
  37. // buffer)
  38. bool Shader::fuellConstBuffer(char* data, int index, int len)
  39. {
  40. if (index < 0 || index > constBuffers->getLastIndex()) return 0;
  41. DXBuffer* zB = constBuffers->z(index);
  42. if (!zB) return 0;
  43. if (len < 0) len = zB->getElementAnzahl() * zB->getElementLength();
  44. zB->setData(data);
  45. zB->copieren(len);
  46. return 1;
  47. }
  48. // Returns the length of a constant buffer
  49. // index: The index of the buffer
  50. int Shader::getConstBufferLaenge(int index) const
  51. {
  52. if (index < 0 || index > constBuffers->getLastIndex()) return 0;
  53. DXBuffer* zB = constBuffers->z(index);
  54. if (!zB) return 0;
  55. return zB->getElementAnzahl() * zB->getElementLength();
  56. }
  57. // Returns the shader type
  58. ShaderType Shader::getType() const
  59. {
  60. return type;
  61. }
  62. //! Returns the index of the first uninitialized buffer
  63. int Shader::getFirstUninitializedBufferIndex() const
  64. {
  65. for (int index = 0; index < constBuffers->getEntryCount(); index++)
  66. {
  67. if (!constBuffers->hat(index) || !constBuffers->z(index)) return index;
  68. }
  69. return constBuffers->getEntryCount();
  70. }
  71. DX11Shader::DX11Shader(ID3D11Device* device, ID3D11DeviceContext* context)
  72. : Shader()
  73. {
  74. this->device = device;
  75. this->context = context;
  76. }
  77. DX11Shader::~DX11Shader() {}
  78. // Creates a constant buffer that passes constant data to the shader
  79. // A maximum of 14 buffers can be created
  80. // zD3d11Device: The device used to create the buffer
  81. // groesse: The size of the buffer in bytes
  82. // index: The position of the buffer in the buffer array. Existing buffer
  83. // is replaced. Buffer 1 cannot be created if buffer 0 has not yet
  84. // been created, etc.
  85. bool DX11Shader::erstelleConstBuffer(int groesse, int index)
  86. {
  87. if (index < 0 || index >= 14) return 0;
  88. bool ok = 1;
  89. while ((groesse / 16) * 16
  90. != groesse) // only multiples of 16 are allowed as size
  91. groesse++;
  92. while (!constBuffers->hat(index))
  93. constBuffers->add(0);
  94. constBuffers->set(
  95. new DX11Buffer(1, device, context, D3D11_BIND_CONSTANT_BUFFER), index);
  96. constBuffers->z(index)->setLength(groesse);
  97. return 1;
  98. }
  99. // Contents of the PixelShader class
  100. // Constructor
  101. DX11PixelShader::DX11PixelShader(
  102. ID3D11Device* device, ID3D11DeviceContext* context)
  103. : DX11Shader(device, context)
  104. {
  105. pixelShader = 0;
  106. }
  107. // Destructor
  108. DX11PixelShader::~DX11PixelShader()
  109. {
  110. if (pixelShader) pixelShader->Release();
  111. }
  112. // Sets the compiled shader
  113. // bytes: The bytes of the compiled code
  114. // length: the length of the byte array
  115. // return: true if bytes is valid, false otherwise
  116. bool DX11PixelShader::setCompiledByteArray(unsigned char* bytes, int length)
  117. {
  118. HRESULT result = device->CreatePixelShader(bytes, length, 0, &pixelShader);
  119. return result == S_OK;
  120. }
  121. // After calling this function, this shader is used as pixel shader
  122. // zD3d11Context: The context object used with the shader
  123. void DX11PixelShader::benutzeShader()
  124. {
  125. int maxI = constBuffers->getLastIndex();
  126. for (int i = 0; i <= maxI; i++)
  127. {
  128. if (!constBuffers->z(i)) continue;
  129. if (!((DX11Buffer*)constBuffers->z(i))->zBuffer())
  130. constBuffers->z(i)->copieren();
  131. ID3D11Buffer* buf = ((DX11Buffer*)constBuffers->z(i))->zBuffer();
  132. context->PSSetConstantBuffers(i, 1, &buf);
  133. }
  134. if (pixelShader) context->PSSetShader(pixelShader, 0, 0);
  135. }
  136. // Contents of the VertexShader class
  137. // Constructor
  138. DX11VertexShader::DX11VertexShader(
  139. ID3D11Device* device, ID3D11DeviceContext* context)
  140. : DX11Shader(device, context)
  141. {
  142. vertexShader = 0;
  143. inputLayout = 0;
  144. shaderByteBuffer = 0;
  145. byteBufferSize = 0;
  146. }
  147. // Destructor
  148. DX11VertexShader::~DX11VertexShader()
  149. {
  150. if (vertexShader) vertexShader->Release();
  151. if (inputLayout) inputLayout->Release();
  152. }
  153. // Sets the compiled shader
  154. // bytes: The bytes of the compiled code
  155. // length: the length of the byte array
  156. // return: true if bytes is valid, false otherwise
  157. bool DX11VertexShader::setCompiledByteArray(unsigned char* bytes, int length)
  158. {
  159. shaderByteBuffer = (unsigned char*)bytes;
  160. byteBufferSize = length;
  161. HRESULT result
  162. = device->CreateVertexShader(bytes, length, 0, &vertexShader);
  163. return result == S_OK;
  164. }
  165. // Creates an InputLayout for the shader
  166. // Must only be called after compile
  167. // zD3d11Device: The device used to create the layout
  168. // descArray: An array with initialization data
  169. // anz: The number of elements in the array
  170. bool DX11VertexShader::erstelleInputLayout(
  171. D3D11_INPUT_ELEMENT_DESC* descArray, int anz)
  172. {
  173. if (!shaderByteBuffer) return 0;
  174. if (inputLayout) inputLayout->Release();
  175. inputLayout = 0;
  176. HRESULT res = device->CreateInputLayout(
  177. descArray, anz, shaderByteBuffer, byteBufferSize, &inputLayout);
  178. if (res == S_OK)
  179. {
  180. shaderByteBuffer = 0;
  181. byteBufferSize = 0;
  182. }
  183. return res == S_OK;
  184. }
  185. // After calling this function, this shader is used as vertex shader
  186. // zD3d11Context: The context object used with the shader
  187. void DX11VertexShader::benutzeShader()
  188. {
  189. int maxI = constBuffers->getLastIndex();
  190. for (int i = 0; i <= maxI; i++)
  191. {
  192. if (!constBuffers->z(i)) continue;
  193. if (!((DX11Buffer*)constBuffers->z(i))->zBuffer())
  194. constBuffers->z(i)->copieren();
  195. ID3D11Buffer* buf = ((DX11Buffer*)constBuffers->z(i))->zBuffer();
  196. context->VSSetConstantBuffers(i, 1, &buf);
  197. }
  198. if (inputLayout) context->IASetInputLayout(inputLayout);
  199. if (vertexShader) context->VSSetShader(vertexShader, 0, 0);
  200. }