#include "Shader.h" #include #include #include #include "Datei.h" #include "DXBuffer.h" #include "Text.h" using namespace Framework; // Inhalt der Shader Klasse // Konstruktor Shader::Shader() : ReferenceCounter() { type = UNBEKANNT; constBuffers = new RCArray(); } // Destruktor Shader::~Shader() { constBuffers->release(); } // Löscht einen constanten Buffer // index: der Index des Buffers, der gelöscht werden soll. Buffer 0 kann nicht // gelöscht werden, solange Buffer 1 noch existiert usw. bool Shader::removeConstBuffer(int index) { if (index < 0) return 0; bool ok = 1; constBuffers->set(0, index); return 1; } // Kopiert daten in einen constanten buffer // zD3d11Context: Das Context Objekt, das zum kopieren verwendt werden soll // 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(char* data, int index, int len) { if (index < 0 || index > constBuffers->getLastIndex()) return 0; DXBuffer* zB = constBuffers->z(index); if (!zB) return 0; if (len < 0) len = zB->getElementAnzahl() * zB->getElementLength(); zB->setData(data); zB->copieren(len); return 1; } // Gibt die Länge eines constanten Buffers zurück // index: Der Index des Buffers int Shader::getConstBufferLänge(int index) const { if (index < 0 || index > constBuffers->getLastIndex()) return 0; DXBuffer* zB = constBuffers->z(index); if (!zB) return 0; return zB->getElementAnzahl() * zB->getElementLength(); } // Gibt den Shadertyp zurück ShaderType Shader::getType() const { return type; } //! Gibt den index des ersten nicht initialisierten buffers zurück int Shader::getFirstUninitializedBufferIndex() const { for (int index = 0; index < constBuffers->getEintragAnzahl(); index++) { if (!constBuffers->hat(index) || !constBuffers->z(index)) return index; } return constBuffers->getEintragAnzahl(); } 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; while ((größe / 16) * 16 != größe) // es sind nur vielfache von 16 als größe erlaubt größe++; while (!constBuffers->hat(index)) constBuffers->add(0); constBuffers->set( new DX11Buffer(1, device, context, D3D11_BIND_CONSTANT_BUFFER), index); constBuffers->z(index)->setLength(größe); return 1; } // Inhalt der PixelShader Klasse // Konstruktor DX11PixelShader::DX11PixelShader( ID3D11Device* device, ID3D11DeviceContext* context) : DX11Shader(device, context) { pixelShader = 0; } // Destruktor DX11PixelShader::~DX11PixelShader() { if (pixelShader) pixelShader->Release(); } // 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 DX11PixelShader::setCompiledByteArray(unsigned char* bytes, int length) { 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 DX11PixelShader::benutzeShader() { int maxI = constBuffers->getLastIndex(); for (int i = 0; i <= maxI; i++) { if (!constBuffers->z(i)) continue; if (!((DX11Buffer*)constBuffers->z(i))->zBuffer()) constBuffers->z(i)->copieren(); ID3D11Buffer* buf = ((DX11Buffer*)constBuffers->z(i))->zBuffer(); context->PSSetConstantBuffers(i, 1, &buf); } if (pixelShader) context->PSSetShader(pixelShader, 0, 0); } // Inhalt der VertexShader Klasse // Konstruktor DX11VertexShader::DX11VertexShader( ID3D11Device* device, ID3D11DeviceContext* context) : DX11Shader(device, context) { vertexShader = 0; inputLayout = 0; shaderByteBuffer = 0; byteBufferSize = 0; } // Destruktor DX11VertexShader::~DX11VertexShader() { if (vertexShader) vertexShader->Release(); if (inputLayout) inputLayout->Release(); } // 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 DX11VertexShader::setCompiledByteArray(unsigned char* bytes, int length) { shaderByteBuffer = (unsigned char*)bytes; byteBufferSize = length; HRESULT result = device->CreateVertexShader(bytes, length, 0, &vertexShader); return result == S_OK; } // erstellt ein InputLayout für den Shader // Darf erst nach compile aufgerufen werden // zD3d11Device: Das Device, mit dem das Layout erstellt werden soll // descArray: Ein Array mit initialisierungsdaten // anz: Die Anzahl der Elemente im Array bool DX11VertexShader::erstelleInputLayout( D3D11_INPUT_ELEMENT_DESC* descArray, int anz) { if (!shaderByteBuffer) return 0; if (inputLayout) inputLayout->Release(); inputLayout = 0; HRESULT res = device->CreateInputLayout( descArray, anz, shaderByteBuffer, byteBufferSize, &inputLayout); if (res == S_OK) { 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 DX11VertexShader::benutzeShader() { int maxI = constBuffers->getLastIndex(); for (int i = 0; i <= maxI; i++) { if (!constBuffers->z(i)) continue; if (!((DX11Buffer*)constBuffers->z(i))->zBuffer()) constBuffers->z(i)->copieren(); ID3D11Buffer* buf = ((DX11Buffer*)constBuffers->z(i))->zBuffer(); context->VSSetConstantBuffers(i, 1, &buf); } if (inputLayout) context->IASetInputLayout(inputLayout); if (vertexShader) context->VSSetShader(vertexShader, 0, 0); }