]> git.tdb.fi Git - libs/gl.git/blob - blender/io_mspgl/export_texture.py
Remove unnecessary import statements from the Blender exporter
[libs/gl.git] / blender / io_mspgl / export_texture.py
1 import os
2 import bpy
3
4 def pixels_to_rgba(pixels):
5         return (int(p*255) for p in pixels)
6
7 def pixels_to_rgb(pixels):
8         for i in range(0, len(pixels), 4):
9                 yield int(pixels[i]*255)
10                 yield int(pixels[i+1]*255)
11                 yield int(pixels[i+2]*255)
12
13 def pixels_to_rgb_invert(pixels, mask):
14         for i in range(0, len(pixels), 4):
15                 r = int(pixels[i]*255)
16                 yield 255-r if mask&1 else r
17                 g = int(pixels[i+1]*255)
18                 yield 255-g if mask&2 else g
19                 b = int(pixels[i+2]*255)
20                 yield 255-b if mask&4 else b
21
22 def pixels_to_gray(pixels):
23         for i in range(0, len(pixels), 4):
24                 yield int((pixels[i]+pixels[i+1]+pixels[i+2])*255/3)
25
26 class TextureExporter:
27         def export_texture(self, tex_node, channels=['R', 'G', 'B']):
28                 image = tex_node.image
29                 from .datafile import RawData, Resource, Statement, Token
30                 tex_res = Resource(image.name+".tex", "texture")
31
32                 tex_res.statements.append(Statement("type", Token("\\2d")))
33
34                 if tex_node.use_mipmap:
35                         tex_res.statements.append(Statement("generate_mipmap", True))
36
37                 colorspace = image.colorspace_settings.name
38                 if len(channels)==1 and colorspace=='sRGB':
39                         raise Exception("Unsupported configuration on texture {}: Grayscale with sRGB".format(image.name))
40
41                 invert_mask = sum(1<<i for i, c in enumerate(channels) if c[0]=='~')
42
43                 fn = bpy.path.basename(image.filepath)
44                 if not invert_mask and fn:
45                         if not tex_node.use_mipmap:
46                                 tex_res.statements.append(Statement("mipmap_levels", 1))
47                         srgb = "_srgb" if colorspace=='sRGB' else ""
48                         tex_res.statements.append(Statement("external_image"+srgb, fn))
49                 else:
50                         if len(channels)==4:
51                                 fmt = 'SRGB8_ALPHA8' if colorspace=='sRGB' else 'RGBA8'
52                         elif len(channels)==1:
53                                 fmt = 'LUMINANCE8'
54                         else:
55                                 fmt = 'SRGB8' if colorspace=='sRGB' else 'RGB8'
56
57                         tex_res.statements.append(Statement("storage", Token(fmt), image.size[0], image.size[1]))
58
59                         pixels = tuple(image.pixels)
60                         texdata = ""
61                         if len(channels)==4:
62                                 texdata = pixels_to_rgba(pixels)
63                         elif len(channels)==1:
64                                 texdata = pixels_to_gray(pixels)
65                         elif invert_mask:
66                                 texdata = pixels_to_rgb_invert(pixels, invert_mask)
67                         else:
68                                 texdata = pixels_to_rgb(pixels)
69
70                         data = RawData(image.name+".mdr", bytes(texdata))
71                         tex_res.statements.append(tex_res.create_reference_statement("external_data", data))
72
73                 return tex_res
74
75 class SamplerExporter:
76         def export_sampler(self, tex_node):
77                 from .datafile import Resource, Statement, Token
78                 samp_res = Resource(self.get_sampler_name(tex_node), "sampler")
79
80                 use_interpolation = tex_node.interpolation!='Closest'
81                 if use_interpolation:
82                         if tex_node.use_mipmap:
83                                 samp_res.statements.append(Statement("filter", Token('LINEAR_MIPMAP_LINEAR')))
84                         else:
85                                 samp_res.statements.append(Statement("filter", Token('LINEAR')))
86                         samp_res.statements.append(Statement("max_anisotropy", tex_node.max_anisotropy))
87                 else:
88                         if tex_node.use_mipmap:
89                                 samp_res.statements.append(Statement("filter", Token('NEAREST_MIPMAP_NEAREST')))
90                         else:
91                                 samp_res.statements.append(Statement("filter", Token('NEAREST')))
92
93                 if tex_node.extension=="REPEAT":
94                         samp_res.statements.append(Statement("wrap", Token('REPEAT')))
95                 elif tex_node.extension=="EXTEND":
96                         samp_res.statements.append(Statement("wrap", Token('CLAMP_TO_EDGE')))
97                 elif tex_node.extension=="CLIP":
98                         samp_res.statements.append(Statement("wrap", Token('CLAMP_TO_BORDER')))
99                         samp_res.statements.append(Statement("border_color", 0.0, 0.0, 0.0, 0.0))
100
101                 return samp_res
102
103         def get_sampler_name(self, tex_node):
104                 name_parts = []
105
106                 use_interpolation = tex_node.interpolation!='Closest'
107                 name_parts.append("linear" if use_interpolation else "nearest")
108                 if tex_node.use_mipmap:
109                         name_parts.append("mip")
110                 if use_interpolation and tex_node.max_anisotropy>1:
111                         name_parts.append("aniso{:g}x".format(tex_node.max_anisotropy))
112                 if tex_node.extension!="REPEAT":
113                         name_parts.append("clip" if tex_node.extension=="CLIP" else "clamp")
114
115                 return "_".join(name_parts)+".samp"