Skip to content

Commit f37ef3b

Browse files
Merge pull request #1495 from vsg-dev/instancing
Implemented vsg::InstanceNode/InstanceDraw/InstanceDrawIndexed to provide higher level geometry instancing support
2 parents c6e05a5 + db243b4 commit f37ef3b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+52897
-48000
lines changed

CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ set(PBR_DEFINES
163163
-v "VSG_DIFFUSE_MAP VSG_METALLROUGHNESS_MAP VSG_NORMAL_MAP"
164164
-v "VSG_DIFFUSE_MAP VSG_METALLROUGHNESS_MAP VSG_TWO_SIDED_LIGHTING"
165165
-v "VSG_DIFFUSE_MAP VSG_NORMAL_MAP VSG_TWO_SIDED_LIGHTING"
166-
-v "VSG_LIGHTMAP_MAP VSG_NORMAL_MAP VSG_WORKFLOW_SPECGLOSS"
167166
-v "VSG_DIFFUSE_MAP VSG_EMISSIVE_MAP VSG_METALLROUGHNESS_MAP VSG_NORMAL_MAP"
168167
-v "VSG_DIFFUSE_MAP VSG_LIGHTMAP_MAP VSG_METALLROUGHNESS_MAP VSG_NORMAL_MAP"
169168
-v "VSG_DIFFUSE_MAP VSG_LIGHTMAP_MAP VSG_NORMAL_MAP VSG_TWO_SIDED_LIGHTING"
@@ -174,8 +173,15 @@ set(PBR_DEFINES
174173
-v "VSG_DIFFUSE_MAP VSG_LIGHTMAP_MAP VSG_METALLROUGHNESS_MAP VSG_NORMAL_MAP VSG_WORKFLOW_SPECGLOSS"
175174
-v "VSG_DIFFUSE_MAP VSG_EMISSIVE_MAP VSG_LIGHTMAP_MAP VSG_METALLROUGHNESS_MAP VSG_NORMAL_MAP VSG_TWO_SIDED_LIGHTING"
176175
-v "VSG_DIFFUSE_MAP VSG_EMISSIVE_MAP VSG_LIGHTMAP_MAP VSG_NORMAL_MAP VSG_SPECULAR_MAP VSG_WORKFLOW_SPECGLOSS"
176+
-v "VSG_DIFFUSE_MAP VSG_INSTANCE_ROTATION VSG_INSTANCE_SCALE VSG_INSTANCE_TRANSLATION VSG_TWO_SIDED_LIGHTING"
177+
-v "VSG_DIFFUSE_MAP VSG_INSTANCE_ROTATION VSG_INSTANCE_SCALE VSG_INSTANCE_TRANSLATION"
178+
-v "VSG_LIGHTMAP_MAP VSG_NORMAL_MAP VSG_WORKFLOW_SPECGLOSS"
177179
-v "VSG_DISPLACEMENT_MAP VSG_DIFFUSE_MAP"
178180
-v "VSG_DISPLACEMENT_MAP VSG_DETAIL_MAP VSG_DIFFUSE_MAP"
181+
-v "VSG_ALPHA_TEST VSG_DIFFUSE_MAP VSG_INSTANCE_ROTATION VSG_INSTANCE_SCALE VSG_INSTANCE_TRANSLATION VSG_NORMAL_MAP"
182+
-v "VSG_ALPHA_TEST VSG_DIFFUSE_MAP VSG_INSTANCE_ROTATION VSG_INSTANCE_SCALE VSG_INSTANCE_TRANSLATION VSG_TWO_SIDED_LIGHTING"
183+
-v "VSG_ALPHA_TEST VSG_DIFFUSE_MAP VSG_INSTANCE_ROTATION VSG_INSTANCE_SCALE VSG_INSTANCE_TRANSLATION"
184+
-v "VSG_ALPHA_TEST VSG_DIFFUSE_MAP"
179185
)
180186
181187
set(PHONG_DEFINES
@@ -185,6 +191,8 @@ set(PHONG_DEFINES
185191
-v "VSG_BILLBOARD VSG_DIFFUSE_MAP"
186192
-v "VSG_DISPLACEMENT_MAP VSG_DIFFUSE_MAP"
187193
-v "VSG_DISPLACEMENT_MAP VSG_DETAIL_MAP VSG_DIFFUSE_MAP"
194+
-v "VSG_INSTANCE_TRANSLATION VSG_INSTANCE_SCALE VSG_INSTANCE_ROTATION"
195+
-v "VSG_INSTANCE_TRANSLATION VSG_INSTANCE_SCALE VSG_INSTANCE_ROTATION VSG_DIFFUSE_MAP"
188196
)
189197
190198
set(FLAT_DEFINES
@@ -194,6 +202,8 @@ set(FLAT_DEFINES
194202
-v "VSG_BILLBOARD VSG_DIFFUSE_MAP"
195203
-v "VSG_DISPLACEMENT_MAP VSG_DIFFUSE_MAP"
196204
-v "VSG_DISPLACEMENT_MAP VSG_DETAIL_MAP VSG_DIFFUSE_MAP"
205+
-v "VSG_INSTANCE_TRANSLATION VSG_INSTANCE_SCALE VSG_INSTANCE_ROTATION"
206+
-v "VSG_INSTANCE_TRANSLATION VSG_INSTANCE_SCALE VSG_INSTANCE_ROTATION VSG_DIFFUSE_MAP"
197207
)
198208
199209
set(TEXT_DEFINES

include/vsg/all.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
6767
#include <vsg/nodes/DepthSorted.h>
6868
#include <vsg/nodes/Geometry.h>
6969
#include <vsg/nodes/Group.h>
70+
#include <vsg/nodes/InstanceDraw.h>
71+
#include <vsg/nodes/InstanceDrawIndexed.h>
72+
#include <vsg/nodes/InstanceNode.h>
7073
#include <vsg/nodes/InstrumentationNode.h>
7174
#include <vsg/nodes/LOD.h>
7275
#include <vsg/nodes/Layer.h>
@@ -267,6 +270,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
267270
#include <vsg/io/DatabasePager.h>
268271
#include <vsg/io/FileSystem.h>
269272
#include <vsg/io/Input.h>
273+
#include <vsg/io/JSONParser.h>
270274
#include <vsg/io/Logger.h>
271275
#include <vsg/io/ObjectFactory.h>
272276
#include <vsg/io/Options.h>

include/vsg/app/RecordTraversal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ namespace vsg
6363
class CommandGraph;
6464
class RecordedCommandBuffers;
6565
class Instrumentation;
66+
class InstanceNode;
67+
class InstanceDraw;
68+
class InstanceDrawIndexed;
6669

6770
VSG_type_name(vsg::RecordTraversal);
6871

@@ -142,6 +145,11 @@ namespace vsg
142145
// Animation nodes
143146
void apply(const Joint& joint);
144147

148+
// instance nodes
149+
void apply(const InstanceNode& instanceNode);
150+
void apply(const InstanceDraw& instanceDraw);
151+
void apply(const InstanceDrawIndexed& instanceDrawIndexed);
152+
145153
// Vulkan nodes
146154
void apply(const StateGroup& object);
147155

include/vsg/core/Array.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ namespace vsg
118118
template<typename... Args>
119119
static ref_ptr<Array> create_if(bool flag, Args&&... args)
120120
{
121-
if (flag) return ref_ptr<Array>(new Array(std::forward<Args>(args)...));
122-
else return {};
121+
if (flag)
122+
return ref_ptr<Array>(new Array(std::forward<Args>(args)...));
123+
else
124+
return {};
123125
}
124126

125127
static ref_ptr<Array> create(std::initializer_list<value_type> l)

include/vsg/core/Array2D.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,13 @@ namespace vsg
103103
return ref_ptr<Array2D>(new Array2D(std::forward<Args>(args)...));
104104
}
105105

106-
107106
template<typename... Args>
108107
static ref_ptr<Array2D> create_if(bool flag, Args&&... args)
109108
{
110-
if (flag) return ref_ptr<Array2D>(new Array2D(std::forward<Args>(args)...));
111-
else return {};
109+
if (flag)
110+
return ref_ptr<Array2D>(new Array2D(std::forward<Args>(args)...));
111+
else
112+
return {};
112113
}
113114

114115
ref_ptr<Object> clone(const CopyOp& copyop = {}) const override

include/vsg/core/Array3D.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ namespace vsg
111111
template<typename... Args>
112112
static ref_ptr<Array3D> create_if(bool flag, Args&&... args)
113113
{
114-
if (flag) return ref_ptr<Array3D>(new Array3D(std::forward<Args>(args)...));
115-
else return {};
114+
if (flag)
115+
return ref_ptr<Array3D>(new Array3D(std::forward<Args>(args)...));
116+
else
117+
return {};
116118
}
117119

118120
ref_ptr<Object> clone(const CopyOp& copyop = {}) const override

include/vsg/core/ConstVisitor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ namespace vsg
5151
class SpotLight;
5252
class InstrumentationNode;
5353
class RegionOfInterest;
54+
class InstanceNode;
55+
class InstanceDraw;
56+
class InstanceDrawIndexed;
5457

5558
// forward declare text classes
5659
class Text;
@@ -354,6 +357,9 @@ namespace vsg
354357
virtual void apply(const SpotLight&);
355358
virtual void apply(const InstrumentationNode&);
356359
virtual void apply(const RegionOfInterest&);
360+
virtual void apply(const InstanceNode&);
361+
virtual void apply(const InstanceDraw&);
362+
virtual void apply(const InstanceDrawIndexed&);
357363

358364
// text
359365
virtual void apply(const Text&);

include/vsg/core/IntrusiveAllocator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
1515
#include <vsg/core/Allocator.h>
1616

1717
#include <list>
18-
#include <vector>
1918
#include <string>
19+
#include <vector>
2020

2121
namespace vsg
2222
{

include/vsg/core/Value.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,10 @@ namespace vsg
6161
template<typename... Args>
6262
static ref_ptr<Value> create_if(bool flag, Args&&... args)
6363
{
64-
if (flag) return ref_ptr<Value>(new Value(std::forward<Args>(args)...));
65-
else return {};
64+
if (flag)
65+
return ref_ptr<Value>(new Value(std::forward<Args>(args)...));
66+
else
67+
return {};
6668
}
6769

6870
ref_ptr<Object> clone(const CopyOp& copyop = {}) const override

include/vsg/core/Visitor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ namespace vsg
5151
class SpotLight;
5252
class InstrumentationNode;
5353
class RegionOfInterest;
54+
class InstanceNode;
55+
class InstanceDraw;
56+
class InstanceDrawIndexed;
5457

5558
// forward declare text classes
5659
class Text;
@@ -354,6 +357,9 @@ namespace vsg
354357
virtual void apply(SpotLight&);
355358
virtual void apply(InstrumentationNode&);
356359
virtual void apply(RegionOfInterest&);
360+
virtual void apply(InstanceNode&);
361+
virtual void apply(InstanceDraw&);
362+
virtual void apply(InstanceDrawIndexed&);
357363

358364
// text
359365
virtual void apply(Text&);

include/vsg/io/Options.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ namespace vsg
103103
/// mechanism for propagating dynamic objects classification up parental chain so that cloning is done on all dynamic objects to avoid sharing of dynamic parts.
104104
ref_ptr<PropagateDynamicObjects> propagateDynamicObjects;
105105

106+
enum InstanceNodeHint
107+
{
108+
INSTANCE_NONE = 0,
109+
INSTANCE_TRANSLATIONS = 1 << 0,
110+
INSTANCE_ROTATIONS = 1 << 1,
111+
INSTANCE_SCALES = 1 << 2,
112+
INSTANCE_COLORS = 1 << 3
113+
};
114+
115+
int instanceNodeHint = INSTANCE_NONE;
116+
106117
public:
107118
ref_ptr<Object> clone(const CopyOp& copyop = {}) const override { return Options::create(*this, copyop); }
108119
int compare(const Object& rhs) const override;

include/vsg/nodes/InstanceDraw.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
/* <editor-fold desc="MIT License">
4+
5+
Copyright(c) 2025 Robert Osfield
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8+
9+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12+
13+
</editor-fold> */
14+
15+
#include <vsg/commands/Command.h>
16+
#include <vsg/nodes/Node.h>
17+
#include <vsg/state/BufferInfo.h>
18+
19+
namespace vsg
20+
{
21+
22+
/** InstanceDraw provides a lightweight way of binding vertex arrays, indices and then issuing a vkCmdDraw command.
23+
* Higher performance equivalent to use of individual vsg::BindVertexBuffers, vsg::BindIndexBuffer and vsg::Draw commands.*/
24+
class VSG_DECLSPEC InstanceDraw : public Inherit<Command, InstanceDraw>
25+
{
26+
public:
27+
InstanceDraw();
28+
InstanceDraw(const InstanceDraw& rhs, const CopyOp& copyop = {});
29+
30+
// vkCmdDraw settings
31+
// vkCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
32+
uint32_t vertexCount = 0;
33+
uint32_t firstVertex = 0;
34+
35+
uint32_t firstBinding = 0;
36+
BufferInfoList arrays;
37+
38+
void assignArrays(const DataList& in_arrays);
39+
40+
public:
41+
ref_ptr<Object> clone(const CopyOp& copyop = {}) const override { return InstanceDraw::create(*this, copyop); }
42+
int compare(const Object& rhs) const override;
43+
44+
void read(Input& input) override;
45+
void write(Output& output) const override;
46+
47+
void compile(Context& context) override;
48+
void record(CommandBuffer& commandBuffer) const override;
49+
50+
protected:
51+
virtual ~InstanceDraw();
52+
};
53+
VSG_type_name(vsg::InstanceDraw)
54+
55+
} // namespace vsg
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#pragma once
2+
3+
/* <editor-fold desc="MIT License">
4+
5+
Copyright(c) 2025 Robert Osfield
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8+
9+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12+
13+
</editor-fold> */
14+
15+
#include <vsg/commands/Command.h>
16+
#include <vsg/nodes/Node.h>
17+
#include <vsg/state/BufferInfo.h>
18+
19+
namespace vsg
20+
{
21+
22+
/** InstanceDrawIndexed provides a lightweight way of binding vertex arrays, indices and then issuing a vkCmdDrawIndexed command.
23+
* Higher performance equivalent to use of individual vsg::BindVertexBuffers, vsg::BindIndexBuffer and vsg::DrawIndexed commands.*/
24+
class VSG_DECLSPEC InstanceDrawIndexed : public Inherit<Command, InstanceDrawIndexed>
25+
{
26+
public:
27+
InstanceDrawIndexed();
28+
InstanceDrawIndexed(const InstanceDrawIndexed& rhs, const CopyOp& copyop = {});
29+
30+
// vkCmdDrawIndexed settings
31+
// vkCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
32+
uint32_t indexCount = 0;
33+
uint32_t firstIndex = 0;
34+
uint32_t vertexOffset = 0;
35+
36+
uint32_t firstBinding = 0;
37+
BufferInfoList arrays;
38+
ref_ptr<BufferInfo> indices;
39+
40+
void assignArrays(const DataList& in_arrays);
41+
void assignIndices(ref_ptr<Data> in_indices);
42+
43+
public:
44+
ref_ptr<Object> clone(const CopyOp& copyop = {}) const override { return InstanceDrawIndexed::create(*this, copyop); }
45+
int compare(const Object& rhs) const override;
46+
47+
void read(Input& input) override;
48+
void write(Output& output) const override;
49+
50+
void compile(Context& context) override;
51+
void record(CommandBuffer& commandBuffer) const override;
52+
53+
protected:
54+
virtual ~InstanceDrawIndexed();
55+
56+
VkIndexType indexType = VK_INDEX_TYPE_UINT16;
57+
};
58+
VSG_type_name(vsg::InstanceDrawIndexed)
59+
60+
} // namespace vsg

0 commit comments

Comments
 (0)