|
13 | 13 | namespace our { |
14 | 14 | int Model::ID_COUNTER = 0; |
15 | 15 |
|
16 | | - void Model::draw(const glm::mat4& VP, const glm::mat4& modelMatrix, const std::vector<our::LightRenderData>& lights, |
17 | | - const glm::vec3& cameraPosition) const { |
18 | | - glm::mat4 MVP = VP * modelMatrix; |
| 16 | + void Model::generateDrawCommands(std::vector<RenderCommand>& modelCommands, |
| 17 | + std::vector<RenderCommand>& transparentCommands, |
| 18 | + const glm::mat4& modelMatrix) const { |
19 | 19 | for (const auto& submesh : submeshes) { |
20 | | - // this dynamic cast will always pass |
21 | | - // as we only make LitMaterials when loading the model |
22 | | - if (LitMaterial* litMaterial = dynamic_cast<LitMaterial*>(submesh->material)) { |
23 | | - litMaterial->setup(lights); |
24 | | - litMaterial->shader->set("cameraPos", cameraPosition); |
25 | | - litMaterial->shader->set("model", modelMatrix * submesh->transform); |
26 | | - litMaterial->shader->set("transform", MVP * submesh->transform); |
27 | | - } else if (submesh->material) { |
28 | | - submesh->material->setup(); |
29 | | - submesh->material->shader->set("model", modelMatrix * submesh->transform); |
30 | | - submesh->material->shader->set("transform", MVP * submesh->transform); |
| 20 | + RenderCommand cmd; |
| 21 | + cmd.localToWorld = modelMatrix * submesh->transform; |
| 22 | + cmd.center = glm::vec3(cmd.localToWorld * glm::vec4(0, 0, 0, 1)); |
| 23 | + cmd.mesh = submesh->mesh; |
| 24 | + cmd.material = submesh->material; |
| 25 | + if (submesh->material->transparent) { |
| 26 | + transparentCommands.push_back(cmd); |
| 27 | + } else { |
| 28 | + modelCommands.push_back(cmd); |
31 | 29 | } |
32 | | - submesh->mesh->draw(); |
33 | 30 | } |
34 | 31 | } |
35 | 32 |
|
@@ -69,6 +66,7 @@ namespace our { |
69 | 66 | loadMaterialsFromScene(scene); |
70 | 67 | glm::mat4 identity(1.0f); |
71 | 68 | processNode(scene->mRootNode, scene, identity); |
| 69 | + generateCombinedMesh(); |
72 | 70 | } |
73 | 71 |
|
74 | 72 | void Model::processNode(aiNode* node, const aiScene* scene, glm::mat4& parentTransform) { |
@@ -263,7 +261,8 @@ namespace our { |
263 | 261 | material->transparent = material->tint.a < 0.999f; |
264 | 262 |
|
265 | 263 | if (material->transparent) { |
266 | | - material->pipelineState.depthTesting.enabled = GL_FALSE; // disable depth writing for transparent materials |
| 264 | + material->pipelineState.depthTesting.enabled = GL_TRUE; // disable depth writing for transparent materials |
| 265 | + material->pipelineState.depthMask = false; |
267 | 266 | material->pipelineState.blending.enabled = true; |
268 | 267 | material->pipelineState.blending.sourceFactor = GL_SRC_ALPHA; |
269 | 268 | int blendFunc = 0; |
@@ -364,6 +363,36 @@ namespace our { |
364 | 363 | } |
365 | 364 | } |
366 | 365 |
|
| 366 | + void Model::generateCombinedMesh() { |
| 367 | + std::vector<Vertex> combinedVertices; |
| 368 | + std::vector<unsigned int> combinedIndices; |
| 369 | + |
| 370 | + for (const auto& submesh : submeshes) { |
| 371 | + unsigned int indexOffset = static_cast<unsigned int>(combinedVertices.size()); |
| 372 | + |
| 373 | + // Transform each vertex into model space using the submesh's local transform |
| 374 | + for (const Vertex& v : submesh->mesh->getVertices()) { |
| 375 | + Vertex transformed = v; |
| 376 | + |
| 377 | + // Apply the submesh transform to position |
| 378 | + glm::vec4 worldPos = submesh->transform * glm::vec4(v.position, 1.0f); |
| 379 | + transformed.position = glm::vec3(worldPos); |
| 380 | + |
| 381 | + // Transform normal using the normal matrix (inverse transpose) |
| 382 | + glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(submesh->transform))); |
| 383 | + transformed.normal = glm::normalize(normalMatrix * v.normal); |
| 384 | + |
| 385 | + combinedVertices.push_back(transformed); |
| 386 | + } |
| 387 | + |
| 388 | + // Re-base indices so they point into the combined vertex buffer |
| 389 | + for (unsigned int idx : submesh->mesh->getIndices()) { |
| 390 | + combinedIndices.push_back(idx + indexOffset); |
| 391 | + } |
| 392 | + } |
| 393 | + combinedMesh = new Mesh(combinedVertices, combinedIndices); |
| 394 | + } |
| 395 | + |
367 | 396 | Model::~Model() { |
368 | 397 | for (auto& submesh : submeshes) { |
369 | 398 | delete submesh->mesh; |
|
0 commit comments