renderer.cxx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. //
  2. // renderer.cxx
  3. // graphics
  4. //
  5. // Created by Sam Jaffe on 5/19/19.
  6. // Copyright © 2019 Sam Jaffe. All rights reserved.
  7. //
  8. #include "game/graphics/renderer.hpp"
  9. #include <vector>
  10. #include <math/matrix/matrix.hpp>
  11. #include <math/matrix/matrix_helpers.hpp>
  12. #include "game/graphics/exception.h"
  13. #include "game/graphics/object.hpp"
  14. #include "game/graphics/vertex.h"
  15. #include "renderer_impl.hpp"
  16. using namespace graphics;
  17. INSTANTIATE_PROTOTYPE_FACTORY(renderer_impl *);
  18. renderer_impl * get_renderer_impl(std::string const & id) {
  19. renderer_impl * rval = renderer_impl_factory::instance().get(id);
  20. if (rval == nullptr) throw unmapped_enum<driver>(id);
  21. return rval;
  22. }
  23. namespace {
  24. const math::matr4 identity4 = math::matrix::identity<float, 4>();
  25. }
  26. direct_renderer::direct_renderer(std::string const & driver_id)
  27. : direct_renderer(::get_renderer_impl(driver_id)) {}
  28. direct_renderer::direct_renderer(renderer_impl * pi) : pimpl(pi) {}
  29. std::shared_ptr<class manager const> direct_renderer::manager() const {
  30. return pimpl->manager();
  31. }
  32. void direct_renderer::draw(object const & obj) {
  33. std::vector<vertex> verts;
  34. vertices(verts, obj);
  35. draw(obj.material, identity4, verts);
  36. }
  37. void direct_renderer::draw(identity<material> material,
  38. math::matr4 const & object_to_world,
  39. std::vector<vertex> const & verts) {
  40. pimpl->draw(material, object_to_world, verts);
  41. }
  42. void direct_renderer::clear() { pimpl->clear(); }
  43. void direct_renderer::flush() { pimpl->flush(); }
  44. batch_renderer::batch_renderer(renderer * impl, std::size_t batch_size)
  45. : batch_renderer(impl, identity4, batch_size) {}
  46. batch_renderer::batch_renderer(renderer * impl, math::matr4 const & to_world,
  47. std::size_t batch_size)
  48. : impl_(impl), batches_(), object_to_world_(to_world),
  49. batch_size_(batch_size), elements_(0) {}
  50. batch_renderer::~batch_renderer() { flush(); }
  51. void batch_renderer::draw(object const & obj) {
  52. std::vector<vertex> & batch_verts = batches_[obj.material];
  53. auto old_size = batch_verts.size();
  54. vertices(batch_verts, obj);
  55. elements_ += batch_verts.size() - old_size;
  56. check();
  57. }
  58. // TODO (sjaffe): object-to-world matrix...
  59. void batch_renderer::draw(identity<material> material, math::matr4 const &,
  60. std::vector<vertex> const & verts) {
  61. auto & batch_verts = batches_[material];
  62. batch_verts.insert(batch_verts.end(), verts.begin(), verts.end());
  63. elements_ += verts.size();
  64. check();
  65. }
  66. void batch_renderer::flush() {
  67. write();
  68. // impl_->flush();
  69. }
  70. void batch_renderer::check() {
  71. if (batch_size_ && elements_ >= batch_size_) { write(); }
  72. }
  73. void batch_renderer::write() {
  74. for (auto & pair : batches_) {
  75. impl_->draw(pair.first, object_to_world_, pair.second);
  76. pair.second.clear();
  77. }
  78. elements_ = 0;
  79. }