Skip to content

Commit 069904d

Browse files
committed
#84 Add occlusion culling feature
1 parent b2cb4b6 commit 069904d

29 files changed

+1751
-14
lines changed

CMakeProjects.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ if (BUILD_EXAMPLE)
99
subdirs (Samples/DrawPrimitives)
1010
subdirs (Samples/Instancing)
1111
subdirs (Samples/LuckyDraw)
12+
subdirs (Samples/OcclusionQuery)
1213
subdirs (Samples/Physics)
1314
subdirs (Samples/Sponza)
1415
subdirs (Samples/SkinnedMesh)

Projects/Irrlicht/Source/CD3D11Driver.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -611,24 +611,23 @@ namespace irr
611611
return;
612612

613613
bool available = block;
614-
GUID tmp;
615-
u32 size = sizeof(DWORD);
616-
u32 r = 0;
614+
UINT64 tmp;
615+
u32 size = sizeof(UINT64);
617616

618617
if (!block)
619-
available = (reinterpret_cast<ID3D11Query*>(OcclusionQueries[index].PID)->GetPrivateData(tmp, &size, &r) == S_OK);
618+
available = Context->GetData(reinterpret_cast<ID3D11Query*>(OcclusionQueries[index].PID), &tmp, size, 0) == S_OK;
620619
else
621620
{
622621
do
623622
{
624-
HRESULT hr = reinterpret_cast<ID3D11Query*>(OcclusionQueries[index].PID)->GetPrivateData(tmp, &size, &r);
623+
HRESULT hr = Context->GetData(reinterpret_cast<ID3D11Query*>(OcclusionQueries[index].PID), &tmp, size, 0);
625624
available = (hr == S_OK);
626625
if (hr != S_FALSE)
627626
break;
628627
} while (!available);
629628
}
630629
if (available)
631-
OcclusionQueries[index].Result = r;
630+
OcclusionQueries[index].Result = (u32)tmp;
632631
}
633632
}
634633

Projects/Main/Source/SkylichtEngine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ This file is part of the "Skylicht Engine".
109109
#include "SkinnedInstancing/CRenderSkinnedInstancing.h"
110110
#include "VertexAnimation/CRenderMeshInstancingVAT.h"
111111

112+
// OcclusionQuery
113+
#include "OcclusionQuery/COcclusionQuery.h"
114+
112115
// 3D Animation
113116
#include "Animation/CAnimationManager.h"
114117
#include "Animation/CAnimationController.h"

Projects/Skylicht/Components/Source/Primitive/CPrimitive.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,17 @@ namespace Skylicht
233233
return m_material;
234234
}
235235

236+
CMesh* CPrimitive::getMesh()
237+
{
238+
CEntityManager* entityMgr = m_gameObject->getEntityManager();
239+
240+
CPrimitiveRenderer* renderer = entityMgr->getSystem<CPrimitiveRenderer>();
241+
if (renderer)
242+
return renderer->getMesh(m_type);
243+
244+
return NULL;
245+
}
246+
236247
void CPrimitive::setCustomMaterial(CMaterial* material)
237248
{
238249
if (material)
@@ -245,4 +256,15 @@ namespace Skylicht
245256
m_useCustomMaterial = false;
246257
}
247258
}
259+
260+
void CPrimitive::setInstancing(bool b)
261+
{
262+
m_instancing = b;
263+
for (CEntity* entity : m_entities)
264+
{
265+
CPrimiviteData* data = GET_ENTITY_DATA(entity, CPrimiviteData);
266+
if (data)
267+
data->Instancing = b;
268+
}
269+
}
248270
}

Projects/Skylicht/Components/Source/Primitive/CPrimitive.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ This file is part of the "Skylicht Engine".
2626

2727
#include "CPrimiviteData.h"
2828
#include "Entity/CEntityHandler.h"
29+
#include "RenderMesh/CMesh.h"
2930

3031
namespace Skylicht
3132
{
@@ -68,12 +69,11 @@ namespace Skylicht
6869

6970
CMaterial* getMaterial();
7071

72+
CMesh* getMesh();
73+
7174
void setCustomMaterial(CMaterial* material);
7275

73-
inline void setInstancing(bool b)
74-
{
75-
m_instancing = b;
76-
}
76+
void setInstancing(bool b);
7777

7878
inline bool isInstancing()
7979
{

Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ namespace Skylicht
165165
}
166166
}
167167

