Merge pull request #2030 from erbridge/cg2glsl-fix

Tidy up cg2glsl.py
This commit is contained in:
Twinaphex 2015-08-17 21:06:24 +02:00
commit d1781c2761
1 changed files with 582 additions and 603 deletions

View File

@ -6,36 +6,50 @@ Author: Hans-Kristian Arntzen (Themaister)
License: Public domain
"""
import sys
if sys.version_info<(3,0,0):
sys.stderr.write("You need python 3.0 or later to run this script\n")
exit(1)
import os
import errno
import subprocess
import sys
if sys.version_info < (3, 0, 0):
sys.stderr.write("You need python 3.0 or later to run this script\n")
exit(1)
batch_mode = False
def log(*arg):
if not batch_mode:
# FIXME: This causes a syntax error in python2, preventing the version warning from displaying.
print(*arg)
def remove_comments(source_lines):
ret = []
killed_comments = [line.split('//')[0] for line in source_lines]
for i in filter(lambda line: len(line) > 0, killed_comments):
ret.append(i)
return ret
def keep_line_if(func, lines):
ret = []
for i in filter(func, lines):
ret.append(i)
for line in filter(func, lines):
ret.append(line)
return ret
def remove_comments(source_lines):
lines_without_comments = [line.split('//')[0] for line in source_lines]
return keep_line_if(lambda line: line, lines_without_comments)
def defines_var(line):
return ('//var' in line) or ('#var' in line)
def replace_by_table(source, table):
for orig, new in table:
if orig:
source = source.replace(orig, new)
return source
def replace_global_in(source):
split_source = source.split('\n')
replace_table = [
('IN.video_size', 'InputSize'),
('IN.texture_size', 'TextureSize'),
@ -44,25 +58,21 @@ def replace_global_in(source):
('IN.frame_direction', 'FrameDirection'),
]
for line in split_source:
if ('//var' in line) or ('#var' in line):
for line in source.splitlines():
if defines_var(line):
for index, replace in enumerate(replace_table):
orig = line.split(' ')[2]
orig = line.split()[2]
if replace[0] == orig:
replace_table[index] = (line.split(':')[2].split(' ')[1], replace_table[index][1])
log('Replace globals:', replace_table)
for replace in replace_table:
if replace[0]:
source = source.replace(replace[0], replace[1])
return source
return replace_by_table(source, replace_table)
def replace_global_vertex(source):
source = replace_global_in(source)
replace_table = [
('attribute', 'COMPAT_ATTRIBUTE'),
('varying', 'COMPAT_VARYING'),
@ -84,22 +94,21 @@ def replace_global_vertex(source):
('output', 'output_dummy'), # 'output' is reserved in GLSL.
]
for replacement in replace_table:
source = source.replace(replacement[0], replacement[1])
return replace_by_table(source, replace_table)
return source
def translate_varyings(varyings, source, direction):
dictionary = {}
for varying in varyings:
for line in source:
if (varying in line) and (('//var' in line) or ('#var' in line)) and (direction in line):
if defines_var(line) and (varying in line) and (direction in line):
log('Found line for', varying + ':', line)
dictionary[varying] = 'VAR' + line.split(':')[0].split('.')[-1].strip()
break
return dictionary
def no_uniform(elem):
banned = [
'_video_size',
@ -116,8 +125,10 @@ def no_uniform(elem):
for ban in banned:
if ban in elem:
return False
return True
def destructify_varyings(source, direction):
# We have to change varying structs that Cg support to single varyings for GL.
# Varying structs aren't supported until later versions
@ -127,13 +138,13 @@ def destructify_varyings(source, direction):
# Don't try to remove this as it breaks compile.
vout_lines = []
for line in source:
if (('//var' in line) or ('#var' in line)) and (('$vout.' in line) or ('$vin.' in line)):
if defines_var(line) and (('$vout.' in line) or ('$vin.' in line)):
vout_lines.append(line)
struct_types = []
for line in source[1:]:
if 'struct' in line:
struct_type = line.split(' ')[1]
struct_type = line.split()[1]
if struct_type not in struct_types:
struct_types.append(struct_type)
@ -150,9 +161,9 @@ def destructify_varyings(source, direction):
while (j < len(source)) and ('};' not in source[j]):
j += 1
lines = ['COMPAT_VARYING ' + string for string in source[i + 1 : j]]
lines = ['COMPAT_VARYING ' + string for string in source[(i + 1):j]]
varyings.extend(lines)
names = [string.strip().split(' ')[1].split(';')[0].strip() for string in source[i + 1 : j]]
names = [string.split()[1].split(';')[0].strip() for string in source[(i + 1):j]]
varyings_name.extend(names)
log('Found elements in struct', struct + ':', names)
last_struct_decl_line = j
@ -174,16 +185,13 @@ def destructify_varyings(source, direction):
# the actual varyings we just declared ...
# Globals only come before main() ...
# Make sure to only look after all struct declarations as there might be overlap.
for line in source[last_struct_decl_line:]:
for line in remove_comments(source[last_struct_decl_line:]):
if 'void main()' in line:
break
for struct in struct_types:
if struct in line:
decomment_line = line.split('//')[0].strip()
if len(decomment_line) == 0:
continue
variable = decomment_line.split(' ')[1].split(';')[0]
variable = line.split()[1].split(';')[0]
# Only redirect if the struct is actually used as vertex output.
for vout_line in vout_lines:
@ -209,7 +217,7 @@ def destructify_varyings(source, direction):
for varying_name in varyings_dict:
trans_from = variable + '.' + varying_name
trans_to = varyings_dict[varying_name]
source[index] = source[index].replace(trans_from, trans_to);
source[index] = source[index].replace(trans_from, trans_to)
for index, _ in enumerate(source):
for varying_name in varyings_name:
@ -224,100 +232,98 @@ def destructify_varyings(source, direction):
return source
def translate_varying(cg):
# Ye, it's ugly as shit. :(
#log('Translate:', cg)
translations = {
'IN.tex_coord' : 'TexCoord',
'IN.vertex_coord' : 'VertexCoord',
'IN.lut_tex_coord' : 'LUTTexCoord',
'ORIG.tex_coord' : 'OrigTexCoord',
'PREV.tex_coord' : 'PrevTexCoord',
'PREV1.tex_coord' : 'Prev1TexCoord',
'PREV2.tex_coord' : 'Prev2TexCoord',
'PREV3.tex_coord' : 'Prev3TexCoord',
'PREV4.tex_coord' : 'Prev4TexCoord',
'PREV5.tex_coord' : 'Prev5TexCoord',
'PREV6.tex_coord' : 'Prev6TexCoord',
'PASS1.tex_coord' : 'Pass1TexCoord',
'PASS2.tex_coord' : 'Pass2TexCoord',
'PASS3.tex_coord' : 'Pass3TexCoord',
'PASS4.tex_coord' : 'Pass4TexCoord',
'PASS5.tex_coord' : 'Pass5TexCoord',
'PASS6.tex_coord' : 'Pass6TexCoord',
'PASS7.tex_coord' : 'Pass7TexCoord',
'PASS8.tex_coord' : 'Pass8TexCoord',
'PASSPREV2.tex_coord' : 'PassPrev2TexCoord',
'PASSPREV3.tex_coord' : 'PassPrev3TexCoord',
'PASSPREV4.tex_coord' : 'PassPrev4TexCoord',
'PASSPREV5.tex_coord' : 'PassPrev5TexCoord',
'PASSPREV6.tex_coord' : 'PassPrev6TexCoord',
'PASSPREV7.tex_coord' : 'PassPrev7TexCoord',
'PASSPREV8.tex_coord' : 'PassPrev8TexCoord',
}
def translate(cg, translations):
if cg in translations:
return translations[cg]
else:
return cg
def translate_varying(cg):
translations = {
'IN.tex_coord': 'TexCoord',
'IN.vertex_coord': 'VertexCoord',
'IN.lut_tex_coord': 'LUTTexCoord',
'ORIG.tex_coord': 'OrigTexCoord',
'PREV.tex_coord': 'PrevTexCoord',
'PREV1.tex_coord': 'Prev1TexCoord',
'PREV2.tex_coord': 'Prev2TexCoord',
'PREV3.tex_coord': 'Prev3TexCoord',
'PREV4.tex_coord': 'Prev4TexCoord',
'PREV5.tex_coord': 'Prev5TexCoord',
'PREV6.tex_coord': 'Prev6TexCoord',
'PASS1.tex_coord': 'Pass1TexCoord',
'PASS2.tex_coord': 'Pass2TexCoord',
'PASS3.tex_coord': 'Pass3TexCoord',
'PASS4.tex_coord': 'Pass4TexCoord',
'PASS5.tex_coord': 'Pass5TexCoord',
'PASS6.tex_coord': 'Pass6TexCoord',
'PASS7.tex_coord': 'Pass7TexCoord',
'PASS8.tex_coord': 'Pass8TexCoord',
'PASSPREV2.tex_coord': 'PassPrev2TexCoord',
'PASSPREV3.tex_coord': 'PassPrev3TexCoord',
'PASSPREV4.tex_coord': 'PassPrev4TexCoord',
'PASSPREV5.tex_coord': 'PassPrev5TexCoord',
'PASSPREV6.tex_coord': 'PassPrev6TexCoord',
'PASSPREV7.tex_coord': 'PassPrev7TexCoord',
'PASSPREV8.tex_coord': 'PassPrev8TexCoord',
}
return translate(cg, translations)
def translate_texture_size(cg):
# Ye, it's ugly as shit. :(
#log('Translate:', cg)
translations = {
'ORIG.texture_size' : 'OrigTextureSize',
'PREV.texture_size' : 'PrevTextureSize',
'PREV1.texture_size' : 'Prev1TextureSize',
'PREV2.texture_size' : 'Prev2TextureSize',
'PREV3.texture_size' : 'Prev3TextureSize',
'PREV4.texture_size' : 'Prev4TextureSize',
'PREV5.texture_size' : 'Prev5TextureSize',
'PREV6.texture_size' : 'Prev6TextureSize',
'PASS1.texture_size' : 'Pass1TextureSize',
'PASS2.texture_size' : 'Pass2TextureSize',
'PASS3.texture_size' : 'Pass3TextureSize',
'PASS4.texture_size' : 'Pass4TextureSize',
'PASS5.texture_size' : 'Pass5TextureSize',
'PASS6.texture_size' : 'Pass6TextureSize',
'PASS7.texture_size' : 'Pass7TextureSize',
'PASS8.texture_size' : 'Pass8TextureSize',
'PASSPREV2.texture_size' : 'PassPrev2TextureSize',
'PASSPREV3.texture_size' : 'PassPrev3TextureSize',
'PASSPREV4.texture_size' : 'PassPrev4TextureSize',
'PASSPREV5.texture_size' : 'PassPrev5TextureSize',
'PASSPREV6.texture_size' : 'PassPrev6TextureSize',
'PASSPREV7.texture_size' : 'PassPrev7TextureSize',
'PASSPREV8.texture_size' : 'PassPrev8TextureSize',
'ORIG.video_size' : 'OrigInputSize',
'PREV.video_size' : 'PrevInputSize',
'PREV1.video_size' : 'Prev1InputSize',
'PREV2.video_size' : 'Prev2InputSize',
'PREV3.video_size' : 'Prev3InputSize',
'PREV4.video_size' : 'Prev4InputSize',
'PREV5.video_size' : 'Prev5InputSize',
'PREV6.video_size' : 'Prev6InputSize',
'PASS1.video_size' : 'Pass1InputSize',
'PASS2.video_size' : 'Pass2InputSize',
'PASS3.video_size' : 'Pass3InputSize',
'PASS4.video_size' : 'Pass4InputSize',
'PASS5.video_size' : 'Pass5InputSize',
'PASS6.video_size' : 'Pass6InputSize',
'PASS7.video_size' : 'Pass7InputSize',
'PASS8.video_size' : 'Pass8InputSize',
'PASSPREV2.video_size' : 'PassPrev2InputSize',
'PASSPREV3.video_size' : 'PassPrev3InputSize',
'PASSPREV4.video_size' : 'PassPrev4InputSize',
'PASSPREV5.video_size' : 'PassPrev5InputSize',
'PASSPREV6.video_size' : 'PassPrev6InputSize',
'PASSPREV7.video_size' : 'PassPrev7InputSize',
'PASSPREV8.video_size' : 'PassPrev8InputSize',
'ORIG.texture_size': 'OrigTextureSize',
'PREV.texture_size': 'PrevTextureSize',
'PREV1.texture_size': 'Prev1TextureSize',
'PREV2.texture_size': 'Prev2TextureSize',
'PREV3.texture_size': 'Prev3TextureSize',
'PREV4.texture_size': 'Prev4TextureSize',
'PREV5.texture_size': 'Prev5TextureSize',
'PREV6.texture_size': 'Prev6TextureSize',
'PASS1.texture_size': 'Pass1TextureSize',
'PASS2.texture_size': 'Pass2TextureSize',
'PASS3.texture_size': 'Pass3TextureSize',
'PASS4.texture_size': 'Pass4TextureSize',
'PASS5.texture_size': 'Pass5TextureSize',
'PASS6.texture_size': 'Pass6TextureSize',
'PASS7.texture_size': 'Pass7TextureSize',
'PASS8.texture_size': 'Pass8TextureSize',
'PASSPREV2.texture_size': 'PassPrev2TextureSize',
'PASSPREV3.texture_size': 'PassPrev3TextureSize',
'PASSPREV4.texture_size': 'PassPrev4TextureSize',
'PASSPREV5.texture_size': 'PassPrev5TextureSize',
'PASSPREV6.texture_size': 'PassPrev6TextureSize',
'PASSPREV7.texture_size': 'PassPrev7TextureSize',
'PASSPREV8.texture_size': 'PassPrev8TextureSize',
'ORIG.video_size': 'OrigInputSize',
'PREV.video_size': 'PrevInputSize',
'PREV1.video_size': 'Prev1InputSize',
'PREV2.video_size': 'Prev2InputSize',
'PREV3.video_size': 'Prev3InputSize',
'PREV4.video_size': 'Prev4InputSize',
'PREV5.video_size': 'Prev5InputSize',
'PREV6.video_size': 'Prev6InputSize',
'PASS1.video_size': 'Pass1InputSize',
'PASS2.video_size': 'Pass2InputSize',
'PASS3.video_size': 'Pass3InputSize',
'PASS4.video_size': 'Pass4InputSize',
'PASS5.video_size': 'Pass5InputSize',
'PASS6.video_size': 'Pass6InputSize',
'PASS7.video_size': 'Pass7InputSize',
'PASS8.video_size': 'Pass8InputSize',
'PASSPREV2.video_size': 'PassPrev2InputSize',
'PASSPREV3.video_size': 'PassPrev3InputSize',
'PASSPREV4.video_size': 'PassPrev4InputSize',
'PASSPREV5.video_size': 'PassPrev5InputSize',
'PASSPREV6.video_size': 'PassPrev6InputSize',
'PASSPREV7.video_size': 'PassPrev7InputSize',
'PASSPREV8.video_size': 'PassPrev8InputSize',
}
if cg in translations:
return translations[cg]
else:
return cg
return translate(cg, translations)
def replace_varyings(source):
@ -326,22 +332,19 @@ def replace_varyings(source):
attribs = []
uniforms = []
for index, line in enumerate(source):
if (('//var' in line) or ('#var' in line)) and ('$vin.' in line):
orig = line.split(' ')[2]
translated = translate_varying(orig)
if translated != orig and translated not in attribs:
cg_attrib = line.split(':')[2].split(' ')[1]
if len(cg_attrib.strip()) > 0:
translations.append((cg_attrib, translated))
attribs.append(translated)
elif ('//var' in line) or ('#var' in line):
orig = line.split(' ')[2]
translated = translate_texture_size(orig)
if translated != orig and translated not in uniforms:
cg_uniform = line.split(':')[2].split(' ')[1]
if len(cg_uniform.strip()) > 0:
translations.append((cg_uniform, translated))
uniforms.append(translated)
if defines_var(line):
func = translate_texture_size
collection = uniforms
if '$vin.' in line:
func = translate_varying
collection = attribs
orig = line.split()[2]
translated = func(orig)
if translated != orig and translated not in collection:
cg_var = line.split(':')[2].split(' ')[1]
if cg_var:
translations.append((cg_var, translated))
collection.append(translated)
for index, line in enumerate(source):
if 'void main()' in line:
@ -361,6 +364,52 @@ def replace_varyings(source):
return ret
def fix_samplers(log_prefix, ref_index, source):
translations = []
added_samplers = []
translated_samplers = []
uniforms = []
struct_texunit0 = False # If True, we have to append uniform sampler2D Texture manually ...
for line in source:
if ('TEXUNIT0' in line) and ('semantic' not in line):
main_sampler = (line.split(':')[2].split(' ')[1], 'Texture')
if main_sampler[0]:
translations.append(main_sampler)
log(log_prefix, 'Sampler:', main_sampler[0], '->', main_sampler[1])
struct_texunit0 = '.' in main_sampler[0]
elif ('//var sampler2D' in line) or ('#var sampler2D' in line):
cg_texture = line.split()[2]
translated = translate_texture(cg_texture)
orig_name = translated
new_name = line.split(':')[2].split(' ')[1]
log(log_prefix, 'Sampler:', new_name, '->', orig_name)
if new_name:
if translated != cg_texture and translated not in translated_samplers:
translated_samplers.append(translated)
added_samplers.append('uniform sampler2D ' + translated + ';')
translations.append((new_name, orig_name))
elif defines_var(line):
orig = line.split()[2]
translated = translate_texture_size(orig)
if translated != orig and translated not in uniforms:
cg_uniform = line.split(':')[2].split(' ')[1]
if cg_uniform:
translations.append((cg_uniform, translated))
uniforms.append(translated)
for sampler in added_samplers:
source.insert(ref_index, sampler)
if struct_texunit0:
source.insert(ref_index, 'uniform sampler2D Texture;')
for index, line in enumerate(source):
for orig, new in translations:
log(log_prefix, 'Translation:', orig, '->', new)
source[index] = source[index].replace(orig, new)
return source
def hack_source_vertex(source):
ref_index = 0
for index, line in enumerate(source):
@ -376,43 +425,16 @@ def hack_source_vertex(source):
break
# Fix samplers in vertex shader (supported by GLSL).
translations = []
added_samplers = []
translated_samplers = []
struct_texunit0 = False # If True, we have to append uniform sampler2D Texture manually ...
for line in source:
if ('TEXUNIT0' in line) and ('semantic' not in line):
main_sampler = (line.split(':')[2].split(' ')[1], 'Texture')
if len(main_sampler[0]) > 0:
translations.append(main_sampler)
log('Vertex: Sampler:', main_sampler[0], '->', main_sampler[1])
struct_texunit0 = '.' in main_sampler[0]
elif ('//var sampler2D' in line) or ('#var sampler2D' in line):
cg_texture = line.split(' ')[2]
translated = translate_texture(cg_texture)
orig_name = translated
new_name = line.split(':')[2].split(' ')[1]
log('Vertex: Sampler:', new_name, '->', orig_name)
if len(new_name) > 0:
if translated != cg_texture and translated not in translated_samplers:
translated_samplers.append(translated)
added_samplers.append('uniform sampler2D ' + translated + ';')
translations.append((new_name, orig_name))
for sampler in added_samplers:
source.insert(ref_index, sampler)
if struct_texunit0:
source.insert(ref_index, 'uniform sampler2D Texture;')
for index, line in enumerate(source):
for translation in translations:
source[index] = source[index].replace(translation[0], translation[1])
source = fix_samplers('Vertex:', ref_index, source)
source = destructify_varyings(source, '$vout.')
source = replace_varyings(source)
return source
def replace_global_fragment(source):
source = replace_global_in(source)
replace_table = [
('varying', 'COMPAT_VARYING'),
('texture2D', 'COMPAT_TEXTURE'),
@ -423,44 +445,38 @@ def replace_global_fragment(source):
('gl_FragColor', 'FragColor'),
]
for replacement in replace_table:
source = source.replace(replacement[0], replacement[1])
return source
return replace_by_table(source, replace_table)
def translate_texture(cg):
log('Translate:', cg)
translations = {
'ORIG.texture' : 'OrigTexture',
'PREV.texture' : 'PrevTexture',
'PREV1.texture' : 'Prev1Texture',
'PREV2.texture' : 'Prev2Texture',
'PREV3.texture' : 'Prev3Texture',
'PREV4.texture' : 'Prev4Texture',
'PREV5.texture' : 'Prev5Texture',
'PREV6.texture' : 'Prev6Texture',
'PASS1.texture' : 'Pass1Texture',
'PASS2.texture' : 'Pass2Texture',
'PASS3.texture' : 'Pass3Texture',
'PASS4.texture' : 'Pass4Texture',
'PASS5.texture' : 'Pass5Texture',
'PASS6.texture' : 'Pass6Texture',
'PASS7.texture' : 'Pass7Texture',
'PASS8.texture' : 'Pass8Texture',
'PASSPREV2.texture' : 'PassPrev2Texture',
'PASSPREV3.texture' : 'PassPrev3Texture',
'PASSPREV4.texture' : 'PassPrev4Texture',
'PASSPREV5.texture' : 'PassPrev5Texture',
'PASSPREV6.texture' : 'PassPrev6Texture',
'PASSPREV7.texture' : 'PassPrev7Texture',
'PASSPREV8.texture' : 'PassPrev8Texture',
'ORIG.texture': 'OrigTexture',
'PREV.texture': 'PrevTexture',
'PREV1.texture': 'Prev1Texture',
'PREV2.texture': 'Prev2Texture',
'PREV3.texture': 'Prev3Texture',
'PREV4.texture': 'Prev4Texture',
'PREV5.texture': 'Prev5Texture',
'PREV6.texture': 'Prev6Texture',
'PASS1.texture': 'Pass1Texture',
'PASS2.texture': 'Pass2Texture',
'PASS3.texture': 'Pass3Texture',
'PASS4.texture': 'Pass4Texture',
'PASS5.texture': 'Pass5Texture',
'PASS6.texture': 'Pass6Texture',
'PASS7.texture': 'Pass7Texture',
'PASS8.texture': 'Pass8Texture',
'PASSPREV2.texture': 'PassPrev2Texture',
'PASSPREV3.texture': 'PassPrev3Texture',
'PASSPREV4.texture': 'PassPrev4Texture',
'PASSPREV5.texture': 'PassPrev5Texture',
'PASSPREV6.texture': 'PassPrev6Texture',
'PASSPREV7.texture': 'PassPrev7Texture',
'PASSPREV8.texture': 'PassPrev8Texture',
}
if cg in translations:
return translations[cg]
else:
return cg
return translate(cg, translations)
def hack_source_fragment(source):
ref_index = 0
@ -474,54 +490,11 @@ def hack_source_fragment(source):
ref_index = index
break
translations = []
added_samplers = []
translated_samplers = []
uniforms = []
struct_texunit0 = False # If True, we have to append uniform sampler2D Texture manually ...
for line in source:
if ('TEXUNIT0' in line) and ('semantic' not in line):
main_sampler = (line.split(':')[2].split(' ')[1], 'Texture')
if len(main_sampler[0]) > 0:
translations.append(main_sampler)
log('Fragment: Sampler:', main_sampler[0], '->', main_sampler[1])
struct_texunit0 = '.' in main_sampler[0]
elif ('//var sampler2D' in line) or ('#var sampler2D' in line):
cg_texture = line.split(' ')[2]
translated = translate_texture(cg_texture)
orig_name = translated
new_name = line.split(':')[2].split(' ')[1]
log('Fragment: Sampler:', new_name, '->', orig_name)
if len(new_name) > 0:
if translated != cg_texture and translated not in translated_samplers:
translated_samplers.append(translated)
added_samplers.append('uniform sampler2D ' + translated + ';')
translations.append((new_name, orig_name))
elif ('//var' in line) or ('#var' in line):
orig = line.split(' ')[2]
translated = translate_texture_size(orig)
if translated != orig and translated not in uniforms:
cg_uniform = line.split(':')[2].split(' ')[1]
if len(cg_uniform.strip()) > 0:
translations.append((cg_uniform, translated))
uniforms.append(translated)
source = fix_samplers('Fragment:', ref_index, source)
source = destructify_varyings(source, '$vin.')
for sampler in added_samplers:
source.insert(ref_index, sampler)
for uniform in uniforms:
source.insert(ref_index, 'uniform COMPAT_PRECISION vec2 ' + uniform + ';')
if struct_texunit0:
source.insert(ref_index, 'uniform sampler2D Texture;')
return source
ret = []
for line in source:
for translation in translations:
log('Translation:', translation[0], '->', translation[1])
line = line.replace(translation[0], translation[1])
ret.append(line)
ret = destructify_varyings(ret, '$vin.')
return ret
def validate_shader(source, target):
log('Shader:')
@ -530,15 +503,16 @@ def validate_shader(source, target):
log('===')
command = ['cgc', '-noentry', '-ogles']
p = subprocess.Popen(command, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout_ret, stderr_ret = p.communicate(source.encode())
log('CGC:', stderr_ret.decode())
return p.returncode == 0
def preprocess_vertex(source_data):
input_data = source_data.split('\n')
input_data = source_data.splitlines()
ret = []
for line in input_data:
if ('uniform' in line) and (('float4x4' in line) or ('half4x4' in line)):
@ -549,11 +523,12 @@ def preprocess_vertex(source_data):
ret.append(line)
return '\n'.join(ret)
def convert(source, dest):
# Have to preprocess first to resolve #includes so we can hack potential vertex shaders.
inc_dir = os.path.split(source)[0]
vert_cmd_preprocess = ['cgc', '-E', '-I', '.' if inc_dir == '' else inc_dir, source]
p = subprocess.Popen(vert_cmd_preprocess, stderr = subprocess.PIPE, stdout = subprocess.PIPE)
p = subprocess.Popen(vert_cmd_preprocess, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
source_data, stderr_ret = p.communicate()
log(stderr_ret.decode())
@ -563,8 +538,8 @@ def convert(source, dest):
source_data = preprocess_vertex(source_data.decode())
vert_cmd = ['cgc', '-profile', 'glesv', '-entry', 'main_vertex', '-quiet']
p = subprocess.Popen(vert_cmd, stdin = subprocess.PIPE, stderr = subprocess.PIPE, stdout = subprocess.PIPE)
vertex_source, stderr_ret = p.communicate(input = source_data.encode())
p = subprocess.Popen(vert_cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
vertex_source, stderr_ret = p.communicate(input=source_data.encode())
log(stderr_ret.decode())
vertex_source = vertex_source.decode()
@ -573,8 +548,8 @@ def convert(source, dest):
return 1
frag_cmd = ['cgc', '-profile', 'glesf', '-entry', 'main_fragment', '-quiet']
p = subprocess.Popen(frag_cmd, stdin = subprocess.PIPE, stderr = subprocess.PIPE, stdout = subprocess.PIPE)
fragment_source, stderr_ret = p.communicate(input = source_data.encode())
p = subprocess.Popen(frag_cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
fragment_source, stderr_ret = p.communicate(input=source_data.encode())
log(stderr_ret.decode())
fragment_source = fragment_source.decode()
@ -585,8 +560,8 @@ def convert(source, dest):
vertex_source = replace_global_vertex(vertex_source)
fragment_source = replace_global_fragment(fragment_source)
vertex_source = vertex_source.split('\n')
fragment_source = fragment_source.split('\n')
vertex_source = vertex_source.splitlines()
fragment_source = fragment_source.splitlines()
# Cg think we're using row-major matrices, but we're using column major.
# Also, Cg tends to compile matrix multiplications as dot products in GLSL.
@ -669,6 +644,7 @@ precision mediump float;
f.write('#endif\n')
return 0
def convert_cgp(source, dest):
string = ''
with open(source, 'r') as f:
@ -676,14 +652,17 @@ def convert_cgp(source, dest):
open(dest, 'w').write(string)
def path_ext(path):
_, ext = os.path.splitext(path)
return ext
def convert_path(source, source_dir, dest_dir, conv):
index = 0 if source_dir[-1] == '/' else 1
return os.path.join(dest_dir, source.replace(source_dir, '')[index:]).replace(conv[0], conv[1])
def main():
if len(sys.argv) != 3:
print('Usage: {} prog.cg(p) prog.glsl(p)'.format(sys.argv[0]))
@ -764,6 +743,6 @@ def main():
else:
sys.exit(convert(source, dest))
if __name__ == '__main__':
sys.exit(main())