Files
WickedEngine/WickedEngine/wiLensFlare.cpp
T
2017-02-02 23:56:59 +01:00

169 lines
5.1 KiB
C++

#include "wiLensFlare.h"
#include "wiRenderer.h"
#include "wiResourceManager.h"
#include "ResourceMapping.h"
using namespace wiGraphicsTypes;
GPUBuffer *wiLensFlare::constantBuffer = nullptr;
PixelShader *wiLensFlare::pixelShader = nullptr;
GeometryShader *wiLensFlare::geometryShader = nullptr;
VertexShader *wiLensFlare::vertexShader = nullptr;
VertexLayout *wiLensFlare::inputLayout = nullptr;
RasterizerState *wiLensFlare::rasterizerState = nullptr;
DepthStencilState *wiLensFlare::depthStencilState = nullptr;
BlendState *wiLensFlare::blendState = nullptr;
void wiLensFlare::Initialize(){
LoadShaders();
SetUpCB();
SetUpStates();
}
void wiLensFlare::CleanUp(){
SAFE_DELETE(constantBuffer);
SAFE_DELETE(pixelShader);
SAFE_DELETE(geometryShader);
SAFE_DELETE(vertexShader);
SAFE_DELETE(inputLayout);
SAFE_DELETE(rasterizerState);
SAFE_DELETE(depthStencilState);
SAFE_DELETE(blendState);
}
void wiLensFlare::Draw(GRAPHICSTHREAD threadID, const XMVECTOR& lightPos, vector<Texture2D*>& rims){
if(!rims.empty())
{
GraphicsDevice* device = wiRenderer::GetDevice();
device->EventBegin("LensFlare", threadID);
device->BindPrimitiveTopology(POINTLIST,threadID);
device->BindVertexLayout(inputLayout,threadID);
device->BindPS(pixelShader,threadID);
device->BindVS(vertexShader,threadID);
device->BindGS(geometryShader,threadID);
ConstantBuffer cb;
cb.mSunPos = lightPos / XMVectorSet((float)device->GetScreenWidth(), (float)device->GetScreenHeight(), 1, 1);
cb.mScreen = XMFLOAT4((float)device->GetScreenWidth(), (float)device->GetScreenHeight(), 0, 0);
device->UpdateBuffer(constantBuffer,&cb,threadID);
device->BindConstantBufferGS(constantBuffer, CB_GETBINDSLOT(ConstantBuffer),threadID);
device->BindRasterizerState(rasterizerState,threadID);
device->BindDepthStencilState(depthStencilState,1,threadID);
device->BindBlendState(blendState,threadID);
//device->BindResourceGS(depthMap,0,threadID);
int i=0;
for(Texture2D* x : rims){
if(x!=nullptr){
device->BindResourcePS(x, TEXSLOT_ONDEMAND0 + i, threadID);
device->BindResourceGS(x, TEXSLOT_ONDEMAND0 + i, threadID);
i++;
}
}
device->Draw(i,threadID);
device->BindGS(nullptr,threadID);
device->EventEnd(threadID);
}
}
void wiLensFlare::LoadShaders(){
VertexLayoutDesc layout[] =
{
{ "POSITION", 0, FORMAT_R32G32B32A32_FLOAT, 0, APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE(layout);
VertexShaderInfo* vsinfo = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "lensFlareVS.cso", wiResourceManager::VERTEXSHADER, layout, numElements));
if (vsinfo != nullptr){
vertexShader = vsinfo->vertexShader;
inputLayout = vsinfo->vertexLayout;
}
pixelShader = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "lensFlarePS.cso", wiResourceManager::PIXELSHADER));
geometryShader = static_cast<GeometryShader*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "lensFlareGS.cso", wiResourceManager::GEOMETRYSHADER));
}
void wiLensFlare::SetUpCB()
{
GPUBufferDesc bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = USAGE_DYNAMIC;
bd.ByteWidth = sizeof(ConstantBuffer);
bd.BindFlags = BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = CPU_ACCESS_WRITE;
constantBuffer = new GPUBuffer;
wiRenderer::GetDevice()->CreateBuffer( &bd, NULL, constantBuffer );
}
void wiLensFlare::SetUpStates()
{
RasterizerStateDesc rs;
rs.FillMode=FILL_SOLID;
rs.CullMode=CULL_NONE;
rs.FrontCounterClockwise=true;
rs.DepthBias=0;
rs.DepthBiasClamp=0;
rs.SlopeScaledDepthBias=0;
rs.DepthClipEnable=false;
rs.ScissorEnable=false;
rs.MultisampleEnable=false;
rs.AntialiasedLineEnable=false;
rasterizerState = new RasterizerState;
wiRenderer::GetDevice()->CreateRasterizerState(&rs,rasterizerState);
DepthStencilStateDesc dsd;
dsd.DepthEnable = false;
dsd.DepthWriteMask = DEPTH_WRITE_MASK_ZERO;
dsd.DepthFunc = COMPARISON_LESS;
dsd.StencilEnable = false;
dsd.StencilReadMask = 0xFF;
dsd.StencilWriteMask = 0xFF;
// Stencil operations if pixel is front-facing.
dsd.FrontFace.StencilFailOp = STENCIL_OP_KEEP;
dsd.FrontFace.StencilDepthFailOp = STENCIL_OP_INCR;
dsd.FrontFace.StencilPassOp = STENCIL_OP_KEEP;
dsd.FrontFace.StencilFunc = COMPARISON_ALWAYS;
// Stencil operations if pixel is back-facing.
dsd.BackFace.StencilFailOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilDepthFailOp = STENCIL_OP_DECR;
dsd.BackFace.StencilPassOp = STENCIL_OP_KEEP;
dsd.BackFace.StencilFunc = COMPARISON_ALWAYS;
// Create the depth stencil state.
depthStencilState = new DepthStencilState;
wiRenderer::GetDevice()->CreateDepthStencilState(&dsd, depthStencilState);
BlendStateDesc bd;
ZeroMemory(&bd, sizeof(bd));
bd.RenderTarget[0].BlendEnable=true;
bd.RenderTarget[0].SrcBlend = BLEND_ONE;
bd.RenderTarget[0].DestBlend = BLEND_ONE;
bd.RenderTarget[0].BlendOp = BLEND_OP_ADD;
bd.RenderTarget[0].SrcBlendAlpha = BLEND_ONE;
bd.RenderTarget[0].DestBlendAlpha = BLEND_ZERO;
bd.RenderTarget[0].BlendOpAlpha = BLEND_OP_ADD;
bd.RenderTarget[0].RenderTargetWriteMask = 0x0f;
blendState = new BlendState;
wiRenderer::GetDevice()->CreateBlendState(&bd,blendState);
}