168+
CMesh* CPrimitiveRenderer::getMesh(CPrimiviteData::EPrimitive type)
169+
{
170+
return m_meshTangent[type];
171+
}
172+
168173
void CPrimitiveRenderer::renderPrimitive(CEntityManager* entityManager,
169174
CPrimiviteData** primitives,
170175
CMesh* mesh,

Projects/Skylicht/Components/Source/Primitive/CPrimitiveRenderer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ namespace Skylicht
5656

5757
virtual void render(CEntityManager* entityManager);
5858

59+
CMesh* getMesh(CPrimiviteData::EPrimitive type);
60+
5961
void renderPrimitive(CEntityManager* entityManager,
6062
CPrimiviteData** primitives,
6163
CMesh* mesh,

Projects/Skylicht/Engine/Source/Entity/CEntityManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ This file is part of the "Skylicht Engine".
3737
#include "RenderMesh/CSoftwareSkinningSystem.h"
3838
#include "SkinnedInstancing/CSkinnedMeshRendererInstancing.h"
3939
#include "SkinnedInstancing/CSkinnedInstanceAnimationSystem.h"
40+
#include "OcclusionQuery/COcclusionQueryRenderer.h"
4041
#include "Culling/CVisibleSystem.h"
4142
#include "Culling/CCullingSystem.h"
4243
#include "LOD/CLODSystem.h"
@@ -76,6 +77,7 @@ namespace Skylicht
7677
addRenderSystem<CSkinnedMeshRenderer>();
7778
addRenderSystem<CMeshRendererInstancing>();
7879
addRenderSystem<CSkinnedMeshRendererInstancing>();
80+
addRenderSystem<COcclusionQueryRenderer>();
7981
addRenderSystem<CDebugRenderer>();
8082
}
8183

Projects/Skylicht/Engine/Source/Entity/IRenderSystem.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ namespace Skylicht
3939
{
4040
Sky = 0,
4141
Opaque,
42+
OcclusionQuery,
4243
Transparent,
4344
Effect,
4445
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
!@
3+
MIT License
4+
5+
Copyright (c) 2020 Skylicht Technology CO., LTD
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
8+
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
9+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
10+
subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
This file is part of the "Skylicht Engine".
21+
https://github.com/skylicht-lab/skylicht-engine
22+
!#
23+
*/
24+
25+
#include "pch.h"
26+
#include "COcclusionQuery.h"
27+
28+
#include "GameObject/CGameObject.h"
29+
#include "Entity/CEntity.h"
30+
31+
namespace Skylicht
32+
{
33+
COcclusionQuery::COcclusionQuery() :
34+
m_queryData(NULL)
35+
{
36+
37+
}
38+
39+
COcclusionQuery::~COcclusionQuery()
40+
{
41+
if (m_gameObject)
42+
m_gameObject->getEntity()->removeData<COcclusionQueryData>();
43+
}
44+
45+
void COcclusionQuery::initComponent()
46+
{
47+
m_queryData = m_gameObject->getEntity()->addData<COcclusionQueryData>();
48+
}
49+
50+
void COcclusionQuery::updateComponent()
51+
{
52+
53+
}
54+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
!@
3+
MIT License
4+
5+
Copyright (c) 2020 Skylicht Technology CO., LTD
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
8+
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
9+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
10+
subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
This file is part of the "Skylicht Engine".
21+
https://github.com/skylicht-lab/skylicht-engine
22+
!#
23+
*/
24+
25+
#pragma once
26+
27+
#include "Components/CComponentSystem.h"
28+
#include "COcclusionQueryData.h"
29+
30+
namespace Skylicht
31+
{
32+
class SKYLICHT_API COcclusionQuery : public CComponentSystem
33+
{
34+
protected:
35+
COcclusionQueryData* m_queryData;
36+
37+
public:
38+
COcclusionQuery();
39+
40+
virtual ~COcclusionQuery();
41+
42+
virtual void initComponent();
43+
44+
virtual void updateComponent();
45+
46+
inline void setAABBox(const core::aabbox3df& box)
47+
{
48+
m_queryData->setAABBox(box);
49+
}
50+
51+
inline u32 getResult()
52+
{
53+
return m_queryData->QueryResult;
54+
}
55+
56+
inline bool getVisible()
57+
{
58+
return m_queryData->QueryVisible;
59+
}
60+
};
61+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
!@
3+
MIT License
4+
5+
Copyright (c) 2024 Skylicht Technology CO., LTD
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
8+
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
9+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
10+
subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
This file is part of the "Skylicht Engine".
21+
https://github.com/skylicht-lab/skylicht-engine
22+
!#
23+
*/
24+
25+
#include "pch.h"
26+
#include "COcclusionQueryData.h"
27+
28+
namespace Skylicht
29+
{
30+
IMPLEMENT_DATA_TYPE_INDEX(COcclusionQueryData);
31+
32+
COcclusionQueryData::COcclusionQueryData() :
33+
m_node(NULL),
34+
m_registerQuery(false),
35+
NeedValidate(true),
36+
QueryResult(0),
37+
QueryVisible(false)
38+
{
39+
float scale = 0.5f;
40+
m_box.MinEdge.set(-scale, -scale, -scale);
41+
m_box.MaxEdge.set(scale, scale, scale);
42+
43+
// Note:
44+
// Use scene-node for compatibility with some functions OcclusionQuery from Irrlicht
45+
ISceneManager* smgr = getIrrlichtDevice()->getSceneManager();
46+
m_node = new COcclusionQuerySceneNode(smgr->getRootSceneNode(), smgr, this);
47+
48+
updateLocalTransform();
49+
}
50+
51+
COcclusionQueryData::~COcclusionQueryData()
52+
{
53+
if (m_registerQuery)
54+
getVideoDriver()->removeOcclusionQuery(m_node);
55+
56+
m_node->remove();
57+
m_node->drop();
58+
}
59+
60+
void COcclusionQueryData::setAABBox(const core::aabbox3df& box)
61+
{
62+
m_box = box;
63+
updateLocalTransform();
64+
}
65+
66+
void COcclusionQueryData::updateLocalTransform()
67+
{
68+
m_node->BBox = m_box;
69+
70+
m_localTransform.makeIdentity();
71+
m_localTransform.setScale(m_box.getExtent());
72+
m_localTransform.setTranslation(m_box.getCenter());
73+
74+
NeedValidate = true;
75+
}
76+
77+
void COcclusionQueryData::registerQuery(CMesh* mesh)
78+
{
79+
getVideoDriver()->addOcclusionQuery(m_node, mesh);
80+
m_registerQuery = true;
81+
}
82+
}

0 commit comments

Comments
 (0)