1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Resources/BsResource.h"
7#include "Math/BsBounds.h"
8#include "RenderAPI/BsSubMesh.h"
9
10namespace bs
11{
12 /** @addtogroup Resources
13 * @{
14 */
15
16 /**
17 * Planned usage for the mesh. These options usually affect performance and you should specify static if you don't plan
18 * on modifying the mesh often, otherwise specify dynamic.
19 */
20 enum BS_SCRIPT_EXPORT(m:Rendering) MeshUsage
21 {
22 /** Specify for a mesh that is not often updated from the CPU. */
23 MU_STATIC BS_SCRIPT_EXPORT(n:Static) = 1 << 0,
24
25 /** Specify for a mesh that is often updated from the CPU. */
26 MU_DYNAMIC BS_SCRIPT_EXPORT(n:Dynamic) = 1 << 1,
27 /**
28 * All mesh data will also be cached in CPU memory, making it available for fast read access from the CPU. Can be
29 * combined with other usage flags.
30 */
31 MU_CPUCACHED BS_SCRIPT_EXPORT(n:CPUCached) = 0x1000,
32 };
33
34 /** Properties of a Mesh. Shared between sim and core thread versions of a Mesh. */
35 class BS_CORE_EXPORT MeshProperties
36 {
37 public:
38 MeshProperties();
39 MeshProperties(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp);
40 MeshProperties(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes);
41
42 /**
43 * Retrieves a sub-mesh containing data used for rendering a certain portion of this mesh. If no sub-meshes are
44 * specified manually a special sub-mesh containing all indices is returned.
45 */
46 const SubMesh& getSubMesh(UINT32 subMeshIdx = 0) const;
47
48 /** Retrieves a total number of sub-meshes in this mesh. */
49 UINT32 getNumSubMeshes() const;
50
51 /** Returns maximum number of vertices the mesh may store. */
52 UINT32 getNumVertices() const { return mNumVertices; }
53
54 /** Returns maximum number of indices the mesh may store. */
55 UINT32 getNumIndices() const { return mNumIndices; }
56
57 /** Returns bounds of the geometry contained in the vertex buffers for all sub-meshes. */
58 const Bounds& getBounds() const { return mBounds; }
59
60 protected:
61 friend class MeshBase;
62 friend class ct::MeshBase;
63 friend class Mesh;
64 friend class ct::Mesh;
65 friend class TransientMesh;
66 friend class ct::TransientMesh;
67 friend class MeshBaseRTTI;
68
69 Vector<SubMesh> mSubMeshes;
70 UINT32 mNumVertices;
71 UINT32 mNumIndices;
72 Bounds mBounds;
73 };
74
75 /** @} */
76
77 /** @addtogroup Implementation
78 * @{
79 */
80
81 /**
82 * Base class all mesh implementations derive from. Meshes hold geometry information, normally in the form of one or
83 * several index or vertex buffers. Different mesh implementations might choose to manage those buffers differently.
84 *
85 * @note Sim thread.
86 */
87 class BS_CORE_EXPORT MeshBase : public Resource
88 {
89 public:
90 /**
91 * Constructs a new mesh with no sub-meshes.
92 *
93 * @param[in] numVertices Number of vertices in the mesh.
94 * @param[in] numIndices Number of indices in the mesh.
95 * @param[in] drawOp Determines how should the provided indices be interpreted by the pipeline. Default
96 * option is triangles, where three indices represent a single triangle.
97 */
98 MeshBase(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
99
100 /**
101 * Constructs a new mesh with one or multiple sub-meshes. (When using just one sub-mesh it is equivalent to using
102 * the other overload).
103 *
104 * @param[in] numVertices Number of vertices in the mesh.
105 * @param[in] numIndices Number of indices in the mesh.
106 * @param[in] subMeshes Defines how are indices separated into sub-meshes, and how are those sub-meshes
107 * rendered.
108 */
109 MeshBase(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes);
110
111 virtual ~MeshBase();
112
113 /** Returns properties that contain information about the mesh. */
114 const MeshProperties& getProperties() const { return mProperties; }
115
116 /** Retrieves a core implementation of a mesh usable only from the core thread. */
117 SPtr<ct::MeshBase> getCore() const;
118
119 protected:
120 /** @copydoc CoreObject::syncToCore */
121 CoreSyncData syncToCore(FrameAlloc* allocator) override;
122
123 MeshProperties mProperties;
124
125 /************************************************************************/
126 /* SERIALIZATION */
127 /************************************************************************/
128 private:
129 MeshBase() { } // Serialization only
130
131 public:
132 friend class MeshBaseRTTI;
133 static RTTITypeBase* getRTTIStatic();
134 RTTITypeBase* getRTTI() const override;
135 };
136
137 namespace ct
138 {
139 /**
140 * Core version of a class used as a basis for all implemenations of meshes.
141 *
142 * @see bs::MeshBase
143 *
144 * @note Core thread.
145 */
146 class BS_CORE_EXPORT MeshBase : public CoreObject
147 {
148 public:
149 MeshBase(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes);
150 virtual ~MeshBase() { }
151
152 /** Get vertex data used for rendering. */
153 virtual SPtr<VertexData> getVertexData() const = 0;
154
155 /** Get index data used for rendering. */
156 virtual SPtr<IndexBuffer> getIndexBuffer() const = 0;
157
158 /**
159 * Returns an offset into the vertex buffers that is returned by getVertexData() that signifies where this meshes
160 * vertices begin.
161 *
162 * @note Used when multiple meshes share the same buffers.
163 */
164 virtual UINT32 getVertexOffset() const { return 0; }
165
166 /**
167 * Returns an offset into the index buffer that is returned by getIndexData() that signifies where this meshes
168 * indices begin.
169 *
170 * @note Used when multiple meshes share the same buffers.
171 */
172 virtual UINT32 getIndexOffset() const { return 0; }
173
174 /** Returns a structure that describes how are the vertices stored in the mesh's vertex buffer. */
175 virtual SPtr<VertexDataDesc> getVertexDesc() const = 0;
176
177 /**
178 * Called whenever this mesh starts being used on the GPU.
179 *
180 * @note Needs to be called after all commands referencing this mesh have been sent to the GPU.
181 */
182 virtual void _notifyUsedOnGPU() { }
183
184 /** Returns properties that contain information about the mesh. */
185 const MeshProperties& getProperties() const { return mProperties; }
186
187 protected:
188 /** @copydoc CoreObject::syncToCore */
189 void syncToCore(const CoreSyncData& data) override;
190
191 MeshProperties mProperties;
192 };
193 }
194
195 /** @} */
196}