Rendering Engine 0.2.9
Modular Graphics Rendering Engine | v0.2.9
mesh_data_gpu.cpp
Go to the documentation of this file.
1#include "mesh_data_gpu.hpp"
2#include "model.hpp"
3#include "i_renderer.hpp"
5
6namespace rendering_engine
7{
9 :
10 mRenderer(renderer),
11 mGpuHandle(nullptr),
12 mSizeOfVerticesBytes(0),
13 mSizeOfIndicesBytes(0),
14 mMeshType(MeshType::None)
15{
16}
17 MeshDataGpu::MeshDataGpu(const std::string& filename, IRenderer* renderer)
18 :
19 mRenderer(renderer),
20 mGpuHandle(nullptr),
21 mSizeOfVerticesBytes(0),
22 mSizeOfIndicesBytes(0),
23 mMeshType(MeshType::None)
24{
25 LoadModel(filename);
26}
27
28MeshDataGpu::MeshDataGpu(std::vector<uint8_t> const& fileBytes, IRenderer* renderer)
29 :
30 mRenderer(renderer),
31 mGpuHandle(nullptr),
32 mSizeOfVerticesBytes(0),
33 mSizeOfIndicesBytes(0),
34 mMeshType(MeshType::None)
35{
36 LoadModel(fileBytes);
37}
38
40{
42}
43
45{
46 if (!mRenderer)
47 {
48 return;
49 }
50 if (mGpuHandle)
51 {
52 if (mGpuHandle->IsOnGPU())
53 {
55 }
56 }
57
58 mGpuHandle = std::unique_ptr<IMeshRenderResources>(mRenderer->ProvideMeshRenderResources());
59
60 switch (mMeshType)
61 {
62 case MeshType::None:
63 {
64 break;
65 }
67 {
68 mGpuHandle->CreateVertexBuffer(ComposeVertex2DBuffer());
69 mGpuHandle->CreateIndexBuffer(mIndices);
70 break;
71 }
73 {
74 mGpuHandle->CreateVertexBuffer(ComposeUnlitBuffer());
75 mGpuHandle->CreateIndexBuffer(mIndices);
76 break;
77 }
79 {
80 mGpuHandle->CreateVertexBuffer(ComposeLitBuffer());
81 mGpuHandle->CreateIndexBuffer(mIndices);
82 break;
83 }
84 }
85}
86
88{
89 if (!mRenderer)
90 {
91 return;
92 }
93 if (!mGpuHandle)
94 {
95 return;
96 }
97
98 mGpuHandle->Shutdown();
99 mGpuHandle.release();
100 mGpuHandle = nullptr;
101}
102
104{
105 bool result = false;
106
107 if (mGpuHandle)
108 {
109 result = mGpuHandle->IsOnGPU();
110 }
111
112 return result;
113}
114
115void MeshDataGpu::LoadModel(std::string path)
116{
117 std::unique_ptr<Model> model = std::make_unique<Model>(path, true);
118
119 if (model)
120 {
121 if (model->HasMeshes())
122 {
123 mPositions = model->Meshes()[0]->Vertices();
124
125 if (model->Meshes()[0]->VertexColors().size() >= 1)
126 mColor = model->Meshes()[0]->VertexColors()[0];
127
128 mNormals = model->Meshes()[0]->Normals();
129 for (const auto& texCoord : model->Meshes()[0]->TextureCoordinates()[0])
130 {
131 mTexCoords.push_back(glm::vec2(texCoord.x, texCoord.y));
132 }
133 mTangents = model->Meshes()[0]->Tangents();
134 mIndices = model->Meshes()[0]->Indices();
135 }
136 }
137
139
140 mMeshType = MeshType::Surface;
141}
142
143void MeshDataGpu::LoadModel(std::vector<uint8_t> const& fileBytes)
144{
145 std::unique_ptr<Model> model = std::make_unique<Model>(fileBytes, true);
146
147 if (model)
148 {
149 if (model->HasMeshes())
150 {
151 mPositions = model->Meshes()[0]->Vertices();
152
153 if (model->Meshes()[0]->VertexColors().size() >= 1)
154 mColor = model->Meshes()[0]->VertexColors()[0];
155
156 mNormals = model->Meshes()[0]->Normals();
157 for (const auto& texCoord : model->Meshes()[0]->TextureCoordinates()[0])
158 {
159 mTexCoords.push_back(glm::vec2(texCoord.x, texCoord.y));
160 }
161 mTangents = model->Meshes()[0]->Tangents();
162 mIndices = model->Meshes()[0]->Indices();
163 }
164 }
165
167
168 mMeshType = MeshType::Surface;
169}
170
172{
173 mPositions2D = { {-0.5f, -0.5f}, { 0.5f, -0.5f}, { 0.5f, 0.5f}, {-0.5f, 0.5f} };
174
175 // TOP-LEFT origin UVs
176 mTexCoords = {
177 {0.0f, 0.0f}, // bottom-left
178 {1.0f, 0.0f}, // bottom-right
179 {1.0f, 1.0f}, // top-right
180 {0.0f, 1.0f} // top-left
181 };
182
183 mColor = { {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f} };
184
185 mIndices = {
186 0, 1, 2, // first triangle
187 2, 3, 0 // second triangle
188 };
189
191
192 mMeshType = MeshType::Sprite2D;
193}
194
195void MeshDataGpu::LoadCustomMesh(std::vector<glm::vec2> positions2D, std::vector<glm::vec2> texCoords, std::vector<glm::vec4> colors, std::vector<std::uint32_t> indices)
196{
197 mPositions2D = positions2D;
198 mTexCoords = texCoords;
199 mColor = colors;
200 mIndices = indices;
201
203
204 mMeshType = MeshType::Sprite2D;
205}
206
208{
209 size_t result = 0;
210
211 if (mGpuHandle)
212 {
213 result = mGpuHandle->GetVertexBufferSize();
214 }
215
216 return result;
217}
218
220{
221 size_t result = 0;
222
223 if (mGpuHandle)
224 {
225 result = mGpuHandle->GetIndexBufferSize();
226 }
227
228 return result;
229}
230
232{
233 return mSizeOfVerticesBytes;
234}
235
237{
238 return mSizeOfIndicesBytes;
239}
240
242{
243 if (!IsOnGPU())
244 {
245 UploadToGPU();
246 }
247 return mGpuHandle.get();
248}
249
251{
252 size_t sizeOfVerticesBytes = 0;
253 size_t sizeOfIndicesBytes = 0;
254
255 sizeOfVerticesBytes += (mPositions2D.size() * sizeof(glm::vec2));
256 sizeOfVerticesBytes += (mPositions.size() * sizeof(glm::vec3));
257 sizeOfVerticesBytes += (mColor.size() * sizeof(glm::vec4));
258 sizeOfVerticesBytes += (mNormals.size() * sizeof(glm::vec3));
259 sizeOfVerticesBytes += (mTexCoords.size() * sizeof(glm::vec2));
260 sizeOfVerticesBytes += (mTangents.size() * sizeof(glm::vec3));
261
262 sizeOfIndicesBytes += (mIndices.size() * sizeof(uint32_t));
263
264 mSizeOfVerticesBytes = sizeOfVerticesBytes;
265 mSizeOfIndicesBytes = sizeOfIndicesBytes;
266}
267
269{
270 std::vector<Vertex2D> result;
271
272 unsigned int index = 0;
273 for (const auto& position : mPositions2D)
274 {
275 Vertex2D vert;
276 vert.position = position;
277 vert.color = mColor.empty() ? glm::vec4(1.0f) : mColor[index];
278 vert.textureCoordinates = mTexCoords.empty() ? glm::vec2(0.0f) : mTexCoords[index];
279
280 result.push_back(vert);
281 ++index;
282 }
283
284 return result;
285}
286
287std::vector<VertexPositionColorTexture> MeshDataGpu::ComposeUnlitBuffer()
288{
289 std::vector<VertexPositionColorTexture> result;
290
291 unsigned int index = 0;
292 for (const auto& position : mPositions)
293 {
295 vert.position = position;
296 vert.color = mColor.empty() ? glm::vec4(1) : mColor[index];
297 vert.textureCoordinates = mTexCoords.empty() ? glm::vec2(0.0f) : mTexCoords[index];
298
299 result.push_back(vert);
300 ++index;
301 }
302
303 return result;
304}
305
306std::vector<VertexPositionColorTextureNormalTangent> MeshDataGpu::ComposeLitBuffer()
307{
308 std::vector<VertexPositionColorTextureNormalTangent> result;
309
310 unsigned int index = 0;
311 for (const auto& position : mPositions)
312 {
314 vert.position = position;
315 vert.color = mColor.empty() ? glm::vec4(1.0f) : mColor[index];
316 vert.textureCoordinates = mTexCoords.empty() ? glm::vec2(0.0f) : mTexCoords[index];
317 vert.normal = mNormals.empty() ? glm::vec3(0.0f, 0.0f, 1.0f) : mNormals[index];
318 vert.tangent = mTangents.empty() ? glm::vec3(1.0f, 0.0f, 0.0f) : mTangents[index];
319
320 result.push_back(vert);
321 ++index;
322 }
323
324 return result;
325}
326
327} // namespace rendering_engine
Interface for GPU mesh resource management.
Defines an abstract interface for rendering backends.
Definition: i_renderer.hpp:29
virtual IMeshRenderResources * ProvideMeshRenderResources() const =0
Provides access to mesh-related GPU resources.
size_t GetCpuIndexBufferSize() const
Get the size (in bytes) of the index buffer in RAM.
void CreateQuad2D()
Creates a 1�1 unit quad centered at the origin.
std::vector< VertexPositionColorTextureNormalTangent > ComposeLitBuffer()
Compose a vertex buffer for lit 3D meshes (with normals, tangents).
void CalculateMeshParameters()
Calculate and cache sizes of RAM buffers for statistics or debugging.
void LoadModel(std::string path)
Load a model from file and extract mesh data to RAM.
size_t GetGpuIndexBufferSize() const
Get the size (in bytes) of the index buffer on GPU.
std::vector< Vertex2D > ComposeVertex2DBuffer()
Compose a vertex buffer for 2D meshes (e.g., sprites).
IMeshRenderResources * GetMeshRenderResources()
Get the interface for mesh GPU resources (Vulkan or other backend).
void UploadToGPU()
Upload mesh data to the GPU using the current mesh type.
void LoadCustomMesh(std::vector< glm::vec2 > positions2D, std::vector< glm::vec2 > texCoords, std::vector< glm::vec4 > colors, std::vector< std::uint32_t > indices)
bool IsOnGPU() const
Check if mesh data is currently uploaded to GPU.
std::vector< VertexPositionColorTexture > ComposeUnlitBuffer()
Compose a vertex buffer for unlit 3D meshes (e.g., billboards, particles).
MeshDataGpu(IRenderer *renderer)
Constructs an empty MeshDataGpu object.
size_t GetCpuVertexBufferSize() const
Get the size (in bytes) of the vertex buffer in RAM.
~MeshDataGpu()
Destructor. Releases GPU resources if allocated.
size_t GetGpuVertexBufferSize() const
Get the size (in bytes) of the vertex buffer on GPU.
void ReleaseFromGPU()
Release GPU resources associated with this mesh.
MeshType
Types of supported mesh layouts for GPU upload and rendering.
@ Sprite2D
2D sprite mesh (typically for UI or simple quads).
@ None
Undefined or not yet set.
@ Surface
Full 3D surface mesh (models with normals/tangents, etc.).
@ Billboard
3D billboard mesh (sprites that face the camera).
Vertex format for 2D UI/Overlay elements.
glm::vec4 color
Vertex color (RGBA)
glm::vec2 position
2D position in screen or world space
glm::vec2 textureCoordinates
UV coordinates for texturing.
Vertex format for lit 3D geometry (normal and tangent support).
Vertex format for unlit 3D geometry.
glm::vec2 textureCoordinates
UV coordinates for texturing.