Shader.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "Shader.h"
  2. #include <d3d11.h>
  3. #include <d3d12.h>
  4. #include <iostream>
  5. #include "Datei.h"
  6. #include "DXBuffer.h"
  7. #include "Text.h"
  8. using namespace Framework;
  9. // Inhalt der Shader Klasse
  10. // Konstruktor
  11. Shader::Shader()
  12. : ReferenceCounter()
  13. {
  14. type = UNBEKANNT;
  15. constBuffers = new RCArray<DXBuffer>();
  16. }
  17. // Destruktor
  18. Shader::~Shader()
  19. {
  20. constBuffers->release();
  21. }
  22. // Löscht einen constanten Buffer
  23. // index: der Index des Buffers, der gelöscht werden soll. Buffer 0 kann nicht
  24. // gelöscht werden, solange Buffer 1 noch existiert usw.
  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. // Kopiert daten in einen constanten buffer
  33. // zD3d11Context: Das Context Objekt, das zum kopieren verwendt werden soll
  34. // data: Einen zeiger auf en byte Array der größe des Buffers
  35. // index: Der Index des Buffers
  36. // län: Die Länge der Daten in Bytes (-1 für die maximale größe des Buffers)
  37. bool Shader::füllConstBuffer(char* data, int index, int len)
  38. {
  39. if (index < 0 || index > constBuffers->getLastIndex()) return 0;
  40. DXBuffer* zB = constBuffers->z(index);
  41. if (!zB) return 0;
  42. if (len < 0) len = zB->getElementAnzahl() * zB->getElementLength();
  43. zB->setData(data);
  44. zB->copieren(len);
  45. return 1;
  46. }
  47. // Gibt die Länge eines constanten Buffers zurück
  48. // index: Der Index des Buffers
  49. int Shader::getConstBufferLänge(int index) const
  50. {
  51. if (index < 0 || index > constBuffers->getLastIndex()) return 0;
  52. DXBuffer* zB = constBuffers->z(index);
  53. if (!zB) return 0;
  54. return zB->getElementAnzahl() * zB->getElementLength();
  55. }
  56. // Gibt den Shadertyp zurück
  57. ShaderType Shader::getType() const
  58. {
  59. return type;
  60. }
  61. //! Gibt den index des ersten nicht initialisierten buffers zurück
  62. int Shader::getFirstUninitializedBufferIndex() const
  63. {
  64. for (int index = 0; index < constBuffers->getEintragAnzahl(); index++)
  65. {
  66. if (!constBuffers->hat(index) || !constBuffers->z(index)) return index;
  67. }
  68. return constBuffers->getEintragAnzahl();
  69. }
  70. DX11Shader::DX11Shader(ID3D11Device* device, ID3D11DeviceContext* context)
  71. : Shader()
  72. {
  73. this->device = device;
  74. this->context = context;
  75. }
  76. DX11Shader::~DX11Shader() {}
  77. // erstellt ein constanten Buffer, der constante daten an den Shader übergibt
  78. // es können maximal 14 Buffer erstellt werden
  79. // zD3d11Device: Das Device, mit dem der Buffer erstellt werden soll
  80. // größe: Die größe des buffers in byte
  81. // index: Die position des Buffers im Buffer Array. Bereits vorhanderner Buffer
  82. // wird ersetzt. Buffer 1 kann nicht erstellt werden, wenn Buffer 0 noch nicht
  83. // erstellt wurde usw.
  84. bool DX11Shader::erstelleConstBuffer(int größe, int index)
  85. {
  86. if (index < 0 || index >= 14) return 0;
  87. bool ok = 1;
  88. while ((größe / 16) * 16
  89. != größe) // es sind nur vielfache von 16 als größe erlaubt
  90. größe++;
  91. while (!constBuffers->hat(index))
  92. constBuffers->add(0);
  93. constBuffers->set(
  94. new DX11Buffer(1, device, context, D3D11_BIND_CONSTANT_BUFFER), index);
  95. constBuffers->z(index)->setLength(größe);
  96. return 1;
  97. }
  98. // Inhalt der PixelShader Klasse
  99. // Konstruktor
  100. DX11PixelShader::DX11PixelShader(
  101. ID3D11Device* device, ID3D11DeviceContext* context)
  102. : DX11Shader(device, context)
  103. {
  104. pixelShader = 0;
  105. }
  106. // Destruktor
  107. DX11PixelShader::~DX11PixelShader()
  108. {
  109. if (pixelShader) pixelShader->Release();
  110. }
  111. // Setzt den Compilierten Shader
  112. // bytes: Die Bytes des compilierten codes
  113. // length: die Länge des bytearrays
  114. // return: true, wenn bytes gültig ist, false sonst
  115. bool DX11PixelShader::setCompiledByteArray(unsigned char* bytes, int length)
  116. {
  117. HRESULT result = device->CreatePixelShader(bytes, length, 0, &pixelShader);
  118. return result == S_OK;
  119. }
  120. // Nach dem Aufruf dieser Funktion wird dieser Shader als Pixel Shader benutzt
  121. // zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
  122. void DX11PixelShader::benutzeShader()
  123. {
  124. int maxI = constBuffers->getLastIndex();
  125. for (int i = 0; i <= maxI; i++)
  126. {
  127. if (!constBuffers->z(i)) continue;
  128. if (!((DX11Buffer*)constBuffers->z(i))->zBuffer())
  129. constBuffers->z(i)->copieren();
  130. ID3D11Buffer* buf = ((DX11Buffer*)constBuffers->z(i))->zBuffer();
  131. context->PSSetConstantBuffers(i, 1, &buf);
  132. }
  133. if (pixelShader) context->PSSetShader(pixelShader, 0, 0);
  134. }
  135. // Inhalt der VertexShader Klasse
  136. // Konstruktor
  137. DX11VertexShader::DX11VertexShader(
  138. ID3D11Device* device, ID3D11DeviceContext* context)
  139. : DX11Shader(device, context)
  140. {
  141. vertexShader = 0;
  142. inputLayout = 0;
  143. shaderByteBuffer = 0;
  144. byteBufferSize = 0;
  145. }
  146. // Destruktor
  147. DX11VertexShader::~DX11VertexShader()
  148. {
  149. if (vertexShader) vertexShader->Release();
  150. if (inputLayout) inputLayout->Release();
  151. }
  152. // Setzt den Compilierten Shader
  153. // bytes: Die Bytes des compilierten codes
  154. // length: die Länge des bytearrays
  155. // return: true, wenn bytes gültig ist, false sonst
  156. bool DX11VertexShader::setCompiledByteArray(unsigned char* bytes, int length)
  157. {
  158. shaderByteBuffer = (unsigned char*)bytes;
  159. byteBufferSize = length;
  160. HRESULT result
  161. = device->CreateVertexShader(bytes, length, 0, &vertexShader);
  162. return result == S_OK;
  163. }
  164. // erstellt ein InputLayout für den Shader
  165. // Darf erst nach compile aufgerufen werden
  166. // zD3d11Device: Das Device, mit dem das Layout erstellt werden soll
  167. // descArray: Ein Array mit initialisierungsdaten
  168. // anz: Die Anzahl der Elemente im Array
  169. bool DX11VertexShader::erstelleInputLayout(
  170. D3D11_INPUT_ELEMENT_DESC* descArray, int anz)
  171. {
  172. if (!shaderByteBuffer) return 0;
  173. if (inputLayout) inputLayout->Release();
  174. inputLayout = 0;
  175. HRESULT res = device->CreateInputLayout(
  176. descArray, anz, shaderByteBuffer, byteBufferSize, &inputLayout);
  177. if (res == S_OK)
  178. {
  179. shaderByteBuffer = 0;
  180. byteBufferSize = 0;
  181. }
  182. return res == S_OK;
  183. }
  184. // Nach dem Aufruf dieser Funktion wird dieser Shader als Vertex Shader benutzt
  185. // zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
  186. void DX11VertexShader::benutzeShader()
  187. {
  188. int maxI = constBuffers->getLastIndex();
  189. for (int i = 0; i <= maxI; i++)
  190. {
  191. if (!constBuffers->z(i)) continue;
  192. if (!((DX11Buffer*)constBuffers->z(i))->zBuffer())
  193. constBuffers->z(i)->copieren();
  194. ID3D11Buffer* buf = ((DX11Buffer*)constBuffers->z(i))->zBuffer();
  195. context->VSSetConstantBuffers(i, 1, &buf);
  196. }
  197. if (inputLayout) context->IASetInputLayout(inputLayout);
  198. if (vertexShader) context->VSSetShader(vertexShader, 0, 0);
  199. }