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