122 lines
4.0 KiB
Python
122 lines
4.0 KiB
Python
#!/usr/bin/python
|
|
|
|
from optparse import OptionParser
|
|
import re
|
|
import sys
|
|
|
|
import pystache
|
|
|
|
|
|
ESCAPE_SEQUENCE = {
|
|
'\\': '\\\\',
|
|
'\n': '\\n',
|
|
'\t': '\\t'
|
|
}
|
|
|
|
|
|
def js_escape(s):
|
|
return ''.join(ESCAPE_SEQUENCE.get(c, c) for c in s)
|
|
|
|
|
|
def glsl_compress(s, shortNames):
|
|
# strip leading whitespace
|
|
s = re.sub(r'\A\s+', '', s)
|
|
# strip trailing whitespace
|
|
s = re.sub(r'\s+\Z', '', s)
|
|
# strip multi-line comments
|
|
s = re.sub(r'/\*.*?\*/', '', s)
|
|
# strip single line comments
|
|
s = re.sub(r'//.*?\n', '', s)
|
|
# replace multiple whitespace with a single space
|
|
s = re.sub(r'\s+', ' ', s)
|
|
# remove whitespace between non-word tokens
|
|
s = re.sub(r'(\S)\s+([^\w])', r'\1\2', s)
|
|
s = re.sub(r'([^\w])\s+(\S)', r'\1\2', s)
|
|
# replace original names with short names
|
|
for originalName, shortName in shortNames.items():
|
|
s = s.replace(originalName, shortName)
|
|
return s
|
|
|
|
|
|
def main(argv):
|
|
option_parser = OptionParser()
|
|
option_parser.add_option('--input')
|
|
option_parser.add_option('--output')
|
|
option_parser.add_option('--template')
|
|
options, args = option_parser.parse_args(argv[1:])
|
|
|
|
context = {}
|
|
nextShortName = ord('a')
|
|
shortNames = {}
|
|
|
|
common, vertex, fragment = [], [], []
|
|
attributes, uniforms, varyings = {}, {}, {}
|
|
block = None
|
|
for line in open(options.input):
|
|
if line.startswith('//!'):
|
|
m = re.match(r'//!\s+NAMESPACE=(\S+)\s*\Z', line)
|
|
if m:
|
|
context['namespace'] = m.group(1)
|
|
continue
|
|
m = re.match(r'//!\s+CLASS=(\S+)\s*\Z', line)
|
|
if m:
|
|
context['className'] = m.group(1)
|
|
continue
|
|
m = re.match(r'//!\s+COMMON\s*\Z', line)
|
|
if m:
|
|
block = common
|
|
continue
|
|
m = re.match(r'//!\s+VERTEX\s*\Z', line)
|
|
if m:
|
|
block = vertex
|
|
continue
|
|
m = re.match(r'//!\s+FRAGMENT\s*\Z', line)
|
|
if m:
|
|
block = fragment
|
|
continue
|
|
else:
|
|
if block is None:
|
|
assert line.rstrip() == ''
|
|
else:
|
|
block.append(line)
|
|
m = re.match(r'attribute\s+\S+\s+(\S+);\s*\Z', line)
|
|
if m:
|
|
attribute = m.group(1)
|
|
if attribute not in attributes:
|
|
shortName = chr(nextShortName)
|
|
nextShortName += 1
|
|
attributes[attribute] = {'originalName': attribute, 'shortName': shortName}
|
|
shortNames[attribute] = shortName
|
|
m = re.match(r'uniform\s+\S+\s+(\S+);\s*\Z', line)
|
|
if m:
|
|
uniform = m.group(1)
|
|
if uniform not in uniforms:
|
|
shortName = chr(nextShortName)
|
|
nextShortName += 1
|
|
uniforms[uniform] = {'originalName': uniform, 'shortName': shortName}
|
|
shortNames[uniform] = shortName
|
|
m = re.match(r'varying\s+\S+\s+(\S+);\s*\Z', line)
|
|
if m:
|
|
varying = m.group(1)
|
|
if varying not in varyings:
|
|
shortName = chr(nextShortName)
|
|
nextShortName += 1
|
|
shortNames[varying] = shortName
|
|
|
|
context['getOriginalFragmentSource'] = js_escape(''.join(common + fragment))
|
|
context['getOriginalVertexSource'] = js_escape(''.join(common + vertex))
|
|
context['getFragmentSource'] = glsl_compress(''.join(common + fragment), shortNames)
|
|
context['getVertexSource'] = glsl_compress(''.join(common + vertex), shortNames)
|
|
context['getAttributes'] = [attributes[a] for a in sorted(attributes.keys())]
|
|
context['getUniforms'] = [uniforms[u] for u in sorted(uniforms.keys())]
|
|
|
|
if options.output and options.output != '-':
|
|
output = open(options.output, 'w')
|
|
else:
|
|
output = sys.stdout
|
|
output.write(pystache.render(open(options.template).read(), context))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv))
|