Shader.cpp 7.1 KB

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