]> git.tdb.fi Git - libs/gl.git/blob - blender/io_mspgl/export_texture.py
c304fd7e471ffd344da316712db29b984272ed01
[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                         if not tex_node.use_mipmap:
43                                 tex_res.statements.append(Statement("mipmap_levels", 1))
44                         srgb = "_srgb" if colorspace=='sRGB' else ""
45                         tex_res.statements.append(Statement("external_image"+srgb, fn))
46                 else:
47                         if usage=='RGBA':
48                                 fmt = 'SRGB8_ALPHA8' if colorspace=='sRGB' else 'RGBA8'
49                         elif usage=='GRAY':
50                                 fmt = 'LUMINANCE8'
51                         else:
52                                 fmt = 'SRGB8' if colorspace=='sRGB' else 'RGB8'
53
54                         tex_res.statements.append(Statement("storage", Token(fmt), image.size[0], image.size[1]))
55
56                         pixels = tuple(image.pixels)
57                         texdata = ""
58                         if usage=='RGBA':
59                                 texdata = pixels_to_rgba(pixels)
60                         elif usage=='GRAY':
61                                 texdata = pixels_to_gray(pixels)
62                         elif invert_green:
63                                 texdata = pixels_to_rgb_invert_green(pixels)
64                         else:
65                                 texdata = pixels_to_rgb(pixels)
66
67                         data = RawData(image.name+".mdr", bytes(texdata))
68                         tex_res.statements.append(tex_res.create_reference_statement("external_data", data))
69
70                 return tex_res
71
72 class SamplerExporter:
73         def export_sampler(self, tex_node):
74                 from .datafile import Resource, Statement, Token
75                 samp_res = Resource(self.get_sampler_name(tex_node), "sampler")
76
77                 use_interpolation = tex_node.interpolation!='Closest'
78                 if use_interpolation:
79                         if tex_node.use_mipmap:
80                                 samp_res.statements.append(Statement("filter", Token('LINEAR_MIPMAP_LINEAR')))
81                         else:
82                                 samp_res.statements.append(Statement("filter", Token('LINEAR')))
83                         samp_res.statements.append(Statement("max_anisotropy", tex_node.max_anisotropy))
84                 else:
85                         if tex_node.use_mipmap:
86                                 samp_res.statements.append(Statement("filter", Token('NEAREST_MIPMAP_NEAREST')))
87                         else:
88                                 samp_res.statements.append(Statement("filter", Token('NEAREST')))
89
90                 if tex_node.extension=="REPEAT":
91                         samp_res.statements.append(Statement("wrap", Token('REPEAT')))
92                 elif tex_node.extension=="EXTEND":
93                         samp_res.statements.append(Statement("wrap", Token('CLAMP_TO_EDGE')))
94                 elif tex_node.extension=="CLIP":
95                         samp_res.statements.append(Statement("wrap", Token('CLAMP_TO_BORDER')))
96                         samp_res.statements.append(Statement("border_color", 0.0, 0.0, 0.0, 0.0))
97
98                 return samp_res
99
100         def get_sampler_name(self, tex_node):
101                 name_parts = []
102
103                 use_interpolation = tex_node.interpolation!='Closest'
104                 name_parts.append("linear" if use_interpolation else "nearest")
105                 if tex_node.use_mipmap:
106                         name_parts.append("mip")
107                 if use_interpolation and tex_node.max_anisotropy>1:
108                         name_parts.append("aniso{:g}x".format(tex_node.max_anisotropy))
109                 if tex_node.extension!="REPEAT":
110                         name_parts.append("clip" if tex_node.extension=="CLIP" else "clamp")
111
112                 return "_".join(name_parts)+".samp"