vsg: include/vsg/utils/PrimitiveFunctor.h Source File

vsg 1.1.9 VulkanSceneGraph library |

Loading...
Searching...
No Matches
PrimitiveFunctor.h
1#pragma once
2
3/* <editor-fold desc="MIT License">
4
5Copyright(c) 2024 Robert Osfield
6
7Permission 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
9The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
11THE 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/io/Logger.h>
16#include <vsg/vk/vulkan.h>
17
18namespace vsg
19{
20
22 template<class T>
23 struct PrimitiveFunctor : public T
24 {
25 template<typename... Args>
26 PrimitiveFunctor(Args&&... args) :
27 T(std::forward<Args>(args)...) {}
28
29 void draw(VkPrimitiveTopology topology, uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount)
30 {
31 uint32_t lastIndex = instanceCount > 1 ? (firstInstance + instanceCount) : firstInstance + 1;
32 for (uint32_t inst = firstInstance; inst < lastIndex; ++inst)
33 {
34 if (!T::instance(inst)) continue;
35
36 switch (topology)
37 {
38 case (VK_PRIMITIVE_TOPOLOGY_POINT_LIST): {
39 uint32_t endVertex = firstVertex + vertexCount;
40 for (uint32_t i = firstVertex; i < endVertex; ++i)
41 {
42 T::point(i);
43 }
44 break;
45 }
46 case (VK_PRIMITIVE_TOPOLOGY_LINE_LIST): {
47 // primitive restart not yet supported.
48 uint32_t primitiveCount = vertexCount / 2;
49 uint32_t endVertex = firstVertex + primitiveCount * 2;
50 for (uint32_t i = firstVertex; i < endVertex; i += 2)
51 {
52 T::line(i, i + 1);
53 }
54 break;
55 }
56 case (VK_PRIMITIVE_TOPOLOGY_LINE_STRIP): {
57 uint32_t endVertex = firstVertex + ((vertexCount >= 2) ? (vertexCount - 1) : 0);
58 for (uint32_t i = firstVertex; i < endVertex; ++i)
59 {
60 T::line(i, i + 1);
61 }
62 break;
63 }
64 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST): {
65 uint32_t primtiveCount = vertexCount / 3;
66 uint32_t endVertex = firstVertex + primtiveCount * 3;
67 for (uint32_t i = firstVertex; i < endVertex; i += 3)
68 {
69 T::triangle(i, i + 1, i + 2);
70 }
71 break;
72 }
73 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP): {
74 // primitive restart not yet supported.
75 uint32_t endVertex = firstVertex + ((vertexCount >= 3) ? (vertexCount - 2) : 0);
76 for (uint32_t i = firstVertex; i < endVertex; ++i)
77 {
78 T::triangle(i, i + 1, i + 2); // do we need to reverse the i+1 and i+2 order on odd triangles?
79 }
80 break;
81 }
82 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN): {
83 // primitive restart not yet supported.
84 uint32_t endVertex = firstVertex + ((vertexCount >= 3) ? (vertexCount - 2) : 0);
85 for (uint32_t i = firstVertex + 1; i < endVertex; ++i)
86 {
87 T::triangle(firstVertex, i + 1, i + 2);
88 }
89 break;
90 }
91 case (VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY):
92 case (VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY):
93 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY):
94 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY):
95 case (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST):
96 default:
97 warn("PrimitiveFunctor::draw(topology = ", topology, ", ...) not implemented.");
98 break;
99 }
100 }
101 }
102
103 template<class IndexArray>
104 void drawIndexed(VkPrimitiveTopology topology, IndexArray indices, uint32_t firstIndex, uint32_t indexCount, uint32_t firstInstance, uint32_t instanceCount)
105 {
106 uint32_t lastIndex = instanceCount > 1 ? (firstInstance + instanceCount) : firstInstance + 1;
107 for (uint32_t inst = firstInstance; inst < lastIndex; ++inst)
108 {
109 if (!T::instance(inst)) continue;
110
111 switch (topology)
112 {
113 case (VK_PRIMITIVE_TOPOLOGY_POINT_LIST): {
114 uint32_t endIndex = firstIndex + indexCount;
115 for (uint32_t i = firstIndex; i < endIndex; ++i)
116 {
117 T::point(indices->at(i));
118 }
119 break;
120 }
121 case (VK_PRIMITIVE_TOPOLOGY_LINE_LIST): {
122 uint32_t primtiveCount = indexCount / 2;
123 uint32_t endIndex = firstIndex + primtiveCount * 2;
124 for (uint32_t i = firstIndex; i < endIndex; i += 2)
125 {
126 T::line(indices->at(i), indices->at(i + 1));
127 }
128 break;
129 }
130 case (VK_PRIMITIVE_TOPOLOGY_LINE_STRIP): {
131 // primitive restart not yet supported.
132 uint32_t endIndex = firstIndex + ((indexCount >= 2) ? (indexCount - 1) : 0);
133 for (uint32_t i = firstIndex; i < endIndex; ++i)
134 {
135 T::line(indices->at(i), indices->at(i + 1));
136 }
137 break;
138 }
139 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST): {
140 uint32_t primtiveCount = indexCount / 3;
141 uint32_t endIndex = firstIndex + primtiveCount * 3;
142 for (uint32_t i = firstIndex; i < endIndex; i += 3)
143 {
144 T::triangle(indices->at(i), indices->at(i + 1), indices->at(i + 2));
145 }
146 break;
147 }
148 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP): {
149 // primitive restart not yet supported.
150 uint32_t endIndex = firstIndex + ((indexCount >= 3) ? (indexCount - 2) : 0);
151 for (uint32_t i = firstIndex; i < endIndex; ++i)
152 {
153 T::triangle(indices->at(i), indices->at(i + 1), indices->at(i + 2)); // do we need to reverse the i+1 and i+2 order on odd triangles?
154 }
155 break;
156 }
157 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN): {
158 // primitive restart not yet supported.
159 uint32_t endIndex = firstIndex + ((indexCount >= 3) ? (indexCount - 2) : 0);
160 for (uint32_t i = firstIndex + 1; i < endIndex; ++i)
161 {
162 T::triangle(indices->at(firstIndex), indices->at(i + 1), indices->at(i + 2));
163 }
164 break;
165 }
166 case (VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY):
167 case (VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY):
168 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY):
169 case (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY):
170 case (VK_PRIMITIVE_TOPOLOGY_PATCH_LIST):
171 default:
172 warn("PrimitiveFunctor::drawIndexed(topology = ", topology, ", ...) not implemented.");
173 break;
174 }
175 }
176 }
177 };
178
179} // namespace vsg