3#include <gmock/gmock.hpp>
4#include <alicorn/std/vector.hpp>
5#include <alicorn/std/string/encoding.hpp>
6#include <boost/algorithm/string/replace.hpp>
8#ifndef OpenGLShader_test
10class OpenGLShader_test :
11 public ::testing::Test
22TEST_F(OpenGLShader_test, Test_Present_Index_CreateBuffer_Fail)
24 using GLProxy_t = ::mock::GLProxy;
26 GLProxy_t::GetInstance() = &GLProxy;
28 const Tested_t Example{ Data_t{} };
29 const ITested_t & IExample = Example;
31 auto itCreator = IExample.GetCreators().find(uT(
"Present"));
32 ASSERT_NE(IExample.GetCreators().end(), itCreator);
34 auto TestCallRender = [&](
const Component_t::ComponentPtr_t & _pComponent)
36 using namespace ::testing;
40 EXPECT_CALL(GLProxy, GenBuffers(_))
43 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _))
46 EXPECT_CALL(GLProxy, GetError())
48 .WillOnce(Return(1908232144));
50 EXPECT_THROW(itCreator->second(_pComponent), ::std::exception);
53 const ::std::vector<int> Source;
55 const auto pBuffer = Component_t::Make(
57 { uT(
"content"), Source },
60 TestCallRender(pBuffer);
62 const auto pData = Component_t::Make(
64 { uT(
"kind"), uT(
"Buffer") },
65 { uT(
"content"), Source },
68 TestCallRender(Component_t::Make({ { uT(
"service"), Object_t{ pData } } }));
72TEST_F(OpenGLShader_test, Test_Present_Index)
74 using GLProxy_t = ::mock::GLProxy;
76 GLProxy_t::GetInstance() = &GLProxy;
78 const Tested_t Example{ Data_t{} };
79 const ITested_t & IExample = Example;
81 const ::mock::GLuint BufferId = 1908241121;
83 ::std::vector<int> Indices =
92 IntroduceBufferSize(Indices);
94 auto itPresentCreator = IExample.GetCreators().find(uT(
"Present"));
95 ASSERT_NE(IExample.GetCreators().end(), itPresentCreator);
97 auto TestCallRender = [&](
const Component_t::ComponentPtr_t & _pPresent)
99 using namespace ::testing;
103 EXPECT_CALL(GLProxy, GenBuffers(1))
105 .WillOnce(Return(BufferId));
107 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferId))
111 static_cast<::mock::GLsizeiptr
>(Indices.size() *
sizeof(
int));
113 EXPECT_CALL(GLProxy, BufferData(GL_ELEMENT_ARRAY_BUFFER, Size,
114 GetExpected(Indices), GL_STATIC_DRAW))
117 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0))
120 EXPECT_CALL(GLProxy, GetError())
122 .WillOnce(Return(GL_NO_ERROR));
124 const auto Render = itPresentCreator->second(_pPresent);
125 ASSERT_NE(
nullptr, Render);
127 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, BufferId))
130 EXPECT_CALL(GLProxy, DrawElements(GL_TRIANGLES, (
int)Indices.size(),
131 GL_UNSIGNED_INT,
nullptr))
134 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0))
137 EXPECT_CALL(GLProxy, BindTexture(GL_TEXTURE_2D, 0))
142 EXPECT_CALL(GLProxy, DeleteBuffers(1, BufferId))
147 const auto pPresent = Component_t::Make(
149 { uT(
"content"), Indices },
152 TestCallRender(pPresent);
158 const auto pData = Component_t::Make(
160 { uT(
"kind"), uT(
"Buffer") },
161 { uT(
"content"), Indices },
164 TestCallRender(Component_t::Make({ { uT(
"service"), Object_t{ pData } } }));
169TEST_F(OpenGLShader_test, Test_Present_Instance_SizeAndCountInvalidValue)
171 ::mock::GLProxy GLProxy;
173 const Tested_t Example{ Data_t{} };
174 const ITested_t & IExample = Example;
176 auto itCreator = IExample.GetCreators().find(uT(
"Present"));
177 ASSERT_NE(IExample.GetCreators().end(), itCreator);
179 auto TestCallMapper = [&](
180 const Component_t::ComponentPtr_t & _pInstance,
181 const auto & _Mapper)
183 const ::std::vector<int> Source;
185 (*_pInstance)[uT(
"mapper")] = _Mapper;
187 const auto pPresent = Component_t::Make(
189 { uT(
"content"), Source },
190 { uT(
"service"), Object_t{ _pInstance } }
193 using namespace ::testing;
195 EXPECT_CALL(GLProxy, GenBuffers(_))
198 EXPECT_THROW(itCreator->second(pPresent), ::std::exception);
201 auto TestCall = [&](
const Component_t::ComponentPtr_t & _pInstance)
203 using BufferMapperMaxCount_t = ::std::function<bool(
void *)>;
204 using BufferMapperCangeCount_t = ::std::function<bool(
void *, ::std::size_t &)>;
206 TestCallMapper(_pInstance, BufferMapperMaxCount_t{});
207 TestCallMapper(_pInstance, BufferMapperCangeCount_t{});
210 TestCall(Component_t::Make(
212 { uT(
"kind"), uT(
"Buffer") },
215 TestCall(Component_t::Make(
217 { uT(
"kind"), uT(
"Buffer") },
218 { uT(
"size"), ::std::size_t(17) },
221 TestCall(Component_t::Make(
223 { uT(
"kind"), uT(
"Buffer") },
224 { uT(
"size"), ::std::size_t(32) },
227 TestCall(Component_t::Make(
229 { uT(
"kind"), uT(
"Buffer") },
230 { uT(
"size"), ::std::size_t(32) },
231 { uT(
"count"), ::std::size_t(5) },
236TEST_F(OpenGLShader_test, Test_Present_Instance_CreateBuffer_Fail)
238 using BufferMapperMaxCount_t = ::std::function<bool(
void *)>;
239 using BufferMapperCangeCount_t = ::std::function<bool(
void *, ::std::size_t &)>;
241 ::mock::GLProxy GLProxy;
243 const Tested_t Example{ Data_t{} };
244 const ITested_t & IExample = Example;
246 auto itCreator = IExample.GetCreators().find(uT(
"Present"));
247 ASSERT_NE(IExample.GetCreators().end(), itCreator);
249 auto TestCallRender = [&](
const auto & _Mapper)
251 const ::std::vector<int> Source;
253 const auto pInstanceData = Component_t::Make(
255 { uT(
"kind"), uT(
"Buffer") },
256 { uT(
"mapper"), _Mapper },
257 { uT(
"size"), ::std::size_t(16) },
258 { uT(
"count"), ::std::size_t(1) },
261 const auto pPresent = Component_t::Make(
263 { uT(
"content"), Source },
264 { uT(
"service"), Object_t{ pInstanceData } }
267 using namespace ::testing;
271 EXPECT_CALL(GLProxy, GenBuffers(_))
274 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _))
277 EXPECT_CALL(GLProxy, GetError())
279 .WillOnce(Return(GL_NO_ERROR));
281 EXPECT_CALL(GLProxy, GenBuffers(_))
284 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, _))
287 EXPECT_CALL(GLProxy, GetError())
289 .WillOnce(Return(1908232144));
291 EXPECT_THROW(itCreator->second(pPresent), ::std::exception);
294 TestCallRender(BufferMapperMaxCount_t{});
295 TestCallRender(BufferMapperCangeCount_t{});
299TEST_F(OpenGLShader_test, Test_Present_Instance_MaxCount)
301 using BufferMapper_t = ::covellite::api::cbBufferMap_t<void>;
303 ::mock::GLProxy GLProxy;
308 MOCK_METHOD1(Map,
bool(
void *));
311 MapperProxy_t MapperProxy;
313 const ::mock::GLuint IndexBufferId = 1909231813;
314 const ::mock::GLuint InstanceBufferId = 1909231820;
315 const ::std::size_t InstanceCount = 120;
316 const ::std::size_t InstanceStride = 48;
317 const ::std::size_t InstanceBufferSize = InstanceCount * InstanceStride;
318 const ::mock::GLint ProgramId = 1909231917;
320 ::std::vector<int> Indices =
332 IntroduceBufferSize(Indices);
334 void * pLocalData = (
void *)1909232013;
336 const BufferMapper_t Mapper = [&](
void * _pData)
339 return MapperProxy.Map(_pData);
342 const Tested_t Example{ Data_t{} };
343 const ITested_t & IExample = Example;
345 auto itCreator = IExample.GetCreators().find(uT(
"Present"));
346 ASSERT_NE(IExample.GetCreators().end(), itCreator);
348 auto TestCallRender = [&](
const Component_t::ComponentPtr_t & _pPresent)
350 using namespace ::testing;
356 EXPECT_CALL(GLProxy, GenBuffers(1))
358 .WillOnce(Return(IndexBufferId));
360 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId))
364 static_cast<::mock::GLsizeiptr
>(Indices.size() *
sizeof(
int));
366 EXPECT_CALL(GLProxy, BufferData(GL_ELEMENT_ARRAY_BUFFER, Size,
367 GetExpected(Indices), GL_STATIC_DRAW))
370 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0))
373 EXPECT_CALL(GLProxy, GetError())
375 .WillOnce(Return(GL_NO_ERROR));
379 EXPECT_CALL(GLProxy, GenBuffers(1))
381 .WillOnce(Return(InstanceBufferId));
383 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, InstanceBufferId))
386 EXPECT_CALL(GLProxy, BufferData(GL_ARRAY_BUFFER, InstanceBufferSize,
387 ::std::vector<uint8_t>{}, GL_DYNAMIC_DRAW))
390 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, 0))
393 EXPECT_CALL(GLProxy, GetError())
395 .WillOnce(Return(GL_NO_ERROR));
399 const auto Render = itCreator->second(_pPresent);
400 ASSERT_NE(
nullptr, Render);
404 const auto TestCallDraw = [&](void)
406 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId))
409 EXPECT_CALL(GLProxy, DrawElementsInstanced(GL_TRIANGLES,
410 (
int)Indices.size(), GL_UNSIGNED_INT,
nullptr, InstanceCount))
413 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0))
416 EXPECT_CALL(GLProxy, BindTexture(GL_TEXTURE_2D, 0))
420 EXPECT_CALL(MapperProxy, Map(
nullptr))
422 .WillOnce(Return(
false));
424 EXPECT_CALL(MapperProxy, Map(_))
427 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, InstanceBufferId))
435 const auto TestCallSetInstanceData = [&](
436 const ::mock::GLenum _iType,
437 const ::mock::GLenum _Type,
438 const ::mock::GLint _LocationIndex0,
441 EXPECT_CALL(MapperProxy, Map(
nullptr))
443 .WillOnce(Return(
true));
445 EXPECT_CALL(MapperProxy, Map(pData))
448 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, InstanceBufferId))
452 BufferSubDataRaw(GL_ARRAY_BUFFER, 0, InstanceBufferSize, pData))
455 EXPECT_CALL(GLProxy, GetIntegerv(GL_CURRENT_PROGRAM))
457 .WillOnce(Return(&ProgramId));
459 constexpr auto BlockSize =
sizeof(float) * 4;
461 EXPECT_CALL(GLProxy, GetProgramiv(ProgramId, GL_ACTIVE_ATTRIBUTES))
463 .WillOnce(Return(BlockSize));
465 for (
int i = 0; i < BlockSize; i++)
467 EXPECT_CALL(GLProxy, GetActiveAttribType(ProgramId, i))
469 .WillOnce(Return(_iType));
471 EXPECT_CALL(GLProxy, GetActiveAttribName(ProgramId, i, 255))
473 .WillOnce(Return(
"iValue" + ::std::to_string(i + 1)));
476 for (
int i = 0; i < InstanceStride / BlockSize; i++)
479 GetAttribLocation(ProgramId,
"iValue" + ::std::to_string(i + 1)))
481 .WillOnce(Return(_LocationIndex0 + i));
483 if (_LocationIndex0 + i >= 0)
485 EXPECT_CALL(GLProxy, EnableVertexAttribArray(_LocationIndex0 + i))
488 EXPECT_CALL(GLProxy, VertexAttribPointer(_LocationIndex0 + i, 4,
489 _Type, GL_FALSE, InstanceStride, (
void*)(BlockSize * i)))
492 EXPECT_CALL(GLProxy, VertexAttribDivisor(_LocationIndex0 + i, 1))
497 EXPECT_CALL(GLProxy, EnableVertexAttribArray(_))
500 EXPECT_CALL(GLProxy, VertexAttribPointer(_, _, _, _, _, _))
503 EXPECT_CALL(GLProxy, VertexAttribDivisor(_, _))
508 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, 0))
514 TestCallSetInstanceData(GL_FLOAT_VEC4, GL_FLOAT, 1909232004, _);
518 TestCallSetInstanceData(GL_FLOAT_VEC4, GL_FLOAT, 1909232004, pLocalData);
522 TestCallSetInstanceData(GL_INT_VEC4, GL_INT, 1909232005, pLocalData);
526 TestCallSetInstanceData(2005221201, 2005221201, 2005221202, pLocalData);
530 TestCallSetInstanceData(GL_FLOAT_VEC4, GL_FLOAT, -1, pLocalData);
534 TestCallSetInstanceData(GL_INT_VEC4, GL_INT, -1, pLocalData);
540 EXPECT_CALL(GLProxy, DeleteBuffers(1, IndexBufferId))
543 EXPECT_CALL(GLProxy, DeleteBuffers(1, InstanceBufferId))
547 const auto pInstanceData = Component_t::Make(
549 { uT(
"kind"), uT(
"Buffer") },
550 { uT(
"size"), InstanceBufferSize },
551 { uT(
"mapper"), Mapper },
552 { uT(
"count"), InstanceCount },
555 const auto pPresent = Component_t::Make(
557 { uT(
"content"), Indices },
558 { uT(
"service"), Object_t{ pInstanceData } }
561 TestCallRender(pPresent);
565TEST_F(OpenGLShader_test, Test_Present_Instance_ChangeCount)
567 using BufferMapper_t = ::std::function<bool(
void *, ::std::size_t &)>;
569 ::mock::GLProxy GLProxy;
574 MOCK_METHOD1(GetCount, ::std::size_t(::std::size_t));
575 MOCK_METHOD1(Map,
bool(
void *));
578 MapperProxy_t MapperProxy;
580 const ::mock::GLuint IndexBufferId = 1909231813;
581 const ::mock::GLuint InstanceBufferId = 1909231820;
582 const ::std::size_t InstanceCount = 120;
583 const ::std::size_t InstanceStride = 48;
584 const ::std::size_t InstanceBufferSize = InstanceCount * InstanceStride;
585 const ::mock::GLint ProgramId = 1909231917;
587 ::std::vector<int> Indices =
599 IntroduceBufferSize(Indices);
601 void * pLocalData = (
void *)1909232013;
603 const BufferMapper_t Mapper = [&](
void * _pData, ::std::size_t & _Count)
606 _Count = MapperProxy.GetCount(_Count);
607 return MapperProxy.Map(_pData);
610 const Tested_t Example{ Data_t{} };
611 const ITested_t & IExample = Example;
613 auto itCreator = IExample.GetCreators().find(uT(
"Present"));
614 ASSERT_NE(IExample.GetCreators().end(), itCreator);
616 auto TestCallRender = [&](
const Component_t::ComponentPtr_t & _pPresent)
618 using namespace ::testing;
624 EXPECT_CALL(GLProxy, GenBuffers(1))
626 .WillOnce(Return(IndexBufferId));
628 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId))
632 static_cast<::mock::GLsizeiptr
>(Indices.size() *
sizeof(
int));
634 EXPECT_CALL(GLProxy, BufferData(GL_ELEMENT_ARRAY_BUFFER, Size,
635 GetExpected(Indices), GL_STATIC_DRAW))
638 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0))
641 EXPECT_CALL(GLProxy, GetError())
643 .WillOnce(Return(GL_NO_ERROR));
647 EXPECT_CALL(GLProxy, GenBuffers(1))
649 .WillOnce(Return(InstanceBufferId));
651 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, InstanceBufferId))
654 EXPECT_CALL(GLProxy, BufferData(GL_ARRAY_BUFFER, InstanceBufferSize,
655 ::std::vector<uint8_t>{}, GL_DYNAMIC_DRAW))
658 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, 0))
661 EXPECT_CALL(GLProxy, GetError())
663 .WillOnce(Return(GL_NO_ERROR));
667 const auto Render = itCreator->second(_pPresent);
668 ASSERT_NE(
nullptr, Render);
672 const auto TestCallDraw = [&](const ::std::size_t _Count)
674 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId))
677 EXPECT_CALL(GLProxy, DrawElementsInstanced(GL_TRIANGLES,
678 (
int)Indices.size(), GL_UNSIGNED_INT,
nullptr, _Count))
681 EXPECT_CALL(GLProxy, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0))
684 EXPECT_CALL(GLProxy, BindTexture(GL_TEXTURE_2D, 0))
688 EXPECT_CALL(MapperProxy, GetCount(InstanceCount))
690 .WillOnce(Return(InstanceCount / 2));
692 EXPECT_CALL(MapperProxy, Map(
nullptr))
694 .WillOnce(Return(
false));
696 EXPECT_CALL(MapperProxy, Map(_))
699 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, InstanceBufferId))
702 TestCallDraw(InstanceCount / 2);
707 EXPECT_CALL(MapperProxy, GetCount(InstanceCount))
709 .WillOnce(Return(InstanceCount * 2));
711 EXPECT_CALL(MapperProxy, Map(
nullptr))
713 .WillOnce(Return(
false));
715 EXPECT_CALL(MapperProxy, Map(_))
718 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, InstanceBufferId))
721 TestCallDraw(InstanceCount);
726 const auto TestCallSetInstanceData = [&](
727 const ::mock::GLenum _iType,
728 const ::mock::GLenum _Type,
729 const ::mock::GLint _LocationIndex0,
731 const ::std::size_t _ReturnCount)
733 EXPECT_CALL(MapperProxy, GetCount(InstanceCount))
735 .WillOnce(Return(0));
737 EXPECT_CALL(MapperProxy, Map(
nullptr))
739 .WillOnce(Return(
true));
741 EXPECT_CALL(MapperProxy, GetCount(0))
743 .WillOnce(Return(_ReturnCount));
745 EXPECT_CALL(MapperProxy, Map(pData))
748 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, InstanceBufferId))
752 BufferSubDataRaw(GL_ARRAY_BUFFER, 0, InstanceBufferSize, pData))
755 EXPECT_CALL(GLProxy, GetIntegerv(GL_CURRENT_PROGRAM))
757 .WillOnce(Return(&ProgramId));
759 constexpr auto BlockSize =
sizeof(float) * 4;
761 EXPECT_CALL(GLProxy, GetProgramiv(ProgramId, GL_ACTIVE_ATTRIBUTES))
763 .WillOnce(Return(BlockSize));
765 for (
int i = 0; i < BlockSize; i++)
767 EXPECT_CALL(GLProxy, GetActiveAttribType(ProgramId, i))
769 .WillOnce(Return(_iType));
771 EXPECT_CALL(GLProxy, GetActiveAttribName(ProgramId, i, 255))
773 .WillOnce(Return(
"iValue" + ::std::to_string(i + 1)));
776 for (
int i = 0; i < InstanceStride / BlockSize; i++)
779 GetAttribLocation(ProgramId,
"iValue" + ::std::to_string(i + 1)))
781 .WillOnce(Return(_LocationIndex0 + i));
783 if (_LocationIndex0 + i >= 0)
785 EXPECT_CALL(GLProxy, EnableVertexAttribArray(_LocationIndex0 + i))
788 EXPECT_CALL(GLProxy, VertexAttribPointer(_LocationIndex0 + i, 4,
789 _Type, GL_FALSE, InstanceStride, (
void *)(BlockSize * i)))
792 EXPECT_CALL(GLProxy, VertexAttribDivisor(_LocationIndex0 + i, 1))
797 EXPECT_CALL(GLProxy, EnableVertexAttribArray(_))
800 EXPECT_CALL(GLProxy, VertexAttribPointer(_, _, _, _, _, _))
803 EXPECT_CALL(GLProxy, VertexAttribDivisor(_, _))
808 EXPECT_CALL(GLProxy, BindBuffer(GL_ARRAY_BUFFER, 0))
814 TestCallSetInstanceData(GL_FLOAT_VEC4, GL_FLOAT, 1909232004, _, 0);
818 TestCallSetInstanceData(GL_FLOAT_VEC4, GL_FLOAT, 1909232004, pLocalData, InstanceCount / 3);
819 TestCallDraw(InstanceCount / 3);
822 TestCallSetInstanceData(GL_INT_VEC4, GL_INT, 1909232005, pLocalData, InstanceCount / 4);
823 TestCallDraw(InstanceCount / 4);
826 TestCallSetInstanceData(2005221201, 2005221201, 2005221202, pLocalData, InstanceCount * 2);
827 TestCallDraw(InstanceCount);
830 TestCallSetInstanceData(GL_FLOAT_VEC4, GL_FLOAT, -1, pLocalData, InstanceCount * 3);
831 TestCallDraw(InstanceCount);
834 TestCallSetInstanceData(GL_INT_VEC4, GL_INT, -1, pLocalData, InstanceCount + 1);
835 TestCallDraw(InstanceCount);
840 EXPECT_CALL(GLProxy, DeleteBuffers(1, IndexBufferId))
843 EXPECT_CALL(GLProxy, DeleteBuffers(1, InstanceBufferId))
847 const auto pInstanceData = Component_t::Make(
849 { uT(
"kind"), uT(
"Buffer") },
850 { uT(
"size"), InstanceBufferSize },
851 { uT(
"mapper"), Mapper },
852 { uT(
"count"), InstanceCount },
855 const auto pPresent = Component_t::Make(
857 { uT(
"content"), Indices },
858 { uT(
"service"), Object_t{ pInstanceData } }
861 TestCallRender(pPresent);