From 0f98d2f1724c681195b23f1a9c2db3935aa42689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 6 Oct 2020 13:38:24 +0200 Subject: [PATCH] python: expose new shaders.Phong features. --- doc/python/magnum.shaders.rst | 13 ++++++ doc/python/pages/changelog.rst | 2 + src/python/magnum/shaders.cpp | 51 +++++++++++++++++++++-- src/python/magnum/test/test_shaders_gl.py | 14 ++++++- 4 files changed, 75 insertions(+), 5 deletions(-) diff --git a/doc/python/magnum.shaders.rst b/doc/python/magnum.shaders.rst index f81dcaf..53ff027 100644 --- a/doc/python/magnum.shaders.rst +++ b/doc/python/magnum.shaders.rst @@ -63,17 +63,30 @@ :data POSITION: Vertex position :data NORMAL: Normal direction :data TANGENT: Tangent direction + :data TANGENT4: Tangent direction with a bitangent sign + :data BITANGENT: Bitangent direction :data TEXTURE_COORDINATES: 2D texture coordinates :data COLOR3: Three-component vertex color :data COLOR4: Four-component vertex color + :data TRANSFORMATION_MATRIX: (Instanced) transformation matrix + :data NORMAL_MATRIX: (Instanced) normal matrix + :data TEXTURE_OFFSET: (Instanced) texture offset +.. py:property:: magnum.shaders.Phong.normal_texture_scale + :raise AttributeError: If the shader was not created with + :ref:`Flags.NORMAL_TEXTURE` .. py:property:: magnum.shaders.Phong.alpha_mask :raise AttributeError: If the shader was not created with :ref:`Flags.ALPHA_MASK` +.. py:property:: magnum.shaders.Phong.texture_matrix + :raise AttributeError: If the shader was not created with + :ref:`Flags.TEXTURE_TRANSFORMATION` .. py:property:: magnum.shaders.Phong.light_positions :raise ValueError: If list length is different from :ref:`light_count` .. py:property:: magnum.shaders.Phong.light_colors :raise ValueError: If list length is different from :ref:`light_count` +.. py:property:: magnum.shaders.Phong.light_ranges + :raise ValueError: If list length is different from :ref:`light_count` .. py:function:: magnum.shaders.Phong.bind_ambient_texture :raise AttributeError: If the shader was not created with diff --git a/doc/python/pages/changelog.rst b/doc/python/pages/changelog.rst index b9beb35..bffd4d7 100644 --- a/doc/python/pages/changelog.rst +++ b/doc/python/pages/changelog.rst @@ -39,6 +39,8 @@ Changelog :ref:`gl.Renderer.set_blend_equation()` and related enums (:gh:`mosra/magnum-bindings#9`) - Exposed :ref:`gl.Renderer.Feature.CLIP_DISTANCEn ` values that are new since 2020.06 +- Exposed new instancing, normal-mapping-related and lighting features in + :ref:`shaders.Phong` - Renamed all helper ``Python.h`` headers to ``PythonBindings.h`` to avoid issues with shitty IDE indexers such as Eclipse, confusing these with Python's ```` diff --git a/src/python/magnum/shaders.cpp b/src/python/magnum/shaders.cpp index 17e6721..1e782b4 100644 --- a/src/python/magnum/shaders.cpp +++ b/src/python/magnum/shaders.cpp @@ -162,9 +162,16 @@ void shaders(py::module& m) { phong.attr("POSITION") = GL::DynamicAttribute{Shaders::Phong::Position{}}; phong.attr("NORMAL") = GL::DynamicAttribute{Shaders::Phong::Normal{}}; phong.attr("TANGENT") = GL::DynamicAttribute{Shaders::Phong::Tangent{}}; + phong.attr("TANGENT4") = GL::DynamicAttribute{Shaders::Phong::Tangent4{}}; + phong.attr("BITANGENT") = GL::DynamicAttribute{Shaders::Phong::Bitangent{}}; phong.attr("TEXTURE_COORDINATES") = GL::DynamicAttribute{Shaders::Phong::TextureCoordinates{}}; phong.attr("COLOR3") = GL::DynamicAttribute{Shaders::Phong::Color3{}}; phong.attr("COLOR4") = GL::DynamicAttribute{Shaders::Phong::Color4{}}; + /* TODO: OBJECT_ID attribute, once multiple FB outputs and mapDraw is + exposed */ + phong.attr("TRANSFORMATION_MATRIX") = GL::DynamicAttribute{Shaders::Phong::TransformationMatrix{}}; + phong.attr("NORMAL_MATRIX") = GL::DynamicAttribute{Shaders::Phong::NormalMatrix{}}; + phong.attr("TEXTURE_OFFSET") = GL::DynamicAttribute{Shaders::Phong::TextureOffset{}}; py::enum_ flags{phong, "Flags", "Flags"}; @@ -175,8 +182,12 @@ void shaders(py::module& m) { .value("NORMAL_TEXTURE", Shaders::Phong::Flag::NormalTexture) .value("ALPHA_MASK", Shaders::Phong::Flag::AlphaMask) .value("VERTEX_COLOR", Shaders::Phong::Flag::VertexColor) - .value("NONE", Shaders::Phong::Flag{}) + .value("BITANGENT", Shaders::Phong::Flag::Bitangent) + .value("TEXTURE_TRANSFORMATION", Shaders::Phong::Flag::TextureTransformation) /* TODO: OBJECT_ID, once multiple FB outputs and mapDraw is exposed */ + .value("INSTANCED_TRANSFORMATION", Shaders::Phong::Flag::InstancedTransformation) + .value("INSTANCED_TEXTURE_OFFSET", Shaders::Phong::Flag::InstancedTextureOffset) + .value("NONE", Shaders::Phong::Flag{}) ; corrade::enumOperators(flags); @@ -197,6 +208,14 @@ void shaders(py::module& m) { &Shaders::Phong::setSpecularColor, "Specular color") .def_property("shininess", nullptr, &Shaders::Phong::setShininess, "Shininess") + .def_property("normal_texture_scale", nullptr, [](Shaders::Phong& self, Float scale) { + if(!(self.flags() & Shaders::Phong::Flag::NormalTexture)) { + PyErr_SetString(PyExc_AttributeError, "the shader was not created with normal texture enabled"); + throw py::error_already_set{}; + } + + self.setNormalTextureScale(scale); + }, "Normal texture scale") .def_property("alpha_mask", nullptr, [](Shaders::Phong& self, Float mask) { if(!(self.flags() & Shaders::Phong::Flag::AlphaMask)) { PyErr_SetString(PyExc_AttributeError, "the shader was not created with alpha mask enabled"); @@ -206,11 +225,19 @@ void shaders(py::module& m) { self.setAlphaMask(mask); }, "Alpha mask") .def_property("transformation_matrix", nullptr, - &Shaders::Phong::setTransformationMatrix, "Set transformation matrix") + &Shaders::Phong::setTransformationMatrix, "Transformation matrix") .def_property("normal_matrix", nullptr, - &Shaders::Phong::setNormalMatrix, "Set normal matrix") + &Shaders::Phong::setNormalMatrix, "Normal matrix") .def_property("projection_matrix", nullptr, - &Shaders::Phong::setProjectionMatrix, "Set projection matrix") + &Shaders::Phong::setProjectionMatrix, "Projection matrix") + .def_property("texture_matrix", nullptr, [](Shaders::Phong& self, const Matrix3& matrix) { + if(!(self.flags() & Shaders::Phong::Flag::TextureTransformation)) { + PyErr_SetString(PyExc_AttributeError, "the shader was not created with texture transformation enabled"); + throw py::error_already_set{}; + } + + self.setTextureMatrix(matrix); + }, "Texture matrix") .def_property("light_positions", nullptr, [](Shaders::Phong& self, const std::vector& positions) { if(positions.size() != self.lightCount()) { PyErr_Format(PyExc_ValueError, "expected %u items but got %u", self.lightCount(), UnsignedInt(positions.size())); @@ -227,6 +254,22 @@ void shaders(py::module& m) { self.setLightColors(colors); }, "Light colors") + .def_property("light_specular_colors", nullptr, [](Shaders::Phong& self, const std::vector& colors) { + if(colors.size() != self.lightCount()) { + PyErr_Format(PyExc_ValueError, "expected %u items but got %u", self.lightCount(), UnsignedInt(colors.size())); + throw py::error_already_set{}; + } + + self.setLightSpecularColors(colors); + }, "Light specular colors") + .def_property("light_ranges", nullptr, [](Shaders::Phong& self, const std::vector& ranges) { + if(ranges.size() != self.lightCount()) { + PyErr_Format(PyExc_ValueError, "expected %u items but got %u", self.lightCount(), UnsignedInt(ranges.size())); + throw py::error_already_set{}; + } + + self.setLightRanges(ranges); + }, "Light ranges") .def("bind_ambient_texture", [](Shaders::Phong& self, GL::Texture2D& texture) { if(!(self.flags() & Shaders::Phong::Flag::AmbientTexture)) { diff --git a/src/python/magnum/test/test_shaders_gl.py b/src/python/magnum/test/test_shaders_gl.py index 09bcf9f..88f85b2 100644 --- a/src/python/magnum/test/test_shaders_gl.py +++ b/src/python/magnum/test/test_shaders_gl.py @@ -85,13 +85,17 @@ class Phong(GLTestCase): self.assertEqual(c.light_count, 3) def test_uniforms_bindings(self): - a = shaders.Phong(shaders.Phong.Flags.ALPHA_MASK|shaders.Phong.Flags.AMBIENT_TEXTURE|shaders.Phong.Flags.DIFFUSE_TEXTURE|shaders.Phong.Flags.SPECULAR_TEXTURE|shaders.Phong.Flags.NORMAL_TEXTURE, 2) + a = shaders.Phong(shaders.Phong.Flags.ALPHA_MASK|shaders.Phong.Flags.AMBIENT_TEXTURE|shaders.Phong.Flags.DIFFUSE_TEXTURE|shaders.Phong.Flags.SPECULAR_TEXTURE|shaders.Phong.Flags.NORMAL_TEXTURE|shaders.Phong.Flags.TEXTURE_TRANSFORMATION, 2) a.diffuse_color = (0.5, 1.0, 0.9) a.transformation_matrix = Matrix4.translation(Vector3.x_axis()) a.projection_matrix = Matrix4.zero_init() a.light_positions = [(0.5, 1.0, 0.3, 1.0), Vector4()] a.light_colors = [Color3(), Color3()] + a.light_specular_colors = [Color3(), Color3()] + a.light_ranges = [0.5, 100] + a.normal_texture_scale = 0.3 a.alpha_mask = 0.3 + a.texture_matrix = Matrix3() texture = gl.Texture2D() texture.set_storage(1, gl.TextureFormat.RGBA8, Vector2i(8)) @@ -103,12 +107,20 @@ class Phong(GLTestCase): def test_uniforms_bindings_errors(self): a = shaders.Phong() + with self.assertRaisesRegex(AttributeError, "the shader was not created with normal texture enabled"): + a.normal_texture_scale = 0.3 with self.assertRaisesRegex(AttributeError, "the shader was not created with alpha mask enabled"): a.alpha_mask = 0.3 + with self.assertRaisesRegex(AttributeError, "the shader was not created with texture transformation enabled"): + a.texture_matrix = Matrix3() with self.assertRaisesRegex(ValueError, "expected 1 items but got 0"): a.light_positions = [] with self.assertRaisesRegex(ValueError, "expected 1 items but got 0"): a.light_colors = [] + with self.assertRaisesRegex(ValueError, "expected 1 items but got 0"): + a.light_specular_colors = [] + with self.assertRaisesRegex(ValueError, "expected 1 items but got 0"): + a.light_ranges = [] texture = gl.Texture2D() with self.assertRaisesRegex(AttributeError, "the shader was not created with ambient texture enabled"):