5#include <unordered_map>
6#include <glm/ext/scalar_constants.hpp>
7#include <glm/gtc/constants.hpp>
14 assert(glFuncs &&
"QOpenGLFunctions not initialized!");
15 return &shaders.try_emplace(name, vShaderPath, fShaderPath, glFuncs).first->second;
19 assert(glFuncs &&
"QOpenGLFunctions not initialized!");
20 return &meshes.try_emplace(name, verts, idx, glFuncs).first->second;
24 std::vector<Vertex> vertices;
25 std::vector<unsigned int> indices;
26 if (loadOBJ(path, vertices, indices)) {
27 return loadMesh(vertices, indices, name);
34 auto it = shaders.find(name);
35 if (it != shaders.end()) {
43 for (
const auto& [name, shader] : shaders) {
44 if (&shader == target)
return name;
46 assert(
false &&
"Shader not found in ResourceManager!");
50 auto it = meshes.find(name);
51 if (it != meshes.end()) {
59bool ResourceManager::loadOBJ(
const std::string &path, std::vector<Vertex> &outVertices, std::vector<unsigned int> &outIndices) {
60 std::ifstream file(path);
61 if (!file.is_open())
return false;
63 std::vector<glm::vec3> positions;
64 std::vector<glm::vec3> normals;
66 std::unordered_map<Vertex, unsigned int> vertexToIndex;
69 while (std::getline(file, line)) {
70 std::istringstream iss(line);
76 iss >> pos.x >> pos.y >> pos.z;
77 positions.push_back(pos);
78 }
else if (type ==
"vt") {
82 }
else if (type ==
"vn") {
84 iss >> norm.x >> norm.y >> norm.z;
85 normals.push_back(norm);
86 }
else if (type ==
"f") {
87 std::string vertexStr;
88 while (iss >> vertexStr) {
89 std::istringstream vss(vertexStr);
91 int posIdx = 0, uvIdx = 0, normIdx = 0;
93 std::getline(vss, idxStr,
'/');
94 posIdx = std::stoi(idxStr);
96 if (std::getline(vss, idxStr,
'/') && !idxStr.empty())
97 uvIdx = std::stoi(idxStr);
98 if (std::getline(vss, idxStr,
'/'))
99 normIdx = std::stoi(idxStr);
102 vertex.
pos = positions[posIdx - 1];
104 if (normIdx) vertex.normal = normals[normIdx - 1];
106 if (vertexToIndex.count(vertex) == 0) {
107 vertexToIndex[vertex] =
static_cast<unsigned int>(outVertices.size());
108 outVertices.push_back(vertex);
111 outIndices.push_back(vertexToIndex[vertex]);
128void ResourceManager::loadPrimCube() {
129 std::vector<Vertex> vertices = {
130 { {-0.5f, -0.5f, -0.5f}, {0.0f,0.0f,0.0f}},
131 { {0.5f, -0.5f, -0.5f}, {0.0f,0.0f,0.0f}},
132 { {0.5f, 0.5f, -0.5f}, {0.0f,0.0f,0.0f}},
133 { {-0.5f, 0.5f, -0.5f}, {0.0f,0.0f,0.0f}},
134 { {-0.5f, -0.5f, 0.5f}, {0.0f,0.0f,0.0f}},
135 { {0.5f, -0.5f, 0.5f}, {0.0f,0.0f,0.0f}},
136 { {0.5f, 0.5f, 0.5f}, {0.0f,0.0f,0.0f}},
137 { {-0.5f, 0.5f, 0.5f}, {0.0f,0.0f,0.0f}}
140 std::vector<unsigned int> indices {
155 loadMesh(vertices, indices,
"prim_cube");
158void ResourceManager::loadPrimSphere() {
159 std::vector<Vertex> vertices;
160 std::vector<unsigned int> indices;
162 unsigned int latitudeSegments = 64;
163 unsigned int longitudeSegments = 64;
166 for (
unsigned int y = 0; y <= latitudeSegments; ++y) {
167 float v = float(y) / latitudeSegments;
168 float theta = v * glm::pi<float>();
170 for (
unsigned int x = 0; x <= longitudeSegments; ++x) {
171 float u = float(x) / longitudeSegments;
172 float phi = u * glm::two_pi<float>();
175 float sinT = std::sin(theta);
176 auto pos = glm::vec3(sinT * std::cos(phi), std::cos(theta), sinT * std::sin(phi)) * 0.5f;
178 glm::vec3 normal = glm::normalize(pos);
180 vertices.push_back({ pos, normal });
186 for (
unsigned int y = 0; y < latitudeSegments; ++y) {
187 for (
unsigned int x = 0; x < longitudeSegments; ++x) {
189 unsigned int i0 = y * (longitudeSegments + 1) + x;
190 unsigned int i1 = (y + 1) * (longitudeSegments + 1) + x;
191 unsigned int i2 = (y + 1) * (longitudeSegments + 1) + (x + 1);
192 unsigned int i3 = y * (longitudeSegments + 1) + (x + 1);
195 indices.push_back(i0);
196 indices.push_back(i1);
197 indices.push_back(i2);
200 indices.push_back(i0);
201 indices.push_back(i2);
202 indices.push_back(i3);
205 loadMesh(vertices, indices,
"prim_sphere");
Mathematical utility functions for 3D graphics and physics.
GPU mesh representation with support for instanced rendering.
static void initialize(QOpenGLFunctions_4_5_Core *funcs)
static Mesh * loadMesh(const std::vector< Vertex > &verts, const std::vector< unsigned int > &idx, const std::string &name)
static Shader * getShader(const std::string &name)
static void loadPrimitives()
static Mesh * getMesh(const std::string &name)
static Shader * loadShader(const std::string &vShaderPath, const std::string &fShaderPath, const std::string &name)
static std::string getShaderName(const Shader *shader)
static Mesh * loadMeshFromOBJ(const std::string &path, const std::string &name)
Vertex data for a single vertex in a mesh.
glm::vec3 pos
Position in local/model space.