-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathpolygon_mesh.h
220 lines (190 loc) Β· 8.68 KB
/
polygon_mesh.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// Copyright (C) 2020-2024 Sami VΓ€isΓ€nen
// Copyright (C) 2020-2024 Ensisoft http://www.ensisoft.com
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
#include "config.h"
#include "warnpush.h"
#include "warnpop.h"
#include <string>
#include <vector>
#include <optional>
#include <unordered_map>
#include <memory>
#include <cstddef>
#include "base/utility.h"
#include "graphics/drawable.h"
#include "graphics/vertex.h"
namespace gfx
{
// Combines multiple primitive draw commands into a single
// drawable shape.
class PolygonMeshClass : public DrawableClass
{
public:
enum class MeshType {
Simple2D,
Simple3D,
Model3D
};
explicit PolygonMeshClass(std::string id = base::RandomString(10),
std::string name = "") noexcept
: mId(std::move(id))
, mName(std::move(name))
{}
// Return whether the polygon's data is considered to be
// static or not. Static content is not assumed to change
// often and will map the polygon to a geometry object
// based on the polygon's data. Thus, each polygon with
// different data will have different geometry object.
// However, If the polygon is updated frequently this would
// then lead to the proliferation of excessive geometry objects.
// In this case static can be set to false and the polygon
// will map to a (single) dynamic geometry object more optimized
// for draw/discard type of use.
inline bool IsStatic() const noexcept
{ return mStatic; }
// Set the polygon static or not. See comments in IsStatic.
inline void SetStatic(bool on_off) noexcept
{ mStatic = on_off; }
inline void SetDynamic(bool on_off) noexcept
{ mStatic = !on_off; }
inline void SetContentHash(size_t hash) noexcept
{ mContentHash = hash; }
inline size_t GetContentHash() const noexcept
{ return mContentHash; }
inline bool HasInlineData() const noexcept
{ return mData.has_value(); }
inline bool HasContentUri() const noexcept
{ return !mContentUri.empty(); }
inline void ResetContentUri() noexcept
{ mContentUri.clear(); }
inline void SetContentUri(std::string uri) noexcept
{ mContentUri = std::move(uri); }
inline void SetMeshType(MeshType type) noexcept
{ mMesh = type; }
inline std::string GetContentUri() const
{ return mContentUri; }
inline std::string GetShaderSrc() const
{ return mShaderSrc; }
inline MeshType GetMeshType() const noexcept
{ return mMesh; }
void SetShaderSrc(std::string src) noexcept
{ mShaderSrc = std::move(src); }
bool HasShaderSrc() const noexcept
{ return !mShaderSrc.empty(); }
void SetIndexBuffer(IndexBuffer&& buffer) noexcept;
void SetIndexBuffer(const IndexBuffer& buffer);
void SetVertexLayout(VertexLayout layout) noexcept;
void SetVertexBuffer(VertexBuffer&& buffer) noexcept;
void SetVertexBuffer(std::vector<uint8_t>&& buffer) noexcept;
void SetVertexBuffer(const VertexBuffer& buffer);
void SetVertexBuffer(const std::vector<uint8_t>& buffer);
void SetCommandBuffer(CommandBuffer&& buffer) noexcept;
void SetCommandBuffer(std::vector<Geometry::DrawCommand>&& buffer) noexcept;
void SetCommandBuffer(const CommandBuffer& buffer);
void SetCommandBuffer(const std::vector<Geometry::DrawCommand>& buffer);
const VertexLayout* GetVertexLayout() const noexcept;
const void* GetVertexBufferPtr() const noexcept;
size_t GetVertexBufferSize() const noexcept;
size_t GetNumDrawCmds() const noexcept;
const Geometry::DrawCommand* GetDrawCmd(size_t index) const noexcept;
std::string GetGeometryId(const Environment& env) const;
std::string GetShaderId(const Environment& env) const;
std::string GetShaderName(const Environment& env) const;
ShaderSource GetShader(const Environment& env, const Device& device) const;
bool Construct(const Environment& env, Geometry::CreateArgs& create) const;
void SetSubMeshDrawCmd(const std::string& key, const DrawCmd& cmd);
const DrawCmd* GetSubMeshDrawCmd(const std::string& key) const noexcept;
Type GetType() const override
{ return Type::Polygon; }
std::string GetId() const override
{ return mId; }
std::string GetName() const override
{ return mName; }
void SetName(const std::string& name) override
{ mName = name; }
std::size_t GetHash() const override;
std::unique_ptr<DrawableClass> Clone() const override;
std::unique_ptr<DrawableClass> Copy() const override;
void IntoJson(data::Writer& data) const override;
bool FromJson(const data::Reader& data) override;
private:
std::string mId;
std::string mName;
std::size_t mContentHash = 0;
// Content URI for a larger mesh (see InlineData)
std::string mContentUri;
// customized part of the vertex shader vertex transform.
std::string mShaderSrc;
// this is to support the simple 2D geometry with
// only a few vertices. Could be migrated to use
// a separate file but this is simply just so much
// simpler for the time being even though it wastes
// a bit of space since the data is kep around all
// the time.
struct InlineData {
std::vector<uint8_t> vertices;
std::vector<uint8_t> indices;
std::vector<Geometry::DrawCommand> cmds;
VertexLayout layout;
Geometry::IndexType index_type = Geometry::IndexType::Index16;
};
std::optional<InlineData> mData;
MeshType mMesh = MeshType::Simple2D;
std::unordered_map<std::string, DrawCmd> mSubMeshes;
bool mStatic = true;
};
class PolygonMeshInstance : public Drawable
{
public:
using MeshType = PolygonMeshClass::MeshType;
explicit PolygonMeshInstance(std::shared_ptr<const PolygonMeshClass> klass,
std::string sub_mesh_key = "") noexcept;
explicit PolygonMeshInstance(const PolygonMeshClass& klass, std::string sub_mesh_key = "");
inline MeshType GetMeshType() const noexcept
{ return mClass->GetMeshType(); }
inline std::string GetSubMeshKey() const
{ return mSubMeshKey; }
inline void SetSubMeshKey(std::string key) noexcept
{ mSubMeshKey = std::move(key); }
inline void SetTime(double time) noexcept
{ mTime = time; }
inline void SetRandomValue(float value) noexcept
{ mRandom = value; }
void ApplyDynamicState(const Environment& env, ProgramState& program, RasterState& state) const override;
ShaderSource GetShader(const Environment& env, const Device& device) const override;
std::string GetShaderId(const Environment& env) const override;
std::string GetShaderName(const Environment& env) const override;
std::string GetGeometryId(const Environment& env) const override;
bool Construct(const Environment& env, Geometry::CreateArgs& create) const override;
bool Construct(const Environment& env, const InstancedDraw& draw, gfx::InstancedDraw::CreateArgs& args) const override;
void Update(const Environment& env, float dt) override;
DrawCmd GetDrawCmd() const override;
DrawPrimitive GetDrawPrimitive() const override
{ return DrawPrimitive::Triangles; }
Type GetType() const override
{ return Type::Polygon; }
Usage GetGeometryUsage() const override;
size_t GetGeometryHash() const override;
const DrawableClass* GetClass() const override
{ return mClass.get(); }
private:
std::shared_ptr<const PolygonMeshClass> mClass;
std::string mSubMeshKey;
double mTime = 0.0;
float mRandom = 0.0f;
mutable bool mError = false;
};
} // namespace