UNPKG

4.04 kBPlain TextView Raw
1#!/usr/bin/python
2
3from optparse import OptionParser
4import json
5import re
6import sys
7
8
9
10ESCAPE_SEQUENCE = {
11 '\\': '\\\\',
12 '\n': '\\n',
13 '\t': '\\t'
14 }
15
16
17def js_escape(s):
18 return ''.join(ESCAPE_SEQUENCE.get(c, c) for c in s)
19
20
21def glsl_compress(s, shortNames):
22 # strip leading whitespace
23 s = re.sub(r'\A\s+', '', s)
24 # strip trailing whitespace
25 s = re.sub(r'\s+\Z', '', s)
26 # strip multi-line comments
27 s = re.sub(r'/\*.*?\*/', '', s)
28 # strip single line comments
29 s = re.sub(r'//.*?\n', '', s)
30 # replace multiple whitespace with a single space
31 s = re.sub(r'\s+', ' ', s)
32 # remove whitespace between non-word tokens
33 s = re.sub(r'(\S)\s+([^\w])', r'\1\2', s)
34 s = re.sub(r'([^\w])\s+(\S)', r'\1\2', s)
35 # replace original names with short names
36 for originalName, shortName in shortNames.items():
37 s = s.replace(originalName, shortName)
38 return s
39
40
41def main(argv):
42 option_parser = OptionParser()
43 option_parser.add_option('--input')
44 option_parser.add_option('--output')
45 options, args = option_parser.parse_args(argv[1:])
46
47 context = {}
48 nextShortName = ord('a')
49 shortNames = {}
50
51 common, vertex, fragment = [], [], []
52 attributes, uniforms, varyings = {}, {}, {}
53 block = None
54 for line in open(options.input, 'rU'):
55 if line.startswith('//!'):
56 m = re.match(r'//!\s+NAMESPACE=(\S+)\s*\Z', line)
57 if m:
58 context['namespace'] = m.group(1)
59 continue
60 m = re.match(r'//!\s+CLASS=(\S+)\s*\Z', line)
61 if m:
62 context['className'] = m.group(1)
63 continue
64 m = re.match(r'//!\s+COMMON\s*\Z', line)
65 if m:
66 block = common
67 continue
68 m = re.match(r'//!\s+VERTEX\s*\Z', line)
69 if m:
70 block = vertex
71 continue
72 m = re.match(r'//!\s+FRAGMENT\s*\Z', line)
73 if m:
74 block = fragment
75 continue
76 else:
77 if block is None:
78 assert line.rstrip() == ''
79 else:
80 block.append(line)
81 m = re.match(r'attribute\s+\S+\s+(\S+);\s*\Z', line)
82 if m:
83 attribute = m.group(1)
84 if attribute not in attributes:
85 shortName = chr(nextShortName)
86 nextShortName += 1
87 attributes[attribute] = {'originalName': attribute, 'shortName': shortName}
88 shortNames[attribute] = shortName
89 m = re.match(r'uniform\s+\S+\s+(\S+);\s*\Z', line)
90 if m:
91 uniform = m.group(1)
92 if uniform not in uniforms:
93 shortName = chr(nextShortName)
94 nextShortName += 1
95 uniforms[uniform] = {'originalName': uniform, 'shortName': shortName}
96 shortNames[uniform] = shortName
97 m = re.match(r'varying\s+\S+\s+(\S+);\s*\Z', line)
98 if m:
99 varying = m.group(1)
100 if varying not in varyings:
101 shortName = chr(nextShortName)
102 nextShortName += 1
103 shortNames[varying] = shortName
104
105 context['getOriginalFragmentSource'] = js_escape(''.join(common + fragment))
106 context['getOriginalVertexSource'] = js_escape(''.join(common + vertex))
107 context['getFragmentSource'] = glsl_compress(''.join(common + fragment), shortNames)
108 context['getVertexSource'] = glsl_compress(''.join(common + vertex), shortNames)
109 context['getAttributes'] = [attributes[a] for a in sorted(attributes.keys())]
110 context['getUniforms'] = [uniforms[u] for u in sorted(uniforms.keys())]
111
112 if options.output and options.output != '-':
113 output = open(options.output, 'wb')
114 else:
115 output = sys.stdout
116 json.dump(context, output)
117
118
119if __name__ == '__main__':
120 sys.exit(main(sys.argv))