// // renderer.cxx // graphics // // Created by Sam Jaffe on 5/19/19. // Copyright © 2019 Sam Jaffe. All rights reserved. // #include "game/graphics/renderer.hpp" #include #include "game/graphics/exception.h" #include "game/graphics/object.hpp" #include "game/graphics/vertex.h" #include "matrix/matrix.hpp" #include "matrix/matrix_helpers.hpp" #include "renderer_impl.hpp" using namespace graphics; renderer_impl * get_renderer_impl(driver d) { switch (d) { case driver::openGL: return get_renderer_impl(); default: throw unmapped_enum(d); } } direct_renderer::direct_renderer(driver d) : pimpl(::get_renderer_impl(d)) {} direct_renderer::direct_renderer(renderer_impl * pi) : pimpl(pi) {} std::shared_ptr direct_renderer::manager() const { return pimpl->manager(); } void direct_renderer::draw(object const & obj) { std::vector verts; vertices(verts, obj); draw(obj.material, math::matr4(), verts); } void direct_renderer::draw(identity material, math::matr4 const & object_to_world, std::vector const & verts) { pimpl->draw(material, object_to_world, verts); } void direct_renderer::clear() { pimpl->clear(); } void direct_renderer::flush() { pimpl->flush(); } batch_renderer::batch_renderer(renderer * impl, std::size_t batch_size) : impl_(impl), batches_(), batch_size_(batch_size), elements_(0) {} batch_renderer::~batch_renderer() { flush(); } void batch_renderer::draw(object const & obj) { std::vector & batch_verts = batches_[obj.material]; auto old_size = batch_verts.size(); vertices(batch_verts, obj); elements_ += batch_verts.size() - old_size; check(); } // TODO (sjaffe): object-to-world matrix... void batch_renderer::draw(identity material, math::matr4 const &, std::vector const & verts) { auto & batch_verts = batches_[material]; batch_verts.insert(batch_verts.end(), verts.begin(), verts.end()); elements_ += verts.size(); check(); } void batch_renderer::flush() { write(); impl_->flush(); } void batch_renderer::check() { if (batch_size_ && elements_ >= batch_size_) { write(); } } void batch_renderer::write() { for (auto & pair : batches_) { impl_->draw(pair.first, math::matrix::identity(), pair.second); } batches_.clear(); elements_ = 0; }