1from unittest.mock import MagicMock, patch 2 3import pytest 4 5from UM.Math.Color import Color 6from UM.Math.Matrix import Matrix 7from UM.Mesh.MeshBuilder import MeshBuilder 8from UM.Mesh.MeshData import MeshData 9from UM.View.RenderBatch import RenderBatch 10 11 12test_addItem_data = [ 13 {"item": {"transformation": Matrix(), "mesh": MeshData()}, "should_add": True}, 14 {"item": {"transformation": None, "mesh": MeshData()}, "should_add": False}, 15 {"item": {"transformation": None, "mesh": None}, "should_add": False}, 16 {"item": {"transformation": Matrix(), "mesh": None}, "should_add": False}, 17 {"item": {"transformation": Matrix(), "mesh": MeshData(), "uniforms": {}}, "should_add": True}, 18] 19 20 21test_compare_data = [ 22 {"item1": {}, "item2": {"sort": 1}}, 23 {"item1": {}, "item2": {"sort": 1}}, 24 {"item1": {"type": RenderBatch.RenderType.Solid, "sort": 0}, "item2": {"sort": 20, "type":RenderBatch.RenderType.NoType}}, # Solid trumps notype, even if sort is higher 25 {"item1": {"type": RenderBatch.RenderType.Transparent, "sort": 0}, "item2": {"sort": 20, "type":RenderBatch.RenderType.NoType}} 26] 27 28 29def test_createRenderBatch(): 30 mocked_shader = MagicMock() 31 with patch("UM.View.GL.OpenGL.OpenGL.getInstance"): 32 render_batch = RenderBatch(mocked_shader) 33 34 35 # Ensure that the proper defaults are set. 36 assert render_batch.renderType == RenderBatch.RenderType.Solid 37 assert render_batch.renderMode == RenderBatch.RenderMode.Triangles 38 assert render_batch.shader == mocked_shader 39 assert not render_batch.backfaceCull 40 assert render_batch.renderRange is None 41 assert render_batch.items == [] 42 43 44@pytest.mark.parametrize("data", test_addItem_data) 45def test_addItem(data): 46 mocked_shader = MagicMock() 47 with patch("UM.View.GL.OpenGL.OpenGL.getInstance"): 48 render_batch = RenderBatch(mocked_shader) 49 50 render_batch.addItem(**data["item"]) 51 52 if data["should_add"]: 53 assert len(render_batch.items) != 0 54 55 56@pytest.mark.parametrize("data", test_compare_data) 57def test_compare(data): 58 mocked_shader = MagicMock() 59 with patch("UM.View.GL.OpenGL.OpenGL.getInstance"): 60 render_batch_1 = RenderBatch(mocked_shader, **data["item1"]) 61 render_batch_2 = RenderBatch(mocked_shader, **data["item2"]) 62 assert render_batch_1 < render_batch_2 63 64 65def test_render(): 66 mocked_shader = MagicMock() 67 with patch("UM.View.GL.OpenGL.OpenGL.getInstance"): 68 render_batch = RenderBatch(mocked_shader) 69 70 # Render without a camera shouldn't cause any effect. 71 render_batch.render(None) 72 assert mocked_shader.bind.call_count == 0 73 74 # Rendering with a camera should cause the shader to be bound and released (even if the batch is empty) 75 mocked_camera = MagicMock() 76 mocked_camera.getWorldTransformation = MagicMock(return_value = Matrix()) 77 mocked_camera.getViewProjectionMatrix = MagicMock(return_value=Matrix()) 78 with patch("UM.View.GL.OpenGLContext.OpenGLContext.properties"): 79 render_batch.render(mocked_camera) 80 assert mocked_shader.bind.call_count == 1 81 assert mocked_shader.release.call_count == 1 82 83 # Actualy render with an item in the batch 84 mb = MeshBuilder() 85 mb.addPyramid(10, 10, 10, color=Color(0.0, 1.0, 0.0, 1.0)) 86 mb.calculateNormals() 87 mesh_data = mb.build() 88 render_batch.addItem(Matrix(), mesh_data, {}) 89 with patch("UM.View.GL.OpenGL.OpenGL.getInstance"): 90 with patch("UM.View.GL.OpenGLContext.OpenGLContext.properties"): 91 render_batch.render(mocked_camera) 92 assert mocked_shader.bind.call_count == 2 93 assert mocked_shader.release.call_count == 2