Browse Source

python: expose new shaders.Phong features.

pull/10/head
Vladimír Vondruš 6 years ago
parent
commit
0f98d2f172
  1. 13
      doc/python/magnum.shaders.rst
  2. 2
      doc/python/pages/changelog.rst
  3. 51
      src/python/magnum/shaders.cpp
  4. 14
      src/python/magnum/test/test_shaders_gl.py

13
doc/python/magnum.shaders.rst

@ -63,17 +63,30 @@
:data POSITION: Vertex position :data POSITION: Vertex position
:data NORMAL: Normal direction :data NORMAL: Normal direction
:data TANGENT: Tangent direction :data TANGENT: Tangent direction
:data TANGENT4: Tangent direction with a bitangent sign
:data BITANGENT: Bitangent direction
:data TEXTURE_COORDINATES: 2D texture coordinates :data TEXTURE_COORDINATES: 2D texture coordinates
:data COLOR3: Three-component vertex color :data COLOR3: Three-component vertex color
:data COLOR4: Four-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 .. py:property:: magnum.shaders.Phong.alpha_mask
:raise AttributeError: If the shader was not created with :raise AttributeError: If the shader was not created with
:ref:`Flags.ALPHA_MASK` :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 .. py:property:: magnum.shaders.Phong.light_positions
:raise ValueError: If list length is different from :ref:`light_count` :raise ValueError: If list length is different from :ref:`light_count`
.. py:property:: magnum.shaders.Phong.light_colors .. py:property:: magnum.shaders.Phong.light_colors
:raise ValueError: If list length is different from :ref:`light_count` :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 .. py:function:: magnum.shaders.Phong.bind_ambient_texture
:raise AttributeError: If the shader was not created with :raise AttributeError: If the shader was not created with

2
doc/python/pages/changelog.rst

@ -39,6 +39,8 @@ Changelog
:ref:`gl.Renderer.set_blend_equation()` and related enums (:gh:`mosra/magnum-bindings#9`) :ref:`gl.Renderer.set_blend_equation()` and related enums (:gh:`mosra/magnum-bindings#9`)
- Exposed :ref:`gl.Renderer.Feature.CLIP_DISTANCEn <gl.Renderer.Feature.CLIP_DISTANCE0>` - Exposed :ref:`gl.Renderer.Feature.CLIP_DISTANCEn <gl.Renderer.Feature.CLIP_DISTANCE0>`
values that are new since 2020.06 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 - Renamed all helper ``Python.h`` headers to ``PythonBindings.h`` to avoid
issues with shitty IDE indexers such as Eclipse, confusing these with issues with shitty IDE indexers such as Eclipse, confusing these with
Python's ``<Python.h>`` Python's ``<Python.h>``

51
src/python/magnum/shaders.cpp

