]> git.tdb.fi Git - libs/gl.git/commitdiff
Support defining uniform values for materials in Blender
authorMikko Rasa <tdb@tdb.fi>
Sun, 28 Mar 2021 11:12:05 +0000 (14:12 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 28 Mar 2021 11:12:05 +0000 (14:12 +0300)
blender/io_mspgl/__init__.py
blender/io_mspgl/export_material.py
blender/io_mspgl/properties.py

index 55661f51130f227f798028b779c8397f06961fef..b5892b1c67abde272a210d384f13ebf83fafaa63 100644 (file)
@@ -172,6 +172,30 @@ class ExportMspGLCamera(bpy.types.Operator, ExportMspGLBase):
                from .export_camera import CameraExporter
                return CameraExporter()
 
+class AddUniform(bpy.types.Operator):
+       bl_idname = "material.add_uniform"
+       bl_label = "Add Uniform"
+       bl_description = "Add a new uniform value to the material"
+
+       def execute(self, context):
+               mat = context.active_object.active_material
+               mat.uniforms.add()
+               mat.active_uniform_index = len(mat.uniforms)-1
+
+               return {"FINISHED"}
+
+class RemoveUniform(bpy.types.Operator):
+       bl_idname = "material.remove_uniform"
+       bl_label = "Remove Uniform"
+       bl_description = "Remove the selected uniform from the material"
+
+       def execute(self, context):
+               mat = context.active_object.active_material
+               mat.uniforms.remove(mat.active_uniform_index)
+               mat.active_uniform_index = min(mat.active_uniform_index, len(mat.uniforms)-1)
+
+               return {"FINISHED"}
+
 def menu_func_export(self, context):
        self.layout.operator(ExportMspGLMesh.bl_idname, text="Msp GL mesh")
        self.layout.operator(ExportMspGLObject.bl_idname, text="Msp GL object")
@@ -180,7 +204,7 @@ def menu_func_export(self, context):
        self.layout.operator(ExportMspGLScene.bl_idname, text="Msp GL scene")
        self.layout.operator(ExportMspGLCamera.bl_idname, text="Msp GL camera")
 
-classes = [ExportMspGLMesh, ExportMspGLObject, ExportMspGLArmature, ExportMspGLAnimation, ExportMspGLScene, ExportMspGLCamera]
+classes = [ExportMspGLMesh, ExportMspGLObject, ExportMspGLArmature, ExportMspGLAnimation, ExportMspGLScene, ExportMspGLCamera, AddUniform, RemoveUniform]
 
 def register():
        for c in classes:
index 5411280d3832596616ace8ea36608fd85e55dedc..c7ca765cb0736c9387c5742b0b9e76a3f0e7c106 100644 (file)
@@ -16,6 +16,12 @@ def create_technique_resource(material, resources):
                        shader += ".shader"
                st.sub.append(Statement("shader", shader))
 
+               if material.uniforms:
+                       ss = Statement("uniforms")
+                       for u in material.uniforms:
+                               ss.sub.append(Statement("uniform", u.name, *u.values[:u.size]))
+                       st.sub.append(ss)
+
        tech_res.statements.append(st)
 
        return tech_res
index df18d444be9819e7d89c3c5446cfc00401fa1a18..baf9ac95c6105c5252e796f326f4d0beccf353fa 100644 (file)
@@ -74,6 +74,22 @@ class MspGLMaterialProperties(bpy.types.Panel):
                        self.layout.prop(mat, "array_layer")
                if mat.render_mode!='EXTERNAL':
                        self.layout.prop(mat, "material_atlas")
+               if mat.render_mode=='CUSTOM':
+                       self.layout.separator()
+                       self.layout.label(text="Uniform values")
+                       self.layout.template_list("MATERIAL_UL_mspgl_uniforms", "", mat, "uniforms", mat, "active_uniform_index")
+                       row = self.layout.row()
+                       row.operator("material.add_uniform")
+                       row.operator("material.remove_uniform")
+
+                       if mat.active_uniform_index<len(mat.uniforms):
+                               uniform = mat.uniforms[mat.active_uniform_index]
+                               self.layout.prop(uniform, "name")
+                               self.layout.prop(uniform, "size")
+                               row = self.layout.row(align=True)
+                               row.label(text="Values")
+                               for i in range(uniform.size):
+                                       row.prop(uniform, "values", text="", index=i)
 
 class MspGLTextureNodeProperties(bpy.types.Panel):
        bl_idname = "NODE_PT_mspgl_properties"
@@ -97,9 +113,28 @@ class MspGLTextureNodeProperties(bpy.types.Panel):
                        self.layout.prop(node, "use_mipmap")
                        self.layout.prop(node, "max_anisotropy")
 
-classes = [MspGLMeshProperties, MspGLObjectProperties, MspGLMaterialProperties, MspGLTextureNodeProperties]
+class MspGLUniform(bpy.types.PropertyGroup):
+       name: bpy.props.StringProperty(name="Name", description="Name of the uniform variable")
+       size: bpy.props.IntProperty(name="Size", description="Number of elements in the uniform", min=1, max=4, default=4)
+       values: bpy.props.FloatVectorProperty(name="Values", description="Values stored in the uniform", size=4)
+
+class MspGLUniformList(bpy.types.UIList):
+       bl_idname = "MATERIAL_UL_mspgl_uniforms"
+
+       def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
+               uniform = item
+               if self.layout_type=="GRID":
+                       layout.label(text="", icon_value=icon)
+               else:
+                       layout.prop(uniform, "name", text="", emboss=False, icon_value=icon)
+                       layout.label(text="({})".format(", ".join("{:.3f}".format(v) for v in uniform.values[:uniform.size])))
+
+classes = [MspGLMeshProperties, MspGLObjectProperties, MspGLMaterialProperties, MspGLTextureNodeProperties, MspGLUniform, MspGLUniformList]
 
 def register_properties():
+       for c in classes:
+               bpy.utils.register_class(c)
+
        bpy.types.Mesh.winding_test = bpy.props.BoolProperty(name="Winding test", description="Perform winding test to skip back faces")
        bpy.types.Mesh.smoothing = bpy.props.EnumProperty(name="Smoothing", description="Smoothing method to use", default="MSPGL",
                items=(("NONE", "None", "No smoothing"),
@@ -128,14 +163,13 @@ def register_properties():
        bpy.types.Material.array_atlas = bpy.props.BoolProperty(name="Texture array atlas", description="The material is stored in a texture array")
        bpy.types.Material.array_layer = bpy.props.IntProperty("Texture array layer", description="Layer of the texture array atlas to use")
        bpy.types.Material.material_atlas = bpy.props.BoolProperty(name="Material atlas", description="Make this material part of a material atlas")
+       bpy.types.Material.uniforms = bpy.props.CollectionProperty(type=MspGLUniform, name="Uniform", description="Uniform variables to add to the technique")
+       bpy.types.Material.active_uniform_index = bpy.props.IntProperty("Active uniform index")
 
        bpy.types.ShaderNodeTexImage.default_filter = bpy.props.BoolProperty(name="Default filter", description="Let the loading program determine filtering options")
        bpy.types.ShaderNodeTexImage.use_mipmap = bpy.props.BoolProperty(name="Use mipmaps", description="Use mipmaps (automatically generated) for the texture", default=True)
        bpy.types.ShaderNodeTexImage.max_anisotropy = bpy.props.FloatProperty(name="Maximum anisotropy", description="Maximum anisotropy to use in texture filtering", min=1, max=16, default=1)
 
-       for c in classes:
-               bpy.utils.register_class(c)
-
 def unregister_properties():
        for c in classes:
                bpy.utils.unregister_class(c)