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