| 556 | } |
| 557 | |
| 558 | void pbr_renderer::render_frame(const render_payload & scene) |
| 559 | { |
| 560 | assert(settings.cameraCount == scene.views.size()); |
| 561 | |
| 562 | // @fixme - refactor to make optional |
| 563 | auto validate_materials = [this, scene]() |
| 564 | { |
| 565 | for (const auto & render_comp : scene.render_components) |
| 566 | { |
| 567 | // In some workflows, it's useful to hand edit scene files and materials |
| 568 | // but this often results in a typo, forgotten copy-and-paste, or other |
| 569 | // types of human-introduced issues. Formerly, we would crash below |
| 570 | // when trying to sort materials, but this is now an explicit check. |
| 571 | if (!render_comp.material->material.get()) |
| 572 | { |
| 573 | std::cout << "[pbr_renderer] material was not assigned - " << render_comp.material->material.name << std::endl; |
| 574 | throw std::runtime_error("unassigned material"); // could also possibly assign the default one |
| 575 | } |
| 576 | } |
| 577 | }; |
| 578 | |
| 579 | validate_materials(); |
| 580 | |
| 581 | cpuProfiler.begin("render_frame"); |
| 582 | |
| 583 | // Renderer default state |
| 584 | glEnable(GL_CULL_FACE); |
| 585 | glEnable(GL_DEPTH_TEST); |
| 586 | glEnable(GL_FRAMEBUFFER_SRGB); |
| 587 | |
| 588 | glBindBufferBase(GL_UNIFORM_BUFFER, uniforms::per_scene::binding, perScene); |
| 589 | glBindBufferBase(GL_UNIFORM_BUFFER, uniforms::per_view::binding, perView); |
| 590 | glBindBufferBase(GL_UNIFORM_BUFFER, uniforms::per_object::binding, perObject); |
| 591 | |
| 592 | // Update per-scene uniform buffer |
| 593 | uniforms::per_scene b = {}; |
| 594 | b.time = timer.milliseconds().count() / 1000.f; // expressed in seconds |
| 595 | b.resolution = float2(settings.renderSize); |
| 596 | b.invResolution = 1.f / b.resolution; |
| 597 | b.activePointLights = static_cast<int>(scene.point_lights.size()); |
| 598 | b.sunlightActive = 0; |
| 599 | |
| 600 | if (scene.sunlight) |
| 601 | { |
| 602 | b.sunlightActive = 1; |
| 603 | b.directional_light.color = scene.sunlight->data.color; |
| 604 | b.directional_light.direction = scene.sunlight->data.direction; |
| 605 | b.directional_light.amount = scene.sunlight->data.amount; |
| 606 | } |
| 607 | |
| 608 | assert(scene.point_lights.size() <= uniforms::MAX_POINT_LIGHTS); |
| 609 | uint32_t lightIdx = 0; |
| 610 | for (auto & light : scene.point_lights) |
| 611 | { |
| 612 | if (!light->enabled) continue; |
| 613 | b.point_lights[lightIdx] = light->data; |
| 614 | lightIdx++; |
| 615 | } |
no test coverage detected