@ -162,9 +162,16 @@ void shaders(py::module& m) {
phong.attr("POSITION") = GL::DynamicAttribute{Shaders::Phong::Position{}}; phong.attr("POSITION") = GL::DynamicAttribute{Shaders::Phong::Position{}};
phong.attr("NORMAL") = GL::DynamicAttribute{Shaders::Phong::Normal{}}; phong.attr("NORMAL") = GL::DynamicAttribute{Shaders::Phong::Normal{}};
phong.attr("TANGENT") = GL::DynamicAttribute{Shaders::Phong::Tangent{}}; 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("TEXTURE_COORDINATES") = GL::DynamicAttribute{Shaders::Phong::TextureCoordinates{}};
phong.attr("COLOR3") = GL::DynamicAttribute{Shaders::Phong::Color3{}}; phong.attr("COLOR3") = GL::DynamicAttribute{Shaders::Phong::Color3{}};
phong.attr("COLOR4") = GL::DynamicAttribute{Shaders::Phong::Color4{}}; 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_<Shaders::Phong::Flag> flags{phong, "Flags", "Flags"}; py::enum_<Shaders::Phong::Flag> flags{phong, "Flags", "Flags"};
@ -175,8 +182,12 @@ void shaders(py::module& m) {
.value("NORMAL_TEXTURE", Shaders::Phong::Flag::NormalTexture) .value("NORMAL_TEXTURE", Shaders::Phong::Flag::NormalTexture)
.value("ALPHA_MASK", Shaders::Phong::Flag::AlphaMask) .value("ALPHA_MASK", Shaders::Phong::Flag::AlphaMask)
.value("VERTEX_COLOR", Shaders::Phong::Flag::VertexColor) .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 */ /* 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); corrade::enumOperators(flags);
@ -197,6 +208,14 @@ void shaders(py::module& m) {
&Shaders::Phong::setSpecularColor, "Specular color") &Shaders::Phong::setSpecularColor, "Specular color")
.def_property("shininess", nullptr, .def_property("shininess", nullptr,
&Shaders::Phong::setShininess, "Shininess") &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) { .def_property("alpha_mask", nullptr, [](Shaders::Phong& self, Float mask) {
if(!(self.flags() & Shaders::Phong::Flag::AlphaMask)) { if(!(self.flags() & Shaders::Phong::Flag::AlphaMask)) {
PyErr_SetString(PyExc_AttributeError, "the shader was not created with alpha mask enabled"); 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); self.setAlphaMask(mask);
}, "Alpha mask") }, "Alpha mask")
.def_property("transformation_matrix", nullptr, .def_property("transformation_matrix", nullptr,
&Shaders::Phong::setTransformationMatrix, "Set transformation matrix") &Shaders::Phong::setTransformationMatrix, "Transformation matrix")
.def_property("normal_matrix", nullptr, .def_property("normal_matrix", nullptr,
&Shaders::Phong::setNormalMatrix, "Set normal matrix") &Shaders::Phong::setNormalMatrix, "Normal matrix")
.def_property("projection_matrix", nullptr, .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<Vector4>& positions) { .def_property("light_positions", nullptr, [](Shaders::Phong& self, const std::vector<Vector4>& positions) {
if(positions.size() != self.lightCount()) { if(positions.size() != self.lightCount()) {
PyErr_Format(PyExc_ValueError, "expected %u items but got %u", self.lightCount(), UnsignedInt(positions.size())); 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); self.setLightColors(colors);
}, "Light colors") }, "Light colors")
.def_property("light_specular_colors", nullptr, [](Shaders::Phong& self, const std::vector<Color3>& 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<Float>& 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) { .def("bind_ambient_texture", [](Shaders::Phong& self, GL::Texture2D& texture) {
if(!(self.flags() & Shaders::Phong::Flag::AmbientTexture)) { if(!(self.flags() & Shaders::Phong::Flag::AmbientTexture)) {

14
src/python/magnum/test/test_shaders_gl.py

@ -85,13 +85,17 @@ class Phong(GLTestCase):
self.assertEqual(c.light_count, 3) self.assertEqual(c.light_count, 3)
def test_uniforms_bindings(self): 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.diffuse_color = (0.5, 1.0, 0.9)
a.transformation_matrix = Matrix4.translation(Vector3.x_axis()) a.transformation_matrix = Matrix4.translation(Vector3.x_axis())
a.projection_matrix = Matrix4.zero_init() a.projection_matrix = Matrix4.zero_init()
a.light_positions = [(0.5, 1.0, 0.3, 1.0), Vector4()] a.light_positions = [(0.5, 1.0, 0.3, 1.0), Vector4()]
a.light_colors = [Color3(), Color3()] 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.alpha_mask = 0.3
a.texture_matrix = Matrix3()
texture = gl.Texture2D() texture = gl.Texture2D()
texture.set_storage(1, gl.TextureFormat.RGBA8, Vector2i(8)) texture.set_storage(1, gl.TextureFormat.RGBA8, Vector2i(8))
@ -103,12 +107,20 @@ class Phong(GLTestCase):
def test_uniforms_bindings_errors(self): def test_uniforms_bindings_errors(self):
a = shaders.Phong() 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"): with self.assertRaisesRegex(AttributeError, "the shader was not created with alpha mask enabled"):
a.alpha_mask = 0.3 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"): with self.assertRaisesRegex(ValueError, "expected 1 items but got 0"):
a.light_positions = [] a.light_positions = []
with self.assertRaisesRegex(ValueError, "expected 1 items but got 0"): with self.assertRaisesRegex(ValueError, "expected 1 items but got 0"):
a.light_colors = [] 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() texture = gl.Texture2D()
with self.assertRaisesRegex(AttributeError, "the shader was not created with ambient texture enabled"): with self.assertRaisesRegex(AttributeError, "the shader was not created with ambient texture enabled"):

Loading…
Cancel
Save