#include "DX11Shader.h" #include #include "DX11Buffer.h" Framework::DX11Shader::DX11Shader( ID3D11Device* device, ID3D11DeviceContext* context, Critical& deviceLock) : Shader(), deviceLock(deviceLock) { this->device = device; this->context = context; } Framework::DX11Shader::~DX11Shader() {} // Creates a constant buffer that passes constant data to the shader // A maximum of 14 buffers can be created // zD3d11Device: The device used to create the buffer // groesse: The size of the buffer in bytes // index: The position of the buffer in the buffer array. Existing buffer // is replaced. Buffer 1 cannot be created if buffer 0 has not yet // been created, etc. bool Framework::DX11Shader::createConstBuffer(int groesse, int index) { if (index < 0 || index >= 14) return 0; bool ok = 1; while ((groesse / 16) * 16 != groesse) // only multiples of 16 are allowed as size groesse++; while (!constBuffers->has(index)) constBuffers->add(0); constBuffers->set( new Framework::DX11Buffer( 1, device, context, D3D11_BIND_CONSTANT_BUFFER, deviceLock), index); constBuffers->z(index)->setLength(groesse); return 1; } // Contents of the PixelShader class // Constructor Framework::DX11PixelShader::DX11PixelShader( ID3D11Device* device, ID3D11DeviceContext* context, Critical& deviceLock) : DX11Shader(device, context, deviceLock) { pixelShader = 0; } // Destructor Framework::DX11PixelShader::~DX11PixelShader() { if (pixelShader) pixelShader->Release(); } // Sets the compiled shader // bytes: The bytes of the compiled code // length: the length of the byte array // return: true if bytes is valid, false otherwise bool Framework::DX11PixelShader::setCompiledByteArray( unsigned char* bytes, int length) { deviceLock.lock(); HRESULT result = device->CreatePixelShader(bytes, length, 0, &pixelShader); deviceLock.unlock(); return result == S_OK; } // After calling this function, this shader is used as pixel shader // zD3d11Context: The context object used with the shader void Framework::DX11PixelShader::useShader() { int maxI = constBuffers->getLastIndex(); for (int i = 0; i <= maxI; i++) { if (!constBuffers->z(i)) continue; if (!((Framework::DX11Buffer*)constBuffers->z(i))->zBuffer()) constBuffers->z(i)->copyToGPU(); ID3D11Buffer* buf = ((Framework::DX11Buffer*)constBuffers->z(i))->zBuffer(); deviceLock.lock(); context->PSSetConstantBuffers(i, 1, &buf); deviceLock.unlock(); } if (pixelShader) { deviceLock.lock(); context->PSSetShader(pixelShader, 0, 0); deviceLock.unlock(); } } // Contents of the VertexShader class // Constructor Framework::DX11VertexShader::DX11VertexShader(ID3D11Device* device, ID3D11DeviceContext* context, Framework::Critical& deviceLock) : DX11Shader(device, context, deviceLock) { vertexShader = 0; inputLayout = 0; shaderByteBuffer = 0; byteBufferSize = 0; } // Destructor Framework::DX11VertexShader::~DX11VertexShader() { if (vertexShader) vertexShader->Release(); if (inputLayout) inputLayout->Release(); } // Sets the compiled shader // bytes: The bytes of the compiled code // length: the length of the byte array // return: true if bytes is valid, false otherwise bool Framework::DX11VertexShader::setCompiledByteArray( unsigned char* bytes, int length) { shaderByteBuffer = (unsigned char*)bytes; byteBufferSize = length; deviceLock.lock(); HRESULT result = device->CreateVertexShader(bytes, length, 0, &vertexShader); deviceLock.unlock(); return result == S_OK; } // Creates an InputLayout for the shader // Must only be called after compile // zD3d11Device: The device used to create the layout // descArray: An array with initialization data // anz: The number of elements in the array bool Framework::DX11VertexShader::createInputLayout( D3D11_INPUT_ELEMENT_DESC* descArray, int anz) { if (!shaderByteBuffer) return 0; if (inputLayout) inputLayout->Release(); inputLayout = 0; deviceLock.lock(); HRESULT res = device->CreateInputLayout( descArray, anz, shaderByteBuffer, byteBufferSize, &inputLayout); deviceLock.unlock(); if (res == S_OK) { shaderByteBuffer = 0; byteBufferSize = 0; } return res == S_OK; } // After calling this function, this shader is used as vertex shader // zD3d11Context: The context object used with the shader void Framework::DX11VertexShader::useShader() { int maxI = constBuffers->getLastIndex(); for (int i = 0; i <= maxI; i++) { if (!constBuffers->z(i)) continue; if (!((Framework::DX11Buffer*)constBuffers->z(i))->zBuffer()) constBuffers->z(i)->copyToGPU(); ID3D11Buffer* buf = ((Framework::DX11Buffer*)constBuffers->z(i))->zBuffer(); deviceLock.lock(); context->VSSetConstantBuffers(i, 1, &buf); deviceLock.unlock(); } if (inputLayout) { deviceLock.lock(); context->IASetInputLayout(inputLayout); deviceLock.unlock(); } if (vertexShader) { deviceLock.lock(); context->VSSetShader(vertexShader, 0, 0); deviceLock.unlock(); } }