Skip to main content

OpenGLMesh.ixx File

OpenGL-specific Mesh implementation and buffer management. More...

Included Headers

#include <glad/gl.h> #include <memory> #include <vector> #include <stdexcept> #include <string> #include <helios.rendering.Vertex> #include <helios.rendering.asset.shape.Shape> #include <helios.rendering.mesh.MeshConfig> #include <helios.rendering.mesh.Mesh>

Namespaces Index

namespacehelios
namespaceext

Platform-specific extensions and backend implementations. More...

namespaceopengl

OpenGL-specific implementations. More...

namespacerendering

OpenGL rendering implementations. More...

namespacemodel

OpenGL mesh implementations. More...

Classes Index

classOpenGLMesh

Representative of an OpenGLMesh. This class manages the OpenGL Vertex Array Object (VAO), the Vertex Buffer Object (VBO) and Element Buffer Object (EBO) handles. The raw mesh data is uploaded to the GPU, preparing it for subsequent rendering commands / draw calls. More...

Description

OpenGL-specific Mesh implementation and buffer management.

File Listing

The file content with the documentation metadata removed is:

1/**
2 * @file OpenGLMesh.ixx
3 * @brief OpenGL-specific Mesh implementation and buffer management.
4 */
5module;
6
7#include <glad/gl.h>
8#include <memory>
9#include <vector>
10#include <stdexcept>
11#include <string>
12
13export module helios.ext.opengl.rendering.model.OpenGLMesh;
14
15import helios.rendering.mesh.Mesh;
16import helios.rendering.mesh.MeshConfig;
17import helios.rendering.asset.shape.Shape;
18import helios.rendering.Vertex;
19
21
22 /**
23 * @brief Representative of an OpenGLMesh.
24 * This class manages the OpenGL Vertex Array Object (VAO), the
25 * Vertex Buffer Object (VBO) and Element Buffer Object (EBO) handles.
26 * The raw mesh data is uploaded to the GPU, preparing it for subsequent
27 * rendering commands / draw calls.
28 */
30
31 protected:
32
33
34 /**
35 * @brief Vertex Array Object handle.
36 */
37 const unsigned int vao_;
38
39
40 /**
41 * @brief Vertex Buffer Object handle.
42 * Stores vertex attributes such as normals and texture coordinates.
43 */
44 const unsigned int vbo_;
45
46
47 /**
48 * @brief Element Buffer Object handle.
49 * Stores the indices used for indexed drawing.
50 */
51 const unsigned int ebo_;
52
53
54 /**
55 * @brief Helper function for generating a Vertex Array Object identifier.
56 *
57 * @return Vertex Array Object handle.
58 */
59 static unsigned int generateGLVertexArray() noexcept {
60 unsigned int vao;
61 glGenVertexArrays(1, &vao);
62 return vao;
63 }
64
65
66 /**
67 * @brief Helper function for generating a Buffer Object identifier,
68 * to be used with vertex buffer or element buffer.
69 *
70 * @return Vertex Array Object handle.
71 */
72 static unsigned int generateGLBuffer() noexcept {
73 unsigned int vbo;
74 glGenBuffers(1, &vbo);
75 return vbo;
76 }
77
78
79 /**
80 * @brief Initializes all buffer objects required by OpenGL from the provided mesh data.
81 * The current implementation generates all VAO, VBO and EBO handles, loads the
82 * vertex and index data to the GPU. It follows [Vri20, 162] in this regard.
83 *
84 * @see [Vri20, 162]
85 */
86 void init() override {
87 glBindVertexArray(vao_);
88 glBindBuffer(GL_ARRAY_BUFFER, vbo_);
89
90 glBufferData(
91 GL_ARRAY_BUFFER,
92 vertices_->size() * sizeof(helios::rendering::Vertex),
93 &(*vertices_)[0],
94 GL_STATIC_DRAW
95 );
96
97 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_);
98 glBufferData(
99 GL_ELEMENT_ARRAY_BUFFER,
100 indices_->size() * sizeof(unsigned int),
101 &(*indices_)[0],
102 GL_STATIC_DRAW
103 );
104
105 // vertex position
106 glEnableVertexAttribArray(0);
107 glVertexAttribPointer(
108 0, 3, GL_FLOAT,
109 GL_FALSE, sizeof(helios::rendering::Vertex), nullptr
110 );
111
112 // vertex normals
113 glEnableVertexAttribArray(1);
114 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(helios::rendering::Vertex),
115 reinterpret_cast<void*>(offsetof(helios::rendering::Vertex, normal))
116 );
117
118 // vertex texture coords
119 glEnableVertexAttribArray(2);
120 glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(helios::rendering::Vertex),
121 reinterpret_cast<void*>(offsetof(helios::rendering::Vertex, texCoords))
122 );
123
124 glBindVertexArray(0);
125 }
126
127 public:
128
129 /**
130 * @brief Rule of three.
131 * @see https://wikis.khronos.org/opengl/Common_Mistakes#RAII_and_hidden_destructor_calls
132 * @see https://en.cppreference.com/w/cpp/language/rule_of_three.html
133 */
134 OpenGLMesh(const OpenGLMesh&) = delete;
135 OpenGLMesh& operator=(const OpenGLMesh&) = delete;
136
137
138 /**
139 * @brief Constructs a new OpenGLMesh instance from raw mesh data.
140 *
141 * @param vertices A shared pointer to a vector of const Vertex
142 * @param indices A shared pointer to a vector of indices
143 * @param meshConfig A shared ptr to the const MeshConfig used with this Mesh.
144 *
145 * @throws std::invalid_argument if either "vertices", "indices" or meshConfig is a null shared pointer
146 */
147 explicit OpenGLMesh(
148 std::shared_ptr<const std::vector<helios::rendering::Vertex>> vertices,
149 std::shared_ptr<const std::vector<unsigned int>> indices,
150 std::shared_ptr<const helios::rendering::mesh::MeshConfig> meshConfig
151 ) :
152 Mesh(
153 std::move(vertices),
154 std::move(indices),
155 std::move(meshConfig)
156 ),
160
161 if (!vertices_ || !indices_ || !meshConfig_) {
162 const std::string msg = "Mesh constructor received a null shared pointer.";
163 logger_.error(msg);
164 throw std::invalid_argument(msg);
165 }
166 /**
167 * @todo this should not be part of the constructor,
168 * instead, lazy init in render pass, then reuse.
169 */
171 }
172
173 /**
174 * @brief Creates a new OpenGLMesh instance from the specified Shape.
175 *
176 * @param shape A const reference to the Shape.
177 * @param meshConfig A shared ptr to the const MeshConfig used with this OpenGLMesh.
178 *
179 * @throws std::invalid_argument if meshConfig is a null shared pointer, or if the
180 * shape contained null data
181 */
182 explicit OpenGLMesh(
184 std::shared_ptr<const helios::rendering::mesh::MeshConfig> meshConfig
185 ) :
186 Mesh(
187 shape,
188 std::move(meshConfig)
189 ),
193
194 if (!vertices_ || !indices_ || !meshConfig_) {
195 const std::string msg = "Mesh constructor received a null shared pointer.";
196 logger_.error(msg);
197 throw std::invalid_argument(msg);
198 }
199
200 /**
201 * @todo this should not be part of the constructor,
202 * instead, lazy init in render pass, then reuse.
203 */
205 }
206
207 /**
208 * @brief Frees allocated resources bv this instance.
209 * If an instance of this class is destructed, `glDeleteBuffers`/`glDeleteVertexArrays`
210 * is called to free the associated resources.
211 *
212 * @see https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDeleteBuffers.xhtml
213 * @see https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDeleteVertexArrays.xhtml
214 *
215 */
216 ~OpenGLMesh() override {
217 glDeleteVertexArrays(1, &vao_);
218 glDeleteBuffers(1, &vbo_);
219 glDeleteBuffers(1, &ebo_);
220 }
221
222 /**
223 * @brief Returns the OpenGL Vertex Array Object Handle.
224 *
225 * @return VAO handle
226 */
227 [[nodiscard]] const unsigned int& vao() const noexcept {
228 return vao_;
229 }
230
231 /**
232 * @brief Returns the OpenGL Vertex Buffer Object handle.
233 *
234 * @return VBO handle
235 */
236 [[nodiscard]] const unsigned int& vbo() const noexcept {
237 return vbo_;
238 }
239
240 /**
241 * @brief Returns the OpenGL Element Buffer Object handle for indexed rendering.
242 *
243 * @return EBO handle
244 */
245 [[nodiscard]] const unsigned int& ebo() const noexcept {
246 return ebo_;
247 }
248
249 };
250
251
252}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.