| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- //
- // direct_renderer_test.cxx
- // graphics-test
- //
- // Created by Sam Jaffe on 6/1/19.
- // Copyright © 2019 Sam Jaffe. All rights reserved.
- //
- #include "game/graphics/renderer.hpp"
- #include <testing/xcode_gtest_helper.h>
- #include <game/math/shape.hpp>
- #include <math/matrix/matrix.hpp>
- #include <math/matrix/matrix_helpers.hpp>
- #include "../src/renderer_impl.hpp"
- #include "game/graphics/exception.h"
- #include "game/graphics/object.hpp"
- #include "game/graphics/vertex.h"
- using testing::_;
- using testing::AnyNumber;
- using testing::IsEmpty;
- using testing::SizeIs;
- struct mock_renderer_impl : graphics::renderer_impl {
- MOCK_CONST_METHOD0(manager, std::shared_ptr<graphics::manager const>());
- MOCK_METHOD3(draw, void(identity<graphics::material>, math::matr4 const &,
- std::vector<graphics::vertex> const &));
- MOCK_METHOD0(clear, void());
- MOCK_METHOD0(flush, void());
- };
- identity<graphics::material> cast(unsigned int id) {
- return *reinterpret_cast<identity<graphics::material> *>(&id);
- }
- struct DirectRendererTest : testing::Test {
- void SetUp() override;
- void TearDown() override;
- std::unique_ptr<graphics::direct_renderer> renderer;
- mock_renderer_impl * mock;
- };
- void DirectRendererTest::SetUp() {
- mock = new mock_renderer_impl;
- renderer.reset(new graphics::direct_renderer(mock));
- }
- void DirectRendererTest::TearDown() {
- renderer.reset();
- delete mock;
- }
- graphics::object DemoObject(unsigned int id = 1) {
- math::dim2::rectangle const size{{{-1.f, -1.f}}, {{2.f, 2.f}}};
- math::dim2::rectangle const tex{{{0.f, 0.f}}, {{1.f, 1.f}}};
- return {size, size, cast(id), tex};
- }
- TEST_F(DirectRendererTest, DrawPassesToDraw) {
- EXPECT_CALL(*mock, draw(cast(1), math::matr4(), IsEmpty())).Times(1);
- renderer->draw(cast(1), math::matr4(), {});
- }
- TEST_F(DirectRendererTest, DrawObjectHasIdenTranslation) {
- auto identity = math::matrix::identity<float, 4>();
- EXPECT_CALL(*mock, draw(cast(1), identity, _)).Times(1);
- renderer->draw(DemoObject());
- }
- TEST_F(DirectRendererTest, DrawObjectHasSixVertices) {
- EXPECT_CALL(*mock, draw(_, _, SizeIs(6))).Times(1);
- renderer->draw(DemoObject());
- }
- TEST_F(DirectRendererTest, MultipleDrawCallsDispatchMultipleDraws) {
- EXPECT_CALL(*mock, draw(_, _, SizeIs(6))).Times(2);
- renderer->draw(DemoObject());
- renderer->draw(DemoObject());
- }
- TEST_F(DirectRendererTest, ClearPassesToClear) {
- EXPECT_CALL(*mock, clear()).Times(1);
- renderer->clear();
- }
- TEST_F(DirectRendererTest, FlushPassesToFlush) {
- EXPECT_CALL(*mock, flush()).Times(1);
- renderer->flush();
- }
- struct BatchRendererTest : testing::Test {
- void SetUp() override;
- void TearDown() override;
- std::unique_ptr<graphics::batch_renderer> renderer;
- std::unique_ptr<graphics::direct_renderer> drenderer;
- mock_renderer_impl * mock;
- };
- void BatchRendererTest::SetUp() {
- mock = new mock_renderer_impl;
- drenderer.reset(new graphics::direct_renderer(mock));
- renderer.reset(new graphics::batch_renderer(drenderer.get()));
- }
- void BatchRendererTest::TearDown() {
- renderer.reset();
- drenderer.reset();
- delete mock;
- }
- TEST_F(BatchRendererTest, DoesNotCallFlushOnDestructor) {
- EXPECT_CALL(*mock, flush()).Times(0);
- renderer.reset();
- testing::Mock::VerifyAndClearExpectations(mock);
- }
- TEST_F(BatchRendererTest, ClearPassesToClear) {
- EXPECT_CALL(*mock, flush()).Times(AnyNumber());
- EXPECT_CALL(*mock, clear()).Times(1);
- renderer->clear();
- }
- TEST_F(BatchRendererTest, FlushDoesNotPassToFlush) {
- EXPECT_CALL(*mock, flush()).Times(0);
- renderer->flush();
- }
- TEST_F(BatchRendererTest, DoesNotWriteImmediately) {
- EXPECT_CALL(*mock, draw(_, _, _)).Times(0);
- renderer->draw(cast(1), math::matr4(), {});
- testing::Mock::VerifyAndClearExpectations(mock);
- // We need to re-enact this expectation
- EXPECT_CALL(*mock, flush()).Times(AnyNumber());
- EXPECT_CALL(*mock, draw(_, _, _)).Times(1);
- }
- TEST_F(BatchRendererTest, GroupsDataTogetherByMaterial) {
- EXPECT_CALL(*mock, flush()).Times(AnyNumber());
- EXPECT_CALL(*mock, draw(cast(1), _, SizeIs(12))).Times(1);
- EXPECT_CALL(*mock, draw(cast(2), _, SizeIs(6))).Times(1);
- renderer->draw(DemoObject());
- renderer->draw(DemoObject());
- renderer->draw(DemoObject(2));
- }
- TEST_F(BatchRendererTest, BatchLimitingCanSplitTheWrites) {
- EXPECT_CALL(*mock, flush()).Times(AnyNumber());
- renderer.reset(new graphics::batch_renderer(drenderer.get(), 15));
- // This sometimes occurs...
- EXPECT_CALL(*mock, draw(_, _, SizeIs(0))).Times(AnyNumber());
- EXPECT_CALL(*mock, draw(cast(1), _, SizeIs(12))).Times(1);
- EXPECT_CALL(*mock, draw(cast(2), _, SizeIs(6))).Times(2);
- renderer->draw(DemoObject());
- renderer->draw(DemoObject());
- renderer->draw(DemoObject(2));
- renderer->draw(DemoObject(2));
- }
- struct InjectRendererTest : testing::Test {
- protected:
- void SetUp() override;
- void TearDown() override;
- mock_renderer_impl * mock;
- private:
- graphics::renderer_impl_factory::scoped_binding scope_;
- };
- void InjectRendererTest::SetUp() {
- mock = new mock_renderer_impl;
- auto & factory = graphics::renderer_impl_factory::instance();
- scope_ = factory.bind_scoped("mock", [this]() { return mock; });
- }
- void InjectRendererTest::TearDown() { delete mock; }
- TEST_F(InjectRendererTest, ThrowsOnRequestOfBlank) {
- EXPECT_THROW(graphics::direct_renderer(""),
- graphics::unmapped_enum<graphics::driver>);
- }
- TEST(UnboundRendererTest, ThrowsOnRequestOfUnboundDriver) {
- EXPECT_THROW(graphics::direct_renderer("mock"),
- graphics::unmapped_enum<graphics::driver>);
- }
- TEST_F(InjectRendererTest, SuccessfulConstructionWithBoundImpl) {
- EXPECT_NO_THROW(graphics::direct_renderer("mock"));
- }
- TEST_F(InjectRendererTest, BoundImplIsSamePointed) {
- graphics::direct_renderer renderer("mock");
- EXPECT_CALL(*mock, draw(cast(1), math::matr4(), IsEmpty())).Times(1);
- renderer.draw(cast(1), math::matr4(), {});
- }
|