562 lines
16 KiB
C++
562 lines
16 KiB
C++
#include "wiEmittedParticle.h"
|
|
#include "wiMath.h"
|
|
#include "wiLoader.h"
|
|
#include "wiRenderer.h"
|
|
#include "wiResourceManager.h"
|
|
#include "wiFrustum.h"
|
|
#include "wiRandom.h"
|
|
#include "ResourceMapping.h"
|
|
#include "wiArchive.h"
|
|
|
|
using namespace std;
|
|
using namespace wiGraphicsTypes;
|
|
|
|
VertexLayout *wiEmittedParticle::vertexLayout = nullptr;
|
|
VertexShader *wiEmittedParticle::vertexShader = nullptr;
|
|
PixelShader *wiEmittedParticle::pixelShader = nullptr,*wiEmittedParticle::simplestPS = nullptr;
|
|
GeometryShader *wiEmittedParticle::geometryShader = nullptr;
|
|
GPUBuffer *wiEmittedParticle::constantBuffer = nullptr;
|
|
BlendState *wiEmittedParticle::blendStateAlpha = nullptr,*wiEmittedParticle::blendStateAdd = nullptr;
|
|
RasterizerState *wiEmittedParticle::rasterizerState = nullptr,*wiEmittedParticle::wireFrameRS = nullptr;
|
|
DepthStencilState *wiEmittedParticle::depthStencilState = nullptr;
|
|
|
|
|
|
static const int NUM_POS_SAMPLES = 30;
|
|
static const float INV_NUM_POS_SAMPLES = 1.0f / NUM_POS_SAMPLES;
|
|
|
|
wiEmittedParticle::wiEmittedParticle()
|
|
{
|
|
name = "";
|
|
object = nullptr;
|
|
materialName = "";
|
|
light = nullptr;
|
|
lightName = "";
|
|
}
|
|
wiEmittedParticle::wiEmittedParticle(const std::string& newName, const std::string& newMat, Object* newObject, float newSize, float newRandomFac, float newNormalFac
|
|
,float newCount, float newLife, float newRandLife, float newScaleX, float newScaleY, float newRot){
|
|
name=newName;
|
|
object=newObject;
|
|
materialName = newMat;
|
|
for (MeshSubset& subset : object->mesh->subsets)
|
|
{
|
|
if (!newMat.compare(subset.material->name)) {
|
|
material = subset.material;
|
|
break;
|
|
}
|
|
}
|
|
|
|
size=newSize;
|
|
random_factor=newRandomFac;
|
|
normal_factor=newNormalFac;
|
|
|
|
count=newCount;
|
|
points.resize(0);
|
|
life=newLife;
|
|
random_life=newRandLife;
|
|
emit=0;
|
|
|
|
scaleX=newScaleX;
|
|
scaleY=newScaleY;
|
|
rotation = newRot;
|
|
|
|
light=nullptr;
|
|
CreateLight();
|
|
|
|
LoadVertexBuffer();
|
|
|
|
XMFLOAT4X4 transform = XMFLOAT4X4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
|
transform4 = transform;
|
|
transform3 = XMFLOAT3X3(
|
|
transform._11,transform._12,transform._13
|
|
,transform._21,transform._22,transform._23
|
|
,transform._31,transform._32,transform._33
|
|
);
|
|
|
|
motionBlurAmount = 0.0f;
|
|
|
|
SetupLightInterpolators();
|
|
}
|
|
int wiEmittedParticle::getCount(){return (int)points.size();}
|
|
|
|
void wiEmittedParticle::SetupLightInterpolators()
|
|
{
|
|
// for smooth light interpolation
|
|
currentSample = 0;
|
|
posSamples = new XMFLOAT3[NUM_POS_SAMPLES];
|
|
radSamples = new float[NUM_POS_SAMPLES];
|
|
energySamples = new float[NUM_POS_SAMPLES];
|
|
for (int i = 0; i < NUM_POS_SAMPLES; ++i)
|
|
{
|
|
radSamples[i] = 0.0f;
|
|
energySamples[i] = 0.0f;
|
|
posSamples[i] = XMFLOAT3(0, 0, 0);
|
|
}
|
|
}
|
|
|
|
int wiEmittedParticle::getRandomPointOnEmitter(){ return wiRandom::getRandom((int)object->mesh->indices.size()-1); }
|
|
|
|
void wiEmittedParticle::CreateLight()
|
|
{
|
|
if (light == nullptr && material->blendFlag == BLENDMODE_ADDITIVE)
|
|
{
|
|
light = new Light();
|
|
light->color.x = material->baseColor.x;
|
|
light->color.y = material->baseColor.y;
|
|
light->color.z = material->baseColor.z;
|
|
light->SetType(Light::POINT);
|
|
light->name = name + "_pslight";
|
|
light->shadow = true;
|
|
light->enerDis = XMFLOAT4(0, 0, 0, 0); // will be filled on Update()
|
|
lightName = light->name;
|
|
}
|
|
}
|
|
|
|
void wiEmittedParticle::addPoint(const XMMATRIX& t4, const XMMATRIX& t3)
|
|
{
|
|
int gen[3];
|
|
gen[0] = getRandomPointOnEmitter();
|
|
switch(gen[0]%3)
|
|
{
|
|
case 0:
|
|
gen[1]=gen[0]+1;
|
|
gen[2]=gen[0]+2;
|
|
break;
|
|
case 1:
|
|
gen[0]=gen[0]-1;
|
|
gen[1]=gen[0]+1;
|
|
gen[2]=gen[0]+2;
|
|
break;
|
|
case 2:
|
|
gen[0]=gen[0]-2;
|
|
gen[1]=gen[0]+1;
|
|
gen[2]=gen[0]+2;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
float f = wiRandom::getRandom(0, 1000) * 0.001f, g = wiRandom::getRandom(0, 1000) * 0.001f;
|
|
if (f + g > 1)
|
|
{
|
|
f = 1 - f;
|
|
g = 1 - g;
|
|
}
|
|
|
|
XMFLOAT3 pos;
|
|
XMFLOAT3 vel;
|
|
XMVECTOR& vbar=XMVectorBaryCentric(
|
|
XMLoadFloat4(&object->mesh->vertices_POS[object->mesh->indices[gen[0]]].pos)
|
|
, XMLoadFloat4(&object->mesh->vertices_POS[object->mesh->indices[gen[1]]].pos)
|
|
, XMLoadFloat4(&object->mesh->vertices_POS[object->mesh->indices[gen[2]]].pos)
|
|
, f
|
|
, g
|
|
);
|
|
XMVECTOR& nbar=XMVectorBaryCentric(
|
|
XMLoadFloat4(&object->mesh->vertices_NOR[object->mesh->indices[gen[0]]].nor)
|
|
, XMLoadFloat4(&object->mesh->vertices_NOR[object->mesh->indices[gen[1]]].nor)
|
|
, XMLoadFloat4(&object->mesh->vertices_NOR[object->mesh->indices[gen[2]]].nor)
|
|
, f
|
|
, g
|
|
);
|
|
XMStoreFloat3( &pos, XMVector3Transform( vbar, t4 ) );
|
|
XMStoreFloat3( &vel, XMVector3Normalize( XMVector3Transform( nbar, t3 ) ));
|
|
|
|
float vrand = (normal_factor*getNewVelocityModifier())/60.0f;
|
|
|
|
vel.x*=vrand;
|
|
vel.y*=vrand;
|
|
vel.z*=vrand;
|
|
|
|
|
|
points.push_back(Point(pos, XMFLOAT4(size, 1, (float)wiRandom::getRandom(0, 1), (float)wiRandom::getRandom(0, 1)), vel/*, XMFLOAT3(1,1,1)*/, getNewLifeSpan()
|
|
,rotation*getNewRotationModifier(),scaleX,scaleY ) );
|
|
}
|
|
void wiEmittedParticle::Update(float dt)
|
|
{
|
|
float gamespeed = wiRenderer::GetGameSpeed() * dt * 60; // it was created for 60 FPS in mind...
|
|
|
|
XMFLOAT3 minP=XMFLOAT3(FLOAT32_MAX,FLOAT32_MAX,FLOAT32_MAX)
|
|
,maxP=XMFLOAT3(-FLOAT32_MAX,-FLOAT32_MAX,-FLOAT32_MAX);
|
|
|
|
for (unsigned int i = 0; i<points.size(); ++i){
|
|
Point &point = points[i];
|
|
|
|
point.pos.x += point.vel.x*gamespeed;
|
|
point.pos.y += point.vel.y*gamespeed;
|
|
point.pos.z += point.vel.z*gamespeed;
|
|
point.rot += point.rotVel*gamespeed;
|
|
|
|
point.life -= gamespeed;
|
|
point.life=wiMath::Clamp(point.life,0,point.maxLife);
|
|
|
|
float lifeLerp = point.life/point.maxLife;
|
|
point.sizOpaMir.x=wiMath::Lerp(point.sizBeginEnd[1],point.sizBeginEnd[0],lifeLerp);
|
|
point.sizOpaMir.y=wiMath::Lerp(1,0,lifeLerp);
|
|
|
|
|
|
minP=wiMath::Min(XMFLOAT3(point.pos.x-point.sizOpaMir.x,point.pos.y-point.sizOpaMir.x,point.pos.z-point.sizOpaMir.x),minP);
|
|
maxP=wiMath::Max(XMFLOAT3(point.pos.x+point.sizOpaMir.x,point.pos.y+point.sizOpaMir.x,point.pos.z+point.sizOpaMir.x),maxP);
|
|
}
|
|
bounding_box.create(minP,maxP);
|
|
|
|
while(!points.empty() && points.front().life<=0)
|
|
points.pop_front();
|
|
|
|
|
|
XMFLOAT4X4& transform = object->world;
|
|
transform4 = transform;
|
|
transform3 = XMFLOAT3X3(
|
|
transform._11,transform._12,transform._13
|
|
,transform._21,transform._22,transform._23
|
|
,transform._31,transform._32,transform._33
|
|
);
|
|
XMMATRIX t4=XMLoadFloat4x4(&transform4), t3=XMLoadFloat3x3(&transform3);
|
|
|
|
emit += (float)count/60.0f*gamespeed;
|
|
|
|
bool clearSpace=false;
|
|
if(points.size()+emit>=MAX_PARTICLES)
|
|
clearSpace=true;
|
|
|
|
for(int i=0;i<(int)emit;++i)
|
|
{
|
|
if(clearSpace)
|
|
points.pop_front();
|
|
|
|
addPoint(t4,t3);
|
|
}
|
|
if((int)emit>0)
|
|
emit=0;
|
|
|
|
}
|
|
void wiEmittedParticle::Burst(float num)
|
|
{
|
|
XMMATRIX t4=XMLoadFloat4x4(&transform4), t3=XMLoadFloat3x3(&transform3);
|
|
|
|
static float burst = 0;
|
|
burst+=num;
|
|
for(int i=0;i<(int)burst;++i)
|
|
addPoint(t4,t3);
|
|
burst-=(int)burst;
|
|
}
|
|
|
|
void wiEmittedParticle::UpdateAttachedLight(float dt)
|
|
{
|
|
if (light != nullptr)
|
|
{
|
|
// smooth light position to eliminate jitter:
|
|
|
|
posSamples[currentSample] = bounding_box.getCenter();
|
|
radSamples[currentSample] = bounding_box.getRadius() * 2;
|
|
energySamples[currentSample] = sqrt((float)points.size());
|
|
|
|
XMFLOAT3 pos = XMFLOAT3(0, 0, 0);
|
|
float rad = 0.0f;
|
|
float energy = 0.0f;
|
|
for (int i = 0; i < NUM_POS_SAMPLES; ++i)
|
|
{
|
|
pos.x += posSamples[i].x;
|
|
pos.y += posSamples[i].y;
|
|
pos.z += posSamples[i].z;
|
|
rad += radSamples[i];
|
|
energy += energySamples[i];
|
|
}
|
|
pos.x *= INV_NUM_POS_SAMPLES;
|
|
pos.y *= INV_NUM_POS_SAMPLES;
|
|
pos.z *= INV_NUM_POS_SAMPLES;
|
|
rad *= INV_NUM_POS_SAMPLES;
|
|
energy *= INV_NUM_POS_SAMPLES;
|
|
currentSample = (currentSample + 1) % NUM_POS_SAMPLES;
|
|
|
|
light->translation_rest = pos;
|
|
|
|
light->enerDis = XMFLOAT4(energy, rad, 0, 0);
|
|
light->UpdateLight();
|
|
}
|
|
}
|
|
void wiEmittedParticle::UpdateRenderData(GRAPHICSTHREAD threadID)
|
|
{
|
|
if (!points.empty())
|
|
{
|
|
std::vector<Point> renderPoints = std::vector<Point>(points.begin(), points.end());
|
|
wiRenderer::GetDevice()->UpdateBuffer(vertexBuffer, renderPoints.data(), threadID, (int)(sizeof(Point)* renderPoints.size()));
|
|
}
|
|
}
|
|
|
|
void wiEmittedParticle::Draw(GRAPHICSTHREAD threadID, int FLAG)
|
|
{
|
|
if(!points.empty())
|
|
{
|
|
GraphicsDevice* device = wiRenderer::GetDevice();
|
|
device->EventBegin("EmittedParticle", threadID);
|
|
|
|
bool additive = (material->blendFlag==BLENDMODE_ADDITIVE || material->premultipliedTexture);
|
|
|
|
device->BindPrimitiveTopology(PRIMITIVETOPOLOGY::POINTLIST,threadID);
|
|
device->BindVertexLayout(vertexLayout,threadID);
|
|
device->BindPS(wireRender?simplestPS:pixelShader,threadID);
|
|
device->BindVS(vertexShader,threadID);
|
|
device->BindGS(geometryShader,threadID);
|
|
|
|
//device->BindResourcePS(depth,1,threadID);
|
|
|
|
ConstantBuffer cb;
|
|
cb.mAdd.x = additive ? 1.0f : 0.0f;
|
|
cb.mAdd.y = (FLAG==DRAW_DARK?true:false);
|
|
cb.mMotionBlurAmount = motionBlurAmount;
|
|
|
|
|
|
device->UpdateBuffer(constantBuffer,&cb,threadID);
|
|
device->BindConstantBufferGS(constantBuffer, CB_GETBINDSLOT(ConstantBuffer),threadID);
|
|
|
|
device->BindRasterizerState(wireRender?wireFrameRS:rasterizerState,threadID);
|
|
device->BindDepthStencilState(depthStencilState,1,threadID);
|
|
|
|
device->BindBlendState((additive?blendStateAdd:blendStateAlpha),threadID);
|
|
|
|
const GPUBuffer* vbs[] = {
|
|
vertexBuffer,
|
|
};
|
|
const UINT strides[] = {
|
|
sizeof(Point),
|
|
};
|
|
device->BindVertexBuffers(vbs, 0, ARRAYSIZE(vbs), strides, threadID);
|
|
|
|
if(!wireRender && material->texture)
|
|
device->BindResourcePS(material->texture,TEXSLOT_ONDEMAND0,threadID);
|
|
device->Draw((int)points.size(),threadID);
|
|
|
|
|
|
device->BindGS(nullptr,threadID);
|
|
device->EventEnd(threadID);
|
|
}
|
|
}
|
|
void wiEmittedParticle::DrawPremul(GRAPHICSTHREAD threadID, int FLAG){
|
|
if(material->premultipliedTexture)
|
|
Draw(threadID,FLAG);
|
|
}
|
|
void wiEmittedParticle::DrawNonPremul(GRAPHICSTHREAD threadID, int FLAG){
|
|
if(!material->premultipliedTexture)
|
|
Draw(threadID,FLAG);
|
|
}
|
|
|
|
|
|
void wiEmittedParticle::CleanUp()
|
|
{
|
|
|
|
points.clear();
|
|
|
|
SAFE_DELETE(vertexBuffer);
|
|
|
|
SAFE_DELETE_ARRAY(posSamples);
|
|
SAFE_DELETE_ARRAY(radSamples);
|
|
SAFE_DELETE_ARRAY(energySamples);
|
|
|
|
//delete(this);
|
|
}
|
|
|
|
|
|
|
|
void wiEmittedParticle::LoadShaders()
|
|
{
|
|
VertexLayoutDesc layout[] =
|
|
{
|
|
{ "POSITION", 0, FORMAT_R32G32B32_FLOAT, 0, APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
|
|
{ "TEXCOORD", 0, FORMAT_R32G32B32A32_FLOAT, 0, APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
|
|
//{ "TEXCOORD", 2, FORMAT_R32G32B32A32_FLOAT, 0, APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
|
|
{ "ROTATION", 0, FORMAT_R32_FLOAT, 0, APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
|
|
{ "VELOCITY", 0, FORMAT_R32G32B32_FLOAT, 0, APPEND_ALIGNED_ELEMENT, INPUT_PER_VERTEX_DATA, 0 },
|
|
};
|
|
UINT numElements = ARRAYSIZE(layout);
|
|
VertexShaderInfo* vsinfo = static_cast<VertexShaderInfo*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "pointspriteVS.cso", wiResourceManager::VERTEXSHADER, layout, numElements));
|
|
if (vsinfo != nullptr){
|
|
vertexShader = vsinfo->vertexShader;
|
|
vertexLayout = vsinfo->vertexLayout;
|
|
}
|
|
|
|
|
|
pixelShader = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "pointspritePS.cso", wiResourceManager::PIXELSHADER));
|
|
simplestPS = static_cast<PixelShader*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "pointspritePS_simplest.cso", wiResourceManager::PIXELSHADER));
|
|
|
|
geometryShader = static_cast<GeometryShader*>(wiResourceManager::GetShaderManager()->add(wiRenderer::SHADERPATH + "pointspriteGS.cso", wiResourceManager::GEOMETRYSHADER));
|
|
|
|
|
|
|
|
}
|
|
void wiEmittedParticle::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 wiEmittedParticle::SetUpStates()
|
|
{
|
|
RasterizerStateDesc rs;
|
|
rs.FillMode=FILL_SOLID;
|
|
rs.CullMode=CULL_BACK;
|
|
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);
|
|
|
|
|
|
rs.FillMode=FILL_WIREFRAME;
|
|
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;
|
|
wireFrameRS = new RasterizerState;
|
|
wiRenderer::GetDevice()->CreateRasterizerState(&rs,wireFrameRS);
|
|
|
|
|
|
|
|
|
|
|
|
DepthStencilStateDesc dsd;
|
|
dsd.DepthEnable = false;
|
|
dsd.DepthWriteMask = DEPTH_WRITE_MASK_ZERO;
|
|
dsd.DepthFunc = COMPARISON_GREATER;
|
|
|
|
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_SRC_ALPHA;
|
|
bd.RenderTarget[0].DestBlend = BLEND_INV_SRC_ALPHA;
|
|
bd.RenderTarget[0].BlendOp = BLEND_OP_ADD;
|
|
bd.RenderTarget[0].SrcBlendAlpha = BLEND_ONE;
|
|
bd.RenderTarget[0].DestBlendAlpha = BLEND_INV_SRC_ALPHA;
|
|
bd.RenderTarget[0].BlendOpAlpha = BLEND_OP_ADD;
|
|
bd.RenderTarget[0].RenderTargetWriteMask = 0x0f;
|
|
bd.IndependentBlendEnable=false;
|
|
blendStateAlpha = new BlendState;
|
|
wiRenderer::GetDevice()->CreateBlendState(&bd,blendStateAlpha);
|
|
|
|
ZeroMemory(&bd, sizeof(bd));
|
|
bd.RenderTarget[0].BlendEnable=true;
|
|
bd.RenderTarget[0].SrcBlend = BLEND_SRC_ALPHA;
|
|
bd.RenderTarget[0].DestBlend = BLEND_ONE;
|
|
bd.RenderTarget[0].BlendOp = BLEND_OP_ADD;
|
|
bd.RenderTarget[0].SrcBlendAlpha = BLEND_SRC_ALPHA;
|
|
bd.RenderTarget[0].DestBlendAlpha = BLEND_INV_SRC_ALPHA;
|
|
bd.RenderTarget[0].BlendOpAlpha = BLEND_OP_ADD;
|
|
bd.RenderTarget[0].RenderTargetWriteMask = COLOR_WRITE_ENABLE_ALL;
|
|
bd.IndependentBlendEnable=false;
|
|
blendStateAdd = new BlendState;
|
|
wiRenderer::GetDevice()->CreateBlendState(&bd,blendStateAdd);
|
|
}
|
|
void wiEmittedParticle::LoadVertexBuffer()
|
|
{
|
|
vertexBuffer=NULL;
|
|
|
|
GPUBufferDesc bd;
|
|
ZeroMemory( &bd, sizeof(bd) );
|
|
bd.Usage = USAGE_DYNAMIC;
|
|
bd.ByteWidth = sizeof( Point ) * MAX_PARTICLES;
|
|
bd.BindFlags = BIND_VERTEX_BUFFER;
|
|
bd.CPUAccessFlags = CPU_ACCESS_WRITE;
|
|
vertexBuffer = new GPUBuffer;
|
|
wiRenderer::GetDevice()->CreateBuffer( &bd, NULL, vertexBuffer );
|
|
}
|
|
void wiEmittedParticle::SetUpStatic()
|
|
{
|
|
LoadShaders();
|
|
SetUpCB();
|
|
SetUpStates();
|
|
}
|
|
void wiEmittedParticle::CleanUpStatic()
|
|
{
|
|
SAFE_DELETE(vertexLayout);
|
|
SAFE_DELETE(vertexShader);
|
|
SAFE_DELETE(pixelShader);
|
|
SAFE_DELETE(simplestPS);
|
|
SAFE_DELETE(geometryShader);
|
|
SAFE_DELETE(constantBuffer);
|
|
SAFE_DELETE(blendStateAlpha);
|
|
SAFE_DELETE(blendStateAdd);
|
|
SAFE_DELETE(rasterizerState);
|
|
SAFE_DELETE(wireFrameRS);
|
|
SAFE_DELETE(depthStencilState);
|
|
}
|
|
|
|
void wiEmittedParticle::Serialize(wiArchive& archive)
|
|
{
|
|
if (archive.IsReadMode())
|
|
{
|
|
archive >> emit;
|
|
archive >> transform4;
|
|
archive >> transform3;
|
|
archive >> name;
|
|
archive >> materialName;
|
|
archive >> size;
|
|
archive >> random_factor;
|
|
archive >> normal_factor;
|
|
archive >> count;
|
|
archive >> life;
|
|
archive >> random_life;
|
|
archive >> scaleX;
|
|
archive >> scaleY;
|
|
archive >> rotation;
|
|
archive >> motionBlurAmount;
|
|
archive >> lightName;
|
|
|
|
LoadVertexBuffer();
|
|
SetupLightInterpolators();
|
|
}
|
|
else
|
|
{
|
|
archive << emit;
|
|
archive << transform4;
|
|
archive << transform3;
|
|
archive << name;
|
|
archive << materialName;
|
|
archive << size;
|
|
archive << random_factor;
|
|
archive << normal_factor;
|
|
archive << count;
|
|
archive << life;
|
|
archive << random_life;
|
|
archive << scaleX;
|
|
archive << scaleY;
|
|
archive << rotation;
|
|
archive << motionBlurAmount;
|
|
archive << lightName;
|
|
}
|
|
}
|