]> git.tdb.fi Git - libs/gl.git/blob - blender/io_mspgl/export_texture.py
Check the flat qualifier from the correct member
[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 def pixels_to_single_channel(pixels, channel):
27         for i in range(0, len(pixels), 4):
28                 yield int(pixels[i+channel]*255)
29
30 class TextureExporter:
31         def export_texture(self, tex_node, channels=['R', 'G', 'B']):
32                 image = tex_node.image
33                 from .datafile import RawData, Resource, Statement, Token
34                 tex_res = Resource(self.get_texture_name(tex_node, channels), "texture")
35
36                 tex_res.statements.append(Statement("type", Token("\\2d")))
37
38                 if tex_node.use_mipmap:
39                         tex_res.statements.append(Statement("generate_mipmap", True))
40
41                 from .texture import Texture
42                 texture = Texture(tex_node, channels)
43
44                 invert_mask = sum(1<<i for i, c in enumerate(channels) if c[0]=='~')
45
46                 fn = bpy.path.basename(image.filepath)
47                 native_channels = None
48                 if fn:
49                         abs_path = bpy.path.abspath(image.filepath) 
50                         if os.path.exists(abs_path):
51                                 import imbuf
52                                 native_bpp = imbuf.load(bpy.path.abspath(image.filepath)).planes
53                                 if native_bpp==32:
54                                         native_channels = ['R', 'G', 'B', 'A']
55                                 elif native_bpp==24:
56                                         native_channels = ['R', 'G', 'B']
57                                 elif native_bpp==8:
58                                         native_channels = ['Y']
59
60                 if not invert_mask and channels==native_channels:
61                         if not tex_node.use_mipmap:
62                                 tex_res.statements.append(Statement("mipmap_levels", 1))
63                         srgb = "_srgb" if texture.srgb else ""
64                         tex_res.statements.append(Statement("external_image"+srgb, fn))
65                 else:
66                         tex_res.statements.append(Statement("storage", Token(texture.pixelformat), texture.width, texture.height))
67
68                         pixels = tuple(image.pixels)
69                         texdata = ""
70                         if len(channels)==4:
71                                 texdata = pixels_to_rgba(pixels)
72                         elif len(channels)==1:
73                                 if channels[0]=='Y':
74                                         texdata = pixels_to_gray(pixels)
75                                 else:
76                                         texdata = pixels_to_single_channel(pixels, "RGBA".index(channels[0]))
77                         elif invert_mask:
78                                 texdata = pixels_to_rgb_invert(pixels, invert_mask)
79                         else:
80                                 texdata = pixels_to_rgb(pixels)
81
82                         data = RawData(os.path.splitext(tex_res.name)[0]+".mdr", bytes(texdata))
83                         tex_res.statements.append(tex_res.create_reference_statement("external_data", data))
84
85                 return tex_res
86
87         def get_texture_name(self, tex_node, channels):
88                 image_name = tex_node.image.name
89                 if len(channels)==1 and channels[0]!='Y':
90                         image_name += "_"+channels[0]
91                 return image_name+".tex"
92
93 class SamplerExporter:
94         def export_sampler(self, tex_node):
95                 from .datafile import Resource, Statement, Token
96                 samp_res = Resource(self.get_sampler_name(tex_node), "sampler")
97
98                 use_interpolation = tex_node.interpolation!='Closest'
99                 if use_interpolation:
100                         if tex_node.use_mipmap:
101                                 samp_res.statements.append(Statement("filter", Token('LINEAR_MIPMAP_LINEAR')))
102                         else:
103                                 samp_res.statements.append(Statement("filter", Token('LINEAR')))
104                         samp_res.statements.append(Statement("max_anisotropy", tex_node.max_anisotropy))
105                 else:
106                         if tex_node.use_mipmap:
107                                 samp_res.statements.append(Statement("filter", Token('NEAREST_MIPMAP_NEAREST')))
108                         else:
109                                 samp_res.statements.append(Statement("filter", Token('NEAREST')))
110
111                 if tex_node.extension=="REPEAT":
112                         samp_res.statements.append(Statement("wrap", Token('REPEAT')))
113                 elif tex_node.extension=="EXTEND":
114                         samp_res.statements.append(Statement("wrap", Token('CLAMP_TO_EDGE')))
115                 elif tex_node.extension=="CLIP":
116                         samp_res.statements.append(Statement("wrap", Token('CLAMP_TO_BORDER')))
117                         samp_res.statements.append(Statement("border_color", 0.0, 0.0, 0.0, 0.0))
118
119                 return samp_res
120
121         def get_sampler_name(self, tex_node):
122                 name_parts = []
123
124                 use_interpolation = tex_node.interpolation!='Closest'
125                 name_parts.append("linear" if use_interpolation else "nearest")
126                 if tex_node.use_mipmap:
127                         name_parts.append("mip")
128                 if use_interpolation and tex_node.max_anisotropy>1:
129                         name_parts.append("aniso{:g}x".format(tex_node.max_anisotropy))
130                 if tex_node.extension!="REPEAT":
131                         name_parts.append("clip" if tex_node.extension=="CLIP" else "clamp")
132
133                 return "_".join(name_parts)+".samp"