diff --git a/doc/python/magnum.shaders.rst b/doc/python/magnum.shaders.rst index 365b127..c0fbafc 100644 --- a/doc/python/magnum.shaders.rst +++ b/doc/python/magnum.shaders.rst @@ -47,3 +47,20 @@ :raise ValueError: If list length is different from `light_count` .. py:property:: magnum.shaders.Phong.light_colors :raise ValueError: If list length is different from `light_count` + +.. py:function:: magnum.shaders.Phong.bind_ambient_texture + :raise AttributeError: If the shader was not created with + `Flags.AMBIENT_TEXTURE` +.. py:function:: magnum.shaders.Phong.bind_diffuse_texture + :raise AttributeError: If the shader was not created with + `Flags.DIFFUSE_TEXTURE` +.. py:function:: magnum.shaders.Phong.bind_specular_texture + :raise AttributeError: If the shader was not created with + `Flags.SPECULAR_TEXTURE` +.. py:function:: magnum.shaders.Phong.bind_normal_texture + :raise AttributeError: If the shader was not created with + `Flags.NORMAL_TEXTURE` +.. py:function:: magnum.shaders.Phong.bind_textures + :raise AttributeError: If the shader was not created with any of + `Flags.AMBIENT_TEXTURE`, `Flags.DIFFUSE_TEXTURE`, + `Flags.SPECULAR_TEXTURE` or `Flags.NORMAL_TEXTURE` diff --git a/src/python/magnum/shaders.cpp b/src/python/magnum/shaders.cpp index 6d12da7..8a5a616 100644 --- a/src/python/magnum/shaders.cpp +++ b/src/python/magnum/shaders.cpp @@ -26,6 +26,7 @@ #include #include /* for vector arguments */ #include +#include #include #include @@ -116,7 +117,6 @@ void shaders(py::module& m) { &Shaders::Phong::setDiffuseColor, "Diffuse color") .def_property("specular_color", nullptr, &Shaders::Phong::setSpecularColor, "Specular color") - // TODO: textures, once exposed .def_property("shininess", nullptr, &Shaders::Phong::setShininess, "Shininess") .def_property("alpha_mask", nullptr, [](Shaders::Phong& self, Float mask) { @@ -148,7 +148,49 @@ void shaders(py::module& m) { } self.setLightColors(colors); - }, "Light colors"); + }, "Light colors") + + .def("bind_ambient_texture", [](Shaders::Phong& self, GL::Texture2D& texture) { + if(!(self.flags() & Shaders::Phong::Flag::AmbientTexture)) { + PyErr_SetString(PyExc_AttributeError, "the shader was not created with ambient texture enabled"); + throw py::error_already_set{}; + } + + self.bindAmbientTexture(texture); + }, "Bind an ambient texture") + .def("bind_diffuse_texture", [](Shaders::Phong& self, GL::Texture2D& texture) { + if(!(self.flags() & Shaders::Phong::Flag::DiffuseTexture)) { + PyErr_SetString(PyExc_AttributeError, "the shader was not created with diffuse texture enabled"); + throw py::error_already_set{}; + } + + self.bindDiffuseTexture(texture); + }, "Bind a diffuse texture") + .def("bind_specular_texture", [](Shaders::Phong& self, GL::Texture2D& texture) { + if(!(self.flags() & Shaders::Phong::Flag::SpecularTexture)) { + PyErr_SetString(PyExc_AttributeError, "the shader was not created with specular texture enabled"); + throw py::error_already_set{}; + } + + self.bindSpecularTexture(texture); + }, "Bind a specular texture") + .def("bind_normal_texture", [](Shaders::Phong& self, GL::Texture2D& texture) { + 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.bindNormalTexture(texture); + }, "Bind a normal texture") + .def("bind_textures", [](Shaders::Phong& self, GL::Texture2D* ambient, GL::Texture2D* diffuse, GL::Texture2D* specular, GL::Texture2D* normal) { + if(!(self.flags() & (Shaders::Phong::Flag::AmbientTexture|Shaders::Phong::Flag::DiffuseTexture|Shaders::Phong::Flag::SpecularTexture|Shaders::Phong::Flag::NormalTexture))) { + PyErr_SetString(PyExc_AttributeError, "the shader was not created with any textures enabled"); + throw py::error_already_set{}; + } + + self.bindTextures(ambient, diffuse, specular, normal); + }, "Bind textures", py::arg("ambient") = nullptr, py::arg("diffuse") = nullptr, py::arg("specular") = nullptr, py::arg("normal") = nullptr) + ; } } diff --git a/src/python/magnum/test/test_shaders_gl.py b/src/python/magnum/test/test_shaders_gl.py index 6cd2d39..c3e94ab 100644 --- a/src/python/magnum/test/test_shaders_gl.py +++ b/src/python/magnum/test/test_shaders_gl.py @@ -30,7 +30,7 @@ import unittest from . import GLTestCase, setUpModule from magnum import * -from magnum import shaders +from magnum import gl, shaders class VertexColor(GLTestCase): def test_init(self): @@ -57,8 +57,8 @@ class Phong(GLTestCase): self.assertEqual(c.flags, shaders.Phong.Flags.NONE) self.assertEqual(c.light_count, 3) - def test_uniforms(self): - a = shaders.Phong(shaders.Phong.Flags.ALPHA_MASK, 2) + 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.diffuse_color = (0.5, 1.0, 0.9) a.transformation_matrix = Matrix4.translation(Vector3.x_axis()) a.projection_matrix = Matrix4.zero_init() @@ -66,7 +66,15 @@ class Phong(GLTestCase): a.light_colors = [Color4(), Color4()] a.alpha_mask = 0.3 - def test_uniforms_errors(self): + texture = gl.Texture2D() + texture.set_storage(1, gl.TextureFormat.RGBA8, Vector2i(8)) + a.bind_ambient_texture(texture) + a.bind_diffuse_texture(texture) + a.bind_specular_texture(texture) + a.bind_normal_texture(texture) + a.bind_textures(ambient=texture, diffuse=texture, specular=texture, normal=texture) + + def test_uniforms_bindings_errors(self): a = shaders.Phong() with self.assertRaisesRegex(AttributeError, "the shader was not created with alpha mask enabled"): a.alpha_mask = 0.3 @@ -74,3 +82,15 @@ class Phong(GLTestCase): a.light_positions = [] with self.assertRaisesRegex(ValueError, "expected 1 items but got 0"): a.light_colors = [] + + texture = gl.Texture2D() + with self.assertRaisesRegex(AttributeError, "the shader was not created with ambient texture enabled"): + a.bind_ambient_texture(texture) + with self.assertRaisesRegex(AttributeError, "the shader was not created with diffuse texture enabled"): + a.bind_diffuse_texture(texture) + with self.assertRaisesRegex(AttributeError, "the shader was not created with specular texture enabled"): + a.bind_specular_texture(texture) + with self.assertRaisesRegex(AttributeError, "the shader was not created with normal texture enabled"): + a.bind_normal_texture(texture) + with self.assertRaisesRegex(AttributeError, "the shader was not created with any textures enabled"): + a.bind_textures(diffuse=texture)