improved culling
This commit is contained in:
@@ -423,14 +423,8 @@ void wiHairParticle::Draw(Camera* camera, SHADERTYPE shaderType, GRAPHICSTHREAD
|
||||
XMStoreFloat3(&eye, Eye);
|
||||
}
|
||||
|
||||
frustum.ConstructFrustum((float)LOD[2], camera->Projection, cull_View);
|
||||
const FrameCulling& culling = frameCullings[camera];
|
||||
|
||||
|
||||
CulledList culledPatches;
|
||||
if(spTree)
|
||||
wiSPTree::getVisible(spTree->root,frustum,culledPatches);
|
||||
|
||||
if(!culledPatches.empty())
|
||||
{
|
||||
GraphicsDevice* device = wiRenderer::GetDevice();
|
||||
device->EventBegin(L"HairParticle", threadID);
|
||||
@@ -462,36 +456,21 @@ void wiHairParticle::Draw(Camera* camera, SHADERTYPE shaderType, GRAPHICSTHREAD
|
||||
// use the depthstencil of the drawworld instead!
|
||||
//device->BindDepthStencilState(dss,STENCILREF_DEFAULT,threadID);
|
||||
|
||||
|
||||
for(int i=0;i<3;++i){
|
||||
vector<Point> renderPoints;
|
||||
renderPoints.reserve(MAX_PARTICLES);
|
||||
|
||||
if(texture){
|
||||
for(int i=0;i<3;++i)
|
||||
{
|
||||
if(texture)
|
||||
{
|
||||
device->BindGS(i<2?qgs[0]:qgs[1],threadID);
|
||||
device->BindRasterizerState(i<2?ncrs:rs,threadID);
|
||||
}
|
||||
else
|
||||
device->BindGS(gs[i],threadID);
|
||||
CulledList::iterator iter = culledPatches.begin();
|
||||
while(iter != culledPatches.end()){
|
||||
Cullable* culled = *iter;
|
||||
Patch* patch = ((PatchHolder*)culled)->patch;
|
||||
|
||||
float dis = wiMath::Distance(eye,((PatchHolder*)culled)->bounds.getCenter());
|
||||
|
||||
if(dis<LOD[i]){
|
||||
culledPatches.erase(iter++);
|
||||
culled=NULL;
|
||||
renderPoints.insert(renderPoints.end(),patch->p.begin(),patch->p.end());
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
{
|
||||
device->BindGS(gs[i], threadID);
|
||||
}
|
||||
|
||||
device->UpdateBuffer(vb[i],renderPoints.data(),threadID,(int)(sizeof(Point)*renderPoints.size()));
|
||||
device->UpdateBuffer(vb[i],culling.renderPoints[i].data(),threadID,(int)(sizeof(Point)*culling.renderPoints[i].size()));
|
||||
device->BindVertexBuffer(vb[i],0,sizeof(Point),threadID);
|
||||
device->Draw((int)renderPoints.size(),threadID);
|
||||
device->Draw((int)culling.renderPoints[i].size(),threadID);
|
||||
}
|
||||
|
||||
device->BindGS(nullptr,threadID);
|
||||
@@ -499,6 +478,70 @@ void wiHairParticle::Draw(Camera* camera, SHADERTYPE shaderType, GRAPHICSTHREAD
|
||||
device->EventEnd(threadID);
|
||||
}
|
||||
}
|
||||
void wiHairParticle::PerformCulling(Camera* camera)
|
||||
{
|
||||
XMMATRIX inverseMat = XMLoadFloat4x4(&OriginalMatrix_Inverse);
|
||||
XMMATRIX renderMatrix = inverseMat * object->getMatrix();
|
||||
XMMATRIX inverseRenderMat = XMMatrixInverse(nullptr, renderMatrix);
|
||||
|
||||
Frustum frustum;
|
||||
|
||||
// Culling camera needs to be transformed according to hair ps transform (inverse)
|
||||
XMFLOAT4X4 cull_View;
|
||||
XMFLOAT3 eye;
|
||||
{
|
||||
XMMATRIX View;
|
||||
XMVECTOR At = XMVectorSet(0, 0, 1, 0), Up = XMVectorSet(0, 1, 0, 0), Eye;
|
||||
|
||||
XMMATRIX camRot = XMMatrixRotationQuaternion(XMLoadFloat4(&camera->rotation));
|
||||
At = XMVector3Normalize(XMVector3Transform(XMVector3Transform(At, camRot), inverseRenderMat));
|
||||
Up = XMVector3Normalize(XMVector3Transform(XMVector3Transform(Up, camRot), inverseRenderMat));
|
||||
Eye = XMVector4Transform(camera->GetEye(), inverseRenderMat);
|
||||
|
||||
View = XMMatrixLookToLH(Eye, At, Up);
|
||||
|
||||
XMStoreFloat4x4(&cull_View, View);
|
||||
XMStoreFloat3(&eye, Eye);
|
||||
}
|
||||
|
||||
frustum.ConstructFrustum((float)LOD[2], camera->Projection, cull_View);
|
||||
|
||||
|
||||
|
||||
FrameCulling& culling = frameCullings[camera];
|
||||
CulledList& culledPatches = culling.culledPatches;
|
||||
|
||||
culling.culledPatches.clear();
|
||||
|
||||
if (spTree != nullptr)
|
||||
{
|
||||
wiSPTree::getVisible(spTree->root, frustum, culledPatches);
|
||||
|
||||
for (int i = 0; i<3; ++i)
|
||||
{
|
||||
vector<Point>& renderPoints = culling.renderPoints[i];
|
||||
renderPoints.clear();
|
||||
renderPoints.reserve(MAX_PARTICLES);
|
||||
|
||||
CulledList::iterator iter = culledPatches.begin();
|
||||
while (iter != culledPatches.end()) {
|
||||
Cullable* culled = *iter;
|
||||
Patch* patch = ((PatchHolder*)culled)->patch;
|
||||
|
||||
float dis = wiMath::Distance(eye, ((PatchHolder*)culled)->bounds.getCenter());
|
||||
|
||||
if (dis<LOD[i]) {
|
||||
culledPatches.erase(iter++);
|
||||
culled = NULL;
|
||||
renderPoints.insert(renderPoints.end(), patch->p.begin(), patch->p.end());
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wiHairParticle::Patch::Patch(){
|
||||
p.resize(0);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include "wiParticle.h"
|
||||
#include "ConstantBufferMapping.h"
|
||||
#include "wiSPTree.h"
|
||||
|
||||
class wiSPTree;
|
||||
struct Material;
|
||||
struct Camera;
|
||||
|
||||
@@ -52,6 +52,12 @@ private:
|
||||
public:
|
||||
static void LoadShaders();
|
||||
private:
|
||||
struct FrameCulling
|
||||
{
|
||||
CulledList culledPatches;
|
||||
vector<Point> renderPoints[3]; // per lod
|
||||
};
|
||||
unordered_map<Camera*, FrameCulling> frameCullings;
|
||||
|
||||
public:
|
||||
wiHairParticle();
|
||||
@@ -61,6 +67,7 @@ public:
|
||||
|
||||
void SetUpPatches();
|
||||
void Draw(Camera* camera, SHADERTYPE shaderType, GRAPHICSTHREAD threadID);
|
||||
void PerformCulling(Camera* camera);
|
||||
|
||||
static void CleanUpStatic();
|
||||
static void SetUpStatic();
|
||||
|
||||
+98
-79
@@ -79,6 +79,8 @@ vector<Cube> wiRenderer::cubes;
|
||||
vector<wiTranslator*> wiRenderer::renderableTranslators;
|
||||
vector<pair<XMFLOAT4X4, XMFLOAT4>> wiRenderer::renderableBoxes;
|
||||
|
||||
unordered_map<Camera*, wiRenderer::FrameCulling> wiRenderer::frameCullings;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
wiRenderer::wiRenderer()
|
||||
@@ -1416,10 +1418,42 @@ void wiRenderer::UpdatePerFrameData()
|
||||
{
|
||||
if (GetGameSpeed() > 0)
|
||||
{
|
||||
|
||||
UpdateSPTree(spTree);
|
||||
UpdateSPTree(spTree_lights);
|
||||
}
|
||||
// Perform culling:
|
||||
{
|
||||
for (auto& x : frameCullings)
|
||||
{
|
||||
Camera* cam = x.first;
|
||||
FrameCulling& culling = x.second;
|
||||
|
||||
culling.culledRenderer.clear();
|
||||
culling.culledObjects.clear();
|
||||
culling.culledObjects_transparent.clear();
|
||||
culling.culledLights.clear();
|
||||
|
||||
if (spTree != nullptr)
|
||||
{
|
||||
wiSPTree::getVisible(spTree->root, cam->frustum, culling.culledObjects, wiSPTree::SortType::SP_TREE_SORT_FRONT_TO_BACK);
|
||||
wiSPTree::getVisible(spTree->root, cam->frustum, culling.culledObjects_transparent, wiSPTree::SortType::SP_TREE_SORT_PAINTER);
|
||||
for (Cullable* object : culling.culledObjects)
|
||||
{
|
||||
for (wiHairParticle* hair : ((Object*)object)->hParticleSystems) {
|
||||
hair->PerformCulling(cam);
|
||||
}
|
||||
culling.culledRenderer[((Object*)object)->mesh].insert((Object*)object);
|
||||
}
|
||||
}
|
||||
if (spTree_lights != nullptr)
|
||||
{
|
||||
Frustum frustum;
|
||||
frustum.ConstructFrustum(min(cam->zFarP, GetScene().worldInfo.fogSEH.y), cam->Projection, cam->View);
|
||||
wiSPTree::getVisible(spTree_lights->root, frustum, culling.culledLights);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UpdateBoneLines();
|
||||
UpdateCubes();
|
||||
@@ -1434,6 +1468,7 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID)
|
||||
UpdateCameraCB(threadID);
|
||||
|
||||
|
||||
// Skinning:
|
||||
{
|
||||
bool streamOutSetUp = false;
|
||||
|
||||
@@ -1523,6 +1558,34 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID)
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Environment probe setup:
|
||||
{
|
||||
Texture2D* envMaps[] = { enviroMap, enviroMap };
|
||||
XMFLOAT3 envMapPositions[] = { XMFLOAT3(0,0,0),XMFLOAT3(0,0,0) };
|
||||
GetScene().environmentProbes.sort(
|
||||
[&](EnvironmentProbe* a, EnvironmentProbe* b) {
|
||||
return wiMath::DistanceSquared(a->translation, getCamera()->translation) < wiMath::DistanceSquared(b->translation, getCamera()->translation);
|
||||
}
|
||||
);
|
||||
int envProbeInd = 0;
|
||||
for (auto& x : GetScene().environmentProbes)
|
||||
{
|
||||
envMaps[envProbeInd] = x->cubeMap.GetTexture();
|
||||
envMapPositions[envProbeInd] = x->translation;
|
||||
envProbeInd++;
|
||||
if (envProbeInd >= ARRAYSIZE(envMaps))
|
||||
break;
|
||||
}
|
||||
|
||||
MiscCB envProbeCB;
|
||||
envProbeCB.mTransform.r[0] = XMLoadFloat3(&envMapPositions[0]);
|
||||
envProbeCB.mTransform.r[1] = XMLoadFloat3(&envMapPositions[1]);
|
||||
envProbeCB.mTransform = XMMatrixTranspose(envProbeCB.mTransform);
|
||||
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &envProbeCB, threadID);
|
||||
GetDevice()->BindResourcePS(envMaps[0], TEXSLOT_ENV0, threadID);
|
||||
GetDevice()->BindResourcePS(envMaps[1], TEXSLOT_ENV1, threadID);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2079,12 +2142,8 @@ void wiRenderer::DrawImagesNormals(GRAPHICSTHREAD threadID, Texture2D* refracRes
|
||||
}
|
||||
void wiRenderer::DrawLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
{
|
||||
Frustum frustum;
|
||||
frustum.ConstructFrustum(min(camera->zFarP, GetScene().worldInfo.fogSEH.y),camera->Projection,camera->View);
|
||||
|
||||
CulledList culledObjects;
|
||||
if(spTree_lights)
|
||||
wiSPTree::getVisible(spTree_lights->root,frustum,culledObjects);
|
||||
const FrameCulling& culling = frameCullings[camera];
|
||||
const CulledList& culledLights = culling.culledLights;
|
||||
|
||||
GetDevice()->EventBegin(L"Light Render", threadID);
|
||||
|
||||
@@ -2143,7 +2202,7 @@ void wiRenderer::DrawLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
}
|
||||
|
||||
|
||||
for(Cullable* c : culledObjects){
|
||||
for(Cullable* c : culledLights){
|
||||
Light* l = (Light*)c;
|
||||
if (l->type != type)
|
||||
continue;
|
||||
@@ -2222,15 +2281,10 @@ void wiRenderer::DrawLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
}
|
||||
void wiRenderer::DrawVolumeLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
{
|
||||
Frustum frustum;
|
||||
frustum.ConstructFrustum(min(camera->zFarP, GetScene().worldInfo.fogSEH.y), camera->Projection, camera->View);
|
||||
const FrameCulling& culling = frameCullings[camera];
|
||||
const CulledList& culledLights = culling.culledLights;
|
||||
|
||||
|
||||
CulledList culledObjects;
|
||||
if(spTree_lights)
|
||||
wiSPTree::getVisible(spTree_lights->root,frustum,culledObjects);
|
||||
|
||||
if(!culledObjects.empty())
|
||||
if(!culledLights.empty())
|
||||
{
|
||||
GetDevice()->EventBegin(L"Light Volume Render", threadID);
|
||||
|
||||
@@ -2259,7 +2313,7 @@ void wiRenderer::DrawVolumeLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
GetDevice()->BindVS(vertexShaders[VSTYPE_VOLUMESPOTLIGHT],threadID);
|
||||
}
|
||||
|
||||
for(Cullable* c : culledObjects){
|
||||
for(Cullable* c : culledLights){
|
||||
Light* l = (Light*)c;
|
||||
if(l->type==type && l->noHalo==false){
|
||||
|
||||
@@ -2312,14 +2366,12 @@ void wiRenderer::DrawVolumeLights(Camera* camera, GRAPHICSTHREAD threadID)
|
||||
}
|
||||
|
||||
|
||||
void wiRenderer::DrawLensFlares(GRAPHICSTHREAD threadID){
|
||||
|
||||
|
||||
CulledList culledObjects;
|
||||
if(spTree_lights)
|
||||
wiSPTree::getVisible(spTree_lights->root,cam->frustum,culledObjects);
|
||||
void wiRenderer::DrawLensFlares(GRAPHICSTHREAD threadID)
|
||||
{
|
||||
const FrameCulling& culling = frameCullings[getCamera()];
|
||||
const CulledList& culledLights = culling.culledLights;
|
||||
|
||||
for(Cullable* c:culledObjects)
|
||||
for(Cullable* c: culledLights)
|
||||
{
|
||||
Light* l = (Light*)c;
|
||||
|
||||
@@ -2362,12 +2414,12 @@ void wiRenderer::ClearShadowMaps(GRAPHICSTHREAD threadID){
|
||||
}
|
||||
void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID)
|
||||
{
|
||||
if (GameSpeed) {
|
||||
if (GameSpeed)
|
||||
{
|
||||
GetDevice()->EventBegin(L"ShadowMap Render", threadID);
|
||||
|
||||
CulledList culledLights;
|
||||
if (spTree_lights)
|
||||
wiSPTree::getVisible(spTree_lights->root, cam->frustum, culledLights);
|
||||
const FrameCulling& culling = frameCullings[getCamera()];
|
||||
const CulledList& culledLights = culling.culledLights;
|
||||
|
||||
if (culledLights.size() > 0)
|
||||
{
|
||||
@@ -2940,39 +2992,12 @@ void wiRenderer::DrawWorld(Camera* camera, bool tessellation, GRAPHICSTHREAD thr
|
||||
{
|
||||
tessellation = tessellation && GetDevice()->CheckCapability(GraphicsDevice::GRAPHICSDEVICE_CAPABILITY_TESSELLATION);
|
||||
|
||||
CulledCollection culledRenderer;
|
||||
CulledList culledObjects;
|
||||
if(spTree)
|
||||
wiSPTree::getVisible(spTree->root, camera->frustum,culledObjects,wiSPTree::SortType::SP_TREE_SORT_FRONT_TO_BACK);
|
||||
else return;
|
||||
const FrameCulling& culling = frameCullings[camera];
|
||||
const CulledList& culledObjects = culling.culledObjects;
|
||||
const CulledCollection& culledRenderer = culling.culledRenderer;
|
||||
|
||||
if(!culledObjects.empty())
|
||||
{
|
||||
|
||||
Texture2D* envMaps[] = { enviroMap, enviroMap };
|
||||
XMFLOAT3 envMapPositions[] = { XMFLOAT3(0,0,0),XMFLOAT3(0,0,0) };
|
||||
GetScene().environmentProbes.sort(
|
||||
[&](EnvironmentProbe* a, EnvironmentProbe* b) {
|
||||
return wiMath::DistanceSquared(a->translation, getCamera()->translation) < wiMath::DistanceSquared(b->translation, getCamera()->translation);
|
||||
}
|
||||
);
|
||||
int envProbeInd = 0;
|
||||
for (auto& x : GetScene().environmentProbes)
|
||||
{
|
||||
envMaps[envProbeInd] = x->cubeMap.GetTexture();
|
||||
envMapPositions[envProbeInd] = x->translation;
|
||||
envProbeInd++;
|
||||
if (envProbeInd >= ARRAYSIZE(envMaps))
|
||||
break;
|
||||
}
|
||||
|
||||
MiscCB envProbeCB;
|
||||
envProbeCB.mTransform.r[0] = XMLoadFloat3(&envMapPositions[0]);
|
||||
envProbeCB.mTransform.r[1] = XMLoadFloat3(&envMapPositions[1]);
|
||||
envProbeCB.mTransform = XMMatrixTranspose(envProbeCB.mTransform);
|
||||
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &envProbeCB, threadID);
|
||||
GetDevice()->BindResourcePS(envMaps[0], TEXSLOT_ENV0, threadID);
|
||||
GetDevice()->BindResourcePS(envMaps[1], TEXSLOT_ENV1, threadID);
|
||||
|
||||
if (shaderType == SHADERTYPE_TILEDFORWARD)
|
||||
{
|
||||
@@ -2989,7 +3014,6 @@ void wiRenderer::DrawWorld(Camera* camera, bool tessellation, GRAPHICSTHREAD thr
|
||||
|
||||
|
||||
for(Cullable* object : culledObjects){
|
||||
culledRenderer[((Object*)object)->mesh].insert((Object*)object);
|
||||
if(grass){
|
||||
for(wiHairParticle* hair : ((Object*)object)->hParticleSystems){
|
||||
hair->Draw(camera, shaderType, threadID);
|
||||
@@ -3025,9 +3049,9 @@ void wiRenderer::DrawWorld(Camera* camera, bool tessellation, GRAPHICSTHREAD thr
|
||||
}
|
||||
|
||||
|
||||
for (CulledCollection::iterator iter = culledRenderer.begin(); iter != culledRenderer.end(); ++iter) {
|
||||
for (CulledCollection::const_iterator iter = culledRenderer.begin(); iter != culledRenderer.end(); ++iter) {
|
||||
Mesh* mesh = iter->first;
|
||||
CulledObjectList& visibleInstances = iter->second;
|
||||
const CulledObjectList& visibleInstances = iter->second;
|
||||
|
||||
float tessF = mesh->getTessellationFactor();
|
||||
|
||||
@@ -3231,10 +3255,10 @@ void wiRenderer::DrawWorld(Camera* camera, bool tessellation, GRAPHICSTHREAD thr
|
||||
void wiRenderer::DrawWorldTransparent(Camera* camera, SHADERTYPE shaderType, Texture2D* refracRes, Texture2D* refRes
|
||||
, Texture2D* waterRippleNormals, GRAPHICSTHREAD threadID, bool grass)
|
||||
{
|
||||
CulledCollection culledRenderer;
|
||||
CulledList culledObjects;
|
||||
if (spTree)
|
||||
wiSPTree::getVisible(spTree->root, camera->frustum,culledObjects, wiSPTree::SortType::SP_TREE_SORT_PAINTER);
|
||||
|
||||
const FrameCulling& culling = frameCullings[camera];
|
||||
const CulledList& culledObjects = culling.culledObjects_transparent;
|
||||
const CulledCollection& culledRenderer = culling.culledRenderer;
|
||||
|
||||
if(!culledObjects.empty())
|
||||
{
|
||||
@@ -3254,7 +3278,6 @@ void wiRenderer::DrawWorldTransparent(Camera* camera, SHADERTYPE shaderType, Tex
|
||||
hair->Draw(camera, shaderType, threadID);
|
||||
}
|
||||
}
|
||||
culledRenderer[((Object*)object)->mesh].insert((Object*)object);
|
||||
}
|
||||
|
||||
GetDevice()->BindPrimitiveTopology(TRIANGLELIST,threadID);
|
||||
@@ -3281,9 +3304,9 @@ void wiRenderer::DrawWorldTransparent(Camera* camera, SHADERTYPE shaderType, Tex
|
||||
|
||||
GetDevice()->BindBlendState(blendStates[BSTYPE_OPAQUE],threadID);
|
||||
|
||||
for (CulledCollection::iterator iter = culledRenderer.begin(); iter != culledRenderer.end(); ++iter) {
|
||||
for (CulledCollection::const_iterator iter = culledRenderer.begin(); iter != culledRenderer.end(); ++iter) {
|
||||
Mesh* mesh = iter->first;
|
||||
CulledObjectList& visibleInstances = iter->second;
|
||||
const CulledObjectList& visibleInstances = iter->second;
|
||||
|
||||
bool isValid = false;
|
||||
for (MeshSubset& subset : mesh->subsets)
|
||||
@@ -3548,14 +3571,14 @@ void wiRenderer::ComputeTiledLightCulling(GRAPHICSTHREAD threadID)
|
||||
dispatchParams.numThreadGroups[2] = 1;
|
||||
|
||||
// Fill Light Array with lights in the frustum
|
||||
CulledList culledObjects;
|
||||
if (spTree_lights)
|
||||
wiSPTree::getVisible(spTree_lights->root, getCamera()->frustum, culledObjects);
|
||||
const FrameCulling& culling = frameCullings[getCamera()];
|
||||
const CulledList& culledLights = culling.culledLights;
|
||||
|
||||
static LightArrayType* lightArray = (LightArrayType*)_mm_malloc(sizeof(LightArrayType)*MAX_LIGHTS, 16);
|
||||
ZeroMemory(lightArray, sizeof(lightArray));
|
||||
|
||||
UINT lightCounter = 0;
|
||||
for (Cullable* c : culledObjects)
|
||||
for (Cullable* c : culledLights)
|
||||
{
|
||||
Light* l = (Light*)c;
|
||||
|
||||
@@ -3732,14 +3755,10 @@ void wiRenderer::ComputeTiledLightCulling(GRAPHICSTHREAD threadID)
|
||||
}
|
||||
void wiRenderer::EnableForwardShadowmaps(GRAPHICSTHREAD threadID)
|
||||
{
|
||||
Frustum frustum;
|
||||
frustum.ConstructFrustum(min(getCamera()->zFarP, GetScene().worldInfo.fogSEH.y), getCamera()->Projection, getCamera()->View);
|
||||
const FrameCulling& culling = frameCullings[getCamera()];
|
||||
const CulledList& culledLights = culling.culledLights;
|
||||
|
||||
CulledList culledObjects;
|
||||
if (spTree_lights)
|
||||
wiSPTree::getVisible(spTree_lights->root, frustum, culledObjects);
|
||||
|
||||
for (Cullable* c : culledObjects)
|
||||
for (Cullable* c : culledLights)
|
||||
{
|
||||
Light* l = (Light*)c;
|
||||
|
||||
|
||||
@@ -389,6 +389,15 @@ public:
|
||||
static Vertex TransformVertex(const Mesh* mesh, int vertexI, const XMMATRIX& mat = XMMatrixIdentity());
|
||||
static Vertex TransformVertex(const Mesh* mesh, const SkinnedVertex& vertex, const XMMATRIX& mat = XMMatrixIdentity());
|
||||
static XMFLOAT3 VertexVelocity(const Mesh* mesh, const int& vertexI);
|
||||
|
||||
struct FrameCulling
|
||||
{
|
||||
CulledCollection culledRenderer;
|
||||
CulledList culledObjects;
|
||||
CulledList culledObjects_transparent;
|
||||
CulledList culledLights;
|
||||
};
|
||||
static unordered_map<Camera*, FrameCulling> frameCullings;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace wiVersion
|
||||
// minor features, major updates
|
||||
const int minor = 9;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 2;
|
||||
const int revision = 4;
|
||||
|
||||
|
||||
long GetVersion()
|
||||
|
||||
Reference in New Issue
Block a user