|
@@ -1,8 +1,8 @@
|
|
|
#include "Shader.h"
|
|
|
#include "Text.h"
|
|
|
#include "Datei.h"
|
|
|
+#include "DXBuffer.h"
|
|
|
#include <d3d11.h>
|
|
|
-#include <D3Dcompiler.h>
|
|
|
#include <iostream>
|
|
|
|
|
|
using namespace Framework;
|
|
@@ -12,119 +12,20 @@ using namespace Framework;
|
|
|
// Konstruktor
|
|
|
Shader::Shader()
|
|
|
{
|
|
|
- shader = new Text();
|
|
|
- shaderBuffer = 0;
|
|
|
type = UNBEKANNT;
|
|
|
for( int i = 0; i < 14; i++ )
|
|
|
- {
|
|
|
constBuffers[ i ] = 0;
|
|
|
- buffLen[ i ] = 0;
|
|
|
- }
|
|
|
- buffAnz = 0;
|
|
|
ref = 1;
|
|
|
}
|
|
|
|
|
|
// Destruktor
|
|
|
Shader::~Shader()
|
|
|
{
|
|
|
- shader->release();
|
|
|
- if( shaderBuffer )
|
|
|
- shaderBuffer->Release();
|
|
|
for( int i = 0; i < 14; i++ )
|
|
|
{
|
|
|
if( constBuffers[ i ] )
|
|
|
- constBuffers[ i ]->Release();
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// Lähdt den Shader Quellcode aus einer Textdatei
|
|
|
-// pfad: Der Pfad zur Datei
|
|
|
-// return: true, wenn der Shader erfolgreich geladen wurde
|
|
|
-bool Shader::ladeAusDatei( const char* pfad )
|
|
|
-{
|
|
|
- Datei d;
|
|
|
- d.setDatei( pfad );
|
|
|
- __int64 gr = d.getSize();
|
|
|
- if( gr > 10 * 1024 )
|
|
|
- return 0; // Datei zu groß für Shader Quellcode
|
|
|
- shader->fillText( ' ', (int)gr );
|
|
|
- if( !d.open( Datei::Style::lesen ) )
|
|
|
- return 0;
|
|
|
- d.lese( shader->getText(), (int)gr );
|
|
|
- d.close();
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-// Setzt den Shader Quellcode
|
|
|
-// zCode: Der Quellcode des Shaders
|
|
|
-void Shader::setShaderCode( Text * zCode )
|
|
|
-{
|
|
|
- shader->setText( zCode->getText() );
|
|
|
-}
|
|
|
-
|
|
|
-// Compiliert den Shader Quellcode
|
|
|
-// zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
|
|
|
-// einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
|
|
|
-// type: Der Typ und die Version des Shaders. Beispiel: 'vs_5_0' für Vertexshader, 'ps_5_0' für Pixelshader.
|
|
|
-// return: true, wenn der Quellcode keine Fehler enthällt
|
|
|
-bool Shader::compile( ID3D11Device * zD3d11Device, const char* einstiegsFunktion, const char* type )
|
|
|
-{
|
|
|
- ID3D10Blob* errorMessage = 0;
|
|
|
- unsigned int flag = D3D10_SHADER_ENABLE_STRICTNESS;
|
|
|
-#ifdef _DEBUG
|
|
|
- flag |= D3D10_SHADER_DEBUG;
|
|
|
-#endif
|
|
|
- if( shaderBuffer )
|
|
|
- shaderBuffer->Release();
|
|
|
- HRESULT result = D3DCompile( shader->getText(), shader->getLength(), 0, 0, 0, einstiegsFunktion, type, flag, 0, &shaderBuffer, &errorMessage );
|
|
|
- if( errorMessage )
|
|
|
- {
|
|
|
- char* err = (char*)errorMessage->GetBufferPointer();
|
|
|
- std::cout << err;
|
|
|
- errorMessage->Release();
|
|
|
+ constBuffers[ i ]->release();
|
|
|
}
|
|
|
- return result == S_OK;
|
|
|
-}
|
|
|
-
|
|
|
-// Nach dem Aufruf dieser Funktion wird dieser Shader als Pixel Shader benutzt
|
|
|
-// zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
|
|
|
-void Shader::benutzeShader( ID3D11DeviceContext * zD3d11Context )
|
|
|
-{}
|
|
|
-
|
|
|
-// erstellt ein constanten Buffer, der constante daten an den Shader übergibt
|
|
|
-// es können maximal 14 Buffer erstellt werden
|
|
|
-// zD3d11Device: Das Device, mit dem der Buffer erstellt werden soll
|
|
|
-// größe: Die größe des buffers in byte
|
|
|
-// 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.
|
|
|
-bool Shader::erstelleConstBuffer( ID3D11Device * zD3d11Device, int größe, int index )
|
|
|
-{
|
|
|
- if( index < 0 || index >= 14 )
|
|
|
- return 0;
|
|
|
- bool ok = 1;
|
|
|
- for( int i = 0; i < index; i++ )
|
|
|
- ok &= constBuffers[ i ] != 0;
|
|
|
- if( !ok )
|
|
|
- return 0;
|
|
|
- D3D11_BUFFER_DESC bufferDesc;
|
|
|
- bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
|
|
- while( (größe / 16) * 16 != größe ) // es sind nur vielfache von 16 als größe erlaubt
|
|
|
- größe++;
|
|
|
- bufferDesc.ByteWidth = größe;
|
|
|
- bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
|
|
- bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
|
- bufferDesc.MiscFlags = 0;
|
|
|
- bufferDesc.StructureByteStride = 0;
|
|
|
- if( constBuffers[ index ] )
|
|
|
- {
|
|
|
- constBuffers[ index ]->Release();
|
|
|
- constBuffers[ index ] = 0;
|
|
|
- buffLen[ index ] = 0;
|
|
|
- }
|
|
|
- HRESULT res = zD3d11Device->CreateBuffer( &bufferDesc, 0, &constBuffers[ index ] );
|
|
|
- if( res == S_OK )
|
|
|
- buffLen[ index ] = größe;
|
|
|
- for( buffAnz = 0; buffAnz < 14 && constBuffers[ buffAnz ]; buffAnz++ );
|
|
|
- return res == S_OK;
|
|
|
}
|
|
|
|
|
|
// Löscht einen constanten Buffer
|
|
@@ -140,11 +41,9 @@ bool Shader::removeConstBuffer( int index )
|
|
|
return 0;
|
|
|
if( constBuffers[ index ] )
|
|
|
{
|
|
|
- constBuffers[ index ]->Release();
|
|
|
+ constBuffers[ index ]->release();
|
|
|
constBuffers[ index ] = 0;
|
|
|
- buffLen[ index ] = 0;
|
|
|
}
|
|
|
- for( buffAnz = 0; buffAnz < 14 && constBuffers[ buffAnz ]; buffAnz++ );
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -153,20 +52,16 @@ bool Shader::removeConstBuffer( int index )
|
|
|
// data: Einen zeiger auf en byte Array der größe des Buffers
|
|
|
// index: Der Index des Buffers
|
|
|
// län: Die Länge der Daten in Bytes (-1 für die maximale größe des Buffers)
|
|
|
-bool Shader::füllConstBuffer( ID3D11DeviceContext * zD3d11Context, char* data, int index, int län )
|
|
|
+bool Shader::füllConstBuffer( char *data, int index, int len )
|
|
|
{
|
|
|
if( index < 0 || index >= 14 )
|
|
|
return 0;
|
|
|
if( !constBuffers[ index ] )
|
|
|
return 0;
|
|
|
- if( län < 0 )
|
|
|
- län = buffLen[ index ];
|
|
|
- D3D11_MAPPED_SUBRESOURCE mappedResource;
|
|
|
- HRESULT res = zD3d11Context->Map( constBuffers[ index ], 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource );
|
|
|
- if( res != S_OK )
|
|
|
- return 0;
|
|
|
- memcpy( mappedResource.pData, data, län );
|
|
|
- zD3d11Context->Unmap( constBuffers[ index ], 0 );
|
|
|
+ if( len < 0 )
|
|
|
+ len = constBuffers[ index ]->getElementAnzahl() * constBuffers[ index ]->getElementLength();
|
|
|
+ constBuffers[ index ]->setData( data );
|
|
|
+ constBuffers[ index ]->copieren( len );
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -176,7 +71,9 @@ int Shader::getConstBufferL
|
|
|
{
|
|
|
if( index < 0 || index >= 14 )
|
|
|
return 0;
|
|
|
- return buffLen[ index ];
|
|
|
+ if( !constBuffers[ index ] )
|
|
|
+ return 0;
|
|
|
+ return constBuffers[ index ]->getElementAnzahl() * constBuffers[ index ]->getElementLength();
|
|
|
}
|
|
|
|
|
|
// Gibt den Shadertyp zurück
|
|
@@ -187,7 +84,7 @@ ShaderType Shader::getType() const
|
|
|
|
|
|
// Erhöht den Reference Counter um 1
|
|
|
// Return: Ein zeiger auf diesen Shader
|
|
|
-Shader* Shader::getThis()
|
|
|
+Shader *Shader::getThis()
|
|
|
{
|
|
|
ref++;
|
|
|
return this;
|
|
@@ -195,7 +92,7 @@ Shader* Shader::getThis()
|
|
|
|
|
|
// Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
|
|
|
// Return: 0
|
|
|
-Shader* Shader::release()
|
|
|
+Shader *Shader::release()
|
|
|
{
|
|
|
ref--;
|
|
|
if( !ref )
|
|
@@ -203,77 +100,90 @@ Shader* Shader::release()
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+DX11Shader::DX11Shader( ID3D11Device *device, ID3D11DeviceContext *context )
|
|
|
+ : Shader()
|
|
|
+{
|
|
|
+ this->device = device;
|
|
|
+ this->context = context;
|
|
|
+}
|
|
|
+
|
|
|
+DX11Shader::~DX11Shader()
|
|
|
+{}
|
|
|
+
|
|
|
+// erstellt ein constanten Buffer, der constante daten an den Shader übergibt
|
|
|
+// es können maximal 14 Buffer erstellt werden
|
|
|
+// zD3d11Device: Das Device, mit dem der Buffer erstellt werden soll
|
|
|
+// größe: Die größe des buffers in byte
|
|
|
+// 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.
|
|
|
+bool DX11Shader::erstelleConstBuffer( int größe, int index )
|
|
|
+{
|
|
|
+ if( index < 0 || index >= 14 )
|
|
|
+ return 0;
|
|
|
+ bool ok = 1;
|
|
|
+ for( int i = 0; i < index; i++ )
|
|
|
+ ok &= constBuffers[ i ] != 0;
|
|
|
+ if( !ok )
|
|
|
+ return 0;
|
|
|
+ while( ( größe / 16 ) * 16 != größe ) // es sind nur vielfache von 16 als größe erlaubt
|
|
|
+ größe++;
|
|
|
+ if( constBuffers[ index ] )
|
|
|
+ constBuffers[ index ]->release();
|
|
|
+ constBuffers[ index ] = new DX11Buffer( 1, device, context, D3D11_BIND_CONSTANT_BUFFER );
|
|
|
+ constBuffers[ index ]->setLength( größe );
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
// Inhalt der PixelShader Klasse
|
|
|
|
|
|
// Konstruktor
|
|
|
-PixelShader::PixelShader()
|
|
|
- : Shader()
|
|
|
+DX11PixelShader::DX11PixelShader( ID3D11Device *device, ID3D11DeviceContext *context )
|
|
|
+ : DX11Shader( device, context )
|
|
|
{
|
|
|
pixelShader = 0;
|
|
|
}
|
|
|
|
|
|
// Destruktor
|
|
|
-PixelShader::~PixelShader()
|
|
|
+DX11PixelShader::~DX11PixelShader()
|
|
|
{
|
|
|
if( pixelShader )
|
|
|
pixelShader->Release();
|
|
|
}
|
|
|
|
|
|
-// Compiliert den Shader Quellcode
|
|
|
-// zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
|
|
|
-// einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
|
|
|
-// type: Der die Version des Shaders. Beispiel: '5_0', '4_0'
|
|
|
-// return: true, wenn kein Fehler aufgetreten ist
|
|
|
-bool PixelShader::compile( ID3D11Device * zD3d11Device, const char* einstiegsFunktion, const char* version )
|
|
|
-{
|
|
|
- Text v = "ps_";
|
|
|
- v += version;
|
|
|
- if( !__super::compile( zD3d11Device, einstiegsFunktion, v ) )
|
|
|
- return 0;
|
|
|
- if( pixelShader )
|
|
|
- pixelShader->Release();
|
|
|
- pixelShader = 0;
|
|
|
- HRESULT result = zD3d11Device->CreatePixelShader( shaderBuffer->GetBufferPointer(), shaderBuffer->GetBufferSize(), 0, &pixelShader );
|
|
|
- shaderBuffer->Release();
|
|
|
- shaderBuffer = 0;
|
|
|
- return result == S_OK;
|
|
|
-}
|
|
|
-
|
|
|
// Setzt den Compilierten Shader
|
|
|
// bytes: Die Bytes des compilierten codes
|
|
|
// length: die Länge des bytearrays
|
|
|
// return: true, wenn bytes gültig ist, false sonst
|
|
|
-bool PixelShader::setCompiledByteArray( ID3D11Device * zD3d11Device, unsigned char* bytes, int length )
|
|
|
+bool DX11PixelShader::setCompiledByteArray( unsigned char *bytes, int length )
|
|
|
{
|
|
|
- HRESULT result = zD3d11Device->CreatePixelShader( bytes, length, 0, &pixelShader );
|
|
|
+ HRESULT result = device->CreatePixelShader( bytes, length, 0, &pixelShader );
|
|
|
return result == S_OK;
|
|
|
}
|
|
|
|
|
|
// Nach dem Aufruf dieser Funktion wird dieser Shader als Pixel Shader benutzt
|
|
|
// zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
|
|
|
-void PixelShader::benutzeShader( ID3D11DeviceContext * zD3d11Context )
|
|
|
+void DX11PixelShader::benutzeShader()
|
|
|
{
|
|
|
- if( buffAnz )
|
|
|
- zD3d11Context->PSSetConstantBuffers( 0, buffAnz, constBuffers );
|
|
|
+ ID3D11Buffer *buffer[ 14 ];
|
|
|
+ int anz = 0;
|
|
|
+ for( ; anz < 14 && constBuffers[ anz ]; anz++ )
|
|
|
+ {
|
|
|
+ if( !( (DX11Buffer *)constBuffers[ anz ] )->zBuffer() )
|
|
|
+ constBuffers[ anz ]->copieren();
|
|
|
+ buffer[ anz ] = ( (DX11Buffer *)constBuffers[ anz ] )->zBuffer();
|
|
|
+ }
|
|
|
+ if( anz )
|
|
|
+ context->PSSetConstantBuffers( 0, anz, buffer );
|
|
|
if( pixelShader )
|
|
|
- zD3d11Context->PSSetShader( pixelShader, 0, 0 );
|
|
|
+ context->PSSetShader( pixelShader, 0, 0 );
|
|
|
}
|
|
|
|
|
|
-// Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
|
|
|
-// Return: 0
|
|
|
-Shader * PixelShader::release()
|
|
|
-{
|
|
|
- ref--;
|
|
|
- if( !ref )
|
|
|
- delete this;
|
|
|
- return 0;
|
|
|
-}
|
|
|
|
|
|
// Inhalt der VertexShader Klasse
|
|
|
|
|
|
// Konstruktor
|
|
|
-VertexShader::VertexShader()
|
|
|
- : Shader()
|
|
|
+DX11VertexShader::DX11VertexShader( ID3D11Device *device, ID3D11DeviceContext *context )
|
|
|
+ : DX11Shader( device, context )
|
|
|
{
|
|
|
vertexShader = 0;
|
|
|
inputLayout = 0;
|
|
@@ -282,7 +192,7 @@ VertexShader::VertexShader()
|
|
|
}
|
|
|
|
|
|
// Destruktor
|
|
|
-VertexShader::~VertexShader()
|
|
|
+DX11VertexShader::~DX11VertexShader()
|
|
|
{
|
|
|
if( vertexShader )
|
|
|
vertexShader->Release();
|
|
@@ -290,33 +200,15 @@ VertexShader::~VertexShader()
|
|
|
inputLayout->Release();
|
|
|
}
|
|
|
|
|
|
-// Compiliert den Shader Quellcode
|
|
|
-// zD3d11Device: Das Device, mit welchem der Shader erstellt werden soll
|
|
|
-// einstiegsFunktion: Der Name der Funktion, die als erstes aufgerufen werden soll
|
|
|
-// type: Der die Version des Shaders. Beispiel: '5_0', '4_0'
|
|
|
-// return: true, wenn kein Fehler aufgetreten ist
|
|
|
-bool VertexShader::compile( ID3D11Device * zD3d11Device, const char* einstiegsFunktion, const char* version )
|
|
|
-{
|
|
|
- Text v = "vs_";
|
|
|
- v += version;
|
|
|
- if( !__super::compile( zD3d11Device, einstiegsFunktion, v ) )
|
|
|
- return 0;
|
|
|
- if( vertexShader )
|
|
|
- vertexShader->Release();
|
|
|
- vertexShader = 0;
|
|
|
- HRESULT result = zD3d11Device->CreateVertexShader( shaderBuffer->GetBufferPointer(), shaderBuffer->GetBufferSize(), 0, &vertexShader );
|
|
|
- return result == S_OK;
|
|
|
-}
|
|
|
-
|
|
|
// Setzt den Compilierten Shader
|
|
|
// bytes: Die Bytes des compilierten codes
|
|
|
// length: die Länge des bytearrays
|
|
|
// return: true, wenn bytes gültig ist, false sonst
|
|
|
-bool VertexShader::setCompiledByteArray( ID3D11Device * zD3d11Device, unsigned char* bytes, int length )
|
|
|
+bool DX11VertexShader::setCompiledByteArray(unsigned char *bytes, int length )
|
|
|
{
|
|
|
- shaderByteBuffer = (unsigned char*)bytes;
|
|
|
+ shaderByteBuffer = (unsigned char *)bytes;
|
|
|
byteBufferSize = length;
|
|
|
- HRESULT result = zD3d11Device->CreateVertexShader( bytes, length, 0, &vertexShader );
|
|
|
+ HRESULT result = device->CreateVertexShader( bytes, length, 0, &vertexShader );
|
|
|
return result == S_OK;
|
|
|
}
|
|
|
|
|
@@ -325,48 +217,38 @@ bool VertexShader::setCompiledByteArray( ID3D11Device * zD3d11Device, unsigned c
|
|
|
// zD3d11Device: Das Device, mit dem das Layout erstellt werden soll
|
|
|
// descArray: Ein Array mit initialisierungsdaten
|
|
|
// anz: Die Anzahl der Elemente im Array
|
|
|
-bool VertexShader::erstelleInputLayout( ID3D11Device * zD3d11Device, D3D11_INPUT_ELEMENT_DESC * descArray, int anz )
|
|
|
+bool DX11VertexShader::erstelleInputLayout( D3D11_INPUT_ELEMENT_DESC * descArray, int anz )
|
|
|
{
|
|
|
- if( !shaderBuffer && !shaderByteBuffer )
|
|
|
+ if( !shaderByteBuffer )
|
|
|
return 0;
|
|
|
if( inputLayout )
|
|
|
inputLayout->Release();
|
|
|
inputLayout = 0;
|
|
|
- HRESULT res = zD3d11Device->CreateInputLayout( descArray, anz, shaderBuffer ? shaderBuffer->GetBufferPointer() : shaderByteBuffer, shaderBuffer ? shaderBuffer->GetBufferSize() : byteBufferSize, &inputLayout );
|
|
|
+ HRESULT res = device->CreateInputLayout( descArray, anz, shaderByteBuffer, byteBufferSize, &inputLayout );
|
|
|
if( res == S_OK )
|
|
|
{
|
|
|
- if( shaderBuffer )
|
|
|
- {
|
|
|
- shaderBuffer->Release();
|
|
|
- shaderBuffer = 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- shaderByteBuffer = 0;
|
|
|
- byteBufferSize = 0;
|
|
|
- }
|
|
|
+ shaderByteBuffer = 0;
|
|
|
+ byteBufferSize = 0;
|
|
|
}
|
|
|
return res == S_OK;
|
|
|
}
|
|
|
|
|
|
// Nach dem Aufruf dieser Funktion wird dieser Shader als Vertex Shader benutzt
|
|
|
// zD3d11Context: Das Context Objekt, mit dem der Shader verwendet werden soll
|
|
|
-void VertexShader::benutzeShader( ID3D11DeviceContext * zD3d11Context )
|
|
|
+void DX11VertexShader::benutzeShader()
|
|
|
{
|
|
|
- if( buffAnz )
|
|
|
- zD3d11Context->VSSetConstantBuffers( 0, buffAnz, constBuffers );
|
|
|
+ ID3D11Buffer *buffer[ 14 ];
|
|
|
+ int anz = 0;
|
|
|
+ for( ; anz < 14 && constBuffers[ anz ]; anz++ )
|
|
|
+ {
|
|
|
+ if( !( (DX11Buffer *)constBuffers[ anz ] )->zBuffer() )
|
|
|
+ constBuffers[ anz ]->copieren();
|
|
|
+ buffer[ anz ] = ( (DX11Buffer *)constBuffers[ anz ] )->zBuffer();
|
|
|
+ }
|
|
|
+ if( anz )
|
|
|
+ context->VSSetConstantBuffers( 0, anz, buffer );
|
|
|
if( inputLayout )
|
|
|
- zD3d11Context->IASetInputLayout( inputLayout );
|
|
|
+ context->IASetInputLayout( inputLayout );
|
|
|
if( vertexShader )
|
|
|
- zD3d11Context->VSSetShader( vertexShader, 0, 0 );
|
|
|
-}
|
|
|
-
|
|
|
-// Verringert den Reference Counter und löscht den Shader, falls der Refeence Counter auf 0 ist
|
|
|
-// Return: 0
|
|
|
-Shader * VertexShader::release()
|
|
|
-{
|
|
|
- ref--;
|
|
|
- if( !ref )
|
|
|
- delete this;
|
|
|
- return 0;
|
|
|
+ context->VSSetShader( vertexShader, 0, 0 );
|
|
|
}
|